From 0553703145c8f062a1ce3810976a2fef50a7a6f8 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 19:45:39 +0000 Subject: [PATCH 01/39] portal: initial AdonisJS setup Based on Inertia+Vue starter kit, with changes to work with files organized by feature rather than type. --- .env.example | 15 +- .oxfmtrc.json | 2 +- .oxlintrc.json | 4 +- docker-compose.development.yml | 35 +- docker/development/caddy/config/Caddyfile | 23 + docker/development/devenv/Dockerfile | 2 +- docker/development/nginx/Dockerfile | 6 - docker/development/nginx/default.conf | 39 - pnpm-lock.yaml | 3752 ++++++++++++++++- pnpm-workspace.yaml | 3 + portal/.adonisjs/client/data.d.ts | 21 + portal/.adonisjs/client/manifest.d.ts | 10 + portal/.adonisjs/client/registry/index.ts | 29 + portal/.adonisjs/client/registry/schema.d.ts | 22 + portal/.adonisjs/client/registry/tree.d.ts | 8 + portal/.adonisjs/server/controllers.ts | 10 + portal/.adonisjs/server/events.ts | 6 + portal/.adonisjs/server/listeners.ts | 6 + portal/.adonisjs/server/pages.d.ts | 29 + portal/.adonisjs/server/routes.d.ts | 18 + portal/.env.example | 4 + portal/.env.test | 1 + portal/.gitignore | 7 + portal/ace.js | 27 + portal/adonisrc.ts | 169 + portal/app/exceptions/handler.ts | 45 + .../features/portalUsers/models/PortalUser.ts | 22 + .../transformers/PortalUserTransformer.ts | 14 + .../splash/controllers/SplashController.ts | 7 + portal/app/middleware/authMiddleware.ts | 16 + .../middleware/containerBindingsMiddleware.ts | 19 + portal/app/middleware/guestMiddleware.ts | 32 + portal/app/middleware/inertiaMiddleware.ts | 62 + portal/app/middleware/silentAuthMiddleware.ts | 16 + portal/bin/console.ts | 47 + portal/bin/server.ts | 45 + portal/bin/test.ts | 62 + portal/config/app.ts | 80 + portal/config/auth.ts | 39 + portal/config/bodyparser.ts | 78 + portal/config/cors.ts | 50 + portal/config/database.ts | 44 + portal/config/encryption.ts | 34 + portal/config/hash.ts | 75 + portal/config/inertia.ts | 20 + portal/config/logger.ts | 50 + portal/config/redis.ts | 28 + portal/config/session.ts | 71 + portal/config/shield.ts | 95 + portal/config/static.ts | 32 + portal/config/vite.ts | 34 + portal/database/migrations/.gitkeep | 3 + portal/database/schema.ts | 25 + portal/database/schemaRules.ts | 3 + portal/hooks/indexInertiaPages.ts | 47 + portal/inertia/app.ts | 26 + portal/inertia/client.ts | 9 + .../features/errors/pages/NotFound.vue | 3 + .../features/errors/pages/ServerError.vue | 3 + .../features/splash/pages/SplashIndex.vue | 12 + .../inertia/features/toasts/FlashToasts.vue | 33 + portal/inertia/layouts/app.vue | 10 + portal/inertia/shims.ts | 5 + portal/inertia/ssr.ts | 24 + portal/inertia/tsconfig.json | 14 + portal/inertia/types.ts | 14 + portal/package.json | 86 + portal/providers/apiProvider.ts | 69 + portal/start/env.ts | 29 + portal/start/kernel.ts | 35 + portal/start/routes.ts | 33 + portal/start/validator.ts | 23 + portal/tests/bootstrap.ts | 38 + portal/tmp/.gitkeep | 0 portal/tsconfig.inertia.json | 8 + portal/tsconfig.json | 8 + portal/vite.config.ts | 23 + 77 files changed, 5840 insertions(+), 108 deletions(-) create mode 100644 docker/development/caddy/config/Caddyfile delete mode 100644 docker/development/nginx/Dockerfile delete mode 100644 docker/development/nginx/default.conf create mode 100644 portal/.adonisjs/client/data.d.ts create mode 100644 portal/.adonisjs/client/manifest.d.ts create mode 100644 portal/.adonisjs/client/registry/index.ts create mode 100644 portal/.adonisjs/client/registry/schema.d.ts create mode 100644 portal/.adonisjs/client/registry/tree.d.ts create mode 100644 portal/.adonisjs/server/controllers.ts create mode 100644 portal/.adonisjs/server/events.ts create mode 100644 portal/.adonisjs/server/listeners.ts create mode 100644 portal/.adonisjs/server/pages.d.ts create mode 100644 portal/.adonisjs/server/routes.d.ts create mode 100644 portal/.env.example create mode 100644 portal/.env.test create mode 100644 portal/.gitignore create mode 100644 portal/ace.js create mode 100644 portal/adonisrc.ts create mode 100644 portal/app/exceptions/handler.ts create mode 100644 portal/app/features/portalUsers/models/PortalUser.ts create mode 100644 portal/app/features/portalUsers/transformers/PortalUserTransformer.ts create mode 100644 portal/app/features/splash/controllers/SplashController.ts create mode 100644 portal/app/middleware/authMiddleware.ts create mode 100644 portal/app/middleware/containerBindingsMiddleware.ts create mode 100644 portal/app/middleware/guestMiddleware.ts create mode 100644 portal/app/middleware/inertiaMiddleware.ts create mode 100644 portal/app/middleware/silentAuthMiddleware.ts create mode 100644 portal/bin/console.ts create mode 100644 portal/bin/server.ts create mode 100644 portal/bin/test.ts create mode 100644 portal/config/app.ts create mode 100644 portal/config/auth.ts create mode 100644 portal/config/bodyparser.ts create mode 100644 portal/config/cors.ts create mode 100644 portal/config/database.ts create mode 100644 portal/config/encryption.ts create mode 100644 portal/config/hash.ts create mode 100644 portal/config/inertia.ts create mode 100644 portal/config/logger.ts create mode 100644 portal/config/redis.ts create mode 100644 portal/config/session.ts create mode 100644 portal/config/shield.ts create mode 100644 portal/config/static.ts create mode 100644 portal/config/vite.ts create mode 100644 portal/database/migrations/.gitkeep create mode 100644 portal/database/schema.ts create mode 100644 portal/database/schemaRules.ts create mode 100644 portal/hooks/indexInertiaPages.ts create mode 100644 portal/inertia/app.ts create mode 100644 portal/inertia/client.ts create mode 100644 portal/inertia/features/errors/pages/NotFound.vue create mode 100644 portal/inertia/features/errors/pages/ServerError.vue create mode 100644 portal/inertia/features/splash/pages/SplashIndex.vue create mode 100644 portal/inertia/features/toasts/FlashToasts.vue create mode 100644 portal/inertia/layouts/app.vue create mode 100644 portal/inertia/shims.ts create mode 100644 portal/inertia/ssr.ts create mode 100644 portal/inertia/tsconfig.json create mode 100644 portal/inertia/types.ts create mode 100644 portal/package.json create mode 100644 portal/providers/apiProvider.ts create mode 100644 portal/start/env.ts create mode 100644 portal/start/kernel.ts create mode 100644 portal/start/routes.ts create mode 100644 portal/start/validator.ts create mode 100644 portal/tests/bootstrap.ts create mode 100644 portal/tmp/.gitkeep create mode 100644 portal/tsconfig.inertia.json create mode 100644 portal/tsconfig.json create mode 100644 portal/vite.config.ts diff --git a/.env.example b/.env.example index ecd00c857..89c8b897d 100644 --- a/.env.example +++ b/.env.example @@ -32,9 +32,16 @@ DEFAULT_ALLOWED_SERVERS= # NOTE: You only need to fill in these values for running the development environment # ========================== +# Host to bind the various exposed devenv ports on +# The default value of "127.0.0.1" only allows access from the local machine +DEVELOPMENT_BIND_HOST=127.0.0.1 + +# Legacy dashboard port DEVELOPMENT_WEB_PORT=3300 +# Modern portal port +DEVELOPMENT_PORTAL_PORT=3400 -# The MySQL database running in the container is exposed to the host on this port, +# The MySQL database running in the container is exposed on this port, # allowing access with database tools such as DBeaver DEVELOPMENT_MYSQL_PORT=3356 # Password for the Zeppelin database user @@ -43,10 +50,14 @@ DEVELOPMENT_MYSQL_PASSWORD=password DEVELOPMENT_MYSQL_ROOT_PASSWORD=password # The development environment container has an SSH server that you can connect to. -# This is the port that server is exposed to the host on. +# This is the port that server is exposed on. DEVELOPMENT_SSH_PORT=3022 DEVELOPMENT_SSH_PASSWORD=password +# If you're accessing the Vite devserver for the portal using a domain rather than IP, add it here. +# Multiple domains supported when separated by commas. +DEVELOPMENT_VITE_ALLOWED_HOSTS= + # If using the cftunnel docker compose profile, set your Cloudflare Tunnel token here #CF_TUNNEL_TOKEN= diff --git a/.oxfmtrc.json b/.oxfmtrc.json index 33fcf9575..ba81b9fd7 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -1,5 +1,5 @@ { "$schema": "./node_modules/oxfmt/configuration_schema.json", - "ignorePatterns": ["dist/**", "*.min.js", "*.yml", "*.yaml", "*.json", "LICENSE.md"], + "ignorePatterns": ["dist/**", "*.min.js", "*.yml", "*.yaml", "*.json", "LICENSE.md", ".adonisjs/**", "public/assets/**"], "printWidth": 120 } diff --git a/.oxlintrc.json b/.oxlintrc.json index fc705770e..ba31af1d3 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,6 +1,6 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", - "ignorePatterns": ["dist/**", "*.min.js", "dashboard/src/**"], + "ignorePatterns": ["dist/**", "*.min.js", "dashboard/src/**", ".adonisjs/**", "public/assets/**"], "plugins": [ "typescript", "unicorn", @@ -13,4 +13,4 @@ "env": { "builtin": true } -} \ No newline at end of file +} diff --git a/docker-compose.development.yml b/docker-compose.development.yml index fb1c9dec8..78b09b00d 100644 --- a/docker-compose.development.yml +++ b/docker-compose.development.yml @@ -5,31 +5,44 @@ volumes: untrusted-home: {} mysql-data: {} redis-data: {} + caddy-data: {} services: - nginx: - build: - context: ./docker/development/nginx - args: - DEVELOPMENT_WEB_PORT: ${DEVELOPMENT_WEB_PORT:?Missing DEVELOPMENT_WEB_PORT} + caddy: + image: caddy:2 + pull_policy: daily ports: - - "${DEVELOPMENT_WEB_PORT:?Missing DEVELOPMENT_WEB_PORT}:443" + - "${DEVELOPMENT_BIND_HOST:-127.0.0.1}:${DEVELOPMENT_WEB_PORT:?Missing DEVELOPMENT_WEB_PORT}:443" + - "${DEVELOPMENT_BIND_HOST:-127.0.0.1}:${DEVELOPMENT_PORTAL_PORT:?Missing DEVELOPMENT_PORTAL_PORT}:444" + volumes: + - ./docker/development/caddy/config:/etc/caddy + - caddy-data:/data + # Mount host tailscale dir for tailscale cert support + # Creates an empty dir on host if it doesn't already exist + # Probably doesn't work on Windows but who cares + - type: bind + source: /var/run/tailscale + target: /var/run/tailscale + read_only: true + bind: + create_host_path: true mysql: - image: mysql:8.0 + image: mysql:8 + pull_policy: daily environment: MYSQL_ROOT_PASSWORD: ${DEVELOPMENT_MYSQL_ROOT_PASSWORD?:Missing DEVELOPMENT_MYSQL_ROOT_PASSWORD} MYSQL_DATABASE: zeppelin MYSQL_USER: zeppelin MYSQL_PASSWORD: ${DEVELOPMENT_MYSQL_PASSWORD?:Missing DEVELOPMENT_MYSQL_PASSWORD} ports: - - "127.0.0.1:${DEVELOPMENT_MYSQL_PORT:?Missing DEVELOPMENT_MYSQL_PORT}:3306" + - "${DEVELOPMENT_BIND_HOST:-127.0.0.1}:${DEVELOPMENT_MYSQL_PORT:?Missing DEVELOPMENT_MYSQL_PORT}:3306" volumes: - mysql-data:/var/lib/mysql - command: --authentication-policy=mysql_native_password redis: - image: redis:8.2.3 + image: redis:8 + pull_policy: daily volumes: - redis-data:/data @@ -40,7 +53,7 @@ services: environment: DEVELOPMENT_SSH_PASSWORD: ${DEVELOPMENT_SSH_PASSWORD:?Missing DEVELOPMENT_SSH_PASSWORD} ports: - - "127.0.0.1:${DEVELOPMENT_SSH_PORT:?Missing DEVELOPMENT_SSH_PORT}:22" + - "${DEVELOPMENT_BIND_HOST:-127.0.0.1}:${DEVELOPMENT_SSH_PORT:?Missing DEVELOPMENT_SSH_PORT}:22" volumes: - home:/home/dev - ./:/workspace/zeppelin diff --git a/docker/development/caddy/config/Caddyfile b/docker/development/caddy/config/Caddyfile new file mode 100644 index 000000000..b0595ce6c --- /dev/null +++ b/docker/development/caddy/config/Caddyfile @@ -0,0 +1,23 @@ +# Dashboard + API +https://:443 { + tls internal { + on_demand + } + + @api path /api /api/* + handle @api { + reverse_proxy devenv:3002 + } + + handle { + reverse_proxy devenv:3001 + } +} + +# Portal +https://:444 { + tls internal { + on_demand + } + reverse_proxy devenv:3003 +} diff --git a/docker/development/devenv/Dockerfile b/docker/development/devenv/Dockerfile index 4976c78ef..1bfda0eec 100644 --- a/docker/development/devenv/Dockerfile +++ b/docker/development/devenv/Dockerfile @@ -14,7 +14,7 @@ RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - RUN apt-get install -y nodejs gcc g++ make python3 # Install pnpm -RUN npm install -g pnpm@11.19.0 +RUN npm install -g --min-release-age=7 pnpm # Delete default sudo user and create unprivileged user RUN userdel -r ubuntu diff --git a/docker/development/nginx/Dockerfile b/docker/development/nginx/Dockerfile deleted file mode 100644 index 602a70773..000000000 --- a/docker/development/nginx/Dockerfile +++ /dev/null @@ -1,6 +0,0 @@ -FROM nginx - -RUN apt-get update && apt-get install -y openssl -RUN openssl req -x509 -newkey rsa:4096 -keyout /etc/ssl/private/localhost-cert.key -out /etc/ssl/certs/localhost-cert.pem -days 3650 -subj '/CN=localhost' -nodes - -COPY ./default.conf /etc/nginx/conf.d/default.conf diff --git a/docker/development/nginx/default.conf b/docker/development/nginx/default.conf deleted file mode 100644 index 2b2070dde..000000000 --- a/docker/development/nginx/default.conf +++ /dev/null @@ -1,39 +0,0 @@ -server { - listen 443 ssl http2; - listen [::]:443 ssl http2; - server_name localhost; - - # Using a variable here stops nginx from crashing if the dev container is restarted or becomes otherwise unavailable - set $backend_upstream "http://devenv:3001"; - set $dashboard_upstream "http://devenv:3002"; - - location / { - # Using a variable in proxy_pass also requires resolver to be set. - # This is the address of the internal docker compose DNS server. - resolver 127.0.0.11; - proxy_pass $dashboard_upstream$uri$is_args$args; - proxy_set_header Upgrade $http_upgrade; - proxy_set_header Connection "upgrade"; - proxy_set_header Host $host; - proxy_http_version 1.1; - proxy_cache_bypass $http_upgrade; - } - - location /api { - resolver 127.0.0.11; - proxy_pass $backend_upstream$uri$is_args$args; - proxy_redirect off; - - client_max_body_size 200M; - } - - ssl_certificate /etc/ssl/certs/localhost-cert.pem; - ssl_certificate_key /etc/ssl/private/localhost-cert.key; - - ssl_session_timeout 1d; - ssl_session_cache shared:MozSSL:10m; - ssl_session_tickets off; - - ssl_protocols TLSv1.3; - ssl_prefer_server_ciphers off; -} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index b40cca622..9516d425a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -72,7 +72,7 @@ importers: version: 1.0.5 express: specifier: ^4.20.0 - version: 4.22.2 + version: 4.22.2(supports-color@10.2.2) fp-ts: specifier: ^2.0.1 version: 2.16.11 @@ -132,7 +132,7 @@ importers: version: 1.0.0 threads: specifier: ^1.7.0 - version: 1.7.0 + version: 1.7.0(supports-color@10.2.2) tlds: specifier: ^1.221.1 version: 1.261.0 @@ -147,7 +147,7 @@ importers: version: 12.1.6 typeorm: specifier: ^0.3.27 - version: 0.3.31(mysql2@3.23.0(@types/node@24.13.3))(redis@5.12.1) + version: 0.3.31(mysql2@3.23.0(@types/node@24.13.3))(redis@5.12.1)(supports-color@10.2.2) utf-8-validate: specifier: ^5.0.5 version: 5.0.10 @@ -199,7 +199,7 @@ importers: version: 9.0.8 ava: specifier: ^5.3.1 - version: 5.3.1 + version: 5.3.1(supports-color@10.2.2) source-map-support: specifier: ^0.5.16 version: 0.5.21 @@ -302,17 +302,533 @@ importers: specifier: ^4.1.0 version: 4.1.0(vue@3.5.40(typescript@6.0.3)) + portal: + dependencies: + '@adonisjs/auth': + specifier: ^10.1.0 + version: 10.1.0(c16d739126567016c4d2c00b96bddf22) + '@adonisjs/core': + specifier: ^7.5.2 + version: 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@adonisjs/cors': + specifier: ^3.0.0 + version: 3.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1)) + '@adonisjs/inertia': + specifier: ^5.0.1 + version: 5.0.1(3f17abe654a593f174d8c7d5a3b95857) + '@adonisjs/lucid': + specifier: ^22.4.2 + version: 22.4.2(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@vinejs/vine@4.4.0)(luxon@3.7.2)(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2) + '@adonisjs/redis': + specifier: ^11.0.0 + version: 11.0.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(supports-color@10.2.2) + '@adonisjs/session': + specifier: ^8.1.0 + version: 8.1.0(770cc5139ed8289213226f432e14c982) + '@adonisjs/shield': + specifier: ^9.0.0 + version: 9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1) + '@adonisjs/static': + specifier: ^2.0.1 + version: 2.0.1(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(supports-color@10.2.2) + '@adonisjs/vite': + specifier: ^6.0.2 + version: 6.0.3(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/shield@9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1))(edge.js@6.5.1)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0)) + '@inertiajs/core': + specifier: ^3.7.1 + version: 3.9.1 + '@inertiajs/vue3': + specifier: ^3.7.1 + version: 3.9.1(vue@3.5.43(typescript@6.0.3)) + '@tuyau/core': + specifier: ^1.2.2 + version: 1.2.2(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1)) + '@vinejs/vine': + specifier: ^4.4.0 + version: 4.4.0 + '@vue/server-renderer': + specifier: ^3.5.43 + version: 3.5.43 + edge.js: + specifier: ^6.5.1 + version: 6.5.1 + lucide-vue-next: + specifier: ^1.0.0 + version: 1.0.0(vue@3.5.43(typescript@6.0.3)) + luxon: + specifier: ^3.7.2 + version: 3.7.2 + mysql2: + specifier: ^3.23.0 + version: 3.23.0(@types/node@26.6.5) + reflect-metadata: + specifier: ^0.2.2 + version: 0.2.2 + vue: + specifier: ^3.5.43 + version: 3.5.43(typescript@6.0.3) + vue-sonner: + specifier: ^2.0.9 + version: 2.0.9 + devDependencies: + '@adonisjs/assembler': + specifier: ^8.5.2 + version: 8.5.2(typescript@6.0.3) + '@adonisjs/prettier-config': + specifier: ^1.5.0 + version: 1.5.0(prettier@3.9.6) + '@adonisjs/tsconfig': + specifier: ^2.0.0 + version: 2.0.0 + '@japa/assert': + specifier: ^4.2.0 + version: 4.2.0(@japa/runner@5.3.0) + '@japa/browser-client': + specifier: ^2.3.0 + version: 2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0) + '@japa/plugin-adonisjs': + specifier: ^5.2.0 + version: 5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0) + '@japa/runner': + specifier: ^5.3.0 + version: 5.3.0 + '@poppinss/ts-exec': + specifier: ^1.4.4 + version: 1.5.0 + '@types/luxon': + specifier: ^3.7.5 + version: 3.7.6 + '@types/node': + specifier: ~26.6.2 + version: 26.6.5 + '@vitejs/plugin-vue': + specifier: ^6.0.9 + version: 6.0.10(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.43(typescript@6.0.3)) + hot-hook: + specifier: ^1.0.0 + version: 1.0.0 + pino-pretty: + specifier: ^13.1.3 + version: 13.2.0 + typescript: + specifier: catalog:ts6 + version: 6.0.3 + vite: + specifier: ^8.3.0 + version: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0) + vue-tsc: + specifier: ^3.3.11 + version: 3.3.13(typescript@6.0.3) + youch: + specifier: ^4.1.1 + version: 4.1.1 + shared: devDependencies: ava: specifier: ^5.3.1 - version: 5.3.1 + version: 5.3.1(supports-color@10.2.2) typescript: specifier: catalog:ts7 version: 7.0.2 packages: + '@adonisjs/ace@14.1.1': + resolution: {integrity: sha512-6MP2eZicAP8hd1US1PR2b6hEzWVaNlEbbAxanwDAyTOMW8PysefQam7b59ipbxw4+ADTJsgIyQWVt815W9f6WQ==} + engines: {node: '>=24.0.0'} + peerDependencies: + youch: ^4.1.0-beta.11 || ^4.1.0 + + '@adonisjs/application@9.1.0': + resolution: {integrity: sha512-KWsTfkITDozW4csD4YofDEbbWuORKI056VgEr9WBwjIdrzIC7hqPxLtnszFVmyv14THPi0SRBTN/fIYQ6/SQ4Q==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.23 || ^8.0.0 + '@adonisjs/config': ^6.1.0-next.0 || ^6.0.0 + '@adonisjs/fold': ^11.0.0-next.3 || ^11.0.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + + '@adonisjs/assembler@8.5.2': + resolution: {integrity: sha512-CipLZEl/2zBa6ejoMogXsXAg4+8hIf0CAhRaHjf9KXfeUininRc9Wg3zFv+To1xgHLjnuPiQfqKBhP6I44KVlA==} + engines: {node: '>=24.0.0'} + peerDependencies: + typescript: ^5.0.0 || ^6.0.0 + + '@adonisjs/auth@10.1.0': + resolution: {integrity: sha512-H92C4HLWBpvxtQrgnsdWdWfoGu2bM/j+nyk/tHmpxH9ETkNOH0z3dRfEebLJI63vtTDpRp5cwiI0bzn32gUQiA==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.26 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.16 || ^7.0.0 + '@adonisjs/i18n': ^3.0.0-next.2 || ^3.0.0 + '@adonisjs/lucid': ^22.0.0-next.1 || ^22.0.0 + '@adonisjs/session': ^8.0.0-next.1 || ^8.0.0 + '@japa/api-client': ^3.1.1 + '@japa/browser-client': ^2.2.0 + '@japa/plugin-adonisjs': ^5.1.0-next.0 || ^5.1.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@adonisjs/i18n': + optional: true + '@adonisjs/lucid': + optional: true + '@adonisjs/session': + optional: true + '@japa/api-client': + optional: true + '@japa/browser-client': + optional: true + '@japa/plugin-adonisjs': + optional: true + + '@adonisjs/bodyparser@11.0.4': + resolution: {integrity: sha512-amqMPVFbzxkOoCMbkFs5sC+rTu7cER2rSv+1v8dsGKszolk5lnGuyNjkha1Lqksvw1qykIIbC1fXr37B9WJTdg==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/http-server': ^8.0.0-next.17 || ^8.0.0 || ^9.0.0 + + '@adonisjs/config@6.1.0': + resolution: {integrity: sha512-YVDRL8xHCtM6iMnAefOBaz6iXVpojwBPDQWPKxnVSucycYeNGrGitJiLy+cGaeAU7Gjm8al9SJRJt3rRPr5PKg==} + engines: {node: '>=24.0.0'} + + '@adonisjs/core@7.6.0': + resolution: {integrity: sha512-DGDkpoNrExwLhhmuzZBaOKe6wk67HI/0+3GLWsJXB+Ze4NjXuKKOT5169R2CqpSO6yvL1Xw39HwSJ9YJ1oTvLg==} + engines: {node: '>=24.0.0'} + hasBin: true + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.23 || ^8.0.0 + '@vinejs/vine': ^4.0.0 + argon2: ^0.44.0 || ^0.45.1 + bcrypt: ^6.0.0 + edge.js: ^6.2.0 + pino-pretty: ^13.1.3 + youch: ^4.1.0-beta.13 || ^4.1.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@vinejs/vine': + optional: true + argon2: + optional: true + bcrypt: + optional: true + edge.js: + optional: true + pino-pretty: + optional: true + youch: + optional: true + + '@adonisjs/cors@3.0.0': + resolution: {integrity: sha512-S3LS+zZ2SziwVvilnkKg4DjmU+df1xqdZRDSQjUKJr5hYEOVAlnci0kHTiz2szxB+QiseQXr/XfN/D5ooMMlYQ==} + engines: {node: '>=18.16.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.7 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.0 || ^7.0.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + + '@adonisjs/env@7.1.0': + resolution: {integrity: sha512-DXKCDIDoHzjxx9O7HvFYYBGQENmF5ANTUXBGE65ygOcJTtXyrLBISUkjrIQGVAKUmcLPF9WInkXQfxMnfO2VJw==} + engines: {node: '>=24.0.0'} + + '@adonisjs/events@10.2.0': + resolution: {integrity: sha512-SzwzbmTLsybSZd47zZMZ3df7puwhY7D8vZ5Uy79SiHjLKbr2eVzUuKjjoYB6/0pZu6IwK9Qx06dI43sl+tLoDw==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/application': ^9.0.0-next.14 || ^9.0.0 + '@adonisjs/fold': ^11.0.0-next.4 || ^11.0.0 + + '@adonisjs/fold@11.1.0': + resolution: {integrity: sha512-M3/AUZ6w8s/3uLJ4RBPwkzpOaXAdYh1EezRA11j+S9/WfUyxx4aiIm9FpjitSJC1Hrc5ap6AqlYu2m6dfzHVRA==} + engines: {node: '>=24.0.0'} + + '@adonisjs/hash@10.1.1': + resolution: {integrity: sha512-i12srCoJ2uomD8fTMPEp16lcRTsB9pI8AlGFrtkrq7xcoLPBVi67lovXkdS6BNHdvdciH9HLcRe73KB2kUvgfw==} + engines: {node: '>=20.6.0'} + peerDependencies: + argon2: ^0.31.2 || ^0.41.0 || ^0.43.0 || ^0.44.0 || ^0.45.1 + bcrypt: ^5.1.1 || ^6.0.0 + peerDependenciesMeta: + argon2: + optional: true + bcrypt: + optional: true + + '@adonisjs/health@3.1.0': + resolution: {integrity: sha512-m3doBnSwi/l9v1DO79xmjAoSPl9b2XCp+crGwF8QUlhe5CgWgtfnL0SeFNEiZGliD3c4gYdihKz4Pnydctva8A==} + engines: {node: '>=24.0.0'} + + '@adonisjs/http-server@9.3.1': + resolution: {integrity: sha512-SX3JATI2PtSNYYia/I0rfJvUR4IHJ9GSluORTIwLfwpqi01nVkkXdokxea9XVh4Wn1z4OOIXy/5gfa8OlFrBxQ==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/application': ^9.0.0-next.14 || ^9.0.0 + '@adonisjs/events': ^10.1.0-next.4 || ^10.1.0 + '@adonisjs/fold': ^11.0.0-next.4 || ^11.0.0 + '@adonisjs/logger': ^7.1.0-next.3 || ^7.1.0 + '@boringnode/encryption': ^0.2.0 || ^1.0.0 + youch: ^4.1.0-beta.13 || ^4.1.0 + peerDependenciesMeta: + youch: + optional: true + + '@adonisjs/http-transformers@2.3.1': + resolution: {integrity: sha512-N3gBcKyoPHDeVvVIedTzc+ARSUURwNGTPid/e3iLdM4v/myoSnXd76FL/GGzMmjfqqxegpjI2IEMibG7ylrKSQ==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/fold': ^11.0.0-next.2 + + '@adonisjs/inertia@5.0.1': + resolution: {integrity: sha512-UuENysVrnTTuaupY+ltzFDsa9lBS0NDa9PV27KxpyxgQcwCP9S88ZQYe9MJosEzz8NVoDLd0CjkNMilXxknXCA==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.29 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.23 || ^7.0.0 + '@adonisjs/session': ^8.0.0-next.2 || ^8.0.0 + '@adonisjs/vite': ^6.0.0-next.0 || ^6.0.0 + '@inertiajs/core': ^3.4.0 + '@inertiajs/react': ^3.4.0 + '@inertiajs/vue3': ^3.4.0 + '@japa/api-client': ^3.1.1 + '@japa/plugin-adonisjs': ^5.1.0-next.1 || ^5.1.0 + '@tuyau/core': ^1.0.0-beta.10 || ^1.0.0 + edge.js: ^6.4.0 + react: ^19.2.3 + vue: ^3.5.17 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@inertiajs/core': + optional: true + '@inertiajs/react': + optional: true + '@inertiajs/vue3': + optional: true + '@japa/api-client': + optional: true + '@japa/plugin-adonisjs': + optional: true + '@tuyau/core': + optional: true + react: + optional: true + vue: + optional: true + + '@adonisjs/logger@7.1.1': + resolution: {integrity: sha512-MmUlp8xBMT6zZy0+vnQcQjHIlNfU4pUJARlINr7Bqha9BvhIn03QZgJL5QJ+kJe1tl6ZpNAryoRTJUiOk/wINQ==} + engines: {node: '>=24.0.0'} + peerDependencies: + pino-pretty: ^13.1.1 + peerDependenciesMeta: + pino-pretty: + optional: true + + '@adonisjs/lucid@22.4.2': + resolution: {integrity: sha512-3ztENqBQIFSGAWREHKCGbL1g4ehtsxxsuFX72Uf5bq+oSc0D6UcumjzYpU8TPyBxhmgS6HuRSfz2rG42iuz7AA==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.29 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.21 || ^7.0.0 + '@vinejs/vine': ^3.0.0 || ^4.0.0 + luxon: ^3.4.4 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@vinejs/vine': + optional: true + luxon: + optional: true + + '@adonisjs/presets@3.0.0': + resolution: {integrity: sha512-+gVIvyEiM7jiN5Gb93200TAC8ed3vZIPfxFFo0pIVgX8k40BleuYhWxFhI6TPocVXXIIpw2JuMFV2Pqjk36W2A==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.9 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.1 || ^7.0.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + + '@adonisjs/prettier-config@1.5.0': + resolution: {integrity: sha512-im5V503HAaWSqmDWXV3k40KMCXvgurGNExkjGjvEkl2N7Wp+RcBN3pC6PAWUA1j4iukp4azzuuuR2tPFgnIkbA==} + + '@adonisjs/redis@11.0.0': + resolution: {integrity: sha512-NXPzn8fC7fjRRbuRC9nVIvEQyuZrf45OFH2sp2EU0MUuMO/Y7CSORHeFfe9TxJQOutmeOwwGoyXgWIh6owfi4w==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/core': ^7.0.0-next.0 || ^7.0.0 + + '@adonisjs/repl@5.0.0': + resolution: {integrity: sha512-cPp0w5svYUA3M1gdxQBO2Mx5g+SZfPweqKCAxk7C1Os/Qu67JKgWqXqNnl1q0Tzv/l0L19Ms1C7ivzQxeBNajg==} + engines: {node: '>=24.0.0'} + + '@adonisjs/session@8.1.0': + resolution: {integrity: sha512-hTd5m49Ro8XhxVQN0yyCeDOihDhj+mFIVltzeWPXkCxK19JHAtA++TAygxSUEhvcm56IVS43XWNE1lNIOPjMJA==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.26 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.16 || ^7.0.0 + '@adonisjs/lucid': ^22.0.0-next.0 || ^22.0.0 + '@adonisjs/redis': ^10.0.0-next.2 || ^10.0.0 + '@aws-sdk/client-dynamodb': ^3.955.0 + '@aws-sdk/util-dynamodb': ^3.955.0 + '@japa/api-client': ^3.1.0 + '@japa/browser-client': ^2.0.3 + '@japa/plugin-adonisjs': ^5.1.0-next.0 || ^5.1.0 + edge.js: ^6.4.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@adonisjs/lucid': + optional: true + '@adonisjs/redis': + optional: true + '@aws-sdk/client-dynamodb': + optional: true + '@aws-sdk/util-dynamodb': + optional: true + '@japa/api-client': + optional: true + '@japa/browser-client': + optional: true + '@japa/plugin-adonisjs': + optional: true + edge.js: + optional: true + + '@adonisjs/shield@9.0.0': + resolution: {integrity: sha512-RmupWRspYGyzS/fAC0QspL7+Uhp6IaidvxE4CYbuqO43PBPCxhC47VjXML720B8hcps7ClK9RWjdMiJkUrn7fA==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.26 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.16 || ^7.0.0 + '@adonisjs/i18n': ^3.0.0-next.2 || ^3.0.0 + '@adonisjs/session': ^8.0.0-next.1 || ^8.0.0 + '@japa/api-client': ^3.1.1 + '@japa/plugin-adonisjs': ^5.1.0-next.0 || ^5.1.0 + edge.js: ^6.4.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@adonisjs/i18n': + optional: true + '@japa/api-client': + optional: true + '@japa/plugin-adonisjs': + optional: true + edge.js: + optional: true + + '@adonisjs/static@2.0.1': + resolution: {integrity: sha512-pXSyQgha1yfyQDXPp0ywv7hJqk4JgCCkzWLkku2PW3Y6i/9GUTyzzNTCpz29loZzSF0b/EpiHXQE/sqBhW+p7w==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.7 || ^8.0.0 + '@adonisjs/core': ^7.0.0-next.0 || ^7.0.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + + '@adonisjs/tsconfig@2.0.0': + resolution: {integrity: sha512-Uz8qvB6KR9otCh9zei2VEj7tPwdsrT7R+voYoN4tUfEijWRdTNgJ8d1CtyLKHaggCCOwZIwZLVklV/h2FDHgNw==} + + '@adonisjs/vite@6.0.3': + resolution: {integrity: sha512-LmY5Zqj1hPZTaqFrLzTSDyCe+15j+9zz4o3Bh+gCnmZAHJyIhDmyyDnBsNzcQ4qgXMAQDhLLKmteXTpFjFloOg==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.10 || ^8.0.0 + '@adonisjs/core': ^7.5.0 + '@adonisjs/shield': ^9.0.0-next.0 || ^9.0.0 + edge.js: ^6.0.1 + vite: ^8.0.0 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@adonisjs/shield': + optional: true + edge.js: + optional: true + + '@antfu/install-pkg@2.1.0': + resolution: {integrity: sha512-sdg9NxU3zR4Mnawfbc/x6GB5Wf17WYud5qOuEuxXjaKpYpMkISSJEjItGebXJ2bQ4DIcly4NYH23mtkGJjvKUw==} + + '@arr/every@1.0.1': + resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==} + engines: {node: '>=4'} + + '@ast-grep/napi-darwin-arm64@0.45.3': + resolution: {integrity: sha512-rMZJ6frSpR/xSbeV4hiA9WR5hHqk3rVYX8lOqEoUCaUnjEuFXvHdGN4WawJ8pVDq/IqM1UnTtsDSYgUdVmO5DA==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [darwin] + + '@ast-grep/napi-darwin-x64@0.45.3': + resolution: {integrity: sha512-tIclZ5pM+YSgk8NNTBoTkaclbS39cU5lbVfSrFWX4LUnxXfUPG+F+ppxyFjKwJTBELsGHEO4LdX3/Lc+FDwPNA==} + engines: {node: '>= 10'} + cpu: [x64] + os: [darwin] + + '@ast-grep/napi-linux-arm64-gnu@0.45.3': + resolution: {integrity: sha512-Bm8F7/oRHQkDXbjH+gBi9oB5huJ0q12r/AIOMIypf5PWlAVvh206Tsw468phw4Oh6kd4Ad1Z+gflNW1MutgK2g==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@ast-grep/napi-linux-arm64-musl@0.45.3': + resolution: {integrity: sha512-yr5xcRerV41GeRxmZ8SKbfGeyZRhQePoNNCgTAb4OrWMelWwbMI80aY7/IlF2bo1sN40BSW4hZdGIO/akTd1RQ==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@ast-grep/napi-linux-x64-gnu@0.45.3': + resolution: {integrity: sha512-lluRK3hxfHMQdFuVID6seAKVx4FH0kEwF6rCh5/I40Sf3EtNR2UCBXAqd6RBA6hqlSckktvBxCfw+h4aescDmg==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@ast-grep/napi-linux-x64-musl@0.45.3': + resolution: {integrity: sha512-09wJQKq86LqILqQtw0+X09SzhcPwUnMVFKyia7S3XLbLqSeQpAMF55Y+zll53JRQ1dCzFEZJyvTT/7j9vwfE3w==} + engines: {node: '>= 10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@ast-grep/napi-win32-arm64-msvc@0.45.3': + resolution: {integrity: sha512-/HiVgw2cdtzXLDLoG4eBBcauekNXewfagy7qiVbjkVu/KcCH8dJ9lpj8DzeWwuBNtZxuD8jpiwP0M1pz3Bc3uw==} + engines: {node: '>= 10'} + cpu: [arm64] + os: [win32] + + '@ast-grep/napi-win32-ia32-msvc@0.45.3': + resolution: {integrity: sha512-/gwJrJQUw65uNtAFcG2rtSTr117Gqqy3bfjaljCPKsa65dTeRcMMnjKLlZ6V9/g8z+4Xf78kdhp5ECbir4yfSw==} + engines: {node: '>= 10'} + cpu: [ia32] + os: [win32] + + '@ast-grep/napi-win32-x64-msvc@0.45.3': + resolution: {integrity: sha512-CEZAMAsaDoQoVE3MT2c/ry3/ydfyaqlTjxv8DK5PG355SrdAYPgevGC2Me6tz4dhphJin89Y20VsnrS5UrYV5Q==} + engines: {node: '>= 10'} + cpu: [x64] + os: [win32] + + '@ast-grep/napi@0.45.3': + resolution: {integrity: sha512-bjJsUt0g3UCwbn9bjv7MnoR15rszSm79yPCXn4DWWK0NuYUUqBU/srtNMR4WnpfR7TnfBRdYFoqSNx0pGCNWJg==} + engines: {node: '>= 10'} + + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} + engines: {node: '>=6.9.0'} + '@babel/helper-string-parser@7.29.7': resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} engines: {node: '>=6.9.0'} @@ -326,10 +842,34 @@ packages: engines: {node: '>=6.0.0'} hasBin: true + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} + engines: {node: '>=6.0.0'} + hasBin: true + '@babel/types@7.29.7': resolution: {integrity: sha512-4zBIxpPzowiZpusoFkyGVwakdRJUyuH5PxQ/PrqghfdFWWasvnCdPfQXHrenDai+gyLARulZjZowCOj6fjT4pA==} engines: {node: '>=6.9.0'} + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@borewit/text-codec@0.2.2': + resolution: {integrity: sha512-DDaRehssg1aNrH4+2hnj1B7vnUGEjU6OIlyRdkMd0aUdIUvKXrJfXsy8LVtXAy7DRvYVluWbMspsRhz2lcW0mQ==} + + '@boringnode/encryption@1.0.1': + resolution: {integrity: sha512-+UL9erFUngnxNEDdXSKCnGQA8D62C/x2vxLF5vc9zaX7T2JolV/bGjpZAvFLzlY2gIffHyw+KsqsEWod5+zV0w==} + engines: {node: '>=20.6'} + + '@boringnode/route-matcher@0.1.1': + resolution: {integrity: sha512-Iim6TZdwX3BuQ+m4wg5wIEviIoi0Xy6j6cpw4B2o1wppByUxafbLMgMIFJ6yS/l1XKXifEGcds9M1Gw7Fk8DUg==} + engines: {node: '>=20.6'} + + '@colors/colors@1.5.0': + resolution: {integrity: sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==} + engines: {node: '>=0.1.90'} + '@csstools/selector-resolve-nested@3.1.0': resolution: {integrity: sha512-mf1LEW0tJLKfWyvn5KdDrhpxHyuxpbNwTIwOYLIvsTffeyOf85j5oIzfG0yosxDgx/sswlqBnESYUcQH0vgZ0g==} engines: {node: '>=18'} @@ -379,6 +919,10 @@ packages: '@emnapi/wasi-threads@1.2.2': resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + '@faker-js/faker@10.6.0': + resolution: {integrity: sha512-3RQHgEtvL1Frl/d1cSreo7qhJ3Gk1OdNUai/CtZ8G+wYeRQnJih3s9xJ9/kgYekPQRdwgh0HXRPqMlzWGwivIQ==} + engines: {node: ^20.19.0 || ^22.13.0 || ^23.5.0 || >=24.0.0, npm: '>=10'} + '@fastify/accept-negotiator@1.1.0': resolution: {integrity: sha512-OIHZrb2ImZ7XG85HXOONLcJWGosv7sIvM2ifAPQVhg9Lv7qdmMBNVaai4QTdyuaqbKM5eO6sLSQOYI7wEQeCJQ==} engines: {node: '>=14'} @@ -401,10 +945,81 @@ packages: '@fastify/static@7.0.4': resolution: {integrity: sha512-p2uKtaf8BMOZWLs6wu+Ihg7bWNBdjNgCwDza4MJtTqg+5ovKmcbgbR9Xs5/smZ1YISfzKOCNYmZV8LaCj+eJ1Q==} + '@inertiajs/core@3.9.1': + resolution: {integrity: sha512-ScLQZ1/KXlvmqCEJMEZABSK5updJZIli1kaG/coWXpWMmpSLsazSJkR7esITYp7X5vTgrOGNIrcRmdMp/GQ0NA==} + peerDependencies: + axios: ^1.15.2 + peerDependenciesMeta: + axios: + optional: true + + '@inertiajs/vue3@3.9.1': + resolution: {integrity: sha512-pISiTjoCm86xHFMdG7QhkzKXrX3fMf9Ihgst08xalxv4pOzwQ5L/Hw/RnOzrqO34waykPEWgAr34nyo2IQ80mg==} + peerDependencies: + vue: ^3.0.0 + + '@ioredis/commands@2.0.0': + resolution: {integrity: sha512-vrx0AE/T0h7cRZwfo1M39Cr+ZhZrkf0V8mQN75wucKCxCLD9l/VX6no3gFvrLqD1IlG/1LtzWovqEw3t0Vr9zg==} + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} + '@japa/assert@4.2.0': + resolution: {integrity: sha512-Krgrcee01BN1StlVwK5JQP6LL5t3DE3uFNbfFoDTfW7kQuHB0xh6yfaV0hrgcoiEjsqmm2OOsVWeju9aXK4vIA==} + engines: {node: '>=18.16.0'} + peerDependencies: + '@japa/runner': ^3.1.2 || ^4.0.0 || ^5.0.0 + + '@japa/browser-client@2.3.0': + resolution: {integrity: sha512-YNcN0l1dZRZpsFtBHWPq5dP/8+US1FALs/uqhGUhvIgKQgIA5I3PvzRmkry+Dh74U6/Mj+IO2kRJL+kPCdVnew==} + engines: {node: '>=18.16.0'} + peerDependencies: + '@japa/assert': ^2.0.0 || ^3.0.0 || ^4.0.0 + '@japa/runner': ^3.1.2 || ^4.0.0 || ^5.0.0 + playwright: ^1.57.0 + + '@japa/core@10.4.0': + resolution: {integrity: sha512-1zvKL29i7r/4jqTNBsw91hk1tp6wbqFXvyV2p+Og4axDRhIXjSAfauRvBL9QuB80bOa+pDIMQ5kCTaCplSm0Eg==} + engines: {node: '>=24.0.0'} + + '@japa/errors-printer@4.1.4': + resolution: {integrity: sha512-ogPT87QLaugKyPVcq+ZypcetVeJpXZN7RfVRlRDIrSHsHBw6ILCtNXghVxD9POjqxtUM7RON3sUkgZzLnVQA5g==} + engines: {node: '>=18.16.0'} + + '@japa/plugin-adonisjs@5.2.0': + resolution: {integrity: sha512-Knk3X/UeZiEvkXmTj9+dAIOdJHMqRUJFsUMw9y8at+AR1VbPJR9T+aU5SaOn6OtejEFnUMILwJYC3ohg23+vhw==} + engines: {node: '>=18.16.0'} + peerDependencies: + '@adonisjs/core': ^7.0.0-next.21 || ^7.0.0 + '@japa/api-client': ^3.1.0 + '@japa/browser-client': ^2.2.0 + '@japa/runner': ^4.0.0 || ^5.0.0 + playwright: ^1.57.0 + peerDependenciesMeta: + '@japa/api-client': + optional: true + '@japa/browser-client': + optional: true + playwright: + optional: true + + '@japa/runner@5.3.0': + resolution: {integrity: sha512-WCnTd1q2EpbKKa96NzL16kVxJXVLRj1VqbswNAn17hYSuMlNKKhPGNbAosB32QZVFcoe9fv4Ebh1HtjyAT/viw==} + engines: {node: '>=18.16.0'} + + '@jest/diff-sequences@30.5.0': + resolution: {integrity: sha512-OsqBjHXCn8cadasoAZBP6nWYvMsRhpMzGXTpxJ5aO04NlbdhIz+FVe3q49l0AwVhsz/cEmIpBes6gAFl1/dWQg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/get-type@30.5.0': + resolution: {integrity: sha512-9/2VUPitAjmBzbvDvqrxmvB7BzWsBW0WmkkojX1ODuxX1NLGxx9gfaZpHB0z8DtJ9uhGNmZG/VXBhf8uO0OV8Q==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + '@jest/schemas@30.5.0': + resolution: {integrity: sha512-/hunigyNpc4RCjC0VaW3f5RCUZVM2+WQ65qP7z083Gmvac7or2LI50XVNOtE4YPgBpV0yxYiAgorAPGniCoJmg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jridgewell/gen-mapping@0.3.13': resolution: {integrity: sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==} @@ -446,6 +1061,9 @@ packages: '@oxc-project/types@0.139.0': resolution: {integrity: sha512-r9gHphtCs+1M7J0pw6Sn/hh/Wpa/iQrOOkrNAlVLF/gHq+/CJmHIWKKUUhdWjcD6CIa8idarspCsASiXCXvFUw==} + '@oxc-project/types@0.153.0': + resolution: {integrity: sha512-jSNrRIyvPVLL5E1z/tS5zLAprosGz/FuI1PWwEOz59j3E4TTTzSpqKb/RDGqJhhW0QHYISGXxq582wGx6T11Tw==} + '@oxfmt/binding-android-arm-eabi@0.59.0': resolution: {integrity: sha512-bNTnfbuG7sAwb2PakMNaDukx5kXeW9duXOBeWtTOiLz3fXz3q2DlWguufPZ+c2IHEVrRXHD+M4aUgEWm841LDA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -690,6 +1308,10 @@ packages: cpu: [x64] os: [win32] + '@phc/format@1.0.0': + resolution: {integrity: sha512-m7X9U6BG2+J+R1lSOdCiITLLrxm+cWlNI3HUFA92oLO77ObGNzaKdh8pMLqdZcshtkKuV84olNNXDfMc4FezBQ==} + engines: {node: '>=10'} + '@pinojs/redact@0.4.0': resolution: {integrity: sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==} @@ -697,6 +1319,63 @@ packages: resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==} engines: {node: '>=14'} + '@poppinss/cliui@6.8.1': + resolution: {integrity: sha512-o/ssbwr+r6woG65rk9eFHnn9dVUphZr/Rk+4+05ENVMBWYpYhTJGdE9RobTG5JLFubvO4gWIyFeNlC+I4EM6eA==} + + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + + '@poppinss/dumper@0.7.0': + resolution: {integrity: sha512-0UTYalzk2t6S4rA2uHOz5bSSW2CHdv4vggJI6Alg90yvl0UgXs6XSXpH96OH+bRkX4J/06djv29pqXJ0lq5Kag==} + + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + + '@poppinss/hooks@7.3.1': + resolution: {integrity: sha512-MyBiHAOmUPT8fY++IQIeiYnxknrLQ9WzrAlZlyyGbFh+C5Srdb+FhQbQkLivAQxIKkhiCeeoSpiGPcv5gDvirA==} + + '@poppinss/inspect@1.0.1': + resolution: {integrity: sha512-kLeEaBSGhlleyYvKc7c9s3uE6xv7cwyulE0EgHf4jU/CL96h0yC4mkdw1wvC1l1PYYQozCGy46FwMBAAMOobCA==} + + '@poppinss/macroable@1.1.2': + resolution: {integrity: sha512-FAVBRzzWhYP5mA3lCwLH1A0fKBqq5anyjGet90Z81aRK5c/+LTGUE1zJhZrErjaenBSOOI9BVUs3WVmotneFQA==} + + '@poppinss/matchit@3.2.0': + resolution: {integrity: sha512-9SoMICN+LMO7ZtMj2ja8N7RHlC4mmuv5WwIBXWjabMd2SyXE1dIydh29exlgm+dGMP84PjwvfJH1TmWL4qz1og==} + + '@poppinss/middleware@3.2.7': + resolution: {integrity: sha512-MZC0Z97ozSz+PpfyxUPUy/ImuthpqvBbY7qku7f4Q2maHz+2uXfchfO8OggXLS6zEJ078l+jpAHZ2rDIRdjeVg==} + + '@poppinss/multiparty@3.0.0': + resolution: {integrity: sha512-z9jchUzsv7E+7sa4tWHb0+95Byx7w0ydlPGxg3nzyb7h3QlRdeW8/QkU9SexUY4lsT12do93AfNBAhSuOoVqjA==} + + '@poppinss/object-builder@1.1.0': + resolution: {integrity: sha512-FOrOq52l7u8goR5yncX14+k+Ewi5djnrt1JwXeS/FvnwAPOiveFhiczCDuvXdssAwamtrV2hp5Rw9v+n2T7hQg==} + engines: {node: '>=20.6.0'} + + '@poppinss/prompts@3.1.6': + resolution: {integrity: sha512-cKHfkID6b3wl1kbHJJRC/pznQ3KnRVydyk7CE38NfTV3VS45BDYCxeZZ7bfDin71qMzITh18lKnu8iuLxBngHA==} + + '@poppinss/qs@6.15.0': + resolution: {integrity: sha512-QzfMhxrRB5EPeGz0l8hTwKZ5dFX6ed0aETGbuD369StCO8Ad3SW4wWBYamOK5IKeM/dfOeKaCwUZPTnGcj+jKg==} + engines: {node: '>=0.6'} + + '@poppinss/string@1.7.2': + resolution: {integrity: sha512-A182GLDfi36iDCbhDrHB0xzrPM1fO3GHnhCDIdadf8C6eycgct4m7zusbLwEh6GPaj2Pz5BVos7XK16w7tZ7wQ==} + + '@poppinss/ts-exec@1.5.0': + resolution: {integrity: sha512-zkIE28rgHt2VFEN+A1QnHS7y7CQiM8kRSfvAAE1N8eZW8ghlju6uYZu3oIbISM0I0qs9E+KZLZAVY1djdTBoYg==} + engines: {node: '>=24.0.0'} + + '@poppinss/types@1.2.1': + resolution: {integrity: sha512-qUYnzl0m9HJTWsXtr8Xo7CwDx6wcjrvo14bOVbIMIlKJCzKrm3LX55dRTDr1/x4PpSvKVgmxvC6Ly2YiqXKOvQ==} + + '@poppinss/utils@7.1.1': + resolution: {integrity: sha512-m1pR6EsycFyDHWDyoWnTI2sgEpOAZuKECQRgZ9i+uGzU/DNoEXn70ldt1V3u2EKp2tNf9T9QqX1wBMHm+xcpiw==} + + '@poppinss/validator-lite@2.1.2': + resolution: {integrity: sha512-UhSG1ouT6r67VbEFHK/8ax3EMZYHioew9PqGmEZjV41G15aPZi6cyhXtBVvF9xqkHMflA5V680k7bQzV0kfD5w==} + '@redis/bloom@5.12.1': resolution: {integrity: sha512-PUUfv+ms7jgPSBVoo/DN4AkPHj4D5TZSd6SbJX7egzBplkYUcKmHRE8RKia7UtZ8bSQbLguLvxVO+asKtQfZWA==} engines: {node: '>= 18.19.0'} @@ -733,36 +1412,72 @@ packages: peerDependencies: '@redis/client': ^5.12.1 + '@rolldown/binding-android-arm-eabi@1.2.13': + resolution: {integrity: sha512-Vu/NICrgdRvUOeaJZIyB2FP63s6fO/4ud5l8dXmxDx9yDyn+mN0y+gsvsVviSli+T361Aqo0h46EuMoobrwawA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + '@rolldown/binding-android-arm64@1.1.5': resolution: {integrity: sha512-lZg8fqIv2v7FF237bwMgzGZEJvGL79/s5knJ/i6FmsGF4XXlzccZ4jb+TrFIxtSSxFtIpdsgrPZeMk1I9AFcyQ==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [android] + '@rolldown/binding-android-arm64@1.2.13': + resolution: {integrity: sha512-6LEoIrGy5vvCd2boNnv2soPSUZj/PRvhp8R/t9KlX+mIZxThIE/ZqxrGXxmuNX0FuvQFvLdZr7S4HrYpYBVhEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + '@rolldown/binding-darwin-arm64@1.1.5': resolution: {integrity: sha512-51Bnx9pNiMRKSUNtBfySkNJ9vMU9Hh3I1ozDd6gyPPYzaXCfnptUcEZxXGYFn+ul2dtcMUiqGR1Yai2K10uoTw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [darwin] + '@rolldown/binding-darwin-arm64@1.2.13': + resolution: {integrity: sha512-CaJSRzlQ6Q+zkDMVA9OkVxBjVoPRCDEE3v0FSJ9kIQBgRjFApA3Si4ijhbNVUji7ZJt+PfO0e46qy4nPInHUPA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + '@rolldown/binding-darwin-x64@1.1.5': resolution: {integrity: sha512-Tm+gbfC0aHu1tBA/JvKQh32S0K6YgCHkiAF4/W6xX0K0RmNuc94VeK419dJoE65R5aRxmo+noZQSWrAMF6yb6g==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [darwin] + '@rolldown/binding-darwin-x64@1.2.13': + resolution: {integrity: sha512-e4r340I5hxSzJkD3YJBxgzq/rJ3wwxwdLLb2FPt1Zpyem20nrQPT11DDEEkazwxaHumH8wpglsp/Ozgj/wT6mw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + '@rolldown/binding-freebsd-x64@1.1.5': resolution: {integrity: sha512-JMzDKCCXq93YccG5gz3hvOs1oXRKAf0XYpfOS88e+wZrC8Iugj6j68867vrYZkvpDDpKn/KoKORThmchMpF6TA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [freebsd] + '@rolldown/binding-freebsd-x64@1.2.13': + resolution: {integrity: sha512-hoBWDZ4/K/mJKVMbsgUd1jfpA2DiOrJ54mpegObU9TBHBBrtX4FLIXJJQRDPZ/2Dn91GvPob+Z2hwKJzf4E5SQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': resolution: {integrity: sha512-uML21j2K5TfPGutKxub+M+nLjZIrWjXQ5Grx4lCe/nimTj9B4L63zHpjXLl4y0L3mcm2htEQIb06oCG/szerNw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm] os: [linux] + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + resolution: {integrity: sha512-oF9fZu3vTWnTiVAkDFxU9PJLt1nh20K9RRpuHsR7ZnE2L7XookBbDBVLojCVSLGbvtSlxeUNnjAj6DbNsKyzbg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + '@rolldown/binding-linux-arm64-gnu@1.1.5': resolution: {integrity: sha512-navSiuTMogvnQoZoM/v+l3ZWo50/NTwSHSzheABx/RCnmUPaKwq9qSo4Br2OYRs21+Fz8uFqITZM3H4opOB0/Q==} engines: {node: ^20.19.0 || >=22.12.0} @@ -770,6 +1485,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-arm64-gnu@1.2.13': + resolution: {integrity: sha512-DTpb/+jMiqWMPgphn4ksW1zW+XLJ6dJJ9FMvnIk9I291LhCctMPhMYJrP5t9p6C9qa3KXadDdUEZHBaPh3kNxQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-arm64-musl@1.1.5': resolution: {integrity: sha512-lAryqH7IteztmCXQXk0etKj4wBQ7Gx5S6LjKhsgp9zb8I5bsuvU/2llH1hDQcjsFeqIsovMVN339/8pUDDBXxA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -777,13 +1499,27 @@ packages: os: [linux] libc: [musl] - '@rolldown/binding-linux-ppc64-gnu@1.1.5': + '@rolldown/binding-linux-arm64-musl@1.2.13': + resolution: {integrity: sha512-xU+Kvv9N2A3SY35zFh1FWWNjxbadE/BKeqnkXe7vScU4GZsw757BlVmDLITZEq8DPpk6m7uoDYkK7P+x/uU5Ow==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.1.5': resolution: {integrity: sha512-fsK/sNBnxzBlL4O1JNrZakVQxPspqpED5dLtNsZS9oOKmtSpdNIzxH2kkol5HYTWJN47sE20ztMJPxfZ89qGOg==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [ppc64] os: [linux] libc: [glibc] + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + resolution: {integrity: sha512-XMk/hnhh25oQ756Lclb1Q11h4ll0xC0Esa5w4Vzp+mAE2S3AGJgeM0SonrIgY8fHhjarb6hcoTuwoFG0VVP2ig==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.1.5': resolution: {integrity: sha512-gLYb4BIadlfTOYT5gO503n8zQjXflgzpD0FcyKh0Mzx3rqCZKnHoJWV9xe1KXUJ5lx2JfcSHr/mhzS0PC/McAA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -791,6 +1527,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-s390x-gnu@1.2.13': + resolution: {integrity: sha512-U1BoTHYmlywE2n3HUWjzZ+8EQsKr+OwpxYuDWaubx42tUL8QSL7nOqRz/NVHanibbFP3M1Rxuprz/wNcbMKjqw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.1.5': resolution: {integrity: sha512-FjcpEKUyJygHgs1o50VYNvkt5+7Le/VEdYt0AkRpkL33MnyQfwr8l5mXwMmfmTbyMPr5vJLC+8/Gd9gXnwU1QQ==} engines: {node: ^20.19.0 || >=22.12.0} @@ -798,6 +1541,13 @@ packages: os: [linux] libc: [glibc] + '@rolldown/binding-linux-x64-gnu@1.2.13': + resolution: {integrity: sha512-J4cm80Pc6wEwV5AZ42o62sIQgDk+Y7R2s646jIwuvO+4V46QB58N4vVuMPWCBaNgursXLpmUWJV//WQAkPvHBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + '@rolldown/binding-linux-x64-musl@1.1.5': resolution: {integrity: sha512-Me+PfPI2TMeOQk0gYWfLQZtTktrmzbr8cDboqX83XKc7UrgAi55gF+2dUkWdxd19n55Essp2yeca+O9N5rBxHg==} engines: {node: ^20.19.0 || >=22.12.0} @@ -805,12 +1555,25 @@ packages: os: [linux] libc: [musl] + '@rolldown/binding-linux-x64-musl@1.2.13': + resolution: {integrity: sha512-W0euZS40U4V6JkmEnVCIX9mcsL6cbXQ4X8c2w+MMOIjFg68TXUW+u3RT+2e1t1pv9mg/EP3pDtK3POXdQ7Rxyw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + '@rolldown/binding-openharmony-arm64@1.1.5': resolution: {integrity: sha512-yc5WrLzXks6zCQfn9Oxr8pORKyl/pF+QjHmW/Qx3qu0oyrrNC+y2JLTU1E2rcWYAmzlnqngWXHQjy51VzW70Vw==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [arm64] os: [openharmony] + '@rolldown/binding-openharmony-arm64@1.2.13': + resolution: {integrity: sha512-do/AF/4n9MRshia3a5aXoy8xM2c6mgfT6D7H/dY6my5z+hfCIR4ab7mk4IRj++nsEQpKy39kd0DQnDq+r692tw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + '@rolldown/binding-wasm32-wasi@1.1.5': resolution: {integrity: sha512-VbQGPX2b4r48TAMIM2cjgluIM1HYutm4pcTEJsle7iEP7sB1dFqtPLBVbdLAZCxy1txCcPxf4QFf4v8uvltPqA==} engines: {node: ^20.19.0 || >=22.12.0} @@ -822,12 +1585,24 @@ packages: cpu: [arm64] os: [win32] + '@rolldown/binding-win32-arm64-msvc@1.2.13': + resolution: {integrity: sha512-6FtUf2cJZobutJdxnGYX8z0vtbgqU0b2v8vfBhkXb9wp2MppMFtkunE+IaOntyi01rkIQoPW2GHABtfzsC0BRQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + '@rolldown/binding-win32-x64-msvc@1.1.5': resolution: {integrity: sha512-tTZuDBPw85tEN5PQi1pnEBzDy0Z49HtScLAbD5t6hyeU92A95pRWaSMw1GZZi/RwgSgUIl0xrSlXIT/9QzvYSA==} engines: {node: ^20.19.0 || >=22.12.0} cpu: [x64] os: [win32] + '@rolldown/binding-win32-x64-msvc@1.2.13': + resolution: {integrity: sha512-UKhFaZTeTcbKrb3iU82m17jVcPEAoqDkCN5MBqgPyZSwp/cQmib21crTS0DdH7T1B7wZRWEI89YQAOJMet5yhg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + '@rolldown/pluginutils@1.0.1': resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} @@ -847,12 +1622,137 @@ packages: resolution: {integrity: sha512-xzvBr1Q1c4lCe7i6sRnrofxeO1QTP/LKQ6A6qy0iB4x5yfiSfARMEQEghojzTNALDTcv8En04qYNIco9/K9eZQ==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} + '@sec-ant/readable-stream@0.4.1': + resolution: {integrity: sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==} + '@silvia-odwyer/photon-node@0.3.4': resolution: {integrity: sha512-bnly4BKB3KDTFxrUIcgCLbaeVVS8lrAkri1pEzskpmxu9MdfGQTy8b8EgcD83ywD3RPMsIulY8xJH5Awa+t9fA==} + '@sinclair/typebox@0.34.52': + resolution: {integrity: sha512-XiMQh7qqVlxZzcVD+kkGMNGMzcTrDMLWI7S4x7z1MkCkbDPrekpZXEUK0eZqZFMuHQg2a2DZOcDIh9o5v3Gonw==} + + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} + engines: {node: '>=18'} + + '@sindresorhus/is@8.1.0': + resolution: {integrity: sha512-2SX/1jW6CIMAiebvVv5ZInoCEuWQmMyBoJXXGC6Vjakjp/fpxP5eHs7/V6WKuPEIbuK06+VpjH+vjLQhr98rDQ==} + engines: {node: '>=22'} + + '@sindresorhus/merge-streams@4.0.0': + resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} + engines: {node: '>=18'} + + '@sindresorhus/slugify@3.0.1': + resolution: {integrity: sha512-N1oPvN6sytRKZCskv0L+vSyvnUYi9JplPXZ90lT6EBsijjHrUdoXttb0Lna6pw1TWMe8vlajQnLDtU9KYHqtDg==} + engines: {node: '>=20'} + + '@sindresorhus/transliterate@2.3.1': + resolution: {integrity: sha512-gVaaGtKYMYAMmI8buULVH3A2TXVJ98QiwGwI7ddrWGuGidGC2uRt4FHs22+8iROJ0QTzju9CuMjlVsrvpqsdhA==} + engines: {node: '>=20'} + + '@speed-highlight/core@1.2.24': + resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==} + '@sqltools/formatter@1.2.5': resolution: {integrity: sha512-Uy0+khmZqUrUGm5dmMqVlnvufZRSK0FbYzVgp0UMstm+F5+W2/jnEEQyc9vo1ZR/E5ZI/B1WjjoTqBqwJL6Krw==} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@swc/core-darwin-arm64@1.16.18': + resolution: {integrity: sha512-ozgiCHyFDCwfXzTnaLR+i8WxEyt06GTudn9rPh08vj+u3Z8vMvt5Pi8T+BikyNXm7y++h6UMdqsnJuWrV+tk2A==} + engines: {node: '>=10'} + cpu: [arm64] + os: [darwin] + + '@swc/core-darwin-x64@1.16.18': + resolution: {integrity: sha512-tuwxXi+sjxxTAi7GP3NeQXQxOf4SXSiFxKAMYLBdoy7JqGYby6uSDXojcFoLOhSp7oiNGstnaFXxfbP0Hpro9w==} + engines: {node: '>=10'} + cpu: [x64] + os: [darwin] + + '@swc/core-linux-arm-gnueabihf@1.16.18': + resolution: {integrity: sha512-SMdhmY1P9Kveh0MRj6vqQF98bsjnDa0lBBvkd/lcpxmjj5QHJOQAU0N3g6h7GPWpBMs3h2g3lHu/QTDn+uMsXg==} + engines: {node: '>=10'} + cpu: [arm] + os: [linux] + + '@swc/core-linux-arm64-gnu@1.16.18': + resolution: {integrity: sha512-ep/mQyhblQYZ6tkfq0IJspcVSFl5jdywks3kejanrbB31uuujRD/QWOoGNp2L3lLRdAdQvgl/M3pA7g3hSuQug==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-arm64-musl@1.16.18': + resolution: {integrity: sha512-pkzGVxrAQu5+febW1a/Aiph3YJk0UiJKXoWbxnDVEIOZWkk5aETHTuyVsOQ3kOgn2dzNMvJVeqcoEQdH+ntqWQ==} + engines: {node: '>=10'} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@swc/core-linux-ppc64-gnu@1.16.18': + resolution: {integrity: sha512-v9kiu4as1pJyQ8ESFTtMNydZ99m86QXLfAtm+XiKPKS93pXL80BCaXokAs9ebioGkIXgmwfbzUCdUC62H3JWkw==} + engines: {node: '>=10'} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-s390x-gnu@1.16.18': + resolution: {integrity: sha512-vU7TKRJ26i86YQr4QY/5bdcH72KzkBbSSUfPlErW6d6KOR47BcVGlYZFTcMMYlmd3CVSXFHW18tBSila66YfoA==} + engines: {node: '>=10'} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-gnu@1.16.18': + resolution: {integrity: sha512-Ml6kbe0BoVJkSgmYPAEUudGcu84jaQeqDN8xeMumbwNpT0vlmm7241Ddp9XKCjQABvjomnXF0OiNOAfjBhNDNw==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@swc/core-linux-x64-musl@1.16.18': + resolution: {integrity: sha512-TGU24+QmmS8y/hg0BLKgOU3W5TCcQC9bgGl8AB0R61gTNQdWdcmCehRLAJwlZfxtAml66xMJ6PWrX8NKrABOsA==} + engines: {node: '>=10'} + cpu: [x64] + os: [linux] + libc: [musl] + + '@swc/core-win32-arm64-msvc@1.16.18': + resolution: {integrity: sha512-S53hm7Amc3YV8t2BUT6R7J+zSnwiGarG+GnxMca4W0uMkxBZ3Gl6jBwEgb6YqrYjf2DzOuRfauztqptCO76a/w==} + engines: {node: '>=10'} + cpu: [arm64] + os: [win32] + + '@swc/core-win32-ia32-msvc@1.16.18': + resolution: {integrity: sha512-+6/10+OJmU12zWkrPVG0QeQEr8VsWeF8gyXrOfHZMIfMOfz8/ULXVZPhV9GhGMKSWake1xEJj2IYCiFRS/xMpQ==} + engines: {node: '>=10'} + cpu: [ia32] + os: [win32] + + '@swc/core-win32-x64-msvc@1.16.18': + resolution: {integrity: sha512-7LsVrIICAZWSajXT6DwO7PYSTnW9maamOCyQylaOh13Viptrgi/7hl9fP75SiHe+kscaJahGXcorgt4MOOh/1w==} + engines: {node: '>=10'} + cpu: [x64] + os: [win32] + + '@swc/core@1.16.18': + resolution: {integrity: sha512-0cYQLkpcwUngg55TDwpwrrVOU+B6zh1NFbp+oS7dVFhmYkzaARelwugo/bzPJh1FrcnppmF+KTqioCGwyqbcEw==} + engines: {node: '>=10'} + peerDependencies: + '@swc/helpers': '>=0.5.17' + peerDependenciesMeta: + '@swc/helpers': + optional: true + + '@swc/counter@0.1.3': + resolution: {integrity: sha512-e2BR4lsJkkRlKZ/qCHPw9ZaSxc0MVUd7gtbtaB7aMvHeJVYe8sOB8DBZkP2DtISHGSku9sCK6T6cnY0CtXrOCQ==} + + '@swc/types@0.1.28': + resolution: {integrity: sha512-V6Mnml8v09QALx6K0elJ7o9K/MkVDtW3t6L+7Ou/JcWtb3xwId2AH4FeOceySd2JaO87IMw4+6vSZxLm34LPbw==} + '@tailwindcss/node@4.3.3': resolution: {integrity: sha512-/T8IKEsf9VTU6tLjgC7+sv2mOPtQxzE2jMw7u4Tt40Tx+QSZxpzh95/H6cMKoja9XuW7iMdLJYBB0o9G1CaAgg==} @@ -947,24 +1847,55 @@ packages: peerDependencies: vite: ^5.2.0 || ^6 || ^7 || ^8 + '@tokenizer/inflate@0.4.1': + resolution: {integrity: sha512-2mAv+8pkG6GIZiF1kNg1jAjh27IDxEPKwdGul3snfztFerfPGI1LjDezZp3i7BElXompqEtPmoPx6c2wgtWsOA==} + engines: {node: '>=18'} + + '@tokenizer/token@0.3.0': + resolution: {integrity: sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==} + + '@ts-morph/common@0.29.0': + resolution: {integrity: sha512-35oUmphHbJvQ/+UTwFNme/t2p3FoKiGJ5auTjjpNTop2dyREspirjMy82PLSC1pnDJ8ah1GU98hwpVt64YXQsg==} + + '@tuyau/core@1.2.2': + resolution: {integrity: sha512-kFE+gxuWZ4F6KjMB6wXNEP44oVdBpYyuAsOxjHpGplC5d+ErSVjynh1vN0rkv9poQJI3z+r81JKqhpmJZs886Q==} + engines: {node: '>=24.0.0'} + peerDependencies: + '@adonisjs/assembler': ^8.0.0-next.27 + '@adonisjs/core': ^7.0.0-next.16 + peerDependenciesMeta: + '@adonisjs/assembler': + optional: true + '@adonisjs/core': + optional: true + '@tybys/wasm-util@0.10.3': resolution: {integrity: sha512-F3fo1MYrRJYL3zER0OUOmkutjr1Vp23m7OsSgp7nq4SP6OqX6C/56XFIPAl5bt3zaBRjmW7SGz3u/6LwFpYcOg==} '@types/body-parser@1.19.6': resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/connect@3.4.38': resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} '@types/cors@2.8.19': resolution: {integrity: sha512-mFNylyeyqN93lfe/9CSxOGREz8cpzAhH+E93xJ4xWQf62V8sQ/24reV2nyzUWM6H6Xji+GGHpkbLe7pVoUEskg==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/express-serve-static-core@4.19.9': resolution: {integrity: sha512-QP2ESEe/ImWY0HDwNAnK9PvEffUyhLTnWkk7KXzHfyeWAnlrDe1fN77bXl6ia8KT3wPlmA7t9/VPRpnf4Ex9sg==} '@types/express@4.17.25': resolution: {integrity: sha512-dVd04UKsfpINUnK0yBoYHDF3xu7xVH4BuDotC/xGuycx4CgbP48X/KF/586bcObxT0HENHXEU8Nqtu6NR+eKhw==} + '@types/he@1.2.3': + resolution: {integrity: sha512-q67/qwlxblDzEDvzHhVkwc1gzVWxaNxeyHUBF4xElrvjL11O+Ytze+1fGpBHlr/H9myiBUaUXNnNPmBHxxfAcA==} + '@types/http-errors@2.0.5': resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} @@ -980,6 +1911,9 @@ packages: '@types/lodash@4.17.24': resolution: {integrity: sha512-gIW7lQLZbue7lRSWEFql49QJJWThrTFFeIMJdp3eH4tKoxm1OvEPg02rm4wCCSHS0cL3/Fizimb35b7k8atwsQ==} + '@types/luxon@3.7.6': + resolution: {integrity: sha512-6KSjliQAXK8ZLgFQO4B7iE4Rpf/B3rItzCFuXezBY/XIAGxOdLd7vRNK9/StRPwiS/yJsVbB7HKpW46B8tcEuQ==} + '@types/mime@1.3.5': resolution: {integrity: sha512-/pyBZWSLD2n0dcHE3hq8s8ZvcETHtEuF+3E7XVt0Ig2nvsVQXdghHVcEkIWjy9A0wKfTn97a/PSDYohKIlnP/w==} @@ -989,6 +1923,12 @@ packages: '@types/node@24.13.3': resolution: {integrity: sha512-Dh8vAsV36ig5wa9OX4pXvMc9D3Veibfw2wix0CUwYODLD8nkj9UsLjASr49nPg+2eKzxhBV+v7L8pXvT4e639Q==} + '@types/node@26.6.5': + resolution: {integrity: sha512-uMzsv9stDdofIZBx4UGh4Z9ZgXnGC9seRDscilBcTHAeOFk67MZg/k9bWVfO+bk4qZmG+l52hRnLwUiH2LnJTg==} + + '@types/normalize-package-data@2.4.4': + resolution: {integrity: sha512-37i+OaWTh9qeK4LSHPsyRC7NahnGotNuZvjLSgcPzblpHB3rrCJxAOgI5gCdKm7coonsaX1Of0ILiTcnZjbfxA==} + '@types/oauth@0.9.6': resolution: {integrity: sha512-H9TRCVKBNOhZZmyHLqFt9drPM9l+ShWiqqJijU1B8P3DX3ub84NjxDuy+Hjrz+fEca5Kwip3qPMKNyiLgNJtIA==} @@ -1001,6 +1941,9 @@ packages: '@types/passport@1.0.17': resolution: {integrity: sha512-aciLyx+wDwT2t2/kJGJR2AEeBz0nJU4WuRX04Wu9Dqc5lSUtwu0WERPHYsLhF9PtseiAMPBGNUOtFjxZ56prsg==} + '@types/pluralize@0.0.33': + resolution: {integrity: sha512-JOqsl+ZoCpP4e8TDke9W79FDcSgPAR0l6pixx2JHkhnRjvShyYiAYw2LVsnA7K08Y6DeOnaU6ujmENO4os/cYg==} + '@types/qs@6.15.1': resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} @@ -1028,6 +1971,9 @@ packages: '@types/uuid@9.0.8': resolution: {integrity: sha512-jg+97EGIcY9AGHJJRaaPVgetKDsrTgbRjQ5Msgjh/DQKEFl0DtyRr/VCOyD1T2R1MNeWPK/u7JoGhlDZnKBAfA==} + '@types/validator@13.15.10': + resolution: {integrity: sha512-T8L6i7wCuyoK8A/ZeLYt1+q0ty3Zb9+qbSSvrIVitzT3YjZqkTZ40IbRsPanlB4h1QB3JVL1SYCdR6ngtFYcuA==} + '@types/ws@8.18.1': resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} @@ -1151,6 +2097,14 @@ packages: cpu: [x64] os: [win32] + '@vinejs/compiler@4.1.3': + resolution: {integrity: sha512-UyH7Zn8dkTMLeU+PF2WjCnWkFb2qYaOxAcvp/uXW0njtKNcJOnVJaPsnWYwqewkTcHN47yvOdzosj3kj3RAP5w==} + engines: {node: '>=18.0.0'} + + '@vinejs/vine@4.4.0': + resolution: {integrity: sha512-cfnNXjs9+f+22d3Eb8koyg2qlCbaT394XBlL4AeEr1WM+NH1omFcXwe1zrkW4hHwPDSfUd4lFUdNO6E+YnTeWQ==} + engines: {node: '>=18.16.0'} + '@vitejs/plugin-vue@5.2.4': resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1158,6 +2112,13 @@ packages: vite: ^5.0.0 || ^6.0.0 vue: ^3.2.25 + '@vitejs/plugin-vue@6.0.10': + resolution: {integrity: sha512-b80aUQh3n+qEzzZm5oQp3rT2QImeCx58K6eFl/RkJ3d65KW0kTuv5lNsLRVAjbW9YRUpo/wzmvzMgV34bTAItA==} + engines: {node: ^20.19.0 || >=22.12.0} + peerDependencies: + vite: ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + vue: ^3.2.25 || ^3.6.0-rc.10 + '@vladfrangu/async_event_emitter@2.4.7': resolution: {integrity: sha512-Xfe6rpCTxSxfbswi/W/Pz7zp1WWSNn4A0eW4mLkQUewCrXXtMj31lCg+iQyTkh/CkusZSq9eDflu7tjEDXUY6g==} engines: {node: '>=v14.0.0', npm: '>=7.0.0'} @@ -1182,36 +2143,66 @@ packages: '@vue/compiler-core@3.5.40': resolution: {integrity: sha512-39E8IgOhTbVDnoJFMKc2DvYnypcZwUqgUhQkccva/0m6FUwtIKSGV7n1hpVmYcFaoRAwf9pBcwnKlCEsN63ZEQ==} + '@vue/compiler-core@3.5.43': + resolution: {integrity: sha512-zdiLhnbe1QQqgDT8xZMpNmyqZ3qlI+/Q/FHQco57Kwl/b05HhCzN6eVGN9QU9rbga4CrS0H5SYY8VGHZCt/1Hg==} + '@vue/compiler-dom@3.5.40': resolution: {integrity: sha512-pwkx4vqlqOspFstrcmzwkKLePVMD3PT65imRzLhanU2V1Fj4K13g6OXjanOyzw3aTAuRk84BOmY8f3rEHqPaVA==} + '@vue/compiler-dom@3.5.43': + resolution: {integrity: sha512-PEZoAk3NQmsn/ejMzSOCyTYqwGqczrWm70PuhBKjjv1+TCoQAaO/zOqNwjV+honlNstT5ILxtc+8r8UUfj+iEQ==} + '@vue/compiler-sfc@3.5.40': resolution: {integrity: sha512-gIf497P4kpuALcvs5n3AEg1Vdn0pSY4XbjASIfHNYF1/MP3T2Mf2STERTubysBxCRxzJGJYtF/O7vwJrxFB3Vw==} + '@vue/compiler-sfc@3.5.43': + resolution: {integrity: sha512-FCbrG3XNCRl+js3huuKx4IVHBLTvMkJhVepjbxSPu1gn4yWLaYtGNQdjJGZaMytXB6qb76qQDDmDSLy/vkmleQ==} + '@vue/compiler-ssr@3.5.40': resolution: {integrity: sha512-rrE5xiXG663+vHCHa3J9p2z5OcBRjXmoqenprJxAFQxg5pSshzeBiCE6pu46axapRJ2Adk0YDA2BRZVjiHXnhg==} + '@vue/compiler-ssr@3.5.43': + resolution: {integrity: sha512-GF62orf7KiJX9RqrHNGrYBudsQGD0OhJ5nDs90O8UiDuS40+YMYomiXu6w6EuvtXuRDc3MSNis3EaaSKAVSWpg==} + '@vue/devtools-api@6.6.4': resolution: {integrity: sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==} + '@vue/language-core@3.3.13': + resolution: {integrity: sha512-axA0Xemn5LuUKuKWob0/kVq7xQ2mJJM6VqA9Exvt35nM9yRC31goWVve/G/Zb2ZCLsXC8FHYjjfXlnshknSCew==} + '@vue/language-core@3.3.7': resolution: {integrity: sha512-LzmkKinXAMMoh8Jfi/jMUSDUjuPdv8mynH5WJGKfXyZtDw3hQ6GBaoI6Bcnl/Xqlu32q/0Z6i/trp4VXykzyLw==} '@vue/reactivity@3.5.40': resolution: {integrity: sha512-B7ot9UlUZOi1zbq61/LvE88ZLTV8IlajTdiZTAEiDQgrnIMIZoPr9kGw0Zw46ObW62O9+H/Be3kMbfb7kYPQZA==} + '@vue/reactivity@3.5.43': + resolution: {integrity: sha512-G/c9GyOZNI2jVaaS6OX1EF1SSFSv7H0ERqNTl4+DTFMlZmB5eVAB53aLQNam/7NL2NPtaDD7RdVrzf8uJzMuOA==} + '@vue/runtime-core@3.5.40': resolution: {integrity: sha512-KAZLweuZ6uUJPK1PMSQPgBU5gCjgrrfjUhSglmU9NhH+Zjepa8cnwSydPWDWHDwOgY4g3VcZ+PljbiHlURNCbw==} + '@vue/runtime-core@3.5.43': + resolution: {integrity: sha512-hU6U6VnVhBGQDpvlnnDlIB8ZGJBiOcgk2lh/0InltHiz3D8oSkluvuvY+do1G2H3+udeKFsmaBlgVYP7gXQzEw==} + '@vue/runtime-dom@3.5.40': resolution: {integrity: sha512-ZfrX8ssZQds900L9pr8AuK05ddnMsR4MPMZr8cPN9GoqoPWcXLhjvvbIA2SMv+7a97sJ1vv9pj/zxK0Cq/eEFQ==} + '@vue/runtime-dom@3.5.43': + resolution: {integrity: sha512-Bb2Jc0YjjJdMt1SJmb9b2L/IWd3I8lIT9x9eS/xvvP9CiVgna0ffua74xKRmt4/uSJ+0r4iN8ex1jrqkhQGWQw==} + '@vue/server-renderer@3.5.40': resolution: {integrity: sha512-XNJym9WpevhTVt1HuwOrCRJ5Q+9z4BjTMrDtjTrvx74SmUll8spNTw6whWJa9mEkO4PKn5TihI/bm/8ds2QVJw==} + '@vue/server-renderer@3.5.43': + resolution: {integrity: sha512-l2Ygjv9NehV94PSBxNWsAHC0j/eIIKbn92mBuWXAPGLnn6HfJ6MH5ubsd+Nk0YoZ5FRuxWI1P2VSoh+dbPQhCQ==} + '@vue/shared@3.5.40': resolution: {integrity: sha512-WxnBtruIqOoV3rA4jeKDWzrYI5h7Cp4+pjwDi8kWGHz+IslhiN+wguLVVhtv2l8VoU02rzDCVfDjgCl1lNpZVg==} + '@vue/shared@3.5.43': + resolution: {integrity: sha512-uksS7YGMR5NZyr4JNq0Rp+QyLns0ueaz20KwzIPW9R0LH1Vnt4E+XUM29PNseEbf1www2gOuhuDi5AKOIXag9Q==} + '@vue/tsconfig@0.7.0': resolution: {integrity: sha512-ku2uNz5MaZ9IerPPUyOHzyjhXoX2kVJaVf7hL315DC17vS6IiZRmmCPfggNbU16QTvM80+uYYy3eYJB59WCtvg==} peerDependencies: @@ -1268,6 +2259,18 @@ packages: alien-signals@3.2.1: resolution: {integrity: sha512-I8FjmltrfnDFoZedi5CG8DghVYNhzb/Ijluz7tCSJH0xpd0484Kowhbb1XDYOxfJpU1p5wnM2X54dA+IfGyD1g==} + angular-html-parser@10.13.0: + resolution: {integrity: sha512-7s1jbhRE+I4POZHNiIRtm3FhDsfiH2dtPqdNBW2Y7vYvqcuRN1lGxPJucfLouRjiEYSvJbMg0XfOh88QTBm3Lw==} + engines: {node: '>= 14'} + + ansi-colors@4.1.3: + resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} + engines: {node: '>=6'} + + ansi-escapes@7.3.0: + resolution: {integrity: sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==} + engines: {node: '>=18'} + ansi-regex@5.0.1: resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} engines: {node: '>=8'} @@ -1280,6 +2283,10 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@5.2.0: + resolution: {integrity: sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==} + engines: {node: '>=10'} + ansi-styles@6.2.3: resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} engines: {node: '>=12'} @@ -1320,6 +2327,17 @@ packages: resolution: {integrity: sha512-tLkvA81vQG/XqE2mjDkGQHoOINtMHtysSnemrmoGe6PydDPMRbVugqyk4A6V/WDWEfm3l+0d8anA9r8cv/5Jaw==} engines: {node: '>=12'} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + + astring@1.9.0: + resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==} + hasBin: true + + async-retry@1.3.3: + resolution: {integrity: sha512-wfr/jstw9xNi/0teMHrRW7dsz3Lt5ARhYNZ2ewpadnhaIp5mbALhOAP+EAdsC7t4Z6wqsDVv9+W6gm1Dk9mEyw==} + atomic-sleep@1.0.0: resolution: {integrity: sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==} engines: {node: '>=8.0.0'} @@ -1348,6 +2366,10 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + balanced-match@4.0.4: + resolution: {integrity: sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==} + engines: {node: 18 || 20 || >=22} + base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} @@ -1355,6 +2377,10 @@ packages: resolution: {integrity: sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A==} engines: {node: '>=6.0.0'} + basic-auth@2.0.1: + resolution: {integrity: sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==} + engines: {node: '>= 0.8'} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -1369,6 +2395,10 @@ packages: brace-expansion@2.1.2: resolution: {integrity: sha512-w5JZcKgdhDOgOwm8H+KgbosopHMuGcl6qbulwjtz3SM7I7P3yW1eAjzMPLrIE+NQ9vjgANKHWeMHnrT0OXW1oA==} + brace-expansion@5.0.12: + resolution: {integrity: sha512-YovQ3rzhaLMIrDjNDMkNS01tea93qhEhG5xy8f6+R0l+dw3Ki+5sCoIoI942iuLZTHWogWktgwVDhU09iNEimQ==} + engines: {node: 20 || >=22} + braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} @@ -1383,6 +2413,10 @@ packages: resolution: {integrity: sha512-ZMANVnAixE6AWWnPzlW2KpUrxhm9woycYvPOo67jWHyFowASTEd9s+QN1EIMsSDtwhIxN4sWE1jotpuDUIgyIw==} engines: {node: '>=6.14.2'} + bundle-name@4.1.1: + resolution: {integrity: sha512-DdH81/zPLVS11EUgWq3tEu/xn+EzljlMYooDNdzWEnFha3R3NBMpMV1UqYIpjYHV/SgpFKMIX1Oh7o06SjM/oA==} + engines: {node: '>=18'} + busboy@1.6.0: resolution: {integrity: sha512-8SFQbg/0hQ9xy3UNTB0YEnsNBbWfhf7RtnzpL7TkBiTBRfrQ9Fxcnz7VJsleJpyp6rVLvXiuORqjlHi5q+PYuA==} engines: {node: '>=10.16.0'} @@ -1411,18 +2445,42 @@ packages: resolution: {integrity: sha512-kfzR4zzQtAE9PC7CzZsjl3aBNbXWuXiSeOCdLcPpBfGW8YuCqQHcRPFDbr/BPVmd3EEPVpuFzLyuT/cUhPr4OQ==} engines: {node: '>=12.20'} + camelcase@9.0.0: + resolution: {integrity: sha512-TO9xmyXTZ9HUHI8M1OnvExxYB0eYVS/1e5s7IDMTAoIcwUd+aNcFODs6Xk83mobk0velyHFQgA1yIrvYc6wclw==} + engines: {node: '>=20'} + + case-anything@3.1.7: + resolution: {integrity: sha512-52UPzAJDZgxaNsYK4kvmov1kVaAfPc+OU2j0OSUZWbdWMuJd7Axi94XWSfSuafMd7K9avhsEnU6W6rXJdAd+Ug==} + engines: {node: '>=18'} + cbor@8.1.0: resolution: {integrity: sha512-DwGjNW9omn6EwP70aXsn7FQJx5kO12tX0bZkaTjzdVFM6/7nhA4t0EENocKGx6D2Bch9PE2KzCUf5SceBdeijg==} engines: {node: '>=12.19'} + chai@6.3.0: + resolution: {integrity: sha512-XWAtwJ6OHO+tj0EKCs0Y2UamnyOxseZWltU4x2U2wh8g4AigdjwvtUjvLP2tqkA/avxHEtzxNaqGq/YGNwckKg==} + engines: {node: '>=18'} + + chalk@4.1.2: + resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} + engines: {node: '>=10'} + chalk@5.6.2: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} engines: {node: ^12.17.0 || ^14.13 || >=16.0.0} + check-disk-space@3.4.0: + resolution: {integrity: sha512-drVkSqfwA+TvuEhFipiR1OC9boEGZL5RrWvVsOthdcvQNXyCCuKkEiTOTXZ7qxSf/GLwq4GvzfrQD/Wz325hgw==} + engines: {node: '>=16'} + chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + chunkd@2.0.1: resolution: {integrity: sha512-7d58XsFmOq0j6el67Ug9mHf9ELUXsQXYJBkyxhH/k+6Ke0qXRnv0kbemx+Twc6fRJ07C49lcbdgm9FL1Ei/6SQ==} @@ -1441,18 +2499,41 @@ packages: resolution: {integrity: sha512-3yONmlN9CSAkzNwnRCiJQ7Q2xK5mWuEfL3PuTZcAUzhObbXsfsnMptJzXwz93nc5zn9V9TwCVMmV7w4xsm43dw==} engines: {node: '>=0.10.0'} + cli-boxes@4.0.1: + resolution: {integrity: sha512-5IOn+jcCEHEraYolBPs/sT4BxYCe2nHg374OPiItB1O96KZFseS2gthU4twyYzeDcFew4DaUM/xwc5BQf08JJw==} + engines: {node: '>=18.20 <19 || >=20.10'} + + cli-cursor@5.0.0: + resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==} + engines: {node: '>=18'} + + cli-table3@0.6.5: + resolution: {integrity: sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==} + engines: {node: 10.* || >= 12.*} + cli-truncate@3.1.0: resolution: {integrity: sha512-wfOBkjXteqSnI59oPcJkcPl/ZmwvMMOj340qUIY1SKZCv0B9Cf4D4fAucRkIKQmsIuYK3x1rrgU7MeGRruiuiA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cli-truncate@5.2.0: + resolution: {integrity: sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==} + engines: {node: '>=20'} + cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} + cluster-key-slot@1.1.1: + resolution: {integrity: sha512-rwHwUfXL40Chm1r08yrhU3qpUvdVlgkKNeyeGPOxnW8/SyVDvgRaed/Uz54AqWNaTCAThlj6QAs3TZcKI0xDEw==} + engines: {node: '>=0.10.0'} + cluster-key-slot@1.1.2: resolution: {integrity: sha512-RMr0FhtfXemyinomL4hrWcYJxmX6deFdCxpJzhDttxgO1+bcCnkk+9drydLVDmAMG7NE6aN/fl4F7ucU/90gAA==} engines: {node: '>=0.10.0'} + code-block-writer@13.0.3: + resolution: {integrity: sha512-Oofo0pq3IKnsFtuHqSF7TqBfr71aeyZDVJ0HpmqB7FBM2qEigL0iPONSCZSO9pE9dZTAxANe5XHG9Uy0YMv8cg==} + code-excerpt@4.0.0: resolution: {integrity: sha512-xxodCmBen3iy2i0WtAK8FlFNrRzjUqjRsMfho58xT/wvZU1YTM3fCnRjcy1gJPMepaRlgm/0e6w8SpWHpn3/cA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -1467,6 +2548,16 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + colorette@2.0.19: + resolution: {integrity: sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==} + + colorette@2.0.20: + resolution: {integrity: sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==} + + commander@10.0.1: + resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} + engines: {node: '>=14'} + common-path-prefix@3.0.0: resolution: {integrity: sha512-QE33hToZseCH3jS0qN96O/bSh3kaw/h+Tq7ngyY9eWDUnTlTNUyqfqvCXioLe5Na5jFsL78ra/wuBU4iuEgd4w==} @@ -1482,14 +2573,25 @@ packages: resolution: {integrity: sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ==} engines: {node: '>= 0.6'} + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + content-type@1.0.5: resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} engines: {node: '>= 0.6'} + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + convert-to-spaces@2.0.1: resolution: {integrity: sha512-rcQ1bsQO9799wq24uE5AM2tAILy4gXGIK/njFWcVQkGNZ96edlpY+A7bjwvzjYvLDyzmG1MmMLZhpcsb+klNMQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + cookie-es@3.1.1: + resolution: {integrity: sha512-UaXxwISYJPTr9hwQxMFYZ7kNhSXboMXP+Z3TRX6f1/NyaGPfuNUZOWP1pUEb75B2HjfklIYLVRfWiFZJyC6Npg==} + cookie-signature@1.0.7: resolution: {integrity: sha512-NXdYc3dLr47pBkpUCHtKSwIOQXLVn8dZEuywboCOJY/osA0wFSLlSawr3KN8qXJEyX66FcONTH8EIlVuK0yyFA==} @@ -1510,6 +2612,10 @@ packages: resolution: {integrity: sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==} engines: {node: '>= 8'} + csrf@3.1.0: + resolution: {integrity: sha512-uTqEnCvWRk042asU6JtapDTcJeeailFy4ydOQS28bj1hcLnYRiqi8SsD2jS412AY1I/4qdOwWZun774iqywf9w==} + engines: {node: '>= 0.8'} + cssesc@3.0.0: resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} engines: {node: '>=4'} @@ -1526,6 +2632,9 @@ packages: resolution: {integrity: sha512-uqCUKXE5q1PNBXjPqvwhwJf9SwMoAHBgWJ6DcrnS5o+W2JOiIILl0JEdVD8SGujrNS02GGxgwAg2PN2zONgtjg==} engines: {node: '>=6'} + dateformat@4.6.3: + resolution: {integrity: sha512-2P0p0pFGzHS5EMnhdxQi7aJN+iMheud0UhG4dlE1DLAlvL8JHjJJTX/CSm4JXwV0Ka5nGk3zC5mcb5bUQUxxMA==} + dayjs@1.11.21: resolution: {integrity: sha512-98IT+HOahAisibz/yjKbzuOBwYcjJ7BCLPzARyHiyEBmRz4fatF+KPJszEHXsGYjUG234aH/cOjW1wwTbKUZlA==} @@ -1537,6 +2646,15 @@ packages: supports-color: optional: true + debug@4.3.4: + resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1558,10 +2676,26 @@ packages: resolution: {integrity: sha512-aWS3UIVH+NPGCD1kki+DCU9Dua032iSsO43LqQpcs4R3+dVv7tX0qBGjiVHJHjplsoUM2XRO/KB92glqc68awg==} deprecated: Package no longer supported. Contact Support at https://www.npmjs.com/support for more info. + deepmerge@4.3.1: + resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} + engines: {node: '>=0.10.0'} + + default-browser-id@5.0.1: + resolution: {integrity: sha512-x1VCxdX4t+8wVfd1so/9w+vQ4vx7lKd2Qp5tDRutErwmR85OgmfX7RlLRMWafRMY7hbEiXIbudNrjOAPa/hL8Q==} + engines: {node: '>=18'} + + default-browser@5.5.1: + resolution: {integrity: sha512-m1pAzaJgZ/gssEqlOhJkPJp8Xly7QyW6xcrkUa2KKcDeDSEMP7X8xipU3snUcfisTQx0w1AGae+9UtJSfVnXGw==} + engines: {node: '>=18'} + define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} + define-lazy-prop@3.0.0: + resolution: {integrity: sha512-N+MeXYoqr3pOgn8xfyRPREN7gHakLYjhsHhWGT3fWAiL4IkAt0iDw14QiiEm2bE30c5XX5q0FtAA3CK5f9/BUg==} + engines: {node: '>=12'} + denque@2.1.0: resolution: {integrity: sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==} engines: {node: '>=0.10'} @@ -1589,6 +2723,9 @@ packages: resolution: {integrity: sha512-tU2NFr823X3TXEc8KyR/4m296KLxPai4nirN3q9kHCpY4TKj96n9lHZnyLzRNMui8EbL07jg9hgH2PWWfKMGIg==} engines: {node: '>=18'} + dlv@1.1.3: + resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==} + dotenv@16.6.1: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} @@ -1604,6 +2741,22 @@ packages: eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + edge-error@4.0.2: + resolution: {integrity: sha512-jB76VYn8wapDHKHSOmP3vbKLoa77RJYsTLNmfl8+cuCD69uxZtP3h+kqV+Prw/YkYmN7yHyp4IApE15pDByk0A==} + engines: {node: '>=18.16.0'} + + edge-lexer@6.0.5: + resolution: {integrity: sha512-paSprHn8GRzOUWTVLapgacqDBSOpJgOY60/V5QQ8bbNLHRKUMSxp8Z2oOO0WKtcKmb5+sAlmvG3izhbFulp19A==} + engines: {node: '>=24.0.0'} + + edge-parser@9.1.1: + resolution: {integrity: sha512-kem/vInJgTzHCABdFe060WGjyGva8j23QwVbZkNFXkNAQhRz3mga5kNBuPFYQ3t73nPT2vZ8WOGV4OCS0P16Cw==} + engines: {node: '>=24.0.0'} + + edge.js@6.5.1: + resolution: {integrity: sha512-+NgWA8KunEdhVB247GWdmqUZ3MSIExeUCAbWNgNvA0ONH43UL+a/l6AE8GsevT4beqVsbp4Q6USwSpfbnMqBkQ==} + engines: {node: '>=18.16.0'} + ee-first@1.1.1: resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} @@ -1621,14 +2774,31 @@ packages: resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} engines: {node: '>= 0.8'} + end-of-stream@1.4.5: + resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} + enhanced-resolve@5.24.2: resolution: {integrity: sha512-rpsZEGT1jFuve6QlpyRp9ckQ+kN61hvF9BzCPyMdaKTm8UJce96KBn3sorXOFXlzjPrs3Vc4T1NsSroZ3PxlFw==} engines: {node: '>=10.13.0'} + enquirer@2.4.1: + resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} + engines: {node: '>=8.6'} + entities@7.0.1: resolution: {integrity: sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==} engines: {node: '>=0.12'} + environment@1.1.0: + resolution: {integrity: sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==} + engines: {node: '>=18'} + + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + error-stack-parser-es@2.0.1: + resolution: {integrity: sha512-J36ntO+rMQVRuR/umlmxmfLi4TpWwtmTnHoJoXTiC2xDNazs0VDPKcX6pbhZMDd2HFtH9isMBJXMdbki+A++Pg==} + es-define-property@1.0.1: resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} engines: {node: '>= 0.4'} @@ -1637,14 +2807,24 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: + resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-object-atoms@1.1.2: resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} + es-toolkit@1.52.0: + resolution: {integrity: sha512-XTNEJQh1tY1ZJVcf6ayP/2n4ZPyaHlW2FWs7xvw5ddPuhUVjLD3olQVQS7kf58JbAB48iL0uL/jerTrjtV3lDA==} + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-goat@4.0.0: + resolution: {integrity: sha512-2Sd4ShcWxbx6OY1IHyla/CVNwvg7XwZVoXZHcSu9w9SReNP1EzzD5T8NWKIR38fIqEns9kDWKUQTXXAmlDrdPg==} + engines: {node: '>=12'} + escape-html@1.0.3: resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} @@ -1680,6 +2860,10 @@ packages: resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} engines: {node: '>= 0.6'} + execa@9.6.1: + resolution: {integrity: sha512-9Be3ZoN4LmYR90tUoVu2te2BsbzHfhJyfEiAVfz7N5/zv+jduIfLrV2xdQXOHbaD6KgpGdO9PRPM1Y4Q9QkPkA==} + engines: {node: ^18.19.0 || >=20.5.0} + express@4.22.2: resolution: {integrity: sha512-IuL+Elrou2ZvCFHs18/CIzy2Nzvo25nZ1/D2eIZlz7c+QUayAcYoiM2BthCjs+EBHVpjYjcuLDAiCWgeIX3X1Q==} engines: {node: '>= 0.10.0'} @@ -1687,6 +2871,9 @@ packages: fast-content-type-parse@1.1.0: resolution: {integrity: sha512-fBHHqSTFLVnR61C+gltJuE5GkVQMV0S2nqUO8TJ+5Z3qAKG8vAx4FKai1s5jq/inV1+sREynIWSuQ6HgoSXpDQ==} + fast-copy@4.1.2: + resolution: {integrity: sha512-DUHggaYcouhy5I1LacDJ+JDSqGlumVJP2EAi5Nwt1pWPeLpSvIjkrY+x4fsoI1/+GlTyq+DM9zdgWCFSfqNODA==} + fast-decode-uri-component@1.0.1: resolution: {integrity: sha512-WKgKWg5eUxvRZGwW8FvfbaH7AXSh2cL+3j5fMGzUMCxWBJ3dV3a7Wz8y2f/uQ0e3B6WmodD3oS54jTQ9HVTIIg==} @@ -1706,12 +2893,19 @@ packages: fast-querystring@1.1.2: resolution: {integrity: sha512-g6KuKWmFXc0fID8WWH0jit4g0AGBoJhCkJMb1RmbsSEUNvQ+ZC8D6CUZ+GtF8nMzSPXnhiePyyqqipzNNEnHjg==} + fast-safe-stringify@2.1.1: + resolution: {integrity: sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==} + fast-uri@2.4.2: resolution: {integrity: sha512-Ll1wlF3LBJ2+vFEeTSH9SFrjnXJorZQexrn0yHa4BJdGS+FFkWW3xU/YuIdmdyloSDuUgTYh/YeY/vUNcdCS/g==} fast-uri@3.1.3: resolution: {integrity: sha512-i70LwGWUduXqzicKXWshooq+sWL1K3WUU5rKZNG/0i3a1OSoX3HqhH5WbWwTmqWfor4urUakGPiRQcleRZTwOg==} + fastest-levenshtein@1.0.16: + resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} + engines: {node: '>= 4.9.1'} + fastify-plugin@4.5.1: resolution: {integrity: sha512-stRHYGeuqpEZTL1Ef0Ovr2ltazUT9g844X5z/zEBFLG8RYlpDiOCIG+ATvYEp+/zmc7sN29mcIMp8gvYplYPIQ==} @@ -1734,6 +2928,14 @@ packages: resolution: {integrity: sha512-ej8ksPF4x6e5wvK9yevct0UCXh8TTFlWGVLlgjZuoBH1HwjIfKE/IdL5mq89sFA7zELi1VhKpmtDnrs7zWyeyg==} engines: {node: '>=14'} + figures@6.1.0: + resolution: {integrity: sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==} + engines: {node: '>=18'} + + file-type@22.1.1: + resolution: {integrity: sha512-sEB0oStmeLGtpmSAD88RDNuLsvhv4iC3u0lE25CUvfCULvj49xoQ3l3K525Vn+ZzsZ6DOLajQCV6RmhwwhqiJg==} + engines: {node: '>=22'} + fill-range@7.1.1: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} @@ -1742,10 +2944,18 @@ packages: resolution: {integrity: sha512-aA4RyPcd3badbdABGDuTXCMTtOneUCAYH/gxoYRTZlIJdF0YPWuGqiAsIrhNnnqdXGswYk6dGujem4w80UJFhg==} engines: {node: '>= 0.8'} + find-cache-directory@6.0.0: + resolution: {integrity: sha512-CvFd5ivA6HcSHbD+59P7CyzINHXzwhuQK8RY7CxJZtgDSAtRlHiCaQpZQ2lMR/WRyUIEmzUvL6G2AGurMfegZA==} + engines: {node: '>=20'} + find-my-way@8.2.2: resolution: {integrity: sha512-Dobi7gcTEq8yszimcfp/R7+owiT4WncAJ7VTTgFH1jYJ5GaG1FbhjwDG820hptN0QDFvzVY3RfCzdInvGPGzjA==} engines: {node: '>=14'} + find-up-simple@1.0.1: + resolution: {integrity: sha512-afd4O7zpqHeRyg4PfDQsXmlDe2PfdHtJt6Akt8jOWaApLOZk5JXs6VMR29lz03pRe9mpykrRCYIYxaJYcfpncQ==} + engines: {node: '>=18'} + find-up@3.0.0: resolution: {integrity: sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==} engines: {node: '>=6'} @@ -1754,6 +2964,10 @@ packages: resolution: {integrity: sha512-v2ZsoEuVHYy8ZIlYqwPe/39Cy+cFDzp4dXPaxNvkEuouymu+2Jbz0PxpKarJHYJTmv2HWT3O382qY8l4jMWthw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -1773,6 +2987,10 @@ packages: resolution: {integrity: sha512-zJ2mQYM18rEFOudeV4GShTGIQ7RbzA7ozbU9I/XBpm7kqgMywgmylMwXHxZJmkVoYkna9d2pVXVXPdYTP9ej8Q==} engines: {node: '>= 0.6'} + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fs-extra@8.1.0: resolution: {integrity: sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==} engines: {node: '>=6 <7 || >=8'} @@ -1792,18 +3010,44 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} + engines: {node: '>=18'} + get-intrinsic@1.3.0: resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} engines: {node: '>= 0.4'} + get-package-type@0.1.0: + resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} + engines: {node: '>=8.0.0'} + + get-port@7.2.0: + resolution: {integrity: sha512-afP4W205ONCuMoPBqcR6PSXnzX35KTcJygfJfcp+QY+uwm3p20p1YczWXhlICIzGMCxYBQcySEcOgsJcrkyobg==} + engines: {node: '>=16'} + get-proto@1.0.1: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} + get-stream@9.0.1: + resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} + engines: {node: '>=18'} + + get-tsconfig@4.14.3: + resolution: {integrity: sha512-++QEw4DIY7WGoukz+/+A/8dGYPT9l9yIadnmSgZ8Rjr3YVSVDipQSO9CdnJo9ePqFqUUqh+wk9uIaoiAwsiPkA==} + + getopts@2.3.0: + resolution: {integrity: sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} + glob-parent@6.0.2: + resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} + engines: {node: '>=10.13.0'} + glob@10.5.0: resolution: {integrity: sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==} deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me @@ -1820,6 +3064,10 @@ packages: graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} + has-flag@4.0.0: + resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} + engines: {node: '>=8'} + has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -1835,13 +3083,30 @@ packages: resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} engines: {node: '>= 0.4'} - highlight.js@10.7.3: - resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} + he@1.2.0: + resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} + hasBin: true + + help-me@5.0.0: + resolution: {integrity: sha512-7xgomUX6ADmcYzFik0HzAxh/73YlKR9bmFzf51CZwR+b6YtzU2m0u49hQCqV6SvlqIqsaxovfwdvbnsw3b/zpg==} + + highlight.js@10.7.3: + resolution: {integrity: sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==} highlight.js@11.11.1: resolution: {integrity: sha512-Xwwo44whKBVCYoliBQwaPvtd/2tYFkRQtXDWj1nackaV2JPXx3L0+Jvd8/qCJ2p+ML0/XVkJ2q+Mr+UVdpJK5w==} engines: {node: '>=12.0.0'} + hosted-git-info@9.0.3: + resolution: {integrity: sha512-Hc+ghLoSt6QaYZUv0WBiIvmMDZuZZ7oaDvdH8MbfOO4lOsxdXLEvuC6ePoGs9H1X9oCLyq6+NVN0MKqD+ydxyg==} + engines: {node: ^20.17.0 || >=22.9.0} + + hot-hook@1.0.0: + resolution: {integrity: sha512-OkZm5tTE4ej8ur8VlcQwMm8G9sFxu4D+shM+ol/h4mrUhuZvFkjk5n/nWKmLq3COmy6epLN7XIIQJ75tnqCGIw==} + + html-entities@2.6.0: + resolution: {integrity: sha512-kig+rMn/QOVRvr7c86gQ8lWXq+Hkv6CbAH1hLu+RG338StTpE8Z0b44SDVaqVu7HGKf27frdmUYEs9hTUX/cLQ==} + http-errors@2.0.0: resolution: {integrity: sha512-FtwrG/euBzaEjYeRqOgly7G0qviiXoJWnvEH2Z1plBdXgbyjv34pHTSb9zoeHMyDy33+DWy5Wt9Wo+TURtOYSQ==} engines: {node: '>= 0.8'} @@ -1850,6 +3115,10 @@ packages: resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} engines: {node: '>= 0.8'} + human-signals@8.0.1: + resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} + engines: {node: '>=18.18.0'} + humanize-duration@3.34.0: resolution: {integrity: sha512-NDxhYxiiRzsST6xULIHuYWRvsCtviJXRdjarhyWyh78S4Ou+MWhM2k4HQ+y7iegdrzreXe11isd0au1N2PB/pQ==} @@ -1864,6 +3133,10 @@ packages: ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + igniculus@1.5.0: + resolution: {integrity: sha512-vhj2J/cSzNg2G5tcK4Z1KZdeYmQa5keoxFULUYAxctK/zHJb1oraO7noCqnJxKe1b2eZdiiaSL1IHPOFAI8UYQ==} + engines: {node: '>=4.0.0'} + ignore-by-default@2.1.0: resolution: {integrity: sha512-yiWd4GVmJp0Q6ghmM2B/V3oZGRmjrKLXvHR3TE1nfoXsmoggllfZUQe74EN0fJdPFZu2NIvNdrMMLm3OsV7Ohw==} engines: {node: '>=10 <11 || >=12 <13 || >=14'} @@ -1872,6 +3145,9 @@ packages: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} + import-meta-resolve@4.2.0: + resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + imurmurhash@0.1.4: resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} engines: {node: '>=0.8.19'} @@ -1880,9 +3156,25 @@ packages: resolution: {integrity: sha512-m6FAo/spmsW2Ab2fU35JTYwtOKa2yAwXSwgjSv1TJzh4Mh7mC3lzAOVLBprb72XsTrgkEIsl7YrFNAiDiRhIGg==} engines: {node: '>=12'} + index-to-position@1.2.0: + resolution: {integrity: sha512-Yg7+ztRkqslMAS2iFaU+Oa4KTSidr63OsFGlOrJoW981kIYO3CGCS3wA95P1mUi/IVSJkn0D479KTJpVpvFNuw==} + engines: {node: '>=18'} + + inflation@2.1.0: + resolution: {integrity: sha512-t54PPJHG1Pp7VQvxyVCJ9mBbjG3Hqryges9bXoOO6GExCPa+//i/d5GSuFtpx3ALLd7lgIAur6zrIlBQyJuMlQ==} + engines: {node: '>= 0.8.0'} + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + interpret@2.2.0: + resolution: {integrity: sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==} + engines: {node: '>= 0.10'} + + ioredis@6.0.0: + resolution: {integrity: sha512-f+Dtubxfpf6KYFq7WVXJoOLn0bk4TJrMrN9SzeE+jrWrCWj7XX3fA6vkryafhADX+GMymRxgDJDOI33COkJc0w==} + engines: {node: '>=20.0.0'} + ipaddr.js@1.9.1: resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} engines: {node: '>= 0.10'} @@ -1899,6 +3191,15 @@ packages: resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} engines: {node: '>= 0.4'} + is-core-module@2.17.0: + resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} + engines: {node: '>= 0.4'} + + is-docker@3.0.0: + resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==} + engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + hasBin: true + is-error@2.2.2: resolution: {integrity: sha512-IOQqts/aHWbiisY5DuPJQ0gcbvaLFCa7fBa9xoLfxBZvQ+ZI/Zh9xoI7Gk+G64N0FdK4AbibytHht2tWgpJWLg==} @@ -1914,10 +3215,23 @@ packages: resolution: {integrity: sha512-O4L094N2/dZ7xqVdrXhh9r1KODPJpFms8B5sGdJLPy664AgvXsreZUyCQQNItZRDlYug4xStLjNp/sz3HvBowQ==} engines: {node: '>=12'} + is-fullwidth-code-point@5.1.0: + resolution: {integrity: sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==} + engines: {node: '>=18'} + is-glob@4.0.3: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-in-ssh@1.0.0: + resolution: {integrity: sha512-jYa6Q9rH90kR1vKB6NM7qqd1mge3Fx4Dhw5TVlK1MUBqhEOuCagrEHMevNuCcbECmXZ0ThXkRm+Ymr51HwEPAw==} + engines: {node: '>=20'} + + is-inside-container@1.0.0: + resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} + engines: {node: '>=14.16'} + hasBin: true + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} @@ -1926,6 +3240,10 @@ packages: resolution: {integrity: sha512-DailKdLb0WU+xX8K5w7VsJhapwHLZ9jjmazqCJq4X12CTgqq73TKnbRcnSLuXYPOoLQgV5IrD7ePiX/h1vnkBw==} engines: {node: '>=8'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + is-plain-object@5.0.0: resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} engines: {node: '>=0.10.0'} @@ -1936,6 +3254,10 @@ packages: is-property@1.0.2: resolution: {integrity: sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==} + is-stream@4.0.1: + resolution: {integrity: sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==} + engines: {node: '>=18'} + is-typed-array@1.1.15: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} @@ -1944,6 +3266,14 @@ packages: resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==} engines: {node: '>=12'} + is-unicode-supported@2.1.0: + resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} + engines: {node: '>=18'} + + is-wsl@3.1.1: + resolution: {integrity: sha512-e6rvdUCiQCAuumZslxRJWR/Doq4VpPR82kqclvcS0efgt430SlGIk05vdCN58+VrzgtIcfNODjozVielycD4Sw==} + engines: {node: '>=16'} + isarray@2.0.5: resolution: {integrity: sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==} @@ -1953,14 +3283,28 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + jest-diff@30.5.2: + resolution: {integrity: sha512-rBtHnI6BWTiWj3lM7fOLVfChx7R9B0u9VV3PRHawKs79x6ZjW1QoSrKenaigNGWlvhtoi2BqvDbABDie+Os3xQ==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jiti@2.7.0: resolution: {integrity: sha512-AC/7JofJvZGrrneWNaEnJeOLUx+JlGt7tNa0wZiRPT4MY1wmfKjt2+6O2p2uz2+skll8OZZmJMNqeke7kKbNgQ==} hasBin: true + joycon@3.1.1: + resolution: {integrity: sha512-34wB/Y7MW7bzjKRjUKTa46I2Z7eV62Rkhva+KkopW7Qvv/OSWBqvkSY7vusOPrNuZcUG3tApvdVgNB8POj3SPw==} + engines: {node: '>=10'} + js-string-escape@1.0.1: resolution: {integrity: sha512-Smw4xcfIQ5LVjAOuJCvN/zIodzA/BBSsluuoSykP+lUvScIi4U6RJLfwHet5cxFnCswUjISV8oAXaqaJDY3chg==} engines: {node: '>= 0.8'} + js-stringify@1.0.2: + resolution: {integrity: sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g==} + + js-tokens@4.0.0: + resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} + js-yaml@3.15.0: resolution: {integrity: sha512-ttBQIIQPDeLjpPOohtUdXuXUVoA2uIB6fEH9HyJ7234s5mBJ5wTx20njxplLZQgLaOfpmPQA7X2t5AX6tIPbog==} hasBin: true @@ -1988,9 +3332,70 @@ packages: jsonfile@5.0.0: resolution: {integrity: sha512-NQRZ5CRo74MhMMC3/3r5g2k4fjodJ/wh8MxjFbCViWKFjxrnudWSY5vomh+23ZaXzAS7J3fBZIR2dV6WbmfM0w==} + jsonschema@1.5.0: + resolution: {integrity: sha512-K+A9hhqbn0f3pJX17Q/7H6yQfD/5OXgdrR5UE12gMXCiN9D5Xq2o5mddV2QEcX/bjla99ASsAAQUyMCCRWAEhw==} + + junk@4.0.1: + resolution: {integrity: sha512-Qush0uP+G8ZScpGMZvHUiRfI0YBWuB3gVBYlI0v0vvOJt5FLicco+IkP0a50LqTTQhmts/m6tP5SWE+USyIvcQ==} + engines: {node: '>=12.20'} + + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + + knex-dynamic-connection@5.1.1: + resolution: {integrity: sha512-xtl22O5I8e+G3ie90FfRaiODnYDgLD1erJeaeKVP+zuj4WMNJpgdmhs0qVaeigAJXsthCYA+pjmegXZh4xg2TA==} + engines: {node: '>=24.0.0'} + + knex@3.3.0: + resolution: {integrity: sha512-LgWl031hNuLv9Lhxdd9093zULa2aNcoP04Bk29e5NidgRcEr/T0rAr2WYi4BhjTiCDoQiRU56meUE5rppLKZzQ==} + engines: {node: '>=16'} + hasBin: true + peerDependencies: + better-sqlite3: '*' + mariadb: '*' + mysql: '*' + mysql2: '*' + pg: '*' + pg-native: '*' + pg-query-stream: ^4.14.0 + sqlite3: '*' + tedious: '*' + peerDependenciesMeta: + better-sqlite3: + optional: true + mariadb: + optional: true + mysql: + optional: true + mysql2: + optional: true + pg: + optional: true + pg-native: + optional: true + pg-query-stream: + optional: true + sqlite3: + optional: true + tedious: + optional: true + knub-command-manager@9.1.0: resolution: {integrity: sha512-pEtpWElbBoTRSL8kWSPRrTIuTIdvYGkP/wzOn77cieumC02adfwEt1Cc09HFvVT4ib35nf1y31oul36csaG7Vg==} + ky@1.14.3: + resolution: {integrity: sha512-9zy9lkjac+TR1c2tG+mkNSVlyOpInnWdSMiue4F+kq8TwJSgv6o8jhLRg8Ho6SnZ9wOYUq/yozts9qQCfk7bIw==} + engines: {node: '>=18'} + + laravel-precognition@2.1.0: + resolution: {integrity: sha512-W9ZobjRAReiIawSWxXUPR6q+Bvq5seO6tn+scdURl/JKOFKveXvR4Sno2KxGqQt2cI81nh8Vt2cFlaOMqXqLNw==} + peerDependencies: + axios: ^1.4.0 + peerDependenciesMeta: + axios: + optional: true + light-my-request@5.14.0: resolution: {integrity: sha512-aORPWntbpH5esaYpGOOmri0OHDOe3wC5M2MQxZ9dvMLZm6DnaAn0kJlcbU9hwsQgLzmZyReKwFwwPkR+nHu5kA==} @@ -2000,30 +3405,60 @@ packages: cpu: [arm64] os: [android] + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + lightningcss-darwin-arm64@1.32.0: resolution: {integrity: sha512-RzeG9Ju5bag2Bv1/lwlVJvBE3q6TtXskdZLLCyfg5pt+HLz9BqlICO7LZM7VHNTTn/5PRhHFBSjk5lc4cmscPQ==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [darwin] + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + lightningcss-darwin-x64@1.32.0: resolution: {integrity: sha512-U+QsBp2m/s2wqpUYT/6wnlagdZbtZdndSmut/NJqlCcMLTWp5muCrID+K5UJ6jqD2BFshejCYXniPDbNh73V8w==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [darwin] + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + lightningcss-freebsd-x64@1.32.0: resolution: {integrity: sha512-JCTigedEksZk3tHTTthnMdVfGf61Fky8Ji2E4YjUTEQX14xiy/lTzXnu1vwiZe3bYe0q+SpsSH/CTeDXK6WHig==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [freebsd] + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + lightningcss-linux-arm-gnueabihf@1.32.0: resolution: {integrity: sha512-x6rnnpRa2GL0zQOkt6rts3YDPzduLpWvwAF6EMhXFVZXD4tPrBkEFqzGowzCsIWsPjqSK+tyNEODUBXeeVHSkw==} engines: {node: '>= 12.0.0'} cpu: [arm] os: [linux] + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + lightningcss-linux-arm64-gnu@1.32.0: resolution: {integrity: sha512-0nnMyoyOLRJXfbMOilaSRcLH3Jw5z9HDNGfT/gwCPgaDjnx0i8w7vBzFLFR1f6CMLKF8gVbebmkUN3fa/kQJpQ==} engines: {node: '>= 12.0.0'} @@ -2031,6 +3466,13 @@ packages: os: [linux] libc: [glibc] + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + lightningcss-linux-arm64-musl@1.32.0: resolution: {integrity: sha512-UpQkoenr4UJEzgVIYpI80lDFvRmPVg6oqboNHfoH4CQIfNA+HOrZ7Mo7KZP02dC6LjghPQJeBsvXhJod/wnIBg==} engines: {node: '>= 12.0.0'} @@ -2038,6 +3480,13 @@ packages: os: [linux] libc: [musl] + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + lightningcss-linux-x64-gnu@1.32.0: resolution: {integrity: sha512-V7Qr52IhZmdKPVr+Vtw8o+WLsQJYCTd8loIfpDaMRWGUZfBOYEJeyJIkqGIDMZPwPx24pUMfwSxxI8phr/MbOA==} engines: {node: '>= 12.0.0'} @@ -2045,6 +3494,13 @@ packages: os: [linux] libc: [glibc] + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + lightningcss-linux-x64-musl@1.32.0: resolution: {integrity: sha512-bYcLp+Vb0awsiXg/80uCRezCYHNg1/l3mt0gzHnWV9XP1W5sKa5/TCdGWaR/zBM2PeF/HbsQv/j2URNOiVuxWg==} engines: {node: '>= 12.0.0'} @@ -2052,22 +3508,45 @@ packages: os: [linux] libc: [musl] + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + lightningcss-win32-arm64-msvc@1.32.0: resolution: {integrity: sha512-8SbC8BR40pS6baCM8sbtYDSwEVQd4JlFTOlaD3gWGHfThTcABnNDBda6eTZeqbofalIJhFx0qKzgHJmcPTnGdw==} engines: {node: '>= 12.0.0'} cpu: [arm64] os: [win32] + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + lightningcss-win32-x64-msvc@1.32.0: resolution: {integrity: sha512-Amq9B/SoZYdDi1kFrojnoqPLxYhQ4Wo5XiL8EVJrVsB8ARoC1PWW6VGtT0WKCemjy8aC+louJnjS7U18x3b06Q==} engines: {node: '>= 12.0.0'} cpu: [x64] os: [win32] + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + lightningcss@1.32.0: resolution: {integrity: sha512-NXYBzinNrblfraPGyrbPoD19C1h9lfI/1mzgWYvXUTe414Gz/X1FD2XBZSZM7rRTrMA8JL3OtAaGifrIKhQ5yQ==} engines: {node: '>= 12.0.0'} + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + load-json-file@7.0.1: resolution: {integrity: sha512-Gnxj3ev3mB5TkVBGad0JM6dmLiQL+o0t23JPBZ9sd+yvSLk05mFoqKBw5N8gbbkU4TNXyqCgIrl/VM17OgUIgQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -2089,16 +3568,34 @@ packages: lodash@4.18.1: resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} + log-update@7.2.0: + resolution: {integrity: sha512-iLs7dGSyjZiUgvrUvuD3FndAxVJk+TywBkkkwUSm9HdYoskJalWg5qVsEiXeufPvRVPbCUmNQewg798rx+sPXg==} + engines: {node: '>=20'} + long@5.3.2: resolution: {integrity: sha512-mNAgZ1GmyNhD7AuqnTG3/VQ26o760+ZYBPKjPvugO8+nLbYfX6TVpJPseBvopbdY+qpZ/lKUnmEc1LeZYS3QAA==} lru-cache@10.4.3: resolution: {integrity: sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==} + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} + engines: {node: 20 || >=22} + lru.min@1.1.4: resolution: {integrity: sha512-DqC6n3QQ77zdFpCMASA1a3Jlb64Hv2N2DciFGkO/4L9+q/IpIAuRlKOvCXabtRW6cQf8usbmM6BE/TOPysCdIA==} engines: {bun: '>=1.0.0', deno: '>=1.30.0', node: '>=8.0.0'} + lucide-vue-next@1.0.0: + resolution: {integrity: sha512-V6SPvx1IHTj/UY+FrIYWV5faISsPSb8BnWSFDxAtezWKvWc9ZZ40PDrdu1/Qb5vg4lHWr1hs1BAMGVGm6V1Xdg==} + deprecated: Package deprecated. Please use @lucide/vue instead. + peerDependencies: + vue: '>=3.0.1' + + luxon@3.7.2: + resolution: {integrity: sha512-vtEhXh/gNjI9Yg1u4jX/0YVPMvxzHuGgCm6tC5kZyb08yjGWGnqAjGJvcXbqQR2P3MyMEFnRbpcdFS6PBcLqew==} + engines: {node: '>=12'} + magic-bytes.js@1.13.0: resolution: {integrity: sha512-afO2mnxW7GDTXMm5/AoN1WuOcdoKhtgXjIvHmobqTD1grNplhGdv3PFOyjCVmrnOZBIT/gD/koDKpYG+0mvHcg==} @@ -2130,6 +3627,10 @@ packages: resolution: {integrity: sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==} engines: {node: '>= 0.6'} + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + mem@9.0.2: resolution: {integrity: sha512-F2t4YIv9XQUBHt6AOJ0y7lSmP1+cY7Fm1DRh9GClTGzKST7UWLMx6ly9WZdLH/G/ppM5RL4MlQfRT71ri9t19A==} engines: {node: '>=12.20'} @@ -2153,10 +3654,18 @@ packages: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + mime-types@2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + mime@1.6.0: resolution: {integrity: sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==} engines: {node: '>=4'} @@ -2171,6 +3680,14 @@ packages: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} + mimic-function@5.0.1: + resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==} + engines: {node: '>=18'} + + minimatch@10.2.6: + resolution: {integrity: sha512-vpLQEs+VLCr1nU0BXS07maYoFwlDAH0gngQuuttxIwutDFEMHq2blX+8vpgxDdK3J1PwjCJiep77OitTZ4Ll1A==} + engines: {node: 18 || 20 || >=22} + minimatch@9.0.9: resolution: {integrity: sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==} engines: {node: '>=16 || 14 >=14.17'} @@ -2213,6 +3730,9 @@ packages: ms@2.0.0: resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} + ms@2.1.2: + resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -2238,6 +3758,11 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + nanoid@3.3.20: + resolution: {integrity: sha512-uKdg2G3GNCKQn9byYOpxbGqrT2fGO5KRt5J/8b3pok8rT6qxGWF6hxMyJiEYtAf+FVyYuD9hRaDqX5uPFYJ4ZQ==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + negotiator@0.6.3: resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} engines: {node: '>= 0.6'} @@ -2371,10 +3896,22 @@ packages: resolution: {integrity: sha512-l2NNj07e9afPnhAhvgVrCD/oy2Ai1yfLpuo3EpiO1jFTsB4sFz6oIfAfSZyQzVpkZQ9xS8ZS5g1jCBgq4Hwo0g==} engines: {node: '>=12.19'} + normalize-package-data@8.0.0: + resolution: {integrity: sha512-RWk+PI433eESQ7ounYxIp67CYuVsS1uYSonX3kA6ps/3LWfjVQa/ptEg6Y3T6uAMq1mWpX9PQ+qx+QaHpsc7gQ==} + engines: {node: ^20.17.0 || >=22.9.0} + normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} + normalize-url@8.1.1: + resolution: {integrity: sha512-JYc0DPlpGWB40kH5g07gGTrYuMqV653k3uBKY6uITPWds3M0ov3GaWGp9lbE3Bzngx8+XkfzgvASb9vk9JDFXQ==} + engines: {node: '>=14.16'} + + npm-run-path@6.0.0: + resolution: {integrity: sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==} + engines: {node: '>=18'} + oauth@0.10.2: resolution: {integrity: sha512-JtFnB+8nxDEXgNyniwz573xxbKSOu3R8D40xQKqcjwJ2CDkYqUDI53o6IuzDJBx60Z8VKCm271+t8iFjakrl8Q==} @@ -2386,6 +3923,9 @@ packages: resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} engines: {node: '>= 0.4'} + object-to-formdata@4.5.1: + resolution: {integrity: sha512-QiM9D0NiU5jV6J6tjE1g7b4Z2tcUnKs1OPUi4iMb2zH+7jwlcUrASghgkFk9GtzqNNq8rTQJtT8AzjBAvLoNMw==} + observable-fns@0.6.1: resolution: {integrity: sha512-9gRK4+sRWzeN6AOewNBTLXir7Zl/i3GB6Yl26gK4flxz8BXVpD3kt8amREmWNb0mxYOGDotvE5a4N+PtGGKdkg==} @@ -2397,6 +3937,17 @@ packages: resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} engines: {node: '>= 0.8'} + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + onetime@7.0.0: + resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==} + engines: {node: '>=18'} + + open@11.0.4: + resolution: {integrity: sha512-++Zlftm0kVLPmzC06t6epuWmcRMDbI4z5P3NNX979WA/k23+NtSOynEGzsVfZwguKw2mi5umVgnBlJQMwRz4Pg==} + engines: {node: '>=20'} + oxfmt@0.59.0: resolution: {integrity: sha512-Xqk6cPZS1yMvVa7OAuenaDZUsgMDutvvbZ9/L5gSvAfW64+WN4HVhgipLj5rVERbYQt8fLs9TopyZ1rU1XEG/w==} engines: {node: ^20.19.0 || >=22.12.0} @@ -2462,13 +4013,28 @@ packages: package-json-from-dist@1.0.1: resolution: {integrity: sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==} + package-manager-detector@1.9.0: + resolution: {integrity: sha512-zAMfbta9nPA8AKkA4WdmNAT8R8s6Dk0/xwPsqNnRidMFcLo1YkLuPDTgs2f64XdzS8vbLNnoJ+uUIkgbz7oRHA==} + parse-color@1.0.0: resolution: {integrity: sha512-fuDHYgFHJGbpGMgw9skY/bj3HL/Jrn4l/5rSspy00DoT4RyLnDcRvPxdZ+r6OFwIsgAuhDh4I09tAId4mI12bw==} + parse-imports@3.0.0: + resolution: {integrity: sha512-IwiqoJANa4O6M76LBWEvoS2iPIUqBOnKG1lV3/J0oVM6V2XjED+mYAXedEMX5xUglVjfGpZOfaEyuOUjBuUE4g==} + engines: {node: '>= 22'} + + parse-json@8.3.0: + resolution: {integrity: sha512-ybiGyvspI+fAoRQbIPRddCcSTV9/LsJbf0e/S85VLowVGzRmokfneg2kwVW/KU5rOXrPSbF1qAKPMgNTqqROQQ==} + engines: {node: '>=18'} + parse-ms@3.0.0: resolution: {integrity: sha512-Tpb8Z7r7XbbtBTrM9UhpkzzaMrqA2VXMT3YChzYltwV3P3pM6t8wl7TvpMnSTosz1aQAdVib7kdoys7vYOPerw==} engines: {node: '>=12'} + parse-ms@4.0.0: + resolution: {integrity: sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==} + engines: {node: '>=18'} + parseurl@1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -2504,6 +4070,13 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-key@4.0.0: + resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} + engines: {node: '>=12'} + + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -2518,6 +4091,9 @@ packages: pause@0.0.1: resolution: {integrity: sha512-KG8UEiEVkR3wGEb4m5yZkVCzigAD+cVEJck2CzYZO37ZGJfctvVptVO192MwrtPhzONn6go8ylnOdMhKqi4nfg==} + pg-connection-string@2.6.2: + resolution: {integrity: sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} @@ -2529,12 +4105,27 @@ packages: resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} engines: {node: '>=12'} + picomatch@4.0.7: + resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} + engines: {node: '>=12'} + pino-abstract-transport@2.0.0: resolution: {integrity: sha512-F63x5tizV6WCh4R6RHyi2Ml+M70DNRXt/+HANowMflpgGFMAym/VKm6G7ZOQRjqN7XbGxK1Lg9t6ZrtzOaivMw==} + pino-abstract-transport@3.0.0: + resolution: {integrity: sha512-wlfUczU+n7Hy/Ha5j9a/gZNy7We5+cXp8YL+X+PG8S0KXxw7n/JXA3c46Y0zQznIJ83URJiwy7Lh56WLokNuxg==} + + pino-pretty@13.2.0: + resolution: {integrity: sha512-jjghD1ML+Di/WxjJDz6j6Y4FT7hIXOlb8h27AyJ+ohtAXJXH4PS/xkv7si+RCCIW59HMgZsMKTDgzdr0RhuRrg==} + hasBin: true + pino-std-serializers@7.1.0: resolution: {integrity: sha512-BndPH67/JxGExRgiX1dX0w1FvZck5Wa4aal9198SrRhZjH3GxKQUKIBnYJTdj2HDN3UQAS06HlfcSbQj2OHmaw==} + pino@10.4.0: + resolution: {integrity: sha512-bk1ZMTwG/Vymx+zPoa28MhNzucFvXJWp3csrSuxuHPSMeUettaCoQ5Jvg07mtC4JGNpcfTwz41oVCnNgBK9+vA==} + hasBin: true + pino@9.14.0: resolution: {integrity: sha512-8OEwKp5juEvb/MjpIc4hjqfgCNysrS94RIOMXYvpYCdm/jglrKEiAYmiumbmGhCvs+IcInsphYDFwqrjr7398w==} hasBin: true @@ -2543,14 +4134,32 @@ packages: resolution: {integrity: sha512-7dmgi4UY4qk+4mj5Cd8v/GExPo0K+SlY+hulOSdfZ/T6jVH6//y7NtzZo5WrfhDBxuQ0jCa7fLZmNaNh7EWL/w==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + pkg-dir@8.0.0: + resolution: {integrity: sha512-4peoBq4Wks0riS0z8741NVv+/8IiTvqnZAr8QGgtdifrtpdXbNw/FxRS1l6NFqm4EMzuS0EDqNNx4XGaz8cuyQ==} + engines: {node: '>=18'} + pkg-up@3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} engines: {node: '>=8'} + playwright-core@1.64.0: + resolution: {integrity: sha512-T9r+MZkTECl2+oUcZ26YgZzTrYidTsIhYYkJix+6iDOymOb1FB2RLLSOxRGnZGv5DStt+aduIVbt+E8WygXYpg==} + engines: {node: '>=20'} + hasBin: true + + playwright@1.64.0: + resolution: {integrity: sha512-kVzTnYFYEyQ9RGzBjNCd2+yEqWmVbxl3AHPynv3qQ6JTjv4a+kwRcnqQwIpuP3NnrnIrE/Q6wWAIAvMfIE2/Yg==} + engines: {node: '>=20'} + hasBin: true + plur@5.1.0: resolution: {integrity: sha512-VP/72JeXqak2KiOzjgKtQen5y3IZHn+9GOuLDafPv0eXa47xq0At93XahYBs26MsifCQ4enGKwbjBTKgb9QJXg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} + pluralize@8.0.0: + resolution: {integrity: sha512-Nc3IT5yHzflTfbjgqWcCPpo7DaKy4FnpB0l/zCAW0Tc7jxAiuqSxHasntB3D7887LSrA93kDJ9IXovxJYxyLCA==} + engines: {node: '>=4'} + possible-typed-array-names@1.1.0: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} @@ -2569,21 +4178,50 @@ packages: resolution: {integrity: sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.29: + resolution: {integrity: sha512-49cGhUbXj8Qenv0iTMxA1cFBzxXoctpC9Ujd77t1WcbJIr6nF/eI7g/8MgxrYldFRuAXvja7xQRwavoW7kgrxQ==} + engines: {node: ^10 || ^12 || >=14} + + powershell-utils@0.2.1: + resolution: {integrity: sha512-C+y9x90UElAddDZmV4qOx9W53B61PO7cIqWz2dQsWlwswuq4mr8NEwytdGKboYbQlGZ3awrkTeNvcZiZNHnQ8A==} + engines: {node: '>=20'} + + prettier-edge@1.0.0: + resolution: {integrity: sha512-D8DwcGGPVWhMUrrE0+R242laEezGmvOpdCdvwVZiySpebZ1H5o7xwmDYhRw//ckOz1EcLOtQyJt/eQ2UC3eXOw==} + engines: {node: '>=18'} + peerDependencies: + prettier: ^3.0.0 + prettier@3.9.6: resolution: {integrity: sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==} engines: {node: '>=14'} hasBin: true + pretty-format@30.5.1: + resolution: {integrity: sha512-byhRAPguVKMQIj4kjJwJ5lAskVhfuiSdiYl/aLTWpgkGEmic2jYhJh1yE9ih8Ox44Xg9ccCT11/S6QrzSJuNrg==} + engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + + pretty-hrtime@1.0.3: + resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} + engines: {node: '>= 0.8'} + pretty-ms@8.0.0: resolution: {integrity: sha512-ASJqOugUF1bbzI35STMBUpZqdfYKlJugy6JBziGi2EE+AL5JPJGSzvpeVXojxrr0ViUYoToUjb5kjSEGf7Y83Q==} engines: {node: '>=14.16'} + pretty-ms@9.3.1: + resolution: {integrity: sha512-HzMy3Geq23nVALD/M2LliU+F+M+gVNsvkQWWqeBZ8HDiCgzo6YPJ/Omrmtq24EFrIsk0a3EkQGEd7bDOo+IhGA==} + engines: {node: '>=18'} + process-warning@3.0.0: resolution: {integrity: sha512-mqn0kFRl0EoqhnL0GQ0veqFHyIN1yig9RHh/InzORTUiZHFRAur+aMtRkELNwGs9aNwKS6tg/An4NYBPGwvtzQ==} process-warning@5.0.0: resolution: {integrity: sha512-a39t9ApHNx2L4+HBnQKqxxHNs1r7KF+Intd8Q/g1bUh6q0WIp9voPXJ/x0j+ZL45KF1pJd9+q2jLIRMfvEshkA==} + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + proxy-addr@2.0.7: resolution: {integrity: sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==} engines: {node: '>= 0.10'} @@ -2591,6 +4229,9 @@ packages: proxy-disposable@1.0.0: resolution: {integrity: sha512-Y673BKpFqk8XkYuoK9DGZ1RIzldz5SkzxTKc/+DkpaMdrDEbEalWlO/uMRMdJsXvdbTybJI26XDwN0KJpZDN4w==} + pump@3.0.4: + resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} + qs@6.15.3: resolution: {integrity: sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==} engines: {node: '>=0.6'} @@ -2601,6 +4242,10 @@ packages: quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} + random-bytes@1.0.0: + resolution: {integrity: sha512-iv7LhNVO047HzYR3InF6pUcUsPQiHTM1Qal51DcGSuZFBil1aBBWG5eHPNek7bvILMaYJ/8RU1e8w1AMdHmLQQ==} + engines: {node: '>= 0.8'} + range-parser@1.2.1: resolution: {integrity: sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==} engines: {node: '>= 0.6'} @@ -2609,6 +4254,24 @@ packages: resolution: {integrity: sha512-s4VSOf6yN0rvbRZGxs8Om5CWj6seneMwK3oDb4lWDH0UPhWcxwOWw5+qk24bxq87szX1ydrwylIOp2uG1ojUpA==} engines: {node: '>= 0.8'} + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + react-is@18.3.1: + resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==} + + react-is@19.3.0: + resolution: {integrity: sha512-UpMYezM4v5/18F28aC66AEsjXIgE02kyEMH6yLdgLXu/UTfa1Ntwck/nNLrbqJsEXW7gPb0coNO9FQse9WTovA==} + + read-package-up@12.0.0: + resolution: {integrity: sha512-Q5hMVBYur/eQNWDdbF4/Wqqr9Bjvtrw2kjGxxBbKLbx8bVCL8gcArjTy8zDUuLGQicftpMuU0riQNcAsbtOVsw==} + engines: {node: '>=20'} + + read-pkg@10.1.0: + resolution: {integrity: sha512-I8g2lArQiP78ll51UeMZojewtYgIRCKCWqZEgOO8c/uefTI+XDXvCSXu3+YNUaTNvZzobrL5+SqHjBrByRRTdg==} + engines: {node: '>=20'} + readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} engines: {node: '>= 6'} @@ -2617,10 +4280,25 @@ packages: resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==} engines: {node: '>=8.10.0'} + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + real-require@0.2.0: resolution: {integrity: sha512-57frrGM/OCTLqLOAh0mhVA9VBMHd+9U7Zb2THMGdBUoZVOtGbJzjxsYGDJ3A9AYYCP4hn6y1TVbaOfzWtm5GFg==} engines: {node: '>= 12.13.0'} + real-require@1.0.0: + resolution: {integrity: sha512-P4nbQYQfePJxRSmY+v/KINxVucm4NF3p3s7pJveMTtom52FR4YGltUQLB8idDXwDDWW+eYrWDFbuzUnjoWHF7g==} + + rechoir@0.8.0: + resolution: {integrity: sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==} + engines: {node: '>= 10.13.0'} + + redis-errors@1.2.0: + resolution: {integrity: sha512-1qny3OExCf0UvUV/5wpYKf2YwPcOqXzkwKKSmKHiE6ZMQs5heeE/c8eXK+PNllPvmjgAbfnsbpkGZWy8cBpn9w==} + engines: {node: '>=4'} + redis@5.12.1: resolution: {integrity: sha512-LDsoVvb/CpoV9EN3FXvgvSHNJWuCIzl9MiO3ppOevuGLpSGJhwfQjpEwfFJcQvNSddHADDdZaWx0HnmMxRXG7g==} engines: {node: '>= 18.19.0'} @@ -2658,10 +4336,26 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + + resolve@1.22.13: + resolution: {integrity: sha512-Dj/cW9zBV2aRj6XzCxuGIs3ESZKv02jixne3q6jFZYZ3/Tg09gHHviSMDL4kObh9pqSahdRHEnDoaP2gn8YLhA==} + engines: {node: '>= 0.4'} + hasBin: true + + restore-cursor@5.1.0: + resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} + engines: {node: '>=18'} + ret@0.4.3: resolution: {integrity: sha512-0f4Memo5QP7WQyUEAYUO3esD/XjOc3Zjjg5CPsAq1p8sIu0XPeMbHJemKA0BO7tV0X7+A0FoEpbmHXWxPyD3wQ==} engines: {node: '>=10'} + retry@0.13.1: + resolution: {integrity: sha512-XQBQ3I8W1Cge0Seh+6gjj03LbmRFWuoszgK9ooCpwYIrhhoO80pfq4cUkU5DkknwfOfFteRwlZ56PYOGYyFWdg==} + engines: {node: '>= 4'} + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} @@ -2669,14 +4363,29 @@ packages: rfdc@1.4.1: resolution: {integrity: sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==} + rndm@1.2.0: + resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==} + rolldown@1.1.5: resolution: {integrity: sha512-t9z29cJjXf/vxQ8dyhCSpt6H6aSwHTk8cT5I3iy6SMXuFpk5mB6PL6XfC8PCwrPTx93udwKUm9HRteAlTGBLiA==} engines: {node: ^20.19.0 || >=22.12.0} hasBin: true + rolldown@1.2.13: + resolution: {integrity: sha512-/5apOkwWxtACcQtZ5WlrAsKS4JwXVThQPJZ3RqIruRY9UG9M8e0VlXN068xum/JRKA4aIUoJ13ghe/kGCvidiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + + run-applescript@7.1.0: + resolution: {integrity: sha512-DPe5pVFaAsinSaV6QjQ6gdiedWDcRCbUuiQfQa2wmWV7+xC9bGulGI8+TdRmoFkAPaBXk8CrAbnlY2ISniJ47Q==} + engines: {node: '>=18'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} + safe-buffer@5.1.2: + resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} + safe-buffer@5.2.1: resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} @@ -2696,6 +4405,9 @@ packages: secure-json-parse@2.7.0: resolution: {integrity: sha512-6aU+Rwsezw7VR8/nyvKTx8QpWH9FrcYiXXlqC4z5d5XQBDRqtbfsRjnwGyqbi3gddNtWHuEk9OANUotL26qKUw==} + secure-json-parse@4.1.1: + resolution: {integrity: sha512-lnd81MQEZKjhW/Gd2TQqdd4XP6QYNdDW/EP+I7nTrFHP9y2LmaGPIHk9xsnzcOiEr1c39c/e84xFgGviQKBTRw==} + seedrandom@3.0.5: resolution: {integrity: sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg==} @@ -2708,6 +4420,10 @@ packages: resolution: {integrity: sha512-VMbMxbDeehAxpOtWJXlcUS5E8iXh6QmN+BkRX1GARS3wRaXEEgzCcB10gTQazO42tpNIya8xIyNx8fll1OFPrg==} engines: {node: '>= 0.8.0'} + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + serialize-error@7.0.1: resolution: {integrity: sha512-8I8TjW5KMOKsZQTvoxjuSIa7foAwPWGOts+6o7sgjz41/qMD9VQHEDxi6PBvK2l0MXUmqZyNpUK+T2tQaaElvw==} engines: {node: '>=10'} @@ -2716,6 +4432,10 @@ packages: resolution: {integrity: sha512-x0RTqQel6g5SY7Lg6ZreMmsOzncHFU7nhnRWkKgWuMTu5NN0DR5oruckMqRvacAN9d5w6ARnRBXl9xhDCgfMeA==} engines: {node: '>= 0.8.0'} + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} @@ -2763,17 +4483,39 @@ packages: resolution: {integrity: sha512-3dOsAHXXUkQTpOYcoAxLIorMTp4gIQr5IW3iVb7A7lFIp0VHhnynm9izx6TssdrIcVIESAlVjtnO2K8bg+Coew==} engines: {node: '>=12'} + slash@5.1.0: + resolution: {integrity: sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==} + engines: {node: '>=14.16'} + + slashes@3.0.12: + resolution: {integrity: sha512-Q9VME8WyGkc7pJf6QEkj3wE+2CnvZMI+XJhwdTPR8Z/kWQRXi7boAWLDibRPyHRTUTPx5FaU7MsyrjI3yLB4HA==} + slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} + slice-ansi@8.0.0: + resolution: {integrity: sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==} + engines: {node: '>=20'} + + slugify@1.6.9: + resolution: {integrity: sha512-vZ7rfeehZui7wQs438JXBckYLkIIdfHOXsaVEUMyS5fHo1483l1bMdo0EDSWYclY0yZKFOipDy4KHuKs6ssvdg==} + engines: {node: '>=8.0.0'} + sonic-boom@4.2.1: resolution: {integrity: sha512-w6AxtubXa2wTXAUsZMMWERrsIRAdrK0Sc+FUytWvYAhBJLyuI4llrMIC1DtlNSdI99EI86KZum2MMq3EAZlF9Q==} + sonic-boom@5.0.2: + resolution: {integrity: sha512-/JEruzo6yhNVhsLblTRchgTQHIt7SsdJP0YyrfWaNKjIOQDfrdZv9gwYraYCAsmKV39/LAdV31FLL5NCDpoL/A==} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + source-map-js@1.2.2: + resolution: {integrity: sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==} + engines: {node: '>=0.10.0'} + source-map-support@0.5.21: resolution: {integrity: sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==} @@ -2781,6 +4523,22 @@ packages: resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} engines: {node: '>=0.10.0'} + spdx-correct@3.2.0: + resolution: {integrity: sha512-kN9dJbvnySHULIluDHy32WHRUu3Og7B9sbY7tsFLctQkIqnMh3hErYgdMjTYuqmcXX+lK5T1lnUt3G7zNswmZA==} + + spdx-exceptions@2.5.0: + resolution: {integrity: sha512-PiU42r+xO4UbUS1buo3LPJkjlO7430Xn5SVAhdpzzsPHsjbYVflnnFdATgabnLude+Cqu25p6N+g2lw/PFsa4w==} + + spdx-expression-parse@3.0.1: + resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} + + spdx-license-ids@3.0.24: + resolution: {integrity: sha512-cLS9TtWkIQFyLkJ3/5aFQAOHOSKTlOs/7WDut/XPSdjom1fJhUdkepeJAKXa9Y05+FabHd0sti+Et559vDtkpQ==} + + split-lines@3.0.0: + resolution: {integrity: sha512-d0TpRBL/VfKDXsk8JxPF7zgF5pCUDdBMSlEL36xBgVeaX448t+yGXcJaikUyzkoKOJ0l6KpMfygzJU9naIuivw==} + engines: {node: '>=12'} + split2@4.2.0: resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==} engines: {node: '>= 10.x'} @@ -2800,6 +4558,9 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + standard-as-callback@2.1.0: + resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==} + statuses@2.0.1: resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==} engines: {node: '>= 0.8'} @@ -2820,9 +4581,17 @@ packages: resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==} engines: {node: '>=12'} + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} + engines: {node: '>=20'} + string_decoder@1.3.0: resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} + stringify-attributes@4.0.0: + resolution: {integrity: sha512-6Hq3K153wTTfhEHb4V/viuqmb0DRn08JCrRnmqc4Q/tmoNuvd4DEyqkiiJXtvVz8ZSUhlCQr7zCpCVTgrelesg==} + engines: {node: '>=14.16'} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} @@ -2838,34 +4607,89 @@ packages: strip-combining-marks@1.0.0: resolution: {integrity: sha512-8YrtmJKxvDmMIoJMOyvh/s3Oe8TxolM5ThgZPmE39vvkfXVuOHAUyiZ1yOZUxDg/kb1QLRyZ0CfQQqeTISAeTA==} + strip-final-newline@4.0.0: + resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} + engines: {node: '>=18'} + + strip-json-comments@5.0.3: + resolution: {integrity: sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw==} + engines: {node: '>=14.16'} + + strtok3@10.4.0: + resolution: {integrity: sha512-zzNQzrgQUNHyFFDzGCkzgWPgxiBcfwqg+/RNK9cZHKRH95KuCKxqXBXe+jC/1Xq+MRLAe/DkizyPe3kR37QV3w==} + engines: {node: '>=18'} + supertap@3.0.1: resolution: {integrity: sha512-u1ZpIBCawJnO+0QePsEiOknOfCRq0yERxiAchT0i4li0WHNUJbf0evXXSXOcCAR4M8iMDoajXYmstm/qO81Isw==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - tailwindcss@4.3.3: + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + + supports-color@7.2.0: + resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} + engines: {node: '>=8'} + + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + + tagged-tag@1.0.0: + resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} + engines: {node: '>=20'} + + tailwindcss@4.3.3: resolution: {integrity: sha512-gOhV3P7ufE62QDGg1zVaTgCR+EtPv92k2nIhVcVKcLmxT1sUBsQGhnZj175j+MqRt4zLF7ic+sCYjfhxMxj7YQ==} tapable@2.3.3: resolution: {integrity: sha512-uxc/zpqFg6x7C8vOE7lh6Lbda8eEL9zmVm/PLeTPBRhh1xCgdWaQ+J1CUieGpIfm2HdtsUpRv+HshiasBMcc6A==} engines: {node: '>=6'} + tarn@3.1.2: + resolution: {integrity: sha512-3RTvqKZcK/17jnJ8rMKFXbyNogywTs1z0gVPPwFsJGX46rkmUHOdIaSQ/aVO1rS7nH+soiXiWk7rvUXxndm8Dg==} + engines: {node: '>=8.0.0'} + temp-dir@3.0.0: resolution: {integrity: sha512-nHc6S/bwIilKHNRgK/3jlhDoIHcp45YgyiwcAk46Tr0LfEqGBVpmiAyuiuxeVE44m3mXnEeVhaipLOEWmH+Njw==} engines: {node: '>=14.16'} + tempura@0.4.1: + resolution: {integrity: sha512-NQ4Cs23jM6UUp3CcS5vjmyjTC6dtA5EsflBG2cyG0wZvP65AV26tJ920MGvTRYIImCY13RBpOhc7q4/pu+FG5A==} + engines: {node: '>=10'} + + terminal-size@4.0.1: + resolution: {integrity: sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==} + engines: {node: '>=18'} + thread-stream@3.2.0: resolution: {integrity: sha512-zLBvqpwr4Esa0kRjcrzGU6zL25lePWaCLMx0RQFrmteozIfeNdaMLpG5U7PeHzvlFkAWaRKA9/KVW4F60iB+qw==} + thread-stream@4.2.0: + resolution: {integrity: sha512-e2zZ96wSChazBsbENf/Pcm/4swHt2cEKQ92rhUjkL9GCKiTDJIaTBenjE/m9DXi0QBmTMDkFDdOomUy20A1tDQ==} + engines: {node: '>=20'} + threads@1.7.0: resolution: {integrity: sha512-Mx5NBSHX3sQYR6iI9VYbgHKBLisyB+xROCBGjjWm1O9wb9vfLxdaGtmT/KCjUqMsSNW6nERzCW3T6H43LqjDZQ==} + tildify@2.0.0: + resolution: {integrity: sha512-Cc+OraorugtXNfs50hU9KS369rFXCfgGLpfCfvlc+Ud5u6VWmUQsOAa9HbTvheQdYnrdJqqv1e5oIqXppMYnSw==} + engines: {node: '>=8'} + time-zone@1.0.0: resolution: {integrity: sha512-TIsDdtKo6+XrPtiTm1ssmMngN1sAhyKnTO2kunQWqNPWIVvCm15Wmw4SWInwTVgJ5u/Tr04+8Ei9TNcw4x4ONA==} engines: {node: '>=4'} + timekeeper@2.3.1: + resolution: {integrity: sha512-LeQRS7/4JcC0PgdSFnfUiStQEdiuySlCj/5SJ18D+T1n9BoY7PxKFfCwLulpHXoLUFr67HxBddQdEX47lDGx1g==} + tiny-worker@2.3.0: resolution: {integrity: sha512-pJ70wq5EAqTAEl9IkGzA+fN0836rycEuz2Cn6yeZ6FRzlVS5IDOkFHpIoEsksPRQV34GDqXm65+OlnZqUSyK2g==} + tinyexec@1.3.1: + resolution: {integrity: sha512-GCvB3aoys96IuDFBMcTB46JOR6mdMtAToqwiW8JlWhsoh1mhHi/xn9ss/Dg7N555GiJyEt2qzoG/NHCwM6h1EA==} + engines: {node: '>=18'} + tinyglobby@0.2.17: resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} engines: {node: '>=12.0.0'} @@ -2878,6 +4702,10 @@ packages: resolution: {integrity: sha512-QXqwfEl9ddlGBaRFXIvNKK6OhipSiLXuRuLJX5DErz0o0Q0rYxulWLdFryTkV5PkdZct5iMInwYEGe/eR++1AA==} hasBin: true + tmp-cache@1.1.0: + resolution: {integrity: sha512-j040fkL/x+XAZQ9K3bKGEPwgYhOZNBQLa3NXEADUiuno9C+3N2JJA4bVPDREixp604G3/vTXWA3DIPpA9lu1RQ==} + engines: {node: '>=6'} + tmp@0.2.5: resolution: {integrity: sha512-voyz6MApa1rQGUxT3E+BK7/ROe8itEx7vD8/HEvt4xwXucvQ5G5oeEiHkmHZJuBO21RpOf+YYm9MOivj709jow==} engines: {node: '>=14.14'} @@ -2898,6 +4726,10 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} + token-types@6.1.2: + resolution: {integrity: sha512-dRXchy+C0IgK8WPC6xvCHFRIWYUbqqdEIKPaKo/AcTUNzwLTK6AH7RjdLWsEZcAN/TBdtfUw3PYEgPr5VPr6ww==} + engines: {node: '>=14.16'} + ts-essentials@10.2.1: resolution: {integrity: sha512-+Id1fRkuir+CsgK2x04/icS2b4V1hQmq7ObzIrDjhN0ozfRYivnP7aaKMVJfLApQm0trjR39A6NIMVchiB9Erw==} peerDependencies: @@ -2909,6 +4741,9 @@ packages: ts-mixer@6.0.4: resolution: {integrity: sha512-ufKpbmrugz5Aou4wcr5Wc1UUFWOLhq+Fm6qa6P0w0K5Qw2yhaUoiWszhCVuNQyNwrlGiscHOmqYoAox1PtvgjA==} + ts-morph@28.0.0: + resolution: {integrity: sha512-Wp3tnZ2bzwxyTZMtgWVzXDfm7lB1Drz+y9DmmYH/L702PQhPyVrp3pkou3yIz4qjS14GY9kcpmLiOOMvl8oG1g==} + ts-toolbelt@9.6.0: resolution: {integrity: sha512-nsZd8ZeNUzukXPlJmTBwUAuABDe/9qtVDelJeT/qW0ow3ZS3BsQJtNkan1802aM9Uf68/Y8ljw86Hu0h5IUW3w==} @@ -2918,6 +4753,10 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsscmp@1.0.6: + resolution: {integrity: sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==} + engines: {node: '>=0.6.x'} + twemoji-parser@12.1.3: resolution: {integrity: sha512-ND4LZXF4X92/PFrzSgGkq6KPPg8swy/U0yRw1k/+izWRVmq1HYi3khPwV3XIB6FRudgVICAaBhJfW8e8G3HC7Q==} @@ -2928,10 +4767,22 @@ packages: resolution: {integrity: sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==} engines: {node: '>=10'} + type-fest@4.41.0: + resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} + engines: {node: '>=16'} + + type-fest@5.10.0: + resolution: {integrity: sha512-NoSdpq/WEiAg5sjmBkmV/hfxv6HJH4NqPNrqjtSO5CwRmpsDfaf4begxW34KdJykH/l1yHtwBWQkCRdoXO8mPA==} + engines: {node: '>=20'} + type-is@1.6.18: resolution: {integrity: sha512-TkRKr9sUTxEH8MdfuCSP7VizJyzRNMjj2J2do2Jr3Kym598JVdEksuzPQCnlFPW4ky9Q+iA+ma9BGm06XQBy8g==} engines: {node: '>= 0.6'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + typed-array-buffer@1.0.3: resolution: {integrity: sha512-nAYYwfY3qnzX30IkA6AQZjVbtK6duGontcQm1WSG1MD94YLqK0515GNApXkoxKOWMusVssAHWLh9SeaoefYFGw==} engines: {node: '>= 0.4'} @@ -3004,12 +4855,23 @@ packages: engines: {node: '>=16.20.0'} hasBin: true + uid-safe@2.1.5: + resolution: {integrity: sha512-KPHm4VL5dDXKz01UuEd88Df+KzynaohSL9fBh096KWAxSKZQDI2uBrVqtvRM4rwrIrRRKsdLNML/lnaaVSRioA==} + engines: {node: '>= 0.8'} + uid2@0.0.4: resolution: {integrity: sha512-IevTus0SbGwQzYh3+fRsAMTVVPOoIVufzacXcHPmdlle1jUpq7BRL+mw3dgeLanvGZdwwbWhRV6XrcFNdBmjWA==} + uint8array-extras@1.6.0: + resolution: {integrity: sha512-8iAasVS4wUx0gPLjH8Xtz2PeDzTSiy8QiLGu2DT3X5GU+egFEQhpnbtkehbAwjvDcxIERmCYcysiODFmE3Ud0Q==} + engines: {node: '>=18'} + undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} + undici-types@8.9.0: + resolution: {integrity: sha512-KTDyRTYX8sWmKXAikPHHSyc63CRPETMctyjKFupcC6OBLXT3xsN0e9aF7m+mIXutFWpUXuedtowG7iLOzp0kQg==} + undici@6.21.3: resolution: {integrity: sha512-gBLkYIlEnSp8pFbT64yFgGE6UIB9tAkhukC23PmMDCe5Nd+cRqKxSjw5y54MK2AZMgZfJWMaNE4nYUHgi1XEOw==} engines: {node: '>=18.17'} @@ -3018,6 +4880,14 @@ packages: resolution: {integrity: sha512-YmfV3YnEDzXRC5lZ2jWtWWHKGUm1zIt8AhesR1tens+HTNv+YZlN/dp6G727LOvMJ8xjP9Be7Y2Sdr96LDm+pg==} engines: {node: '>=18.17'} + unicorn-magic@0.3.0: + resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} + engines: {node: '>=18'} + + unicorn-magic@0.4.1: + resolution: {integrity: sha512-lzlXPoVB0Uy/FvTaUgX39RbixYiSKoc3JSoSf01+0c2B6FR3qdYIPN7Qjo/AV7n6sqLCk0509cT3LRj1oSZ1+A==} + engines: {node: '>=20'} + universalify@0.1.2: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} @@ -3046,6 +4916,13 @@ packages: deprecated: uuid@10 and below is no longer supported. For ESM codebases, update to uuid@latest. For CommonJS codebases, use uuid@11 (but be aware this version will likely be deprecated in 2028). hasBin: true + validate-npm-package-license@3.0.4: + resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} + + validator@13.15.35: + resolution: {integrity: sha512-TQ5pAGhd5whStmqWvYF4OjQROlmv9SMFVt37qoCBdqRffuuklWYQlCNnEs2ZaIBD1kZRNnikiZOS1eqgkar0iw==} + engines: {node: '>= 0.10'} + vary@1.1.2: resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} engines: {node: '>= 0.8'} @@ -3097,6 +4974,49 @@ packages: yaml: optional: true + vite@8.3.4: + resolution: {integrity: sha512-IftLE8phJhdNRIGNEV4JCCvfNScoZQVfcXaN8TQropWGJtOHcu+iAB9pHcuGvmEb/kddw0LBe/jS8ztdC6xdiQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.7.1 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + vscode-jsonrpc@9.0.1: resolution: {integrity: sha512-rfuA6T75H6m5EkbhtEPzre9pT0HPcDI2MMy4+nPFIBks5J8JBAUHD4tRYSgaBOijIEC7SRkC1kKyXTLqbmh9jw==} engines: {node: '>=14.0.0'} @@ -3121,6 +5041,26 @@ packages: peerDependencies: vue: ^3.5.0 + vue-sonner@2.0.9: + resolution: {integrity: sha512-i6BokNlNDL93fpzNxN/LZSn6D6MzlO+i3qXt6iVZne3x1k7R46d5HlFB4P8tYydhgqOrRbIZEsnRd3kG7qGXyw==} + peerDependencies: + '@nuxt/kit': ^4.0.3 + '@nuxt/schema': ^4.0.3 + nuxt: ^4.0.3 + peerDependenciesMeta: + '@nuxt/kit': + optional: true + '@nuxt/schema': + optional: true + nuxt: + optional: true + + vue-tsc@3.3.13: + resolution: {integrity: sha512-jE4/bXdOMSHVxEGgQCqNllJy+9N3Gx6tfSAsg0yhFK/MAN6eXqISihupnDEKSCt12VVnjN2gI3AqLYcqoh5x/A==} + hasBin: true + peerDependencies: + typescript: '>=5.0.0' + vue-tsc@3.3.7: resolution: {integrity: sha512-+C+rgD49wAQ5bUTl2sp5a8Bzg4YoldMNXM+g7CFe604MYcQ8PrZPMQhIjJSzKXtPBCa+C5ayMipqjbA7splekQ==} hasBin: true @@ -3146,6 +5086,14 @@ packages: typescript: optional: true + vue@3.5.43: + resolution: {integrity: sha512-o5qZoksdnjIKvW1srZ3ab7pcDNYAerBjRe54D0LBLfRdCYFrSgBHVXokMas35czQc0//lmx4/tuY4ZNQ+Rf2Ng==} + peerDependencies: + typescript: '*' + peerDependenciesMeta: + typescript: + optional: true + vuex@4.1.0: resolution: {integrity: sha512-hmV6UerDrPcgbSy9ORAtNXDr9M4wlNP4pEFKye4ujJF8oqgFFuxDCdOLS3eNoRTtq5O3hoBDh9Doj1bQMYHRbQ==} peerDependencies: @@ -3164,6 +5112,10 @@ packages: engines: {node: '>= 8'} hasBin: true + wrap-ansi@10.0.2: + resolution: {integrity: sha512-6OLRNZqRntVGBm26ghZ5eZhCuWWyOkRCSn8XsOIuq5stpCE/tjLbdozd93naILZig0lmD8ANfRwnhn0DLeXGlg==} + engines: {node: '>=20'} + wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -3172,6 +5124,9 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + write-file-atomic@5.0.1: resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -3188,6 +5143,10 @@ packages: utf-8-validate: optional: true + wsl-utils@1.0.1: + resolution: {integrity: sha512-c16PKLIRxBYpR3jSWsdS7SFp0COm5SOQdiFjY818dYFHJbMGuLBszpF07LBWmOS1uzrHa9VGdynsEgoeKy0oOQ==} + engines: {node: '>=20'} + y18n@5.0.8: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} @@ -3201,6 +5160,10 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + yargs@17.7.3: resolution: {integrity: sha512-GZtjxm/J/4TSxuL3FNYjCmLktBTnIw/rVmKSIyKeYAZpmJB2ig9VauCC5xsa82GNKVKDAqpOn3KVzNt0zmrU0g==} engines: {node: '>=12'} @@ -3209,11 +5172,394 @@ packages: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} + yoctocolors@2.2.0: + resolution: {integrity: sha512-xYqdZFUK/VYazNl/oCDYN+3WloWQwMfZxBoiNt6qNyk+xfOdi598muWE42rNZFp1kNOiqW936q5RhUdnpqElSg==} + engines: {node: '>=18'} + + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + + youch@4.1.1: + resolution: {integrity: sha512-mxW3qiSnl+GRxXsaUMzv2Mbada1Y8CDltET9UxejDQe6DBYlSekghl5U5K0ReAikcHDi0G1vKZEmmo/NWAGKLA==} + zod@4.4.3: resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} snapshots: + '@adonisjs/ace@14.1.1(youch@4.1.1)': + dependencies: + '@poppinss/cliui': 6.8.1 + '@poppinss/hooks': 7.3.1 + '@poppinss/macroable': 1.1.2 + '@poppinss/prompts': 3.1.6 + '@poppinss/utils': 7.1.1 + fastest-levenshtein: 1.0.16 + jsonschema: 1.5.0 + string-width: 8.3.0 + yargs-parser: 22.0.0 + youch: 4.1.1 + + '@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0)': + dependencies: + '@adonisjs/config': 6.1.0 + '@adonisjs/fold': 11.1.0 + '@poppinss/hooks': 7.3.1 + '@poppinss/macroable': 1.1.2 + '@poppinss/utils': 7.1.1 + glob-parent: 6.0.2 + tempura: 0.4.1 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + + '@adonisjs/assembler@8.5.2(typescript@6.0.3)': + dependencies: + '@adonisjs/env': 7.1.0 + '@antfu/install-pkg': 2.1.0 + '@ast-grep/napi': 0.45.3 + '@poppinss/cliui': 6.8.1 + '@poppinss/hooks': 7.3.1 + '@poppinss/utils': 7.1.1 + chokidar: 5.0.0 + dedent: 1.7.2 + execa: 9.6.1 + fast-glob: 3.3.3 + fdir: 6.5.0(picomatch@4.0.5) + get-port: 7.2.0 + get-tsconfig: 4.14.3 + import-meta-resolve: 4.2.0 + junk: 4.0.1 + open: 11.0.4 + parse-imports: 3.0.0 + picomatch: 4.0.5 + pretty-hrtime: 1.0.3 + tmp-cache: 1.1.0 + ts-morph: 28.0.0 + typescript: 6.0.3 + transitivePeerDependencies: + - babel-plugin-macros + + '@adonisjs/auth@10.1.0(c16d739126567016c4d2c00b96bddf22)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@adonisjs/presets': 3.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1)) + basic-auth: 2.0.1 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@adonisjs/lucid': 22.4.2(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@vinejs/vine@4.4.0)(luxon@3.7.2)(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2) + '@adonisjs/session': 8.1.0(770cc5139ed8289213226f432e14c982) + '@japa/browser-client': 2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0) + '@japa/plugin-adonisjs': 5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0) + + '@adonisjs/bodyparser@11.0.4(@adonisjs/http-server@9.3.1(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/events@10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0)(@adonisjs/logger@7.1.1(pino-pretty@13.2.0))(@boringnode/encryption@1.0.1)(youch@4.1.1))(supports-color@10.2.2)': + dependencies: + '@adonisjs/http-server': 9.3.1(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/events@10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0)(@adonisjs/logger@7.1.1(pino-pretty@13.2.0))(@boringnode/encryption@1.0.1)(youch@4.1.1) + '@poppinss/macroable': 1.1.2 + '@poppinss/middleware': 3.2.7 + '@poppinss/multiparty': 3.0.0 + '@poppinss/qs': 6.15.0 + '@poppinss/utils': 7.1.1 + file-type: 22.1.1(supports-color@10.2.2) + inflation: 2.1.0 + media-typer: 1.1.1 + raw-body: 3.0.2 + transitivePeerDependencies: + - supports-color + + '@adonisjs/config@6.1.0': + dependencies: + '@poppinss/utils': 7.1.1 + + '@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1)': + dependencies: + '@adonisjs/ace': 14.1.1(youch@4.1.1) + '@adonisjs/application': 9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0) + '@adonisjs/bodyparser': 11.0.4(@adonisjs/http-server@9.3.1(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/events@10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0)(@adonisjs/logger@7.1.1(pino-pretty@13.2.0))(@boringnode/encryption@1.0.1)(youch@4.1.1))(supports-color@10.2.2) + '@adonisjs/config': 6.1.0 + '@adonisjs/env': 7.1.0 + '@adonisjs/events': 10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0) + '@adonisjs/fold': 11.1.0 + '@adonisjs/hash': 10.1.1 + '@adonisjs/health': 3.1.0 + '@adonisjs/http-server': 9.3.1(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/events@10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0)(@adonisjs/logger@7.1.1(pino-pretty@13.2.0))(@boringnode/encryption@1.0.1)(youch@4.1.1) + '@adonisjs/http-transformers': 2.3.1(@adonisjs/fold@11.1.0) + '@adonisjs/logger': 7.1.1(pino-pretty@13.2.0) + '@adonisjs/repl': 5.0.0 + '@boringnode/encryption': 1.0.1 + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.7.0 + '@poppinss/macroable': 1.1.2 + '@poppinss/utils': 7.1.1 + '@sindresorhus/is': 8.1.0 + '@types/he': 1.2.3 + error-stack-parser-es: 2.0.1 + he: 1.2.0 + pretty-hrtime: 1.0.3 + string-width: 8.3.0 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@vinejs/vine': 4.4.0 + edge.js: 6.5.1 + pino-pretty: 13.2.0 + youch: 4.1.1 + transitivePeerDependencies: + - supports-color + + '@adonisjs/cors@3.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + + '@adonisjs/env@7.1.0': + dependencies: + '@poppinss/utils': 7.1.1 + '@poppinss/validator-lite': 2.1.2 + split-lines: 3.0.0 + + '@adonisjs/events@10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0)': + dependencies: + '@adonisjs/application': 9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0) + '@adonisjs/fold': 11.1.0 + '@poppinss/utils': 7.1.1 + '@sindresorhus/is': 7.2.0 + emittery: 1.2.1 + + '@adonisjs/fold@11.1.0': + dependencies: + '@poppinss/utils': 7.1.1 + parse-imports: 3.0.0 + + '@adonisjs/hash@10.1.1': + dependencies: + '@phc/format': 1.0.0 + '@poppinss/utils': 7.1.1 + + '@adonisjs/health@3.1.0': + dependencies: + '@poppinss/utils': 7.1.1 + check-disk-space: 3.4.0 + + '@adonisjs/http-server@9.3.1(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/events@10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0)(@adonisjs/logger@7.1.1(pino-pretty@13.2.0))(@boringnode/encryption@1.0.1)(youch@4.1.1)': + dependencies: + '@adonisjs/application': 9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0) + '@adonisjs/events': 10.2.0(@adonisjs/application@9.1.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/config@6.1.0)(@adonisjs/fold@11.1.0))(@adonisjs/fold@11.1.0) + '@adonisjs/fold': 11.1.0 + '@adonisjs/logger': 7.1.1(pino-pretty@13.2.0) + '@boringnode/encryption': 1.0.1 + '@boringnode/route-matcher': 0.1.1 + '@poppinss/macroable': 1.1.2 + '@poppinss/matchit': 3.2.0 + '@poppinss/middleware': 3.2.7 + '@poppinss/qs': 6.15.0 + '@poppinss/types': 1.2.1 + '@poppinss/utils': 7.1.1 + '@sindresorhus/is': 8.1.0 + content-disposition: 1.1.0 + cookie-es: 3.1.1 + destroy: 1.2.0 + encodeurl: 2.0.0 + etag: 1.8.1 + fresh: 0.5.2 + mime-types: 3.0.2 + on-finished: 2.4.1 + proxy-addr: 2.0.7 + tmp-cache: 1.1.0 + type-is: 2.1.0 + vary: 1.1.2 + optionalDependencies: + youch: 4.1.1 + + '@adonisjs/http-transformers@2.3.1(@adonisjs/fold@11.1.0)': + dependencies: + '@adonisjs/fold': 11.1.0 + '@poppinss/exception': 1.2.3 + '@poppinss/types': 1.2.1 + + '@adonisjs/inertia@5.0.1(3f17abe654a593f174d8c7d5a3b95857)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@adonisjs/session': 8.1.0(770cc5139ed8289213226f432e14c982) + '@adonisjs/vite': 6.0.3(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/shield@9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1))(edge.js@6.5.1)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0)) + '@poppinss/macroable': 1.1.2 + '@poppinss/utils': 7.1.1 + edge-error: 4.0.2 + edge.js: 6.5.1 + html-entities: 2.6.0 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@inertiajs/core': 3.9.1 + '@inertiajs/vue3': 3.9.1(vue@3.5.43(typescript@6.0.3)) + '@japa/plugin-adonisjs': 5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0) + '@tuyau/core': 1.2.2(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1)) + vue: 3.5.43(typescript@6.0.3) + + '@adonisjs/logger@7.1.1(pino-pretty@13.2.0)': + dependencies: + '@poppinss/utils': 7.1.1 + abstract-logging: 2.0.1 + pino: 10.4.0 + optionalDependencies: + pino-pretty: 13.2.0 + + '@adonisjs/lucid@22.4.2(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@vinejs/vine@4.4.0)(luxon@3.7.2)(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@adonisjs/presets': 3.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1)) + '@faker-js/faker': 10.6.0 + '@poppinss/hooks': 7.3.1 + '@poppinss/macroable': 1.1.2 + '@poppinss/qs': 6.15.0 + '@poppinss/utils': 7.1.1 + deepmerge: 4.3.1 + fast-deep-equal: 3.1.3 + igniculus: 1.5.0 + kleur: 4.1.5 + knex: 3.3.0(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2) + knex-dynamic-connection: 5.1.1(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2) + pretty-hrtime: 1.0.3 + slash: 5.1.0 + tarn: 3.1.2 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@vinejs/vine': 4.4.0 + luxon: 3.7.2 + transitivePeerDependencies: + - better-sqlite3 + - mariadb + - mysql + - mysql2 + - pg + - pg-native + - pg-query-stream + - sqlite3 + - supports-color + - tedious + + '@adonisjs/presets@3.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + + '@adonisjs/prettier-config@1.5.0(prettier@3.9.6)': + dependencies: + prettier-edge: 1.0.0(prettier@3.9.6) + transitivePeerDependencies: + - prettier + + '@adonisjs/redis@11.0.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(supports-color@10.2.2)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@poppinss/utils': 7.1.1 + emittery: 1.2.1 + ioredis: 6.0.0(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + '@adonisjs/repl@5.0.0': + dependencies: + '@poppinss/colors': 4.1.6 + string-width: 8.3.0 + + '@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@poppinss/macroable': 1.1.2 + '@poppinss/utils': 7.1.1 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@adonisjs/lucid': 22.4.2(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@vinejs/vine@4.4.0)(luxon@3.7.2)(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2) + '@adonisjs/redis': 11.0.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(supports-color@10.2.2) + '@japa/browser-client': 2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0) + '@japa/plugin-adonisjs': 5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0) + edge.js: 6.5.1 + + '@adonisjs/shield@9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@adonisjs/session': 8.1.0(770cc5139ed8289213226f432e14c982) + csrf: 3.1.0 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@japa/plugin-adonisjs': 5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0) + edge.js: 6.5.1 + + '@adonisjs/static@2.0.1(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(supports-color@10.2.2)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + serve-static: 2.2.1(supports-color@10.2.2) + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + transitivePeerDependencies: + - supports-color + + '@adonisjs/tsconfig@2.0.0': {} + + '@adonisjs/vite@6.0.3(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/shield@9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1))(edge.js@6.5.1)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0))': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@poppinss/utils': 7.1.1 + edge-error: 4.0.2 + picomatch: 4.0.7 + vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0) + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@adonisjs/shield': 9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1) + edge.js: 6.5.1 + + '@antfu/install-pkg@2.1.0': + dependencies: + package-manager-detector: 1.9.0 + tinyexec: 1.3.1 + + '@arr/every@1.0.1': {} + + '@ast-grep/napi-darwin-arm64@0.45.3': + optional: true + + '@ast-grep/napi-darwin-x64@0.45.3': + optional: true + + '@ast-grep/napi-linux-arm64-gnu@0.45.3': + optional: true + + '@ast-grep/napi-linux-arm64-musl@0.45.3': + optional: true + + '@ast-grep/napi-linux-x64-gnu@0.45.3': + optional: true + + '@ast-grep/napi-linux-x64-musl@0.45.3': + optional: true + + '@ast-grep/napi-win32-arm64-msvc@0.45.3': + optional: true + + '@ast-grep/napi-win32-ia32-msvc@0.45.3': + optional: true + + '@ast-grep/napi-win32-x64-msvc@0.45.3': + optional: true + + '@ast-grep/napi@0.45.3': + optionalDependencies: + '@ast-grep/napi-darwin-arm64': 0.45.3 + '@ast-grep/napi-darwin-x64': 0.45.3 + '@ast-grep/napi-linux-arm64-gnu': 0.45.3 + '@ast-grep/napi-linux-arm64-musl': 0.45.3 + '@ast-grep/napi-linux-x64-gnu': 0.45.3 + '@ast-grep/napi-linux-x64-musl': 0.45.3 + '@ast-grep/napi-win32-arm64-msvc': 0.45.3 + '@ast-grep/napi-win32-ia32-msvc': 0.45.3 + '@ast-grep/napi-win32-x64-msvc': 0.45.3 + + '@babel/code-frame@7.29.7': + dependencies: + '@babel/helper-validator-identifier': 7.29.7 + js-tokens: 4.0.0 + picocolors: 1.1.1 + '@babel/helper-string-parser@7.29.7': {} '@babel/helper-validator-identifier@7.29.7': {} @@ -3222,11 +5568,31 @@ snapshots: dependencies: '@babel/types': 7.29.7 + '@babel/parser@7.29.9': + dependencies: + '@babel/types': 7.29.8 + '@babel/types@7.29.7': dependencies: '@babel/helper-string-parser': 7.29.7 '@babel/helper-validator-identifier': 7.29.7 + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@borewit/text-codec@0.2.2': {} + + '@boringnode/encryption@1.0.1': + dependencies: + '@poppinss/utils': 7.1.1 + + '@boringnode/route-matcher@0.1.1': {} + + '@colors/colors@1.5.0': + optional: true + '@csstools/selector-resolve-nested@3.1.0(postcss-selector-parser@7.1.4)': dependencies: postcss-selector-parser: 7.1.4 @@ -3300,6 +5666,8 @@ snapshots: tslib: 2.8.1 optional: true + '@faker-js/faker@10.6.0': {} + '@fastify/accept-negotiator@1.1.0': {} '@fastify/ajv-compiler@3.6.0': @@ -3335,6 +5703,23 @@ snapshots: fastq: 1.20.1 glob: 10.5.0 + '@inertiajs/core@3.9.1': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + es-toolkit: 1.52.0 + laravel-precognition: 2.1.0 + + '@inertiajs/vue3@3.9.1(vue@3.5.43(typescript@6.0.3))': + dependencies: + '@inertiajs/core': 3.9.1 + es-toolkit: 1.52.0 + laravel-precognition: 2.1.0 + vue: 3.5.43(typescript@6.0.3) + transitivePeerDependencies: + - axios + + '@ioredis/commands@2.0.0': {} + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -3344,6 +5729,68 @@ snapshots: wrap-ansi: 8.1.0 wrap-ansi-cjs: wrap-ansi@7.0.0 + '@japa/assert@4.2.0(@japa/runner@5.3.0)': + dependencies: + '@japa/runner': 5.3.0 + '@poppinss/macroable': 1.1.2 + '@types/chai': 5.2.3 + assertion-error: 2.0.1 + chai: 6.3.0 + + '@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0)': + dependencies: + '@japa/assert': 4.2.0(@japa/runner@5.3.0) + '@japa/runner': 5.3.0 + '@poppinss/qs': 6.15.0 + '@sindresorhus/slugify': 3.0.1 + playwright: 1.64.0 + + '@japa/core@10.4.0': + dependencies: + '@poppinss/hooks': 7.3.1 + '@poppinss/macroable': 1.1.2 + '@poppinss/string': 1.7.2 + async-retry: 1.3.3 + emittery: 1.2.1 + string-width: 8.3.0 + + '@japa/errors-printer@4.1.4': + dependencies: + '@poppinss/colors': 4.1.6 + jest-diff: 30.5.2 + supports-color: 10.2.2 + youch: 4.1.1 + + '@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0)': + dependencies: + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@japa/runner': 5.3.0 + optionalDependencies: + '@japa/browser-client': 2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0) + playwright: 1.64.0 + + '@japa/runner@5.3.0': + dependencies: + '@japa/core': 10.4.0 + '@japa/errors-printer': 4.1.4 + '@poppinss/colors': 4.1.6 + '@poppinss/hooks': 7.3.1 + '@poppinss/string': 1.7.2 + '@poppinss/utils': 7.1.1 + error-stack-parser-es: 1.0.5 + find-cache-directory: 6.0.0 + getopts: 2.3.0 + supports-color: 10.2.2 + timekeeper: 2.3.1 + + '@jest/diff-sequences@30.5.0': {} + + '@jest/get-type@30.5.0': {} + + '@jest/schemas@30.5.0': + dependencies: + '@sinclair/typebox': 0.34.52 + '@jridgewell/gen-mapping@0.3.13': dependencies: '@jridgewell/sourcemap-codec': 1.5.5 @@ -3386,6 +5833,8 @@ snapshots: '@oxc-project/types@0.139.0': {} + '@oxc-project/types@0.153.0': {} + '@oxfmt/binding-android-arm-eabi@0.59.0': optional: true @@ -3500,11 +5949,90 @@ snapshots: '@oxlint/binding-win32-x64-msvc@1.74.0': optional: true + '@phc/format@1.0.0': {} + '@pinojs/redact@0.4.0': {} '@pkgjs/parseargs@0.11.0': optional: true + '@poppinss/cliui@6.8.1': + dependencies: + '@poppinss/colors': 4.1.6 + cli-boxes: 4.0.1 + cli-table3: 0.6.5 + cli-truncate: 5.2.0 + log-update: 7.2.0 + pretty-hrtime: 1.0.3 + string-width: 8.3.0 + supports-color: 10.2.2 + terminal-size: 4.0.1 + + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.7.0': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.2.0 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + + '@poppinss/hooks@7.3.1': {} + + '@poppinss/inspect@1.0.1': {} + + '@poppinss/macroable@1.1.2': {} + + '@poppinss/matchit@3.2.0': + dependencies: + '@arr/every': 1.0.1 + + '@poppinss/middleware@3.2.7': {} + + '@poppinss/multiparty@3.0.0': + dependencies: + http-errors: 2.0.1 + + '@poppinss/object-builder@1.1.0': {} + + '@poppinss/prompts@3.1.6': + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/exception': 1.2.3 + '@poppinss/object-builder': 1.1.0 + enquirer: 2.4.1 + + '@poppinss/qs@6.15.0': {} + + '@poppinss/string@1.7.2': + dependencies: + '@types/pluralize': 0.0.33 + case-anything: 3.1.7 + pluralize: 8.0.0 + slugify: 1.6.9 + + '@poppinss/ts-exec@1.5.0': + dependencies: + '@swc/core': 1.16.18 + get-tsconfig: 4.14.3 + transitivePeerDependencies: + - '@swc/helpers' + + '@poppinss/types@1.2.1': {} + + '@poppinss/utils@7.1.1': + dependencies: + '@poppinss/exception': 1.2.3 + '@poppinss/object-builder': 1.1.0 + '@poppinss/string': 1.7.2 + '@poppinss/types': 1.2.1 + flattie: 1.1.1 + + '@poppinss/validator-lite@2.1.2': {} + '@redis/bloom@5.12.1(@redis/client@5.12.1)': dependencies: '@redis/client': 5.12.1 @@ -3525,42 +6053,81 @@ snapshots: dependencies: '@redis/client': 5.12.1 + '@rolldown/binding-android-arm-eabi@1.2.13': + optional: true + '@rolldown/binding-android-arm64@1.1.5': optional: true + '@rolldown/binding-android-arm64@1.2.13': + optional: true + '@rolldown/binding-darwin-arm64@1.1.5': optional: true + '@rolldown/binding-darwin-arm64@1.2.13': + optional: true + '@rolldown/binding-darwin-x64@1.1.5': optional: true + '@rolldown/binding-darwin-x64@1.2.13': + optional: true + '@rolldown/binding-freebsd-x64@1.1.5': optional: true + '@rolldown/binding-freebsd-x64@1.2.13': + optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.1.5': optional: true + '@rolldown/binding-linux-arm-gnueabihf@1.2.13': + optional: true + '@rolldown/binding-linux-arm64-gnu@1.1.5': optional: true + '@rolldown/binding-linux-arm64-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-arm64-musl@1.1.5': optional: true + '@rolldown/binding-linux-arm64-musl@1.2.13': + optional: true + '@rolldown/binding-linux-ppc64-gnu@1.1.5': optional: true + '@rolldown/binding-linux-ppc64-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-s390x-gnu@1.1.5': optional: true + '@rolldown/binding-linux-s390x-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-x64-gnu@1.1.5': optional: true + '@rolldown/binding-linux-x64-gnu@1.2.13': + optional: true + '@rolldown/binding-linux-x64-musl@1.1.5': optional: true + '@rolldown/binding-linux-x64-musl@1.2.13': + optional: true + '@rolldown/binding-openharmony-arm64@1.1.5': optional: true + '@rolldown/binding-openharmony-arm64@1.2.13': + optional: true + '@rolldown/binding-wasm32-wasi@1.1.5': dependencies: '@emnapi/core': 1.11.1 @@ -3568,28 +6135,115 @@ snapshots: '@napi-rs/wasm-runtime': 1.1.6(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) optional: true - '@rolldown/binding-win32-arm64-msvc@1.1.5': + '@rolldown/binding-win32-arm64-msvc@1.1.5': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.13': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.1.5': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.13': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + + '@sapphire/async-queue@1.5.5': {} + + '@sapphire/shapeshift@4.0.0': + dependencies: + fast-deep-equal: 3.1.3 + lodash: 4.18.1 + + '@sapphire/snowflake@3.5.3': {} + + '@sapphire/snowflake@3.5.5': {} + + '@sec-ant/readable-stream@0.4.1': {} + + '@silvia-odwyer/photon-node@0.3.4': {} + + '@sinclair/typebox@0.34.52': {} + + '@sindresorhus/is@7.2.0': {} + + '@sindresorhus/is@8.1.0': {} + + '@sindresorhus/merge-streams@4.0.0': {} + + '@sindresorhus/slugify@3.0.1': + dependencies: + '@sindresorhus/transliterate': 2.3.1 + escape-string-regexp: 5.0.0 + + '@sindresorhus/transliterate@2.3.1': {} + + '@speed-highlight/core@1.2.24': {} + + '@sqltools/formatter@1.2.5': {} + + '@standard-schema/spec@1.1.0': {} + + '@swc/core-darwin-arm64@1.16.18': + optional: true + + '@swc/core-darwin-x64@1.16.18': + optional: true + + '@swc/core-linux-arm-gnueabihf@1.16.18': + optional: true + + '@swc/core-linux-arm64-gnu@1.16.18': + optional: true + + '@swc/core-linux-arm64-musl@1.16.18': + optional: true + + '@swc/core-linux-ppc64-gnu@1.16.18': optional: true - '@rolldown/binding-win32-x64-msvc@1.1.5': + '@swc/core-linux-s390x-gnu@1.16.18': optional: true - '@rolldown/pluginutils@1.0.1': {} + '@swc/core-linux-x64-gnu@1.16.18': + optional: true - '@sapphire/async-queue@1.5.5': {} + '@swc/core-linux-x64-musl@1.16.18': + optional: true - '@sapphire/shapeshift@4.0.0': - dependencies: - fast-deep-equal: 3.1.3 - lodash: 4.18.1 + '@swc/core-win32-arm64-msvc@1.16.18': + optional: true - '@sapphire/snowflake@3.5.3': {} + '@swc/core-win32-ia32-msvc@1.16.18': + optional: true - '@sapphire/snowflake@3.5.5': {} + '@swc/core-win32-x64-msvc@1.16.18': + optional: true - '@silvia-odwyer/photon-node@0.3.4': {} + '@swc/core@1.16.18': + dependencies: + '@swc/counter': 0.1.3 + '@swc/types': 0.1.28 + optionalDependencies: + '@swc/core-darwin-arm64': 1.16.18 + '@swc/core-darwin-x64': 1.16.18 + '@swc/core-linux-arm-gnueabihf': 1.16.18 + '@swc/core-linux-arm64-gnu': 1.16.18 + '@swc/core-linux-arm64-musl': 1.16.18 + '@swc/core-linux-ppc64-gnu': 1.16.18 + '@swc/core-linux-s390x-gnu': 1.16.18 + '@swc/core-linux-x64-gnu': 1.16.18 + '@swc/core-linux-x64-musl': 1.16.18 + '@swc/core-win32-arm64-msvc': 1.16.18 + '@swc/core-win32-ia32-msvc': 1.16.18 + '@swc/core-win32-x64-msvc': 1.16.18 - '@sqltools/formatter@1.2.5': {} + '@swc/counter@0.1.3': {} + + '@swc/types@0.1.28': + dependencies: + '@swc/counter': 0.1.3 '@tailwindcss/node@4.3.3': dependencies: @@ -3659,6 +6313,29 @@ snapshots: tailwindcss: 4.3.3 vite: 8.1.5(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) + '@tokenizer/inflate@0.4.1(supports-color@10.2.2)': + dependencies: + debug: 4.4.3(supports-color@10.2.2) + token-types: 6.1.2 + transitivePeerDependencies: + - supports-color + + '@tokenizer/token@0.3.0': {} + + '@ts-morph/common@0.29.0': + dependencies: + minimatch: 10.2.6 + path-browserify: 1.0.1 + tinyglobby: 0.2.17 + + '@tuyau/core@1.2.2(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))': + dependencies: + ky: 1.14.3 + object-to-formdata: 4.5.1 + optionalDependencies: + '@adonisjs/assembler': 8.5.2(typescript@6.0.3) + '@adonisjs/core': 7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1) + '@tybys/wasm-util@0.10.3': dependencies: tslib: 2.8.1 @@ -3669,6 +6346,11 @@ snapshots: '@types/connect': 3.4.38 '@types/node': 24.13.3 + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + '@types/connect@3.4.38': dependencies: '@types/node': 24.13.3 @@ -3677,6 +6359,8 @@ snapshots: dependencies: '@types/node': 24.13.3 + '@types/deep-eql@4.0.2': {} + '@types/express-serve-static-core@4.19.9': dependencies: '@types/node': 24.13.3 @@ -3691,6 +6375,8 @@ snapshots: '@types/qs': 6.15.1 '@types/serve-static': 1.15.10 + '@types/he@1.2.3': {} + '@types/http-errors@2.0.5': {} '@types/js-yaml@3.12.10': {} @@ -3703,6 +6389,8 @@ snapshots: '@types/lodash@4.17.24': {} + '@types/luxon@3.7.6': {} + '@types/mime@1.3.5': {} '@types/multer@1.4.13': @@ -3713,6 +6401,12 @@ snapshots: dependencies: undici-types: 7.18.2 + '@types/node@26.6.5': + dependencies: + undici-types: 8.9.0 + + '@types/normalize-package-data@2.4.4': {} + '@types/oauth@0.9.6': dependencies: '@types/node': 24.13.3 @@ -3732,6 +6426,8 @@ snapshots: dependencies: '@types/express': 4.17.25 + '@types/pluralize@0.0.33': {} + '@types/qs@6.15.1': {} '@types/range-parser@1.2.7': {} @@ -3759,6 +6455,8 @@ snapshots: '@types/uuid@9.0.8': {} + '@types/validator@13.15.10': {} + '@types/ws@8.18.1': dependencies: '@types/node': 24.13.3 @@ -3823,11 +6521,32 @@ snapshots: '@typescript/typescript-win32-x64@7.0.2': optional: true + '@vinejs/compiler@4.1.3': {} + + '@vinejs/vine@4.4.0': + dependencies: + '@poppinss/macroable': 1.1.2 + '@poppinss/types': 1.2.1 + '@standard-schema/spec': 1.1.0 + '@types/validator': 13.15.10 + '@vinejs/compiler': 4.1.3 + camelcase: 9.0.0 + dayjs: 1.11.21 + dlv: 1.1.3 + normalize-url: 8.1.1 + validator: 13.15.35 + '@vitejs/plugin-vue@5.2.4(vite@8.1.5(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.40(typescript@6.0.3))': dependencies: vite: 8.1.5(@types/node@24.13.3)(jiti@2.7.0)(yaml@2.9.0) vue: 3.5.40(typescript@6.0.3) + '@vitejs/plugin-vue@6.0.10(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0))(vue@3.5.43(typescript@6.0.3))': + dependencies: + '@rolldown/pluginutils': 1.0.1 + vite: 8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0) + vue: 3.5.43(typescript@6.0.3) + '@vladfrangu/async_event_emitter@2.4.7': {} '@volar/language-core@2.4.28': @@ -3854,11 +6573,24 @@ snapshots: estree-walker: 2.0.2 source-map-js: 1.2.1 + '@vue/compiler-core@3.5.43': + dependencies: + '@babel/parser': 7.29.9 + '@vue/shared': 3.5.43 + entities: 7.0.1 + estree-walker: 2.0.2 + source-map-js: 1.2.1 + '@vue/compiler-dom@3.5.40': dependencies: '@vue/compiler-core': 3.5.40 '@vue/shared': 3.5.40 + '@vue/compiler-dom@3.5.43': + dependencies: + '@vue/compiler-core': 3.5.43 + '@vue/shared': 3.5.43 + '@vue/compiler-sfc@3.5.40': dependencies: '@babel/parser': 7.29.7 @@ -3871,13 +6603,40 @@ snapshots: postcss: 8.5.19 source-map-js: 1.2.1 + '@vue/compiler-sfc@3.5.43': + dependencies: + '@babel/parser': 7.29.9 + '@vue/compiler-core': 3.5.43 + '@vue/compiler-dom': 3.5.43 + '@vue/compiler-ssr': 3.5.43 + '@vue/shared': 3.5.43 + estree-walker: 2.0.2 + magic-string: 0.30.21 + postcss: 8.5.29 + source-map-js: 1.2.1 + '@vue/compiler-ssr@3.5.40': dependencies: '@vue/compiler-dom': 3.5.40 '@vue/shared': 3.5.40 + '@vue/compiler-ssr@3.5.43': + dependencies: + '@vue/compiler-dom': 3.5.43 + '@vue/shared': 3.5.43 + '@vue/devtools-api@6.6.4': {} + '@vue/language-core@3.3.13': + dependencies: + '@volar/language-core': 2.4.28 + '@vue/compiler-dom': 3.5.40 + '@vue/shared': 3.5.40 + alien-signals: 3.2.1 + muggle-string: 0.4.1 + path-browserify: 1.0.1 + picomatch: 4.0.5 + '@vue/language-core@3.3.7': dependencies: '@volar/language-core': 2.4.28 @@ -3892,11 +6651,20 @@ snapshots: dependencies: '@vue/shared': 3.5.40 + '@vue/reactivity@3.5.43': + dependencies: + '@vue/shared': 3.5.43 + '@vue/runtime-core@3.5.40': dependencies: '@vue/reactivity': 3.5.40 '@vue/shared': 3.5.40 + '@vue/runtime-core@3.5.43': + dependencies: + '@vue/reactivity': 3.5.43 + '@vue/shared': 3.5.43 + '@vue/runtime-dom@3.5.40': dependencies: '@vue/reactivity': 3.5.40 @@ -3904,14 +6672,29 @@ snapshots: '@vue/shared': 3.5.40 csstype: 3.2.3 + '@vue/runtime-dom@3.5.43': + dependencies: + '@vue/reactivity': 3.5.43 + '@vue/runtime-core': 3.5.43 + '@vue/shared': 3.5.43 + csstype: 3.2.3 + '@vue/server-renderer@3.5.40': dependencies: '@vue/compiler-ssr': 3.5.40 '@vue/runtime-dom': 3.5.40 '@vue/shared': 3.5.40 + '@vue/server-renderer@3.5.43': + dependencies: + '@vue/compiler-ssr': 3.5.43 + '@vue/runtime-dom': 3.5.43 + '@vue/shared': 3.5.43 + '@vue/shared@3.5.40': {} + '@vue/shared@3.5.43': {} + '@vue/tsconfig@0.7.0(typescript@6.0.3)(vue@3.5.40(typescript@6.0.3))': optionalDependencies: typescript: 6.0.3 @@ -3954,6 +6737,14 @@ snapshots: alien-signals@3.2.1: {} + angular-html-parser@10.13.0: {} + + ansi-colors@4.1.3: {} + + ansi-escapes@7.3.0: + dependencies: + environment: 1.1.0 + ansi-regex@5.0.1: {} ansi-regex@6.2.2: {} @@ -3962,6 +6753,8 @@ snapshots: dependencies: color-convert: 2.0.1 + ansi-styles@5.2.0: {} + ansi-styles@6.2.3: {} ansis@4.3.1: {} @@ -3989,9 +6782,17 @@ snapshots: arrify@3.0.0: {} + assertion-error@2.0.1: {} + + astring@1.9.0: {} + + async-retry@1.3.3: + dependencies: + retry: 0.13.1 + atomic-sleep@1.0.0: {} - ava@5.3.1: + ava@5.3.1(supports-color@10.2.2): dependencies: acorn: 8.17.0 acorn-walk: 8.3.5 @@ -4011,7 +6812,7 @@ snapshots: common-path-prefix: 3.0.0 concordance: 5.0.4 currently-unhandled: 0.4.1 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) emittery: 1.2.1 figures: 5.0.0 globby: 13.2.2 @@ -4052,19 +6853,25 @@ snapshots: balanced-match@1.0.2: {} + balanced-match@4.0.4: {} + base64-js@1.5.1: {} base64url@3.0.1: {} + basic-auth@2.0.1: + dependencies: + safe-buffer: 5.1.2 + binary-extensions@2.3.0: {} blueimp-md5@2.19.0: {} - body-parser@1.20.6: + body-parser@1.20.6(supports-color@10.2.2): dependencies: bytes: 3.1.2 content-type: 1.0.5 - debug: 2.6.9 + debug: 2.6.9(supports-color@10.2.2) depd: 2.0.0 destroy: 1.2.0 http-errors: 2.0.1 @@ -4081,6 +6888,10 @@ snapshots: dependencies: balanced-match: 1.0.2 + brace-expansion@5.0.12: + dependencies: + balanced-match: 4.0.4 + braces@3.0.3: dependencies: fill-range: 7.1.1 @@ -4096,6 +6907,10 @@ snapshots: dependencies: node-gyp-build: 4.8.4 + bundle-name@4.1.1: + dependencies: + run-applescript: 7.1.0 + busboy@1.6.0: dependencies: streamsearch: 1.1.0 @@ -4123,12 +6938,25 @@ snapshots: callsites@4.2.0: {} + camelcase@9.0.0: {} + + case-anything@3.1.7: {} + cbor@8.1.0: dependencies: nofilter: 3.1.0 + chai@6.3.0: {} + + chalk@4.1.2: + dependencies: + ansi-styles: 4.3.0 + supports-color: 7.2.0 + chalk@5.6.2: {} + check-disk-space@3.4.0: {} + chokidar@3.6.0: dependencies: anymatch: 3.1.3 @@ -4141,6 +6969,10 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + chunkd@2.0.1: {} ci-info@3.9.0: {} @@ -4153,19 +6985,40 @@ snapshots: clean-yaml-object@0.1.0: {} + cli-boxes@4.0.1: {} + + cli-cursor@5.0.0: + dependencies: + restore-cursor: 5.1.0 + + cli-table3@0.6.5: + dependencies: + string-width: 4.2.3 + optionalDependencies: + '@colors/colors': 1.5.0 + cli-truncate@3.1.0: dependencies: slice-ansi: 5.0.0 string-width: 5.1.2 + cli-truncate@5.2.0: + dependencies: + slice-ansi: 8.0.0 + string-width: 8.3.0 + cliui@8.0.1: dependencies: string-width: 4.2.3 strip-ansi: 6.0.1 wrap-ansi: 7.0.0 + cluster-key-slot@1.1.1: {} + cluster-key-slot@1.1.2: {} + code-block-writer@13.0.3: {} + code-excerpt@4.0.0: dependencies: convert-to-spaces: 2.0.1 @@ -4178,6 +7031,12 @@ snapshots: color-name@1.1.4: {} + colorette@2.0.19: {} + + colorette@2.0.20: {} + + commander@10.0.1: {} + common-path-prefix@3.0.0: {} concat-stream@2.0.0: @@ -4202,10 +7061,16 @@ snapshots: dependencies: safe-buffer: 5.2.1 + content-disposition@1.1.0: {} + content-type@1.0.5: {} + content-type@2.1.0: {} + convert-to-spaces@2.0.1: {} + cookie-es@3.1.1: {} + cookie-signature@1.0.7: {} cookie@0.7.2: {} @@ -4225,6 +7090,12 @@ snapshots: shebang-command: 2.0.0 which: 2.0.2 + csrf@3.1.0: + dependencies: + rndm: 1.2.0 + tsscmp: 1.0.6 + uid-safe: 2.1.5 + cssesc@3.0.0: {} csstype@3.2.3: {} @@ -4237,26 +7108,49 @@ snapshots: dependencies: time-zone: 1.0.0 + dateformat@4.6.3: {} + dayjs@1.11.21: {} - debug@2.6.9: + debug@2.6.9(supports-color@10.2.2): dependencies: ms: 2.0.0 + optionalDependencies: + supports-color: 10.2.2 - debug@4.4.3: + debug@4.3.4(supports-color@10.2.2): + dependencies: + ms: 2.1.2 + optionalDependencies: + supports-color: 10.2.2 + + debug@4.4.3(supports-color@10.2.2): dependencies: ms: 2.1.3 + optionalDependencies: + supports-color: 10.2.2 dedent@1.7.2: {} deep-diff@1.0.2: {} + deepmerge@4.3.1: {} + + default-browser-id@5.0.1: {} + + default-browser@5.5.1: + dependencies: + bundle-name: 4.1.1 + default-browser-id: 5.0.1 + define-data-property@1.1.4: dependencies: es-define-property: 1.0.1 es-errors: 1.3.0 gopd: 1.2.0 + define-lazy-prop@3.0.0: {} + denque@2.1.0: {} depd@2.0.0: {} @@ -4290,6 +7184,8 @@ snapshots: - bufferutil - utf-8-validate + dlv@1.1.3: {} + dotenv@16.6.1: {} dotenv@17.4.2: {} @@ -4302,6 +7198,32 @@ snapshots: eastasianwidth@0.2.0: {} + edge-error@4.0.2: {} + + edge-lexer@6.0.5: + dependencies: + edge-error: 4.0.2 + + edge-parser@9.1.1: + dependencies: + acorn: 8.17.0 + astring: 1.9.0 + edge-error: 4.0.2 + edge-lexer: 6.0.5 + js-stringify: 1.0.2 + + edge.js@6.5.1: + dependencies: + '@poppinss/inspect': 1.0.1 + '@poppinss/macroable': 1.1.2 + '@poppinss/utils': 7.1.1 + edge-error: 4.0.2 + edge-lexer: 6.0.5 + edge-parser: 9.1.1 + he: 1.2.0 + property-information: 7.2.0 + stringify-attributes: 4.0.0 + ee-first@1.1.1: {} emittery@1.2.1: {} @@ -4312,23 +7234,44 @@ snapshots: encodeurl@2.0.0: {} + end-of-stream@1.4.5: + dependencies: + once: 1.4.0 + enhanced-resolve@5.24.2: dependencies: graceful-fs: 4.2.11 tapable: 2.3.3 + enquirer@2.4.1: + dependencies: + ansi-colors: 4.1.3 + strip-ansi: 6.0.1 + entities@7.0.1: {} + environment@1.1.0: {} + + error-stack-parser-es@1.0.5: {} + + error-stack-parser-es@2.0.1: {} + es-define-property@1.0.1: {} es-errors@1.3.0: {} + es-module-lexer@1.7.0: {} + es-object-atoms@1.1.2: dependencies: es-errors: 1.3.0 + es-toolkit@1.52.0: {} + escalade@3.2.0: {} + escape-goat@4.0.0: {} + escape-html@1.0.3: {} escape-string-regexp@1.0.5: {} @@ -4337,8 +7280,7 @@ snapshots: escape-string-regexp@5.0.0: {} - esm@3.2.25: - optional: true + esm@3.2.25: {} esprima@4.0.1: {} @@ -4348,21 +7290,36 @@ snapshots: etag@1.8.1: {} - express@4.22.2: + execa@9.6.1: + dependencies: + '@sindresorhus/merge-streams': 4.0.0 + cross-spawn: 7.0.6 + figures: 6.1.0 + get-stream: 9.0.1 + human-signals: 8.0.1 + is-plain-obj: 4.1.0 + is-stream: 4.0.1 + npm-run-path: 6.0.0 + pretty-ms: 9.3.1 + signal-exit: 4.1.0 + strip-final-newline: 4.0.0 + yoctocolors: 2.2.0 + + express@4.22.2(supports-color@10.2.2): dependencies: accepts: 1.3.8 array-flatten: 1.1.1 - body-parser: 1.20.6 + body-parser: 1.20.6(supports-color@10.2.2) content-disposition: 0.5.4 content-type: 1.0.5 cookie: 0.7.2 cookie-signature: 1.0.7 - debug: 2.6.9 + debug: 2.6.9(supports-color@10.2.2) depd: 2.0.0 encodeurl: 2.0.0 escape-html: 1.0.3 etag: 1.8.1 - finalhandler: 1.3.2 + finalhandler: 1.3.2(supports-color@10.2.2) fresh: 0.5.2 http-errors: 2.0.1 merge-descriptors: 1.0.3 @@ -4374,8 +7331,8 @@ snapshots: qs: 6.15.3 range-parser: 1.2.1 safe-buffer: 5.2.1 - send: 0.19.2 - serve-static: 1.16.3 + send: 0.19.2(supports-color@10.2.2) + serve-static: 1.16.3(supports-color@10.2.2) setprototypeof: 1.2.0 statuses: 2.0.2 type-is: 1.6.18 @@ -4386,6 +7343,8 @@ snapshots: fast-content-type-parse@1.1.0: {} + fast-copy@4.1.2: {} + fast-decode-uri-component@1.0.1: {} fast-deep-equal@3.1.3: {} @@ -4414,10 +7373,14 @@ snapshots: dependencies: fast-decode-uri-component: 1.0.1 + fast-safe-stringify@2.1.1: {} + fast-uri@2.4.2: {} fast-uri@3.1.3: {} + fastest-levenshtein@1.0.16: {} + fastify-plugin@4.5.1: {} fastify@4.29.1: @@ -4452,13 +7415,26 @@ snapshots: escape-string-regexp: 5.0.0 is-unicode-supported: 1.3.0 + figures@6.1.0: + dependencies: + is-unicode-supported: 2.1.0 + + file-type@22.1.1(supports-color@10.2.2): + dependencies: + '@tokenizer/inflate': 0.4.1(supports-color@10.2.2) + strtok3: 10.4.0 + token-types: 6.1.2 + uint8array-extras: 1.6.0 + transitivePeerDependencies: + - supports-color + fill-range@7.1.1: dependencies: to-regex-range: 5.0.1 - finalhandler@1.3.2: + finalhandler@1.3.2(supports-color@10.2.2): dependencies: - debug: 2.6.9 + debug: 2.6.9(supports-color@10.2.2) encodeurl: 2.0.0 escape-html: 1.0.3 on-finished: 2.4.1 @@ -4468,12 +7444,19 @@ snapshots: transitivePeerDependencies: - supports-color + find-cache-directory@6.0.0: + dependencies: + common-path-prefix: 3.0.0 + pkg-dir: 8.0.0 + find-my-way@8.2.2: dependencies: fast-deep-equal: 3.1.3 fast-querystring: 1.1.2 safe-regex2: 3.1.0 + find-up-simple@1.0.1: {} + find-up@3.0.0: dependencies: locate-path: 3.0.0 @@ -4483,6 +7466,8 @@ snapshots: locate-path: 7.2.0 path-exists: 5.0.0 + flattie@1.1.1: {} + for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -4498,6 +7483,8 @@ snapshots: fresh@0.5.2: {} + fresh@2.0.0: {} + fs-extra@8.1.0: dependencies: graceful-fs: 4.2.11 @@ -4515,6 +7502,8 @@ snapshots: get-caller-file@2.0.5: {} + get-east-asian-width@1.7.0: {} + get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 @@ -4528,15 +7517,34 @@ snapshots: hasown: 2.0.4 math-intrinsics: 1.1.0 + get-package-type@0.1.0: {} + + get-port@7.2.0: {} + get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 es-object-atoms: 1.1.2 + get-stream@9.0.1: + dependencies: + '@sec-ant/readable-stream': 0.4.1 + is-stream: 4.0.1 + + get-tsconfig@4.14.3: + dependencies: + resolve-pkg-maps: 1.0.0 + + getopts@2.3.0: {} + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 + glob-parent@6.0.2: + dependencies: + is-glob: 4.0.3 + glob@10.5.0: dependencies: foreground-child: 3.3.1 @@ -4558,6 +7566,8 @@ snapshots: graceful-fs@4.2.11: {} + has-flag@4.0.0: {} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.1 @@ -4572,10 +7582,28 @@ snapshots: dependencies: function-bind: 1.1.2 + he@1.2.0: {} + + help-me@5.0.0: {} + highlight.js@10.7.3: {} highlight.js@11.11.1: {} + hosted-git-info@9.0.3: + dependencies: + lru-cache: 11.5.3 + + hot-hook@1.0.0: + dependencies: + chokidar: 5.0.0 + fast-glob: 3.3.3 + parse-imports: 3.0.0 + picomatch: 4.0.5 + read-package-up: 12.0.0 + + html-entities@2.6.0: {} + http-errors@2.0.0: dependencies: depd: 2.0.0 @@ -4592,6 +7620,8 @@ snapshots: statuses: 2.0.2 toidentifier: 1.0.1 + human-signals@8.0.1: {} + humanize-duration@3.34.0: {} iconv-lite@0.4.24: @@ -4604,16 +7634,37 @@ snapshots: ieee754@1.2.1: {} + igniculus@1.5.0: {} + ignore-by-default@2.1.0: {} ignore@5.3.2: {} + import-meta-resolve@4.2.0: {} + imurmurhash@0.1.4: {} indent-string@5.0.0: {} + index-to-position@1.2.0: {} + + inflation@2.1.0: {} + inherits@2.0.4: {} + interpret@2.2.0: {} + + ioredis@6.0.0(supports-color@10.2.2): + dependencies: + '@ioredis/commands': 2.0.0 + cluster-key-slot: 1.1.1 + debug: 4.4.3(supports-color@10.2.2) + denque: 2.1.0 + redis-errors: 1.2.0 + standard-as-callback: 2.1.0 + transitivePeerDependencies: + - supports-color + ipaddr.js@1.9.1: {} irregular-plurals@3.5.0: {} @@ -4624,6 +7675,12 @@ snapshots: is-callable@1.2.7: {} + is-core-module@2.17.0: + dependencies: + hasown: 2.0.4 + + is-docker@3.0.0: {} + is-error@2.2.2: {} is-extglob@2.1.1: {} @@ -4632,26 +7689,46 @@ snapshots: is-fullwidth-code-point@4.0.0: {} + is-fullwidth-code-point@5.1.0: + dependencies: + get-east-asian-width: 1.7.0 + is-glob@4.0.3: dependencies: is-extglob: 2.1.1 + is-in-ssh@1.0.0: {} + + is-inside-container@1.0.0: + dependencies: + is-docker: 3.0.0 + is-number@7.0.0: {} is-observable@2.1.0: {} + is-plain-obj@4.1.0: {} + is-plain-object@5.0.0: {} is-promise@4.0.0: {} is-property@1.0.2: {} + is-stream@4.0.1: {} + is-typed-array@1.1.15: dependencies: which-typed-array: 1.1.22 is-unicode-supported@1.3.0: {} + is-unicode-supported@2.1.0: {} + + is-wsl@3.1.1: + dependencies: + is-inside-container: 1.0.0 + isarray@2.0.5: {} isexe@2.0.0: {} @@ -4662,10 +7739,23 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 + jest-diff@30.5.2: + dependencies: + '@jest/diff-sequences': 30.5.0 + '@jest/get-type': 30.5.0 + chalk: 4.1.2 + pretty-format: 30.5.1 + jiti@2.7.0: {} + joycon@3.1.1: {} + js-string-escape@1.0.1: {} + js-stringify@1.0.2: {} + + js-tokens@4.0.0: {} + js-yaml@3.15.0: dependencies: argparse: 1.0.10 @@ -4697,49 +7787,131 @@ snapshots: optionalDependencies: graceful-fs: 4.2.11 + jsonschema@1.5.0: {} + + junk@4.0.1: {} + + kleur@4.1.5: {} + + knex-dynamic-connection@5.1.1(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2): + dependencies: + debug: 4.4.3(supports-color@10.2.2) + knex: 3.3.0(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2) + transitivePeerDependencies: + - better-sqlite3 + - mariadb + - mysql + - mysql2 + - pg + - pg-native + - pg-query-stream + - sqlite3 + - supports-color + - tedious + + knex@3.3.0(mysql2@3.23.0(@types/node@26.6.5))(supports-color@10.2.2): + dependencies: + colorette: 2.0.19 + commander: 10.0.1 + debug: 4.3.4(supports-color@10.2.2) + escalade: 3.2.0 + esm: 3.2.25 + get-package-type: 0.1.0 + getopts: 2.3.0 + interpret: 2.2.0 + lodash: 4.18.1 + pg-connection-string: 2.6.2 + rechoir: 0.8.0 + resolve-from: 5.0.0 + tarn: 3.1.2 + tildify: 2.0.0 + optionalDependencies: + mysql2: 3.23.0(@types/node@26.6.5) + transitivePeerDependencies: + - supports-color + knub-command-manager@9.1.0: dependencies: escape-string-regexp: 2.0.0 + ky@1.14.3: {} + + laravel-precognition@2.1.0: + dependencies: + es-toolkit: 1.52.0 + light-my-request@5.14.0: dependencies: cookie: 0.7.2 process-warning: 3.0.0 set-cookie-parser: 2.7.2 - lightningcss-android-arm64@1.32.0: + lightningcss-android-arm64@1.32.0: + optional: true + + lightningcss-android-arm64@1.33.0: optional: true lightningcss-darwin-arm64@1.32.0: optional: true + lightningcss-darwin-arm64@1.33.0: + optional: true + lightningcss-darwin-x64@1.32.0: optional: true + lightningcss-darwin-x64@1.33.0: + optional: true + lightningcss-freebsd-x64@1.32.0: optional: true + lightningcss-freebsd-x64@1.33.0: + optional: true + lightningcss-linux-arm-gnueabihf@1.32.0: optional: true + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + lightningcss-linux-arm64-gnu@1.32.0: optional: true + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + lightningcss-linux-arm64-musl@1.32.0: optional: true + lightningcss-linux-arm64-musl@1.33.0: + optional: true + lightningcss-linux-x64-gnu@1.32.0: optional: true + lightningcss-linux-x64-gnu@1.33.0: + optional: true + lightningcss-linux-x64-musl@1.32.0: optional: true + lightningcss-linux-x64-musl@1.33.0: + optional: true + lightningcss-win32-arm64-msvc@1.32.0: optional: true + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + lightningcss-win32-x64-msvc@1.32.0: optional: true + lightningcss-win32-x64-msvc@1.33.0: + optional: true + lightningcss@1.32.0: dependencies: detect-libc: 2.1.2 @@ -4756,6 +7928,22 @@ snapshots: lightningcss-win32-arm64-msvc: 1.32.0 lightningcss-win32-x64-msvc: 1.32.0 + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + load-json-file@7.0.1: {} locate-path@3.0.0: @@ -4773,12 +7961,28 @@ snapshots: lodash@4.18.1: {} + log-update@7.2.0: + dependencies: + ansi-escapes: 7.3.0 + cli-cursor: 5.0.0 + slice-ansi: 8.0.0 + strip-ansi: 7.2.0 + wrap-ansi: 10.0.2 + long@5.3.2: {} lru-cache@10.4.3: {} + lru-cache@11.5.3: {} + lru.min@1.1.4: {} + lucide-vue-next@1.0.0(vue@3.5.43(typescript@6.0.3)): + dependencies: + vue: 3.5.43(typescript@6.0.3) + + luxon@3.7.2: {} + magic-bytes.js@1.13.0: {} magic-string@0.30.21: @@ -4803,6 +8007,8 @@ snapshots: media-typer@0.3.0: {} + media-typer@1.1.1: {} + mem@9.0.2: dependencies: map-age-cleaner: 0.1.3 @@ -4821,16 +8027,28 @@ snapshots: mime-db@1.52.0: {} + mime-db@1.54.0: {} + mime-types@2.1.35: dependencies: mime-db: 1.52.0 + mime-types@3.0.2: + dependencies: + mime-db: 1.54.0 + mime@1.6.0: {} mime@3.0.0: {} mimic-fn@4.0.0: {} + mimic-function@5.0.1: {} + + minimatch@10.2.6: + dependencies: + brace-expansion: 5.0.12 + minimatch@9.0.9: dependencies: brace-expansion: 2.1.2 @@ -4882,6 +8100,8 @@ snapshots: ms@2.0.0: {} + ms@2.1.2: {} + ms@2.1.3: {} muggle-string@0.4.1: {} @@ -4905,12 +8125,26 @@ snapshots: named-placeholders: 1.1.6 sql-escaper: 1.5.1 + mysql2@3.23.0(@types/node@26.6.5): + dependencies: + '@types/node': 26.6.5 + aws-ssl-profiles: 1.1.2 + denque: 2.1.0 + generate-function: 2.3.1 + iconv-lite: 0.7.3 + long: 5.3.2 + lru.min: 1.1.4 + named-placeholders: 1.1.6 + sql-escaper: 1.5.1 + named-placeholders@1.1.6: dependencies: lru.min: 1.1.4 nanoid@3.3.16: {} + nanoid@3.3.20: {} + negotiator@0.6.3: {} node-gyp-build@4.8.4: {} @@ -4919,14 +8153,29 @@ snapshots: nofilter@3.1.0: {} + normalize-package-data@8.0.0: + dependencies: + hosted-git-info: 9.0.3 + semver: 7.8.5 + validate-npm-package-license: 3.0.4 + normalize-path@3.0.0: {} + normalize-url@8.1.1: {} + + npm-run-path@6.0.0: + dependencies: + path-key: 4.0.0 + unicorn-magic: 0.3.0 + oauth@0.10.2: {} object-assign@4.1.1: {} object-inspect@1.13.4: {} + object-to-formdata@4.5.1: {} + observable-fns@0.6.1: {} on-exit-leak-free@2.1.2: {} @@ -4935,6 +8184,23 @@ snapshots: dependencies: ee-first: 1.1.1 + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + onetime@7.0.0: + dependencies: + mimic-function: 5.0.1 + + open@11.0.4: + dependencies: + default-browser: 5.5.1 + define-lazy-prop: 3.0.0 + is-in-ssh: 1.0.0 + is-inside-container: 1.0.0 + powershell-utils: 0.2.1 + wsl-utils: 1.0.1 + oxfmt@0.59.0: dependencies: tinypool: 2.1.0 @@ -5013,12 +8279,27 @@ snapshots: package-json-from-dist@1.0.1: {} + package-manager-detector@1.9.0: {} + parse-color@1.0.0: dependencies: color-convert: 0.5.3 + parse-imports@3.0.0: + dependencies: + es-module-lexer: 1.7.0 + slashes: 3.0.12 + + parse-json@8.3.0: + dependencies: + '@babel/code-frame': 7.29.7 + index-to-position: 1.2.0 + type-fest: 4.41.0 + parse-ms@3.0.0: {} + parse-ms@4.0.0: {} + parseurl@1.3.3: {} passport-custom@1.1.1: @@ -5049,6 +8330,10 @@ snapshots: path-key@3.1.1: {} + path-key@4.0.0: {} + + path-parse@1.0.7: {} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 @@ -5060,18 +8345,56 @@ snapshots: pause@0.0.1: {} + pg-connection-string@2.6.2: {} + picocolors@1.1.1: {} picomatch@2.3.2: {} picomatch@4.0.5: {} + picomatch@4.0.7: {} + pino-abstract-transport@2.0.0: dependencies: split2: 4.2.0 + pino-abstract-transport@3.0.0: + dependencies: + split2: 4.2.0 + + pino-pretty@13.2.0: + dependencies: + colorette: 2.0.20 + dateformat: 4.6.3 + fast-copy: 4.1.2 + fast-safe-stringify: 2.1.1 + help-me: 5.0.0 + joycon: 3.1.1 + minimist: 1.2.8 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 3.0.0 + pump: 3.0.4 + secure-json-parse: 4.1.1 + sonic-boom: 5.0.2 + strip-json-comments: 5.0.3 + pino-std-serializers@7.1.0: {} + pino@10.4.0: + dependencies: + '@pinojs/redact': 0.4.0 + atomic-sleep: 1.0.0 + on-exit-leak-free: 2.1.2 + pino-abstract-transport: 3.0.0 + pino-std-serializers: 7.1.0 + process-warning: 5.0.0 + quick-format-unescaped: 4.0.4 + real-require: 1.0.0 + safe-stable-stringify: 2.5.0 + sonic-boom: 4.2.1 + thread-stream: 4.2.0 + pino@9.14.0: dependencies: '@pinojs/redact': 0.4.0 @@ -5091,14 +8414,26 @@ snapshots: find-up: 6.3.0 load-json-file: 7.0.1 + pkg-dir@8.0.0: + dependencies: + find-up-simple: 1.0.1 + pkg-up@3.1.0: dependencies: find-up: 3.0.0 + playwright-core@1.64.0: {} + + playwright@1.64.0: + dependencies: + playwright-core: 1.64.0 + plur@5.1.0: dependencies: irregular-plurals: 3.5.0 + pluralize@8.0.0: {} + possible-typed-array-names@1.1.0: {} postcss-nesting@13.0.2(postcss@8.5.19): @@ -5119,16 +8454,45 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + postcss@8.5.29: + dependencies: + nanoid: 3.3.20 + picocolors: 1.1.1 + source-map-js: 1.2.2 + + powershell-utils@0.2.1: {} + + prettier-edge@1.0.0(prettier@3.9.6): + dependencies: + angular-html-parser: 10.13.0 + edge-lexer: 6.0.5 + prettier: 3.9.6 + prettier@3.9.6: {} + pretty-format@30.5.1: + dependencies: + '@jest/react-is-18': react-is@18.3.1 + '@jest/react-is-19': react-is@19.3.0 + '@jest/schemas': 30.5.0 + ansi-styles: 5.2.0 + + pretty-hrtime@1.0.3: {} + pretty-ms@8.0.0: dependencies: parse-ms: 3.0.0 + pretty-ms@9.3.1: + dependencies: + parse-ms: 4.0.0 + process-warning@3.0.0: {} process-warning@5.0.0: {} + property-information@7.2.0: {} + proxy-addr@2.0.7: dependencies: forwarded: 0.2.0 @@ -5136,6 +8500,11 @@ snapshots: proxy-disposable@1.0.0: {} + pump@3.0.4: + dependencies: + end-of-stream: 1.4.5 + once: 1.4.0 + qs@6.15.3: dependencies: es-define-property: 1.0.1 @@ -5145,6 +8514,8 @@ snapshots: quick-format-unescaped@4.0.4: {} + random-bytes@1.0.0: {} + range-parser@1.2.1: {} raw-body@2.5.3: @@ -5154,6 +8525,31 @@ snapshots: iconv-lite: 0.4.24 unpipe: 1.0.0 + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + + react-is@18.3.1: {} + + react-is@19.3.0: {} + + read-package-up@12.0.0: + dependencies: + find-up-simple: 1.0.1 + read-pkg: 10.1.0 + type-fest: 5.10.0 + + read-pkg@10.1.0: + dependencies: + '@types/normalize-package-data': 2.4.4 + normalize-package-data: 8.0.0 + parse-json: 8.3.0 + type-fest: 5.10.0 + unicorn-magic: 0.4.1 + readable-stream@3.6.2: dependencies: inherits: 2.0.4 @@ -5164,8 +8560,18 @@ snapshots: dependencies: picomatch: 2.3.2 + readdirp@5.1.1: {} + real-require@0.2.0: {} + real-require@1.0.0: {} + + rechoir@0.8.0: + dependencies: + resolve: 1.22.13 + + redis-errors@1.2.0: {} + redis@5.12.1: dependencies: '@redis/bloom': 5.12.1(@redis/client@5.12.1) @@ -5197,12 +8603,30 @@ snapshots: resolve-from@5.0.0: {} + resolve-pkg-maps@1.0.0: {} + + resolve@1.22.13: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.17.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + + restore-cursor@5.1.0: + dependencies: + onetime: 7.0.0 + signal-exit: 4.1.0 + ret@0.4.3: {} + retry@0.13.1: {} + reusify@1.1.0: {} rfdc@1.4.1: {} + rndm@1.2.0: {} + rolldown@1.1.5: dependencies: '@oxc-project/types': 0.139.0 @@ -5224,10 +8648,35 @@ snapshots: '@rolldown/binding-win32-arm64-msvc': 1.1.5 '@rolldown/binding-win32-x64-msvc': 1.1.5 + rolldown@1.2.13: + dependencies: + '@oxc-project/types': 0.153.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.13 + '@rolldown/binding-android-arm64': 1.2.13 + '@rolldown/binding-darwin-arm64': 1.2.13 + '@rolldown/binding-darwin-x64': 1.2.13 + '@rolldown/binding-freebsd-x64': 1.2.13 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.13 + '@rolldown/binding-linux-arm64-gnu': 1.2.13 + '@rolldown/binding-linux-arm64-musl': 1.2.13 + '@rolldown/binding-linux-ppc64-gnu': 1.2.13 + '@rolldown/binding-linux-s390x-gnu': 1.2.13 + '@rolldown/binding-linux-x64-gnu': 1.2.13 + '@rolldown/binding-linux-x64-musl': 1.2.13 + '@rolldown/binding-openharmony-arm64': 1.2.13 + '@rolldown/binding-win32-arm64-msvc': 1.2.13 + '@rolldown/binding-win32-x64-msvc': 1.2.13 + + run-applescript@7.1.0: {} + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 + safe-buffer@5.1.2: {} + safe-buffer@5.2.1: {} safe-regex2@3.1.0: @@ -5244,13 +8693,15 @@ snapshots: secure-json-parse@2.7.0: {} + secure-json-parse@4.1.1: {} + seedrandom@3.0.5: {} semver@7.8.5: {} - send@0.19.2: + send@0.19.2(supports-color@10.2.2): dependencies: - debug: 2.6.9 + debug: 2.6.9(supports-color@10.2.2) depd: 2.0.0 destroy: 1.2.0 encodeurl: 2.0.0 @@ -5266,16 +8717,41 @@ snapshots: transitivePeerDependencies: - supports-color + send@1.2.1(supports-color@10.2.2): + dependencies: + debug: 4.4.3(supports-color@10.2.2) + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.2.1 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + serialize-error@7.0.1: dependencies: type-fest: 0.13.1 - serve-static@1.16.3: + serve-static@1.16.3(supports-color@10.2.2): + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 0.19.2(supports-color@10.2.2) + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1(supports-color@10.2.2): dependencies: encodeurl: 2.0.0 escape-html: 1.0.3 parseurl: 1.3.3 - send: 0.19.2 + send: 1.2.1(supports-color@10.2.2) transitivePeerDependencies: - supports-color @@ -5336,17 +8812,34 @@ snapshots: slash@4.0.0: {} + slash@5.1.0: {} + + slashes@3.0.12: {} + slice-ansi@5.0.0: dependencies: ansi-styles: 6.2.3 is-fullwidth-code-point: 4.0.0 + slice-ansi@8.0.0: + dependencies: + ansi-styles: 6.2.3 + is-fullwidth-code-point: 5.1.0 + + slugify@1.6.9: {} + sonic-boom@4.2.1: dependencies: atomic-sleep: 1.0.0 + sonic-boom@5.0.2: + dependencies: + atomic-sleep: 1.0.0 + source-map-js@1.2.1: {} + source-map-js@1.2.2: {} + source-map-support@0.5.21: dependencies: buffer-from: 1.1.2 @@ -5354,6 +8847,22 @@ snapshots: source-map@0.6.1: {} + spdx-correct@3.2.0: + dependencies: + spdx-expression-parse: 3.0.1 + spdx-license-ids: 3.0.24 + + spdx-exceptions@2.5.0: {} + + spdx-expression-parse@3.0.1: + dependencies: + spdx-exceptions: 2.5.0 + spdx-license-ids: 3.0.24 + + spdx-license-ids@3.0.24: {} + + split-lines@3.0.0: {} + split2@4.2.0: {} sprintf-js@1.0.3: {} @@ -5366,6 +8875,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + standard-as-callback@2.1.0: {} + statuses@2.0.1: {} statuses@2.0.2: {} @@ -5384,10 +8895,19 @@ snapshots: emoji-regex: 9.2.2 strip-ansi: 7.2.0 + string-width@8.3.0: + dependencies: + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + string_decoder@1.3.0: dependencies: safe-buffer: 5.2.1 + stringify-attributes@4.0.0: + dependencies: + escape-goat: 4.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 @@ -5400,6 +8920,14 @@ snapshots: strip-combining-marks@1.0.0: {} + strip-final-newline@4.0.0: {} + + strip-json-comments@5.0.3: {} + + strtok3@10.4.0: + dependencies: + '@tokenizer/token': 0.3.0 + supertap@3.0.1: dependencies: indent-string: 5.0.0 @@ -5407,20 +8935,40 @@ snapshots: serialize-error: 7.0.1 strip-ansi: 7.2.0 + supports-color@10.2.2: {} + + supports-color@7.2.0: + dependencies: + has-flag: 4.0.0 + + supports-preserve-symlinks-flag@1.0.0: {} + + tagged-tag@1.0.0: {} + tailwindcss@4.3.3: {} tapable@2.3.3: {} + tarn@3.1.2: {} + temp-dir@3.0.0: {} + tempura@0.4.1: {} + + terminal-size@4.0.1: {} + thread-stream@3.2.0: dependencies: real-require: 0.2.0 - threads@1.7.0: + thread-stream@4.2.0: + dependencies: + real-require: 1.0.0 + + threads@1.7.0(supports-color@10.2.2): dependencies: callsites: 3.1.0 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) is-observable: 2.1.0 observable-fns: 0.6.1 optionalDependencies: @@ -5428,13 +8976,19 @@ snapshots: transitivePeerDependencies: - supports-color + tildify@2.0.0: {} + time-zone@1.0.0: {} + timekeeper@2.3.1: {} + tiny-worker@2.3.0: dependencies: esm: 3.2.25 optional: true + tinyexec@1.3.1: {} + tinyglobby@0.2.17: dependencies: fdir: 6.5.0(picomatch@4.0.5) @@ -5444,6 +8998,8 @@ snapshots: tlds@1.261.0: {} + tmp-cache@1.1.0: {} + tmp@0.2.5: {} to-buffer@1.2.2: @@ -5460,12 +9016,23 @@ snapshots: toidentifier@1.0.1: {} + token-types@6.1.2: + dependencies: + '@borewit/text-codec': 0.2.2 + '@tokenizer/token': 0.3.0 + ieee754: 1.2.1 + ts-essentials@10.2.1(typescript@7.0.2): optionalDependencies: typescript: 7.0.2 ts-mixer@6.0.4: {} + ts-morph@28.0.0: + dependencies: + '@ts-morph/common': 0.29.0 + code-block-writer: 13.0.3 + ts-toolbelt@9.6.0: {} tsconfig-paths@3.15.0: @@ -5477,6 +9044,8 @@ snapshots: tslib@2.8.1: {} + tsscmp@1.0.6: {} + twemoji-parser@12.1.3: {} twemoji@12.1.6: @@ -5488,11 +9057,23 @@ snapshots: type-fest@0.13.1: {} + type-fest@4.41.0: {} + + type-fest@5.10.0: + dependencies: + tagged-tag: 1.0.0 + type-is@1.6.18: dependencies: media-typer: 0.3.0 mime-types: 2.1.35 + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + typed-array-buffer@1.0.3: dependencies: call-bound: 1.0.4 @@ -5501,14 +9082,14 @@ snapshots: typedarray@0.0.6: {} - typeorm@0.3.31(mysql2@3.23.0(@types/node@24.13.3))(redis@5.12.1): + typeorm@0.3.31(mysql2@3.23.0(@types/node@24.13.3))(redis@5.12.1)(supports-color@10.2.2): dependencies: '@sqltools/formatter': 1.2.5 ansis: 4.3.1 app-root-path: 3.1.0 buffer: 6.0.3 dayjs: 1.11.21 - debug: 4.4.3 + debug: 4.4.3(supports-color@10.2.2) dedent: 1.7.2 dotenv: 16.6.1 glob: 10.5.0 @@ -5550,14 +9131,26 @@ snapshots: '@typescript/typescript-win32-arm64': 7.0.2 '@typescript/typescript-win32-x64': 7.0.2 + uid-safe@2.1.5: + dependencies: + random-bytes: 1.0.0 + uid2@0.0.4: {} + uint8array-extras@1.6.0: {} + undici-types@7.18.2: {} + undici-types@8.9.0: {} + undici@6.21.3: {} undici@6.27.0: {} + unicorn-magic@0.3.0: {} + + unicorn-magic@0.4.1: {} + universalify@0.1.2: {} unpipe@1.0.0: {} @@ -5574,6 +9167,13 @@ snapshots: uuid@9.0.1: {} + validate-npm-package-license@3.0.4: + dependencies: + spdx-correct: 3.2.0 + spdx-expression-parse: 3.0.1 + + validator@13.15.35: {} + vary@1.1.2: {} vety@1.0.0-rc2(bufferutil@4.1.0)(typescript@7.0.2)(utf-8-validate@5.0.10): @@ -5600,6 +9200,19 @@ snapshots: jiti: 2.7.0 yaml: 2.9.0 + vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.29 + rolldown: 1.2.13 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 26.6.5 + fsevents: 2.3.3 + jiti: 2.7.0 + yaml: 2.9.0 + vscode-jsonrpc@9.0.1: {} vscode-languageserver-protocol@3.18.2: @@ -5620,6 +9233,14 @@ snapshots: '@vue/devtools-api': 6.6.4 vue: 3.5.40(typescript@6.0.3) + vue-sonner@2.0.9: {} + + vue-tsc@3.3.13(typescript@6.0.3): + dependencies: + '@volar/typescript': 2.4.28(typescript@6.0.3) + '@vue/language-core': 3.3.13 + typescript: 6.0.3 + vue-tsc@3.3.7(typescript@6.0.3): dependencies: '@volar/typescript': 2.4.28(typescript@6.0.3) @@ -5647,6 +9268,16 @@ snapshots: optionalDependencies: typescript: 6.0.3 + vue@3.5.43(typescript@6.0.3): + dependencies: + '@vue/compiler-dom': 3.5.43 + '@vue/compiler-sfc': 3.5.43 + '@vue/runtime-dom': 3.5.43 + '@vue/server-renderer': 3.5.43 + '@vue/shared': 3.5.43 + optionalDependencies: + typescript: 6.0.3 + vuex@4.1.0(vue@3.5.40(typescript@6.0.3)): dependencies: '@vue/devtools-api': 6.6.4 @@ -5668,6 +9299,11 @@ snapshots: dependencies: isexe: 2.0.0 + wrap-ansi@10.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 8.3.0 + wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -5680,6 +9316,8 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.2.0 + wrappy@1.0.2: {} + write-file-atomic@5.0.1: dependencies: imurmurhash: 0.1.4 @@ -5690,12 +9328,19 @@ snapshots: bufferutil: 4.1.0 utf-8-validate: 5.0.10 + wsl-utils@1.0.1: + dependencies: + is-wsl: 3.1.1 + powershell-utils: 0.2.1 + y18n@5.0.8: {} yaml@2.9.0: {} yargs-parser@21.1.1: {} + yargs-parser@22.0.0: {} + yargs@17.7.3: dependencies: cliui: 8.0.1 @@ -5708,4 +9353,19 @@ snapshots: yocto-queue@1.2.2: {} + yoctocolors@2.2.0: {} + + youch-core@0.3.3: + dependencies: + '@poppinss/exception': 1.2.3 + error-stack-parser-es: 1.0.5 + + youch@4.1.1: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.7.0 + '@speed-highlight/core': 1.2.24 + cookie-es: 3.1.1 + youch-core: 0.3.3 + zod@4.4.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index c277ca243..4f88b2811 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -6,13 +6,16 @@ packages: - 'shared' - 'dashboard' - 'config-checker' + - 'portal' allowBuilds: + '@swc/core': true bufferutil: true esbuild: true utf-8-validate: true minimumReleaseAge: 20160 # in minutes (2 weeks) +minimumReleaseAgeIgnoreMissingTime: false minimumReleaseAgeExclude: - 'vety' - 'knub-command-manager' diff --git a/portal/.adonisjs/client/data.d.ts b/portal/.adonisjs/client/data.d.ts new file mode 100644 index 000000000..5cafc4b8a --- /dev/null +++ b/portal/.adonisjs/client/data.d.ts @@ -0,0 +1,21 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + +/// +import type { InferData, InferVariants } from '@adonisjs/core/types/transformers' +import type { InferSharedProps, InferFlashData } from '@adonisjs/inertia/types' +import type PortalUsersPortalUserTransformer from '#backend/features/portalUsers/transformers/PortalUserTransformer' +import type InertiaMiddleware from '#backend/middleware/inertiaMiddleware' + +export namespace Data { + export namespace PortalUsers { + export type PortalUser = InferData + export namespace PortalUser { + export type Variants = InferVariants + } + } + export type SharedProps = InferSharedProps + export type FlashMessages = InferFlashData +} diff --git a/portal/.adonisjs/client/manifest.d.ts b/portal/.adonisjs/client/manifest.d.ts new file mode 100644 index 000000000..d3db53431 --- /dev/null +++ b/portal/.adonisjs/client/manifest.d.ts @@ -0,0 +1,10 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + +/// +/// +/// +/// +/// diff --git a/portal/.adonisjs/client/registry/index.ts b/portal/.adonisjs/client/registry/index.ts new file mode 100644 index 000000000..184eda5ad --- /dev/null +++ b/portal/.adonisjs/client/registry/index.ts @@ -0,0 +1,29 @@ +/* eslint-disable prettier/prettier */ +import type { AdonisEndpoint } from '@tuyau/core/types' +import type { Registry } from './schema.d.ts' +import type { ApiDefinition } from './tree.d.ts' + +const placeholder: any = {} + +const routes = { + 'splash.get_index': { + methods: ["GET","HEAD"], + pattern: '/', + tokens: [{"old":"/","type":0,"val":"/","end":""}], + types: placeholder as Registry['splash.get_index']['types'], + }, +} as const satisfies Record + +export { routes } + +export const registry = { + routes, + $tree: {} as ApiDefinition, +} + +declare module '@tuyau/core/types' { + export interface UserRegistry { + routes: typeof routes + $tree: ApiDefinition + } +} diff --git a/portal/.adonisjs/client/registry/schema.d.ts b/portal/.adonisjs/client/registry/schema.d.ts new file mode 100644 index 000000000..a85956444 --- /dev/null +++ b/portal/.adonisjs/client/registry/schema.d.ts @@ -0,0 +1,22 @@ +/* eslint-disable prettier/prettier */ +/// + +import type { ExtractBody, ExtractErrorResponse, ExtractQuery, ExtractQueryForGet, ExtractResponse } from '@tuyau/core/types' +import type { InferInput, SimpleError } from '@vinejs/vine/types' + +export type ParamValue = string | number | bigint | boolean + +export interface Registry { + 'splash.get_index': { + methods: ["GET","HEAD"] + pattern: '/' + types: { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ExtractResponse>> + errorResponse: ExtractErrorResponse>> + } + } +} diff --git a/portal/.adonisjs/client/registry/tree.d.ts b/portal/.adonisjs/client/registry/tree.d.ts new file mode 100644 index 000000000..742080652 --- /dev/null +++ b/portal/.adonisjs/client/registry/tree.d.ts @@ -0,0 +1,8 @@ +/* eslint-disable prettier/prettier */ +import type { routes } from './index.ts' + +export interface ApiDefinition { + splash: { + getIndex: typeof routes['splash.get_index'] + } +} diff --git a/portal/.adonisjs/server/controllers.ts b/portal/.adonisjs/server/controllers.ts new file mode 100644 index 000000000..c135649bc --- /dev/null +++ b/portal/.adonisjs/server/controllers.ts @@ -0,0 +1,10 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + +export const controllers = { + splash: { + Splash: () => import('#backend/features/splash/controllers/SplashController'), + }, +} diff --git a/portal/.adonisjs/server/events.ts b/portal/.adonisjs/server/events.ts new file mode 100644 index 000000000..a74e59b65 --- /dev/null +++ b/portal/.adonisjs/server/events.ts @@ -0,0 +1,6 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + +export const events = {} diff --git a/portal/.adonisjs/server/listeners.ts b/portal/.adonisjs/server/listeners.ts new file mode 100644 index 000000000..05f35f86d --- /dev/null +++ b/portal/.adonisjs/server/listeners.ts @@ -0,0 +1,6 @@ +/** + * This file is automatically generated. + * DO NOT EDIT manually + */ + +export const listeners = {} diff --git a/portal/.adonisjs/server/pages.d.ts b/portal/.adonisjs/server/pages.d.ts new file mode 100644 index 000000000..9555263fc --- /dev/null +++ b/portal/.adonisjs/server/pages.d.ts @@ -0,0 +1,29 @@ +import '@adonisjs/inertia/types' + + + import type { + VNodeProps, + AllowedComponentProps, + ComponentInstance + } from 'vue' + + type ExtractProps = Omit< + ComponentInstance['$props'], + keyof VNodeProps | keyof AllowedComponentProps + > + + +declare module '@adonisjs/inertia/types' { + + export interface InertiaPages { + + 'features/errors/pages/NotFound': ExtractProps<(typeof import('../../inertia/features/errors/pages/NotFound.vue'))['default']> + + 'features/errors/pages/ServerError': ExtractProps<(typeof import('../../inertia/features/errors/pages/ServerError.vue'))['default']> + + 'features/splash/pages/SplashIndex': ExtractProps<(typeof import('../../inertia/features/splash/pages/SplashIndex.vue'))['default']> + + } + +} + diff --git a/portal/.adonisjs/server/routes.d.ts b/portal/.adonisjs/server/routes.d.ts new file mode 100644 index 000000000..fc464179c --- /dev/null +++ b/portal/.adonisjs/server/routes.d.ts @@ -0,0 +1,18 @@ +import '@adonisjs/core/types/http' + +type ParamValue = string | number | bigint | boolean + +export type ScannedRoutes = { + ALL: { + 'splash.get_index': { paramsTuple?: []; params?: {} } + } + GET: { + 'splash.get_index': { paramsTuple?: []; params?: {} } + } + HEAD: { + 'splash.get_index': { paramsTuple?: []; params?: {} } + } +} +declare module '@adonisjs/core/types/http' { + export interface RoutesList extends ScannedRoutes {} +} \ No newline at end of file diff --git a/portal/.env.example b/portal/.env.example new file mode 100644 index 000000000..acb8eb393 --- /dev/null +++ b/portal/.env.example @@ -0,0 +1,4 @@ +HOST=0.0.0.0 +PORT=3003 +SESSION_DRIVER=redis +LOG_LEVEL=debug diff --git a/portal/.env.test b/portal/.env.test new file mode 100644 index 000000000..28d2da02d --- /dev/null +++ b/portal/.env.test @@ -0,0 +1 @@ +SESSION_DRIVER=memory diff --git a/portal/.gitignore b/portal/.gitignore new file mode 100644 index 000000000..5870e82d6 --- /dev/null +++ b/portal/.gitignore @@ -0,0 +1,7 @@ +# Dependencies and AdonisJS build +build +tmp/* +!tmp/.gitkeep + +# Frontend assets compiled code +public/assets diff --git a/portal/ace.js b/portal/ace.js new file mode 100644 index 000000000..0eefd202f --- /dev/null +++ b/portal/ace.js @@ -0,0 +1,27 @@ +/* +|-------------------------------------------------------------------------- +| JavaScript entrypoint for running ace commands +|-------------------------------------------------------------------------- +| +| DO NOT MODIFY THIS FILE AS IT WILL BE OVERRIDDEN DURING THE BUILD +| PROCESS. +| +| See docs.adonisjs.com/guides/typescript-build-process#creating-production-build +| +| Since, we cannot run TypeScript source code using "node" binary, we need +| a JavaScript entrypoint to run ace commands. +| +| This file registers the "ts-node/esm" hook with the Node.js module system +| and then imports the "bin/console.ts" file. +| +*/ + +/** + * Register hook to process TypeScript files using @poppinss/ts-exec + */ +import '@poppinss/ts-exec' + +/** + * Import ace console entrypoint + */ +await import('./bin/console.js') diff --git a/portal/adonisrc.ts b/portal/adonisrc.ts new file mode 100644 index 000000000..7c742c8f6 --- /dev/null +++ b/portal/adonisrc.ts @@ -0,0 +1,169 @@ +import { indexEntities } from '@adonisjs/core/generators' +import { defineConfig } from '@adonisjs/core/app' +import { generateRegistry } from '@tuyau/core/hooks' + +export default defineConfig({ + /* + |-------------------------------------------------------------------------- + | Experimental flags + |-------------------------------------------------------------------------- + | + | The following features will be enabled by default in the next major release + | of AdonisJS. You can opt into them today to avoid any breaking changes + | during upgrade. + | + */ + experimental: {}, + + /* + |-------------------------------------------------------------------------- + | Commands + |-------------------------------------------------------------------------- + | + | List of ace commands to register from packages. The application commands + | will be scanned automatically from the "./commands" directory. + | + */ + commands: [ + () => import('@adonisjs/core/commands'), + () => import('@adonisjs/lucid/commands'), + () => import('@adonisjs/session/commands'), + () => import('@adonisjs/inertia/commands'), + ], + + /* + |-------------------------------------------------------------------------- + | Service providers + |-------------------------------------------------------------------------- + | + | List of service providers to import and register when booting the + | application + | + */ + providers: [ + () => import('@adonisjs/core/providers/app_provider'), + () => import('@adonisjs/core/providers/hash_provider'), + { + file: () => import('@adonisjs/core/providers/repl_provider'), + environment: ['repl', 'test'], + }, + () => import('@adonisjs/core/providers/vinejs_provider'), + () => import('@adonisjs/core/providers/edge_provider'), + () => import('@adonisjs/session/session_provider'), + () => import('@adonisjs/vite/vite_provider'), + () => import('@adonisjs/shield/shield_provider'), + () => import('@adonisjs/static/static_provider'), + () => import('@adonisjs/lucid/database_provider'), + () => import('@adonisjs/cors/cors_provider'), + () => import('@adonisjs/inertia/inertia_provider'), + () => import('@adonisjs/auth/auth_provider'), + () => import('@adonisjs/redis/redis_provider'), + () => import('#providers/apiProvider'), + ], + + /* + |-------------------------------------------------------------------------- + | Preloads + |-------------------------------------------------------------------------- + | + | List of modules to import before starting the application. + | + */ + preloads: [ + () => import('#start/routes'), + () => import('#start/kernel'), + () => import('#start/validator'), + ], + + /* + |-------------------------------------------------------------------------- + | Tests + |-------------------------------------------------------------------------- + | + | List of test suites to organize tests by their type. Feel free to remove + | and add additional suites. + | + */ + tests: { + suites: [ + { + files: ['tests/unit/**/*.spec.{ts,js}'], + name: 'unit', + timeout: 2000, + }, + { + files: ['tests/functional/**/*.spec.{ts,js}'], + name: 'functional', + timeout: 30000, + }, + { + files: ['tests/browser/**/*.spec.{ts,js}'], + name: 'browser', + timeout: 300000, + }, + ], + forceExit: false, + }, + + /* + |-------------------------------------------------------------------------- + | Metafiles + |-------------------------------------------------------------------------- + | + | A collection of files you want to copy to the build folder when creating + | the production build. + | + */ + metaFiles: [ + { + pattern: 'resources/views/**/*.edge', + reloadServer: false, + }, + { + pattern: 'public/**', + reloadServer: false, + }, + ], + + hooks: { + init: [ + indexEntities({ + controllers: { + source: "app", + importAlias: "#backend", + glob: ["**/controllers/*.ts"], + skipSegments: ["features", "controllers"], + }, + + events: { + source: "app", + importAlias: "#backend", + glob: ["**/events/*.ts"], + skipSegments: ["features", "events"], + }, + + listeners: { + source: "app", + importAlias: "#backend", + glob: ["**/listeners/*.ts"], + skipSegments: ["features", "listeners"], + }, + + transformers: { + enabled: true, + withSharedProps: true, + source: "app", + importAlias: "#backend", + glob: ["**/transformers/*.ts"], + skipSegments: ["features", "transformers"], + inertiaMiddlewareImportPath: "#backend/middleware/inertiaMiddleware", + }, + }), + + () => import("./hooks/indexInertiaPages.ts"), + + generateRegistry(), + ], + buildStarting: [() => import('@adonisjs/vite/build_hook')], + }, +}) diff --git a/portal/app/exceptions/handler.ts b/portal/app/exceptions/handler.ts new file mode 100644 index 000000000..0c7cb2256 --- /dev/null +++ b/portal/app/exceptions/handler.ts @@ -0,0 +1,45 @@ +import app from '@adonisjs/core/services/app' +import { type HttpContext, ExceptionHandler } from '@adonisjs/core/http' +import type { StatusPageRange, StatusPageRenderer } from '@adonisjs/core/types/http' + +export default class HttpExceptionHandler extends ExceptionHandler { + /** + * In debug mode, the exception handler will display verbose errors + * with pretty printed stack traces. + */ + protected debug = !app.inProduction + + /** + * Status pages are used to display a custom HTML pages for certain error + * codes. You might want to enable them in production only, but feel + * free to enable them in development as well. + */ + protected renderStatusPages = app.inProduction + + /** + * Status pages is a collection of error code range and a callback + * to return the HTML contents to send as a response. + */ + protected statusPages: Record = { + '404': (_, { inertia }) => inertia.render('features/errors/pages/NotFound', {}), + '500..599': (_, { inertia }) => inertia.render('features/errors/pages/ServerError', {}), + } + + /** + * The method is used for handling errors and returning + * response to the client + */ + async handle(error: unknown, ctx: HttpContext) { + return super.handle(error, ctx) + } + + /** + * The method is used to report error to the logging service or + * the a third party error monitoring service. + * + * @note You should not attempt to send a response from this method. + */ + async report(error: unknown, ctx: HttpContext) { + return super.report(error, ctx) + } +} diff --git a/portal/app/features/portalUsers/models/PortalUser.ts b/portal/app/features/portalUsers/models/PortalUser.ts new file mode 100644 index 000000000..f218e4e5e --- /dev/null +++ b/portal/app/features/portalUsers/models/PortalUser.ts @@ -0,0 +1,22 @@ +import { BaseModel, column } from "@adonisjs/lucid/orm"; + +export class PortalUser extends BaseModel { + static table = "portal_users"; + + @column({ isPrimary: true }) + declare id: number; + + @column() + declare user_id: number; + + @column() + declare username: string; + + @column() + declare avatar: string; + + @column() + declare created_at: string; +} + +export default PortalUser diff --git a/portal/app/features/portalUsers/transformers/PortalUserTransformer.ts b/portal/app/features/portalUsers/transformers/PortalUserTransformer.ts new file mode 100644 index 000000000..5856203a1 --- /dev/null +++ b/portal/app/features/portalUsers/transformers/PortalUserTransformer.ts @@ -0,0 +1,14 @@ +import type { PortalUser } from '#backend/features/portalUsers/models/PortalUser' +import { BaseTransformer } from '@adonisjs/core/transformers' + +export class PortalUserTransformer extends BaseTransformer { + toObject() { + return this.pick(this.resource, [ + "user_id", + "username", + "avatar", + ]) + } +} + +export default PortalUserTransformer diff --git a/portal/app/features/splash/controllers/SplashController.ts b/portal/app/features/splash/controllers/SplashController.ts new file mode 100644 index 000000000..d9ea912a9 --- /dev/null +++ b/portal/app/features/splash/controllers/SplashController.ts @@ -0,0 +1,7 @@ +import type { HttpContext } from '@adonisjs/core/http' + +export default class SplashController { + async getIndex({ inertia }: HttpContext) { + return inertia.render("features/splash/pages/SplashIndex", { example: "hi" }); + } +} diff --git a/portal/app/middleware/authMiddleware.ts b/portal/app/middleware/authMiddleware.ts new file mode 100644 index 000000000..79904069d --- /dev/null +++ b/portal/app/middleware/authMiddleware.ts @@ -0,0 +1,16 @@ +import type { HttpContext } from '@adonisjs/core/http' +import type { NextFn } from '@adonisjs/core/types/http' +import type { Authenticators } from '@adonisjs/auth/types' + +export default class AuthMiddleware { + redirectTo = '/login' + + async handle( + ctx: HttpContext, + next: NextFn, + options: { guards?: (keyof Authenticators)[] } = {} + ) { + await ctx.auth.authenticateUsing(options.guards, { loginRoute: this.redirectTo }) + return next() + } +} diff --git a/portal/app/middleware/containerBindingsMiddleware.ts b/portal/app/middleware/containerBindingsMiddleware.ts new file mode 100644 index 000000000..8f5322b4d --- /dev/null +++ b/portal/app/middleware/containerBindingsMiddleware.ts @@ -0,0 +1,19 @@ +import { Logger } from '@adonisjs/core/logger' +import { HttpContext } from '@adonisjs/core/http' +import { type NextFn } from '@adonisjs/core/types/http' + +/** + * The container bindings middleware binds classes to their request + * specific value using the container resolver. + * + * - We bind "HttpContext" class to the "ctx" object + * - And bind "Logger" class to the "ctx.logger" object + */ +export default class ContainerBindingsMiddleware { + handle(ctx: HttpContext, next: NextFn) { + ctx.containerResolver.bindValue(HttpContext, ctx) + ctx.containerResolver.bindValue(Logger, ctx.logger) + + return next() + } +} diff --git a/portal/app/middleware/guestMiddleware.ts b/portal/app/middleware/guestMiddleware.ts new file mode 100644 index 000000000..787d00d03 --- /dev/null +++ b/portal/app/middleware/guestMiddleware.ts @@ -0,0 +1,32 @@ +import type { HttpContext } from '@adonisjs/core/http' +import type { NextFn } from '@adonisjs/core/types/http' +import type { Authenticators } from '@adonisjs/auth/types' + +/** + * Guest middleware is used to deny access to routes that should + * be accessed by unauthenticated users. + * + * For example, the login page should not be accessible if the user + * is already logged-in + */ +export default class GuestMiddleware { + /** + * The URL to redirect to when user is logged-in + */ + redirectTo = '/' + + async handle( + ctx: HttpContext, + next: NextFn, + options: { guards?: (keyof Authenticators)[] } = {} + ) { + for (let guard of options.guards || [ctx.auth.defaultGuard]) { + if (await ctx.auth.use(guard).check()) { + ctx.session.reflash() + return ctx.response.redirect(this.redirectTo, true) + } + } + + return next() + } +} diff --git a/portal/app/middleware/inertiaMiddleware.ts b/portal/app/middleware/inertiaMiddleware.ts new file mode 100644 index 000000000..5cc3a9a80 --- /dev/null +++ b/portal/app/middleware/inertiaMiddleware.ts @@ -0,0 +1,62 @@ +import type { HttpContext } from '@adonisjs/core/http' +import type { NextFn } from '@adonisjs/core/types/http' +import BaseInertiaMiddleware from '@adonisjs/inertia/inertia_middleware' +import { PortalUserTransformer } from '#backend/features/portalUsers/transformers/PortalUserTransformer' + +export default class InertiaMiddleware extends BaseInertiaMiddleware { + share(ctx: HttpContext) { + /** + * The share method is called everytime an Inertia page is rendered. In + * certain cases, a page may get rendered before the session middleware + * or the auth middleware are executed. For example: During a 404 request. + * + * In that case, we must always assume that HttpContext is not fully hydrated + * with all the properties + */ + const { auth, request } = ctx as Partial + + const theme: 'light' | 'dark' = + request?.plainCookie('app_theme', { + defaultValue: 'light', + encoded: false, + }) ?? 'light' + + /** + * Data shared with all Inertia pages. Make sure you are using + * transformers for rich data-types like Models. + */ + return { + errors: ctx.inertia.always(this.getValidationErrors(ctx)), + user: ctx.inertia.always(auth?.user ? PortalUserTransformer.transform(auth.user) : undefined), + preferences: ctx.inertia.always({ theme }), + } + } + + flash(ctx: HttpContext) { + /** + * Flash messages travel in the dedicated `flash` field of the page + * object instead of props, and the client strips them from history + * state so they never reappear when navigating back. + */ + const { session } = ctx as Partial + + const success: string | undefined = session?.flashMessages.get('success') + const error: string | undefined = session?.flashMessages.get('error') + + return { success, error } + } + + async handle(ctx: HttpContext, next: NextFn) { + await this.init(ctx) + + const output = await next() + this.dispose(ctx) + + return output + } +} + +declare module '@adonisjs/inertia/types' { + type MiddlewareSharedProps = InferSharedProps + export interface SharedProps extends MiddlewareSharedProps {} +} diff --git a/portal/app/middleware/silentAuthMiddleware.ts b/portal/app/middleware/silentAuthMiddleware.ts new file mode 100644 index 000000000..3e46f4090 --- /dev/null +++ b/portal/app/middleware/silentAuthMiddleware.ts @@ -0,0 +1,16 @@ +import type { HttpContext } from '@adonisjs/core/http' +import type { NextFn } from '@adonisjs/core/types/http' + +/** + * Silent auth middleware can be used as a global middleware to silent check + * if the user is logged-in or not. + * + * The request continues as usual, even when the user is not logged-in. + */ +export default class SilentAuthMiddleware { + async handle(ctx: HttpContext, next: NextFn) { + await ctx.auth.check() + + return next() + } +} diff --git a/portal/bin/console.ts b/portal/bin/console.ts new file mode 100644 index 000000000..23f042f3b --- /dev/null +++ b/portal/bin/console.ts @@ -0,0 +1,47 @@ +/* +|-------------------------------------------------------------------------- +| Ace entry point +|-------------------------------------------------------------------------- +| +| The "console.ts" file is the entrypoint for booting the AdonisJS +| command-line framework and executing commands. +| +| Commands do not boot the application, unless the currently running command +| has "options.startApp" flag set to true. +| +*/ + +await import('reflect-metadata') +const { Ignitor, prettyPrintError } = await import('@adonisjs/core/ignitor') + +/** + * URL to the application root. AdonisJS need it to resolve + * paths to file and directories for scaffolding commands + */ +const APP_ROOT = new URL('../', import.meta.url) + +/** + * The importer is used to import files in context of the + * application. + */ +const IMPORTER = (filePath: string) => { + if (filePath.startsWith('./') || filePath.startsWith('../')) { + return import(new URL(filePath, APP_ROOT).href) + } + return import(filePath) +} + +new Ignitor(APP_ROOT, { importer: IMPORTER }) + .tap((app) => { + app.booting(async () => { + await import('#start/env') + }) + app.listen('SIGTERM', () => app.terminate()) + app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate()) + }) + .ace() + .handle(process.argv.splice(2)) + .catch((error) => { + process.exitCode = 1 + prettyPrintError(error) + }) diff --git a/portal/bin/server.ts b/portal/bin/server.ts new file mode 100644 index 000000000..0556b1ddc --- /dev/null +++ b/portal/bin/server.ts @@ -0,0 +1,45 @@ +/* +|-------------------------------------------------------------------------- +| HTTP server entrypoint +|-------------------------------------------------------------------------- +| +| The "server.ts" file is the entrypoint for starting the AdonisJS HTTP +| server. Either you can run this file directly or use the "serve" +| command to run this file and monitor file changes +| +*/ + +await import('reflect-metadata') +const { Ignitor, prettyPrintError } = await import('@adonisjs/core/ignitor') + +/** + * URL to the application root. AdonisJS need it to resolve + * paths to file and directories for scaffolding commands + */ +const APP_ROOT = new URL('../', import.meta.url) + +/** + * The importer is used to import files in context of the + * application. + */ +const IMPORTER = (filePath: string) => { + if (filePath.startsWith('./') || filePath.startsWith('../')) { + return import(new URL(filePath, APP_ROOT).href) + } + return import(filePath) +} + +new Ignitor(APP_ROOT, { importer: IMPORTER }) + .tap((app) => { + app.booting(async () => { + await import('#start/env') + }) + app.listen('SIGTERM', () => app.terminate()) + app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate()) + }) + .httpServer() + .start() + .catch((error) => { + process.exitCode = 1 + prettyPrintError(error) + }) diff --git a/portal/bin/test.ts b/portal/bin/test.ts new file mode 100644 index 000000000..3b82dd68f --- /dev/null +++ b/portal/bin/test.ts @@ -0,0 +1,62 @@ +/* +|-------------------------------------------------------------------------- +| Test runner entrypoint +|-------------------------------------------------------------------------- +| +| The "test.ts" file is the entrypoint for running tests using Japa. +| +| Either you can run this file directly or use the "test" +| command to run this file and monitor file changes. +| +*/ + +process.env.NODE_ENV = 'test' + +import 'reflect-metadata' +import { Ignitor, prettyPrintError } from '@adonisjs/core/ignitor' +import { configure, processCLIArgs, run } from '@japa/runner' + +/** + * URL to the application root. AdonisJS need it to resolve + * paths to file and directories for scaffolding commands + */ +const APP_ROOT = new URL('../', import.meta.url) + +/** + * The importer is used to import files in context of the + * application. + */ +const IMPORTER = (filePath: string) => { + if (filePath.startsWith('./') || filePath.startsWith('../')) { + return import(new URL(filePath, APP_ROOT).href) + } + return import(filePath) +} + +new Ignitor(APP_ROOT, { importer: IMPORTER }) + .tap((app) => { + app.booting(async () => { + await import('#start/env') + }) + app.listen('SIGTERM', () => app.terminate()) + app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate()) + }) + .testRunner() + .configure(async (app) => { + const { runnerHooks, ...config } = await import('../tests/bootstrap.js') + + processCLIArgs(process.argv.splice(2)) + configure({ + ...app.rcFile.tests, + ...config, + ...{ + setup: runnerHooks.setup, + teardown: runnerHooks.teardown.concat([() => app.terminate()]), + }, + }) + }) + .run(() => run()) + .catch((error) => { + process.exitCode = 1 + prettyPrintError(error) + }) diff --git a/portal/config/app.ts b/portal/config/app.ts new file mode 100644 index 000000000..4d1880276 --- /dev/null +++ b/portal/config/app.ts @@ -0,0 +1,80 @@ +import app from '@adonisjs/core/services/app' +import { defineConfig } from '@adonisjs/core/http' + +/** + * The configuration settings used by the HTTP server + */ +export const http = defineConfig({ + /** + * Generate a unique request id for each incoming request. + * Useful to correlate logs and debug a request flow. + */ + generateRequestId: true, + + /** + * Allow HTTP method spoofing via the "_method" form/query parameter. + * This lets HTML forms target PUT/PATCH/DELETE routes while still + * submitting with POST. + */ + allowMethodSpoofing: false, + + /** + * Enabling async local storage will let you access HTTP context + * from anywhere inside your application. + */ + useAsyncLocalStorage: false, + + router: { + matcher: 'tree', + }, + + /** + * Redirect configuration controls the behavior of + * response.redirect().back() and query string forwarding. + */ + redirect: { + /** + * When enabled, all redirects automatically carry over the current + * request's query string parameters to the redirect destination. + * Use withQs(false) to opt out for a specific redirect. + */ + forwardQueryString: true, + }, + + /** + * Manage cookies configuration. The settings for the session id cookie are + * defined inside the "config/session.ts" file. + */ + cookie: { + /** + * Restrict the cookie to a specific domain. + * Keep empty to use the current host. + */ + domain: '', + + /** + * Restrict the cookie to a URL path. '/' means all routes. + */ + path: '/', + + /** + * Default lifetime for cookies managed by the HTTP layer. + */ + maxAge: '2h', + + /** + * Prevent JavaScript access to the cookie in the browser. + */ + httpOnly: true, + + /** + * Send cookies only over HTTPS in production. + */ + secure: app.inProduction, + + /** + * Cross-site policy for cookie sending. + */ + sameSite: 'lax', + }, +}) diff --git a/portal/config/auth.ts b/portal/config/auth.ts new file mode 100644 index 000000000..4318ff6d7 --- /dev/null +++ b/portal/config/auth.ts @@ -0,0 +1,39 @@ +import { defineConfig } from '@adonisjs/auth' +import { sessionGuard, sessionUserProvider } from '@adonisjs/auth/session' +import type { InferAuthenticators, InferAuthEvents, Authenticators } from '@adonisjs/auth/types' + +const authConfig = defineConfig({ + /** + * Default guard used when no guard is explicitly specified. + */ + default: 'web', + + guards: { + /** + * Session-based guard for browser authentication. + */ + web: sessionGuard({ + /** + * Enable persistent login using remember-me tokens. + */ + useRememberMeTokens: false, + + provider: sessionUserProvider({ + model: () => import('#backend/features/portalUsers/models/PortalUser'), + }), + }), + }, +}) + +export default authConfig + +/** + * Inferring types from the configured auth + * guards. + */ +declare module '@adonisjs/auth/types' { + export interface Authenticators extends InferAuthenticators {} +} +declare module '@adonisjs/core/types' { + interface EventsList extends InferAuthEvents {} +} diff --git a/portal/config/bodyparser.ts b/portal/config/bodyparser.ts new file mode 100644 index 000000000..7e836e691 --- /dev/null +++ b/portal/config/bodyparser.ts @@ -0,0 +1,78 @@ +import { defineConfig } from '@adonisjs/core/bodyparser' + +const bodyParserConfig = defineConfig({ + /** + * Parse request bodies for these HTTP methods. + * Keep this aligned with methods that receive payloads in your routes. + */ + allowedMethods: ['POST', 'PUT', 'PATCH', 'DELETE'], + + /** + * Config for the "application/x-www-form-urlencoded" + * content-type parser. + */ + form: { + /** + * Normalize empty string values to null. + */ + convertEmptyStringsToNull: true, + + /** + * Content types handled by the form parser. + */ + types: ['application/x-www-form-urlencoded'], + }, + + /** + * Config for the JSON parser. + */ + json: { + /** + * Normalize empty string values to null. + */ + convertEmptyStringsToNull: true, + + /** + * Content types handled by the JSON parser. + */ + types: [ + 'application/json', + 'application/json-patch+json', + 'application/vnd.api+json', + 'application/csp-report', + ], + }, + + /** + * Config for the "multipart/form-data" content-type parser. + * File uploads are handled by the multipart parser. + */ + multipart: { + /** + * Automatically process uploaded files into the system tmp directory. + */ + autoProcess: true, + + /** + * Normalize empty string values to null. + */ + convertEmptyStringsToNull: true, + + /** + * Routes where multipart processing is handled manually. + */ + processManually: [], + + /** + * Maximum accepted payload size for multipart requests. + */ + limit: '20mb', + + /** + * Content types handled by the multipart parser. + */ + types: ['multipart/form-data'], + }, +}) + +export default bodyParserConfig diff --git a/portal/config/cors.ts b/portal/config/cors.ts new file mode 100644 index 000000000..c47fc66e7 --- /dev/null +++ b/portal/config/cors.ts @@ -0,0 +1,50 @@ +import app from '@adonisjs/core/services/app' +import { defineConfig } from '@adonisjs/cors' + +/** + * Configuration options to tweak the CORS policy. The following + * options are documented on the official documentation website. + * + * https://docs.adonisjs.com/guides/security/cors + */ +const corsConfig = defineConfig({ + /** + * Enable or disable CORS handling globally. + */ + enabled: true, + + /** + * In development, allow every origin to simplify local front/backend setup. + * In production, keep an explicit allowlist (empty by default, so no + * cross-origin browser access is allowed until configured). + */ + origin: app.inDev ? true : [], + + /** + * HTTP methods accepted for cross-origin requests. + */ + methods: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE'], + + /** + * Reflect request headers by default. Use a string array to restrict + * allowed headers. + */ + headers: true, + + /** + * Response headers exposed to the browser. + */ + exposeHeaders: [], + + /** + * Allow cookies/authorization headers on cross-origin requests. + */ + credentials: true, + + /** + * Cache CORS preflight response for N seconds. + */ + maxAge: 90, +}) + +export default corsConfig diff --git a/portal/config/database.ts b/portal/config/database.ts new file mode 100644 index 000000000..ffdea34ba --- /dev/null +++ b/portal/config/database.ts @@ -0,0 +1,44 @@ +import { rootEnv } from '#start/env' +import { defineConfig } from '@adonisjs/lucid' + +const dbConfig = defineConfig({ + /** + * Default connection used for all queries. + */ + connection: 'mysql', + + connections: { + mysql: { + client: 'mysql2', + + connection: { + host: rootEnv.get("DB_HOST", "mysql"), + port: rootEnv.get("DB_PORT", 3306), + user: rootEnv.get("DB_USER", "zeppelin"), + password: rootEnv.get("DB_PASSWORD", rootEnv.get("DEVELOPMENT_MYSQL_PASSWORD", "")), + database: rootEnv.get("DB_DATABASE", "zeppelin"), + timezone: "Z", + }, + + migrations: { + /** + * Sort migration files naturally by filename. + */ + naturalSort: true, + + /** + * Paths containing migration files. + */ + paths: ['database/migrations'], + }, + + schemaGeneration: { + enabled: true, + rulesPaths: ['./database/schemaRules.js'], + excludeTables: ["migrations"], + }, + }, + }, +}) + +export default dbConfig diff --git a/portal/config/encryption.ts b/portal/config/encryption.ts new file mode 100644 index 000000000..4e3c993b4 --- /dev/null +++ b/portal/config/encryption.ts @@ -0,0 +1,34 @@ +import { rootEnv } from '#start/env' +import { defineConfig, drivers } from '@adonisjs/core/encryption' + +const encryptionConfig = defineConfig({ + /** + * Default encryption driver used by the application. + */ + default: 'gcm', + + list: { + gcm: drivers.aes256gcm({ + /** + * Keys used for encryption/decryption. + * First key encrypts, all keys are tried for decryption. + */ + keys: [rootEnv.get('KEY')], + + /** + * Stable identifier for this driver. + */ + id: 'gcm', + }), + }, +}) + +export default encryptionConfig + +/** + * Inferring types for the list of encryptors you have configured + * in your application. + */ +declare module '@adonisjs/core/types' { + export interface EncryptorsList extends InferEncryptors {} +} diff --git a/portal/config/hash.ts b/portal/config/hash.ts new file mode 100644 index 000000000..a54c08675 --- /dev/null +++ b/portal/config/hash.ts @@ -0,0 +1,75 @@ +import { defineConfig, drivers } from '@adonisjs/core/hash' + +/** + * Hashing configuration. + * + * This starter uses Node.js scrypt under the hood. + * Node.js reference: https://nodejs.org/api/crypto.html#cryptoscryptpassword-salt-keylen-options-callback + */ +const hashConfig = defineConfig({ + /** + * Default hasher used by the application. + */ + default: 'scrypt', + + list: { + /** + * Scrypt is memory-hard, which makes brute-force attacks more expensive. + */ + scrypt: drivers.scrypt({ + /** + * Work factor (Node alias: N / cost). + * Higher values increase security and CPU+memory usage. + * + * Tuning guideline: + * - Start with 16384. + * - Increase gradually (for example 32768) and benchmark login/signup latency. + * - Keep values practical for your slowest production machine. + * + * Node constraint: value must be a power of two greater than 1. + */ + cost: 16384, + + /** + * Block size (Node alias: r / blockSize). + * Increases memory and CPU linearly. + * + * Tuning guideline: + * - Keep 8 unless you have a measured reason to change it. + * - Raise only with benchmark data, because memory usage grows quickly. + */ + blockSize: 8, + + /** + * Parallelization (Node alias: p / parallelization). + * Controls how many independent computations are performed. + * + * Tuning guideline: + * - Keep 1 for most applications. + * - Increase only after load testing if your infrastructure benefits from it. + */ + parallelization: 1, + + /** + * Maximum memory limit in bytes (Node alias: maxmem / maxMemory). + * Hashing throws if the estimated memory usage is above this limit. + * Node documents the check as approximately: 128 * N * r > maxmem. + * + * Tuning guideline: + * - Keep this aligned with your cost/blockSize choices. + * - Increase carefully on memory-constrained environments. + */ + maxMemory: 33554432, + }), + }, +}) + +export default hashConfig + +/** + * Inferring types for the list of hashers you have configured + * in your application. + */ +declare module '@adonisjs/core/types' { + export interface HashersList extends InferHashers {} +} diff --git a/portal/config/inertia.ts b/portal/config/inertia.ts new file mode 100644 index 000000000..0eaaf9921 --- /dev/null +++ b/portal/config/inertia.ts @@ -0,0 +1,20 @@ +import { defineConfig } from '@adonisjs/inertia' + +const inertiaConfig = defineConfig({ + /** + * Server-side rendering options. + */ + ssr: { + /** + * Toggle SSR mode for Inertia pages. + */ + enabled: false, + + /** + * Entry file used by the SSR server build. + */ + entrypoint: 'inertia/ssr.ts', + }, +}) + +export default inertiaConfig diff --git a/portal/config/logger.ts b/portal/config/logger.ts new file mode 100644 index 000000000..778302b6f --- /dev/null +++ b/portal/config/logger.ts @@ -0,0 +1,50 @@ +import { portalEnv } from '#start/env' +import app from '@adonisjs/core/services/app' +import { defineConfig, targets } from '@adonisjs/core/logger' + +const loggerConfig = defineConfig({ + /** + * Default logger name used by ctx.logger and app logger calls. + */ + default: 'app', + + loggers: { + app: { + /** + * Toggle this logger on/off. + */ + enabled: true, + + /** + * Logger name shown in log records. + */ + name: "zeppelin-portal", + + /** + * Minimum level to output (trace, debug, info, warn, error, fatal). + */ + level: portalEnv.get('LOG_LEVEL', "info"), + + /** + * Configure where logs are written. + * Pretty logs in development, stdout in production. + */ + transport: { + targets: targets() + .pushIf(!app.inProduction, targets.pretty()) + .pushIf(app.inProduction, targets.file({ destination: 1 })) + .toArray(), + }, + }, + }, +}) + +export default loggerConfig + +/** + * Inferring types for the list of loggers you have configured + * in your application. + */ +declare module '@adonisjs/core/types' { + export interface LoggersList extends InferLoggers {} +} diff --git a/portal/config/redis.ts b/portal/config/redis.ts new file mode 100644 index 000000000..331bf585c --- /dev/null +++ b/portal/config/redis.ts @@ -0,0 +1,28 @@ +import { rootEnv } from '#start/env' +import { defineConfig } from '@adonisjs/redis' +import type { InferConnections } from '@adonisjs/redis/types' + +const url = new URL(rootEnv.get("REDIS_URL", "redis://redis:6379")); + +const redisConfig = defineConfig({ + connection: 'main', + connections: { + main: { + host: url.hostname, + port: url.port ? Number(url.port) : 6379, + username: decodeURIComponent(url.username), + password: decodeURIComponent(url.password), + db: url.pathname !== '/' && url.pathname + ? Number(url.pathname.slice(1)) + : 0, + ...(url.protocol === 'rediss:' ? { tls: {} } : {}), + keyPrefix: "portal:", + }, + }, +}) + +export default redisConfig + +declare module '@adonisjs/redis/types' { + interface RedisConnections extends InferConnections {} +} diff --git a/portal/config/session.ts b/portal/config/session.ts new file mode 100644 index 000000000..ffd3f6f59 --- /dev/null +++ b/portal/config/session.ts @@ -0,0 +1,71 @@ +import { portalEnv } from '#start/env' +import { defineConfig, stores } from '@adonisjs/session' + +const sessionConfig = defineConfig({ + /** + * Enable or disable session support globally. + */ + enabled: true, + + /** + * Cookie name storing the session identifier. + */ + cookieName: 'portalSession', + + /** + * When set to true, the session id cookie will be deleted + * once the user closes the browser. + */ + clearWithBrowser: true, + + /** + * Define how long to keep the session data alive without + * any activity. + */ + age: '2h', + + /** + * Configuration for session cookie and the + * cookie store. + */ + cookie: { + /** + * Restrict the cookie to a URL path. '/' means all routes. + */ + path: '/', + + /** + * Prevent JavaScript access to the cookie in the browser. + */ + httpOnly: true, + + /** + * Send cookies only over HTTPS in production. + */ + secure: true, + + /** + * Cross-site policy for cookie sending. + */ + sameSite: 'strict', + }, + + /** + * The store to use. Make sure to validate the environment + * variable in order to infer the store name without any + * errors. + */ + store: portalEnv.get('SESSION_DRIVER', "redis"), + + /** + * List of configured stores. Refer documentation to see + * list of available stores and their config. + */ + stores: { + redis: stores.redis({ + connection: "main" + }), + }, +}) + +export default sessionConfig diff --git a/portal/config/shield.ts b/portal/config/shield.ts new file mode 100644 index 000000000..37067c673 --- /dev/null +++ b/portal/config/shield.ts @@ -0,0 +1,95 @@ +import { defineConfig } from '@adonisjs/shield' + +const shieldConfig = defineConfig({ + /** + * Configure CSP policies for your app. Refer documentation + * to learn more. + */ + csp: { + /** + * Enable the Content-Security-Policy header. + */ + enabled: false, + + /** + * Per-resource CSP directives. + */ + directives: {}, + + /** + * Report violations without blocking resources. + */ + reportOnly: false, + }, + + /** + * Configure CSRF protection options. Refer documentation + * to learn more. + */ + csrf: { + /** + * Enable CSRF token verification for state-changing requests. + */ + enabled: true, + + /** + * Route patterns to exclude from CSRF checks. + * Useful for external webhooks or API endpoints. + */ + exceptRoutes: [], + + /** + * Expose an encrypted XSRF-TOKEN cookie for frontend HTTP clients. + */ + enableXsrfCookie: true, + + /** + * HTTP methods protected by CSRF validation. + */ + methods: ['POST', 'PUT', 'PATCH', 'DELETE'], + }, + + /** + * Control how your website should be embedded inside + * iframes. + */ + xFrame: { + /** + * Enable the X-Frame-Options header. + */ + enabled: true, + + /** + * Block all framing attempts. Default value is DENY. + */ + action: 'DENY', + }, + + /** + * Force browser to always use HTTPS. + */ + hsts: { + /** + * Enable the Strict-Transport-Security header. + */ + enabled: true, + + /** + * HSTS policy duration remembered by browsers. + */ + maxAge: '180 days', + }, + + /** + * Disable browsers from sniffing content types and rely only + * on the response content-type header. + */ + contentTypeSniffing: { + /** + * Enable X-Content-Type-Options: nosniff. + */ + enabled: true, + }, +}) + +export default shieldConfig diff --git a/portal/config/static.ts b/portal/config/static.ts new file mode 100644 index 000000000..ad1e27d03 --- /dev/null +++ b/portal/config/static.ts @@ -0,0 +1,32 @@ +import { defineConfig } from '@adonisjs/static' + +/** + * Configuration options to tweak the static files middleware. + * The complete set of options are documented on the + * official documentation website. + * + * https://docs.adonisjs.com/guides/basics/static-file-server + */ +const staticServerConfig = defineConfig({ + /** + * Enable or disable static file serving middleware. + */ + enabled: true, + + /** + * Generate ETag headers for client/proxy caching. + */ + etag: true, + + /** + * Include Last-Modified headers for conditional requests. + */ + lastModified: true, + + /** + * Policy for files starting with a dot. + */ + dotFiles: 'ignore', +}) + +export default staticServerConfig diff --git a/portal/config/vite.ts b/portal/config/vite.ts new file mode 100644 index 000000000..1e0f4db60 --- /dev/null +++ b/portal/config/vite.ts @@ -0,0 +1,34 @@ +import { defineConfig } from '@adonisjs/vite' + +const viteBackendConfig = defineConfig({ + /** + * The output of vite will be written inside this + * directory. The path should be relative from + * the application root. + */ + buildDirectory: 'public/assets', + + /** + * The path to the manifest file generated by the + * "vite build" command. + */ + manifestFile: 'public/assets/.vite/manifest.json', + + /** + * Feel free to change the value of the "assetsUrl" to + * point to a CDN in production. + */ + assetsUrl: '/assets', + + /** + * HTML attributes added to generated script tags. + */ + scriptAttributes: { + /** + * Execute scripts after HTML parsing is complete. + */ + defer: true, + }, +}) + +export default viteBackendConfig diff --git a/portal/database/migrations/.gitkeep b/portal/database/migrations/.gitkeep new file mode 100644 index 000000000..d52e26635 --- /dev/null +++ b/portal/database/migrations/.gitkeep @@ -0,0 +1,3 @@ +# We don't currently use Adonis's migrations at all. +# All migrations are handled by the /backend project instead. +# schema.ts is generated based on database inspection. diff --git a/portal/database/schema.ts b/portal/database/schema.ts new file mode 100644 index 000000000..b99c87b33 --- /dev/null +++ b/portal/database/schema.ts @@ -0,0 +1,25 @@ +/** + * This file is automatically generated + * DO NOT EDIT manually + * Run "node ace migration:run" command to re-generate this file + */ + +import { BaseModel, column } from '@adonisjs/lucid/orm' +import { DateTime } from 'luxon' + +export class UserSchema extends BaseModel { + static $columns = ['createdAt', 'email', 'fullName', 'id', 'password', 'updatedAt'] as const + $columns = UserSchema.$columns + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime + @column() + declare email: string + @column() + declare fullName: string | null + @column({ isPrimary: true }) + declare id: number + @column({ serializeAs: null }) + declare password: string + @column.dateTime({ autoCreate: true, autoUpdate: true }) + declare updatedAt: DateTime | null +} diff --git a/portal/database/schemaRules.ts b/portal/database/schemaRules.ts new file mode 100644 index 000000000..1153c9244 --- /dev/null +++ b/portal/database/schemaRules.ts @@ -0,0 +1,3 @@ +import { type SchemaRules } from '@adonisjs/lucid/types/schema_generator' + +export default {} satisfies SchemaRules diff --git a/portal/hooks/indexInertiaPages.ts b/portal/hooks/indexInertiaPages.ts new file mode 100644 index 000000000..6a346ea9e --- /dev/null +++ b/portal/hooks/indexInertiaPages.ts @@ -0,0 +1,47 @@ +import { hooks } from '@adonisjs/core/app' + +/** + * Custom hook to load inertia pages from feature folders, e.g. `features/docs/pages/DocsIndex.vue` + */ +export default hooks.init((_parent, _manager, generator) => { + generator.add('inertiaPages', { + source: './inertia', + glob: ['**/pages/*.vue'], + output: './.adonisjs/server/pages.d.ts', + + as(vfs, buffer, _config, helpers) { + const pages = vfs.asList() + + buffer.writeLine(`import '@adonisjs/inertia/types'`) + buffer.writeLine(` + import type { + VNodeProps, + AllowedComponentProps, + ComponentInstance + } from 'vue' + + type ExtractProps = Omit< + ComponentInstance['$props'], + keyof VNodeProps | keyof AllowedComponentProps + > + `) + + buffer.writeLine( + `declare module '@adonisjs/inertia/types' {` + ).indent() + + buffer.writeLine( + `export interface InertiaPages {` + ).indent() + + for (const [name, file] of Object.entries(pages)) { + buffer.writeLine( + `'${name}': ExtractProps<(typeof import('${helpers.toImportPath(file)}'))['default']>` + ) + } + + buffer.dedent().writeLine('}') + buffer.dedent().writeLine('}') + }, + }) +}) diff --git a/portal/inertia/app.ts b/portal/inertia/app.ts new file mode 100644 index 000000000..c132d3d7c --- /dev/null +++ b/portal/inertia/app.ts @@ -0,0 +1,26 @@ +import 'vue-sonner/style.css' +import { client } from '#frontend/client.js' +import { createInertiaApp } from '@inertiajs/vue3' +import { TuyauProvider } from '@adonisjs/inertia/vue' +import { createApp, type DefineComponent, h } from 'vue' +import { resolvePageComponent } from '@adonisjs/inertia/helpers' + +const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS' + +createInertiaApp({ + title: (title) => (title ? `${title} - ${appName}` : appName), + resolve: (name) => { + return resolvePageComponent( + `./${name}.vue`, + import.meta.glob('./**/pages/*.vue') + ) + }, + setup({ el, App, props, plugin }) { + createApp({ render: () => h(TuyauProvider, { client }, { default: () => h(App, props) }) }) + .use(plugin) + .mount(el) + }, + progress: { + color: '#4B5563', + }, +}) diff --git a/portal/inertia/client.ts b/portal/inertia/client.ts new file mode 100644 index 000000000..174e57eec --- /dev/null +++ b/portal/inertia/client.ts @@ -0,0 +1,9 @@ +import { registry } from '#client/registry/index.js' +import { createTuyau } from '@tuyau/core/client' + +export const client = createTuyau({ + baseUrl: '/', + registry, +}) + +export const urlFor = client.urlFor diff --git a/portal/inertia/features/errors/pages/NotFound.vue b/portal/inertia/features/errors/pages/NotFound.vue new file mode 100644 index 000000000..5364c9fcd --- /dev/null +++ b/portal/inertia/features/errors/pages/NotFound.vue @@ -0,0 +1,3 @@ + diff --git a/portal/inertia/features/errors/pages/ServerError.vue b/portal/inertia/features/errors/pages/ServerError.vue new file mode 100644 index 000000000..c3b388d13 --- /dev/null +++ b/portal/inertia/features/errors/pages/ServerError.vue @@ -0,0 +1,3 @@ + diff --git a/portal/inertia/features/splash/pages/SplashIndex.vue b/portal/inertia/features/splash/pages/SplashIndex.vue new file mode 100644 index 000000000..904b442f9 --- /dev/null +++ b/portal/inertia/features/splash/pages/SplashIndex.vue @@ -0,0 +1,12 @@ + + + diff --git a/portal/inertia/features/toasts/FlashToasts.vue b/portal/inertia/features/toasts/FlashToasts.vue new file mode 100644 index 000000000..91e1afb84 --- /dev/null +++ b/portal/inertia/features/toasts/FlashToasts.vue @@ -0,0 +1,33 @@ + + + diff --git a/portal/inertia/layouts/app.vue b/portal/inertia/layouts/app.vue new file mode 100644 index 000000000..9cb154e68 --- /dev/null +++ b/portal/inertia/layouts/app.vue @@ -0,0 +1,10 @@ + + + diff --git a/portal/inertia/shims.ts b/portal/inertia/shims.ts new file mode 100644 index 000000000..95cd7fc99 --- /dev/null +++ b/portal/inertia/shims.ts @@ -0,0 +1,5 @@ +declare module '*.vue' { + import type { DefineComponent } from 'vue' + const component: DefineComponent + export default component +} diff --git a/portal/inertia/ssr.ts b/portal/inertia/ssr.ts new file mode 100644 index 000000000..2f2c0a163 --- /dev/null +++ b/portal/inertia/ssr.ts @@ -0,0 +1,24 @@ +import { client } from '#frontend/client.js' +import { createInertiaApp } from '@inertiajs/vue3' +import { TuyauProvider } from '@adonisjs/inertia/vue' +import { renderToString } from '@vue/server-renderer' +import { createSSRApp, h, type DefineComponent } from 'vue' +import { resolvePageComponent } from '@adonisjs/inertia/helpers' + +export default function render(page: any) { + return createInertiaApp({ + page, + render: renderToString, + resolve: (name) => { + return resolvePageComponent( + `./${name}.vue`, + import.meta.glob('./**/pages/*.vue', { eager: true }) + ) + }, + setup: ({ App, props, plugin }) => { + return createSSRApp({ + render: () => h(TuyauProvider, { client }, { default: () => h(App, props) }), + }).use(plugin) + }, + }) +} diff --git a/portal/inertia/tsconfig.json b/portal/inertia/tsconfig.json new file mode 100644 index 000000000..83546ac29 --- /dev/null +++ b/portal/inertia/tsconfig.json @@ -0,0 +1,14 @@ +{ + "extends": "@adonisjs/tsconfig/tsconfig.client.json", + "compilerOptions": { + "jsx": "preserve", + "module": "ESNext", + "jsxImportSource": "vue" + }, + "include": [ + "./**/*.ts", + "./**/*.vue", + "../.adonisjs/client/**/*.ts", + "../.adonisjs/server/**/*.ts" + ] +} diff --git a/portal/inertia/types.ts b/portal/inertia/types.ts new file mode 100644 index 000000000..689107761 --- /dev/null +++ b/portal/inertia/types.ts @@ -0,0 +1,14 @@ +import type { Data } from '#client/data.d.ts' + +/** + * Bridge the shared props and flash data inferred from the Inertia + * middleware into the Inertia client, so `usePage().props`, `usePage().flash`, + * and layout callbacks are typed globally without passing a generic at each + * call site. + */ +declare module '@inertiajs/core' { + interface InertiaConfig { + sharedPageProps: Data.SharedProps + flashDataType: Data.FlashMessages + } +} diff --git a/portal/package.json b/portal/package.json new file mode 100644 index 000000000..6e01be918 --- /dev/null +++ b/portal/package.json @@ -0,0 +1,86 @@ +{ + "name": "portal", + "version": "0.0.0", + "private": true, + "type": "module", + "license": "UNLICENSED", + "engines": { + "node": ">=24.0.0" + }, + "scripts": { + "start": "node bin/server.js", + "build": "node ace build", + "dev": "node ace serve --hmr", + "test": "node ace test", + "ace": "node ace", + "typecheck": "tsc --noEmit && vue-tsc --noEmit --project inertia/tsconfig.json" + }, + "imports": { + "#backend/*": "./app/*.js", + "#frontend/*.vue": "./inertia/*.vue", + "#frontend/*": "./inertia/*", + "#generated/*": "./.adonisjs/server/*.js", + "#client/*": "./.adonisjs/client/*", + "#providers/*": "./providers/*.js", + "#database/*": "./database/*.js", + "#tests/*": "./tests/*.js", + "#start/*": "./start/*.js", + "#config/*": "./config/*.js" + }, + "devDependencies": { + "@adonisjs/assembler": "^8.5.2", + "@adonisjs/prettier-config": "^1.5.0", + "@adonisjs/tsconfig": "^2.0.0", + "@japa/assert": "^4.2.0", + "@japa/browser-client": "^2.3.0", + "@japa/plugin-adonisjs": "^5.2.0", + "@japa/runner": "^5.3.0", + "@poppinss/ts-exec": "^1.4.4", + "@types/luxon": "^3.7.5", + "@types/node": "~26.6.2", + "@vitejs/plugin-vue": "^6.0.9", + "hot-hook": "^1.0.0", + "pino-pretty": "^13.1.3", + "typescript": "catalog:ts6", + "vite": "^8.3.0", + "vue-tsc": "^3.3.11", + "youch": "^4.1.1" + }, + "dependencies": { + "@adonisjs/auth": "^10.1.0", + "@adonisjs/core": "^7.5.2", + "@adonisjs/cors": "^3.0.0", + "@adonisjs/inertia": "^5.0.1", + "@adonisjs/lucid": "^22.4.2", + "@adonisjs/redis": "^11.0.0", + "@adonisjs/session": "^8.1.0", + "@adonisjs/shield": "^9.0.0", + "@adonisjs/static": "^2.0.1", + "@adonisjs/vite": "^6.0.2", + "@inertiajs/core": "^3.7.1", + "@inertiajs/vue3": "^3.7.1", + "@tuyau/core": "^1.2.2", + "@vinejs/vine": "^4.4.0", + "@vue/server-renderer": "^3.5.43", + "edge.js": "^6.5.1", + "lucide-vue-next": "^1.0.0", + "luxon": "^3.7.2", + "mysql2": "^3.23.0", + "reflect-metadata": "^0.2.2", + "vue": "^3.5.43", + "vue-sonner": "^2.0.9" + }, + "hotHook": { + "boundaries": [ + "./app/features/**/*Controller.ts", + "./app/features/**/*Middleware.ts", + "./app/middleware/*.ts" + ] + }, + "allowScripts": { + "@swc/core": true, + "better-sqlite3": true, + "esbuild": true, + "fsevents": true + } +} diff --git a/portal/providers/apiProvider.ts b/portal/providers/apiProvider.ts new file mode 100644 index 000000000..8e4e00cd9 --- /dev/null +++ b/portal/providers/apiProvider.ts @@ -0,0 +1,69 @@ +import { HttpContext } from '@adonisjs/core/http' +import { BaseSerializer } from '@adonisjs/core/transformers' +import { type SimplePaginatorMetaKeys } from '@adonisjs/lucid/types/querybuilder' + +/** + * Custom serializer for API responses that ensures consistent JSON structure + * across all API endpoints. Wraps response data in a 'data' property and handles + * pagination metadata for Lucid ORM query results. + */ +class ApiSerializer extends BaseSerializer<{ + Wrap: 'data' + PaginationMetaData: SimplePaginatorMetaKeys +}> { + /** + * Wraps all serialized data under this key in the response object. + * Example: { data: [...] } instead of returning raw arrays/objects + */ + wrap: 'data' = 'data' + + /** + * Validates and defines pagination metadata structure for paginated responses. + * Ensures that pagination info from Lucid queries is properly formatted. + * + * @throws Error if metadata doesn't match Lucid's pagination structure + */ + definePaginationMetaData(metaData: unknown): SimplePaginatorMetaKeys { + if (!this.isLucidPaginatorMetaData(metaData)) { + throw new Error( + 'Invalid pagination metadata. Expected metadata to contain Lucid pagination keys' + ) + } + return metaData + } +} + +/** + * Single instance of ApiSerializer used across the application + */ +const serializer = new ApiSerializer() +const serialize = Object.assign( + function (this: HttpContext, ...[data, resolver]: Parameters) { + return serializer.serialize(data, resolver ?? this.containerResolver) + }, + { + withoutWrapping( + this: HttpContext, + ...[data, resolver]: Parameters + ) { + return serializer.serializeWithoutWrapping(data, resolver ?? this.containerResolver) + }, + } +) as ApiSerializer['serialize'] & { withoutWrapping: ApiSerializer['serializeWithoutWrapping'] } + +/** + * Adds the serialize method to all HttpContext instances. + * Usage in controllers: return ctx.serialize(data) + * This ensures all API responses follow the same structure with data wrapping. + */ +HttpContext.instanceProperty('serialize', serialize) + +/** + * Module augmentation to add the serialize method to HttpContext. + * This allows controllers to use ctx.serialize() for consistent API responses. + */ +declare module '@adonisjs/core/http' { + export interface HttpContext { + serialize: typeof serialize + } +} diff --git a/portal/start/env.ts b/portal/start/env.ts new file mode 100644 index 000000000..9677c90c8 --- /dev/null +++ b/portal/start/env.ts @@ -0,0 +1,29 @@ +/* +|-------------------------------------------------------------------------- +| Environment variables service +|-------------------------------------------------------------------------- +| +| The `Env.create` method creates an instance of the Env service. The +| service validates the environment variables and also cast values +| to JavaScript data types. +| +*/ + +import { Env } from '@adonisjs/core/env' + +export const rootEnv = await Env.create(new URL('../../', import.meta.url), { + KEY: Env.schema.string(), + DB_HOST: Env.schema.string.optional(), + DB_PORT: Env.schema.number.optional(), + DB_USER: Env.schema.string.optional(), + DB_PASSWORD: Env.schema.string.optional(), + DB_DATABASE: Env.schema.string.optional(), + REDIS_URL: Env.schema.string.optional(), + DEVELOPMENT_MYSQL_PASSWORD: Env.schema.string.optional(), + DEVELOPMENT_VITE_ALLOWED_HOSTS: Env.schema.string.optional(), +}); + +export const portalEnv = await Env.create(new URL("../", import.meta.url), { + SESSION_DRIVER: Env.schema.enum.optional(["redis", "memory"] as const), + LOG_LEVEL: Env.schema.string.optional(), +}); diff --git a/portal/start/kernel.ts b/portal/start/kernel.ts new file mode 100644 index 000000000..2a7925ab2 --- /dev/null +++ b/portal/start/kernel.ts @@ -0,0 +1,35 @@ +/* +|-------------------------------------------------------------------------- +| HTTP kernel file +|-------------------------------------------------------------------------- +| +| The HTTP kernel file is used to register the middleware with the server +| or the router. +| +*/ + +import router from '@adonisjs/core/services/router' +import server from '@adonisjs/core/services/server' + +server.errorHandler(() => import('#backend/exceptions/handler')) + +server.use([ + () => import('#backend/middleware/containerBindingsMiddleware'), + () => import('@adonisjs/static/static_middleware'), + () => import('@adonisjs/cors/cors_middleware'), + () => import('@adonisjs/vite/vite_middleware'), + () => import('#backend/middleware/inertiaMiddleware'), +]) + +router.use([ + () => import('@adonisjs/core/bodyparser_middleware'), + () => import('@adonisjs/session/session_middleware'), + () => import('@adonisjs/shield/shield_middleware'), + () => import('@adonisjs/auth/initialize_auth_middleware'), + () => import('#backend/middleware/silentAuthMiddleware'), +]) + +export const middleware = router.named({ + guest: () => import('#backend/middleware/guestMiddleware'), + auth: () => import('#backend/middleware/authMiddleware'), +}) diff --git a/portal/start/routes.ts b/portal/start/routes.ts new file mode 100644 index 000000000..e6b55d7d8 --- /dev/null +++ b/portal/start/routes.ts @@ -0,0 +1,33 @@ +/* +|-------------------------------------------------------------------------- +| Routes file +|-------------------------------------------------------------------------- +| +| The routes file is used for defining the HTTP routes. +| +*/ + +// import { middleware } from '#start/kernel' +import { controllers } from '#generated/controllers' +import router from '@adonisjs/core/services/router' + +router.get("/", [controllers.splash.Splash, "getIndex"]); + +// router.on('/').renderInertia('home', {}).as('home') + +// router +// .group(() => { +// router.get('signup', [controllers.NewAccount, 'create']) +// router.post('signup', [controllers.NewAccount, 'store']) + +// router.get('login', [controllers.Session, 'create']) +// router.post('login', [controllers.Session, 'store']) +// }) +// .use(middleware.guest()) + +// router +// .group(() => { +// router.on('/dashboard').renderInertia('dashboard', {}).as('dashboard') +// router.post('logout', [controllers.Session, 'destroy']) +// }) +// .use(middleware.auth()) diff --git a/portal/start/validator.ts b/portal/start/validator.ts new file mode 100644 index 000000000..6a2ca7dde --- /dev/null +++ b/portal/start/validator.ts @@ -0,0 +1,23 @@ +/* +|-------------------------------------------------------------------------- +| Validator file +|-------------------------------------------------------------------------- +| +| The validator file is used for configuring global transforms for VineJS. +| The transform below converts all VineJS date outputs from JavaScript +| Date objects to Luxon DateTime instances, so that validated dates are +| ready to use with Lucid models and other parts of the app that expect +| Luxon DateTime. +| +*/ + +import { DateTime } from 'luxon' +import { VineDate } from '@vinejs/vine' + +declare module '@vinejs/vine/types' { + interface VineGlobalTransforms { + date: DateTime + } +} + +VineDate.transform((value) => DateTime.fromJSDate(value)) diff --git a/portal/tests/bootstrap.ts b/portal/tests/bootstrap.ts new file mode 100644 index 000000000..2484bbbd0 --- /dev/null +++ b/portal/tests/bootstrap.ts @@ -0,0 +1,38 @@ +import { assert } from '@japa/assert' +import app from '@adonisjs/core/services/app' +import type { Config } from '@japa/runner/types' +import { pluginAdonisJS } from '@japa/plugin-adonisjs' +import { dbAssertions } from '@adonisjs/lucid/plugins/db' +import testUtils from '@adonisjs/core/services/test_utils' + +/** + * This file is imported by the "bin/test.ts" entrypoint file + */ + +/** + * Configure Japa plugins in the plugins array. + * Learn more - https://japa.dev/docs/runner-config#plugins-optional + */ +export const plugins: Config['plugins'] = [assert(), pluginAdonisJS(app), dbAssertions(app)] + +/** + * Configure lifecycle function to run before and after all the + * tests. + * + * The setup functions are executed before all the tests + * The teardown functions are executed after all the tests + */ +export const runnerHooks: Required> = { + setup: [], + teardown: [], +} + +/** + * Configure suites by tapping into the test suite instance. + * Learn more - https://japa.dev/docs/test-suites#lifecycle-hooks + */ +export const configureSuite: Config['configureSuite'] = (suite) => { + if (['browser', 'functional', 'e2e'].includes(suite.name)) { + return suite.setup(() => testUtils.httpServer().start()) + } +} diff --git a/portal/tmp/.gitkeep b/portal/tmp/.gitkeep new file mode 100644 index 000000000..e69de29bb diff --git a/portal/tsconfig.inertia.json b/portal/tsconfig.inertia.json new file mode 100644 index 000000000..8521e34a8 --- /dev/null +++ b/portal/tsconfig.inertia.json @@ -0,0 +1,8 @@ +{ + "extends": "./inertia/tsconfig.json", + "compilerOptions": { + "rootDir": "./inertia", + "composite": true + }, + "include": ["./inertia/**/*.ts", "./inertia/**/*.vue"] +} diff --git a/portal/tsconfig.json b/portal/tsconfig.json new file mode 100644 index 000000000..32a388df7 --- /dev/null +++ b/portal/tsconfig.json @@ -0,0 +1,8 @@ +{ + "extends": "@adonisjs/tsconfig/tsconfig.app.json", + "compilerOptions": { + "rootDir": "./", + "outDir": "./build" + }, + "references": [{ "path": "./tsconfig.inertia.json" }] +} diff --git a/portal/vite.config.ts b/portal/vite.config.ts new file mode 100644 index 000000000..cea410f39 --- /dev/null +++ b/portal/vite.config.ts @@ -0,0 +1,23 @@ +import { defineConfig } from 'vite' +import vue from '@vitejs/plugin-vue' +import adonisjs from '@adonisjs/vite/client' +import { rootEnv } from '#start/env' + +const allowedHosts = rootEnv.get("DEVELOPMENT_VITE_ALLOWED_HOSTS", "") + .split(",") + .map((v) => v.trim()) + .filter(Boolean); + +export default defineConfig({ + plugins: [ + vue(), + adonisjs({ entryPoints: ['inertia/app.ts'], reload: ['resources/views/**/*.edge'] }), + ], + + server: { + watch: { + ignored: ['**/storage/**', '**/tmp/**'], + }, + allowedHosts, + }, +}) From 9a3f9749aa57ed3b5ff59ea408d2764d08e57081 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:07:57 +0000 Subject: [PATCH 02/39] portal: run formatter --- portal/.adonisjs/client/data.d.ts | 16 ++--- portal/.adonisjs/server/controllers.ts | 4 +- portal/.adonisjs/server/events.ts | 2 +- portal/.adonisjs/server/listeners.ts | 2 +- portal/.adonisjs/server/pages.d.ts | 34 ++++----- portal/ace.js | 4 +- portal/adonisrc.ts | 72 +++++++++---------- portal/app/exceptions/handler.ts | 20 +++--- .../transformers/PortalUserTransformer.ts | 12 ++-- .../splash/controllers/SplashController.ts | 2 +- portal/app/middleware/authMiddleware.ts | 18 ++--- .../middleware/containerBindingsMiddleware.ts | 12 ++-- portal/app/middleware/guestMiddleware.ts | 20 +++--- portal/app/middleware/inertiaMiddleware.ts | 40 +++++------ portal/app/middleware/silentAuthMiddleware.ts | 8 +-- portal/bin/console.ts | 28 ++++---- portal/bin/server.ts | 28 ++++---- portal/bin/test.ts | 38 +++++----- portal/config/app.ts | 16 ++--- portal/config/auth.ts | 18 ++--- portal/config/bodyparser.ts | 21 +++--- portal/config/cors.ts | 10 +-- portal/config/database.ts | 16 ++--- portal/config/encryption.ts | 16 ++--- portal/config/hash.ts | 10 +-- portal/config/inertia.ts | 8 +-- portal/config/logger.ts | 16 ++--- portal/config/redis.ts | 20 +++--- portal/config/session.ts | 20 +++--- portal/config/shield.ts | 12 ++-- portal/config/static.ts | 8 +-- portal/config/vite.ts | 12 ++-- portal/hooks/indexInertiaPages.ts | 36 ++++------ portal/inertia/app.ts | 25 +++---- portal/inertia/client.ts | 10 +-- .../features/errors/pages/NotFound.vue | 4 +- .../features/errors/pages/ServerError.vue | 4 +- .../features/splash/pages/SplashIndex.vue | 4 +- .../inertia/features/toasts/FlashToasts.vue | 22 +++--- portal/inertia/shims.ts | 8 +-- portal/inertia/ssr.ts | 24 +++---- portal/inertia/types.ts | 8 +-- portal/providers/apiProvider.ts | 41 +++++------ portal/start/env.ts | 4 +- portal/start/kernel.ts | 36 +++++----- portal/start/routes.ts | 4 +- portal/start/validator.ts | 10 +-- portal/tests/bootstrap.ts | 26 +++---- portal/vite.config.ts | 20 +++--- 49 files changed, 398 insertions(+), 451 deletions(-) diff --git a/portal/.adonisjs/client/data.d.ts b/portal/.adonisjs/client/data.d.ts index 5cafc4b8a..70622aa4d 100644 --- a/portal/.adonisjs/client/data.d.ts +++ b/portal/.adonisjs/client/data.d.ts @@ -4,18 +4,18 @@ */ /// -import type { InferData, InferVariants } from '@adonisjs/core/types/transformers' -import type { InferSharedProps, InferFlashData } from '@adonisjs/inertia/types' -import type PortalUsersPortalUserTransformer from '#backend/features/portalUsers/transformers/PortalUserTransformer' -import type InertiaMiddleware from '#backend/middleware/inertiaMiddleware' +import type { InferData, InferVariants } from "@adonisjs/core/types/transformers"; +import type { InferSharedProps, InferFlashData } from "@adonisjs/inertia/types"; +import type PortalUsersPortalUserTransformer from "#backend/features/portalUsers/transformers/PortalUserTransformer"; +import type InertiaMiddleware from "#backend/middleware/inertiaMiddleware"; export namespace Data { export namespace PortalUsers { - export type PortalUser = InferData + export type PortalUser = InferData; export namespace PortalUser { - export type Variants = InferVariants + export type Variants = InferVariants; } } - export type SharedProps = InferSharedProps - export type FlashMessages = InferFlashData + export type SharedProps = InferSharedProps; + export type FlashMessages = InferFlashData; } diff --git a/portal/.adonisjs/server/controllers.ts b/portal/.adonisjs/server/controllers.ts index c135649bc..900cfd430 100644 --- a/portal/.adonisjs/server/controllers.ts +++ b/portal/.adonisjs/server/controllers.ts @@ -5,6 +5,6 @@ export const controllers = { splash: { - Splash: () => import('#backend/features/splash/controllers/SplashController'), + Splash: () => import("#backend/features/splash/controllers/SplashController"), }, -} +}; diff --git a/portal/.adonisjs/server/events.ts b/portal/.adonisjs/server/events.ts index a74e59b65..762b5604a 100644 --- a/portal/.adonisjs/server/events.ts +++ b/portal/.adonisjs/server/events.ts @@ -3,4 +3,4 @@ * DO NOT EDIT manually */ -export const events = {} +export const events = {}; diff --git a/portal/.adonisjs/server/listeners.ts b/portal/.adonisjs/server/listeners.ts index 05f35f86d..d9cfaa2b4 100644 --- a/portal/.adonisjs/server/listeners.ts +++ b/portal/.adonisjs/server/listeners.ts @@ -3,4 +3,4 @@ * DO NOT EDIT manually */ -export const listeners = {} +export const listeners = {}; diff --git a/portal/.adonisjs/server/pages.d.ts b/portal/.adonisjs/server/pages.d.ts index 9555263fc..e9de18138 100644 --- a/portal/.adonisjs/server/pages.d.ts +++ b/portal/.adonisjs/server/pages.d.ts @@ -1,29 +1,21 @@ -import '@adonisjs/inertia/types' +import "@adonisjs/inertia/types"; +import type { VNodeProps, AllowedComponentProps, ComponentInstance } from "vue"; - import type { - VNodeProps, - AllowedComponentProps, - ComponentInstance - } from 'vue' - - type ExtractProps = Omit< - ComponentInstance['$props'], - keyof VNodeProps | keyof AllowedComponentProps - > - - -declare module '@adonisjs/inertia/types' { +type ExtractProps = Omit["$props"], keyof VNodeProps | keyof AllowedComponentProps>; +declare module "@adonisjs/inertia/types" { export interface InertiaPages { + "features/errors/pages/NotFound": ExtractProps< + (typeof import("../../inertia/features/errors/pages/NotFound.vue"))["default"] + >; - 'features/errors/pages/NotFound': ExtractProps<(typeof import('../../inertia/features/errors/pages/NotFound.vue'))['default']> - - 'features/errors/pages/ServerError': ExtractProps<(typeof import('../../inertia/features/errors/pages/ServerError.vue'))['default']> - - 'features/splash/pages/SplashIndex': ExtractProps<(typeof import('../../inertia/features/splash/pages/SplashIndex.vue'))['default']> + "features/errors/pages/ServerError": ExtractProps< + (typeof import("../../inertia/features/errors/pages/ServerError.vue"))["default"] + >; + "features/splash/pages/SplashIndex": ExtractProps< + (typeof import("../../inertia/features/splash/pages/SplashIndex.vue"))["default"] + >; } - } - diff --git a/portal/ace.js b/portal/ace.js index 0eefd202f..d7647d08f 100644 --- a/portal/ace.js +++ b/portal/ace.js @@ -19,9 +19,9 @@ /** * Register hook to process TypeScript files using @poppinss/ts-exec */ -import '@poppinss/ts-exec' +import "@poppinss/ts-exec"; /** * Import ace console entrypoint */ -await import('./bin/console.js') +await import("./bin/console.js"); diff --git a/portal/adonisrc.ts b/portal/adonisrc.ts index 7c742c8f6..3842b508a 100644 --- a/portal/adonisrc.ts +++ b/portal/adonisrc.ts @@ -1,6 +1,6 @@ -import { indexEntities } from '@adonisjs/core/generators' -import { defineConfig } from '@adonisjs/core/app' -import { generateRegistry } from '@tuyau/core/hooks' +import { indexEntities } from "@adonisjs/core/generators"; +import { defineConfig } from "@adonisjs/core/app"; +import { generateRegistry } from "@tuyau/core/hooks"; export default defineConfig({ /* @@ -25,10 +25,10 @@ export default defineConfig({ | */ commands: [ - () => import('@adonisjs/core/commands'), - () => import('@adonisjs/lucid/commands'), - () => import('@adonisjs/session/commands'), - () => import('@adonisjs/inertia/commands'), + () => import("@adonisjs/core/commands"), + () => import("@adonisjs/lucid/commands"), + () => import("@adonisjs/session/commands"), + () => import("@adonisjs/inertia/commands"), ], /* @@ -41,24 +41,24 @@ export default defineConfig({ | */ providers: [ - () => import('@adonisjs/core/providers/app_provider'), - () => import('@adonisjs/core/providers/hash_provider'), + () => import("@adonisjs/core/providers/app_provider"), + () => import("@adonisjs/core/providers/hash_provider"), { - file: () => import('@adonisjs/core/providers/repl_provider'), - environment: ['repl', 'test'], + file: () => import("@adonisjs/core/providers/repl_provider"), + environment: ["repl", "test"], }, - () => import('@adonisjs/core/providers/vinejs_provider'), - () => import('@adonisjs/core/providers/edge_provider'), - () => import('@adonisjs/session/session_provider'), - () => import('@adonisjs/vite/vite_provider'), - () => import('@adonisjs/shield/shield_provider'), - () => import('@adonisjs/static/static_provider'), - () => import('@adonisjs/lucid/database_provider'), - () => import('@adonisjs/cors/cors_provider'), - () => import('@adonisjs/inertia/inertia_provider'), - () => import('@adonisjs/auth/auth_provider'), - () => import('@adonisjs/redis/redis_provider'), - () => import('#providers/apiProvider'), + () => import("@adonisjs/core/providers/vinejs_provider"), + () => import("@adonisjs/core/providers/edge_provider"), + () => import("@adonisjs/session/session_provider"), + () => import("@adonisjs/vite/vite_provider"), + () => import("@adonisjs/shield/shield_provider"), + () => import("@adonisjs/static/static_provider"), + () => import("@adonisjs/lucid/database_provider"), + () => import("@adonisjs/cors/cors_provider"), + () => import("@adonisjs/inertia/inertia_provider"), + () => import("@adonisjs/auth/auth_provider"), + () => import("@adonisjs/redis/redis_provider"), + () => import("#providers/apiProvider"), ], /* @@ -69,11 +69,7 @@ export default defineConfig({ | List of modules to import before starting the application. | */ - preloads: [ - () => import('#start/routes'), - () => import('#start/kernel'), - () => import('#start/validator'), - ], + preloads: [() => import("#start/routes"), () => import("#start/kernel"), () => import("#start/validator")], /* |-------------------------------------------------------------------------- @@ -87,18 +83,18 @@ export default defineConfig({ tests: { suites: [ { - files: ['tests/unit/**/*.spec.{ts,js}'], - name: 'unit', + files: ["tests/unit/**/*.spec.{ts,js}"], + name: "unit", timeout: 2000, }, { - files: ['tests/functional/**/*.spec.{ts,js}'], - name: 'functional', + files: ["tests/functional/**/*.spec.{ts,js}"], + name: "functional", timeout: 30000, }, { - files: ['tests/browser/**/*.spec.{ts,js}'], - name: 'browser', + files: ["tests/browser/**/*.spec.{ts,js}"], + name: "browser", timeout: 300000, }, ], @@ -116,11 +112,11 @@ export default defineConfig({ */ metaFiles: [ { - pattern: 'resources/views/**/*.edge', + pattern: "resources/views/**/*.edge", reloadServer: false, }, { - pattern: 'public/**', + pattern: "public/**", reloadServer: false, }, ], @@ -164,6 +160,6 @@ export default defineConfig({ generateRegistry(), ], - buildStarting: [() => import('@adonisjs/vite/build_hook')], + buildStarting: [() => import("@adonisjs/vite/build_hook")], }, -}) +}); diff --git a/portal/app/exceptions/handler.ts b/portal/app/exceptions/handler.ts index 0c7cb2256..c93096ae0 100644 --- a/portal/app/exceptions/handler.ts +++ b/portal/app/exceptions/handler.ts @@ -1,36 +1,36 @@ -import app from '@adonisjs/core/services/app' -import { type HttpContext, ExceptionHandler } from '@adonisjs/core/http' -import type { StatusPageRange, StatusPageRenderer } from '@adonisjs/core/types/http' +import app from "@adonisjs/core/services/app"; +import { type HttpContext, ExceptionHandler } from "@adonisjs/core/http"; +import type { StatusPageRange, StatusPageRenderer } from "@adonisjs/core/types/http"; export default class HttpExceptionHandler extends ExceptionHandler { /** * In debug mode, the exception handler will display verbose errors * with pretty printed stack traces. */ - protected debug = !app.inProduction + protected debug = !app.inProduction; /** * Status pages are used to display a custom HTML pages for certain error * codes. You might want to enable them in production only, but feel * free to enable them in development as well. */ - protected renderStatusPages = app.inProduction + protected renderStatusPages = app.inProduction; /** * Status pages is a collection of error code range and a callback * to return the HTML contents to send as a response. */ protected statusPages: Record = { - '404': (_, { inertia }) => inertia.render('features/errors/pages/NotFound', {}), - '500..599': (_, { inertia }) => inertia.render('features/errors/pages/ServerError', {}), - } + "404": (_, { inertia }) => inertia.render("features/errors/pages/NotFound", {}), + "500..599": (_, { inertia }) => inertia.render("features/errors/pages/ServerError", {}), + }; /** * The method is used for handling errors and returning * response to the client */ async handle(error: unknown, ctx: HttpContext) { - return super.handle(error, ctx) + return super.handle(error, ctx); } /** @@ -40,6 +40,6 @@ export default class HttpExceptionHandler extends ExceptionHandler { * @note You should not attempt to send a response from this method. */ async report(error: unknown, ctx: HttpContext) { - return super.report(error, ctx) + return super.report(error, ctx); } } diff --git a/portal/app/features/portalUsers/transformers/PortalUserTransformer.ts b/portal/app/features/portalUsers/transformers/PortalUserTransformer.ts index 5856203a1..026339685 100644 --- a/portal/app/features/portalUsers/transformers/PortalUserTransformer.ts +++ b/portal/app/features/portalUsers/transformers/PortalUserTransformer.ts @@ -1,14 +1,10 @@ -import type { PortalUser } from '#backend/features/portalUsers/models/PortalUser' -import { BaseTransformer } from '@adonisjs/core/transformers' +import type { PortalUser } from "#backend/features/portalUsers/models/PortalUser"; +import { BaseTransformer } from "@adonisjs/core/transformers"; export class PortalUserTransformer extends BaseTransformer { toObject() { - return this.pick(this.resource, [ - "user_id", - "username", - "avatar", - ]) + return this.pick(this.resource, ["user_id", "username", "avatar"]); } } -export default PortalUserTransformer +export default PortalUserTransformer; diff --git a/portal/app/features/splash/controllers/SplashController.ts b/portal/app/features/splash/controllers/SplashController.ts index d9ea912a9..355b52a35 100644 --- a/portal/app/features/splash/controllers/SplashController.ts +++ b/portal/app/features/splash/controllers/SplashController.ts @@ -1,4 +1,4 @@ -import type { HttpContext } from '@adonisjs/core/http' +import type { HttpContext } from "@adonisjs/core/http"; export default class SplashController { async getIndex({ inertia }: HttpContext) { diff --git a/portal/app/middleware/authMiddleware.ts b/portal/app/middleware/authMiddleware.ts index 79904069d..fb5e5fdb7 100644 --- a/portal/app/middleware/authMiddleware.ts +++ b/portal/app/middleware/authMiddleware.ts @@ -1,16 +1,12 @@ -import type { HttpContext } from '@adonisjs/core/http' -import type { NextFn } from '@adonisjs/core/types/http' -import type { Authenticators } from '@adonisjs/auth/types' +import type { HttpContext } from "@adonisjs/core/http"; +import type { NextFn } from "@adonisjs/core/types/http"; +import type { Authenticators } from "@adonisjs/auth/types"; export default class AuthMiddleware { - redirectTo = '/login' + redirectTo = "/login"; - async handle( - ctx: HttpContext, - next: NextFn, - options: { guards?: (keyof Authenticators)[] } = {} - ) { - await ctx.auth.authenticateUsing(options.guards, { loginRoute: this.redirectTo }) - return next() + async handle(ctx: HttpContext, next: NextFn, options: { guards?: (keyof Authenticators)[] } = {}) { + await ctx.auth.authenticateUsing(options.guards, { loginRoute: this.redirectTo }); + return next(); } } diff --git a/portal/app/middleware/containerBindingsMiddleware.ts b/portal/app/middleware/containerBindingsMiddleware.ts index 8f5322b4d..3d5f95c4a 100644 --- a/portal/app/middleware/containerBindingsMiddleware.ts +++ b/portal/app/middleware/containerBindingsMiddleware.ts @@ -1,6 +1,6 @@ -import { Logger } from '@adonisjs/core/logger' -import { HttpContext } from '@adonisjs/core/http' -import { type NextFn } from '@adonisjs/core/types/http' +import { Logger } from "@adonisjs/core/logger"; +import { HttpContext } from "@adonisjs/core/http"; +import { type NextFn } from "@adonisjs/core/types/http"; /** * The container bindings middleware binds classes to their request @@ -11,9 +11,9 @@ import { type NextFn } from '@adonisjs/core/types/http' */ export default class ContainerBindingsMiddleware { handle(ctx: HttpContext, next: NextFn) { - ctx.containerResolver.bindValue(HttpContext, ctx) - ctx.containerResolver.bindValue(Logger, ctx.logger) + ctx.containerResolver.bindValue(HttpContext, ctx); + ctx.containerResolver.bindValue(Logger, ctx.logger); - return next() + return next(); } } diff --git a/portal/app/middleware/guestMiddleware.ts b/portal/app/middleware/guestMiddleware.ts index 787d00d03..28cd12911 100644 --- a/portal/app/middleware/guestMiddleware.ts +++ b/portal/app/middleware/guestMiddleware.ts @@ -1,6 +1,6 @@ -import type { HttpContext } from '@adonisjs/core/http' -import type { NextFn } from '@adonisjs/core/types/http' -import type { Authenticators } from '@adonisjs/auth/types' +import type { HttpContext } from "@adonisjs/core/http"; +import type { NextFn } from "@adonisjs/core/types/http"; +import type { Authenticators } from "@adonisjs/auth/types"; /** * Guest middleware is used to deny access to routes that should @@ -13,20 +13,16 @@ export default class GuestMiddleware { /** * The URL to redirect to when user is logged-in */ - redirectTo = '/' + redirectTo = "/"; - async handle( - ctx: HttpContext, - next: NextFn, - options: { guards?: (keyof Authenticators)[] } = {} - ) { + async handle(ctx: HttpContext, next: NextFn, options: { guards?: (keyof Authenticators)[] } = {}) { for (let guard of options.guards || [ctx.auth.defaultGuard]) { if (await ctx.auth.use(guard).check()) { - ctx.session.reflash() - return ctx.response.redirect(this.redirectTo, true) + ctx.session.reflash(); + return ctx.response.redirect(this.redirectTo, true); } } - return next() + return next(); } } diff --git a/portal/app/middleware/inertiaMiddleware.ts b/portal/app/middleware/inertiaMiddleware.ts index 5cc3a9a80..80580f0e4 100644 --- a/portal/app/middleware/inertiaMiddleware.ts +++ b/portal/app/middleware/inertiaMiddleware.ts @@ -1,7 +1,7 @@ -import type { HttpContext } from '@adonisjs/core/http' -import type { NextFn } from '@adonisjs/core/types/http' -import BaseInertiaMiddleware from '@adonisjs/inertia/inertia_middleware' -import { PortalUserTransformer } from '#backend/features/portalUsers/transformers/PortalUserTransformer' +import type { HttpContext } from "@adonisjs/core/http"; +import type { NextFn } from "@adonisjs/core/types/http"; +import BaseInertiaMiddleware from "@adonisjs/inertia/inertia_middleware"; +import { PortalUserTransformer } from "#backend/features/portalUsers/transformers/PortalUserTransformer"; export default class InertiaMiddleware extends BaseInertiaMiddleware { share(ctx: HttpContext) { @@ -13,13 +13,13 @@ export default class InertiaMiddleware extends BaseInertiaMiddleware { * In that case, we must always assume that HttpContext is not fully hydrated * with all the properties */ - const { auth, request } = ctx as Partial + const { auth, request } = ctx as Partial; - const theme: 'light' | 'dark' = - request?.plainCookie('app_theme', { - defaultValue: 'light', + const theme: "light" | "dark" = + request?.plainCookie("app_theme", { + defaultValue: "light", encoded: false, - }) ?? 'light' + }) ?? "light"; /** * Data shared with all Inertia pages. Make sure you are using @@ -29,7 +29,7 @@ export default class InertiaMiddleware extends BaseInertiaMiddleware { errors: ctx.inertia.always(this.getValidationErrors(ctx)), user: ctx.inertia.always(auth?.user ? PortalUserTransformer.transform(auth.user) : undefined), preferences: ctx.inertia.always({ theme }), - } + }; } flash(ctx: HttpContext) { @@ -38,25 +38,25 @@ export default class InertiaMiddleware extends BaseInertiaMiddleware { * object instead of props, and the client strips them from history * state so they never reappear when navigating back. */ - const { session } = ctx as Partial + const { session } = ctx as Partial; - const success: string | undefined = session?.flashMessages.get('success') - const error: string | undefined = session?.flashMessages.get('error') + const success: string | undefined = session?.flashMessages.get("success"); + const error: string | undefined = session?.flashMessages.get("error"); - return { success, error } + return { success, error }; } async handle(ctx: HttpContext, next: NextFn) { - await this.init(ctx) + await this.init(ctx); - const output = await next() - this.dispose(ctx) + const output = await next(); + this.dispose(ctx); - return output + return output; } } -declare module '@adonisjs/inertia/types' { - type MiddlewareSharedProps = InferSharedProps +declare module "@adonisjs/inertia/types" { + type MiddlewareSharedProps = InferSharedProps; export interface SharedProps extends MiddlewareSharedProps {} } diff --git a/portal/app/middleware/silentAuthMiddleware.ts b/portal/app/middleware/silentAuthMiddleware.ts index 3e46f4090..8969ed4b1 100644 --- a/portal/app/middleware/silentAuthMiddleware.ts +++ b/portal/app/middleware/silentAuthMiddleware.ts @@ -1,5 +1,5 @@ -import type { HttpContext } from '@adonisjs/core/http' -import type { NextFn } from '@adonisjs/core/types/http' +import type { HttpContext } from "@adonisjs/core/http"; +import type { NextFn } from "@adonisjs/core/types/http"; /** * Silent auth middleware can be used as a global middleware to silent check @@ -9,8 +9,8 @@ import type { NextFn } from '@adonisjs/core/types/http' */ export default class SilentAuthMiddleware { async handle(ctx: HttpContext, next: NextFn) { - await ctx.auth.check() + await ctx.auth.check(); - return next() + return next(); } } diff --git a/portal/bin/console.ts b/portal/bin/console.ts index 23f042f3b..a6a8c569a 100644 --- a/portal/bin/console.ts +++ b/portal/bin/console.ts @@ -11,37 +11,37 @@ | */ -await import('reflect-metadata') -const { Ignitor, prettyPrintError } = await import('@adonisjs/core/ignitor') +await import("reflect-metadata"); +const { Ignitor, prettyPrintError } = await import("@adonisjs/core/ignitor"); /** * URL to the application root. AdonisJS need it to resolve * paths to file and directories for scaffolding commands */ -const APP_ROOT = new URL('../', import.meta.url) +const APP_ROOT = new URL("../", import.meta.url); /** * The importer is used to import files in context of the * application. */ const IMPORTER = (filePath: string) => { - if (filePath.startsWith('./') || filePath.startsWith('../')) { - return import(new URL(filePath, APP_ROOT).href) + if (filePath.startsWith("./") || filePath.startsWith("../")) { + return import(new URL(filePath, APP_ROOT).href); } - return import(filePath) -} + return import(filePath); +}; new Ignitor(APP_ROOT, { importer: IMPORTER }) .tap((app) => { app.booting(async () => { - await import('#start/env') - }) - app.listen('SIGTERM', () => app.terminate()) - app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate()) + await import("#start/env"); + }); + app.listen("SIGTERM", () => app.terminate()); + app.listenIf(app.managedByPm2, "SIGINT", () => app.terminate()); }) .ace() .handle(process.argv.splice(2)) .catch((error) => { - process.exitCode = 1 - prettyPrintError(error) - }) + process.exitCode = 1; + prettyPrintError(error); + }); diff --git a/portal/bin/server.ts b/portal/bin/server.ts index 0556b1ddc..529d06ecf 100644 --- a/portal/bin/server.ts +++ b/portal/bin/server.ts @@ -9,37 +9,37 @@ | */ -await import('reflect-metadata') -const { Ignitor, prettyPrintError } = await import('@adonisjs/core/ignitor') +await import("reflect-metadata"); +const { Ignitor, prettyPrintError } = await import("@adonisjs/core/ignitor"); /** * URL to the application root. AdonisJS need it to resolve * paths to file and directories for scaffolding commands */ -const APP_ROOT = new URL('../', import.meta.url) +const APP_ROOT = new URL("../", import.meta.url); /** * The importer is used to import files in context of the * application. */ const IMPORTER = (filePath: string) => { - if (filePath.startsWith('./') || filePath.startsWith('../')) { - return import(new URL(filePath, APP_ROOT).href) + if (filePath.startsWith("./") || filePath.startsWith("../")) { + return import(new URL(filePath, APP_ROOT).href); } - return import(filePath) -} + return import(filePath); +}; new Ignitor(APP_ROOT, { importer: IMPORTER }) .tap((app) => { app.booting(async () => { - await import('#start/env') - }) - app.listen('SIGTERM', () => app.terminate()) - app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate()) + await import("#start/env"); + }); + app.listen("SIGTERM", () => app.terminate()); + app.listenIf(app.managedByPm2, "SIGINT", () => app.terminate()); }) .httpServer() .start() .catch((error) => { - process.exitCode = 1 - prettyPrintError(error) - }) + process.exitCode = 1; + prettyPrintError(error); + }); diff --git a/portal/bin/test.ts b/portal/bin/test.ts index 3b82dd68f..cb423783a 100644 --- a/portal/bin/test.ts +++ b/portal/bin/test.ts @@ -10,42 +10,42 @@ | */ -process.env.NODE_ENV = 'test' +process.env.NODE_ENV = "test"; -import 'reflect-metadata' -import { Ignitor, prettyPrintError } from '@adonisjs/core/ignitor' -import { configure, processCLIArgs, run } from '@japa/runner' +import "reflect-metadata"; +import { Ignitor, prettyPrintError } from "@adonisjs/core/ignitor"; +import { configure, processCLIArgs, run } from "@japa/runner"; /** * URL to the application root. AdonisJS need it to resolve * paths to file and directories for scaffolding commands */ -const APP_ROOT = new URL('../', import.meta.url) +const APP_ROOT = new URL("../", import.meta.url); /** * The importer is used to import files in context of the * application. */ const IMPORTER = (filePath: string) => { - if (filePath.startsWith('./') || filePath.startsWith('../')) { - return import(new URL(filePath, APP_ROOT).href) + if (filePath.startsWith("./") || filePath.startsWith("../")) { + return import(new URL(filePath, APP_ROOT).href); } - return import(filePath) -} + return import(filePath); +}; new Ignitor(APP_ROOT, { importer: IMPORTER }) .tap((app) => { app.booting(async () => { - await import('#start/env') - }) - app.listen('SIGTERM', () => app.terminate()) - app.listenIf(app.managedByPm2, 'SIGINT', () => app.terminate()) + await import("#start/env"); + }); + app.listen("SIGTERM", () => app.terminate()); + app.listenIf(app.managedByPm2, "SIGINT", () => app.terminate()); }) .testRunner() .configure(async (app) => { - const { runnerHooks, ...config } = await import('../tests/bootstrap.js') + const { runnerHooks, ...config } = await import("../tests/bootstrap.js"); - processCLIArgs(process.argv.splice(2)) + processCLIArgs(process.argv.splice(2)); configure({ ...app.rcFile.tests, ...config, @@ -53,10 +53,10 @@ new Ignitor(APP_ROOT, { importer: IMPORTER }) setup: runnerHooks.setup, teardown: runnerHooks.teardown.concat([() => app.terminate()]), }, - }) + }); }) .run(() => run()) .catch((error) => { - process.exitCode = 1 - prettyPrintError(error) - }) + process.exitCode = 1; + prettyPrintError(error); + }); diff --git a/portal/config/app.ts b/portal/config/app.ts index 4d1880276..1191620a8 100644 --- a/portal/config/app.ts +++ b/portal/config/app.ts @@ -1,5 +1,5 @@ -import app from '@adonisjs/core/services/app' -import { defineConfig } from '@adonisjs/core/http' +import app from "@adonisjs/core/services/app"; +import { defineConfig } from "@adonisjs/core/http"; /** * The configuration settings used by the HTTP server @@ -25,7 +25,7 @@ export const http = defineConfig({ useAsyncLocalStorage: false, router: { - matcher: 'tree', + matcher: "tree", }, /** @@ -50,17 +50,17 @@ export const http = defineConfig({ * Restrict the cookie to a specific domain. * Keep empty to use the current host. */ - domain: '', + domain: "", /** * Restrict the cookie to a URL path. '/' means all routes. */ - path: '/', + path: "/", /** * Default lifetime for cookies managed by the HTTP layer. */ - maxAge: '2h', + maxAge: "2h", /** * Prevent JavaScript access to the cookie in the browser. @@ -75,6 +75,6 @@ export const http = defineConfig({ /** * Cross-site policy for cookie sending. */ - sameSite: 'lax', + sameSite: "lax", }, -}) +}); diff --git a/portal/config/auth.ts b/portal/config/auth.ts index 4318ff6d7..3813c579c 100644 --- a/portal/config/auth.ts +++ b/portal/config/auth.ts @@ -1,12 +1,12 @@ -import { defineConfig } from '@adonisjs/auth' -import { sessionGuard, sessionUserProvider } from '@adonisjs/auth/session' -import type { InferAuthenticators, InferAuthEvents, Authenticators } from '@adonisjs/auth/types' +import { defineConfig } from "@adonisjs/auth"; +import { sessionGuard, sessionUserProvider } from "@adonisjs/auth/session"; +import type { InferAuthenticators, InferAuthEvents, Authenticators } from "@adonisjs/auth/types"; const authConfig = defineConfig({ /** * Default guard used when no guard is explicitly specified. */ - default: 'web', + default: "web", guards: { /** @@ -19,21 +19,21 @@ const authConfig = defineConfig({ useRememberMeTokens: false, provider: sessionUserProvider({ - model: () => import('#backend/features/portalUsers/models/PortalUser'), + model: () => import("#backend/features/portalUsers/models/PortalUser"), }), }), }, -}) +}); -export default authConfig +export default authConfig; /** * Inferring types from the configured auth * guards. */ -declare module '@adonisjs/auth/types' { +declare module "@adonisjs/auth/types" { export interface Authenticators extends InferAuthenticators {} } -declare module '@adonisjs/core/types' { +declare module "@adonisjs/core/types" { interface EventsList extends InferAuthEvents {} } diff --git a/portal/config/bodyparser.ts b/portal/config/bodyparser.ts index 7e836e691..e3d8e469d 100644 --- a/portal/config/bodyparser.ts +++ b/portal/config/bodyparser.ts @@ -1,11 +1,11 @@ -import { defineConfig } from '@adonisjs/core/bodyparser' +import { defineConfig } from "@adonisjs/core/bodyparser"; const bodyParserConfig = defineConfig({ /** * Parse request bodies for these HTTP methods. * Keep this aligned with methods that receive payloads in your routes. */ - allowedMethods: ['POST', 'PUT', 'PATCH', 'DELETE'], + allowedMethods: ["POST", "PUT", "PATCH", "DELETE"], /** * Config for the "application/x-www-form-urlencoded" @@ -20,7 +20,7 @@ const bodyParserConfig = defineConfig({ /** * Content types handled by the form parser. */ - types: ['application/x-www-form-urlencoded'], + types: ["application/x-www-form-urlencoded"], }, /** @@ -35,12 +35,7 @@ const bodyParserConfig = defineConfig({ /** * Content types handled by the JSON parser. */ - types: [ - 'application/json', - 'application/json-patch+json', - 'application/vnd.api+json', - 'application/csp-report', - ], + types: ["application/json", "application/json-patch+json", "application/vnd.api+json", "application/csp-report"], }, /** @@ -66,13 +61,13 @@ const bodyParserConfig = defineConfig({ /** * Maximum accepted payload size for multipart requests. */ - limit: '20mb', + limit: "20mb", /** * Content types handled by the multipart parser. */ - types: ['multipart/form-data'], + types: ["multipart/form-data"], }, -}) +}); -export default bodyParserConfig +export default bodyParserConfig; diff --git a/portal/config/cors.ts b/portal/config/cors.ts index c47fc66e7..40abe38f3 100644 --- a/portal/config/cors.ts +++ b/portal/config/cors.ts @@ -1,5 +1,5 @@ -import app from '@adonisjs/core/services/app' -import { defineConfig } from '@adonisjs/cors' +import app from "@adonisjs/core/services/app"; +import { defineConfig } from "@adonisjs/cors"; /** * Configuration options to tweak the CORS policy. The following @@ -23,7 +23,7 @@ const corsConfig = defineConfig({ /** * HTTP methods accepted for cross-origin requests. */ - methods: ['GET', 'HEAD', 'POST', 'PUT', 'DELETE'], + methods: ["GET", "HEAD", "POST", "PUT", "DELETE"], /** * Reflect request headers by default. Use a string array to restrict @@ -45,6 +45,6 @@ const corsConfig = defineConfig({ * Cache CORS preflight response for N seconds. */ maxAge: 90, -}) +}); -export default corsConfig +export default corsConfig; diff --git a/portal/config/database.ts b/portal/config/database.ts index ffdea34ba..cee7b2225 100644 --- a/portal/config/database.ts +++ b/portal/config/database.ts @@ -1,15 +1,15 @@ -import { rootEnv } from '#start/env' -import { defineConfig } from '@adonisjs/lucid' +import { rootEnv } from "#start/env"; +import { defineConfig } from "@adonisjs/lucid"; const dbConfig = defineConfig({ /** * Default connection used for all queries. */ - connection: 'mysql', + connection: "mysql", connections: { mysql: { - client: 'mysql2', + client: "mysql2", connection: { host: rootEnv.get("DB_HOST", "mysql"), @@ -29,16 +29,16 @@ const dbConfig = defineConfig({ /** * Paths containing migration files. */ - paths: ['database/migrations'], + paths: ["database/migrations"], }, schemaGeneration: { enabled: true, - rulesPaths: ['./database/schemaRules.js'], + rulesPaths: ["./database/schemaRules.js"], excludeTables: ["migrations"], }, }, }, -}) +}); -export default dbConfig +export default dbConfig; diff --git a/portal/config/encryption.ts b/portal/config/encryption.ts index 4e3c993b4..3cd9cc47d 100644 --- a/portal/config/encryption.ts +++ b/portal/config/encryption.ts @@ -1,11 +1,11 @@ -import { rootEnv } from '#start/env' -import { defineConfig, drivers } from '@adonisjs/core/encryption' +import { rootEnv } from "#start/env"; +import { defineConfig, drivers } from "@adonisjs/core/encryption"; const encryptionConfig = defineConfig({ /** * Default encryption driver used by the application. */ - default: 'gcm', + default: "gcm", list: { gcm: drivers.aes256gcm({ @@ -13,22 +13,22 @@ const encryptionConfig = defineConfig({ * Keys used for encryption/decryption. * First key encrypts, all keys are tried for decryption. */ - keys: [rootEnv.get('KEY')], + keys: [rootEnv.get("KEY")], /** * Stable identifier for this driver. */ - id: 'gcm', + id: "gcm", }), }, -}) +}); -export default encryptionConfig +export default encryptionConfig; /** * Inferring types for the list of encryptors you have configured * in your application. */ -declare module '@adonisjs/core/types' { +declare module "@adonisjs/core/types" { export interface EncryptorsList extends InferEncryptors {} } diff --git a/portal/config/hash.ts b/portal/config/hash.ts index a54c08675..87fd78670 100644 --- a/portal/config/hash.ts +++ b/portal/config/hash.ts @@ -1,4 +1,4 @@ -import { defineConfig, drivers } from '@adonisjs/core/hash' +import { defineConfig, drivers } from "@adonisjs/core/hash"; /** * Hashing configuration. @@ -10,7 +10,7 @@ const hashConfig = defineConfig({ /** * Default hasher used by the application. */ - default: 'scrypt', + default: "scrypt", list: { /** @@ -62,14 +62,14 @@ const hashConfig = defineConfig({ maxMemory: 33554432, }), }, -}) +}); -export default hashConfig +export default hashConfig; /** * Inferring types for the list of hashers you have configured * in your application. */ -declare module '@adonisjs/core/types' { +declare module "@adonisjs/core/types" { export interface HashersList extends InferHashers {} } diff --git a/portal/config/inertia.ts b/portal/config/inertia.ts index 0eaaf9921..c4f91fef6 100644 --- a/portal/config/inertia.ts +++ b/portal/config/inertia.ts @@ -1,4 +1,4 @@ -import { defineConfig } from '@adonisjs/inertia' +import { defineConfig } from "@adonisjs/inertia"; const inertiaConfig = defineConfig({ /** @@ -13,8 +13,8 @@ const inertiaConfig = defineConfig({ /** * Entry file used by the SSR server build. */ - entrypoint: 'inertia/ssr.ts', + entrypoint: "inertia/ssr.ts", }, -}) +}); -export default inertiaConfig +export default inertiaConfig; diff --git a/portal/config/logger.ts b/portal/config/logger.ts index 778302b6f..edd3b8ecd 100644 --- a/portal/config/logger.ts +++ b/portal/config/logger.ts @@ -1,12 +1,12 @@ -import { portalEnv } from '#start/env' -import app from '@adonisjs/core/services/app' -import { defineConfig, targets } from '@adonisjs/core/logger' +import { portalEnv } from "#start/env"; +import app from "@adonisjs/core/services/app"; +import { defineConfig, targets } from "@adonisjs/core/logger"; const loggerConfig = defineConfig({ /** * Default logger name used by ctx.logger and app logger calls. */ - default: 'app', + default: "app", loggers: { app: { @@ -23,7 +23,7 @@ const loggerConfig = defineConfig({ /** * Minimum level to output (trace, debug, info, warn, error, fatal). */ - level: portalEnv.get('LOG_LEVEL', "info"), + level: portalEnv.get("LOG_LEVEL", "info"), /** * Configure where logs are written. @@ -37,14 +37,14 @@ const loggerConfig = defineConfig({ }, }, }, -}) +}); -export default loggerConfig +export default loggerConfig; /** * Inferring types for the list of loggers you have configured * in your application. */ -declare module '@adonisjs/core/types' { +declare module "@adonisjs/core/types" { export interface LoggersList extends InferLoggers {} } diff --git a/portal/config/redis.ts b/portal/config/redis.ts index 331bf585c..7e8cbdf50 100644 --- a/portal/config/redis.ts +++ b/portal/config/redis.ts @@ -1,28 +1,26 @@ -import { rootEnv } from '#start/env' -import { defineConfig } from '@adonisjs/redis' -import type { InferConnections } from '@adonisjs/redis/types' +import { rootEnv } from "#start/env"; +import { defineConfig } from "@adonisjs/redis"; +import type { InferConnections } from "@adonisjs/redis/types"; const url = new URL(rootEnv.get("REDIS_URL", "redis://redis:6379")); const redisConfig = defineConfig({ - connection: 'main', + connection: "main", connections: { main: { host: url.hostname, port: url.port ? Number(url.port) : 6379, username: decodeURIComponent(url.username), password: decodeURIComponent(url.password), - db: url.pathname !== '/' && url.pathname - ? Number(url.pathname.slice(1)) - : 0, - ...(url.protocol === 'rediss:' ? { tls: {} } : {}), + db: url.pathname !== "/" && url.pathname ? Number(url.pathname.slice(1)) : 0, + ...(url.protocol === "rediss:" ? { tls: {} } : {}), keyPrefix: "portal:", }, }, -}) +}); -export default redisConfig +export default redisConfig; -declare module '@adonisjs/redis/types' { +declare module "@adonisjs/redis/types" { interface RedisConnections extends InferConnections {} } diff --git a/portal/config/session.ts b/portal/config/session.ts index ffd3f6f59..3aafc69a0 100644 --- a/portal/config/session.ts +++ b/portal/config/session.ts @@ -1,5 +1,5 @@ -import { portalEnv } from '#start/env' -import { defineConfig, stores } from '@adonisjs/session' +import { portalEnv } from "#start/env"; +import { defineConfig, stores } from "@adonisjs/session"; const sessionConfig = defineConfig({ /** @@ -10,7 +10,7 @@ const sessionConfig = defineConfig({ /** * Cookie name storing the session identifier. */ - cookieName: 'portalSession', + cookieName: "portalSession", /** * When set to true, the session id cookie will be deleted @@ -22,7 +22,7 @@ const sessionConfig = defineConfig({ * Define how long to keep the session data alive without * any activity. */ - age: '2h', + age: "2h", /** * Configuration for session cookie and the @@ -32,7 +32,7 @@ const sessionConfig = defineConfig({ /** * Restrict the cookie to a URL path. '/' means all routes. */ - path: '/', + path: "/", /** * Prevent JavaScript access to the cookie in the browser. @@ -47,7 +47,7 @@ const sessionConfig = defineConfig({ /** * Cross-site policy for cookie sending. */ - sameSite: 'strict', + sameSite: "strict", }, /** @@ -55,7 +55,7 @@ const sessionConfig = defineConfig({ * variable in order to infer the store name without any * errors. */ - store: portalEnv.get('SESSION_DRIVER', "redis"), + store: portalEnv.get("SESSION_DRIVER", "redis"), /** * List of configured stores. Refer documentation to see @@ -63,9 +63,9 @@ const sessionConfig = defineConfig({ */ stores: { redis: stores.redis({ - connection: "main" + connection: "main", }), }, -}) +}); -export default sessionConfig +export default sessionConfig; diff --git a/portal/config/shield.ts b/portal/config/shield.ts index 37067c673..3d30d92cd 100644 --- a/portal/config/shield.ts +++ b/portal/config/shield.ts @@ -1,4 +1,4 @@ -import { defineConfig } from '@adonisjs/shield' +import { defineConfig } from "@adonisjs/shield"; const shieldConfig = defineConfig({ /** @@ -46,7 +46,7 @@ const shieldConfig = defineConfig({ /** * HTTP methods protected by CSRF validation. */ - methods: ['POST', 'PUT', 'PATCH', 'DELETE'], + methods: ["POST", "PUT", "PATCH", "DELETE"], }, /** @@ -62,7 +62,7 @@ const shieldConfig = defineConfig({ /** * Block all framing attempts. Default value is DENY. */ - action: 'DENY', + action: "DENY", }, /** @@ -77,7 +77,7 @@ const shieldConfig = defineConfig({ /** * HSTS policy duration remembered by browsers. */ - maxAge: '180 days', + maxAge: "180 days", }, /** @@ -90,6 +90,6 @@ const shieldConfig = defineConfig({ */ enabled: true, }, -}) +}); -export default shieldConfig +export default shieldConfig; diff --git a/portal/config/static.ts b/portal/config/static.ts index ad1e27d03..5fd46835c 100644 --- a/portal/config/static.ts +++ b/portal/config/static.ts @@ -1,4 +1,4 @@ -import { defineConfig } from '@adonisjs/static' +import { defineConfig } from "@adonisjs/static"; /** * Configuration options to tweak the static files middleware. @@ -26,7 +26,7 @@ const staticServerConfig = defineConfig({ /** * Policy for files starting with a dot. */ - dotFiles: 'ignore', -}) + dotFiles: "ignore", +}); -export default staticServerConfig +export default staticServerConfig; diff --git a/portal/config/vite.ts b/portal/config/vite.ts index 1e0f4db60..62ea2fbd1 100644 --- a/portal/config/vite.ts +++ b/portal/config/vite.ts @@ -1,4 +1,4 @@ -import { defineConfig } from '@adonisjs/vite' +import { defineConfig } from "@adonisjs/vite"; const viteBackendConfig = defineConfig({ /** @@ -6,19 +6,19 @@ const viteBackendConfig = defineConfig({ * directory. The path should be relative from * the application root. */ - buildDirectory: 'public/assets', + buildDirectory: "public/assets", /** * The path to the manifest file generated by the * "vite build" command. */ - manifestFile: 'public/assets/.vite/manifest.json', + manifestFile: "public/assets/.vite/manifest.json", /** * Feel free to change the value of the "assetsUrl" to * point to a CDN in production. */ - assetsUrl: '/assets', + assetsUrl: "/assets", /** * HTML attributes added to generated script tags. @@ -29,6 +29,6 @@ const viteBackendConfig = defineConfig({ */ defer: true, }, -}) +}); -export default viteBackendConfig +export default viteBackendConfig; diff --git a/portal/hooks/indexInertiaPages.ts b/portal/hooks/indexInertiaPages.ts index 6a346ea9e..4a51a2e6a 100644 --- a/portal/hooks/indexInertiaPages.ts +++ b/portal/hooks/indexInertiaPages.ts @@ -1,18 +1,18 @@ -import { hooks } from '@adonisjs/core/app' +import { hooks } from "@adonisjs/core/app"; /** * Custom hook to load inertia pages from feature folders, e.g. `features/docs/pages/DocsIndex.vue` */ export default hooks.init((_parent, _manager, generator) => { - generator.add('inertiaPages', { - source: './inertia', - glob: ['**/pages/*.vue'], - output: './.adonisjs/server/pages.d.ts', + generator.add("inertiaPages", { + source: "./inertia", + glob: ["**/pages/*.vue"], + output: "./.adonisjs/server/pages.d.ts", as(vfs, buffer, _config, helpers) { - const pages = vfs.asList() + const pages = vfs.asList(); - buffer.writeLine(`import '@adonisjs/inertia/types'`) + buffer.writeLine(`import '@adonisjs/inertia/types'`); buffer.writeLine(` import type { VNodeProps, @@ -24,24 +24,18 @@ export default hooks.init((_parent, _manager, generator) => { ComponentInstance['$props'], keyof VNodeProps | keyof AllowedComponentProps > - `) + `); - buffer.writeLine( - `declare module '@adonisjs/inertia/types' {` - ).indent() + buffer.writeLine(`declare module '@adonisjs/inertia/types' {`).indent(); - buffer.writeLine( - `export interface InertiaPages {` - ).indent() + buffer.writeLine(`export interface InertiaPages {`).indent(); for (const [name, file] of Object.entries(pages)) { - buffer.writeLine( - `'${name}': ExtractProps<(typeof import('${helpers.toImportPath(file)}'))['default']>` - ) + buffer.writeLine(`'${name}': ExtractProps<(typeof import('${helpers.toImportPath(file)}'))['default']>`); } - buffer.dedent().writeLine('}') - buffer.dedent().writeLine('}') + buffer.dedent().writeLine("}"); + buffer.dedent().writeLine("}"); }, - }) -}) + }); +}); diff --git a/portal/inertia/app.ts b/portal/inertia/app.ts index c132d3d7c..1bca51dd5 100644 --- a/portal/inertia/app.ts +++ b/portal/inertia/app.ts @@ -1,26 +1,23 @@ -import 'vue-sonner/style.css' -import { client } from '#frontend/client.js' -import { createInertiaApp } from '@inertiajs/vue3' -import { TuyauProvider } from '@adonisjs/inertia/vue' -import { createApp, type DefineComponent, h } from 'vue' -import { resolvePageComponent } from '@adonisjs/inertia/helpers' +import "vue-sonner/style.css"; +import { client } from "#frontend/client.js"; +import { createInertiaApp } from "@inertiajs/vue3"; +import { TuyauProvider } from "@adonisjs/inertia/vue"; +import { createApp, type DefineComponent, h } from "vue"; +import { resolvePageComponent } from "@adonisjs/inertia/helpers"; -const appName = import.meta.env.VITE_APP_NAME || 'AdonisJS' +const appName = import.meta.env.VITE_APP_NAME || "AdonisJS"; createInertiaApp({ title: (title) => (title ? `${title} - ${appName}` : appName), resolve: (name) => { - return resolvePageComponent( - `./${name}.vue`, - import.meta.glob('./**/pages/*.vue') - ) + return resolvePageComponent(`./${name}.vue`, import.meta.glob("./**/pages/*.vue")); }, setup({ el, App, props, plugin }) { createApp({ render: () => h(TuyauProvider, { client }, { default: () => h(App, props) }) }) .use(plugin) - .mount(el) + .mount(el); }, progress: { - color: '#4B5563', + color: "#4B5563", }, -}) +}); diff --git a/portal/inertia/client.ts b/portal/inertia/client.ts index 174e57eec..fdc500f34 100644 --- a/portal/inertia/client.ts +++ b/portal/inertia/client.ts @@ -1,9 +1,9 @@ -import { registry } from '#client/registry/index.js' -import { createTuyau } from '@tuyau/core/client' +import { registry } from "#client/registry/index.js"; +import { createTuyau } from "@tuyau/core/client"; export const client = createTuyau({ - baseUrl: '/', + baseUrl: "/", registry, -}) +}); -export const urlFor = client.urlFor +export const urlFor = client.urlFor; diff --git a/portal/inertia/features/errors/pages/NotFound.vue b/portal/inertia/features/errors/pages/NotFound.vue index 5364c9fcd..7d76ee3d0 100644 --- a/portal/inertia/features/errors/pages/NotFound.vue +++ b/portal/inertia/features/errors/pages/NotFound.vue @@ -1,3 +1 @@ - + diff --git a/portal/inertia/features/errors/pages/ServerError.vue b/portal/inertia/features/errors/pages/ServerError.vue index c3b388d13..745263567 100644 --- a/portal/inertia/features/errors/pages/ServerError.vue +++ b/portal/inertia/features/errors/pages/ServerError.vue @@ -1,3 +1 @@ - + diff --git a/portal/inertia/features/splash/pages/SplashIndex.vue b/portal/inertia/features/splash/pages/SplashIndex.vue index 904b442f9..38f1976a0 100644 --- a/portal/inertia/features/splash/pages/SplashIndex.vue +++ b/portal/inertia/features/splash/pages/SplashIndex.vue @@ -1,6 +1,4 @@ - + diff --git a/portal/inertia/shims.ts b/portal/inertia/shims.ts index 95cd7fc99..525d5f827 100644 --- a/portal/inertia/shims.ts +++ b/portal/inertia/shims.ts @@ -1,5 +1,5 @@ -declare module '*.vue' { - import type { DefineComponent } from 'vue' - const component: DefineComponent - export default component +declare module "*.vue" { + import type { DefineComponent } from "vue"; + const component: DefineComponent; + export default component; } diff --git a/portal/inertia/ssr.ts b/portal/inertia/ssr.ts index 2f2c0a163..6738be7d3 100644 --- a/portal/inertia/ssr.ts +++ b/portal/inertia/ssr.ts @@ -1,24 +1,24 @@ -import { client } from '#frontend/client.js' -import { createInertiaApp } from '@inertiajs/vue3' -import { TuyauProvider } from '@adonisjs/inertia/vue' -import { renderToString } from '@vue/server-renderer' -import { createSSRApp, h, type DefineComponent } from 'vue' -import { resolvePageComponent } from '@adonisjs/inertia/helpers' +import { client } from "#frontend/client.js"; +import { createInertiaApp } from "@inertiajs/vue3"; +import { TuyauProvider } from "@adonisjs/inertia/vue"; +import { renderToString } from "@vue/server-renderer"; +import { createSSRApp, h, type DefineComponent } from "vue"; +import { resolvePageComponent } from "@adonisjs/inertia/helpers"; export default function render(page: any) { return createInertiaApp({ page, render: renderToString, resolve: (name) => { - return resolvePageComponent( - `./${name}.vue`, - import.meta.glob('./**/pages/*.vue', { eager: true }) - ) + return resolvePageComponent( + `./${name}.vue`, + import.meta.glob("./**/pages/*.vue", { eager: true }), + ); }, setup: ({ App, props, plugin }) => { return createSSRApp({ render: () => h(TuyauProvider, { client }, { default: () => h(App, props) }), - }).use(plugin) + }).use(plugin); }, - }) + }); } diff --git a/portal/inertia/types.ts b/portal/inertia/types.ts index 689107761..1c00c1184 100644 --- a/portal/inertia/types.ts +++ b/portal/inertia/types.ts @@ -1,4 +1,4 @@ -import type { Data } from '#client/data.d.ts' +import type { Data } from "#client/data.d.ts"; /** * Bridge the shared props and flash data inferred from the Inertia @@ -6,9 +6,9 @@ import type { Data } from '#client/data.d.ts' * and layout callbacks are typed globally without passing a generic at each * call site. */ -declare module '@inertiajs/core' { +declare module "@inertiajs/core" { interface InertiaConfig { - sharedPageProps: Data.SharedProps - flashDataType: Data.FlashMessages + sharedPageProps: Data.SharedProps; + flashDataType: Data.FlashMessages; } } diff --git a/portal/providers/apiProvider.ts b/portal/providers/apiProvider.ts index 8e4e00cd9..08c7e7002 100644 --- a/portal/providers/apiProvider.ts +++ b/portal/providers/apiProvider.ts @@ -1,6 +1,6 @@ -import { HttpContext } from '@adonisjs/core/http' -import { BaseSerializer } from '@adonisjs/core/transformers' -import { type SimplePaginatorMetaKeys } from '@adonisjs/lucid/types/querybuilder' +import { HttpContext } from "@adonisjs/core/http"; +import { BaseSerializer } from "@adonisjs/core/transformers"; +import { type SimplePaginatorMetaKeys } from "@adonisjs/lucid/types/querybuilder"; /** * Custom serializer for API responses that ensures consistent JSON structure @@ -8,14 +8,14 @@ import { type SimplePaginatorMetaKeys } from '@adonisjs/lucid/types/querybuilder * pagination metadata for Lucid ORM query results. */ class ApiSerializer extends BaseSerializer<{ - Wrap: 'data' - PaginationMetaData: SimplePaginatorMetaKeys + Wrap: "data"; + PaginationMetaData: SimplePaginatorMetaKeys; }> { /** * Wraps all serialized data under this key in the response object. * Example: { data: [...] } instead of returning raw arrays/objects */ - wrap: 'data' = 'data' + wrap: "data" = "data"; /** * Validates and defines pagination metadata structure for paginated responses. @@ -25,45 +25,40 @@ class ApiSerializer extends BaseSerializer<{ */ definePaginationMetaData(metaData: unknown): SimplePaginatorMetaKeys { if (!this.isLucidPaginatorMetaData(metaData)) { - throw new Error( - 'Invalid pagination metadata. Expected metadata to contain Lucid pagination keys' - ) + throw new Error("Invalid pagination metadata. Expected metadata to contain Lucid pagination keys"); } - return metaData + return metaData; } } /** * Single instance of ApiSerializer used across the application */ -const serializer = new ApiSerializer() +const serializer = new ApiSerializer(); const serialize = Object.assign( - function (this: HttpContext, ...[data, resolver]: Parameters) { - return serializer.serialize(data, resolver ?? this.containerResolver) + function (this: HttpContext, ...[data, resolver]: Parameters) { + return serializer.serialize(data, resolver ?? this.containerResolver); }, { - withoutWrapping( - this: HttpContext, - ...[data, resolver]: Parameters - ) { - return serializer.serializeWithoutWrapping(data, resolver ?? this.containerResolver) + withoutWrapping(this: HttpContext, ...[data, resolver]: Parameters) { + return serializer.serializeWithoutWrapping(data, resolver ?? this.containerResolver); }, - } -) as ApiSerializer['serialize'] & { withoutWrapping: ApiSerializer['serializeWithoutWrapping'] } + }, +) as ApiSerializer["serialize"] & { withoutWrapping: ApiSerializer["serializeWithoutWrapping"] }; /** * Adds the serialize method to all HttpContext instances. * Usage in controllers: return ctx.serialize(data) * This ensures all API responses follow the same structure with data wrapping. */ -HttpContext.instanceProperty('serialize', serialize) +HttpContext.instanceProperty("serialize", serialize); /** * Module augmentation to add the serialize method to HttpContext. * This allows controllers to use ctx.serialize() for consistent API responses. */ -declare module '@adonisjs/core/http' { +declare module "@adonisjs/core/http" { export interface HttpContext { - serialize: typeof serialize + serialize: typeof serialize; } } diff --git a/portal/start/env.ts b/portal/start/env.ts index 9677c90c8..628b12a86 100644 --- a/portal/start/env.ts +++ b/portal/start/env.ts @@ -9,9 +9,9 @@ | */ -import { Env } from '@adonisjs/core/env' +import { Env } from "@adonisjs/core/env"; -export const rootEnv = await Env.create(new URL('../../', import.meta.url), { +export const rootEnv = await Env.create(new URL("../../", import.meta.url), { KEY: Env.schema.string(), DB_HOST: Env.schema.string.optional(), DB_PORT: Env.schema.number.optional(), diff --git a/portal/start/kernel.ts b/portal/start/kernel.ts index 2a7925ab2..aea0ec483 100644 --- a/portal/start/kernel.ts +++ b/portal/start/kernel.ts @@ -8,28 +8,28 @@ | */ -import router from '@adonisjs/core/services/router' -import server from '@adonisjs/core/services/server' +import router from "@adonisjs/core/services/router"; +import server from "@adonisjs/core/services/server"; -server.errorHandler(() => import('#backend/exceptions/handler')) +server.errorHandler(() => import("#backend/exceptions/handler")); server.use([ - () => import('#backend/middleware/containerBindingsMiddleware'), - () => import('@adonisjs/static/static_middleware'), - () => import('@adonisjs/cors/cors_middleware'), - () => import('@adonisjs/vite/vite_middleware'), - () => import('#backend/middleware/inertiaMiddleware'), -]) + () => import("#backend/middleware/containerBindingsMiddleware"), + () => import("@adonisjs/static/static_middleware"), + () => import("@adonisjs/cors/cors_middleware"), + () => import("@adonisjs/vite/vite_middleware"), + () => import("#backend/middleware/inertiaMiddleware"), +]); router.use([ - () => import('@adonisjs/core/bodyparser_middleware'), - () => import('@adonisjs/session/session_middleware'), - () => import('@adonisjs/shield/shield_middleware'), - () => import('@adonisjs/auth/initialize_auth_middleware'), - () => import('#backend/middleware/silentAuthMiddleware'), -]) + () => import("@adonisjs/core/bodyparser_middleware"), + () => import("@adonisjs/session/session_middleware"), + () => import("@adonisjs/shield/shield_middleware"), + () => import("@adonisjs/auth/initialize_auth_middleware"), + () => import("#backend/middleware/silentAuthMiddleware"), +]); export const middleware = router.named({ - guest: () => import('#backend/middleware/guestMiddleware'), - auth: () => import('#backend/middleware/authMiddleware'), -}) + guest: () => import("#backend/middleware/guestMiddleware"), + auth: () => import("#backend/middleware/authMiddleware"), +}); diff --git a/portal/start/routes.ts b/portal/start/routes.ts index e6b55d7d8..4156a2ce4 100644 --- a/portal/start/routes.ts +++ b/portal/start/routes.ts @@ -8,8 +8,8 @@ */ // import { middleware } from '#start/kernel' -import { controllers } from '#generated/controllers' -import router from '@adonisjs/core/services/router' +import { controllers } from "#generated/controllers"; +import router from "@adonisjs/core/services/router"; router.get("/", [controllers.splash.Splash, "getIndex"]); diff --git a/portal/start/validator.ts b/portal/start/validator.ts index 6a2ca7dde..050cac257 100644 --- a/portal/start/validator.ts +++ b/portal/start/validator.ts @@ -11,13 +11,13 @@ | */ -import { DateTime } from 'luxon' -import { VineDate } from '@vinejs/vine' +import { DateTime } from "luxon"; +import { VineDate } from "@vinejs/vine"; -declare module '@vinejs/vine/types' { +declare module "@vinejs/vine/types" { interface VineGlobalTransforms { - date: DateTime + date: DateTime; } } -VineDate.transform((value) => DateTime.fromJSDate(value)) +VineDate.transform((value) => DateTime.fromJSDate(value)); diff --git a/portal/tests/bootstrap.ts b/portal/tests/bootstrap.ts index 2484bbbd0..d863cfb20 100644 --- a/portal/tests/bootstrap.ts +++ b/portal/tests/bootstrap.ts @@ -1,9 +1,9 @@ -import { assert } from '@japa/assert' -import app from '@adonisjs/core/services/app' -import type { Config } from '@japa/runner/types' -import { pluginAdonisJS } from '@japa/plugin-adonisjs' -import { dbAssertions } from '@adonisjs/lucid/plugins/db' -import testUtils from '@adonisjs/core/services/test_utils' +import { assert } from "@japa/assert"; +import app from "@adonisjs/core/services/app"; +import type { Config } from "@japa/runner/types"; +import { pluginAdonisJS } from "@japa/plugin-adonisjs"; +import { dbAssertions } from "@adonisjs/lucid/plugins/db"; +import testUtils from "@adonisjs/core/services/test_utils"; /** * This file is imported by the "bin/test.ts" entrypoint file @@ -13,7 +13,7 @@ import testUtils from '@adonisjs/core/services/test_utils' * Configure Japa plugins in the plugins array. * Learn more - https://japa.dev/docs/runner-config#plugins-optional */ -export const plugins: Config['plugins'] = [assert(), pluginAdonisJS(app), dbAssertions(app)] +export const plugins: Config["plugins"] = [assert(), pluginAdonisJS(app), dbAssertions(app)]; /** * Configure lifecycle function to run before and after all the @@ -22,17 +22,17 @@ export const plugins: Config['plugins'] = [assert(), pluginAdonisJS(app), dbAsse * The setup functions are executed before all the tests * The teardown functions are executed after all the tests */ -export const runnerHooks: Required> = { +export const runnerHooks: Required> = { setup: [], teardown: [], -} +}; /** * Configure suites by tapping into the test suite instance. * Learn more - https://japa.dev/docs/test-suites#lifecycle-hooks */ -export const configureSuite: Config['configureSuite'] = (suite) => { - if (['browser', 'functional', 'e2e'].includes(suite.name)) { - return suite.setup(() => testUtils.httpServer().start()) +export const configureSuite: Config["configureSuite"] = (suite) => { + if (["browser", "functional", "e2e"].includes(suite.name)) { + return suite.setup(() => testUtils.httpServer().start()); } -} +}; diff --git a/portal/vite.config.ts b/portal/vite.config.ts index cea410f39..8d5a9a119 100644 --- a/portal/vite.config.ts +++ b/portal/vite.config.ts @@ -1,23 +1,21 @@ -import { defineConfig } from 'vite' -import vue from '@vitejs/plugin-vue' -import adonisjs from '@adonisjs/vite/client' -import { rootEnv } from '#start/env' +import { defineConfig } from "vite"; +import vue from "@vitejs/plugin-vue"; +import adonisjs from "@adonisjs/vite/client"; +import { rootEnv } from "#start/env"; -const allowedHosts = rootEnv.get("DEVELOPMENT_VITE_ALLOWED_HOSTS", "") +const allowedHosts = rootEnv + .get("DEVELOPMENT_VITE_ALLOWED_HOSTS", "") .split(",") .map((v) => v.trim()) .filter(Boolean); export default defineConfig({ - plugins: [ - vue(), - adonisjs({ entryPoints: ['inertia/app.ts'], reload: ['resources/views/**/*.edge'] }), - ], + plugins: [vue(), adonisjs({ entryPoints: ["inertia/app.ts"], reload: ["resources/views/**/*.edge"] })], server: { watch: { - ignored: ['**/storage/**', '**/tmp/**'], + ignored: ["**/storage/**", "**/tmp/**"], }, allowedHosts, }, -}) +}); From ab9252568583ee0442f255670171899c25c97e15 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:24:29 +0000 Subject: [PATCH 03/39] portal: create portal_users table --- .../1792935256055-CreatePortalUsersTable.ts | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 backend/src/migrations/1792935256055-CreatePortalUsersTable.ts diff --git a/backend/src/migrations/1792935256055-CreatePortalUsersTable.ts b/backend/src/migrations/1792935256055-CreatePortalUsersTable.ts new file mode 100644 index 000000000..e33648a03 --- /dev/null +++ b/backend/src/migrations/1792935256055-CreatePortalUsersTable.ts @@ -0,0 +1,54 @@ +import { MigrationInterface, QueryRunner, Table } from "typeorm"; + +export class CreatePortalUsersTable1792935256055 implements MigrationInterface { + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.createTable( + new Table({ + name: "portal_users", + columns: [ + { + name: "id", + type: "int", + isPrimary: true, + isGenerated: true, + generationStrategy: "increment", + }, + { + name: "user_id", + type: "bigint", + }, + { + name: "username", + type: "varchar", + length: "255", + }, + { + name: "avatar", + type: "varchar", + length: "255", + isNullable: true, + }, + { + name: "last_login_at", + type: "datetime", + }, + { + name: "created_at", + type: "datetime", + default: "CURRENT_TIMESTAMP", + }, + ], + indices: [ + { + columnNames: ["user_id"], + isUnique: true, + }, + ], + }), + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.dropTable("portal_users"); + } +} From f294079e9315e696ccc1894310b29d032a057059 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:24:53 +0000 Subject: [PATCH 04/39] portal: fix lucid schema rules for bigints --- portal/config/database.ts | 3 +++ portal/database/schemaRules.ts | 41 ++++++++++++++++++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/portal/config/database.ts b/portal/config/database.ts index cee7b2225..80714a0b3 100644 --- a/portal/config/database.ts +++ b/portal/config/database.ts @@ -18,6 +18,9 @@ const dbConfig = defineConfig({ password: rootEnv.get("DB_PASSWORD", rootEnv.get("DEVELOPMENT_MYSQL_PASSWORD", "")), database: rootEnv.get("DB_DATABASE", "zeppelin"), timezone: "Z", + supportBigNumbers: true, + bigNumberStrings: true, + charset: "utf8mb4", }, migrations: { diff --git a/portal/database/schemaRules.ts b/portal/database/schemaRules.ts index 1153c9244..1f5a1fa68 100644 --- a/portal/database/schemaRules.ts +++ b/portal/database/schemaRules.ts @@ -1,3 +1,40 @@ -import { type SchemaRules } from '@adonisjs/lucid/types/schema_generator' +import { ColumnInfo, DatabaseColumn, type SchemaRules } from "@adonisjs/lucid/types/schema_generator"; -export default {} satisfies SchemaRules +export default { + types: { + // We have supportBigNumbers + bigNumberStrings enabled in database.ts, so use "string" for bigints + // Note: Does not work for primary keys (Lucid's primary key rules override this). See separate primaryKey rule below. + bigint: { + tsType: "string", + decorators: [{ name: "@column" }], + }, + }, + + // Override Lucid's primary key rule so bigints are correctly typed as "string" with supportBigNumbers + bigNumberStrings + primaryKey: (_tableName: string, primaryKeys: string[], columns: Record) => { + const columnName = primaryKeys[0]; + if (!columnName || !columns[columnName]) { + return undefined; + } + + const column = columns[columnName]; + let tsType: string; + if (/^bigint\b/.test(column.type)) { + tsType = "string"; + } else if (/^(tinyint|smallint|mediumint|int|integer)\b/.test(column.type)) { + tsType = "number"; + } else if (/^(char|varchar|uuid)\b/.test(column.type)) { + tsType = "string"; + } else { + throw new Error(`Unsupported primary key type: ${column.type}`); + } + + return { + columnName, + columnInfo: { + tsType, + decorators: [{ name: "@column", args: { isPrimary: true } }], + }, + }; + }, +} satisfies SchemaRules; From bcd9efae83b6e6743b0197f6ac20b864fcd38c03 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:25:29 +0000 Subject: [PATCH 05/39] portal: generate full db schema types --- .../features/portalUsers/models/PortalUser.ts | 21 +- portal/database/schema.ts | 770 +++++++++++++++++- portal/package.json | 1 + 3 files changed, 762 insertions(+), 30 deletions(-) diff --git a/portal/app/features/portalUsers/models/PortalUser.ts b/portal/app/features/portalUsers/models/PortalUser.ts index f218e4e5e..3b09fa263 100644 --- a/portal/app/features/portalUsers/models/PortalUser.ts +++ b/portal/app/features/portalUsers/models/PortalUser.ts @@ -1,22 +1,7 @@ -import { BaseModel, column } from "@adonisjs/lucid/orm"; +import { PortalUserSchema } from "#database/schema"; -export class PortalUser extends BaseModel { +export class PortalUser extends PortalUserSchema { static table = "portal_users"; - - @column({ isPrimary: true }) - declare id: number; - - @column() - declare user_id: number; - - @column() - declare username: string; - - @column() - declare avatar: string; - - @column() - declare created_at: string; } -export default PortalUser +export default PortalUser; diff --git a/portal/database/schema.ts b/portal/database/schema.ts index b99c87b33..1493149c3 100644 --- a/portal/database/schema.ts +++ b/portal/database/schema.ts @@ -4,22 +4,768 @@ * Run "node ace migration:run" command to re-generate this file */ -import { BaseModel, column } from '@adonisjs/lucid/orm' -import { DateTime } from 'luxon' +import { BaseModel, column } from "@adonisjs/lucid/orm"; +import { DateTime } from "luxon"; -export class UserSchema extends BaseModel { - static $columns = ['createdAt', 'email', 'fullName', 'id', 'password', 'updatedAt'] as const - $columns = UserSchema.$columns +export class AllowedGuildSchema extends BaseModel { + static $columns = ["createdAt", "icon", "id", "name", "ownerId", "updatedAt"] as const; + $columns = AllowedGuildSchema.$columns; @column.dateTime({ autoCreate: true }) - declare createdAt: DateTime + declare createdAt: DateTime; @column() - declare email: string + declare icon: string | null; + @column({ isPrimary: true }) + declare id: string; + @column() + declare name: string; + @column() + declare ownerId: string; + @column.dateTime({ autoCreate: true, autoUpdate: true }) + declare updatedAt: DateTime; +} + +export class AntiraidLevelSchema extends BaseModel { + static $columns = ["guildId", "level"] as const; + $columns = AntiraidLevelSchema.$columns; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare level: string; +} + +export class ApiAuditLogSchema extends BaseModel { + static $columns = ["authorId", "createdAt", "eventData", "eventType", "guildId", "id"] as const; + $columns = ApiAuditLogSchema.$columns; + @column() + declare authorId: string; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column() + declare eventData: string; + @column() + declare eventType: string; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; +} + +export class ApiLoginSchema extends BaseModel { + static $columns = ["expiresAt", "id", "loggedInAt", "token", "userId"] as const; + $columns = ApiLoginSchema.$columns; + @column.dateTime() + declare expiresAt: DateTime; + @column({ isPrimary: true }) + declare id: string; + @column.dateTime() + declare loggedInAt: DateTime; @column() - declare fullName: string | null + declare token: string; + @column() + declare userId: string; +} + +export class ApiPermissionSchema extends BaseModel { + static $columns = ["expiresAt", "guildId", "permissions", "targetId", "type"] as const; + $columns = ApiPermissionSchema.$columns; + @column.dateTime() + declare expiresAt: DateTime | null; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare permissions: string; + @column() + declare targetId: string; + @column() + declare type: string; +} + +export class ApiUserInfoSchema extends BaseModel { + static $columns = ["data", "id", "updatedAt"] as const; + $columns = ApiUserInfoSchema.$columns; + @column() + declare data: string; @column({ isPrimary: true }) - declare id: number - @column({ serializeAs: null }) - declare password: string + declare id: string; @column.dateTime({ autoCreate: true, autoUpdate: true }) - declare updatedAt: DateTime | null + declare updatedAt: DateTime; +} + +export class ArchiveSchema extends BaseModel { + static $columns = ["body", "createdAt", "expiresAt", "guildId", "id"] as const; + $columns = ArchiveSchema.$columns; + @column() + declare body: string; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column.dateTime() + declare expiresAt: DateTime | null; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: string; +} + +export class AutoReactionSchema extends BaseModel { + static $columns = ["channelId", "guildId", "reactions"] as const; + $columns = AutoReactionSchema.$columns; + @column() + declare channelId: string; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare reactions: string; +} + +export class CaseNoteSchema extends BaseModel { + static $columns = ["body", "caseId", "createdAt", "id", "modId", "modName"] as const; + $columns = CaseNoteSchema.$columns; + @column() + declare body: string; + @column() + declare caseId: number; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column({ isPrimary: true }) + declare id: number; + @column() + declare modId: string | null; + @column() + declare modName: string | null; +} + +export class CaseSchema extends BaseModel { + static $columns = [ + "auditLogId", + "caseNumber", + "createdAt", + "guildId", + "id", + "isHidden", + "logMessageId", + "modId", + "modName", + "ppId", + "ppName", + "type", + "userId", + "userName", + ] as const; + $columns = CaseSchema.$columns; + @column() + declare auditLogId: string | null; + @column() + declare caseNumber: number; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare isHidden: boolean; + @column() + declare logMessageId: string | null; + @column() + declare modId: string | null; + @column() + declare modName: string | null; + @column() + declare ppId: string | null; + @column() + declare ppName: string | null; + @column() + declare type: number; + @column() + declare userId: string; + @column() + declare userName: string; +} + +export class ConfigSchema extends BaseModel { + static $columns = ["config", "editedAt", "editedBy", "id", "isActive", "key"] as const; + $columns = ConfigSchema.$columns; + @column() + declare config: string; + @column.dateTime() + declare editedAt: DateTime; + @column() + declare editedBy: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare isActive: boolean; + @column() + declare key: string; +} + +export class ContextMenuSchema extends BaseModel { + static $columns = ["actionName", "contextId", "guildId"] as const; + $columns = ContextMenuSchema.$columns; + @column() + declare actionName: string; + @column({ isPrimary: true }) + declare contextId: string; + @column() + declare guildId: string; +} + +export class CounterTriggerStateSchema extends BaseModel { + static $columns = ["channelId", "id", "triggerId", "userId"] as const; + $columns = CounterTriggerStateSchema.$columns; + @column() + declare channelId: string; + @column({ isPrimary: true }) + declare id: string; + @column() + declare triggerId: number; + @column() + declare userId: string; +} + +export class CounterTriggerSchema extends BaseModel { + static $columns = [ + "comparisonOp", + "comparisonValue", + "counterId", + "deleteAt", + "id", + "name", + "reverseComparisonOp", + "reverseComparisonValue", + ] as const; + $columns = CounterTriggerSchema.$columns; + @column() + declare comparisonOp: string; + @column() + declare comparisonValue: number; + @column() + declare counterId: number; + @column.dateTime() + declare deleteAt: DateTime | null; + @column({ isPrimary: true }) + declare id: number; + @column() + declare name: string; + @column() + declare reverseComparisonOp: string; + @column() + declare reverseComparisonValue: number; +} + +export class CounterValueSchema extends BaseModel { + static $columns = ["channelId", "counterId", "id", "userId", "value"] as const; + $columns = CounterValueSchema.$columns; + @column() + declare channelId: string; + @column() + declare counterId: number; + @column({ isPrimary: true }) + declare id: string; + @column() + declare userId: string; + @column() + declare value: number; +} + +export class CounterSchema extends BaseModel { + static $columns = ["deleteAt", "guildId", "id", "lastDecayAt", "name", "perChannel", "perUser"] as const; + $columns = CounterSchema.$columns; + @column.dateTime() + declare deleteAt: DateTime | null; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column.dateTime() + declare lastDecayAt: DateTime; + @column() + declare name: string; + @column() + declare perChannel: boolean; + @column() + declare perUser: boolean; +} + +export class MemberCacheSchema extends BaseModel { + static $columns = ["deleteAt", "guildId", "id", "lastSeen", "nickname", "roles", "userId", "username"] as const; + $columns = MemberCacheSchema.$columns; + @column.dateTime() + declare deleteAt: DateTime | null; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column.date() + declare lastSeen: DateTime; + @column() + declare nickname: string | null; + @column() + declare roles: string; + @column() + declare userId: string; + @column() + declare username: string; +} + +export class MemberTimezoneSchema extends BaseModel { + static $columns = ["guildId", "memberId", "timezone"] as const; + $columns = MemberTimezoneSchema.$columns; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare memberId: string; + @column() + declare timezone: string; +} + +export class MessageSchema extends BaseModel { + static $columns = [ + "channelId", + "data", + "deletedAt", + "guildId", + "id", + "isBot", + "isPermanent", + "postedAt", + "userId", + ] as const; + $columns = MessageSchema.$columns; + @column() + declare channelId: string; + @column() + declare data: string; + @column.dateTime() + declare deletedAt: DateTime | null; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: string; + @column() + declare isBot: boolean; + @column() + declare isPermanent: boolean; + @column.dateTime() + declare postedAt: DateTime; + @column() + declare userId: string; +} + +export class MuteSchema extends BaseModel { + static $columns = [ + "caseId", + "createdAt", + "expiresAt", + "guildId", + "muteRole", + "rolesToRestore", + "timeoutExpiresAt", + "type", + "userId", + ] as const; + $columns = MuteSchema.$columns; + @column() + declare caseId: number | null; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime | null; + @column.dateTime() + declare expiresAt: DateTime | null; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare muteRole: string | null; + @column() + declare rolesToRestore: string | null; + @column.dateTime() + declare timeoutExpiresAt: DateTime | null; + @column() + declare type: boolean; + @column() + declare userId: string; +} + +export class NicknameHistorySchema extends BaseModel { + static $columns = ["guildId", "id", "nickname", "timestamp", "userId"] as const; + $columns = NicknameHistorySchema.$columns; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare nickname: string | null; + @column.dateTime() + declare timestamp: DateTime; + @column() + declare userId: string; +} + +export class PersistedDatumSchema extends BaseModel { + static $columns = ["guildId", "isVoiceMuted", "nickname", "roles", "userId"] as const; + $columns = PersistedDatumSchema.$columns; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare isVoiceMuted: number; + @column() + declare nickname: string | null; + @column() + declare roles: string | null; + @column() + declare userId: string; +} + +export class PhishermanCacheSchema extends BaseModel { + static $columns = ["data", "domain", "expiresAt", "id"] as const; + $columns = PhishermanCacheSchema.$columns; + @column() + declare data: string; + @column() + declare domain: string; + @column.dateTime() + declare expiresAt: DateTime; + @column({ isPrimary: true }) + declare id: number; +} + +export class PhishermanKeyCacheSchema extends BaseModel { + static $columns = ["expiresAt", "hash", "id", "isValid"] as const; + $columns = PhishermanKeyCacheSchema.$columns; + @column.dateTime() + declare expiresAt: DateTime; + @column() + declare hash: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare isValid: boolean; +} + +export class PingableRoleSchema extends BaseModel { + static $columns = ["channelId", "guildId", "id", "roleId"] as const; + $columns = PingableRoleSchema.$columns; + @column() + declare channelId: string; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare roleId: string; +} + +export class PortalUserSchema extends BaseModel { + static $columns = ["avatar", "createdAt", "id", "lastLoginAt", "userId", "username"] as const; + $columns = PortalUserSchema.$columns; + @column() + declare avatar: string | null; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column({ isPrimary: true }) + declare id: number; + @column.dateTime() + declare lastLoginAt: DateTime; + @column() + declare userId: string; + @column() + declare username: string; +} + +export class ReactionRoleSchema extends BaseModel { + static $columns = ["channelId", "emoji", "guildId", "isExclusive", "messageId", "order", "roleId"] as const; + $columns = ReactionRoleSchema.$columns; + @column() + declare channelId: string; + @column() + declare emoji: string; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare isExclusive: boolean; + @column() + declare messageId: string; + @column() + declare order: number | null; + @column() + declare roleId: string; +} + +export class ReminderSchema extends BaseModel { + static $columns = ["body", "channelId", "createdAt", "guildId", "id", "remindAt", "userId"] as const; + $columns = ReminderSchema.$columns; + @column() + declare body: string; + @column() + declare channelId: string; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column.dateTime() + declare remindAt: DateTime; + @column() + declare userId: string; +} + +export class RoleButtonSchema extends BaseModel { + static $columns = ["channelId", "guildId", "hash", "id", "messageId", "name"] as const; + $columns = RoleButtonSchema.$columns; + @column() + declare channelId: string; + @column() + declare guildId: string; + @column() + declare hash: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare messageId: string; + @column() + declare name: string; +} + +export class RoleQueueSchema extends BaseModel { + static $columns = ["guildId", "id", "priority", "roleId", "shouldAdd", "userId"] as const; + $columns = RoleQueueSchema.$columns; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare priority: number; + @column() + declare roleId: string; + @column() + declare shouldAdd: boolean; + @column() + declare userId: string; +} + +export class ScheduledPostSchema extends BaseModel { + static $columns = [ + "attachments", + "authorId", + "authorName", + "channelId", + "content", + "enableMentions", + "guildId", + "id", + "postAt", + "repeatInterval", + "repeatTimes", + "repeatUntil", + ] as const; + $columns = ScheduledPostSchema.$columns; + @column() + declare attachments: string; + @column() + declare authorId: string; + @column() + declare authorName: string; + @column() + declare channelId: string; + @column() + declare content: string; + @column() + declare enableMentions: boolean; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column.dateTime() + declare postAt: DateTime; + @column() + declare repeatInterval: number | null; + @column() + declare repeatTimes: number | null; + @column.dateTime() + declare repeatUntil: DateTime | null; +} + +export class SelfGrantableRoleSchema extends BaseModel { + static $columns = ["aliases", "channelId", "guildId", "id", "roleId"] as const; + $columns = SelfGrantableRoleSchema.$columns; + @column() + declare aliases: string; + @column() + declare channelId: string; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare roleId: string; +} + +export class SlowmodeChannelSchema extends BaseModel { + static $columns = ["channelId", "guildId", "slowmodeSeconds"] as const; + $columns = SlowmodeChannelSchema.$columns; + @column() + declare channelId: string; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare slowmodeSeconds: number; +} + +export class SlowmodeUserSchema extends BaseModel { + static $columns = ["channelId", "expiresAt", "guildId", "userId"] as const; + $columns = SlowmodeUserSchema.$columns; + @column() + declare channelId: string; + @column.dateTime() + declare expiresAt: DateTime; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare userId: string; +} + +export class StarboardMessageSchema extends BaseModel { + static $columns = ["guildId", "messageId", "starboardChannelId", "starboardMessageId"] as const; + $columns = StarboardMessageSchema.$columns; + @column() + declare guildId: string; + @column() + declare messageId: string; + @column() + declare starboardChannelId: string; + @column({ isPrimary: true }) + declare starboardMessageId: string; +} + +export class StarboardReactionSchema extends BaseModel { + static $columns = ["guildId", "id", "messageId", "reactorId"] as const; + $columns = StarboardReactionSchema.$columns; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare messageId: string; + @column() + declare reactorId: string; +} + +export class StatSchema extends BaseModel { + static $columns = ["createdAt", "guildId", "id", "key", "source", "value"] as const; + $columns = StatSchema.$columns; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: string; + @column() + declare key: string; + @column() + declare source: string; + @column() + declare value: number; +} + +export class SupporterSchema extends BaseModel { + static $columns = ["amount", "name", "userId"] as const; + $columns = SupporterSchema.$columns; + @column() + declare amount: string | null; + @column() + declare name: string; + @column({ isPrimary: true }) + declare userId: string; +} + +export class TagResponseSchema extends BaseModel { + static $columns = ["commandMessageId", "guildId", "id", "responseMessageId"] as const; + $columns = TagResponseSchema.$columns; + @column() + declare commandMessageId: string; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare responseMessageId: string; +} + +export class TagSchema extends BaseModel { + static $columns = ["body", "createdAt", "guildId", "tag", "userId"] as const; + $columns = TagSchema.$columns; + @column() + declare body: string; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime | null; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare tag: string; + @column() + declare userId: string; +} + +export class TempbanSchema extends BaseModel { + static $columns = ["createdAt", "expiresAt", "guildId", "modId", "userId"] as const; + $columns = TempbanSchema.$columns; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column.dateTime() + declare expiresAt: DateTime; + @column({ isPrimary: true }) + declare guildId: string; + @column() + declare modId: string; + @column() + declare userId: string; +} + +export class UsernameHistorySchema extends BaseModel { + static $columns = ["id", "timestamp", "userId", "username"] as const; + $columns = UsernameHistorySchema.$columns; + @column({ isPrimary: true }) + declare id: number; + @column.dateTime() + declare timestamp: DateTime; + @column() + declare userId: string; + @column() + declare username: string | null; +} + +export class VcAlertSchema extends BaseModel { + static $columns = ["active", "body", "channelId", "expiresAt", "guildId", "id", "requestorId", "userId"] as const; + $columns = VcAlertSchema.$columns; + @column() + declare active: boolean; + @column() + declare body: string; + @column() + declare channelId: string; + @column.dateTime() + declare expiresAt: DateTime; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: number; + @column() + declare requestorId: string; + @column() + declare userId: string; +} + +export class WebhookSchema extends BaseModel { + static $columns = ["channelId", "createdAt", "guildId", "id", "token"] as const; + $columns = WebhookSchema.$columns; + @column() + declare channelId: string; + @column.dateTime({ autoCreate: true }) + declare createdAt: DateTime; + @column() + declare guildId: string; + @column({ isPrimary: true }) + declare id: string; + @column() + declare token: string; } diff --git a/portal/package.json b/portal/package.json index 6e01be918..5d8561fcf 100644 --- a/portal/package.json +++ b/portal/package.json @@ -13,6 +13,7 @@ "dev": "node ace serve --hmr", "test": "node ace test", "ace": "node ace", + "generate-db-schema": "node ace schema:generate", "typecheck": "tsc --noEmit && vue-tsc --noEmit --project inertia/tsconfig.json" }, "imports": { From 6c65aa32c41702ee408da55981ef3c23c948058f Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:25:49 +0000 Subject: [PATCH 06/39] portal: leftover formatting --- portal/.adonisjs/client/registry/index.ts | 30 ++++++++-------- portal/.adonisjs/client/registry/schema.d.ts | 38 ++++++++++++-------- portal/.adonisjs/client/registry/tree.d.ts | 6 ++-- portal/.adonisjs/server/routes.d.ts | 22 ++++++------ 4 files changed, 53 insertions(+), 43 deletions(-) diff --git a/portal/.adonisjs/client/registry/index.ts b/portal/.adonisjs/client/registry/index.ts index 184eda5ad..925caf1c2 100644 --- a/portal/.adonisjs/client/registry/index.ts +++ b/portal/.adonisjs/client/registry/index.ts @@ -1,29 +1,29 @@ /* eslint-disable prettier/prettier */ -import type { AdonisEndpoint } from '@tuyau/core/types' -import type { Registry } from './schema.d.ts' -import type { ApiDefinition } from './tree.d.ts' +import type { AdonisEndpoint } from "@tuyau/core/types"; +import type { Registry } from "./schema.d.ts"; +import type { ApiDefinition } from "./tree.d.ts"; -const placeholder: any = {} +const placeholder: any = {}; const routes = { - 'splash.get_index': { - methods: ["GET","HEAD"], - pattern: '/', - tokens: [{"old":"/","type":0,"val":"/","end":""}], - types: placeholder as Registry['splash.get_index']['types'], + "splash.get_index": { + methods: ["GET", "HEAD"], + pattern: "/", + tokens: [{ old: "/", type: 0, val: "/", end: "" }], + types: placeholder as Registry["splash.get_index"]["types"], }, -} as const satisfies Record +} as const satisfies Record; -export { routes } +export { routes }; export const registry = { routes, $tree: {} as ApiDefinition, -} +}; -declare module '@tuyau/core/types' { +declare module "@tuyau/core/types" { export interface UserRegistry { - routes: typeof routes - $tree: ApiDefinition + routes: typeof routes; + $tree: ApiDefinition; } } diff --git a/portal/.adonisjs/client/registry/schema.d.ts b/portal/.adonisjs/client/registry/schema.d.ts index a85956444..ed44b1405 100644 --- a/portal/.adonisjs/client/registry/schema.d.ts +++ b/portal/.adonisjs/client/registry/schema.d.ts @@ -1,22 +1,32 @@ /* eslint-disable prettier/prettier */ /// -import type { ExtractBody, ExtractErrorResponse, ExtractQuery, ExtractQueryForGet, ExtractResponse } from '@tuyau/core/types' -import type { InferInput, SimpleError } from '@vinejs/vine/types' +import type { + ExtractBody, + ExtractErrorResponse, + ExtractQuery, + ExtractQueryForGet, + ExtractResponse, +} from "@tuyau/core/types"; +import type { InferInput, SimpleError } from "@vinejs/vine/types"; -export type ParamValue = string | number | bigint | boolean +export type ParamValue = string | number | bigint | boolean; export interface Registry { - 'splash.get_index': { - methods: ["GET","HEAD"] - pattern: '/' + "splash.get_index": { + methods: ["GET", "HEAD"]; + pattern: "/"; types: { - body: {} - paramsTuple: [] - params: {} - query: {} - response: ExtractResponse>> - errorResponse: ExtractErrorResponse>> - } - } + body: {}; + paramsTuple: []; + params: {}; + query: {}; + response: ExtractResponse< + Awaited> + >; + errorResponse: ExtractErrorResponse< + Awaited> + >; + }; + }; } diff --git a/portal/.adonisjs/client/registry/tree.d.ts b/portal/.adonisjs/client/registry/tree.d.ts index 742080652..de4b5c5db 100644 --- a/portal/.adonisjs/client/registry/tree.d.ts +++ b/portal/.adonisjs/client/registry/tree.d.ts @@ -1,8 +1,8 @@ /* eslint-disable prettier/prettier */ -import type { routes } from './index.ts' +import type { routes } from "./index.ts"; export interface ApiDefinition { splash: { - getIndex: typeof routes['splash.get_index'] - } + getIndex: (typeof routes)["splash.get_index"]; + }; } diff --git a/portal/.adonisjs/server/routes.d.ts b/portal/.adonisjs/server/routes.d.ts index fc464179c..54120b5a8 100644 --- a/portal/.adonisjs/server/routes.d.ts +++ b/portal/.adonisjs/server/routes.d.ts @@ -1,18 +1,18 @@ -import '@adonisjs/core/types/http' +import "@adonisjs/core/types/http"; -type ParamValue = string | number | bigint | boolean +type ParamValue = string | number | bigint | boolean; export type ScannedRoutes = { ALL: { - 'splash.get_index': { paramsTuple?: []; params?: {} } - } + "splash.get_index": { paramsTuple?: []; params?: {} }; + }; GET: { - 'splash.get_index': { paramsTuple?: []; params?: {} } - } + "splash.get_index": { paramsTuple?: []; params?: {} }; + }; HEAD: { - 'splash.get_index': { paramsTuple?: []; params?: {} } - } -} -declare module '@adonisjs/core/types/http' { + "splash.get_index": { paramsTuple?: []; params?: {} }; + }; +}; +declare module "@adonisjs/core/types/http" { export interface RoutesList extends ScannedRoutes {} -} \ No newline at end of file +} From 3317d5c346977a4367f1bdfaa74ae566ae1b63e7 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 20:26:23 +0000 Subject: [PATCH 07/39] formatter: ignore docs .md files --- .oxfmtrc.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.oxfmtrc.json b/.oxfmtrc.json index ba81b9fd7..8ab6161a0 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -1,5 +1,5 @@ { "$schema": "./node_modules/oxfmt/configuration_schema.json", - "ignorePatterns": ["dist/**", "*.min.js", "*.yml", "*.yaml", "*.json", "LICENSE.md", ".adonisjs/**", "public/assets/**"], + "ignorePatterns": ["dist/**", "*.min.js", "*.yml", "*.yaml", "*.json", "LICENSE.md", ".adonisjs/**", "public/assets/**", "docs/**/*.md"], "printWidth": 120 } From e053cee68b72fe45ab058d79e0a01aafceb902ac Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 21:37:03 +0000 Subject: [PATCH 08/39] portal: fix dev server hmr not working --- docker/development/caddy/config/Caddyfile | 7 +++++++ portal/adonisrc.ts | 1 + portal/hooks/devHmrPort.ts | 10 ++++++++++ portal/start/env.ts | 1 + portal/vite.config.ts | 4 ++++ 5 files changed, 23 insertions(+) create mode 100644 portal/hooks/devHmrPort.ts diff --git a/docker/development/caddy/config/Caddyfile b/docker/development/caddy/config/Caddyfile index b0595ce6c..79b0c2145 100644 --- a/docker/development/caddy/config/Caddyfile +++ b/docker/development/caddy/config/Caddyfile @@ -19,5 +19,12 @@ https://:444 { tls internal { on_demand } + + @vite_hmr { + path / + header Upgrade websocket + } + + reverse_proxy @vite_hmr devenv:3004 reverse_proxy devenv:3003 } diff --git a/portal/adonisrc.ts b/portal/adonisrc.ts index 3842b508a..eefb86971 100644 --- a/portal/adonisrc.ts +++ b/portal/adonisrc.ts @@ -161,5 +161,6 @@ export default defineConfig({ generateRegistry(), ], buildStarting: [() => import("@adonisjs/vite/build_hook")], + devServerStarting: [() => import("./hooks/devHmrPort.ts")] }, }); diff --git a/portal/hooks/devHmrPort.ts b/portal/hooks/devHmrPort.ts new file mode 100644 index 000000000..efd47e421 --- /dev/null +++ b/portal/hooks/devHmrPort.ts @@ -0,0 +1,10 @@ +import { hooks } from "@adonisjs/core/app"; + +// AdonisJS internals override VITE_HMR_PORT env var. +// This overrides that override (yo dawg) with our own value. +export default hooks.devServerStarting((server) => { + server.options.env = { + ...server.options.env, + VITE_HMR_PORT: "3004", + }; +}); diff --git a/portal/start/env.ts b/portal/start/env.ts index 628b12a86..5a3d0aa3b 100644 --- a/portal/start/env.ts +++ b/portal/start/env.ts @@ -21,6 +21,7 @@ export const rootEnv = await Env.create(new URL("../../", import.meta.url), { REDIS_URL: Env.schema.string.optional(), DEVELOPMENT_MYSQL_PASSWORD: Env.schema.string.optional(), DEVELOPMENT_VITE_ALLOWED_HOSTS: Env.schema.string.optional(), + DEVELOPMENT_PORTAL_PORT: Env.schema.number.optional(), }); export const portalEnv = await Env.create(new URL("../", import.meta.url), { diff --git a/portal/vite.config.ts b/portal/vite.config.ts index 8d5a9a119..6942f2289 100644 --- a/portal/vite.config.ts +++ b/portal/vite.config.ts @@ -17,5 +17,9 @@ export default defineConfig({ ignored: ["**/storage/**", "**/tmp/**"], }, allowedHosts, + ws: { + port: 3004, + clientPort: rootEnv.get("DEVELOPMENT_PORTAL_PORT", 3400), + }, }, }); From cc7cc17015613ea0f63efd821f7a1985e77c1f43 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 21:37:27 +0000 Subject: [PATCH 09/39] portal: restore inertia_layout.edge Needed for Inertia to work. Whoops. --- portal/resources/views/inertia_layout.edge | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 portal/resources/views/inertia_layout.edge diff --git a/portal/resources/views/inertia_layout.edge b/portal/resources/views/inertia_layout.edge new file mode 100644 index 000000000..d1879fa5c --- /dev/null +++ b/portal/resources/views/inertia_layout.edge @@ -0,0 +1,12 @@ + + + + + + @inertiaHead() + @vite(['inertia/app.ts']) + + + @inertia() + + From 5974aaaf6303f403bce0bd3ab4c951e38b107ffa Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 21:37:59 +0000 Subject: [PATCH 10/39] portal: small package.json tweaks --- portal/package.json | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/portal/package.json b/portal/package.json index 5d8561fcf..e139f7576 100644 --- a/portal/package.json +++ b/portal/package.json @@ -1,12 +1,7 @@ { - "name": "portal", - "version": "0.0.0", + "name": "@zeppelinbot/portal", "private": true, "type": "module", - "license": "UNLICENSED", - "engines": { - "node": ">=24.0.0" - }, "scripts": { "start": "node bin/server.js", "build": "node ace build", @@ -73,8 +68,8 @@ }, "hotHook": { "boundaries": [ - "./app/features/**/*Controller.ts", - "./app/features/**/*Middleware.ts", + "./app/features/**/controllers/*.ts", + "./app/features/**/middleware/*.ts", "./app/middleware/*.ts" ] }, From 536cd57e0e479916499cd71613b87ff2451668c0 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 21:44:03 +0000 Subject: [PATCH 11/39] portal: copy old nuxt portal frontend --- assets/squiggle2.afdesign | Bin 0 -> 32304 bytes pnpm-lock.yaml | 12 +- portal/inertia/app.ts | 2 + portal/inertia/assets/grid-16x16.png | Bin 0 -> 1871 bytes portal/inertia/assets/grid-64x64.png | Bin 0 -> 1837 bytes portal/inertia/assets/grid-8x8.png | Bin 0 -> 1883 bytes portal/inertia/assets/logo.svg | 123 +++++++++++ portal/inertia/assets/squiggle.svg | 11 + portal/inertia/components/BasicButton.vue | 45 ++++ portal/inertia/components/BasicLink.vue | 13 ++ portal/inertia/components/BasicTab.vue | 52 +++++ portal/inertia/components/DefaultH1.vue | 15 ++ portal/inertia/components/MainMenuItem.vue | 35 +++ portal/inertia/components/PageHeader.vue | 36 ++++ portal/inertia/components/Squiggle.vue | 11 + portal/inertia/css/global.css | 112 ++++++++++ .../features/splash/pages/SplashIndex.vue | 61 +++++- portal/inertia/layouts/MainLayout.vue | 203 ++++++++++++++++++ portal/inertia/layouts/app.vue | 10 - portal/package.json | 1 + 20 files changed, 721 insertions(+), 21 deletions(-) create mode 100644 assets/squiggle2.afdesign create mode 100644 portal/inertia/assets/grid-16x16.png create mode 100644 portal/inertia/assets/grid-64x64.png create mode 100644 portal/inertia/assets/grid-8x8.png create mode 100644 portal/inertia/assets/logo.svg create mode 100644 portal/inertia/assets/squiggle.svg create mode 100644 portal/inertia/components/BasicButton.vue create mode 100644 portal/inertia/components/BasicLink.vue create mode 100644 portal/inertia/components/BasicTab.vue create mode 100644 portal/inertia/components/DefaultH1.vue create mode 100644 portal/inertia/components/MainMenuItem.vue create mode 100644 portal/inertia/components/PageHeader.vue create mode 100644 portal/inertia/components/Squiggle.vue create mode 100644 portal/inertia/css/global.css create mode 100644 portal/inertia/layouts/MainLayout.vue delete mode 100644 portal/inertia/layouts/app.vue diff --git a/assets/squiggle2.afdesign b/assets/squiggle2.afdesign new file mode 100644 index 0000000000000000000000000000000000000000..e8e1f16eca0881419f6afafcac4e5981075c26a7 GIT binary patch literal 32304 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 literal 0 HcmV?d00001 diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9516d425a..a9da1db24 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,10 +9,6 @@ catalogs: typescript: specifier: 6.0.3 version: 6.0.3 - ts7: - typescript: - specifier: 7.0.2 - version: 7.0.2 overrides: discord.js: 14.23.2 @@ -334,6 +330,9 @@ importers: '@adonisjs/vite': specifier: ^6.0.2 version: 6.0.3(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/shield@9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1))(edge.js@6.5.1)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0)) + '@fontsource-variable/recursive': + specifier: ^5.3.0 + version: 5.3.0 '@inertiajs/core': specifier: ^3.7.1 version: 3.9.1 @@ -945,6 +944,9 @@ packages: '@fastify/static@7.0.4': resolution: {integrity: sha512-p2uKtaf8BMOZWLs6wu+Ihg7bWNBdjNgCwDza4MJtTqg+5ovKmcbgbR9Xs5/smZ1YISfzKOCNYmZV8LaCj+eJ1Q==} + '@fontsource-variable/recursive@5.3.0': + resolution: {integrity: sha512-4B4/lWCVeZgdbpJdIIU1sOVO/ECjjM673ohuxvyQ6uCK41TPlGzKRNokKY84noUgGYnpwc//MW4k2KrOMY19jQ==} + '@inertiajs/core@3.9.1': resolution: {integrity: sha512-ScLQZ1/KXlvmqCEJMEZABSK5updJZIli1kaG/coWXpWMmpSLsazSJkR7esITYp7X5vTgrOGNIrcRmdMp/GQ0NA==} peerDependencies: @@ -5703,6 +5705,8 @@ snapshots: fastq: 1.20.1 glob: 10.5.0 + '@fontsource-variable/recursive@5.3.0': {} + '@inertiajs/core@3.9.1': dependencies: '@jridgewell/trace-mapping': 0.3.31 diff --git a/portal/inertia/app.ts b/portal/inertia/app.ts index 1bca51dd5..abbecfb79 100644 --- a/portal/inertia/app.ts +++ b/portal/inertia/app.ts @@ -1,3 +1,5 @@ +import "@fontsource-variable/recursive"; +import "./css/global.css"; import "vue-sonner/style.css"; import { client } from "#frontend/client.js"; import { createInertiaApp } from "@inertiajs/vue3"; diff --git a/portal/inertia/assets/grid-16x16.png b/portal/inertia/assets/grid-16x16.png new file mode 100644 index 0000000000000000000000000000000000000000..6719d4167e1602b318131661767fad0cbf1d2d68 GIT binary patch literal 1871 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 literal 0 HcmV?d00001 diff --git a/portal/inertia/assets/grid-8x8.png b/portal/inertia/assets/grid-8x8.png new file mode 100644 index 0000000000000000000000000000000000000000..52bb2558978068d337e3e9f8e12cb9dd07a67404 GIT binary patch literal 1883 zcmc&#eQXnD96nG8TUjPB0*EQM+rW?7-nH9`J$w709kdB;x~*d^iIZFVwmoU@%H4Hq z=X7H-Wy^>`6Xuo;Mgm0n5{$+Sw=rB0FgjQ?f(dLQ8U%+Br??@g?_I~n80eq=aqYdo z=lMOqulIeg-eF&rl=yfef*?s&i@6Z~=St74necZnvta;19zDc3U82jjn)GlX4ejO1 zfF>FWLmWYjInglfSr0_C4EPzA!mfXE6hj#=g_UI42wT_$0*s}S2St^3r>Ang$Kb_s zvJ;I_5(~uVUcjUf zrL) zQcmRf0yEPZ>gtZC@AqZCnn}~zc_vz$@%g%p;V+W2a!Rj%x$D%LZ|wzTm(JE6tvT?) zng+|M7WLu0)3KFXynWZs4|fc{eEQ0OaBQw!wW#ZxN1B7BikVe?9Va`#x@o5LLyg43 zVlhHyD);Q|y5R79rux{u?^Z|kfelX|R5?5gl*LXpZcH_P^j3*&AcZX|>|c7(LpLp3 zkkYOH-POFrX5Tj2>s3GT+iSb?&o$pZe)z@xyFP3@)Y*D)^^x}5=TB7Cr)_UbvJRzO z&wbK@EU_Q%go8F!Ap0eqk$0$vj zt$*n6!S1W|8~@@XZzNw;&c3vJad7bsx32MzS9(W`$j?+OP>ps_3oGY$Is1>4?~Enc z`&4U#3j5ieckEkU>gP^9!&=k78=cjHovBPnQvA66&X5pQTr3{lt2j5XQE3?L9GP+K zxj=GzUFux;xkw0G+ya6q=1I>qq@{HsH1=A}dCq9-wQa`|dU9v?R$ZvRT)wHh_EYz* zmYO-6en^iM_3fzHH+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/portal/inertia/assets/squiggle.svg b/portal/inertia/assets/squiggle.svg new file mode 100644 index 000000000..55016b8af --- /dev/null +++ b/portal/inertia/assets/squiggle.svg @@ -0,0 +1,11 @@ + + + + + + + + + + + diff --git a/portal/inertia/components/BasicButton.vue b/portal/inertia/components/BasicButton.vue new file mode 100644 index 000000000..b0d92aefb --- /dev/null +++ b/portal/inertia/components/BasicButton.vue @@ -0,0 +1,45 @@ + + + + + diff --git a/portal/inertia/components/BasicLink.vue b/portal/inertia/components/BasicLink.vue new file mode 100644 index 000000000..3584bc9c6 --- /dev/null +++ b/portal/inertia/components/BasicLink.vue @@ -0,0 +1,13 @@ + + + diff --git a/portal/inertia/components/BasicTab.vue b/portal/inertia/components/BasicTab.vue new file mode 100644 index 000000000..b7cecfe64 --- /dev/null +++ b/portal/inertia/components/BasicTab.vue @@ -0,0 +1,52 @@ + + + + + diff --git a/portal/inertia/components/DefaultH1.vue b/portal/inertia/components/DefaultH1.vue new file mode 100644 index 000000000..afed5707d --- /dev/null +++ b/portal/inertia/components/DefaultH1.vue @@ -0,0 +1,15 @@ + + + diff --git a/portal/inertia/components/MainMenuItem.vue b/portal/inertia/components/MainMenuItem.vue new file mode 100644 index 000000000..ef51c2fcd --- /dev/null +++ b/portal/inertia/components/MainMenuItem.vue @@ -0,0 +1,35 @@ + + + + + diff --git a/portal/inertia/components/PageHeader.vue b/portal/inertia/components/PageHeader.vue new file mode 100644 index 000000000..674df79a6 --- /dev/null +++ b/portal/inertia/components/PageHeader.vue @@ -0,0 +1,36 @@ + + + + + diff --git a/portal/inertia/components/Squiggle.vue b/portal/inertia/components/Squiggle.vue new file mode 100644 index 000000000..57555200d --- /dev/null +++ b/portal/inertia/components/Squiggle.vue @@ -0,0 +1,11 @@ + + + diff --git a/portal/inertia/css/global.css b/portal/inertia/css/global.css new file mode 100644 index 000000000..08a4be60d --- /dev/null +++ b/portal/inertia/css/global.css @@ -0,0 +1,112 @@ +:root { + --color-blue-50: rgb(193, 245, 255); + --color-blue-100: rgb(178, 231, 255); + --color-blue-200: rgb(149, 203, 255); + --color-blue-300: rgb(121, 175, 234); + --color-blue-400: rgb(92, 149, 206); + --color-blue-500: rgb(62, 123, 178); + --color-blue-600: rgb(26, 98, 151); + --color-blue-700: rgb(0, 75, 125); + --color-blue-800: rgb(0, 52, 100); + --color-blue-900: rgb(0, 32, 76); + --color-blue-950: rgb(0, 22, 64); + --color-steelblue-50: rgb(210, 243, 255); + --color-steelblue-100: rgb(196, 229, 255); + --color-steelblue-200: rgb(168, 201, 245); + --color-steelblue-300: rgb(141, 174, 216); + --color-steelblue-400: rgb(114, 147, 188); + --color-steelblue-500: rgb(88, 121, 161); + --color-steelblue-600: rgb(62, 97, 135); + --color-steelblue-700: rgb(34, 73, 109); + --color-steelblue-800: rgb(0, 51, 85); + --color-steelblue-900: rgb(0, 30, 61); + --color-steelblue-950: rgb(0, 20, 50); + --color-green-50: rgb(164, 255, 127); + --color-green-100: rgb(149, 251, 113); + --color-green-200: rgb(120, 222, 86); + --color-green-300: rgb(90, 193, 59); + --color-green-400: rgb(59, 166, 29); + --color-green-500: rgb(17, 139, 0); + --color-green-600: rgb(0, 112, 0); + --color-green-700: rgb(0, 87, 0); + --color-green-800: rgb(0, 62, 0); + --color-green-900: rgb(0, 41, 0); + --color-green-950: rgb(0, 35, 0); + --color-yellow-50: rgb(255, 238, 63); + --color-yellow-100: rgb(255, 224, 45); + --color-yellow-200: rgb(231, 197, 0); + --color-yellow-300: rgb(200, 170, 0); + --color-yellow-400: rgb(170, 143, 0); + --color-yellow-500: rgb(141, 118, 0); + --color-yellow-600: rgb(113, 94, 0); + --color-yellow-700: rgb(88, 70, 0); + --color-yellow-800: rgb(68, 47, 0); + --color-yellow-900: rgb(55, 25, 0); + --color-yellow-950: rgb(50, 12, 0); + --color-orange-50: rgb(255, 210, 101); + --color-orange-100: rgb(255, 196, 87); + --color-orange-200: rgb(255, 168, 60); + --color-orange-300: rgb(255, 141, 28); + --color-orange-400: rgb(224, 115, 0); + --color-orange-500: rgb(193, 90, 0); + --color-orange-600: rgb(162, 64, 0); + --color-orange-700: rgb(132, 39, 0); + --color-orange-800: rgb(105, 9, 0); + --color-orange-900: rgb(81, 0, 0); + --color-orange-950: rgb(72, 0, 0); + --color-red-50: rgb(255, 178, 120); + --color-red-100: rgb(255, 164, 107); + --color-red-200: rgb(255, 134, 81); + --color-red-300: rgb(255, 105, 56); + --color-red-400: rgb(255, 75, 29); + --color-red-500: rgb(231, 39, 0); + --color-red-600: rgb(198, 0, 0); + --color-red-700: rgb(166, 0, 0); + --color-red-800: rgb(135, 0, 0); + --color-red-900: rgb(106, 0, 0); + --color-red-950: rgb(94, 0, 0); + --color-gray-50: rgb(241, 241, 241); + --color-gray-100: rgb(226, 226, 226); + --color-gray-200: rgb(198, 198, 198); + --color-gray-300: rgb(171, 171, 171); + --color-gray-400: rgb(145, 145, 145); + --color-gray-500: rgb(119, 119, 119); + --color-gray-600: rgb(94, 94, 94); + --color-gray-700: rgb(71, 71, 71); + --color-gray-800: rgb(48, 48, 48); + --color-gray-900: rgb(27, 27, 27); + --color-gray-950: rgb(17, 17, 17); + + --text-base: 16px; + --text-lg: 24px; + --text-xl: 32px; + --text-xl2: 40px; + --text-xl3: 48px; +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +body { + margin: 0; + font: + 16px/1.2 "Recursive Variable", + -apple-system, + BlinkMacSystemFont, + avenir next, + avenir, + segoe ui, + helvetica neue, + Adwaita Sans, + Cantarell, + Ubuntu, + roboto, + noto, + helvetica, + arial, + sans-serif; + font-weight: 350; +} diff --git a/portal/inertia/features/splash/pages/SplashIndex.vue b/portal/inertia/features/splash/pages/SplashIndex.vue index 38f1976a0..c24d8a7e9 100644 --- a/portal/inertia/features/splash/pages/SplashIndex.vue +++ b/portal/inertia/features/splash/pages/SplashIndex.vue @@ -1,10 +1,57 @@ - + + + diff --git a/portal/inertia/layouts/MainLayout.vue b/portal/inertia/layouts/MainLayout.vue new file mode 100644 index 000000000..c7fcd2b25 --- /dev/null +++ b/portal/inertia/layouts/MainLayout.vue @@ -0,0 +1,203 @@ + + + + + + + diff --git a/portal/inertia/layouts/app.vue b/portal/inertia/layouts/app.vue deleted file mode 100644 index 9cb154e68..000000000 --- a/portal/inertia/layouts/app.vue +++ /dev/null @@ -1,10 +0,0 @@ - - - diff --git a/portal/package.json b/portal/package.json index e139f7576..0eb6affcb 100644 --- a/portal/package.json +++ b/portal/package.json @@ -53,6 +53,7 @@ "@adonisjs/shield": "^9.0.0", "@adonisjs/static": "^2.0.1", "@adonisjs/vite": "^6.0.2", + "@fontsource-variable/recursive": "^5.3.0", "@inertiajs/core": "^3.7.1", "@inertiajs/vue3": "^3.7.1", "@tuyau/core": "^1.2.2", From 5557bf355c3410a3ff90bf1759d6976ad7a0d735 Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Sun, 25 Oct 2026 21:44:57 +0000 Subject: [PATCH 12/39] formatter: fix ignorePatterns; reformat Properly ignores the .adonisjs dir now. --- .oxfmtrc.json | 2 +- portal/.adonisjs/client/data.d.ts | 16 ++++----- portal/.adonisjs/client/registry/index.ts | 30 ++++++++-------- portal/.adonisjs/client/registry/schema.d.ts | 38 ++++++++------------ portal/.adonisjs/client/registry/tree.d.ts | 6 ++-- portal/.adonisjs/server/controllers.ts | 4 +-- portal/.adonisjs/server/events.ts | 2 +- portal/.adonisjs/server/listeners.ts | 2 +- portal/.adonisjs/server/pages.d.ts | 34 +++++++++++------- portal/.adonisjs/server/routes.d.ts | 22 ++++++------ portal/adonisrc.ts | 2 +- 11 files changed, 78 insertions(+), 80 deletions(-) diff --git a/.oxfmtrc.json b/.oxfmtrc.json index 8ab6161a0..4f13a815d 100644 --- a/.oxfmtrc.json +++ b/.oxfmtrc.json @@ -1,5 +1,5 @@ { "$schema": "./node_modules/oxfmt/configuration_schema.json", - "ignorePatterns": ["dist/**", "*.min.js", "*.yml", "*.yaml", "*.json", "LICENSE.md", ".adonisjs/**", "public/assets/**", "docs/**/*.md"], + "ignorePatterns": ["**/dist/**", "**/*.min.js", "**/*.yml", "**/*.yaml", "**/*.json", "**/LICENSE.md", "**/.adonisjs/**", "public/assets/**", "docs/**/*.md"], "printWidth": 120 } diff --git a/portal/.adonisjs/client/data.d.ts b/portal/.adonisjs/client/data.d.ts index 70622aa4d..5cafc4b8a 100644 --- a/portal/.adonisjs/client/data.d.ts +++ b/portal/.adonisjs/client/data.d.ts @@ -4,18 +4,18 @@ */ /// -import type { InferData, InferVariants } from "@adonisjs/core/types/transformers"; -import type { InferSharedProps, InferFlashData } from "@adonisjs/inertia/types"; -import type PortalUsersPortalUserTransformer from "#backend/features/portalUsers/transformers/PortalUserTransformer"; -import type InertiaMiddleware from "#backend/middleware/inertiaMiddleware"; +import type { InferData, InferVariants } from '@adonisjs/core/types/transformers' +import type { InferSharedProps, InferFlashData } from '@adonisjs/inertia/types' +import type PortalUsersPortalUserTransformer from '#backend/features/portalUsers/transformers/PortalUserTransformer' +import type InertiaMiddleware from '#backend/middleware/inertiaMiddleware' export namespace Data { export namespace PortalUsers { - export type PortalUser = InferData; + export type PortalUser = InferData export namespace PortalUser { - export type Variants = InferVariants; + export type Variants = InferVariants } } - export type SharedProps = InferSharedProps; - export type FlashMessages = InferFlashData; + export type SharedProps = InferSharedProps + export type FlashMessages = InferFlashData } diff --git a/portal/.adonisjs/client/registry/index.ts b/portal/.adonisjs/client/registry/index.ts index 925caf1c2..184eda5ad 100644 --- a/portal/.adonisjs/client/registry/index.ts +++ b/portal/.adonisjs/client/registry/index.ts @@ -1,29 +1,29 @@ /* eslint-disable prettier/prettier */ -import type { AdonisEndpoint } from "@tuyau/core/types"; -import type { Registry } from "./schema.d.ts"; -import type { ApiDefinition } from "./tree.d.ts"; +import type { AdonisEndpoint } from '@tuyau/core/types' +import type { Registry } from './schema.d.ts' +import type { ApiDefinition } from './tree.d.ts' -const placeholder: any = {}; +const placeholder: any = {} const routes = { - "splash.get_index": { - methods: ["GET", "HEAD"], - pattern: "/", - tokens: [{ old: "/", type: 0, val: "/", end: "" }], - types: placeholder as Registry["splash.get_index"]["types"], + 'splash.get_index': { + methods: ["GET","HEAD"], + pattern: '/', + tokens: [{"old":"/","type":0,"val":"/","end":""}], + types: placeholder as Registry['splash.get_index']['types'], }, -} as const satisfies Record; +} as const satisfies Record -export { routes }; +export { routes } export const registry = { routes, $tree: {} as ApiDefinition, -}; +} -declare module "@tuyau/core/types" { +declare module '@tuyau/core/types' { export interface UserRegistry { - routes: typeof routes; - $tree: ApiDefinition; + routes: typeof routes + $tree: ApiDefinition } } diff --git a/portal/.adonisjs/client/registry/schema.d.ts b/portal/.adonisjs/client/registry/schema.d.ts index ed44b1405..a85956444 100644 --- a/portal/.adonisjs/client/registry/schema.d.ts +++ b/portal/.adonisjs/client/registry/schema.d.ts @@ -1,32 +1,22 @@ /* eslint-disable prettier/prettier */ /// -import type { - ExtractBody, - ExtractErrorResponse, - ExtractQuery, - ExtractQueryForGet, - ExtractResponse, -} from "@tuyau/core/types"; -import type { InferInput, SimpleError } from "@vinejs/vine/types"; +import type { ExtractBody, ExtractErrorResponse, ExtractQuery, ExtractQueryForGet, ExtractResponse } from '@tuyau/core/types' +import type { InferInput, SimpleError } from '@vinejs/vine/types' -export type ParamValue = string | number | bigint | boolean; +export type ParamValue = string | number | bigint | boolean export interface Registry { - "splash.get_index": { - methods: ["GET", "HEAD"]; - pattern: "/"; + 'splash.get_index': { + methods: ["GET","HEAD"] + pattern: '/' types: { - body: {}; - paramsTuple: []; - params: {}; - query: {}; - response: ExtractResponse< - Awaited> - >; - errorResponse: ExtractErrorResponse< - Awaited> - >; - }; - }; + body: {} + paramsTuple: [] + params: {} + query: {} + response: ExtractResponse>> + errorResponse: ExtractErrorResponse>> + } + } } diff --git a/portal/.adonisjs/client/registry/tree.d.ts b/portal/.adonisjs/client/registry/tree.d.ts index de4b5c5db..742080652 100644 --- a/portal/.adonisjs/client/registry/tree.d.ts +++ b/portal/.adonisjs/client/registry/tree.d.ts @@ -1,8 +1,8 @@ /* eslint-disable prettier/prettier */ -import type { routes } from "./index.ts"; +import type { routes } from './index.ts' export interface ApiDefinition { splash: { - getIndex: (typeof routes)["splash.get_index"]; - }; + getIndex: typeof routes['splash.get_index'] + } } diff --git a/portal/.adonisjs/server/controllers.ts b/portal/.adonisjs/server/controllers.ts index 900cfd430..c135649bc 100644 --- a/portal/.adonisjs/server/controllers.ts +++ b/portal/.adonisjs/server/controllers.ts @@ -5,6 +5,6 @@ export const controllers = { splash: { - Splash: () => import("#backend/features/splash/controllers/SplashController"), + Splash: () => import('#backend/features/splash/controllers/SplashController'), }, -}; +} diff --git a/portal/.adonisjs/server/events.ts b/portal/.adonisjs/server/events.ts index 762b5604a..a74e59b65 100644 --- a/portal/.adonisjs/server/events.ts +++ b/portal/.adonisjs/server/events.ts @@ -3,4 +3,4 @@ * DO NOT EDIT manually */ -export const events = {}; +export const events = {} diff --git a/portal/.adonisjs/server/listeners.ts b/portal/.adonisjs/server/listeners.ts index d9cfaa2b4..05f35f86d 100644 --- a/portal/.adonisjs/server/listeners.ts +++ b/portal/.adonisjs/server/listeners.ts @@ -3,4 +3,4 @@ * DO NOT EDIT manually */ -export const listeners = {}; +export const listeners = {} diff --git a/portal/.adonisjs/server/pages.d.ts b/portal/.adonisjs/server/pages.d.ts index e9de18138..9555263fc 100644 --- a/portal/.adonisjs/server/pages.d.ts +++ b/portal/.adonisjs/server/pages.d.ts @@ -1,21 +1,29 @@ -import "@adonisjs/inertia/types"; +import '@adonisjs/inertia/types' -import type { VNodeProps, AllowedComponentProps, ComponentInstance } from "vue"; -type ExtractProps = Omit["$props"], keyof VNodeProps | keyof AllowedComponentProps>; + import type { + VNodeProps, + AllowedComponentProps, + ComponentInstance + } from 'vue' + + type ExtractProps = Omit< + ComponentInstance['$props'], + keyof VNodeProps | keyof AllowedComponentProps + > + + +declare module '@adonisjs/inertia/types' { -declare module "@adonisjs/inertia/types" { export interface InertiaPages { - "features/errors/pages/NotFound": ExtractProps< - (typeof import("../../inertia/features/errors/pages/NotFound.vue"))["default"] - >; - "features/errors/pages/ServerError": ExtractProps< - (typeof import("../../inertia/features/errors/pages/ServerError.vue"))["default"] - >; + 'features/errors/pages/NotFound': ExtractProps<(typeof import('../../inertia/features/errors/pages/NotFound.vue'))['default']> + + 'features/errors/pages/ServerError': ExtractProps<(typeof import('../../inertia/features/errors/pages/ServerError.vue'))['default']> + + 'features/splash/pages/SplashIndex': ExtractProps<(typeof import('../../inertia/features/splash/pages/SplashIndex.vue'))['default']> - "features/splash/pages/SplashIndex": ExtractProps< - (typeof import("../../inertia/features/splash/pages/SplashIndex.vue"))["default"] - >; } + } + diff --git a/portal/.adonisjs/server/routes.d.ts b/portal/.adonisjs/server/routes.d.ts index 54120b5a8..fc464179c 100644 --- a/portal/.adonisjs/server/routes.d.ts +++ b/portal/.adonisjs/server/routes.d.ts @@ -1,18 +1,18 @@ -import "@adonisjs/core/types/http"; +import '@adonisjs/core/types/http' -type ParamValue = string | number | bigint | boolean; +type ParamValue = string | number | bigint | boolean export type ScannedRoutes = { ALL: { - "splash.get_index": { paramsTuple?: []; params?: {} }; - }; + 'splash.get_index': { paramsTuple?: []; params?: {} } + } GET: { - "splash.get_index": { paramsTuple?: []; params?: {} }; - }; + 'splash.get_index': { paramsTuple?: []; params?: {} } + } HEAD: { - "splash.get_index": { paramsTuple?: []; params?: {} }; - }; -}; -declare module "@adonisjs/core/types/http" { - export interface RoutesList extends ScannedRoutes {} + 'splash.get_index': { paramsTuple?: []; params?: {} } + } } +declare module '@adonisjs/core/types/http' { + export interface RoutesList extends ScannedRoutes {} +} \ No newline at end of file diff --git a/portal/adonisrc.ts b/portal/adonisrc.ts index eefb86971..ecc244459 100644 --- a/portal/adonisrc.ts +++ b/portal/adonisrc.ts @@ -161,6 +161,6 @@ export default defineConfig({ generateRegistry(), ], buildStarting: [() => import("@adonisjs/vite/build_hook")], - devServerStarting: [() => import("./hooks/devHmrPort.ts")] + devServerStarting: [() => import("./hooks/devHmrPort.ts")], }, }); From 805da4adf3b5ab6fb5905b54709ee23c01ac670a Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Mon, 26 Oct 2026 00:27:07 +0000 Subject: [PATCH 13/39] portal: work on layout --- portal/inertia/assets/charcoal-noise.webp | Bin 0 -> 34452 bytes portal/inertia/assets/paper-texture.jpg | Bin 0 -> 95290 bytes portal/inertia/components/BasicButton.vue | 50 ++++++---- portal/inertia/components/ContentPaper.vue | 94 ++++++++++++++++++ portal/inertia/components/SidebarPaper.vue | 79 +++++++++++++++ portal/inertia/components/Squiggle.vue | 2 +- portal/inertia/components/WithSidebar.vue | 24 +++++ portal/inertia/css/global.css | 5 +- .../features/splash/pages/SplashIndex.vue | 34 +++---- portal/inertia/layouts/MainLayout.vue | 65 ++++++++++-- 10 files changed, 304 insertions(+), 49 deletions(-) create mode 100644 portal/inertia/assets/charcoal-noise.webp create mode 100644 portal/inertia/assets/paper-texture.jpg create mode 100644 portal/inertia/components/ContentPaper.vue create mode 100644 portal/inertia/components/SidebarPaper.vue create mode 100644 portal/inertia/components/WithSidebar.vue diff --git a/portal/inertia/assets/charcoal-noise.webp b/portal/inertia/assets/charcoal-noise.webp new file mode 100644 index 0000000000000000000000000000000000000000..88a654b79f39c524fd7cfa1052b14216d0279010 GIT binary patch literal 34452 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 z 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

B}@ON`kV8(nJiOuX%mJ{{aw?%(Q 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图?=pr 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 b9gD3BM-RLYV?MBqhTJb0n=Ac*{~h>0Q@4J* literal 0 HcmV?d00001 diff --git a/portal/inertia/components/BasicButton.vue b/portal/inertia/components/BasicButton.vue index b0d92aefb..0770c36bc 100644 --- a/portal/inertia/components/BasicButton.vue +++ b/portal/inertia/components/BasicButton.vue @@ -1,9 +1,5 @@ @@ -12,34 +8,50 @@ diff --git a/portal/inertia/components/ContentPaper.vue b/portal/inertia/components/ContentPaper.vue new file mode 100644 index 000000000..92192fc8e --- /dev/null +++ b/portal/inertia/components/ContentPaper.vue @@ -0,0 +1,94 @@ + + + + + diff --git a/portal/inertia/components/SidebarPaper.vue b/portal/inertia/components/SidebarPaper.vue new file mode 100644 index 000000000..c6dca80bc --- /dev/null +++ b/portal/inertia/components/SidebarPaper.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/portal/inertia/components/Squiggle.vue b/portal/inertia/components/Squiggle.vue index 57555200d..75c9b58e7 100644 --- a/portal/inertia/components/Squiggle.vue +++ b/portal/inertia/components/Squiggle.vue @@ -4,7 +4,7 @@ diff --git a/portal/inertia/css/global.css b/portal/inertia/css/global.css index 08a4be60d..e00a91b97 100644 --- a/portal/inertia/css/global.css +++ b/portal/inertia/css/global.css @@ -77,6 +77,9 @@ --color-gray-900: rgb(27, 27, 27); --color-gray-950: rgb(17, 17, 17); + --color-ink-dark: hsl(203, 28%, 22%); + --color-ink-light: hsl(202, 21%, 82%); + --text-base: 16px; --text-lg: 24px; --text-xl: 32px; @@ -108,5 +111,5 @@ body { helvetica, arial, sans-serif; - font-weight: 350; + font-weight: 400; } diff --git a/portal/inertia/features/splash/pages/SplashIndex.vue b/portal/inertia/features/splash/pages/SplashIndex.vue index c24d8a7e9..297108ff1 100644 --- a/portal/inertia/features/splash/pages/SplashIndex.vue +++ b/portal/inertia/features/splash/pages/SplashIndex.vue @@ -1,26 +1,28 @@ diff --git a/portal/inertia/layouts/MainLayout.vue b/portal/inertia/layouts/MainLayout.vue index c7fcd2b25..b33a8a708 100644 --- a/portal/inertia/layouts/MainLayout.vue +++ b/portal/inertia/layouts/MainLayout.vue @@ -4,10 +4,11 @@

-
+
@@ -103,11 +101,6 @@ body { width: calc(7 * 64px); } } -@media (min-width: 448px) { - .wrap { - width: calc(7 * 64px); - } -} @media (min-width: 576px) { .wrap { width: calc(9 * 64px); @@ -133,6 +126,31 @@ body { width: calc(17 * 64px); } } +@media (min-width: 1216px) { + .wrap { + width: calc(19 * 64px); + } +} +@media (min-width: 1344px) { + .wrap { + width: calc(21 * 64px); + } +} +@media (min-width: 1472px) { + .wrap { + width: calc(23 * 64px); + } +} +@media (min-width: 1600px) { + .wrap { + width: calc(25 * 64px); + } +} +@media (min-width: 1728px) { + .wrap { + width: calc(27 * 64px); + } +} .header { height: 64px; @@ -144,6 +162,7 @@ body { flex: 0 0 calc(64px * 4); margin: -16px 0 -17px; padding-left: 2px; + position: relative; } .logo img { width: 100%; @@ -151,11 +170,24 @@ body { object-fit: contain; object-position: left center; } +.logo .name { + font-size: 24px; + font-weight: 500; + padding: 4px 8px; + background-color: #f4f0e4; + color: #293d49; + box-shadow: 3px 3px 12px -2px rgba(0, 0, 0); + position: absolute; + top: 50%; + right: 50px; + transform: translateY(-50%) rotateZ(-5deg); + transform-origin: 50% 50%; +} .menu { flex: 1 1 auto; justify-content: flex-end; align-items: center; - gap: 32px; + gap: 64px; font-weight: 450; display: none; @@ -195,9 +227,20 @@ body { From f51f07997681b1c53fda659008a901154c3a08cb Mon Sep 17 00:00:00 2001 From: Dragory <2606411+Dragory@users.noreply.github.com> Date: Tue, 27 Oct 2026 20:40:53 +0000 Subject: [PATCH 14/39] portal: layout work + docs page start --- backend/package.json | 7 + backend/src/exportDocsData.ts | 34 +++ backend/src/exportSchemas.ts | 20 +- .../src/utils/makeJsonSchemaDeepPartial.ts | 18 ++ pnpm-lock.yaml | 18 ++ portal/.adonisjs/client/registry/index.ts | 6 + portal/.adonisjs/client/registry/schema.d.ts | 12 + portal/.adonisjs/client/registry/tree.d.ts | 3 + portal/.adonisjs/server/controllers.ts | 3 + portal/.adonisjs/server/pages.d.ts | 2 + portal/.adonisjs/server/routes.d.ts | 3 + .../docs/controllers/DocsController.ts | 7 + .../app/features/docs/utils/docsLayoutData.ts | 40 +++ .../docs/utils/formatZodConfigSchema.ts | 104 ++++++++ portal/app/features/menu/types.ts | 10 + portal/inertia/app.ts | 3 +- portal/inertia/assets/charcoal-noise.webp | Bin 34452 -> 25334 bytes portal/inertia/components/BasicButton.vue | 18 +- portal/inertia/components/MainMenuItem.vue | 2 - portal/inertia/components/Squiggle.vue | 3 + portal/inertia/css/global.css | 38 ++- .../features/docs/layouts/DocsLayout.vue | 34 +++ .../inertia/features/docs/pages/DocsIndex.vue | 37 +++ .../layout}/ContentPaper.vue | 48 +++- portal/inertia/features/layout/MainLayout.vue | 229 ++++++++++++++++ portal/inertia/features/layout/PaperH1.vue | 11 + .../inertia/features/layout/SidebarMenu.vue | 79 ++++++ .../layout}/WithSidebar.vue | 4 +- .../inertia/features/layout/measurements.ts | 1 + .../features/pageCounter/usePageCount.ts | 3 + .../features/splash/pages/SplashIndex.vue | 8 +- portal/inertia/layouts/MainLayout.vue | 246 ------------------ portal/package.json | 5 +- portal/start/routes.ts | 10 + shared/src/docsData.json | 1 + shared/src/docsData.ts | 4 + shared/src/docsDataTypes.ts | 17 ++ shared/tsconfig.json | 3 +- 38 files changed, 793 insertions(+), 298 deletions(-) create mode 100644 backend/src/exportDocsData.ts create mode 100644 backend/src/utils/makeJsonSchemaDeepPartial.ts create mode 100644 portal/app/features/docs/controllers/DocsController.ts create mode 100644 portal/app/features/docs/utils/docsLayoutData.ts create mode 100644 portal/app/features/docs/utils/formatZodConfigSchema.ts create mode 100644 portal/app/features/menu/types.ts create mode 100644 portal/inertia/features/docs/layouts/DocsLayout.vue create mode 100644 portal/inertia/features/docs/pages/DocsIndex.vue rename portal/inertia/{components => features/layout}/ContentPaper.vue (66%) create mode 100644 portal/inertia/features/layout/MainLayout.vue create mode 100644 portal/inertia/features/layout/PaperH1.vue create mode 100644 portal/inertia/features/layout/SidebarMenu.vue rename portal/inertia/{components => features/layout}/WithSidebar.vue (89%) create mode 100644 portal/inertia/features/layout/measurements.ts create mode 100644 portal/inertia/features/pageCounter/usePageCount.ts delete mode 100644 portal/inertia/layouts/MainLayout.vue create mode 100644 shared/src/docsData.json create mode 100644 shared/src/docsData.ts create mode 100644 shared/src/docsDataTypes.ts diff --git a/backend/package.json b/backend/package.json index ccbb1f101..c3ab5b713 100644 --- a/backend/package.json +++ b/backend/package.json @@ -22,6 +22,7 @@ "migrate-rollback-dev": "pnpm run build && pnpm run migrate-rollback", "validate-active-configs": "node --enable-source-maps dist/validateActiveConfigs.js > ../config-errors.txt", "export-config-json-schema": "node --enable-source-maps dist/exportSchemas.js ../config-checker/public/config-schema.json", + "export-docs-data": "node --enable-source-maps dist/exportDocsData.js ../shared/src/docsData.json", "test": "pnpm run build && pnpm run run-tests", "run-tests": "ava" }, @@ -85,6 +86,12 @@ "ts-toolbelt": "^9.6.0", "typescript": "catalog:ts7" }, + "exports": { + "./*.js": { + "types": "./dist/*.d.ts", + "default": "./dist/*.js" + } + }, "ava": { "files": [ "dist/**/*.test.js" diff --git a/backend/src/exportDocsData.ts b/backend/src/exportDocsData.ts new file mode 100644 index 000000000..715780b77 --- /dev/null +++ b/backend/src/exportDocsData.ts @@ -0,0 +1,34 @@ +import z from "zod"; +import { availableGlobalPlugins, availableGuildPlugins } from "./plugins/availablePlugins.js"; +import { ZeppelinPluginDocs } from "./types.js"; +import { writeFileSync } from "node:fs"; +import { GlobalPluginBlueprint, GuildPluginBlueprint } from "vety"; + +import type { ZeppelinPluginDocsData, ZeppelinDocsData } from "@zeppelinbot/shared/docsDataTypes.js"; + +const outputPath = process.argv[2]; +if (!outputPath) { + console.error("Output dir required"); + process.exit(1); +} + +function pluginToDocsData(plugin: GuildPluginBlueprint | GlobalPluginBlueprint, docs: ZeppelinPluginDocs): ZeppelinPluginDocsData { + return { + name: plugin.name, + prettyName: docs.prettyName ?? plugin.name, + type: docs.type, + description: docs.description, + usageGuide: docs.usageGuide, + configurationGuide: docs.configurationGuide, + configJsonSchema: z.toJSONSchema(docs.configSchema, { io: "input", cycles: "ref" }), + }; +} + +const docsData: ZeppelinDocsData = { + guildPlugins: availableGuildPlugins.map(({ plugin, docs }) => pluginToDocsData(plugin, docs)), + globalPlugins: availableGlobalPlugins.map(({ plugin, docs }) => pluginToDocsData(plugin, docs)), +}; + +writeFileSync(outputPath, JSON.stringify(docsData), { encoding: "utf8" }); + +process.exit(0); diff --git a/backend/src/exportSchemas.ts b/backend/src/exportSchemas.ts index dbe50eb46..7311cde9c 100644 --- a/backend/src/exportSchemas.ts +++ b/backend/src/exportSchemas.ts @@ -3,25 +3,7 @@ import { z } from "zod"; import { availableGuildPlugins } from "./plugins/availablePlugins.js"; import { zZeppelinGuildConfig } from "./types.js"; import { JSONSchema } from "zod/v4/core"; - -function makeJsonSchemaDeepPartial(schema: Record) { - if (schema.type === "object") { - delete schema.required; - } - for (const value of Object.values(schema)) { - if (value && typeof value === "object") { - if (Array.isArray(value)) { - for (const item of value) { - if (item && typeof item === "object") { - makeJsonSchemaDeepPartial(item); - } - } - } else { - makeJsonSchemaDeepPartial(value); - } - } - } -} +import { makeJsonSchemaDeepPartial } from "./utils/makeJsonSchemaDeepPartial.js"; const basePluginOverrideCriteriaSchema = z.strictObject({ channel: z diff --git a/backend/src/utils/makeJsonSchemaDeepPartial.ts b/backend/src/utils/makeJsonSchemaDeepPartial.ts new file mode 100644 index 000000000..b59413961 --- /dev/null +++ b/backend/src/utils/makeJsonSchemaDeepPartial.ts @@ -0,0 +1,18 @@ +export function makeJsonSchemaDeepPartial(schema: Record) { + if (schema.type === "object") { + delete schema.required; + } + for (const value of Object.values(schema)) { + if (value && typeof value === "object") { + if (Array.isArray(value)) { + for (const item of value) { + if (item && typeof item === "object") { + makeJsonSchemaDeepPartial(item); + } + } + } else { + makeJsonSchemaDeepPartial(value); + } + } + } +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a9da1db24..729b07fd5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -9,6 +9,10 @@ catalogs: typescript: specifier: 6.0.3 version: 6.0.3 + ts7: + typescript: + specifier: 7.0.2 + version: 7.0.2 overrides: discord.js: 14.23.2 @@ -330,6 +334,9 @@ importers: '@adonisjs/vite': specifier: ^6.0.2 version: 6.0.3(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/shield@9.0.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@adonisjs/session@8.1.0(770cc5139ed8289213226f432e14c982))(@japa/plugin-adonisjs@5.2.0(@adonisjs/core@7.6.0(@adonisjs/assembler@8.5.2(typescript@6.0.3))(@vinejs/vine@4.4.0)(edge.js@6.5.1)(pino-pretty@13.2.0)(supports-color@10.2.2)(youch@4.1.1))(@japa/browser-client@2.3.0(@japa/assert@4.2.0(@japa/runner@5.3.0))(@japa/runner@5.3.0)(playwright@1.64.0))(@japa/runner@5.3.0)(playwright@1.64.0))(edge.js@6.5.1))(edge.js@6.5.1)(vite@8.3.4(@types/node@26.6.5)(jiti@2.7.0)(yaml@2.9.0)) + '@fontsource-variable/playpen-sans': + specifier: ^5.3.0 + version: 5.3.0 '@fontsource-variable/recursive': specifier: ^5.3.0 version: 5.3.0 @@ -348,6 +355,9 @@ importers: '@vue/server-renderer': specifier: ^3.5.43 version: 3.5.43 + '@zeppelinbot/shared': + specifier: workspace:* + version: link:../shared edge.js: specifier: ^6.5.1 version: 6.5.1 @@ -369,6 +379,9 @@ importers: vue-sonner: specifier: ^2.0.9 version: 2.0.9 + zod: + specifier: ^4.4.3 + version: 4.4.3 devDependencies: '@adonisjs/assembler': specifier: ^8.5.2 @@ -944,6 +957,9 @@ packages: '@fastify/static@7.0.4': resolution: {integrity: sha512-p2uKtaf8BMOZWLs6wu+Ihg7bWNBdjNgCwDza4MJtTqg+5ovKmcbgbR9Xs5/smZ1YISfzKOCNYmZV8LaCj+eJ1Q==} + '@fontsource-variable/playpen-sans@5.3.0': + resolution: {integrity: sha512-IoqGZSrVkaGXgD61IGkSOF0nTNmb8I4gyxZxpuHXCocAj4he5sL4oLWy1BmyiZiDv0pUeopaKQv9Q2Zpnse87Q==} + '@fontsource-variable/recursive@5.3.0': resolution: {integrity: sha512-4B4/lWCVeZgdbpJdIIU1sOVO/ECjjM673ohuxvyQ6uCK41TPlGzKRNokKY84noUgGYnpwc//MW4k2KrOMY19jQ==} @@ -5705,6 +5721,8 @@ snapshots: fastq: 1.20.1 glob: 10.5.0 + '@fontsource-variable/playpen-sans@5.3.0': {} + '@fontsource-variable/recursive@5.3.0': {} '@inertiajs/core@3.9.1': diff --git a/portal/.adonisjs/client/registry/index.ts b/portal/.adonisjs/client/registry/index.ts index 184eda5ad..3c4011d4b 100644 --- a/portal/.adonisjs/client/registry/index.ts +++ b/portal/.adonisjs/client/registry/index.ts @@ -12,6 +12,12 @@ const routes = { tokens: [{"old":"/","type":0,"val":"/","end":""}], types: placeholder as Registry['splash.get_index']['types'], }, + 'docs.get_index': { + methods: ["GET","HEAD"], + pattern: '/docs', + tokens: [{"old":"/docs","type":0,"val":"docs","end":""}], + types: placeholder as Registry['docs.get_index']['types'], + }, } as const satisfies Record export { routes } diff --git a/portal/.adonisjs/client/registry/schema.d.ts b/portal/.adonisjs/client/registry/schema.d.ts index a85956444..d574203f9 100644 --- a/portal/.adonisjs/client/registry/schema.d.ts +++ b/portal/.adonisjs/client/registry/schema.d.ts @@ -19,4 +19,16 @@ export interface Registry { errorResponse: ExtractErrorResponse>> } } + 'docs.get_index': { + methods: ["GET","HEAD"] + pattern: '/docs' + types: { + body: {} + paramsTuple: [] + params: {} + query: {} + response: ExtractResponse>> + errorResponse: ExtractErrorResponse>> + } + } } diff --git a/portal/.adonisjs/client/registry/tree.d.ts b/portal/.adonisjs/client/registry/tree.d.ts index 742080652..7d464955e 100644 --- a/portal/.adonisjs/client/registry/tree.d.ts +++ b/portal/.adonisjs/client/registry/tree.d.ts @@ -5,4 +5,7 @@ export interface ApiDefinition { splash: { getIndex: typeof routes['splash.get_index'] } + docs: { + getIndex: typeof routes['docs.get_index'] + } } diff --git a/portal/.adonisjs/server/controllers.ts b/portal/.adonisjs/server/controllers.ts index c135649bc..ace0bdb84 100644 --- a/portal/.adonisjs/server/controllers.ts +++ b/portal/.adonisjs/server/controllers.ts @@ -4,6 +4,9 @@ */ export const controllers = { + docs: { + Docs: () => import('#backend/features/docs/controllers/DocsController'), + }, splash: { Splash: () => import('#backend/features/splash/controllers/SplashController'), }, diff --git a/portal/.adonisjs/server/pages.d.ts b/portal/.adonisjs/server/pages.d.ts index 9555263fc..26a7125b0 100644 --- a/portal/.adonisjs/server/pages.d.ts +++ b/portal/.adonisjs/server/pages.d.ts @@ -17,6 +17,8 @@ declare module '@adonisjs/inertia/types' { export interface InertiaPages { + 'features/docs/pages/DocsIndex': ExtractProps<(typeof import('../../inertia/features/docs/pages/DocsIndex.vue'))['default']> + 'features/errors/pages/NotFound': ExtractProps<(typeof import('../../inertia/features/errors/pages/NotFound.vue'))['default']> 'features/errors/pages/ServerError': ExtractProps<(typeof import('../../inertia/features/errors/pages/ServerError.vue'))['default']> diff --git a/portal/.adonisjs/server/routes.d.ts b/portal/.adonisjs/server/routes.d.ts index fc464179c..ebe3f5e7b 100644 --- a/portal/.adonisjs/server/routes.d.ts +++ b/portal/.adonisjs/server/routes.d.ts @@ -5,12 +5,15 @@ type ParamValue = string | number | bigint | boolean export type ScannedRoutes = { ALL: { 'splash.get_index': { paramsTuple?: []; params?: {} } + 'docs.get_index': { paramsTuple?: []; params?: {} } } GET: { 'splash.get_index': { paramsTuple?: []; params?: {} } + 'docs.get_index': { paramsTuple?: []; params?: {} } } HEAD: { 'splash.get_index': { paramsTuple?: []; params?: {} } + 'docs.get_index': { paramsTuple?: []; params?: {} } } } declare module '@adonisjs/core/types/http' { diff --git a/portal/app/features/docs/controllers/DocsController.ts b/portal/app/features/docs/controllers/DocsController.ts new file mode 100644 index 000000000..d5744b6e1 --- /dev/null +++ b/portal/app/features/docs/controllers/DocsController.ts @@ -0,0 +1,7 @@ +import type { HttpContext } from "@adonisjs/core/http"; + +export default class DocsController { + async getIndex({ inertia }: HttpContext) { + return inertia.render("features/docs/pages/DocsIndex", {}); + } +} diff --git a/portal/app/features/docs/utils/docsLayoutData.ts b/portal/app/features/docs/utils/docsLayoutData.ts new file mode 100644 index 000000000..ee151d2ad --- /dev/null +++ b/portal/app/features/docs/utils/docsLayoutData.ts @@ -0,0 +1,40 @@ +import { MenuCategory } from "#backend/features/menu/types"; +import { docsData } from "@zeppelinbot/shared/docsData.js"; + +const sortedGuildPlugins = docsData.guildPlugins.toSorted((a, b) => { + if (a.prettyName.toLowerCase() > b.prettyName.toLowerCase()) return 1; + if (a.prettyName.toLowerCase() < b.prettyName.toLowerCase()) return 1; + return 0; +}); + +const menu: MenuCategory[] = [ + { + title: "General", + items: [ + { + label: "Introduction", + path: "/docs", + }, + ], + }, + { + title: "Plugins", + items: sortedGuildPlugins.filter((p) => p.type === "stable").map((p) => ({ + label: p.prettyName, + path: `/docs/plugins/${p.name}` + })), + }, + { + title: "Legacy plugins", + items: sortedGuildPlugins.filter((p) => p.type === "legacy").map((p) => ({ + label: p.prettyName, + path: `/docs/plugins/${p.name}` + })), + }, +]; + +export const docsLayoutData = { + menu, +}; + +export type DocsLayoutData = typeof docsLayoutData; diff --git a/portal/app/features/docs/utils/formatZodConfigSchema.ts b/portal/app/features/docs/utils/formatZodConfigSchema.ts new file mode 100644 index 000000000..85c7c0fd6 --- /dev/null +++ b/portal/app/features/docs/utils/formatZodConfigSchema.ts @@ -0,0 +1,104 @@ +import { z } from "zod"; +import { $ZodPipeDef } from "zod/v4/core"; + +function indentLine(str: string, indentLength: number) { + return " ".repeat(indentLength) + str; +} + +function indentLines(str: string, indentLength: number) { + return str + .split("\n") + .map((line) => indentLine(line, indentLength)) + .join("\n"); +} + +function isZodObject(schema: z.ZodType): schema is z.ZodObject { + return schema.def.type === "object"; +} + +function isZodRecord(schema: z.ZodType): schema is z.ZodRecord { + return schema.def.type === "record"; +} + +function isZodOptional(schema: z.ZodType): schema is z.ZodOptional { + return schema.def.type === "optional"; +} + +function isZodArray(schema: z.ZodType): schema is z.ZodArray { + return schema.def.type === "array"; +} + +function isZodUnion(schema: z.ZodType): schema is z.ZodUnion { + return schema.def.type === "union"; +} + +function isZodNullable(schema: z.ZodType): schema is z.ZodNullable { + return schema.def.type === "nullable"; +} + +function isZodDefault(schema: z.ZodType): schema is z.ZodDefault { + return schema.def.type === "default"; +} + +function isZodLiteral(schema: z.ZodType): schema is z.ZodLiteral { + return schema.def.type === "literal"; +} + +function isZodIntersection(schema: z.ZodType): schema is z.ZodIntersection { + return schema.def.type === "intersection"; +} + +export function formatZodConfigSchema(schema: z.ZodType): string { + if (isZodObject(schema)) { + return ( + `{\n` + + Object.entries(schema.def.shape) + .map(([k, value]) => indentLines(`${k}: ${formatZodConfigSchema(value as z.ZodType)}`, 2)) + .join("\n") + + "\n}" + ); + } + if (isZodRecord(schema)) { + return "{\n" + indentLines(`[string]: ${formatZodConfigSchema(schema.valueType as z.ZodType)}`, 2) + "\n}"; + } + if (isZodOptional(schema)) { + return `Optional<${formatZodConfigSchema(schema.def.innerType)}>`; + } + if (isZodArray(schema)) { + return `Array<${formatZodConfigSchema(schema.def.element)}>`; + } + if (isZodUnion(schema)) { + return schema.def.options.map((t: any) => formatZodConfigSchema(t)).join(" | "); + } + if (isZodNullable(schema)) { + return `Nullable<${formatZodConfigSchema(schema.def.innerType)}>`; + } + if (isZodDefault(schema)) { + return formatZodConfigSchema(schema.def.innerType); + } + if (isZodLiteral(schema)) { + return schema.def.values.join(" | "); + } + if (isZodIntersection(schema)) { + return [ + formatZodConfigSchema(schema.def.left as z.ZodType), + formatZodConfigSchema(schema.def.right as z.ZodType), + ].join(" & "); + } + if (schema.def.type === "string") { + return "string"; + } + if (schema.def.type === "number") { + return "number"; + } + if (schema.def.type === "boolean") { + return "boolean"; + } + if (schema.def.type === "never") { + return "never"; + } + if (schema.def.type === "pipe") { + return formatZodConfigSchema((schema.def as $ZodPipeDef).in as z.ZodType); + } + return "unknown"; +} diff --git a/portal/app/features/menu/types.ts b/portal/app/features/menu/types.ts new file mode 100644 index 000000000..a1905854c --- /dev/null +++ b/portal/app/features/menu/types.ts @@ -0,0 +1,10 @@ +export interface MenuItem { + label: string; + path: string; + activeStartsWith?: boolean; +} + +export interface MenuCategory { + title: string; + items: MenuItem[]; +} diff --git a/portal/inertia/app.ts b/portal/inertia/app.ts index abbecfb79..79e55b5c6 100644 --- a/portal/inertia/app.ts +++ b/portal/inertia/app.ts @@ -1,4 +1,5 @@ import "@fontsource-variable/recursive"; +import "@fontsource-variable/playpen-sans"; import "./css/global.css"; import "vue-sonner/style.css"; import { client } from "#frontend/client.js"; @@ -7,7 +8,7 @@ import { TuyauProvider } from "@adonisjs/inertia/vue"; import { createApp, type DefineComponent, h } from "vue"; import { resolvePageComponent } from "@adonisjs/inertia/helpers"; -const appName = import.meta.env.VITE_APP_NAME || "AdonisJS"; +const appName = import.meta.env.VITE_APP_NAME || "Zeppelin"; createInertiaApp({ title: (title) => (title ? `${title} - ${appName}` : appName), diff --git a/portal/inertia/assets/charcoal-noise.webp b/portal/inertia/assets/charcoal-noise.webp index 88a654b79f39c524fd7cfa1052b14216d0279010..a2d456d30d412891b066b6edf9480d985914bb4a 100644 GIT binary patch literal 25334 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 z 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 w$x}j*KyTapCl5YvG0_8LCdD - - - + + diff --git a/portal/inertia/components/MainMenuItem.vue b/portal/inertia/components/MainMenuItem.vue index ef51c2fcd..ec8c75f20 100644 --- a/portal/inertia/components/MainMenuItem.vue +++ b/portal/inertia/components/MainMenuItem.vue @@ -14,8 +14,6 @@ color: inherit; } .squiggle { - width: 100%; - height: 4px; visibility: hidden; } .active .squiggle { diff --git a/portal/inertia/components/Squiggle.vue b/portal/inertia/components/Squiggle.vue index 75c9b58e7..0c27344bf 100644 --- a/portal/inertia/components/Squiggle.vue +++ b/portal/inertia/components/Squiggle.vue @@ -7,5 +7,8 @@ background-image: url(../assets/squiggle.svg); background-repeat: repeat-x; background-size: auto 100%; + + width: 100%; + height: 4px; } diff --git a/portal/inertia/css/global.css b/portal/inertia/css/global.css index e00a91b97..46d0fe283 100644 --- a/portal/inertia/css/global.css +++ b/portal/inertia/css/global.css @@ -85,18 +85,8 @@ --text-xl: 32px; --text-xl2: 40px; --text-xl3: 48px; -} -*, -*::before, -*::after { - box-sizing: border-box; -} - -body { - margin: 0; - font: - 16px/1.2 "Recursive Variable", + --font-stack-system-sans: -apple-system, BlinkMacSystemFont, avenir next, @@ -111,5 +101,31 @@ body { helvetica, arial, sans-serif; + --font-stack-recursive: "Recursive Variable", var(--font-stack-system-sans); + --font-stack-playpen-sans: "Playpen Sans Variable", var(--font-stack-system-sans); +} + +*, +*::before, +*::after { + box-sizing: border-box; +} + +body { + margin: 0; + font: 16px/1.2 var(--font-stack-system-sans); font-weight: 400; } + +@layer base { + body { + background-color: white; + color: black; + } + @media (prefers-color-scheme: dark) { + body { + background-color: black; + color: white; + } + } +} diff --git a/portal/inertia/features/docs/layouts/DocsLayout.vue b/portal/inertia/features/docs/layouts/DocsLayout.vue new file mode 100644 index 000000000..194428f3a --- /dev/null +++ b/portal/inertia/features/docs/layouts/DocsLayout.vue @@ -0,0 +1,34 @@ + + + + + diff --git a/portal/inertia/features/docs/pages/DocsIndex.vue b/portal/inertia/features/docs/pages/DocsIndex.vue new file mode 100644 index 000000000..7c100af58 --- /dev/null +++ b/portal/inertia/features/docs/pages/DocsIndex.vue @@ -0,0 +1,37 @@ + + + diff --git a/portal/inertia/components/ContentPaper.vue b/portal/inertia/features/layout/ContentPaper.vue similarity index 66% rename from portal/inertia/components/ContentPaper.vue rename to portal/inertia/features/layout/ContentPaper.vue index 92192fc8e..11f5cc0d3 100644 --- a/portal/inertia/components/ContentPaper.vue +++ b/portal/inertia/features/layout/ContentPaper.vue @@ -3,8 +3,8 @@
@@ -14,6 +14,8 @@ diff --git a/portal/inertia/features/layout/MainLayout.vue b/portal/inertia/features/layout/MainLayout.vue new file mode 100644 index 000000000..709cbd62d --- /dev/null +++ b/portal/inertia/features/layout/MainLayout.vue @@ -0,0 +1,229 @@ + + + + + + + diff --git a/portal/inertia/features/layout/PaperH1.vue b/portal/inertia/features/layout/PaperH1.vue new file mode 100644 index 000000000..bd26ee61e --- /dev/null +++ b/portal/inertia/features/layout/PaperH1.vue @@ -0,0 +1,11 @@ + + + diff --git a/portal/inertia/features/layout/SidebarMenu.vue b/portal/inertia/features/layout/SidebarMenu.vue new file mode 100644 index 000000000..5632123c5 --- /dev/null +++ b/portal/inertia/features/layout/SidebarMenu.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/portal/inertia/components/WithSidebar.vue b/portal/inertia/features/layout/WithSidebar.vue similarity index 89% rename from portal/inertia/components/WithSidebar.vue rename to portal/inertia/features/layout/WithSidebar.vue index be640b832..db02145d9 100644 --- a/portal/inertia/components/WithSidebar.vue +++ b/portal/inertia/features/layout/WithSidebar.vue @@ -13,10 +13,10 @@ .with-sidebar { display: flex; align-items: flex-start; - gap: 32px; + gap: 24px; } .sidebar-wrap { - flex: 0 0 240px; + flex: 0 0 calc(96px * 2.5); } .content-wrap { flex: 1 1 100%; diff --git a/portal/inertia/features/layout/measurements.ts b/portal/inertia/features/layout/measurements.ts new file mode 100644 index 000000000..eb6b15ae4 --- /dev/null +++ b/portal/inertia/features/layout/measurements.ts @@ -0,0 +1 @@ +export const LAYOUT_GRID_SIZE_PX = 48; diff --git a/portal/inertia/features/pageCounter/usePageCount.ts b/portal/inertia/features/pageCounter/usePageCount.ts new file mode 100644 index 000000000..a9bd37106 --- /dev/null +++ b/portal/inertia/features/pageCounter/usePageCount.ts @@ -0,0 +1,3 @@ +export function usePageCount() { + +} diff --git a/portal/inertia/features/splash/pages/SplashIndex.vue b/portal/inertia/features/splash/pages/SplashIndex.vue index 297108ff1..90be945f9 100644 --- a/portal/inertia/features/splash/pages/SplashIndex.vue +++ b/portal/inertia/features/splash/pages/SplashIndex.vue @@ -1,5 +1,5 @@ - + diff --git a/portal/inertia/features/docs/pages/DocsIndex.vue b/portal/inertia/features/docs/pages/DocsIndex.vue index 7c100af58..6a6156929 100644 --- a/portal/inertia/features/docs/pages/DocsIndex.vue +++ b/portal/inertia/features/docs/pages/DocsIndex.vue @@ -4,34 +4,35 @@

Introduction

-

- Zeppelin is a private moderation bot for Discord, designed with large servers and reliability in mind. -

+

Zeppelin is a private moderation bot for Discord, designed with large servers and reliability in mind.

Getting the bot

- Access to the bot is granted on a case by case basis. For details, please see the #info channel on the Official Zeppelin Discord server. + Access to the bot is granted on a case by case basis. For details, please see the #info channel on the + Official Zeppelin Discord server.

Configuration

- All Zeppelin configuration is done through the dashboard by editing a YAML config file. - By default, only the server owner has access to this, but they can give other users access as they see fit. - See Configuration format for more details. + All Zeppelin configuration is done through the dashboard by editing a YAML config file. By default, only the + server owner has access to this, but they can give other users access as they see fit. See + Configuration format for more details.

Plugins

- Zeppelin is divided into plugins: grouped functionality that can be enabled/disabled as needed, and that have their own configurations. + Zeppelin is divided into plugins: grouped functionality that can be enabled/disabled as needed, and that have + their own configurations.

Commands

- The commands for each plugin are listed on the plugin's page (see "Plugins" on the menu). On these pages, the command prefix is assumed to be ! but this can be changed on a per-server basis. + The commands for each plugin are listed on the plugin's page (see "Plugins" on the menu). On these pages, the + command prefix is assumed to be ! but this can be changed on a per-server basis.

diff --git a/portal/inertia/features/layout/ContentPaper.vue b/portal/inertia/features/layout/ContentPaper.vue index f093f8359..2b1ffa11b 100644 --- a/portal/inertia/features/layout/ContentPaper.vue +++ b/portal/inertia/features/layout/ContentPaper.vue @@ -22,7 +22,7 @@ --stripe-color: rgba(0, 0, 0, 0.005); color: var(--color-ink-dark); position: relative; - + background-image: radial-gradient(circle at bottom right, rgba(0, 0, 0, 0.1) 0%, transparent 100%), repeating-linear-gradient( @@ -59,12 +59,12 @@ position: absolute; inset: 0; z-index: 1; - + background-image: radial-gradient(circle at bottom right, rgba(0, 0, 0, 0.1) 0%, transparent 100%); background-color: #ece8dd; transform: rotateZ(1deg) translateX(5px); - + box-shadow: 5px 5px 12px -2px rgba(0, 0, 0, 0.25); } @media (prefers-color-scheme: dark) { @@ -73,13 +73,14 @@ background: /* radial-gradient(circle at bottom right, rgba(0, 0, 0, 0.1) 0%, transparent 100%) 100% 100%, */ repeating-linear-gradient( - 1deg, - var(--stripe-color) 0px, - var(--stripe-color) 1px, - transparent 3px, - transparent 5px, - var(--stripe-color) 6px - ) 100% 100%, + 1deg, + var(--stripe-color) 0px, + var(--stripe-color) 1px, + transparent 3px, + transparent 5px, + var(--stripe-color) 6px + ) + 100% 100%, url(../../assets/charcoal-noise.webp) repeat top left / 50% 50%, #222; color: rgb(213, 213, 213); diff --git a/portal/inertia/features/layout/MainLayout.vue b/portal/inertia/features/layout/MainLayout.vue index b09e0346e..804f99ba9 100644 --- a/portal/inertia/features/layout/MainLayout.vue +++ b/portal/inertia/features/layout/MainLayout.vue @@ -31,7 +31,12 @@
- @@ -83,20 +88,17 @@ body { background: /* Grid 1 */ - linear-gradient(var(--grid1-color) 1px, transparent 1px) repeat calc(50% - var(--grid1-size) / 2) top / var(--grid1-size) var(--grid1-size), - linear-gradient(90deg, var(--grid1-color) 1px, transparent 1px) repeat calc(50% - var(--grid1-size) / 2) top / var(--grid1-size) var(--grid1-size), + linear-gradient(var(--grid1-color) 1px, transparent 1px) repeat calc(50% - var(--grid1-size) / 2) top / + var(--grid1-size) var(--grid1-size), + linear-gradient(90deg, var(--grid1-color) 1px, transparent 1px) repeat calc(50% - var(--grid1-size) / 2) top / + var(--grid1-size) var(--grid1-size), + /* Grid 2 */ linear-gradient(var(--grid2-color) 1px, transparent 1px) repeat calc(50% - var(--grid2-size) / 2) top / + var(--grid2-size) var(--grid2-size), + linear-gradient(90deg, var(--grid2-color) 1px, transparent 1px) repeat calc(50% - var(--grid2-size) / 2) top / + var(--grid2-size) var(--grid2-size), + /* "Light" / vignette */ radial-gradient(circle at 50% 160px, var(--bg-color1) 0, var(--bg-color2) 1200px) no-repeat + center / 100% 100%; - /* Grid 2 */ - linear-gradient(var(--grid2-color) 1px, transparent 1px) repeat calc(50% - var(--grid2-size) / 2) top / var(--grid2-size) var(--grid2-size), - linear-gradient(90deg, var(--grid2-color) 1px, transparent 1px) repeat calc(50% - var(--grid2-size) / 2) top / var(--grid2-size) var(--grid2-size), - - /* "Light" / vignette */ - radial-gradient( - circle at 50% 160px, - var(--bg-color1) 0, - var(--bg-color2) 1200px - ) no-repeat center / 100% 100%; - min-height: 100vh; font: 14px/1.4 var(--font-stack-playpen-sans); } @@ -196,7 +198,9 @@ body { } .mobile-menu { display: none; - background: url(../../assets/charcoal-noise.webp) repeat top left / 50% 50%, #222; + background: + url(../../assets/charcoal-noise.webp) repeat top left / 50% 50%, + #222; padding: 24px; box-shadow: 5px 5px 16px -2px rgba(0, 0, 0, 0.75); margin-top: -48px; @@ -290,22 +294,26 @@ onMounted(() => { mounted.value = true; }); -const rootCss = computed(() => ` +const rootCss = computed( + () => ` :root { --layout-grid-size: ${LAYOUT_GRID_SIZE_PX}px; } -`); +`, +); const breakpointSteps = [8, 9, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30]; const wrapCss = computed(() => { return breakpointSteps - .map((step) => ` + .map( + (step) => ` @media (min-width: ${step * LAYOUT_GRID_SIZE_PX}px) { .main-layout-wrap { width: ${step * LAYOUT_GRID_SIZE_PX}px !important; } } - `) + `, + ) .join("\n"); }); diff --git a/portal/inertia/features/layout/SidebarMenu.vue b/portal/inertia/features/layout/SidebarMenu.vue index cd2d675ce..5525b7b27 100644 --- a/portal/inertia/features/layout/SidebarMenu.vue +++ b/portal/inertia/features/layout/SidebarMenu.vue @@ -57,11 +57,11 @@ -