From c72f9527ac4c9c262d3506297ba7c6c438cc2108 Mon Sep 17 00:00:00 2001 From: Brendan Date: Mon, 14 Sep 2026 17:03:13 +0000 Subject: [PATCH] Restructure Factorize as npm workspaces monorepo --- .github/workflows/ci.yml | 2 +- .github/workflows/deploy.yml | 6 +- README.md | 34 +- docs/cloudflare-tail.md | 6 +- factorize-tail-relay/package-lock.json | 1613 ----------------- factorize-tail-relay/package.json | 1 - package-lock.json | 64 +- package.json | 35 +- .../app/.dev.vars.example | 0 packages/app/package.json | 32 + .../app/public}/android-chrome-192x192.png | Bin .../app/public}/android-chrome-512x512.png | Bin .../app/public}/apple-touch-icon.png | Bin .../app/public}/bee-mark-monochrome.png | Bin {public => packages/app/public}/bee-mark.png | Bin .../app/public}/favicon-16x16.png | Bin .../app/public}/favicon-32x32.png | Bin .../app/public}/favicon-48x48.png | Bin {public => packages/app/public}/favicon.ico | Bin .../app/public}/site.webmanifest | 0 {public => packages/app/public}/styles.css | 0 {src => packages/app/src}/cloudflare-tail.ts | 0 {src => packages/app/src}/crypto.ts | 0 {src => packages/app/src}/custom-handler.ts | 0 {src => packages/app/src}/device-oauth.ts | 0 .../app/src}/exe-herdr-backend.ts | 0 {src => packages/app/src}/exe.ts | 0 {src => packages/app/src}/execution.ts | 0 {src => packages/app/src}/flow-schemas.ts | 0 {src => packages/app/src}/flow-service.ts | 0 {src => packages/app/src}/github-registry.ts | 0 {src => packages/app/src}/github.ts | 0 {src => packages/app/src}/index.ts | 0 {src => packages/app/src}/linear-source.ts | 0 {src => packages/app/src}/linear.ts | 0 {src => packages/app/src}/matcher.ts | 0 {src => packages/app/src}/protected-api.ts | 0 {src => packages/app/src}/recovery.ts | 0 {src => packages/app/src}/tailwind.css | 0 {src => packages/app/src}/tenant.ts | 0 {src => packages/app/src}/types.ts | 0 {src => packages/app/src}/ui.ts | 0 {src => packages/app/src}/worker.ts | 0 {src => packages/app/src}/workspace.ts | 0 .../app/test}/cloudflare-tail.test.ts | 0 .../app/test}/custom-handler.test.ts | 0 .../app/test}/device-oauth.e2e.test.ts | 0 .../app/test}/device-oauth.test.ts | 0 {test => packages/app/test}/exe.test.ts | 0 .../app/test}/execution-backend.test.ts | 0 .../app/test}/flow-service.test.ts | 0 {test => packages/app/test}/github.test.ts | 0 {test => packages/app/test}/linear.test.ts | 0 {test => packages/app/test}/matcher.test.ts | 0 {test => packages/app/test}/recovery.test.ts | 0 .../app/test}/ticket-prompt.test.ts | 0 {test => packages/app/test}/ui.test.ts | 0 {test => packages/app/test}/worker.test.ts | 0 {test => packages/app/test}/workspace.test.ts | 0 tsconfig.json => packages/app/tsconfig.json | 0 .../app/vitest.config.ts | 0 .../app/vitest.e2e.config.ts | 0 wrangler.jsonc => packages/app/wrangler.jsonc | 2 +- packages/tail-relay/package.json | 15 + .../tail-relay}/src/index.ts | 0 .../tail-relay}/tsconfig.json | 0 .../tail-relay}/wrangler.jsonc | 2 +- 67 files changed, 127 insertions(+), 1685 deletions(-) delete mode 100644 factorize-tail-relay/package-lock.json delete mode 100644 factorize-tail-relay/package.json rename .dev.vars.example => packages/app/.dev.vars.example (100%) create mode 100644 packages/app/package.json rename {public => packages/app/public}/android-chrome-192x192.png (100%) rename {public => packages/app/public}/android-chrome-512x512.png (100%) rename {public => packages/app/public}/apple-touch-icon.png (100%) rename {public => packages/app/public}/bee-mark-monochrome.png (100%) rename {public => packages/app/public}/bee-mark.png (100%) rename {public => packages/app/public}/favicon-16x16.png (100%) rename {public => packages/app/public}/favicon-32x32.png (100%) rename {public => packages/app/public}/favicon-48x48.png (100%) rename {public => packages/app/public}/favicon.ico (100%) rename {public => packages/app/public}/site.webmanifest (100%) rename {public => packages/app/public}/styles.css (100%) rename {src => packages/app/src}/cloudflare-tail.ts (100%) rename {src => packages/app/src}/crypto.ts (100%) rename {src => packages/app/src}/custom-handler.ts (100%) rename {src => packages/app/src}/device-oauth.ts (100%) rename {src => packages/app/src}/exe-herdr-backend.ts (100%) rename {src => packages/app/src}/exe.ts (100%) rename {src => packages/app/src}/execution.ts (100%) rename {src => packages/app/src}/flow-schemas.ts (100%) rename {src => packages/app/src}/flow-service.ts (100%) rename {src => packages/app/src}/github-registry.ts (100%) rename {src => packages/app/src}/github.ts (100%) rename {src => packages/app/src}/index.ts (100%) rename {src => packages/app/src}/linear-source.ts (100%) rename {src => packages/app/src}/linear.ts (100%) rename {src => packages/app/src}/matcher.ts (100%) rename {src => packages/app/src}/protected-api.ts (100%) rename {src => packages/app/src}/recovery.ts (100%) rename {src => packages/app/src}/tailwind.css (100%) rename {src => packages/app/src}/tenant.ts (100%) rename {src => packages/app/src}/types.ts (100%) rename {src => packages/app/src}/ui.ts (100%) rename {src => packages/app/src}/worker.ts (100%) rename {src => packages/app/src}/workspace.ts (100%) rename {test => packages/app/test}/cloudflare-tail.test.ts (100%) rename {test => packages/app/test}/custom-handler.test.ts (100%) rename {test => packages/app/test}/device-oauth.e2e.test.ts (100%) rename {test => packages/app/test}/device-oauth.test.ts (100%) rename {test => packages/app/test}/exe.test.ts (100%) rename {test => packages/app/test}/execution-backend.test.ts (100%) rename {test => packages/app/test}/flow-service.test.ts (100%) rename {test => packages/app/test}/github.test.ts (100%) rename {test => packages/app/test}/linear.test.ts (100%) rename {test => packages/app/test}/matcher.test.ts (100%) rename {test => packages/app/test}/recovery.test.ts (100%) rename {test => packages/app/test}/ticket-prompt.test.ts (100%) rename {test => packages/app/test}/ui.test.ts (100%) rename {test => packages/app/test}/worker.test.ts (100%) rename {test => packages/app/test}/workspace.test.ts (100%) rename tsconfig.json => packages/app/tsconfig.json (100%) rename vitest.config.ts => packages/app/vitest.config.ts (100%) rename vitest.e2e.config.ts => packages/app/vitest.e2e.config.ts (100%) rename wrangler.jsonc => packages/app/wrangler.jsonc (93%) create mode 100644 packages/tail-relay/package.json rename {factorize-tail-relay => packages/tail-relay}/src/index.ts (100%) rename {factorize-tail-relay => packages/tail-relay}/tsconfig.json (100%) rename {factorize-tail-relay => packages/tail-relay}/wrangler.jsonc (61%) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index e58e893..2b2322c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,7 +18,7 @@ permissions: jobs: check: - name: Test and validate Worker + name: Test and validate Workers runs-on: ubuntu-latest timeout-minutes: 10 steps: diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 39b2884..328255b 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -15,7 +15,7 @@ concurrency: jobs: deploy: - name: Deploy Worker + name: Deploy app Worker runs-on: ubuntu-latest timeout-minutes: 15 environment: production @@ -27,8 +27,8 @@ jobs: cache: npm - run: npm ci - run: npm run build:css - - name: Deploy Worker - run: npm run deploy + - name: Deploy app Worker + run: npm run deploy:app env: CLOUDFLARE_API_TOKEN: ${{ secrets.CLOUDFLARE_API_TOKEN }} CLOUDFLARE_ACCOUNT_ID: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }} diff --git a/README.md b/README.md index a3d661f..5fa2617 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # Factorize [![CI](https://github.com/asselstine/factorize/actions/workflows/ci.yml/badge.svg)](https://github.com/asselstine/factorize/actions/workflows/ci.yml) -[![Deploy to Cloudflare](https://img.shields.io/badge/Deploy_to-Cloudflare-F38020?style=flat&logo=cloudflare&logoColor=white)](https://deploy.workers.cloudflare.com/?url=https://github.com/asselstine/factorize) +[![Deploy to Cloudflare](https://img.shields.io/badge/Deploy_to-Cloudflare-F38020?style=flat&logo=cloudflare&logoColor=white)](https://deploy.workers.cloudflare.com/?url=https://github.com/asselstine/factorize&path=packages/app) **A no-code software factory for Linear teams.** Factorize turns selected Linear issue changes into coding-agent jobs on your own exe.dev VM, using Herdr to run the agent you choose. @@ -21,15 +21,15 @@ Linear webhook → Cloudflare Worker → Durable Object → exe.dev /exec → He ## Deploy to Cloudflare -Click the **Deploy to Cloudflare** button above to create a copy of this Worker in your own Cloudflare account. Cloudflare provisions the Durable Object binding and configures Workers Builds for the copied repository. +Click the **Deploy to Cloudflare** button above to create a copy of the app Worker in your own Cloudflare account. The button selects `packages/app` as the Worker root; Cloudflare provisions the Durable Object binding and configures Workers Builds for the copied repository. > The Deploy to Cloudflare button works for public GitHub or GitLab repositories. If you are using a private fork, deploy with Wrangler instead. ### Deploy with Wrangler 1. Clone the repository and install dependencies. -2. Set `APP_ORIGIN` in `wrangler.jsonc` to your final HTTPS Worker URL or custom domain. -3. Create a dedicated OAuth KV namespace with `npx wrangler kv namespace create OAUTH_KV`, then replace `REPLACE_WITH_OAUTH_KV_ID` in `wrangler.jsonc` with its ID. +2. Set `APP_ORIGIN` in `packages/app/wrangler.jsonc` to your final HTTPS Worker URL or custom domain. +3. Create a dedicated OAuth KV namespace with `npm exec --workspace=factorize -- wrangler kv namespace create OAUTH_KV`, then set its ID in `packages/app/wrangler.jsonc`. 4. Configure the Linear OAuth callback as `https://your-domain.example/auth/linear/callback`. 5. Build assets, add secrets, and deploy: @@ -37,13 +37,13 @@ Click the **Deploy to Cloudflare** button above to create a copy of this Worker npm ci npm run build:css -npx wrangler secret put LINEAR_CLIENT_ID -npx wrangler secret put LINEAR_CLIENT_SECRET -npx wrangler secret put LINEAR_WEBHOOK_SIGNING_SECRET -npx wrangler secret put CREDENTIAL_ENCRYPTION_KEY -npx wrangler secret put SESSION_SIGNING_SECRET +npm exec --workspace=factorize -- wrangler secret put LINEAR_CLIENT_ID +npm exec --workspace=factorize -- wrangler secret put LINEAR_CLIENT_SECRET +npm exec --workspace=factorize -- wrangler secret put LINEAR_WEBHOOK_SIGNING_SECRET +npm exec --workspace=factorize -- wrangler secret put CREDENTIAL_ENCRYPTION_KEY +npm exec --workspace=factorize -- wrangler secret put SESSION_SIGNING_SECRET -npm run deploy +npm run deploy:app ``` For a headless machine, authenticate first with `npx wrangler login --device --browser=false`, then open the displayed URL and approve the device code from your browser. @@ -61,7 +61,7 @@ For a headless machine, authenticate first with `npx wrangler login --device --b ```bash npm install -cp .dev.vars.example .dev.vars +cp packages/app/.dev.vars.example packages/app/.dev.vars npm run dev ``` @@ -109,7 +109,7 @@ Cloudflare Worker failures can also start flows through the separately deployabl | `LINEAR_WEBHOOK_SIGNING_SECRET` | Verifies Linear webhook signatures | | `CREDENTIAL_ENCRYPTION_KEY` | Base64-encoded 32-byte key for encrypted credentials | | `SESSION_SIGNING_SECRET` | Independent secret for signed browser sessions | -| `APP_ORIGIN` | Public Worker origin, configured in `wrangler.jsonc` | +| `APP_ORIGIN` | Public Worker origin, configured in `packages/app/wrangler.jsonc` | | `OAUTH_KV` | KV binding containing OAuth clients, grants, refresh tokens, and revocation state | Never commit `.dev.vars` or production secret values. The included `.dev.vars.example` is a safe template. @@ -119,12 +119,14 @@ Never commit `.dev.vars` or production secret values. The included `.dev.vars.ex | Command | What it does | | --- | --- | | `npm run dev` | Build CSS and start local Wrangler development | -| `npm run build:css` | Compile Tailwind into `public/styles.css` | +| `npm run build:css` | Compile Tailwind into `packages/app/public/styles.css` | | `npm test` | Run the unit test suite | -| `npm run check` | Type-check, test, and validate a Wrangler dry-run deploy | -| `npm run deploy` | Deploy the Worker with Wrangler | +| `npm run check` | Type-check/test the app and dry-run both Worker deployments | +| `npm run deploy:app` | Deploy only the `factorize` app Worker | +| `npm run deploy:tail-relay` | Deploy only the `factorize-tail-relay` Worker | +| `npm run deploy` | Deploy the app, then the Tail relay; stop on the first failure | -GitHub Actions runs `npm run check` on every push and pull request. +GitHub Actions installs the single root lockfile and runs `npm run check` on every push and pull request. The two packages are independently deployable Cloudflare Workers; the root scripts only provide a unified developer workflow. ## REST API and OAuth diff --git a/docs/cloudflare-tail.md b/docs/cloudflare-tail.md index a06fd9f..0fbd881 100644 --- a/docs/cloudflare-tail.md +++ b/docs/cloudflare-tail.md @@ -1,12 +1,12 @@ # Cloudflare Tail flow source -Cloudflare Tail is a Factorize flow source for native uncaught Worker exceptions and structured `console.error` failures. Tail Workers require a Workers Paid or Enterprise plan. The relay stays in the same Cloudflare account as the producer Workers; the Factorize flow may be in any account. +Cloudflare Tail is a Factorize flow source for native uncaught Worker exceptions and structured `console.error` failures. Tail Workers require a Workers Paid or Enterprise plan. The relay is a separate Cloudflare Worker and must be deployed in the same Cloudflare account as the producer Workers; the Factorize app Worker may be in any account. ## Configure the flow and relay 1. Create a flow, choose **Cloudflare Tail**, and save it. Copy the one-time relay destination and signing secret from the response/flow setup view. -2. In `factorize-tail-relay`, run `npm install`, set `FACTORIZE_TAIL_DESTINATION` as a Wrangler variable, and run `npx wrangler secret put FACTORIZE_TAIL_SECRET`. -3. Run `npm run deploy`. Keep the relay name `factorize-tail-relay`; Factorize excludes its own relay traces to prevent loops. +2. From the repository root, run `npm ci` and set `FACTORIZE_TAIL_DESTINATION` as a Wrangler variable in `packages/tail-relay/wrangler.jsonc`. +3. Authenticate Wrangler to the producer Workers' Cloudflare account, then run `npm exec --workspace=factorize-tail-relay -- wrangler secret put FACTORIZE_TAIL_SECRET` and `npm run deploy:tail-relay`. Keep the relay name `factorize-tail-relay`; Factorize excludes its own relay traces to prevent loops. 4. Add the relay to every producer Worker. One relay can consume multiple producers and forwards each event with its `scriptName`: ```jsonc diff --git a/factorize-tail-relay/package-lock.json b/factorize-tail-relay/package-lock.json deleted file mode 100644 index 93cd202..0000000 --- a/factorize-tail-relay/package-lock.json +++ /dev/null @@ -1,1613 +0,0 @@ -{ - "name": "factorize-tail-relay", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "factorize-tail-relay", - "devDependencies": { - "@cloudflare/workers-types": "^5.20260910.1", - "typescript": "^5.9.3", - "wrangler": "^4.44.0" - } - }, - "node_modules/@cloudflare/kv-asset-handler": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/@cloudflare/kv-asset-handler/-/kv-asset-handler-0.5.0.tgz", - "integrity": "sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==", - "dev": true, - "license": "MIT OR Apache-2.0", - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/@cloudflare/unenv-preset": { - "version": "2.16.1", - "resolved": "https://registry.npmjs.org/@cloudflare/unenv-preset/-/unenv-preset-2.16.1.tgz", - "integrity": "sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==", - "dev": true, - "license": "MIT OR Apache-2.0", - "peerDependencies": { - "unenv": "2.0.0-rc.24", - "workerd": ">1.20260305.0 <2.0.0-0" - }, - "peerDependenciesMeta": { - "workerd": { - "optional": true - } - } - }, - "node_modules/@cloudflare/workerd-darwin-64": { - "version": "1.20260911.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-64/-/workerd-darwin-64-1.20260911.1.tgz", - "integrity": "sha512-785eaY1bkR1cm4Z/PCUeteZYmTMe6lre2zz63/GdGGimsoMsKxgl4brFPRukim8iv28EyD1XoCB/VPYF20BERA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-darwin-arm64": { - "version": "1.20260911.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-darwin-arm64/-/workerd-darwin-arm64-1.20260911.1.tgz", - "integrity": "sha512-WU4bFqEN0H7ndGWxoedegv95DmNVBtv0ncXcHG9nYFTUI78sxEb0qoT3U6Ga4hyBkzsJFBX/zvVBIGX3qKldGA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-linux-64": { - "version": "1.20260911.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-64/-/workerd-linux-64-1.20260911.1.tgz", - "integrity": "sha512-0Y2gy62oxQxWa38qinSPE6zNL5+JmumJtDY9AWW1HB8KHuATxN71o5MGzmVFfB8PwZsiHfUd2Sv7O22krCOrhw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-linux-arm64": { - "version": "1.20260911.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-linux-arm64/-/workerd-linux-arm64-1.20260911.1.tgz", - "integrity": "sha512-kttNPnx1r2lCqFUoMH62z7CqGV+j4QBbw5fdtaz4pzOrzBv0AWkNATt7onFUe+SwP8zhcepMtbm2F4kKzTf6VA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workerd-windows-64": { - "version": "1.20260911.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workerd-windows-64/-/workerd-windows-64-1.20260911.1.tgz", - "integrity": "sha512-5iO/YfoBDOgO3CrHdkiiVP8SL3O2jC+c6Ux3d378TSPKLhU5+CgHjtE/ZSodWQrzr4FzFRqdW8S7n5nbyD1MHQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=16" - } - }, - "node_modules/@cloudflare/workers-types": { - "version": "5.20260911.1", - "resolved": "https://registry.npmjs.org/@cloudflare/workers-types/-/workers-types-5.20260911.1.tgz", - "integrity": "sha512-yiAvknjulcU85B3yB4aKOn9+l+garWP+AbHgsdCFckeRYDdhZ1rPULi64BDf52R3VTaKqxi47kF+o9ZbjsCt5g==", - "dev": true, - "license": "MIT OR Apache-2.0" - }, - "node_modules/@cspotcode/source-map-support": { - "version": "0.8.1", - "resolved": "https://registry.npmjs.org/@cspotcode/source-map-support/-/source-map-support-0.8.1.tgz", - "integrity": "sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/trace-mapping": "0.3.9" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@emnapi/runtime": { - "version": "1.11.3", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.11.3.tgz", - "integrity": "sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==", - "dev": true, - "license": "MIT", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, - "node_modules/@esbuild/aix-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.28.1.tgz", - "integrity": "sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "aix" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.28.1.tgz", - "integrity": "sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.28.1.tgz", - "integrity": "sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/android-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.28.1.tgz", - "integrity": "sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "android" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.28.1.tgz", - "integrity": "sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/darwin-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.28.1.tgz", - "integrity": "sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.28.1.tgz", - "integrity": "sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/freebsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.28.1.tgz", - "integrity": "sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.28.1.tgz", - "integrity": "sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==", - "cpu": [ - "arm" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.28.1.tgz", - "integrity": "sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.28.1.tgz", - "integrity": "sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-loong64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.28.1.tgz", - "integrity": "sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==", - "cpu": [ - "loong64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-mips64el": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.28.1.tgz", - "integrity": "sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==", - "cpu": [ - "mips64el" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-ppc64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.28.1.tgz", - "integrity": "sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-riscv64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.28.1.tgz", - "integrity": "sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-s390x": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.28.1.tgz", - "integrity": "sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==", - "cpu": [ - "s390x" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/linux-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.28.1.tgz", - "integrity": "sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.28.1.tgz", - "integrity": "sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/netbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.28.1.tgz", - "integrity": "sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "netbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.28.1.tgz", - "integrity": "sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openbsd-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.28.1.tgz", - "integrity": "sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openbsd" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/openharmony-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.28.1.tgz", - "integrity": "sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "openharmony" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/sunos-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.28.1.tgz", - "integrity": "sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "sunos" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-arm64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.28.1.tgz", - "integrity": "sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-ia32": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.28.1.tgz", - "integrity": "sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@esbuild/win32-x64": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.28.1.tgz", - "integrity": "sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "MIT", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/colour": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/@img/colour/-/colour-1.1.0.tgz", - "integrity": "sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - } - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.35.4.tgz", - "integrity": "sha512-Uhfl4V4lhP2nbUVF9+hyH1+luj86f1gUFeo8ALYxFoULoU+G87D43BfeMP8XHsk9boxAnCY/bf2EHwhA7MuGsA==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.35.4.tgz", - "integrity": "sha512-hWniXY3bG5qKpkKrAwPe4y+VTPmf086YQAnkxWh7uA1YrlRouWGa0M0Mxj3ZjnXFkv7/TD1bTy9lGUK26vRvWw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-freebsd-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-freebsd-wasm32/-/sharp-freebsd-wasm32-0.35.4.tgz", - "integrity": "sha512-lIsKw/BU+kjB4eZjxrYrZmwOJYi3Ajrv66iAlBmUPyKc3HpnloevB1g3wxGD9P/5BbQ1brBGl65VRRrCvQDEqA==", - "dev": true, - "license": "Apache-2.0", - "optional": true, - "os": [ - "freebsd" - ], - "dependencies": { - "@img/sharp-wasm32": "0.35.4" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.3.3.tgz", - "integrity": "sha512-suTBPTDGrI9WodccaDdwZItTSaBYASlBk1NSfElSHrUfzu3szG6lvIF58+WiFvnfzuK8ZBFS5zE00PxqxnRiPg==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.3.3.tgz", - "integrity": "sha512-FVJZ5mITMobmXIz/hPDTw0EintTW5H3WfrxwLqEqjiIihlu+hVRyGrFQ60xl0Lxn7Bt3zdpevPaQi0HEzqz9fw==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.3.3.tgz", - "integrity": "sha512-3rbU4vqXXc3hY/OiXdl52xZvT0F1yEngWfvqudtPJg/KkyiaQw2DRsFrNzpmLvfavbwOq3qXn36GP8obHRULQA==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.3.3.tgz", - "integrity": "sha512-0DaL0A6Xu6sQSQFwe4iVCrKWU2cCTItnRsYsCdxAMm9NF6twAA9BKnoqy4hqz4+azQ0JHuA26qiUKsf1XJ/v5A==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-ppc64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-ppc64/-/sharp-libvips-linux-ppc64-1.3.3.tgz", - "integrity": "sha512-cdn1OvUBwsXhbC0zSzJnNzf5MZ/mTrobawDvNXBTxe8VtqKAm0sRuEY2Evzovb/w9JMk4TvRxqt1mekSuJz64w==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-riscv64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-riscv64/-/sharp-libvips-linux-riscv64-1.3.3.tgz", - "integrity": "sha512-HjPVx7yKz+0lqdhDlTw1tt90wamBoxhiXpvl1XZpJLiHH4RCJ5yDTqH+VlYPv2fwFs89JFw4c1IexYOcQUi4IQ==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.3.3.tgz", - "integrity": "sha512-neWLh+3yCNThxnfy3c4BbVBeGgt9aftno+XbT56iK28RgeDs3UOFWviLWlUu0bArYVYJaFDK+RRohbicUNCm8Q==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.3.3.tgz", - "integrity": "sha512-4vKmvAst9nrowcqquKFAyZJUDolUaIp8uRiN0mWFguJ1IplC9/pitXtlnnlU4aa/eJw3J7i67V+pwUL+wZGdsA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.3.3.tgz", - "integrity": "sha512-Y9kQaLMuNoB0bPYOOdcZMaseNrFpPodIWWMrx+CZyydf2xn68j9WYc6sWWRrDwNkzCQjKYfc68L7jKjGlHMibw==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linuxmusl-x64": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.3.3.tgz", - "integrity": "sha512-fj8Mv0HHfD1Rr+4I68+3agJynxDWtBFgicTbSOb9Bke6pIwzGcJ+RX/yHjmiEGFMCavY/dxvem7MyNaJF+wDiw==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "LGPL-3.0-or-later", - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.35.4.tgz", - "integrity": "sha512-7OAS8gI0EReKGVN2HssHlM6umJgxF5VI3xN0p9FA91p/YO+ou5hiNghLdZ5BEHztwaaK5+bLKRf8x/o2L2nk9A==", - "cpu": [ - "arm" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.35.4.tgz", - "integrity": "sha512-De4jpEnAU8Hd5oT0j1G3uL4ZvTuipVMn7YC6vPaJhy6/7EwEae0SVAoBrUMYQbkLGDm85taVWwuPc1a44LTzCQ==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-ppc64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-ppc64/-/sharp-linux-ppc64-0.35.4.tgz", - "integrity": "sha512-2oYZJeIl4kCcMGk4ouZVjnkCtFrpQFlNEtJ6GbxzhHQchwH0NH/qEb9ykmOl29dqwMq+JhFdZn+1ak2FKhI9fQ==", - "cpu": [ - "ppc64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-ppc64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-riscv64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-riscv64/-/sharp-linux-riscv64-0.35.4.tgz", - "integrity": "sha512-cPbNChoRURAWdebDIHSenxRpgEdy7JkPydSnUxRm9VvKD7m0/xVaR/8Fzlu81pk5nHEvHH87UZUA7cTtwnbJSA==", - "cpu": [ - "riscv64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-riscv64": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.35.4.tgz", - "integrity": "sha512-RY0JFY8Fd6RonCBtHz+DvadaPkXDSI1AUn6yWL9TipqkZ1vY8w8evqdgyDFnkm4/K1ve1TvZiaePP5oSd4+WVQ==", - "cpu": [ - "s390x" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.3.3" - } - }, - "node_modules/@img/sharp-linux-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.35.4.tgz", - "integrity": "sha512-9qvvEAuk8k89TfWUoX2htWjbAMX8p+NxCppjpcg5k6xMsjhBQPTsoIh36h9Qde4WRuGpJeYnOjdosDn/cnv+OA==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "glibc" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.35.4.tgz", - "integrity": "sha512-KB5jxpfWQTr0nc3xdHtWChdbifHrBGsd2SM62Eyxrl8afikm+f5qGBU75SJIZBT/S1MC8XyacdlXBMSWq6OURA==", - "cpu": [ - "arm64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3" - } - }, - "node_modules/@img/sharp-linuxmusl-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.35.4.tgz", - "integrity": "sha512-f+eZJZIQNEEd26RPSW+76chwOf1XtA2Y/O+5ocVyLliHkeih3e+jhLVBdNTd2rS3IbNXK8+ug93Vf5ZXtF5Lxg==", - "cpu": [ - "x64" - ], - "dev": true, - "libc": [ - "musl" - ], - "license": "Apache-2.0", - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-x64": "1.3.3" - } - }, - "node_modules/@img/sharp-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.35.4.tgz", - "integrity": "sha512-zQnl4Kwp7Q6NHsENtU2T/00Zi+w3AQNwz3+UaTyVBy2FpXrzXzGjndpK61onhZjRtRpQXxCTeqw19bVyXOh7jA==", - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.11.3" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-webcontainers-wasm32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-webcontainers-wasm32/-/sharp-webcontainers-wasm32-0.35.4.tgz", - "integrity": "sha512-ESfNkywmCfPNyaZjxooddJQiQ+l/nTpGEOGthxiLnIHXC/CmcBixnfwUleX9mCz9ovrUUvKMap/pm8RYbzfwaA==", - "cpu": [ - "wasm32" - ], - "dev": true, - "license": "Apache-2.0", - "optional": true, - "dependencies": { - "@img/sharp-wasm32": "0.35.4" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-arm64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-arm64/-/sharp-win32-arm64-0.35.4.tgz", - "integrity": "sha512-iNdlBX9gLVvqe2I3uIJSIKTq6wckP/DYxZtcqxm09x5Gi24DnFBmPAWZmr60ZyYMG0xlzo6goG3670ar+RXvRw==", - "cpu": [ - "arm64" - ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.35.4.tgz", - "integrity": "sha512-kqRsbaa5CS6KHlpxnN7WhE6vAAugXyZButpRdvDWetlv6Qv4N9WTcrWzF7tXfB9T7MsoadqdI8hmwLq6UlLvtw==", - "cpu": [ - "ia32" - ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.35.4.tgz", - "integrity": "sha512-XtmnYhBcrORsJ4XJngyzr/EWP0hRZLAZRFaApdKuviyqF78+ylxh2y06ZmtULAMOnObJ3ucpN0AcwSWnMowTRg==", - "cpu": [ - "x64" - ], - "dev": true, - "license": "Apache-2.0 AND LGPL-3.0-or-later", - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@jridgewell/resolve-uri": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz", - "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6.0.0" - } - }, - "node_modules/@jridgewell/sourcemap-codec": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.6.0.tgz", - "integrity": "sha512-T7jf+5zgsZHwNJ4lvQ7/aezbyk0nNX+zJVWpmHA7VYsEx7a7qr5Rg5IbtJFqkgze5Y2sruq1RUY8Q837Od7iFw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.9.tgz", - "integrity": "sha512-3Belt6tdc8bPgAtbcmdtNJlirVoTmEb5e2gC94PnkwEW9jI6CAHUeoG85tjWP5WquqfavoMtMwiG4P926ZKKuQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@jridgewell/resolve-uri": "^3.0.3", - "@jridgewell/sourcemap-codec": "^1.4.10" - } - }, - "node_modules/@poppinss/colors": { - "version": "4.1.6", - "resolved": "https://registry.npmjs.org/@poppinss/colors/-/colors-4.1.6.tgz", - "integrity": "sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==", - "dev": true, - "license": "MIT", - "dependencies": { - "kleur": "^4.1.5" - } - }, - "node_modules/@poppinss/dumper": { - "version": "0.6.5", - "resolved": "https://registry.npmjs.org/@poppinss/dumper/-/dumper-0.6.5.tgz", - "integrity": "sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==", - "dev": true, - "license": "MIT", - "dependencies": { - "@poppinss/colors": "^4.1.5", - "@sindresorhus/is": "^7.0.2", - "supports-color": "^10.0.0" - } - }, - "node_modules/@poppinss/exception": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@poppinss/exception/-/exception-1.2.3.tgz", - "integrity": "sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==", - "dev": true, - "license": "MIT" - }, - "node_modules/@sindresorhus/is": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-7.2.0.tgz", - "integrity": "sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "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/sindresorhus/is?sponsor=1" - } - }, - "node_modules/@speed-highlight/core": { - "version": "1.2.24", - "resolved": "https://registry.npmjs.org/@speed-highlight/core/-/core-1.2.24.tgz", - "integrity": "sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==", - "dev": true, - "license": "CC0-1.0" - }, - "node_modules/blake3-wasm": { - "version": "2.1.5", - "resolved": "https://registry.npmjs.org/blake3-wasm/-/blake3-wasm-2.1.5.tgz", - "integrity": "sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==", - "dev": true, - "license": "MIT" - }, - "node_modules/cookie": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", - "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/express" - } - }, - "node_modules/detect-libc": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", - "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", - "dev": true, - "license": "Apache-2.0", - "engines": { - "node": ">=8" - } - }, - "node_modules/error-stack-parser-es": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/error-stack-parser-es/-/error-stack-parser-es-1.0.5.tgz", - "integrity": "sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "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/sponsors/antfu" - } - }, - "node_modules/esbuild": { - "version": "0.28.1", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.28.1.tgz", - "integrity": "sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "bin": { - "esbuild": "bin/esbuild" - }, - "engines": { - "node": ">=18" - }, - "optionalDependencies": { - "@esbuild/aix-ppc64": "0.28.1", - "@esbuild/android-arm": "0.28.1", - "@esbuild/android-arm64": "0.28.1", - "@esbuild/android-x64": "0.28.1", - "@esbuild/darwin-arm64": "0.28.1", - "@esbuild/darwin-x64": "0.28.1", - "@esbuild/freebsd-arm64": "0.28.1", - "@esbuild/freebsd-x64": "0.28.1", - "@esbuild/linux-arm": "0.28.1", - "@esbuild/linux-arm64": "0.28.1", - "@esbuild/linux-ia32": "0.28.1", - "@esbuild/linux-loong64": "0.28.1", - "@esbuild/linux-mips64el": "0.28.1", - "@esbuild/linux-ppc64": "0.28.1", - "@esbuild/linux-riscv64": "0.28.1", - "@esbuild/linux-s390x": "0.28.1", - "@esbuild/linux-x64": "0.28.1", - "@esbuild/netbsd-arm64": "0.28.1", - "@esbuild/netbsd-x64": "0.28.1", - "@esbuild/openbsd-arm64": "0.28.1", - "@esbuild/openbsd-x64": "0.28.1", - "@esbuild/openharmony-arm64": "0.28.1", - "@esbuild/sunos-x64": "0.28.1", - "@esbuild/win32-arm64": "0.28.1", - "@esbuild/win32-ia32": "0.28.1", - "@esbuild/win32-x64": "0.28.1" - } - }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "dev": true, - "hasInstallScript": true, - "license": "MIT", - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, - "node_modules/kleur": { - "version": "4.1.5", - "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", - "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=6" - } - }, - "node_modules/miniflare": { - "version": "5.20260911.0-alpha", - "resolved": "https://registry.npmjs.org/miniflare/-/miniflare-5.20260911.0-alpha.tgz", - "integrity": "sha512-CRieJmvHx+7rNqnA5SKdsYsER6rfkUIE/jruIUw+fLhsQ4sORfuMtr3+FQzsQ9/y8lhk061V4Fl1DFdHiyBB6g==", - "dev": true, - "license": "MIT", - "dependencies": { - "@cspotcode/source-map-support": "0.8.1", - "sharp": "0.35.4", - "undici": "7.29.0", - "workerd": "1.20260911.1", - "ws": "8.21.0", - "youch": "4.1.0-beta.10" - }, - "engines": { - "node": ">=22.0.0" - } - }, - "node_modules/path-to-regexp": { - "version": "6.3.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-6.3.0.tgz", - "integrity": "sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/pathe": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz", - "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", - "dev": true, - "license": "MIT" - }, - "node_modules/semver": { - "version": "7.8.5", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.8.5.tgz", - "integrity": "sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==", - "dev": true, - "license": "ISC", - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/sharp": { - "version": "0.35.4", - "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.35.4.tgz", - "integrity": "sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==", - "dev": true, - "license": "Apache-2.0", - "dependencies": { - "@img/colour": "^1.1.0", - "detect-libc": "^2.1.2", - "semver": "^7.8.5" - }, - "engines": { - "node": ">=20.9.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-darwin-arm64": "0.35.4", - "@img/sharp-darwin-x64": "0.35.4", - "@img/sharp-freebsd-wasm32": "0.35.4", - "@img/sharp-libvips-darwin-arm64": "1.3.3", - "@img/sharp-libvips-darwin-x64": "1.3.3", - "@img/sharp-libvips-linux-arm": "1.3.3", - "@img/sharp-libvips-linux-arm64": "1.3.3", - "@img/sharp-libvips-linux-ppc64": "1.3.3", - "@img/sharp-libvips-linux-riscv64": "1.3.3", - "@img/sharp-libvips-linux-s390x": "1.3.3", - "@img/sharp-libvips-linux-x64": "1.3.3", - "@img/sharp-libvips-linuxmusl-arm64": "1.3.3", - "@img/sharp-libvips-linuxmusl-x64": "1.3.3", - "@img/sharp-linux-arm": "0.35.4", - "@img/sharp-linux-arm64": "0.35.4", - "@img/sharp-linux-ppc64": "0.35.4", - "@img/sharp-linux-riscv64": "0.35.4", - "@img/sharp-linux-s390x": "0.35.4", - "@img/sharp-linux-x64": "0.35.4", - "@img/sharp-linuxmusl-arm64": "0.35.4", - "@img/sharp-linuxmusl-x64": "0.35.4", - "@img/sharp-webcontainers-wasm32": "0.35.4", - "@img/sharp-win32-arm64": "0.35.4", - "@img/sharp-win32-ia32": "0.35.4", - "@img/sharp-win32-x64": "0.35.4" - }, - "peerDependenciesMeta": { - "@types/node": { - "optional": true - } - } - }, - "node_modules/supports-color": { - "version": "10.2.2", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-10.2.2.tgz", - "integrity": "sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=18" - }, - "funding": { - "url": "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/chalk/supports-color?sponsor=1" - } - }, - "node_modules/tslib": { - "version": "2.8.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz", - "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", - "dev": true, - "license": "0BSD", - "optional": true - }, - "node_modules/typescript": { - "version": "5.9.3", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", - "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", - "dev": true, - "license": "Apache-2.0", - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, - "node_modules/undici": { - "version": "7.29.0", - "resolved": "https://registry.npmjs.org/undici/-/undici-7.29.0.tgz", - "integrity": "sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=20.18.1" - } - }, - "node_modules/unenv": { - "version": "2.0.0-rc.24", - "resolved": "https://registry.npmjs.org/unenv/-/unenv-2.0.0-rc.24.tgz", - "integrity": "sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==", - "dev": true, - "license": "MIT", - "dependencies": { - "pathe": "^2.0.3" - } - }, - "node_modules/workerd": { - "version": "1.20260911.1", - "resolved": "https://registry.npmjs.org/workerd/-/workerd-1.20260911.1.tgz", - "integrity": "sha512-vRr8QdBxueQOZJO1hRCI73EZlix87IAyBAcSyI3rA1VB+6oxjw3oaqzYnIV8C4IOPtUgihbdMAgzkb5GM4V7DQ==", - "dev": true, - "hasInstallScript": true, - "license": "Apache-2.0", - "bin": { - "workerd": "bin/workerd" - }, - "engines": { - "node": ">=16" - }, - "optionalDependencies": { - "@cloudflare/workerd-darwin-64": "1.20260911.1", - "@cloudflare/workerd-darwin-arm64": "1.20260911.1", - "@cloudflare/workerd-linux-64": "1.20260911.1", - "@cloudflare/workerd-linux-arm64": "1.20260911.1", - "@cloudflare/workerd-windows-64": "1.20260911.1" - } - }, - "node_modules/wrangler": { - "version": "4.131.1", - "resolved": "https://registry.npmjs.org/wrangler/-/wrangler-4.131.1.tgz", - "integrity": "sha512-1u5FMdJAn6UOcL02cVsIITcnHrk6mC7N+RF10EkVhPL18R/o9g5BZb4PCjByL+3AsRP5wQpppCIPHhYPRmIJwg==", - "dev": true, - "license": "MIT OR Apache-2.0", - "dependencies": { - "@cloudflare/kv-asset-handler": "0.5.0", - "@cloudflare/unenv-preset": "2.16.1", - "blake3-wasm": "2.1.5", - "esbuild": "0.28.1", - "miniflare": "5.20260911.0-alpha", - "path-to-regexp": "6.3.0", - "unenv": "2.0.0-rc.24", - "workerd": "1.20260911.1" - }, - "bin": { - "cf-wrangler": "bin/cf-wrangler.js", - "wrangler": "bin/wrangler.js", - "wrangler2": "bin/wrangler.js" - }, - "engines": { - "node": ">=22.0.0" - }, - "optionalDependencies": { - "fsevents": "2.3.3" - }, - "peerDependencies": { - "@cloudflare/workers-types": "^5.20260911.1" - }, - "peerDependenciesMeta": { - "@cloudflare/workers-types": { - "optional": true - } - } - }, - "node_modules/ws": { - "version": "8.21.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.21.0.tgz", - "integrity": "sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, - "node_modules/youch": { - "version": "4.1.0-beta.10", - "resolved": "https://registry.npmjs.org/youch/-/youch-4.1.0-beta.10.tgz", - "integrity": "sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "@poppinss/colors": "^4.1.5", - "@poppinss/dumper": "^0.6.4", - "@speed-highlight/core": "^1.2.7", - "cookie": "^1.0.2", - "youch-core": "^0.3.3" - } - }, - "node_modules/youch-core": { - "version": "0.3.3", - "resolved": "https://registry.npmjs.org/youch-core/-/youch-core-0.3.3.tgz", - "integrity": "sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==", - "dev": true, - "license": "MIT", - "dependencies": { - "@poppinss/exception": "^1.2.2", - "error-stack-parser-es": "^1.0.5" - } - } - } -} diff --git a/factorize-tail-relay/package.json b/factorize-tail-relay/package.json deleted file mode 100644 index b2cc9a3..0000000 --- a/factorize-tail-relay/package.json +++ /dev/null @@ -1 +0,0 @@ -{"name":"factorize-tail-relay","private":true,"type":"module","scripts":{"deploy":"wrangler deploy","check":"tsc --noEmit && wrangler deploy --dry-run"},"devDependencies":{"@cloudflare/workers-types":"^5.20260910.1","typescript":"^5.9.3","wrangler":"^4.44.0"}} diff --git a/package-lock.json b/package-lock.json index 3886b30..d5772dc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,30 +1,15 @@ { - "name": "factorize", + "name": "factorize-workspace", "version": "0.1.0", "lockfileVersion": 3, "requires": true, "packages": { "": { - "name": "factorize", + "name": "factorize-workspace", "version": "0.1.0", - "dependencies": { - "@cloudflare/workers-oauth-provider": "^0.10.3", - "@modelcontextprotocol/hono": "^2.0.0", - "@modelcontextprotocol/server": "^2.0.0", - "hono": "^4.11.4", - "mustache": "^4.2.0", - "zod": "^4.6.2" - }, - "devDependencies": { - "@cloudflare/vitest-pool-workers": "^0.10.10", - "@cloudflare/workers-types": "^5.20260910.1", - "@tailwindcss/cli": "^4.1.14", - "@types/mustache": "^4.2.6", - "tailwindcss": "^4.1.14", - "typescript": "^5.9.3", - "vitest": "^3.2.4", - "wrangler": "^4.44.0" - } + "workspaces": [ + "packages/*" + ] }, "node_modules/@cloudflare/kv-asset-handler": { "version": "0.5.0", @@ -4043,6 +4028,14 @@ "node": ">=12.0.0" } }, + "node_modules/factorize": { + "resolved": "packages/app", + "link": true + }, + "node_modules/factorize-tail-relay": { + "resolved": "packages/tail-relay", + "link": true + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -5760,6 +5753,37 @@ "funding": { "url": "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/sponsors/colinhacks" } + }, + "packages/app": { + "name": "factorize", + "version": "0.1.0", + "dependencies": { + "@cloudflare/workers-oauth-provider": "^0.10.3", + "@modelcontextprotocol/hono": "^2.0.0", + "@modelcontextprotocol/server": "^2.0.0", + "hono": "^4.11.4", + "mustache": "^4.2.0", + "zod": "^4.6.2" + }, + "devDependencies": { + "@cloudflare/vitest-pool-workers": "^0.10.10", + "@cloudflare/workers-types": "^5.20260910.1", + "@tailwindcss/cli": "^4.1.14", + "@types/mustache": "^4.2.6", + "tailwindcss": "^4.1.14", + "typescript": "^5.9.3", + "vitest": "^3.2.4", + "wrangler": "^4.44.0" + } + }, + "packages/tail-relay": { + "name": "factorize-tail-relay", + "version": "0.1.0", + "devDependencies": { + "@cloudflare/workers-types": "^5.20260910.1", + "typescript": "^5.9.3", + "wrangler": "^4.44.0" + } } } } diff --git a/package.json b/package.json index 34eabc2..dc5a110 100644 --- a/package.json +++ b/package.json @@ -1,32 +1,15 @@ { - "name": "factorize", + "name": "factorize-workspace", "version": "0.1.0", "private": true, - "type": "module", + "workspaces": ["packages/*"], "scripts": { - "dev": "npm run build:css && wrangler dev", - "build:css": "tailwindcss -i ./src/tailwind.css -o ./public/styles.css --minify", - "check": "tsc --noEmit && vitest run && npm run test:e2e && wrangler deploy --dry-run", - "test": "vitest run", - "test:e2e": "vitest run --config vitest.e2e.config.ts", - "deploy": "wrangler deploy" - }, - "dependencies": { - "@cloudflare/workers-oauth-provider": "^0.10.3", - "@modelcontextprotocol/hono": "^2.0.0", - "@modelcontextprotocol/server": "^2.0.0", - "hono": "^4.11.4", - "mustache": "^4.2.0", - "zod": "^4.6.2" - }, - "devDependencies": { - "@cloudflare/vitest-pool-workers": "^0.10.10", - "@cloudflare/workers-types": "^5.20260910.1", - "@tailwindcss/cli": "^4.1.14", - "@types/mustache": "^4.2.6", - "tailwindcss": "^4.1.14", - "typescript": "^5.9.3", - "vitest": "^3.2.4", - "wrangler": "^4.44.0" + "dev": "npm run dev --workspace=factorize", + "build:css": "npm run build:css --workspace=factorize", + "test": "npm run test --workspaces --if-present", + "check": "npm run check --workspace=factorize && npm run check --workspace=factorize-tail-relay", + "deploy": "npm run deploy:app && npm run deploy:tail-relay", + "deploy:app": "npm run deploy --workspace=factorize", + "deploy:tail-relay": "npm run deploy --workspace=factorize-tail-relay" } } diff --git a/.dev.vars.example b/packages/app/.dev.vars.example similarity index 100% rename from .dev.vars.example rename to packages/app/.dev.vars.example diff --git a/packages/app/package.json b/packages/app/package.json new file mode 100644 index 0000000..34eabc2 --- /dev/null +++ b/packages/app/package.json @@ -0,0 +1,32 @@ +{ + "name": "factorize", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "dev": "npm run build:css && wrangler dev", + "build:css": "tailwindcss -i ./src/tailwind.css -o ./public/styles.css --minify", + "check": "tsc --noEmit && vitest run && npm run test:e2e && wrangler deploy --dry-run", + "test": "vitest run", + "test:e2e": "vitest run --config vitest.e2e.config.ts", + "deploy": "wrangler deploy" + }, + "dependencies": { + "@cloudflare/workers-oauth-provider": "^0.10.3", + "@modelcontextprotocol/hono": "^2.0.0", + "@modelcontextprotocol/server": "^2.0.0", + "hono": "^4.11.4", + "mustache": "^4.2.0", + "zod": "^4.6.2" + }, + "devDependencies": { + "@cloudflare/vitest-pool-workers": "^0.10.10", + "@cloudflare/workers-types": "^5.20260910.1", + "@tailwindcss/cli": "^4.1.14", + "@types/mustache": "^4.2.6", + "tailwindcss": "^4.1.14", + "typescript": "^5.9.3", + "vitest": "^3.2.4", + "wrangler": "^4.44.0" + } +} diff --git a/public/android-chrome-192x192.png b/packages/app/public/android-chrome-192x192.png similarity index 100% rename from public/android-chrome-192x192.png rename to packages/app/public/android-chrome-192x192.png diff --git a/public/android-chrome-512x512.png b/packages/app/public/android-chrome-512x512.png similarity index 100% rename from public/android-chrome-512x512.png rename to packages/app/public/android-chrome-512x512.png diff --git a/public/apple-touch-icon.png b/packages/app/public/apple-touch-icon.png similarity index 100% rename from public/apple-touch-icon.png rename to packages/app/public/apple-touch-icon.png diff --git a/public/bee-mark-monochrome.png b/packages/app/public/bee-mark-monochrome.png similarity index 100% rename from public/bee-mark-monochrome.png rename to packages/app/public/bee-mark-monochrome.png diff --git a/public/bee-mark.png b/packages/app/public/bee-mark.png similarity index 100% rename from public/bee-mark.png rename to packages/app/public/bee-mark.png diff --git a/public/favicon-16x16.png b/packages/app/public/favicon-16x16.png similarity index 100% rename from public/favicon-16x16.png rename to packages/app/public/favicon-16x16.png diff --git a/public/favicon-32x32.png b/packages/app/public/favicon-32x32.png similarity index 100% rename from public/favicon-32x32.png rename to packages/app/public/favicon-32x32.png diff --git a/public/favicon-48x48.png b/packages/app/public/favicon-48x48.png similarity index 100% rename from public/favicon-48x48.png rename to packages/app/public/favicon-48x48.png diff --git a/public/favicon.ico b/packages/app/public/favicon.ico similarity index 100% rename from public/favicon.ico rename to packages/app/public/favicon.ico diff --git a/public/site.webmanifest b/packages/app/public/site.webmanifest similarity index 100% rename from public/site.webmanifest rename to packages/app/public/site.webmanifest diff --git a/public/styles.css b/packages/app/public/styles.css similarity index 100% rename from public/styles.css rename to packages/app/public/styles.css diff --git a/src/cloudflare-tail.ts b/packages/app/src/cloudflare-tail.ts similarity index 100% rename from src/cloudflare-tail.ts rename to packages/app/src/cloudflare-tail.ts diff --git a/src/crypto.ts b/packages/app/src/crypto.ts similarity index 100% rename from src/crypto.ts rename to packages/app/src/crypto.ts diff --git a/src/custom-handler.ts b/packages/app/src/custom-handler.ts similarity index 100% rename from src/custom-handler.ts rename to packages/app/src/custom-handler.ts diff --git a/src/device-oauth.ts b/packages/app/src/device-oauth.ts similarity index 100% rename from src/device-oauth.ts rename to packages/app/src/device-oauth.ts diff --git a/src/exe-herdr-backend.ts b/packages/app/src/exe-herdr-backend.ts similarity index 100% rename from src/exe-herdr-backend.ts rename to packages/app/src/exe-herdr-backend.ts diff --git a/src/exe.ts b/packages/app/src/exe.ts similarity index 100% rename from src/exe.ts rename to packages/app/src/exe.ts diff --git a/src/execution.ts b/packages/app/src/execution.ts similarity index 100% rename from src/execution.ts rename to packages/app/src/execution.ts diff --git a/src/flow-schemas.ts b/packages/app/src/flow-schemas.ts similarity index 100% rename from src/flow-schemas.ts rename to packages/app/src/flow-schemas.ts diff --git a/src/flow-service.ts b/packages/app/src/flow-service.ts similarity index 100% rename from src/flow-service.ts rename to packages/app/src/flow-service.ts diff --git a/src/github-registry.ts b/packages/app/src/github-registry.ts similarity index 100% rename from src/github-registry.ts rename to packages/app/src/github-registry.ts diff --git a/src/github.ts b/packages/app/src/github.ts similarity index 100% rename from src/github.ts rename to packages/app/src/github.ts diff --git a/src/index.ts b/packages/app/src/index.ts similarity index 100% rename from src/index.ts rename to packages/app/src/index.ts diff --git a/src/linear-source.ts b/packages/app/src/linear-source.ts similarity index 100% rename from src/linear-source.ts rename to packages/app/src/linear-source.ts diff --git a/src/linear.ts b/packages/app/src/linear.ts similarity index 100% rename from src/linear.ts rename to packages/app/src/linear.ts diff --git a/src/matcher.ts b/packages/app/src/matcher.ts similarity index 100% rename from src/matcher.ts rename to packages/app/src/matcher.ts diff --git a/src/protected-api.ts b/packages/app/src/protected-api.ts similarity index 100% rename from src/protected-api.ts rename to packages/app/src/protected-api.ts diff --git a/src/recovery.ts b/packages/app/src/recovery.ts similarity index 100% rename from src/recovery.ts rename to packages/app/src/recovery.ts diff --git a/src/tailwind.css b/packages/app/src/tailwind.css similarity index 100% rename from src/tailwind.css rename to packages/app/src/tailwind.css diff --git a/src/tenant.ts b/packages/app/src/tenant.ts similarity index 100% rename from src/tenant.ts rename to packages/app/src/tenant.ts diff --git a/src/types.ts b/packages/app/src/types.ts similarity index 100% rename from src/types.ts rename to packages/app/src/types.ts diff --git a/src/ui.ts b/packages/app/src/ui.ts similarity index 100% rename from src/ui.ts rename to packages/app/src/ui.ts diff --git a/src/worker.ts b/packages/app/src/worker.ts similarity index 100% rename from src/worker.ts rename to packages/app/src/worker.ts diff --git a/src/workspace.ts b/packages/app/src/workspace.ts similarity index 100% rename from src/workspace.ts rename to packages/app/src/workspace.ts diff --git a/test/cloudflare-tail.test.ts b/packages/app/test/cloudflare-tail.test.ts similarity index 100% rename from test/cloudflare-tail.test.ts rename to packages/app/test/cloudflare-tail.test.ts diff --git a/test/custom-handler.test.ts b/packages/app/test/custom-handler.test.ts similarity index 100% rename from test/custom-handler.test.ts rename to packages/app/test/custom-handler.test.ts diff --git a/test/device-oauth.e2e.test.ts b/packages/app/test/device-oauth.e2e.test.ts similarity index 100% rename from test/device-oauth.e2e.test.ts rename to packages/app/test/device-oauth.e2e.test.ts diff --git a/test/device-oauth.test.ts b/packages/app/test/device-oauth.test.ts similarity index 100% rename from test/device-oauth.test.ts rename to packages/app/test/device-oauth.test.ts diff --git a/test/exe.test.ts b/packages/app/test/exe.test.ts similarity index 100% rename from test/exe.test.ts rename to packages/app/test/exe.test.ts diff --git a/test/execution-backend.test.ts b/packages/app/test/execution-backend.test.ts similarity index 100% rename from test/execution-backend.test.ts rename to packages/app/test/execution-backend.test.ts diff --git a/test/flow-service.test.ts b/packages/app/test/flow-service.test.ts similarity index 100% rename from test/flow-service.test.ts rename to packages/app/test/flow-service.test.ts diff --git a/test/github.test.ts b/packages/app/test/github.test.ts similarity index 100% rename from test/github.test.ts rename to packages/app/test/github.test.ts diff --git a/test/linear.test.ts b/packages/app/test/linear.test.ts similarity index 100% rename from test/linear.test.ts rename to packages/app/test/linear.test.ts diff --git a/test/matcher.test.ts b/packages/app/test/matcher.test.ts similarity index 100% rename from test/matcher.test.ts rename to packages/app/test/matcher.test.ts diff --git a/test/recovery.test.ts b/packages/app/test/recovery.test.ts similarity index 100% rename from test/recovery.test.ts rename to packages/app/test/recovery.test.ts diff --git a/test/ticket-prompt.test.ts b/packages/app/test/ticket-prompt.test.ts similarity index 100% rename from test/ticket-prompt.test.ts rename to packages/app/test/ticket-prompt.test.ts diff --git a/test/ui.test.ts b/packages/app/test/ui.test.ts similarity index 100% rename from test/ui.test.ts rename to packages/app/test/ui.test.ts diff --git a/test/worker.test.ts b/packages/app/test/worker.test.ts similarity index 100% rename from test/worker.test.ts rename to packages/app/test/worker.test.ts diff --git a/test/workspace.test.ts b/packages/app/test/workspace.test.ts similarity index 100% rename from test/workspace.test.ts rename to packages/app/test/workspace.test.ts diff --git a/tsconfig.json b/packages/app/tsconfig.json similarity index 100% rename from tsconfig.json rename to packages/app/tsconfig.json diff --git a/vitest.config.ts b/packages/app/vitest.config.ts similarity index 100% rename from vitest.config.ts rename to packages/app/vitest.config.ts diff --git a/vitest.e2e.config.ts b/packages/app/vitest.e2e.config.ts similarity index 100% rename from vitest.e2e.config.ts rename to packages/app/vitest.e2e.config.ts diff --git a/wrangler.jsonc b/packages/app/wrangler.jsonc similarity index 93% rename from wrangler.jsonc rename to packages/app/wrangler.jsonc index 24a7ed0..b0ce32f 100644 --- a/wrangler.jsonc +++ b/packages/app/wrangler.jsonc @@ -1,5 +1,5 @@ { - "$schema": "./node_modules/wrangler/config-schema.json", + "$schema": "../../node_modules/wrangler/config-schema.json", "name": "factorize", "main": "src/worker.ts", "compatibility_date": "2026-09-10", diff --git a/packages/tail-relay/package.json b/packages/tail-relay/package.json new file mode 100644 index 0000000..ee09c24 --- /dev/null +++ b/packages/tail-relay/package.json @@ -0,0 +1,15 @@ +{ + "name": "factorize-tail-relay", + "version": "0.1.0", + "private": true, + "type": "module", + "scripts": { + "check": "tsc --noEmit && wrangler deploy --dry-run", + "deploy": "wrangler deploy" + }, + "devDependencies": { + "@cloudflare/workers-types": "^5.20260910.1", + "typescript": "^5.9.3", + "wrangler": "^4.44.0" + } +} diff --git a/factorize-tail-relay/src/index.ts b/packages/tail-relay/src/index.ts similarity index 100% rename from factorize-tail-relay/src/index.ts rename to packages/tail-relay/src/index.ts diff --git a/factorize-tail-relay/tsconfig.json b/packages/tail-relay/tsconfig.json similarity index 100% rename from factorize-tail-relay/tsconfig.json rename to packages/tail-relay/tsconfig.json diff --git a/factorize-tail-relay/wrangler.jsonc b/packages/tail-relay/wrangler.jsonc similarity index 61% rename from factorize-tail-relay/wrangler.jsonc rename to packages/tail-relay/wrangler.jsonc index fec4a02..d0a1412 100644 --- a/factorize-tail-relay/wrangler.jsonc +++ b/packages/tail-relay/wrangler.jsonc @@ -1,5 +1,5 @@ { - "$schema": "node_modules/wrangler/config-schema.json", + "$schema": "../../node_modules/wrangler/config-schema.json", "name": "factorize-tail-relay", "main": "src/index.ts", "compatibility_date": "2026-09-10"