From 8ea49772dfea60b21a02f55a0e2192a88b7a5309 Mon Sep 17 00:00:00 2001 From: Mike Conrad Date: Sun, 18 May 2025 20:44:42 -0400 Subject: [PATCH] MVP, working sentry scraper --- .dockerignore | 19 + .env.example | 6 +- Dockerfile | 35 ++ adonisrc.ts | 2 +- app/controllers/replays_controller.ts | 80 +++ app/middleware/auth_middleware.ts | 2 +- app/middleware/guest_middleware.ts | 2 +- app/middleware/silent_auth_middleware.ts | 7 +- app/models/replay.ts | 172 +++++++ app/models/user.ts | 2 +- config/auth.ts | 4 +- config/database.ts | 15 +- config/inertia.ts | 6 +- .../1747441798566_create_users_table.ts | 2 +- .../1747444420483_create_replays_table.ts | 47 ++ docker-compose.yml | 36 ++ inertia/app/app.ts | 8 +- inertia/app/ssr.ts | 3 +- inertia/css/app.css | 2 +- inertia/pages/errors/not_found.vue | 2 +- inertia/pages/errors/server_error.vue | 4 +- inertia/pages/home.vue | 112 ++-- inertia/tsconfig.json | 8 +- package-lock.json | 480 +++++------------- package.json | 7 +- resources/views/inertia_layout.edge | 127 ++--- start/kernel.ts | 6 +- start/routes.ts | 3 +- vite.config.ts | 6 +- 29 files changed, 724 insertions(+), 481 deletions(-) create mode 100644 .dockerignore create mode 100644 Dockerfile create mode 100644 app/controllers/replays_controller.ts create mode 100644 app/models/replay.ts create mode 100644 database/migrations/1747444420483_create_replays_table.ts create mode 100644 docker-compose.yml diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..0f4a665 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,19 @@ +# Adonis default .gitignore ignores +node_modules +build +coverage +.vscode +.DS_STORE +.env +tmp + +# Additional .gitignore ignores (any custom file you wish) +.idea + +# Additional good to have ignores for dockerignore +Dockerfile* +docker-compose* +.dockerignore +*.md +.git +.gitignore diff --git a/.env.example b/.env.example index 096740d..496e094 100644 --- a/.env.example +++ b/.env.example @@ -4,4 +4,8 @@ HOST=localhost LOG_LEVEL=info APP_KEY= NODE_ENV=development -SESSION_DRIVER=cookie \ No newline at end of file +SESSION_DRIVER=cookie +PG_HOST=localhost +PG_PASSWORD=password +SENTRY_TOKEN= +SENTRY_ORG= \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..88ee6d4 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,35 @@ +FROM node:20.12.2-alpine3.18 AS base + + +# All deps stage +FROM base AS deps +WORKDIR /app +ADD package.json package-lock.json ./ +RUN npm ci + +FROM base AS dev-deps +WORKDIR /app +ADD package.json package-lock.json ./ +RUN npm ci + +# Production only deps stage +FROM base AS production-deps +WORKDIR /app +ADD package.json package-lock.json ./ +RUN npm ci --omit=dev + +# Build stage +FROM base AS build +WORKDIR /app +COPY --from=deps /app/node_modules /app/node_modules +ADD . . +RUN node ace build --ignore-ts-errors + +# Production stage +FROM base +ENV NODE_ENV=production +WORKDIR /app +COPY --from=production-deps /app/node_modules /app/node_modules +COPY --from=build /app/build /app +EXPOSE 8080 +CMD ["node", "./bin/server.js"] diff --git a/adonisrc.ts b/adonisrc.ts index 448ae44..dcb5d0f 100644 --- a/adonisrc.ts +++ b/adonisrc.ts @@ -52,7 +52,7 @@ export default defineConfig({ () => import('@adonisjs/cors/cors_provider'), () => import('@adonisjs/lucid/database_provider'), () => import('@adonisjs/auth/auth_provider'), - () => import('@adonisjs/inertia/inertia_provider') + () => import('@adonisjs/inertia/inertia_provider'), ], /* diff --git a/app/controllers/replays_controller.ts b/app/controllers/replays_controller.ts new file mode 100644 index 0000000..3f1f688 --- /dev/null +++ b/app/controllers/replays_controller.ts @@ -0,0 +1,80 @@ +import Replay from '#models/replay' +import env from '#start/env' +import type { HttpContext } from '@adonisjs/core/http' +const SENTRY_TOKEN = env.get('SENTRY_TOKEN') +const SENTRY_ORG = env.get('SENTRY_ORG') +let recordsUpdated = 0 +export default class ReplaysController { + + + async index({ request, response }: HttpContext) { + const {statsPeriod, start, end} = request.qs() + recordsUpdated = 0 + + let queryString: string = '?statsPeriod=24h'// Default in case none is provided + if (statsPeriod) { + queryString = `?statsPeriod=${statsPeriod}` + } else if (start && end) { + queryString = `?start=${start}&end=${end}` + } + const replays = await fetchBatch(`https://sentry.io/api/0/organizations/${SENTRY_ORG}/replays/${queryString}`) + return response.json(replays) + } + +} + + +async function fetchBatch(url: string) { + const options: RequestInit = { + headers: { + Authorization: `Bearer ${SENTRY_TOKEN}` + } + } + const req = await fetch(url, options) + const resp = await req.json() as unknown + const replays = await resp.data as unknown + const headers = await req.headers + + const cleanedData = replays.map(record => sanitizeInput(record, Replay.allowedFields)) + + let updated = await Replay.updateOrCreateMany('id', cleanedData ) + recordsUpdated = recordsUpdated + updated.length + const pagination = parseSentryLinkHeader(headers.get('link')) + + if (pagination.hasNextResults == true) { + console.log('fetching', pagination.next) + await fetchBatch(pagination.next) + } + console.log('no more results') + return {recordsUpdated} + +} +function parseSentryLinkHeader(header:string) { + const links = header.split(',').map(part => part.trim()) + + const result = {} + + for (const link of links) { + const match = link.match(/<([^>]+)>;\s*rel="([^"]+)";\s*results="([^"]+)";\s*cursor="([^"]+)"/) + if (!match) continue + + const [, url, rel, results] = match + + if (rel === 'previous') { + result.previous = url + result.hasPreviousResults = results === 'true' + } else if (rel === 'next') { + result.next = url + result.hasNextResults = results === 'true' + } + } + + return result + } + + function sanitizeInput(data: Record, allowedFields: string[]) { + return allowedFields.reduce((acc, key) => { + if (key in data) acc[key] = data[key] + return acc + }, {} as Record) + } \ No newline at end of file diff --git a/app/middleware/auth_middleware.ts b/app/middleware/auth_middleware.ts index 6e07003..f5a2ba3 100644 --- a/app/middleware/auth_middleware.ts +++ b/app/middleware/auth_middleware.ts @@ -22,4 +22,4 @@ export default class AuthMiddleware { await ctx.auth.authenticateUsing(options.guards, { loginRoute: this.redirectTo }) return next() } -} \ No newline at end of file +} diff --git a/app/middleware/guest_middleware.ts b/app/middleware/guest_middleware.ts index e459796..f9904cf 100644 --- a/app/middleware/guest_middleware.ts +++ b/app/middleware/guest_middleware.ts @@ -28,4 +28,4 @@ export default class GuestMiddleware { return next() } -} \ No newline at end of file +} diff --git a/app/middleware/silent_auth_middleware.ts b/app/middleware/silent_auth_middleware.ts index 99437c6..3e46f40 100644 --- a/app/middleware/silent_auth_middleware.ts +++ b/app/middleware/silent_auth_middleware.ts @@ -8,12 +8,9 @@ import type { NextFn } from '@adonisjs/core/types/http' * The request continues as usual, even when the user is not logged-in. */ export default class SilentAuthMiddleware { - async handle( - ctx: HttpContext, - next: NextFn, - ) { + async handle(ctx: HttpContext, next: NextFn) { await ctx.auth.check() return next() } -} \ No newline at end of file +} diff --git a/app/models/replay.ts b/app/models/replay.ts new file mode 100644 index 0000000..066415f --- /dev/null +++ b/app/models/replay.ts @@ -0,0 +1,172 @@ +import { DateTime } from 'luxon' +import { BaseModel, column } from '@adonisjs/lucid/orm' + +export default class Replay extends BaseModel { + @column({ isPrimary: true }) + declare id: string + + @column() + declare project_id: string + + @column({ + prepare: (value) => { + // The values from sentry are just arrays so convert them to json + return JSON.stringify(value) + } + }) + declare trace_ids: string[] + + @column({ + prepare: (value) => { + return JSON.stringify(value) + } + }) + declare error_ids: string[] + + @column() + declare environment: string | null + + @column({ + prepare: (value) => { + // The values from sentry are just arrays so convert them to json + return JSON.stringify(value) + } + }) + declare tags: any + + @column() + declare user: any + + + @column() + declare sdk: any + + + @column() + declare os: any + + + @column() + declare browser: any + + + @column() + declare device: any + @column() + declare ota_updates: any + + @column() + declare is_archived: boolean | null + + + @column({ + prepare: (value) => { + // The values from sentry are just arrays so convert them to json + return JSON.stringify(value) + } + }) + declare urls: any + + + @column({ + prepare: (value) => { + // The values from sentry are just arrays so convert them to json + return JSON.stringify(value) + } + }) + declare clicks: any + + @column() + declare count_dead_clicks: number | null + + @column() + declare count_rage_clicks: number | null + + @column() + declare count_errors: number | null + + @column() + declare duration: number | null + + @column.dateTime() + declare finished_at: DateTime | null + + @column.dateTime({serializeAs: 'started_at'}) + declare started_at: DateTime | null + + @column() + declare activity: number | null + + @column() + declare count_urls: number | null + + @column() + declare replay_type: string + + @column() + declare count_segments: number | null + + @column() + declare platform: string | null + + + @column({ + prepare: (value) => { + // The values from sentry are just arrays so convert them to json + return JSON.stringify(value) + } + }) + declare releases: any + + @column() + declare dist: string | null + + @column() + declare count_warnings: number | null + + @column() + declare count_infos: number | null + + @column() + declare has_viewed: boolean + + @column.dateTime({ autoCreate: true }) + declare created_at: DateTime + + @column.dateTime({ autoCreate: true, autoUpdate: true }) + declare updated_at: DateTime + + public static allowedFields = [ + 'id', + 'project_id', + 'trace_ids', + 'error_ids', + 'environment', + 'tags', + 'user', + 'sdk', + 'os', + 'browser', + 'device', + 'ota_updates', + 'is_archived', + 'urls', + 'clicks', + 'count_dead_clicks', + 'count_rage_clicks', + 'count_errors', + 'duration', + 'finished_at', + 'started_at', + 'activity', + 'count_urls', + 'replay_type', + 'count_segments', + 'platform', + 'releases', + 'dist', + 'count_warnings', + 'count_infos', + 'has_viewed', + ] +} diff --git a/app/models/user.ts b/app/models/user.ts index ce4b0b8..dfe4857 100644 --- a/app/models/user.ts +++ b/app/models/user.ts @@ -27,4 +27,4 @@ export default class User extends compose(BaseModel, AuthFinder) { @column.dateTime({ autoCreate: true, autoUpdate: true }) declare updatedAt: DateTime | null -} \ No newline at end of file +} diff --git a/config/auth.ts b/config/auth.ts index 80d6bf9..8a760fa 100644 --- a/config/auth.ts +++ b/config/auth.ts @@ -8,7 +8,7 @@ const authConfig = defineConfig({ web: sessionGuard({ useRememberMeTokens: false, provider: sessionUserProvider({ - model: () => import('#models/user') + model: () => import('#models/user'), }), }), }, @@ -25,4 +25,4 @@ declare module '@adonisjs/auth/types' { } declare module '@adonisjs/core/types' { interface EventsList extends InferAuthEvents {} -} \ No newline at end of file +} diff --git a/config/database.ts b/config/database.ts index ed32052..020bc6a 100644 --- a/config/database.ts +++ b/config/database.ts @@ -1,13 +1,18 @@ import app from '@adonisjs/core/services/app' import { defineConfig } from '@adonisjs/lucid' +import env from '#start/env' const dbConfig = defineConfig({ - connection: 'sqlite', + connection: 'postgres', connections: { - sqlite: { - client: 'better-sqlite3', + postgres: { + client: 'pg', connection: { - filename: app.tmpPath('db.sqlite3') + host: env.get('PG_HOST'), + port: env.get('PG_PORT', 5432), + user: env.get('PG_USER', 'postgres'), + password: env.get('PG_PASSWORD', 'postgres'), + database: env.get('PG_DB_NAME', 'postgres'), }, useNullAsDefault: true, migrations: { @@ -18,4 +23,4 @@ const dbConfig = defineConfig({ }, }) -export default dbConfig \ No newline at end of file +export default dbConfig diff --git a/config/inertia.ts b/config/inertia.ts index 5a43db6..3c93ab1 100644 --- a/config/inertia.ts +++ b/config/inertia.ts @@ -19,12 +19,12 @@ const inertiaConfig = defineConfig({ */ ssr: { enabled: true, - entrypoint: 'inertia/app/ssr.ts' - } + entrypoint: 'inertia/app/ssr.ts', + }, }) export default inertiaConfig declare module '@adonisjs/inertia/types' { export interface SharedProps extends InferSharedProps {} -} \ No newline at end of file +} diff --git a/database/migrations/1747441798566_create_users_table.ts b/database/migrations/1747441798566_create_users_table.ts index d6a6798..dbca083 100644 --- a/database/migrations/1747441798566_create_users_table.ts +++ b/database/migrations/1747441798566_create_users_table.ts @@ -18,4 +18,4 @@ export default class extends BaseSchema { async down() { this.schema.dropTable(this.tableName) } -} \ No newline at end of file +} diff --git a/database/migrations/1747444420483_create_replays_table.ts b/database/migrations/1747444420483_create_replays_table.ts new file mode 100644 index 0000000..fe473b6 --- /dev/null +++ b/database/migrations/1747444420483_create_replays_table.ts @@ -0,0 +1,47 @@ +import { BaseSchema } from '@adonisjs/lucid/schema' + +export default class extends BaseSchema { + protected tableName = 'replays' + + async up() { + this.schema.createTable(this.tableName, (table) => { + table.string('id').primary() + table.string('project_id') + table.jsonb('trace_ids') + table.jsonb('error_ids') + table.string('environment').nullable() + table.jsonb('tags') + table.jsonb('user') + table.jsonb('sdk') + table.jsonb('os') + table.jsonb('browser') + table.jsonb('device') + table.jsonb('ota_updates') + table.boolean('is_archived').nullable() + table.jsonb('urls') + table.jsonb('clicks') + table.integer('count_dead_clicks').nullable() + table.integer('count_rage_clicks').nullable() + table.integer('count_errors').nullable() + table.bigInteger('duration').nullable() + table.timestamp('finished_at', { useTz: true }).nullable() + table.timestamp('started_at', { useTz: true }).nullable() + table.integer('activity').nullable() + table.integer('count_urls').nullable() + table.string('replay_type') + table.integer('count_segments').nullable() + table.string('platform').nullable() + table.jsonb('releases') + table.string('dist').nullable() + table.integer('count_warnings').nullable() + table.integer('count_infos').nullable() + table.boolean('has_viewed') + table.timestamp('created_at', { useTz: true }).defaultTo(this.now()) + table.timestamp('updated_at', { useTz: true }).defaultTo(this.now()) + }) + } + + async down() { + this.schema.dropTable(this.tableName) + } +} diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..b7e3df5 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,36 @@ + name: sentry + services: + reverse-proxy: + image: traefik:latest + command: --api.insecure=true --providers.docker + ports: + - 80:80 + - 8080:8080 + volumes: + # So that Traefik can listen to the Docker events + - /var/run/docker.sock:/var/run/docker.sock + + scraper: + # image: paragontruss.azurecr.io/sentry-scraper + build: + context: . + target: dev-deps + ports: + - 3333:3333 + env_file: .env + volumes: + - backend_node_modules:/app/node_modules + - ./:/app + command: node ace serve --watch + labels: + - "traefik.http.routers.backend.rule=Host(`sentry.docker.localhost`)" + db: + image: postgres:16 + environment: + - POSTGRES_PASSWORD=password + grafana: + image: grafana/grafana:latest + labels: + - "traefik.http.routers.grafana.rule=Host(`grafana.docker.localhost`)" + volumes: + backend_node_modules: {} \ No newline at end of file diff --git a/inertia/app/app.ts b/inertia/app/app.ts index ca93214..a65926c 100644 --- a/inertia/app/app.ts +++ b/inertia/app/app.ts @@ -1,7 +1,7 @@ /// /// -import '../css/app.css'; +import '../css/app.css' import { createSSRApp, h } from 'vue' import type { DefineComponent } from 'vue' import { createInertiaApp } from '@inertiajs/vue3' @@ -17,15 +17,13 @@ createInertiaApp({ resolve: (name) => { return resolvePageComponent( `../pages/${name}.vue`, - import.meta.glob('../pages/**/*.vue'), + import.meta.glob('../pages/**/*.vue') ) }, setup({ el, App, props, plugin }) { - createSSRApp({ render: () => h(App, props) }) - .use(plugin) .mount(el) }, -}) \ No newline at end of file +}) diff --git a/inertia/app/ssr.ts b/inertia/app/ssr.ts index caffcff..2194fd1 100644 --- a/inertia/app/ssr.ts +++ b/inertia/app/ssr.ts @@ -1,4 +1,3 @@ - import { createInertiaApp } from '@inertiajs/vue3' import { renderToString } from '@vue/server-renderer' import { createSSRApp, h, type DefineComponent } from 'vue' @@ -16,4 +15,4 @@ export default function render(page: any) { return createSSRApp({ render: () => h(App, props) }).use(plugin) }, }) -} \ No newline at end of file +} diff --git a/inertia/css/app.css b/inertia/css/app.css index 7f97fa9..3e92e8f 100644 --- a/inertia/css/app.css +++ b/inertia/css/app.css @@ -7,4 +7,4 @@ html, body { height: 100%; width: 100%; -} \ No newline at end of file +} diff --git a/inertia/pages/errors/not_found.vue b/inertia/pages/errors/not_found.vue index 65248e1..06b5f75 100644 --- a/inertia/pages/errors/not_found.vue +++ b/inertia/pages/errors/not_found.vue @@ -4,4 +4,4 @@ This page does not exist. - \ No newline at end of file + diff --git a/inertia/pages/errors/server_error.vue b/inertia/pages/errors/server_error.vue index a9942ff..394a19f 100644 --- a/inertia/pages/errors/server_error.vue +++ b/inertia/pages/errors/server_error.vue @@ -1,5 +1,5 @@ \ No newline at end of file + diff --git a/inertia/pages/home.vue b/inertia/pages/home.vue index 479d633..a640779 100644 --- a/inertia/pages/home.vue +++ b/inertia/pages/home.vue @@ -1,11 +1,13 @@ \ No newline at end of file + diff --git a/inertia/tsconfig.json b/inertia/tsconfig.json index 74e910a..e03d10d 100644 --- a/inertia/tsconfig.json +++ b/inertia/tsconfig.json @@ -6,8 +6,8 @@ "module": "ESNext", "jsxImportSource": "vue", "paths": { - "~/*": ["./*"], - }, + "~/*": ["./*"] + } }, - "include": ["./**/*.ts", "./**/*.vue"], -} \ No newline at end of file + "include": ["./**/*.ts", "./**/*.vue"] +} diff --git a/package-lock.json b/package-lock.json index 59d54b4..aff4bfa 100644 --- a/package-lock.json +++ b/package-lock.json @@ -21,9 +21,9 @@ "@inertiajs/vue3": "^2.0.11", "@vinejs/vine": "^3.0.1", "@vue/server-renderer": "^3.5.14", - "better-sqlite3": "^11.10.0", "edge.js": "^6.2.1", "luxon": "^3.6.1", + "pg": "^8.16.0", "reflect-metadata": "^0.2.2", "vue": "^3.5.14" }, @@ -3329,26 +3329,6 @@ "devOptional": true, "license": "MIT" }, - "node_modules/base64-js": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/base64-js/-/base64-js-1.5.1.tgz", - "integrity": "sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/basic-auth": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", @@ -3367,37 +3347,6 @@ "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", "license": "MIT" }, - "node_modules/better-sqlite3": { - "version": "11.10.0", - "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.10.0.tgz", - "integrity": "sha512-EwhOpyXiOEL/lKzHz9AW1msWFNzGc/z+LzeB3/jnFJpxu+th2yqvzsSWas1v9jgs9+xiXJcD5A8CJxAG2TaghQ==", - "hasInstallScript": true, - "license": "MIT", - "dependencies": { - "bindings": "^1.5.0", - "prebuild-install": "^7.1.1" - } - }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "license": "MIT", - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, - "node_modules/bl": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", - "integrity": "sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==", - "license": "MIT", - "dependencies": { - "buffer": "^5.5.0", - "inherits": "^2.0.4", - "readable-stream": "^3.4.0" - } - }, "node_modules/brace-expansion": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", @@ -3453,30 +3402,6 @@ "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7" } }, - "node_modules/buffer": { - "version": "5.7.1", - "resolved": "https://registry.npmjs.org/buffer/-/buffer-5.7.1.tgz", - "integrity": "sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "base64-js": "^1.3.1", - "ieee754": "^1.1.13" - } - }, "node_modules/builtin-modules": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz", @@ -3689,12 +3614,6 @@ "url": "https://paulmillr.com/funding/" } }, - "node_modules/chownr": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.4.tgz", - "integrity": "sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==", - "license": "ISC" - }, "node_modules/ci-info": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.2.0.tgz", @@ -4093,21 +4012,6 @@ "node": ">=0.10" } }, - "node_modules/decompress-response": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", - "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", - "license": "MIT", - "dependencies": { - "mimic-response": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/dedent": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-1.6.0.tgz", @@ -4133,15 +4037,6 @@ "node": ">=6" } }, - "node_modules/deep-extend": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/deep-extend/-/deep-extend-0.6.0.tgz", - "integrity": "sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==", - "license": "MIT", - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/deep-is": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz", @@ -4177,15 +4072,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detect-libc": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.4.tgz", - "integrity": "sha512-3UDv+G9CsCKO1WKMGw9fwq/SWJYbI0c5Y7LU1AXYoDdbhE2AHQ6N6Nb34sG8Fj7T5APy8qXDCKuuIHd1BR0tVA==", - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, "node_modules/diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -4352,6 +4238,7 @@ "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", "integrity": "sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==", + "dev": true, "license": "MIT", "dependencies": { "once": "^1.4.0" @@ -4875,15 +4762,6 @@ "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/expand-template": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/expand-template/-/expand-template-2.0.3.tgz", - "integrity": "sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==", - "license": "(MIT OR WTFPL)", - "engines": { - "node": ">=6" - } - }, "node_modules/fast-copy": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/fast-copy/-/fast-copy-3.0.2.tgz", @@ -5050,12 +4928,6 @@ "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "license": "MIT" - }, "node_modules/fill-range": { "version": "7.1.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.1.1.tgz", @@ -5280,12 +5152,6 @@ "node": ">= 0.6" } }, - "node_modules/fs-constants": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", - "integrity": "sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==", - "license": "MIT" - }, "node_modules/fs-readdir-recursive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", @@ -5419,12 +5285,6 @@ "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==", "license": "MIT" }, - "node_modules/github-from-package": { - "version": "0.0.0", - "resolved": "https://registry.npmjs.org/github-from-package/-/github-from-package-0.0.0.tgz", - "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==", - "license": "MIT" - }, "node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -5779,12 +5639,6 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "license": "ISC" }, - "node_modules/ini": { - "version": "1.3.8", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz", - "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==", - "license": "ISC" - }, "node_modules/interpret": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", @@ -6467,18 +6321,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/mimic-response": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", - "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", - "license": "MIT", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -6509,6 +6351,7 @@ "version": "1.2.8", "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, "license": "MIT", "funding": { "url": "https://github.com/sponsors/ljharb" @@ -6530,12 +6373,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "license": "MIT" - }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -6569,12 +6406,6 @@ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1" } }, - "node_modules/napi-build-utils": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/napi-build-utils/-/napi-build-utils-2.0.0.tgz", - "integrity": "sha512-GEbrYkbfF7MoNaoh2iGG84Mnf/WZfB0GdGEsM8wz7Expx/LlWf5U8t9nvJKXSp3qr5IsEbK04cBGhol/KwOsWA==", - "license": "MIT" - }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -6591,18 +6422,6 @@ "node": ">= 0.6" } }, - "node_modules/node-abi": { - "version": "3.75.0", - "resolved": "https://registry.npmjs.org/node-abi/-/node-abi-3.75.0.tgz", - "integrity": "sha512-OhYaY5sDsIka7H7AtijtI9jwGYLyl29eQn/W623DiN/MIv5sUqc4g7BIDThX+gb7di9f6xK02nkp8sdfFWZLTg==", - "license": "MIT", - "dependencies": { - "semver": "^7.3.5" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/node-releases": { "version": "2.0.19", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.19.tgz", @@ -6704,6 +6523,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, "license": "ISC", "dependencies": { "wrappy": "1" @@ -6985,12 +6805,101 @@ "url": "https://github.com/sponsors/Borewit" } }, + "node_modules/pg": { + "version": "8.16.0", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.16.0.tgz", + "integrity": "sha512-7SKfdvP8CTNXjMUzfcVTaI+TDzBEeaUnVwiVGZQD1Hh33Kpev7liQba9uLd4CfN8r9mCVsD0JIpq03+Unpz+kg==", + "license": "MIT", + "dependencies": { + "pg-connection-string": "^2.9.0", + "pg-pool": "^3.10.0", + "pg-protocol": "^1.10.0", + "pg-types": "2.2.0", + "pgpass": "1.0.5" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.2.5" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.2.5", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.2.5.tgz", + "integrity": "sha512-OOX22Vt0vOSRrdoUPKJ8Wi2OpE/o/h9T8X1s4qSkCedbNah9ei2W2765be8iMVxQUsvgT7zIAT2eIa9fs5+vtg==", + "license": "MIT", + "optional": true + }, "node_modules/pg-connection-string": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==", "license": "MIT" }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "license": "ISC", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.10.0.tgz", + "integrity": "sha512-DzZ26On4sQ0KmqnO34muPcmKbhrjmyiO4lCCR0VwEd7MjmiKf5NTg/6+apUEu0NF7ESa37CGzFxH513CoUmWnA==", + "license": "MIT", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.10.0.tgz", + "integrity": "sha512-IpdytjudNuLv8nhlHs/UrVBhU0e78J0oIS/0AVdTbWxSOkFUVdsHC/NrorO6nXsQNDTT1kzDSOMJubBQviX18Q==", + "license": "MIT" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "license": "MIT", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pg/node_modules/pg-connection-string": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.9.0.tgz", + "integrity": "sha512-P2DEBKuvh5RClafLngkAuGe9OUlFV7ebu8w1kmaaOgPcpJd1RIFh7otETfI6hAR8YupOLFTY7nuvvIn7PLciUQ==", + "license": "MIT" + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "license": "MIT", + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picocolors": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz", @@ -7158,30 +7067,43 @@ "node": "^10 || ^12 || >=14" } }, - "node_modules/prebuild-install": { - "version": "7.1.3", - "resolved": "https://registry.npmjs.org/prebuild-install/-/prebuild-install-7.1.3.tgz", - "integrity": "sha512-8Mf2cbV7x1cXPUILADGI3wuhfqWvtiLA1iclTDbFRZkgRQS0NqsPZphna9V+HyTEadheuPmjaJMsbzKQFOzLug==", + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "license": "MIT", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", "license": "MIT", "dependencies": { - "detect-libc": "^2.0.0", - "expand-template": "^2.0.3", - "github-from-package": "0.0.0", - "minimist": "^1.2.3", - "mkdirp-classic": "^0.5.3", - "napi-build-utils": "^2.0.0", - "node-abi": "^3.3.0", - "pump": "^3.0.0", - "rc": "^1.2.7", - "simple-get": "^4.0.0", - "tar-fs": "^2.0.0", - "tunnel-agent": "^0.6.0" - }, - "bin": { - "prebuild-install": "bin.js" + "xtend": "^4.0.0" }, "engines": { - "node": ">=10" + "node": ">=0.10.0" } }, "node_modules/prelude-ls": { @@ -7344,6 +7266,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.2.tgz", "integrity": "sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==", + "dev": true, "license": "MIT", "dependencies": { "end-of-stream": "^1.1.0", @@ -7452,30 +7375,6 @@ "node": ">= 0.8" } }, - "node_modules/rc": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/rc/-/rc-1.2.8.tgz", - "integrity": "sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==", - "license": "(BSD-2-Clause OR MIT OR Apache-2.0)", - "dependencies": { - "deep-extend": "^0.6.0", - "ini": "~1.3.0", - "minimist": "^1.2.0", - "strip-json-comments": "~2.0.1" - }, - "bin": { - "rc": "cli.js" - } - }, - "node_modules/rc/node_modules/strip-json-comments": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", - "integrity": "sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==", - "license": "MIT", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/react-is": { "version": "18.3.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", @@ -7693,20 +7592,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "license": "MIT", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/readdirp": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz", @@ -7971,6 +7856,7 @@ "version": "7.7.2", "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "dev": true, "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -8171,51 +8057,6 @@ "url": "https://github.com/sponsors/isaacs" } }, - "node_modules/simple-concat": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/simple-concat/-/simple-concat-1.0.1.tgz", - "integrity": "sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, - "node_modules/simple-get": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/simple-get/-/simple-get-4.0.1.tgz", - "integrity": "sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT", - "dependencies": { - "decompress-response": "^6.0.0", - "once": "^1.3.1", - "simple-concat": "^1.0.0" - } - }, "node_modules/slash": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz", @@ -8386,15 +8227,6 @@ "node": ">= 0.8" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "license": "MIT", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string-width": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", @@ -8563,34 +8395,6 @@ "url": "https://opencollective.com/synckit" } }, - "node_modules/tar-fs": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.2.tgz", - "integrity": "sha512-EsaAXwxmx8UB7FRKqeozqEPop69DXcmYwTQwXvyAPF352HJsPdkVhvTaDPYqfNgruveJIJy3TA2l+2zj8LJIJA==", - "license": "MIT", - "dependencies": { - "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^2.1.4" - } - }, - "node_modules/tar-stream": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-2.2.0.tgz", - "integrity": "sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==", - "license": "MIT", - "dependencies": { - "bl": "^4.0.3", - "end-of-stream": "^1.4.1", - "fs-constants": "^1.0.0", - "inherits": "^2.0.3", - "readable-stream": "^3.1.1" - }, - "engines": { - "node": ">=6" - } - }, "node_modules/tarn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", @@ -8815,18 +8619,6 @@ "node": ">=0.6.x" } }, - "node_modules/tunnel-agent": { - "version": "0.6.0", - "resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz", - "integrity": "sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==", - "license": "Apache-2.0", - "dependencies": { - "safe-buffer": "^5.0.1" - }, - "engines": { - "node": "*" - } - }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -9011,12 +8803,6 @@ "punycode": "^2.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==", - "license": "MIT" - }, "node_modules/v8-compile-cache-lib": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/v8-compile-cache-lib/-/v8-compile-cache-lib-3.0.1.tgz", @@ -9255,8 +9041,18 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", + "dev": true, "license": "ISC" }, + "node_modules/xtend": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", + "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", + "license": "MIT", + "engines": { + "node": ">=0.4" + } + }, "node_modules/yargs-parser": { "version": "21.1.1", "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", diff --git a/package.json b/package.json index c6e043c..e22dfb9 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,6 @@ "@vitejs/plugin-vue": "^5.2.4", "eslint": "^9.26.0", "hot-hook": "^0.4.0", - "pino-pretty": "^13.0.0", "prettier": "^3.5.3", "ts-node-maintained": "^10.9.5", "typescript": "~5.8.3", @@ -64,11 +63,13 @@ "@inertiajs/vue3": "^2.0.11", "@vinejs/vine": "^3.0.1", "@vue/server-renderer": "^3.5.14", - "better-sqlite3": "^11.10.0", "edge.js": "^6.2.1", "luxon": "^3.6.1", + "pg": "^8.16.0", "reflect-metadata": "^0.2.2", - "vue": "^3.5.14" + "vue": "^3.5.14", + "pino-pretty": "^13.0.0" + }, "hotHook": { "boundaries": [ diff --git a/resources/views/inertia_layout.edge b/resources/views/inertia_layout.edge index 8669dc4..04cf565 100644 --- a/resources/views/inertia_layout.edge +++ b/resources/views/inertia_layout.edge @@ -1,72 +1,79 @@ - - - + + + - AdonisJS x Inertia x VueJS + + AdonisJS x Inertia x VueJS + - - + + - + - + - + colors: { + primary: { + DEFAULT: "#5A45FF" + }, + sand: { + 1: "var(--sand-1)", + 2: "var(--sand-2)", + 3: "var(--sand-3)", + 4: "var(--sand-4)", + 5: "var(--sand-5)", + 6: "var(--sand-6)", + 7: "var(--sand-7)", + 8: "var(--sand-8)", + 9: "var(--sand-9)", + 10: "var(--sand-10)", + 11: "var(--sand-11)", + 12: "var(--sand-12)" + } + } + } + } + }; + - @vite(['inertia/app/app.ts', `inertia/pages/${page.component}.vue`]) - @inertiaHead() - @stack('dumper') - + @vite(['inertia/app/app.ts', `inertia/pages/${page.component}.vue`]) + @inertiaHead() + @stack('dumper') + - - @inertia() - + + @inertia() + - \ No newline at end of file + diff --git a/start/kernel.ts b/start/kernel.ts index 888233a..17fb18e 100644 --- a/start/kernel.ts +++ b/start/kernel.ts @@ -27,7 +27,7 @@ server.use([ () => import('@adonisjs/static/static_middleware'), () => import('@adonisjs/cors/cors_middleware'), () => import('@adonisjs/vite/vite_middleware'), - () => import('@adonisjs/inertia/inertia_middleware') + () => import('@adonisjs/inertia/inertia_middleware'), ]) /** @@ -38,7 +38,7 @@ router.use([ () => import('@adonisjs/core/bodyparser_middleware'), () => import('@adonisjs/session/session_middleware'), () => import('@adonisjs/shield/shield_middleware'), - () => import('@adonisjs/auth/initialize_auth_middleware') + () => import('@adonisjs/auth/initialize_auth_middleware'), ]) /** @@ -47,5 +47,5 @@ router.use([ */ export const middleware = router.named({ guest: () => import('#middleware/guest_middleware'), - auth: () => import('#middleware/auth_middleware') + auth: () => import('#middleware/auth_middleware'), }) diff --git a/start/routes.ts b/start/routes.ts index 5b456af..9cc2ca5 100644 --- a/start/routes.ts +++ b/start/routes.ts @@ -7,6 +7,7 @@ | */ +import ReplaysController from '#controllers/replays_controller' import router from '@adonisjs/core/services/router' router.on('/').renderInertia('home') - +router.get('/replays', [ReplaysController, 'index']) diff --git a/vite.config.ts b/vite.config.ts index 479eded..3ea5c0f 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -5,7 +5,11 @@ import vue from '@vitejs/plugin-vue' import adonisjs from '@adonisjs/vite/client' export default defineConfig({ - plugins: [inertia({ ssr: { enabled: true, entrypoint: 'inertia/app/ssr.ts' } }), vue(), adonisjs({ entrypoints: ['inertia/app/app.ts'], reload: ['resources/views/**/*.edge'] })], + plugins: [ + inertia({ ssr: { enabled: true, entrypoint: 'inertia/app/ssr.ts' } }), + vue(), + adonisjs({ entrypoints: ['inertia/app/app.ts'], reload: ['resources/views/**/*.edge'] }), + ], /** * Define aliases for importing modules from