diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..f7517d2 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,88 @@ +# Build artefacts +node_modules +.pnpm-store +build +.svelte-kit +.svelte-kit-test +.output +.vercel +.netlify +.wrangler + +# Vite caches +.vite +.cache +*.tsbuildinfo +vite.config.js.timestamp-* +vite.config.ts.timestamp-* + +# Tests, coverage, editor noise +coverage +coverage-* +*.lcov +.nyc_output +.idea +.vscode/* +!.vscode/extensions.json +!.vscode/settings.json +*.swp +*.swo +*~ + +# OS junk +.DS_Store +Thumbs.db + +# Logs / temp +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* +tmp +temp +*.tmp +*.temp + +# Env / secrets — must never be baked into the image +.env +.env.* +!.env.example +!.env.test + +# Source control +.git +.gitignore +.github +.worktrees +.gitattributes + +# Project-local supabase / docker artefacts +supabase/.temp +supabase/.env +supabase/.env.* +docker-compose*.yml +Dockerfile +.dockerignore + +# Docs that don't belong in the runtime image (kept locally only) +README.md +CHANGELOG.md +CONTRIBUTING.md +LICENSE +SECURITY.md +osv-scanner.toml +.releaserc.cjs +.cursor +.clusterfuzzlite + +# Test fixtures / mocks +src/mocks +*.test.ts +*.test.js +*.spec.ts +*.spec.js +__tests__ +tests \ No newline at end of file diff --git a/.env.example b/.env.example index 5af81fb..3cd9230 100644 --- a/.env.example +++ b/.env.example @@ -1,21 +1,74 @@ -PUBLIC_SUPABASE_URL=https://your-project.supabase.co -PUBLIC_SUPABASE_ANON_KEY=your-anon-key -# Required for workflow runs cache writes (server-only; bypasses RLS so cache table can be written) -SUPABASE_SERVICE_ROLE_KEY=your-service-role-key - -# Production only: set to your app URL (e.g. https://your-project.pages.dev) so OAuth redirects back to the app instead of localhost -# PUBLIC_APP_URL=https://your-project.pages.dev - -# ─── GitHub App (AI Optimization → Apply as PR) ──────────────────────────── -# Create a GitHub App at https://github.com/settings/apps/new with: -# Permissions: Contents (Read & Write), Pull requests (Read & Write), Workflows (Read & Write), Actions (Read) -# Callback URL: https://your-project.pages.dev/auth/github-app/callback -# For local dev: http://localhost:5173/auth/github-app/callback -# -# GITHUB_APP_ID: the numeric App ID shown on the App settings page -# GITHUB_APP_PRIVATE_KEY: the RSA private key downloaded from the App settings page. -# Store the full PEM content (multi-line), or collapse newlines to literal \n for single-line secrets. -# GITHUB_APP_SLUG: the URL slug of your App (e.g. "workflow-metrics-bot" from github.com/apps/workflow-metrics-bot) +# ============================================================================= +# DATABASE — pick ONE of the two blocks below and delete the other. +# ============================================================================= + +# --- (A) Bundled Postgres (docker compose with the postgres overlay) ------- +# Use this when `docker compose -f docker-compose.yml -f docker-compose.postgres.yml up`. +# The hostname `postgres` is the service name in docker-compose.postgres.yml. +# POSTGRES_PASSWORD is also defined below for the postgres container itself. +DATABASE_URL=postgres://workflow_metrics:${POSTGRES_PASSWORD}@postgres:5432/workflow_metrics + +# --- (B) External Postgres (managed, K8s, or your own instance) ----------- +# Uncomment and replace the placeholders. sslmode=require is recommended for +# managed Postgres providers (Neon, RDS, Crunchy Bridge, Supabase pooled, …). +# DATABASE_URL=postgres://workflow_metrics:CHANGE_ME@db.example.com:5432/workflow_metrics?sslmode=require + +# Required only when using bundled mode (block A). The compose overlay reads +# this to provision the postgres container. +POSTGRES_PASSWORD=change-me-local-dev-password +# Optional — defaults are workflow_metrics / workflow_metrics if unset. +# POSTGRES_DB=workflow_metrics +# POSTGRES_USER=workflow_metrics + +# ============================================================================= +# BETTER AUTH — Stage 2a wires these. Listed here so docker compose / Helm +# can inject them now without a second round of edits. +# Generate BETTER_AUTH_SECRET with: openssl rand -base64 32 +# ============================================================================= +BETTER_AUTH_SECRET=change-me-run-openssl-rand-base64-32 +# The public URL where the app is reachable. Used as the OAuth callback base. +BETTER_AUTH_URL=http://localhost:3000 + +# ============================================================================= +# GITHUB OAUTH (login) +# Create an OAuth App at https://github.com/settings/applications/new. +# Authorization callback URL (after Better Auth lands) = ${BETTER_AUTH_URL}/api/auth/callback/github +# ============================================================================= +GITHUB_CLIENT_ID=your-github-oauth-app-client-id +GITHUB_CLIENT_SECRET=your-github-oauth-app-client-secret + +# ============================================================================= +# GITHUB APP (Apply as PR) +# Separate from the OAuth App above. Create at https://github.com/settings/apps/new. +# Repository permissions: Contents (R/W), Pull requests (R/W), Workflows (R/W), Actions (R). +# ============================================================================= GITHUB_APP_ID=your-github-app-id +# Multi-line PEM is fine. Or collapse newlines to literal \n for single-line secrets. GITHUB_APP_PRIVATE_KEY="-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----" GITHUB_APP_SLUG=your-github-app-slug + +# ============================================================================= +# APP +# ============================================================================= +# Production URL of the app (no trailing slash). OAuth redirects back here. +PUBLIC_APP_URL=http://localhost:3000 +# Node adapter binds to HOST:PORT (defaults 0.0.0.0:3000). Override per-env here. +HOST=0.0.0.0 +PORT=3000 + +# ============================================================================= +# MISTRAL AI (optional) +# Per-user keys are entered in Settings and stored in the DB. This server-wide +# fallback is used when no per-user key is set (e.g. demos). +# ============================================================================= +# MISTRAL_API_KEY=your-mistral-api-key + +# ============================================================================= +# DEPRECATED — Supabase +# The app still calls `locals.supabase.*`. These are required until Stage 4 +# removes the Supabase wiring. Do not delete yet. +# ============================================================================= +PUBLIC_SUPABASE_URL=https://your-project.supabase.co +PUBLIC_SUPABASE_ANON_KEY=your-anon-key +# Server-only; bypasses RLS for cache writes. Never expose to the browser. +SUPABASE_SERVICE_ROLE_KEY=your-service-role-key \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..6b4126f --- /dev/null +++ b/Dockerfile @@ -0,0 +1,76 @@ +# syntax=docker/dockerfile:1.7 +ARG NODE_VERSION=24-alpine + +# ============================================================================ +# Stage 1 — install all dependencies (dev + prod) using the frozen lockfile +# ============================================================================ +FROM node:${NODE_VERSION} AS deps +WORKDIR /app + +# Corepack ships with Node 16+; pin the exact pnpm version from package.json +# so the lockfile interpretation matches local dev and CI. +RUN corepack enable && corepack prepare pnpm@10.30.3 --activate + +# Copy only the manifests so this layer is reused across source-only changes. +COPY package.json pnpm-lock.yaml pnpm-workspace.yaml .npmrc ./ +RUN --mount=type=cache,id=pnpm,target=/pnpm/store \ + pnpm config set store-dir /pnpm/store && \ + pnpm install --frozen-lockfile + +# ============================================================================ +# Stage 2 — build the SvelteKit Node bundle and prune dev dependencies +# ============================================================================ +FROM node:${NODE_VERSION} AS build +WORKDIR /app + +RUN corepack enable && corepack prepare pnpm@10.30.3 --activate + +# Reuse node_modules from the deps stage and copy the rest of the source. +COPY --from=deps /app/node_modules ./node_modules +COPY . . + +# SvelteKit's `$env/static/public` requires PUBLIC_* vars at build time. +# The Supabase wiring still imports them (Stage 4 will remove it). Provide +# placeholders so `pnpm build` succeeds without a `.env` in the image. Real +# values come from runtime env_file in docker-compose.yml / the Helm chart. +ENV PUBLIC_SUPABASE_URL=https://placeholder.supabase.co \ + PUBLIC_SUPABASE_ANON_KEY=placeholder-anon-key \ + PUBLIC_APP_URL=http://localhost:3000 + +# Build the Node adapter output to ./build and drop dev-only deps. +# CI=1 lets `pnpm prune --prod` run non-interactively inside the build. +RUN CI=1 pnpm build && CI=1 pnpm prune --prod + +# ============================================================================ +# Stage 3 — runtime image (small, non-root, healthchecked) +# ============================================================================ +FROM node:${NODE_VERSION} AS runtime +WORKDIR /app + +ENV NODE_ENV=production \ + PORT=3000 \ + HOST=0.0.0.0 + +# wget is used by the HEALTHCHECK below. node:alpine does not ship it. +# The base image already provides a non-root `node` user (uid/gid 1000), so we +# reuse it instead of creating a duplicate account. +RUN apk add --no-cache wget + +# Copy only what we need to run the app: the built bundle, pruned node_modules, +# and the package.json so any runtime introspection (engines, etc.) still works. +COPY --from=build --chown=node:node /app/build ./build +COPY --from=build --chown=node:node /app/node_modules ./node_modules +COPY --from=build --chown=node:node /app/package.json ./package.json + +USER node + +EXPOSE 3000 + +# Liveness/readiness probe target. Intentionally unauthenticated and DB-free +# — see src/routes/healthz/+server.ts. The Node process binds to HOST:PORT, +# so we probe via 127.0.0.1 to avoid any DNS surprises. +HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ + CMD wget --no-verbose --tries=1 --spider http://127.0.0.1:3000/healthz || exit 1 + +# Default SvelteKit adapter-node entry point. PORT and HOST above are honoured. +CMD ["node", "build/index.js"] \ No newline at end of file diff --git a/docker-compose.postgres.yml b/docker-compose.postgres.yml new file mode 100644 index 0000000..bc00687 --- /dev/null +++ b/docker-compose.postgres.yml @@ -0,0 +1,43 @@ +# Overlay that adds a bundled Postgres to the base compose. +# +# Use ONLY when you want Postgres to run alongside the app container (local +# dev, CI smoke tests, single-node deploys). The base docker-compose.yml +# stays Postgres-free so external-DB users don't pay for an unused service. +# +# Usage: +# +# docker compose -f docker-compose.yml -f docker-compose.postgres.yml up +# +# Requires Docker Compose v2.20+ for the `include:` directive. + +include: + - path: ./docker-compose.yml + +services: + app: + depends_on: + postgres: + condition: service_healthy + + postgres: + image: postgres:16-alpine + container_name: workflow-metrics-postgres + restart: unless-stopped + environment: + POSTGRES_DB: ${POSTGRES_DB:-workflow_metrics} + POSTGRES_USER: ${POSTGRES_USER:-workflow_metrics} + POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?POSTGRES_PASSWORD must be set when using bundled mode} + volumes: + - pgdata:/var/lib/postgresql/data + healthcheck: + test: + - CMD-SHELL + - pg_isready -U "$${POSTGRES_USER:-workflow_metrics}" -d "$${POSTGRES_DB:-workflow_metrics}" + interval: 5s + timeout: 5s + retries: 10 + start_period: 5s + +volumes: + pgdata: + name: workflow-metrics-pgdata \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..37912e7 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,37 @@ +# Base compose for workflow-metrics. +# +# This file ships the **app** service only. Postgres is intentionally not here +# so the same image works against a managed Postgres / K8s service / an existing +# instance — point `DATABASE_URL` in `.env` at it and `docker compose up`. +# +# Two ways to run: +# +# 1. Bundled Postgres (dev default) — bring in the overlay that adds one: +# +# docker compose -f docker-compose.yml -f docker-compose.postgres.yml up +# +# 2. External Postgres (managed, K8s, shared cluster) — point DATABASE_URL +# in .env at your instance, then just: +# +# docker compose -f docker-compose.yml up +# +# See `.env.example` for the matching DATABASE_URL forms. + +services: + app: + build: + context: . + dockerfile: Dockerfile + image: workflow-metrics:local + container_name: workflow-metrics-app + env_file: + - .env + environment: + # Ensure the runtime picks up the right interface and port even if the + # operator forgets to export them in .env. + HOST: ${HOST:-0.0.0.0} + PORT: ${PORT:-3000} + NODE_ENV: production + ports: + - "${PORT:-3000}:3000" + restart: unless-stopped \ No newline at end of file diff --git a/package.json b/package.json index 345c555..dd00711 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "dev": "vite dev", "build": "vite build", "preview": "vite preview", - "deploy": "pnpm run build && pnpm exec wrangler pages deploy .svelte-kit/cloudflare --project-name=workflow-metrics", + "start": "node build/index.js", "prepare": "svelte-kit sync || echo ''", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", @@ -43,7 +43,7 @@ }, "devDependencies": { "@eslint/js": "9.39.3", - "@sveltejs/adapter-cloudflare": "7.2.8", + "@sveltejs/adapter-node": "5.5.7", "@sveltejs/kit": "^2.60.1", "@sveltejs/vite-plugin-svelte": "6.2.4", "@tailwindcss/vite": "4.3.0", @@ -68,7 +68,6 @@ "typescript": "5.9.3", "typescript-eslint": "8.56.1", "vite": "6.4.3", - "vitest": "3.2.6", - "wrangler": "4.69.0" + "vitest": "3.2.6" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9faf8cd..fbd4ae3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -67,9 +67,9 @@ importers: '@eslint/js': specifier: 9.39.3 version: 9.39.3 - '@sveltejs/adapter-cloudflare': - specifier: 7.2.8 - version: 7.2.8(@sveltejs/kit@2.68.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.1(@typescript-eslint/types@8.56.1))(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(svelte@5.56.1(@typescript-eslint/types@8.56.1))(typescript@5.9.3)(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(wrangler@4.69.0) + '@sveltejs/adapter-node': + specifier: 5.5.7 + version: 5.5.7(@sveltejs/kit@2.68.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.1(@typescript-eslint/types@8.56.1))(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(svelte@5.56.1(@typescript-eslint/types@8.56.1))(typescript@5.9.3)(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0))) '@sveltejs/kit': specifier: ^2.60.1 version: 2.68.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.1(@typescript-eslint/types@8.56.1))(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(svelte@5.56.1(@typescript-eslint/types@8.56.1))(typescript@5.9.3)(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)) @@ -145,9 +145,6 @@ importers: vitest: specifier: 3.2.6 version: 3.2.6(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0) - wrangler: - specifier: 4.69.0 - version: 4.69.0 packages: @@ -202,56 +199,6 @@ packages: resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@cloudflare/kv-asset-handler@0.4.2': - resolution: {integrity: sha512-SIOD2DxrRRwQ+jgzlXCqoEFiKOFqaPjhnNTGKXSRLvp1HiOvapLaFG2kEr9dYQTYe8rKrd9uvDUzmAITeNyaHQ==} - engines: {node: '>=18.0.0'} - - '@cloudflare/unenv-preset@2.14.0': - resolution: {integrity: sha512-XKAkWhi1nBdNsSEoNG9nkcbyvfUrSjSf+VYVPfOto3gLTZVc3F4g6RASCMh6IixBKCG2yDgZKQIHGKtjcnLnKg==} - peerDependencies: - unenv: 2.0.0-rc.24 - workerd: ^1.20260218.0 - peerDependenciesMeta: - workerd: - optional: true - - '@cloudflare/workerd-darwin-64@1.20260305.0': - resolution: {integrity: sha512-chhKOpymo0Eh9J3nymrauMqKGboCc4uz/j0gA1G4gioMnKsN2ZDKJ+qjRZDnCoVGy8u2C4pxlmyIfsXCAfIzhQ==} - engines: {node: '>=16'} - cpu: [x64] - os: [darwin] - - '@cloudflare/workerd-darwin-arm64@1.20260305.0': - resolution: {integrity: sha512-K9aG2OQk5bBfOP+fyGPqLcqZ9OR3ra6uwnxJ8f2mveq2A2LsCI7ZeGxQiAj75Ti80ytH/gJffZIx4Np2JtU3aQ==} - engines: {node: '>=16'} - cpu: [arm64] - os: [darwin] - - '@cloudflare/workerd-linux-64@1.20260305.0': - resolution: {integrity: sha512-tt7XUoIw/cYFeGbkPkcZ6XX1aZm26Aju/4ih+DXxOosbBeGshFSrNJDBfAKKOvkjsAZymJ+WWVDBU+hmNaGfwA==} - engines: {node: '>=16'} - cpu: [x64] - os: [linux] - - '@cloudflare/workerd-linux-arm64@1.20260305.0': - resolution: {integrity: sha512-72QTkY5EzylmvCZ8ZTrnJ9DctmQsfSof1OKyOWqu/pv/B2yACfuPMikq8RpPxvVu7hhS0ztGP6ZvXz72Htq4Zg==} - engines: {node: '>=16'} - cpu: [arm64] - os: [linux] - - '@cloudflare/workerd-windows-64@1.20260305.0': - resolution: {integrity: sha512-BA0uaQPOaI2F6mJtBDqplGnQQhpXCzwEMI33p/TnDxtSk9u8CGIfBFuI6uqo8mJ6ijIaPjeBLGOn2CiRMET4qg==} - engines: {node: '>=16'} - cpu: [x64] - os: [win32] - - '@cloudflare/workers-types@4.20260228.1': - resolution: {integrity: sha512-gTpLuST3b1gdQfp+u1yiMavoE+n1g1CXuHeiDtlChOePVje+R/V92k6JeEY+6o9qVmQpHzluMe9j/OwvRJuCUg==} - - '@cspotcode/source-map-support@0.8.1': - resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} - engines: {node: '>=12'} - '@dagrejs/dagre@1.1.8': resolution: {integrity: sha512-5SEDlndt4W/LaVzPYJW+bSmSEZc9EzTf8rJ20WCKvjS5EAZAN0b+x0Yww7VMT4R3Wootkg+X9bUfUxazYw6Blw==} @@ -665,9 +612,6 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@jridgewell/trace-mapping@0.3.9': - resolution: {integrity: sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==} - '@layerstack/svelte-actions@1.0.1': resolution: {integrity: sha512-Tv8B3TeT7oaghx0R0I4avnSdfAT6GxEK+StL8k/hEaa009iNOIGFl3f76kfvNvPioQHAMFGtnWGLPHfsfD41nQ==} @@ -755,14 +699,50 @@ packages: '@polka/url@1.0.0-next.29': resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} - '@poppinss/colors@4.1.6': - resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + '@rollup/plugin-commonjs@29.0.3': + resolution: {integrity: sha512-ZaOxZceP7SOUW7Lqw5IRVweSQYWaeIPnXIGLiB690EBA3FGJTO40EEr2L5yZplJWsgTCogILRSpcAe7+U0Otdg==} + engines: {node: '>=16.0.0 || 14 >= 14.17'} + peerDependencies: + rollup: ^2.68.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-json@6.1.0': + resolution: {integrity: sha512-EGI2te5ENk1coGeADSIwZ7G2Q8CJS2sF120T7jLw4xFw9n7wIOXHo+kIYRAoVpJAN+kmqZSoO3Fp4JtoNF4ReA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true + + '@rollup/plugin-node-resolve@16.0.3': + resolution: {integrity: sha512-lUYM3UBGuM93CnMPG1YocWu7X802BrNF3jW2zny5gQyLQgRFJhV1Sq0Zi74+dh/6NBx1DxFC4b4GXg9wUCG5Qg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^2.78.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - '@poppinss/dumper@0.6.5': - resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} + '@rollup/plugin-replace@6.0.3': + resolution: {integrity: sha512-J4RZarRvQAm5IF0/LwUUg+obsm+xZhYnbMXmXROyoSE1ATJe3oXSb9L5MMppdxP2ylNSjv6zFBwKYjcKMucVfA==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true - '@poppinss/exception@1.2.3': - resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + '@rollup/pluginutils@5.4.0': + resolution: {integrity: sha512-MfPp06CjRLfXQ3wY0R8vJDYBy/MvVcc9OulEfR0B8Iv9ko+GCNaRZ+EpJYFl27LhKsZK0o420sYCRHCjfCgeUg==} + engines: {node: '>=14.0.0'} + peerDependencies: + rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0 + peerDependenciesMeta: + rollup: + optional: true '@rollup/rollup-android-arm-eabi@4.59.0': resolution: {integrity: sha512-upnNBkA6ZH2VKGcBj9Fyl9IGNPULcjXRlg0LLeaioQWueH30p6IXtJEbKAgvyv+mJaMxSm1l6xwDXYjpEMiLMg==} @@ -902,13 +882,6 @@ packages: cpu: [x64] os: [win32] - '@sindresorhus/is@7.2.0': - resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} - engines: {node: '>=18'} - - '@speed-highlight/core@1.2.14': - resolution: {integrity: sha512-G4ewlBNhUtlLvrJTb88d2mdy2KRijzs4UhnlrOSRT4bmjh/IqNElZa3zkrZ+TC47TwtlDWzVLFADljF1Ijp5hA==} - '@standard-schema/spec@1.1.0': resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} @@ -951,11 +924,10 @@ packages: peerDependencies: acorn: ^8.9.0 - '@sveltejs/adapter-cloudflare@7.2.8': - resolution: {integrity: sha512-bIdhY/Fi4AQmqiBdQVKnafH1h9Gw+xbCvHyUu4EouC8rJOU02zwhi14k/FDhQ0mJF1iblIu3m8UNQ8GpGIvIOQ==} + '@sveltejs/adapter-node@5.5.7': + resolution: {integrity: sha512-uOfc9eVlI3A37RRSaKcgrheBYPrfJwC9VMqDp8x/O6tlKdcLLvHThSWD0KNIbjQ/d+7bwLGx3vx6aowAcRfd2g==} peerDependencies: - '@sveltejs/kit': ^2.0.0 - wrangler: ^4.0.0 + '@sveltejs/kit': ^2.4.0 '@sveltejs/kit@2.68.0': resolution: {integrity: sha512-PdKiWsqinAoubVsSiRgVFkg3MHzGhQPnwQ8VxnGQKpZYijpapZ3UHHBje0GeByt2TvfjHPw+kxV+dNK2RIZg9g==} @@ -1124,6 +1096,9 @@ packages: '@types/phoenix@1.6.7': resolution: {integrity: sha512-oN9ive//QSBkf19rfDv45M7eZPi0eEXylht2OLEXicu5b4KoQ1OzXIw+xDSGWxSxe1JmepRR/ZH283vsu518/Q==} + '@types/resolve@1.20.2': + resolution: {integrity: sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q==} + '@types/trusted-types@2.0.7': resolution: {integrity: sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==} @@ -1323,9 +1298,6 @@ packages: '@internationalized/date': ^3.8.1 svelte: ^5.33.0 - blake3-wasm@2.1.5: - resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} - brace-expansion@1.1.13: resolution: {integrity: sha512-9ZLprWS6EENmhEOpjCYW2c8VkmOvckIJZfkr7rBW6dObmfgJ/L1GpSYW5Hpo9lDz4D1+n0Ckz8rU7FwHDQiG/w==} @@ -1391,6 +1363,9 @@ packages: resolution: {integrity: sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==} engines: {node: '>= 10'} + commondir@1.0.1: + resolution: {integrity: sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg==} + concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} @@ -1595,9 +1570,6 @@ packages: resolution: {integrity: sha512-SkE2t82KlkkxQRVMVLAGKxLfORGQfrkx5dkj+vlgXRVNEdPc4eZcR+J/Fvj8C+yKSFH5L0q3NFlyufOVQnCcYQ==} engines: {node: '>=10.13.0'} - error-stack-parser-es@1.0.5: - resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} - es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} @@ -1673,6 +1645,9 @@ packages: resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} engines: {node: '>=4.0'} + estree-walker@2.0.2: + resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} @@ -1847,10 +1822,16 @@ packages: resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} engines: {node: '>=0.10.0'} + is-module@1.0.0: + resolution: {integrity: sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g==} + is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} + is-reference@1.2.1: + resolution: {integrity: sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ==} + is-reference@3.0.3: resolution: {integrity: sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==} @@ -2071,11 +2052,6 @@ packages: resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==} engines: {node: '>=8.6'} - miniflare@4.20260305.0: - resolution: {integrity: sha512-jVhtKJtiwaZa3rI+WgoLvSJmEazDsoUmAPYRUmEe2VO6VSbvkhbnDRm+dsPbYRatgNIExwrpqG1rv96jHiSb0w==} - engines: {node: '>=18.0.0'} - hasBin: true - minimatch@10.2.4: resolution: {integrity: sha512-oRjTw/97aTBN0RHbYCdtF1MQfvusSIBQM0IZEgzl6426+8jSC0nF1a/GmnVLpfB9yyr6g6FTqWqiZVbxrtaCIg==} engines: {node: 18 || 20 || >=22} @@ -2167,9 +2143,6 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - pathe@2.0.3: resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} @@ -2355,10 +2328,6 @@ packages: resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} engines: {node: '>= 14.18.0'} - regexparam@3.0.0: - resolution: {integrity: sha512-RSYAtP31mvYLkAHrOlh25pCNQ5hWnT106VukGaaFfuJrZFkGRX5GhUAdPqpSDXxOhA2c4akmRuplv1mRqnBn6Q==} - engines: {node: '>=8'} - resolve-from@4.0.0: resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} engines: {node: '>=4'} @@ -2484,10 +2453,6 @@ packages: engines: {node: '>=16 || 14 >=14.17'} hasBin: true - 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'} @@ -2630,13 +2595,6 @@ packages: undici-types@7.18.2: resolution: {integrity: sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w==} - undici@7.28.0: - resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} - engines: {node: '>=20.18.1'} - - unenv@2.0.0-rc.24: - resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} - universal-user-agent@7.0.3: resolution: {integrity: sha512-TmnEAEAsBJVZM/AADELsK76llnwcf9vMKuPz8JflO1frO8Lchitr0fNaN9d+Ap0BjKtqWqd/J17qeDnXh8CL2A==} @@ -2741,25 +2699,6 @@ packages: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} - workerd@1.20260305.0: - resolution: {integrity: sha512-JkhfCLU+w+KbQmZ9k49IcDYc78GBo7eG8Mir8E2+KVjR7otQAmpcLlsous09YLh8WQ3Bt3Mi6/WMStvMAPukeA==} - engines: {node: '>=16'} - hasBin: true - - worktop@0.8.0-next.18: - resolution: {integrity: sha512-+TvsA6VAVoMC3XDKR5MoC/qlLqDixEfOBysDEKnPIPou/NvoPWCAuXHXMsswwlvmEuvX56lQjvELLyLuzTKvRw==} - engines: {node: '>=12'} - - wrangler@4.69.0: - resolution: {integrity: sha512-EmVfIM65I5b4ITHe3Y9R7zQyf4NUBQ1leStakMlWiVR9n6VlDwuEltyQI2l3i0JciDnWyR3uqe+T6C08ivniTQ==} - engines: {node: '>=20.0.0'} - hasBin: true - peerDependencies: - '@cloudflare/workers-types': ^4.20260305.0 - peerDependenciesMeta: - '@cloudflare/workers-types': - optional: true - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2793,12 +2732,6 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - youch-core@0.3.3: - resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} - - youch@4.1.0-beta.10: - resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} - zimmerframe@1.1.4: resolution: {integrity: sha512-B58NGBEoc8Y9MWWCQGl/gq9xBCe4IiKM0a2x7GZdQKOW5Exr8S1W24J6OgM1njK8xCRGvAJIL/MxXHf6SkmQKQ==} @@ -2853,35 +2786,6 @@ snapshots: '@bcoe/v8-coverage@1.0.2': {} - '@cloudflare/kv-asset-handler@0.4.2': {} - - '@cloudflare/unenv-preset@2.14.0(unenv@2.0.0-rc.24)(workerd@1.20260305.0)': - dependencies: - unenv: 2.0.0-rc.24 - optionalDependencies: - workerd: 1.20260305.0 - - '@cloudflare/workerd-darwin-64@1.20260305.0': - optional: true - - '@cloudflare/workerd-darwin-arm64@1.20260305.0': - optional: true - - '@cloudflare/workerd-linux-64@1.20260305.0': - optional: true - - '@cloudflare/workerd-linux-arm64@1.20260305.0': - optional: true - - '@cloudflare/workerd-windows-64@1.20260305.0': - optional: true - - '@cloudflare/workers-types@4.20260228.1': {} - - '@cspotcode/source-map-support@0.8.1': - dependencies: - '@jridgewell/trace-mapping': 0.3.9 - '@dagrejs/dagre@1.1.8': dependencies: '@dagrejs/graphlib': 2.2.4 @@ -3171,11 +3075,6 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@jridgewell/trace-mapping@0.3.9': - dependencies: - '@jridgewell/resolve-uri': 3.1.2 - '@jridgewell/sourcemap-codec': 1.5.5 - '@layerstack/svelte-actions@1.0.1': dependencies: '@floating-ui/dom': 1.7.5 @@ -3296,17 +3195,48 @@ snapshots: '@polka/url@1.0.0-next.29': {} - '@poppinss/colors@4.1.6': + '@rollup/plugin-commonjs@29.0.3(rollup@4.59.0)': dependencies: - kleur: 4.1.5 + '@rollup/pluginutils': 5.4.0(rollup@4.59.0) + commondir: 1.0.1 + estree-walker: 2.0.2 + fdir: 6.5.0(picomatch@2.3.2) + is-reference: 1.2.1 + magic-string: 0.30.21 + picomatch: 2.3.2 + optionalDependencies: + rollup: 4.59.0 - '@poppinss/dumper@0.6.5': + '@rollup/plugin-json@6.1.0(rollup@4.59.0)': dependencies: - '@poppinss/colors': 4.1.6 - '@sindresorhus/is': 7.2.0 - supports-color: 10.2.2 + '@rollup/pluginutils': 5.4.0(rollup@4.59.0) + optionalDependencies: + rollup: 4.59.0 + + '@rollup/plugin-node-resolve@16.0.3(rollup@4.59.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.59.0) + '@types/resolve': 1.20.2 + deepmerge: 4.3.1 + is-module: 1.0.0 + resolve: 1.22.11 + optionalDependencies: + rollup: 4.59.0 - '@poppinss/exception@1.2.3': {} + '@rollup/plugin-replace@6.0.3(rollup@4.59.0)': + dependencies: + '@rollup/pluginutils': 5.4.0(rollup@4.59.0) + magic-string: 0.30.21 + optionalDependencies: + rollup: 4.59.0 + + '@rollup/pluginutils@5.4.0(rollup@4.59.0)': + dependencies: + '@types/estree': 1.0.8 + estree-walker: 2.0.2 + picomatch: 2.3.2 + optionalDependencies: + rollup: 4.59.0 '@rollup/rollup-android-arm-eabi@4.59.0': optional: true @@ -3383,10 +3313,6 @@ snapshots: '@rollup/rollup-win32-x64-msvc@4.59.0': optional: true - '@sindresorhus/is@7.2.0': {} - - '@speed-highlight/core@1.2.14': {} - '@standard-schema/spec@1.1.0': {} '@supabase/auth-js@2.98.0': @@ -3440,12 +3366,14 @@ snapshots: dependencies: acorn: 8.16.0 - '@sveltejs/adapter-cloudflare@7.2.8(@sveltejs/kit@2.68.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.1(@typescript-eslint/types@8.56.1))(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(svelte@5.56.1(@typescript-eslint/types@8.56.1))(typescript@5.9.3)(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(wrangler@4.69.0)': + '@sveltejs/adapter-node@5.5.7(@sveltejs/kit@2.68.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.1(@typescript-eslint/types@8.56.1))(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(svelte@5.56.1(@typescript-eslint/types@8.56.1))(typescript@5.9.3)(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))': dependencies: - '@cloudflare/workers-types': 4.20260228.1 + '@rollup/plugin-commonjs': 29.0.3(rollup@4.59.0) + '@rollup/plugin-json': 6.1.0(rollup@4.59.0) + '@rollup/plugin-node-resolve': 16.0.3(rollup@4.59.0) + '@rollup/plugin-replace': 6.0.3(rollup@4.59.0) '@sveltejs/kit': 2.68.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.1(@typescript-eslint/types@8.56.1))(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(svelte@5.56.1(@typescript-eslint/types@8.56.1))(typescript@5.9.3)(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)) - worktop: 0.8.0-next.18 - wrangler: 4.69.0 + rollup: 4.59.0 '@sveltejs/kit@2.68.0(@opentelemetry/api@1.9.0)(@sveltejs/vite-plugin-svelte@6.2.4(svelte@5.56.1(@typescript-eslint/types@8.56.1))(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0)))(svelte@5.56.1(@typescript-eslint/types@8.56.1))(typescript@5.9.3)(vite@6.4.3(@types/node@25.3.2)(jiti@1.21.7)(lightningcss@1.32.0)(yaml@2.9.0))': dependencies: @@ -3597,6 +3525,8 @@ snapshots: '@types/phoenix@1.6.7': {} + '@types/resolve@1.20.2': {} + '@types/trusted-types@2.0.7': {} '@types/ws@8.18.1': @@ -3850,8 +3780,6 @@ snapshots: transitivePeerDependencies: - '@sveltejs/kit' - blake3-wasm@2.1.5: {} - brace-expansion@1.1.13: dependencies: balanced-match: 1.0.2 @@ -3918,6 +3846,8 @@ snapshots: commander@7.2.0: {} + commondir@1.0.1: {} + concat-map@0.0.1: {} cookie@1.1.1: {} @@ -4099,8 +4029,6 @@ snapshots: graceful-fs: 4.2.11 tapable: 2.3.3 - error-stack-parser-es@1.0.5: {} - es-module-lexer@1.7.0: {} esbuild@0.28.1: @@ -4228,6 +4156,8 @@ snapshots: estraverse@5.3.0: {} + estree-walker@2.0.2: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -4368,8 +4298,14 @@ snapshots: dependencies: is-extglob: 2.1.1 + is-module@1.0.0: {} + is-number@7.0.0: {} + is-reference@1.2.1: + dependencies: + '@types/estree': 1.0.8 + is-reference@3.0.3: dependencies: '@types/estree': 1.0.8 @@ -4580,18 +4516,6 @@ snapshots: braces: 3.0.3 picomatch: 2.3.2 - miniflare@4.20260305.0: - dependencies: - '@cspotcode/source-map-support': 0.8.1 - sharp: 0.34.5 - undici: 7.28.0 - workerd: 1.20260305.0 - ws: 8.21.0 - youch: 4.1.0-beta.10 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - minimatch@10.2.4: dependencies: brace-expansion: 5.0.6 @@ -4670,8 +4594,6 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.3 - path-to-regexp@6.3.0: {} - pathe@2.0.3: {} pathval@2.0.1: {} @@ -4771,8 +4693,6 @@ snapshots: readdirp@4.1.2: {} - regexparam@3.0.0: {} - resolve-from@4.0.0: {} resolve@1.22.11: @@ -4944,8 +4864,6 @@ snapshots: tinyglobby: 0.2.15 ts-interface-checker: 0.1.13 - supports-color@10.2.2: {} - supports-color@7.2.0: dependencies: has-flag: 4.0.0 @@ -5119,12 +5037,6 @@ snapshots: undici-types@7.18.2: {} - undici@7.28.0: {} - - unenv@2.0.0-rc.24: - dependencies: - pathe: 2.0.3 - universal-user-agent@7.0.3: {} uri-js@4.4.1: @@ -5225,35 +5137,6 @@ snapshots: word-wrap@1.2.5: {} - workerd@1.20260305.0: - optionalDependencies: - '@cloudflare/workerd-darwin-64': 1.20260305.0 - '@cloudflare/workerd-darwin-arm64': 1.20260305.0 - '@cloudflare/workerd-linux-64': 1.20260305.0 - '@cloudflare/workerd-linux-arm64': 1.20260305.0 - '@cloudflare/workerd-windows-64': 1.20260305.0 - - worktop@0.8.0-next.18: - dependencies: - mrmime: 2.0.1 - regexparam: 3.0.0 - - wrangler@4.69.0: - dependencies: - '@cloudflare/kv-asset-handler': 0.4.2 - '@cloudflare/unenv-preset': 2.14.0(unenv@2.0.0-rc.24)(workerd@1.20260305.0) - blake3-wasm: 2.1.5 - esbuild: 0.28.1 - miniflare: 4.20260305.0 - path-to-regexp: 6.3.0 - unenv: 2.0.0-rc.24 - workerd: 1.20260305.0 - optionalDependencies: - fsevents: 2.3.3 - transitivePeerDependencies: - - bufferutil - - utf-8-validate - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -5274,19 +5157,6 @@ snapshots: yocto-queue@0.1.0: {} - youch-core@0.3.3: - dependencies: - '@poppinss/exception': 1.2.3 - error-stack-parser-es: 1.0.5 - - youch@4.1.0-beta.10: - dependencies: - '@poppinss/colors': 4.1.6 - '@poppinss/dumper': 0.6.5 - '@speed-highlight/core': 1.2.14 - cookie: 1.1.1 - youch-core: 0.3.3 - zimmerframe@1.1.4: {} zod@4.3.6: {} diff --git a/src/routes/healthz/+server.ts b/src/routes/healthz/+server.ts new file mode 100644 index 0000000..b12f246 --- /dev/null +++ b/src/routes/healthz/+server.ts @@ -0,0 +1,19 @@ +import { json } from '@sveltejs/kit'; +import type { RequestHandler } from './$types'; + +/** + * Liveness / readiness probe. + * + * Intentionally has no dependencies: + * - no DB call (Postgres might be slow to come up after the app) + * - no auth (Kubernetes probes don't carry cookies) + * - no `platform.env` reads (the Node adapter doesn't expose those) + * + * If the Node process can serve this response it is alive and the HTTP + * listener is healthy. Use a separate readiness check (e.g. hitting + * `/api/dashboard/data` for a logged-in probe target) when you need to + * gate on downstream dependencies. + */ +export const GET: RequestHandler = async () => { + return json({ ok: true }); +}; \ No newline at end of file diff --git a/svelte.config.js b/svelte.config.js index 0659d7c..17ec532 100644 --- a/svelte.config.js +++ b/svelte.config.js @@ -1,12 +1,11 @@ -import adapter from '@sveltejs/adapter-cloudflare'; +import adapter from '@sveltejs/adapter-node'; /** @type {import('@sveltejs/kit').Config} */ const config = { kit: { adapter: adapter({ - platformProxy: { - persist: { path: '.wrangler/state/v3' } - } + out: 'build', + precompress: false }), alias: { $components: './src/lib/components', @@ -16,4 +15,4 @@ const config = { } }; -export default config; +export default config; \ No newline at end of file diff --git a/wrangler.toml b/wrangler.toml deleted file mode 100644 index 11d9bb5..0000000 --- a/wrangler.toml +++ /dev/null @@ -1,18 +0,0 @@ -name = "workflow-metrics" # ← Change it to your own app name -compatibility_date = "2024-12-01" -compatibility_flags = ["nodejs_als"] -pages_build_output_dir = ".svelte-kit/cloudflare" - -[vars] -# Set via Cloudflare dashboard secrets, not here: -# PUBLIC_SUPABASE_URL = "" -# PUBLIC_SUPABASE_ANON_KEY = "" -# SUPABASE_SERVICE_ROLE_KEY = "" -# GITHUB_APP_ID = "" ← GitHub App numeric ID (AI Optimization → Apply as PR) -# GITHUB_APP_PRIVATE_KEY = "" ← RSA private key PEM (collapse newlines to \n for single-line secrets) -# GITHUB_APP_SLUG = "" ← URL slug of the GitHub App (e.g. "workflow-metrics-bot") - -# Optional KV for caching GitHub API responses (uncomment when needed): -# [[kv_namespaces]] -# binding = "CACHE" -# id = "your-kv-namespace-id"