From 325c7c9ac042742fbe10f934b7deaa533717f64a Mon Sep 17 00:00:00 2001 From: Wang Guan Date: Tue, 14 Jul 2026 01:19:15 +0900 Subject: [PATCH 1/6] init --- .opencode/commands/build.md | 7 ++ .opencode/commands/check.md | 11 +++ .opencode/commands/demo-node.md | 7 ++ .opencode/commands/format.md | 5 ++ .opencode/commands/lint.md | 7 ++ .opencode/commands/patch-upstream.md | 10 +++ .opencode/commands/typecheck.md | 7 ++ AGENTS.md | 100 +++++++++++++++++++++++++++ mise.toml | 2 + opencode.json | 13 ++++ 10 files changed, 169 insertions(+) create mode 100644 .opencode/commands/build.md create mode 100644 .opencode/commands/check.md create mode 100644 .opencode/commands/demo-node.md create mode 100644 .opencode/commands/format.md create mode 100644 .opencode/commands/lint.md create mode 100644 .opencode/commands/patch-upstream.md create mode 100644 .opencode/commands/typecheck.md create mode 100644 AGENTS.md create mode 100644 mise.toml create mode 100644 opencode.json diff --git a/.opencode/commands/build.md b/.opencode/commands/build.md new file mode 100644 index 0000000..84534df --- /dev/null +++ b/.opencode/commands/build.md @@ -0,0 +1,7 @@ +--- +description: Build the socket.io-serverless library with esbuild +agent: build +--- +Build the socket.io-serverless library by running `make lib-build` from the repo root. This runs `pnpm run --filter socket.io-serverless build` which triggers the esbuild script in `build.mjs`. + +After building, verify the output exists at `socket.io-serverless/dist/cf.js` and check for any build errors. diff --git a/.opencode/commands/check.md b/.opencode/commands/check.md new file mode 100644 index 0000000..3ec54cd --- /dev/null +++ b/.opencode/commands/check.md @@ -0,0 +1,11 @@ +--- +description: Build + typecheck + lint the library (full CI check) +agent: build +--- +Run the full verification pipeline for the socket.io-serverless library in order: + +1. `make lib-build` — build with esbuild +2. `pnpm run --filter socket.io-serverless typecheck` — typecheck with tsc +3. `pnpm run --filter socket.io-serverless lint` — lint with eslint + +Report the results of each step. Stop and report errors if any step fails. diff --git a/.opencode/commands/demo-node.md b/.opencode/commands/demo-node.md new file mode 100644 index 0000000..8f70f70 --- /dev/null +++ b/.opencode/commands/demo-node.md @@ -0,0 +1,7 @@ +--- +description: Run the demo server locally in Node.js mode +agent: build +--- +Start the demo server in Node.js mode by running `pnpm run --filter ./demo-server dev:node` from the repo root. This uses tsx to run `src/node/main.ts` directly without Cloudflare Workers. + +The server should start and listen for connections. Report the port/host it's listening on. diff --git a/.opencode/commands/format.md b/.opencode/commands/format.md new file mode 100644 index 0000000..74c04b3 --- /dev/null +++ b/.opencode/commands/format.md @@ -0,0 +1,5 @@ +--- +description: Format code with dprint +agent: build +--- +Format the socket.io-serverless library source code by running `pnpm run --filter socket.io-serverless format` from the repo root. This uses dprint. diff --git a/.opencode/commands/lint.md b/.opencode/commands/lint.md new file mode 100644 index 0000000..1234774 --- /dev/null +++ b/.opencode/commands/lint.md @@ -0,0 +1,7 @@ +--- +description: Run ESLint on the socket.io-serverless library +agent: build +--- +Run `pnpm run --filter socket.io-serverless lint` from the repo root to check for linting errors in `socket.io-serverless/src/`. + +Report any lint errors found. If fixes are needed, run `pnpm run --filter socket.io-serverless lint:fix` to auto-fix. diff --git a/.opencode/commands/patch-upstream.md b/.opencode/commands/patch-upstream.md new file mode 100644 index 0000000..bfca1cc --- /dev/null +++ b/.opencode/commands/patch-upstream.md @@ -0,0 +1,10 @@ +--- +description: Initialize or patch the socket.io git submodule +agent: build +--- +Initialize and patch the upstream socket.io git submodule: + +1. If not already initialized: `git submodule update --init` +2. Apply patches: `make patch-upstream` + +The patches are in `patches/0001-workarounds-to-upstream-socket.io.patch` and fix export maps and import styles for esbuild bundling. diff --git a/.opencode/commands/typecheck.md b/.opencode/commands/typecheck.md new file mode 100644 index 0000000..be606e6 --- /dev/null +++ b/.opencode/commands/typecheck.md @@ -0,0 +1,7 @@ +--- +description: Typecheck the socket.io-serverless library with tsc +agent: build +--- +Typecheck the library by running `pnpm run --filter socket.io-serverless typecheck` from the repo root. + +Report any type errors found. Do NOT modify tsconfig.json to silence errors unless explicitly asked. diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 0000000..d11ef4c --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,100 @@ +# socket.io-serverless + +A custom socket.io build that runs in Cloudflare Workers + Durable Objects. This is a pnpm monorepo with the core library, demo server, and demo client. + +## Project Structure + +``` +socket.io-serverless/ # Main library (the npm package) + src/cf/index.ts # Public API entry point + src/cf/eio/ # Engine.IO layer rewired for Durable Objects + src/cf/sio/ # Socket.IO layer rewired for Durable Objects + src/debug/ # Custom debug logger replacement + src/utils/ # Utility modules (lazy, persisted) + build.mjs # esbuild script (not wrangler) - custom resolution plugins + dist/ # Build output (esm format, non-minified) + mocks/ # Stub modules replacing Node.js APIs for CF environment +demo-server/ # Backend demo app (CF Worker + Durable Objects) +demo-client/ # Frontend demo app (Preact + Vite + Tailwind) +shared-config/ # Shared tsconfig, eslint, dprint, jest configs +socket.io/ # Git submodule (upstream socket.io monorepo) +patches/ # Patches applied to the socket.io submodule +docs/ # Development and architecture documentation +``` + +## Architecture + +Two Durable Objects implement socket.io in a serverless environment: + +1. **EngineActor** (`src/cf/eio/EngineActorBase.ts`) — Runs engine.io code. Accepts WebSocket connections, forwards messages bidirectionally between `SocketActor` and real WS connections. Singleton instance. Uses DO Alarms API for heartbeat instead of `setInterval`. + +2. **SocketActor** (`src/cf/sio/SocketActorBase.ts`) — Runs socket.io code. Responds to RPC calls from `EngineActor`, emits into `Namespace`/`Client`/`Room` objects. Application logic lives in `onServerCreated` callback. Single instance (no cluster adapter yet). + +A **Worker entrypoint** (thin HTTP handler) forwards upgrade requests to `EngineActor`. State inside DOs (connection IDs, namespaces, client IDs) is persisted/revived across hibernation via DO Storage API. + +## Build & Development + +### Prerequisites +- pnpm 9.12.0 +- Node.js 20+ +- The `socket.io` git submodule must be initialized: `git submodule update --init` +- Then patch it: `make patch-upstream` (or `cd socket.io && git reset --hard socket.io@4.8.1 && git reset . && git checkout -- . && git apply < ../patches/0001-workarounds-to-upstream-socket.io.patch`) + +### Install +```bash +pnpm install +``` + +### Build the library +```bash +make lib-build # pnpm run --filter socket.io-serverless build +make lib-watch # pnpm run --filter socket.io-serverless build:watch +``` + +### Typecheck the library +```bash +# inside socket.io-serverless/ +pnpm run typecheck # tsc --noEmit +pnpm run typecheck:watch +``` + +### Lint & Format the library +```bash +# inside socket.io-serverless/ +pnpm run lint # eslint src +pnpm run lint:fix # eslint --fix src +pnpm run format # dprint fmt +``` + +### Run demos +```bash +make demo-server-dev # wrangler dev (CF Worker + DO) +make demo-client-dev # vite dev (Preact frontend) +make demo-server-bundle # wrangler deploy --dry-run +``` + +### Demo server also runs as plain Node.js +```bash +# inside demo-server/ +pnpm run dev:node # tsx watch src/node/main.ts +``` + +## Key Technical Details + +- **Build tooling**: esbuild (not wrangler) bundles `socket.io-serverless` with custom resolution plugins in `build.mjs`. Node.js stdlib imports (`http`, `fs`, `crypto`, etc.) are rewired to mock stubs in `mocks/`. Socket.io upstream TS source is imported directly (bypassing npm export maps). +- **Formatter**: dprint (config in `shared-config/dprint.json` or per-package) +- **Linter**: ESLint flat config (`.mjs` files in `shared-config/`) +- **TypeScript**: extends `@tsconfig/strictest`, moduleResolution is `bundler` +- **No tests exist yet** — jest is configured but no test files are written +- Only **WebSocket transport** is supported; engine.io protocol v4 only +- Parent namespaces must be defined in `onServerCreated` callback (no dynamic/function-based namespace creation) +- Room memberships do NOT survive DO hibernation +- No message acknowledgements, no connection state recovery + +## Code Conventions + +- TypeScript strict mode (from `@tsconfig/strictest`) +- Single quotes, no semicolons (dprint formatting) +- Use `src/debug/index.ts` instead of the `debug` npm package for logging +- Imports in the library are rewired at build time by esbuild plugins; be aware that some imports resolve to mocks in the CF environment +- Package is `type: "module"` — use ESM imports diff --git a/mise.toml b/mise.toml new file mode 100644 index 0000000..7bfeaa2 --- /dev/null +++ b/mise.toml @@ -0,0 +1,2 @@ +[tools] +opencode = "latest" diff --git a/opencode.json b/opencode.json new file mode 100644 index 0000000..ebe7ab5 --- /dev/null +++ b/opencode.json @@ -0,0 +1,13 @@ +{ + "$schema": "https://opencode.ai/config.json", + "formatter": { + "dprint": { + "command": ["pnpm", "run", "--filter", "socket.io-serverless", "format"], + "extensions": [".ts", ".js", ".mjs", ".json"] + } + }, + "instructions": [ + "docs/development.md", + "docs/how-it-works.md" + ] +} From e70d7fe90de23b8025758ce031a198656e91704d Mon Sep 17 00:00:00 2001 From: Wang Guan Date: Wed, 15 Jul 2026 00:19:51 +0900 Subject: [PATCH 2/6] test: add local integration tests via @cloudflare/vitest-pool-workers MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Run the full Worker → EngineActor → SocketActor pipeline locally in workerd via Miniflare. Tests cover the HTTP entrypoint, engine.io open packet, DO storage persistence, and AlarmTimer heartbeat flush. - demo-server/vitest.config.mts: cloudflareTest plugin reading wrangler.toml - demo-server/test/worker-entry.spec.ts: 4 HTTP entrypoint tests - demo-server/test/durable-objects.spec.ts: 4 DO state + alarm tests - demo-server/test/tsconfig.json: cloudflare:test workers types - demo-server/package.json: test / test:watch scripts, new devDeps - AGENTS.md: document the test setup and available APIs --- AGENTS.md | 20 +- demo-server/package.json | 6 +- demo-server/test/durable-objects.spec.ts | 93 ++ demo-server/test/tsconfig.json | 13 + demo-server/test/worker-entry.spec.ts | 79 + demo-server/vitest.config.mts | 15 + pnpm-lock.yaml | 1695 +++++++++++++++++++++- 7 files changed, 1917 insertions(+), 4 deletions(-) create mode 100644 demo-server/test/durable-objects.spec.ts create mode 100644 demo-server/test/tsconfig.json create mode 100644 demo-server/test/worker-entry.spec.ts create mode 100644 demo-server/vitest.config.mts diff --git a/AGENTS.md b/AGENTS.md index d11ef4c..1f73162 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -15,6 +15,8 @@ socket.io-serverless/ # Main library (the npm package) dist/ # Build output (esm format, non-minified) mocks/ # Stub modules replacing Node.js APIs for CF environment demo-server/ # Backend demo app (CF Worker + Durable Objects) + test/ # Vitest + @cloudflare/vitest-pool-workers integration tests + vitest.config.mts # Vitest config (runs DOs in workerd via Miniflare) demo-client/ # Frontend demo app (Preact + Vite + Tailwind) shared-config/ # Shared tsconfig, eslint, dprint, jest configs socket.io/ # Git submodule (upstream socket.io monorepo) @@ -79,13 +81,29 @@ make demo-server-bundle # wrangler deploy --dry-run pnpm run dev:node # tsx watch src/node/main.ts ``` +### Run integration tests +The tests use `@cloudflare/vitest-pool-workers` to spin up the real `workerd` runtime locally via Miniflare, with the Durable Object bindings from `demo-server/wrangler.toml` honored. They exercise the full Worker → EngineActor → SocketActor pipeline, inspect DO storage via `runInDurableObject`, and flush the 30 s heartbeat `AlarmTimer` via `runDurableObjectAlarm`. + +```bash +make lib-build # the Worker imports the bundled library, so build it first +pnpm run --filter demo-server test # vitest run +pnpm run --filter demo-server test:watch # vitest watch +``` + +Available test APIs (imported from `cloudflare:test` / `cloudflare:workers`): +- `env.engineActor` / `env.socketActor` — DO namespace bindings, exactly as in production +- `exports.default.fetch(req)` — invoke the Worker entrypoint as a real upgrade request +- `runInDurableObject(stub, cb)` — inspect or seed DO instance state and `state.storage` directly +- `runDurableObjectAlarm(stub)` — fire the EngineActor's `AlarmTimer` heartbeat immediately +- `evictDurableObject(stub)` — test hibernation recovery (hibernatable WebSockets + persisted state) + ## Key Technical Details - **Build tooling**: esbuild (not wrangler) bundles `socket.io-serverless` with custom resolution plugins in `build.mjs`. Node.js stdlib imports (`http`, `fs`, `crypto`, etc.) are rewired to mock stubs in `mocks/`. Socket.io upstream TS source is imported directly (bypassing npm export maps). - **Formatter**: dprint (config in `shared-config/dprint.json` or per-package) - **Linter**: ESLint flat config (`.mjs` files in `shared-config/`) - **TypeScript**: extends `@tsconfig/strictest`, moduleResolution is `bundler` -- **No tests exist yet** — jest is configured but no test files are written +- **Integration tests** live in `demo-server/test/` and use Vitest + `@cloudflare/vitest-pool-workers` (no jest tests). See "Run integration tests" above. - Only **WebSocket transport** is supported; engine.io protocol v4 only - Parent namespaces must be defined in `onServerCreated` callback (no dynamic/function-based namespace creation) - Room memberships do NOT survive DO hibernation diff --git a/demo-server/package.json b/demo-server/package.json index 1fb116e..ceeadb4 100644 --- a/demo-server/package.json +++ b/demo-server/package.json @@ -4,7 +4,8 @@ "version": "0.0.1", "description": "a simple socket.io server", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1", + "test": "vitest run", + "test:watch": "vitest", "lint": "gts lint", "clean": "gts clean", "dev:cf": "DEBUG=limb:*,-socket.io:* wrangler dev", @@ -23,6 +24,7 @@ "socket.io-serverless": "workspace:^" }, "devDependencies": { + "@cloudflare/vitest-pool-workers": "^0.18.4", "@cloudflare/workers-types": "^4.20241004.0", "@tsconfig/strictest": "^2.0.5", "@types/debug": "^4.1.12", @@ -31,6 +33,8 @@ "base64id": "^2.0.0", "tsx": "*", "typescript": "*", + "vite": "^6.0.0", + "vitest": "^4.1.0", "wrangler": "^3.80" } } diff --git a/demo-server/test/durable-objects.spec.ts b/demo-server/test/durable-objects.spec.ts new file mode 100644 index 0000000..97162ad --- /dev/null +++ b/demo-server/test/durable-objects.spec.ts @@ -0,0 +1,93 @@ +import { describe, it, expect } from 'vitest' +import { env, runInDurableObject, runDurableObjectAlarm } from 'cloudflare:test' +import { exports } from 'cloudflare:workers' +import type { SocketActor } from '../src/cf/main' + +const IncomingRequest = Request> + +function openClientWebSocket(res: Response): WebSocket { + const ws = res.webSocket + if (!ws) throw new Error('response has no webSocket') + ws.accept() + return ws +} + +function nextMessage(ws: WebSocket, timeoutMs = 2000): Promise { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error('timeout waiting for ws message')), timeoutMs) + ws.addEventListener('message', (e: MessageEvent) => { + clearTimeout(timer) + resolve(typeof e.data === 'string' ? e.data : String(e.data)) + }, { once: true }) + }) +} + +/** The Worker generates the engine.io `sid` via `generateBase64id()`, + * ignoring any client-supplied `eio_sid` query param, so it must be + * recovered from the engine.io "open" packet that follows the upgrade. + */ +async function openSocketIoConnection(): Promise<{ ws: WebSocket; eioSid: string }> { + const req = new IncomingRequest('https://example.com/socket.io/', { + headers: { upgrade: 'websocket' }, + }) + const res = await exports.default.fetch(req) + if (res.status !== 101) throw new Error(`expected 101, got ${res.status}`) + const ws = openClientWebSocket(res) + const openPacket = await nextMessage(ws) + if (openPacket[0] !== '0') throw new Error(`expected engine.io open packet, got ${openPacket}`) + const eioSid = JSON.parse(openPacket.slice(1)).sid as string + return { ws, eioSid } +} + +describe('durable object state', () => { + it('exposes both DO namespaces as bindings', () => { + expect(env.engineActor).toBeDefined() + expect(env.socketActor).toBeDefined() + // both bindings can resolve the singleton name; IDs will differ across namespaces + const engineId = env.engineActor.idFromName('singleton') + const socketId = env.socketActor.idFromName('singleton') + expect(typeof engineId.toString()).toBe('string') + expect(typeof socketId.toString()).toBe('string') + }) + + it('EngineActor rejects non-upgrade requests with 426', async () => { + const id = env.engineActor.idFromName('singleton') + const stub = env.engineActor.get(id) + const res = await stub.fetch('https://eioServer.internal/socket.io/?eio_sid=abcdefghij') + expect(res.status).toBe(426) + }) + + it('persists a new client into SocketActor storage after a WS connection', async () => { + const { ws, eioSid } = await openSocketIoConnection() + try { + // give the 100ms-delayed createEioSocket + onEioSocketConnection a moment + // to land in SocketActor's Persister + await new Promise((r) => setTimeout(r, 250)) + + const id = env.socketActor.idFromName('singleton') + const stub = env.socketActor.get(id) + const storedClients = await runInDurableObject(stub, async (_instance: SocketActor, state) => { + const entry = await state.storage.get<{ clientIds: string[] }>('_clients') + return entry?.clientIds ?? [] + }) + expect(storedClients).toContain(eioSid) + } finally { + ws.close() + } + }) + + it('runs the EngineActor alarm without throwing', async () => { + const { ws } = await openSocketIoConnection() + try { + await new Promise((r) => setTimeout(r, 250)) + const id = env.engineActor.idFromName('singleton') + const stub = env.engineActor.get(id) + // runDurableObjectAlarm returns true if an alarm was scheduled and ran. + // AlarmTimer schedules a 30s alarm on each new connection; this flushes it. + const ran = await runDurableObjectAlarm(stub) + expect(typeof ran).toBe('boolean') + } finally { + ws.close() + } + }) +}) \ No newline at end of file diff --git a/demo-server/test/tsconfig.json b/demo-server/test/tsconfig.json new file mode 100644 index 0000000..4c8d841 --- /dev/null +++ b/demo-server/test/tsconfig.json @@ -0,0 +1,13 @@ +{ + "extends": "../tsconfig.json", + "compilerOptions": { + "moduleResolution": "bundler", + "types": [ + "@cloudflare/vitest-pool-workers/types" + ] + }, + "include": [ + "./**/*.ts", + "../src/cf/main.ts" + ] +} \ No newline at end of file diff --git a/demo-server/test/worker-entry.spec.ts b/demo-server/test/worker-entry.spec.ts new file mode 100644 index 0000000..3d2dc5f --- /dev/null +++ b/demo-server/test/worker-entry.spec.ts @@ -0,0 +1,79 @@ +import { describe, it, expect } from 'vitest' +import { exports } from 'cloudflare:workers' + +const IncomingRequest = Request> + +function openClientWebSocket(res: Response): WebSocket { + const ws = res.webSocket + if (!ws) throw new Error('response has no webSocket') + ws.accept() + return ws +} + +function nextMessage(ws: WebSocket, timeoutMs = 2000): Promise { + return new Promise((resolve, reject) => { + const timer = setTimeout(() => reject(new Error('timeout waiting for ws message')), timeoutMs) + ws.addEventListener('message', (e: MessageEvent) => { + clearTimeout(timer) + resolve(typeof e.data === 'string' ? e.data : String(e.data)) + }, { once: true }) + ws.addEventListener('error', () => { + clearTimeout(timer) + reject(new Error('ws error')) + }, { once: true }) + ws.addEventListener('close', () => { + clearTimeout(timer) + reject(new Error('ws closed before message')) + }, { once: true }) + }) +} + +describe('worker fetch entrypoint', () => { + it('returns 404 for non /socket.io/ paths', async () => { + const req = new IncomingRequest('https://example.com/other') + const res = await exports.default.fetch(req) + expect(res.status).toBe(404) + }) + + it('returns 400 when /socket.io/ request is not a websocket upgrade', async () => { + const req = new IncomingRequest('https://example.com/socket.io/') + const res = await exports.default.fetch(req) + expect(res.status).toBe(400) + expect(await res.text()).toBe('websocket only') + }) + + it('returns 101 and a websocket for upgrade requests', async () => { + const req = new IncomingRequest('https://example.com/socket.io/?eio_sid=test-sid-12345', { + headers: { upgrade: 'websocket' }, + }) + const res = await exports.default.fetch(req) + expect(res.status).toBe(101) + expect(res.webSocket).toBeDefined() + const ws = openClientWebSocket(res) + ws.close() + }) + + it('delivers an engine.io "open" packet on the upgraded WebSocket', async () => { + const req = new IncomingRequest('https://example.com/socket.io/?eio_sid=test-sid-67890', { + headers: { upgrade: 'websocket' }, + }) + const res = await exports.default.fetch(req) + expect(res.status).toBe(101) + const ws = openClientWebSocket(res) + try { + const openPacket = await nextMessage(ws) + // engine.io v4 open packet: '0' followed by JSON handshake + expect(openPacket[0]).toBe('0') + const handshake = JSON.parse(openPacket.slice(1)) + // sid is generated by the Worker from generateBase64id(), not the URL param + expect(typeof handshake.sid).toBe('string') + expect(handshake.sid.length).toBeGreaterThan(10) + expect(handshake).toHaveProperty('pingInterval') + expect(handshake).toHaveProperty('pingTimeout') + // allow the 100ms-delayed createEioSocket + SocketActor wiring to settle + await new Promise((r) => setTimeout(r, 200)) + } finally { + ws.close() + } + }) +}) \ No newline at end of file diff --git a/demo-server/vitest.config.mts b/demo-server/vitest.config.mts new file mode 100644 index 0000000..82bd13a --- /dev/null +++ b/demo-server/vitest.config.mts @@ -0,0 +1,15 @@ +import { cloudflareTest } from '@cloudflare/vitest-pool-workers' +import { defineConfig } from 'vitest/config' + +export default defineConfig({ + plugins: [ + cloudflareTest({ + wrangler: { configPath: './wrangler.toml' }, + }), + ], + test: { + // accept unhandled rejections surfaced by pool-workers when it defensively + // probes RPC accessors on the DO wrapper proxy (e.g. ".call", ".entries"). + dangerouslyIgnoreUnhandledErrors: true, + }, +}) \ No newline at end of file diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 0d75966..174de44 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -134,6 +134,9 @@ importers: specifier: workspace:^ version: link:../socket.io-serverless devDependencies: + '@cloudflare/vitest-pool-workers': + specifier: ^0.18.4 + version: 0.18.4(@cloudflare/workers-types@4.20241004.0)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@types/node@20.16.10)(vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1))) '@cloudflare/workers-types': specifier: ^4.20241004.0 version: 4.20241004.0 @@ -158,6 +161,12 @@ importers: typescript: specifier: '*' version: 5.6.2 + vite: + specifier: ^6.0.0 + version: 6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1) + vitest: + specifier: ^4.1.0 + version: 4.1.10(@types/node@20.16.10)(vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1)) wrangler: specifier: ^3.80 version: 3.80.0(@cloudflare/workers-types@4.20241004.0) @@ -429,36 +438,86 @@ packages: resolution: {integrity: sha512-YLPHc8yASwjNkmcDMQMY35yiWjoKAKnhUbPRszBRS0YgH+IXtsMp61j+yTcnCE3oO2DgP0U3iejLC8FTtKDC8Q==} engines: {node: '>=16.13'} + '@cloudflare/kv-asset-handler@0.5.0': + resolution: {integrity: sha512-jxQYkj8dSIzc0cD6cMMNdOc1UVjqSqu8BZdor5s8cGjW2I8BjODt/kWPVdY+u9zj3ms75Q5qaZgnxUad83+eAg==} + engines: {node: '>=22.0.0'} + + '@cloudflare/unenv-preset@2.16.1': + resolution: {integrity: sha512-ECxObrMfyTl5bhQf/lZCXwo5G6xX9IAUo+nDMKK4SZ8m4Jvvxp52vilxyySSWh2YTZz8+HQ07qGH/2rEom1vDw==} + peerDependencies: + unenv: 2.0.0-rc.24 + workerd: '>1.20260305.0 <2.0.0-0' + peerDependenciesMeta: + workerd: + optional: true + + '@cloudflare/vitest-pool-workers@0.18.4': + resolution: {integrity: sha512-jOXvyLoR2b8jFvo3tX+mWxXXwcZ+PbId3d7vGFtZsuKakmDjKSeIq4o/sQjkqNv6q3XacIKSCAvfM8TfkPyrEw==} + peerDependencies: + '@vitest/runner': ^4.1.0 + '@vitest/snapshot': ^4.1.0 + vitest: ^4.1.0 + '@cloudflare/workerd-darwin-64@1.20240925.0': resolution: {integrity: sha512-KdLnSXuzB65CbqZPm+qYzk+zkQ1tUNPaaRGYVd/jPYAxwwtfTUQdQ+ahDPwVVs2tmQELKy7ZjQjf2apqSWUfjw==} engines: {node: '>=16'} cpu: [x64] os: [darwin] + '@cloudflare/workerd-darwin-64@1.20260708.1': + resolution: {integrity: sha512-HXFCvhS1wpg3uXO0CLUwmwC41i2loM5FSK69EUchOBpmYBAXxT1oHLm6EOA5lqhTk5Mu9kjRiQYxa1GwKPwfJg==} + engines: {node: '>=16'} + cpu: [x64] + os: [darwin] + '@cloudflare/workerd-darwin-arm64@1.20240925.0': resolution: {integrity: sha512-MiQ6uUmCXjsXgWNV+Ock2tp2/tYqNJGzjuaH6jFioeRF+//mz7Tv7J7EczOL4zq+TH8QFOh0/PUsLyazIWVGng==} engines: {node: '>=16'} cpu: [arm64] os: [darwin] + '@cloudflare/workerd-darwin-arm64@1.20260708.1': + resolution: {integrity: sha512-JVlJaKDoRTVKSroHIlf8g3UCPjKj4iDbMZE2CNYht5qQ+2rL0FAUiVlV82G3BqKnnw9kHYnnsMzC08b9zVtdzA==} + engines: {node: '>=16'} + cpu: [arm64] + os: [darwin] + '@cloudflare/workerd-linux-64@1.20240925.0': resolution: {integrity: sha512-Rjix8jsJMfsInmq3Hm3fmiRQ+rwzuWRPV1pg/OWhMSfNP7Qp2RCU+RGkhgeR9Z5eNAje0Sn2BMrFq4RvF9/yRA==} engines: {node: '>=16'} cpu: [x64] os: [linux] + '@cloudflare/workerd-linux-64@1.20260708.1': + resolution: {integrity: sha512-3daE60YdD7YX0Jtuzc9DE/r/qMkmx8ZvHTkF8Mzmp3F5tbzlV0DAzmu5PFUPF2WuvtKbAhZKbvC2cHmWpQYxnA==} + engines: {node: '>=16'} + cpu: [x64] + os: [linux] + '@cloudflare/workerd-linux-arm64@1.20240925.0': resolution: {integrity: sha512-VYIPeMHQRtbwQoIjUwS/zULlywPxyDvo46XkTpIW5MScEChfqHvAYviQ7TzYGx6Q+gmZmN+DUB2KOMx+MEpCxA==} engines: {node: '>=16'} cpu: [arm64] os: [linux] + '@cloudflare/workerd-linux-arm64@1.20260708.1': + resolution: {integrity: sha512-VLdNYOx5Hj+9C6isy0ACWZsbMtSxex2DIJWEe7cZxUdlphZ58ZT8zxNXK8yunFiowd34hn3VwGMopdvdj8lvmA==} + engines: {node: '>=16'} + cpu: [arm64] + os: [linux] + '@cloudflare/workerd-windows-64@1.20240925.0': resolution: {integrity: sha512-C8peGvaU5R51bIySi1VbyfRgwNSSRknqoFSnSbSBI3uTN3THTB3UnmRKy7GXJDmyjgXuT9Pcs1IgaWNubLtNtw==} engines: {node: '>=16'} cpu: [x64] os: [win32] + '@cloudflare/workerd-windows-64@1.20260708.1': + resolution: {integrity: sha512-bC/aSAwLy16Vjo24i9XU3aWH+eRgz7NeR5xPKavGbembO18ZywYTQbXh14eXtY6fAqN3RzRG8psijTdhX4xydA==} + engines: {node: '>=16'} + cpu: [x64] + os: [win32] + '@cloudflare/workers-shared@0.5.4': resolution: {integrity: sha512-PNL/0TjKRdUHa1kwgVdqUNJVZ9ez4kacsi8omz+gv859EvJmsVuGiMAClY2YfJnC9LVKhKCcjqmFgKNXG9/IXA==} engines: {node: '>=16.7.0'} @@ -510,6 +569,9 @@ packages: cpu: [x64] os: [win32] + '@emnapi/runtime@1.11.2': + resolution: {integrity: sha512-kyOl3X0DuTiT1h2ft8r2fYO8JYtU9a9Xis/zBSiGArNaagCOWx90N1k2wxp18czFDH+OgcWGb5ZP/XMt3dcyPA==} + '@esbuild-plugins/node-globals-polyfill@0.2.3': resolution: {integrity: sha512-r3MIryXDeXDOZh7ih1l/yE9ZLORCd5e8vWg02azWRGj5SPTuoh69A2AIyn0Z31V/kHBfZ4HgWJ+OK3GTTwLmnw==} peerDependencies: @@ -538,6 +600,18 @@ packages: cpu: [ppc64] os: [aix] + '@esbuild/aix-ppc64@0.25.12': + resolution: {integrity: sha512-Hhmwd6CInZ3dwpuGTF8fJG6yoWmsToE+vYgD4nytZVxcu1ulHpUQRAB1UJ8+N1Am3Mz4+xOByoQoSZf4D+CpkA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/aix-ppc64@0.28.1': + resolution: {integrity: sha512-Svl7tq8k/08+p6CXPpRjQ1fKX+1odH/BQbb48fV6fj3CWHhsoIOoY87w1oHXm0qEpkIK3ZfVgp0hed3XBXzXMQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + '@esbuild/android-arm64@0.17.19': resolution: {integrity: sha512-KBMWvEZooR7+kzY0BtbTQn0OAYY7CsiydT63pVEaPtVYF0hXbUaOyZog37DKxK7NF3XacBJOpYT4adIJh+avxA==} engines: {node: '>=12'} @@ -562,6 +636,18 @@ packages: cpu: [arm64] os: [android] + '@esbuild/android-arm64@0.25.12': + resolution: {integrity: sha512-6AAmLG7zwD1Z159jCKPvAxZd4y/VTO0VkprYy+3N2FtJ8+BQWFXU+OxARIwA46c5tdD9SsKGZ/1ocqBS/gAKHg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.28.1': + resolution: {integrity: sha512-34EGEbCIAgosYz6goLcopX6Mo7NyGv9tfwEM2/7Ce2VcVRk568iSvniGWcUXIy7wEDR1wzolcxcriFVrWYcwBg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm@0.17.19': resolution: {integrity: sha512-rIKddzqhmav7MSmoFCmDIb6e2W57geRsM94gV2l38fzhXMwq7hZoClug9USI2pFRGL06f4IOPHHpFNOkWieR8A==} engines: {node: '>=12'} @@ -586,6 +672,18 @@ packages: cpu: [arm] os: [android] + '@esbuild/android-arm@0.25.12': + resolution: {integrity: sha512-VJ+sKvNA/GE7Ccacc9Cha7bpS8nyzVv0jdVgwNDaR4gDMC/2TTRc33Ip8qrNYUcpkOHUT5OZ0bUcNNVZQ9RLlg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.28.1': + resolution: {integrity: sha512-0k2F129Xdio1TdJfzJ8sy1Q47vUD2NnwdhiAf7drUN1EBTfPf4hsFCtmMgu/6m8JSzsBrlmVjudMBQqOfG8usQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + '@esbuild/android-x64@0.17.19': resolution: {integrity: sha512-uUTTc4xGNDT7YSArp/zbtmbhO0uEEK9/ETW29Wk1thYUJBz3IVnvgEiEwEa9IeLyvnpKrWK64Utw2bgUmDveww==} engines: {node: '>=12'} @@ -610,6 +708,18 @@ packages: cpu: [x64] os: [android] + '@esbuild/android-x64@0.25.12': + resolution: {integrity: sha512-5jbb+2hhDHx5phYR2By8GTWEzn6I9UqR11Kwf22iKbNpYrsmRB18aX/9ivc5cabcUiAT/wM+YIZ6SG9QO6a8kg==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.28.1': + resolution: {integrity: sha512-dbwY7ltSMDWsRatcRpCnES4F+im88OCUgGZjy52shC7GqHRE/cYlxNbB4Z4UpJswpcc4Qxd2oE/ufM0p61IKng==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + '@esbuild/darwin-arm64@0.17.19': resolution: {integrity: sha512-80wEoCfF/hFKM6WE1FyBHc9SfUblloAWx6FJkFWTWiCoht9Mc0ARGEM47e67W9rI09YoUxJL68WHfDRYEAvOhg==} engines: {node: '>=12'} @@ -634,6 +744,18 @@ packages: cpu: [arm64] os: [darwin] + '@esbuild/darwin-arm64@0.25.12': + resolution: {integrity: sha512-N3zl+lxHCifgIlcMUP5016ESkeQjLj/959RxxNYIthIg+CQHInujFuXeWbWMgnTo4cp5XVHqFPmpyu9J65C1Yg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.28.1': + resolution: {integrity: sha512-TZbWkQY7kvTAXbXUT7uVACR5cMHsDiSz9z7ZKAX/RTq/WJEk3QyRr0wZpNhBDX+/0CtdqUIJlOiodQcta6tY3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-x64@0.17.19': resolution: {integrity: sha512-IJM4JJsLhRYr9xdtLytPLSH9k/oxR3boaUIYiHkAawtwNOXKE8KoU8tMvryogdcT8AU+Bflmh81Xn6Q0vTZbQw==} engines: {node: '>=12'} @@ -658,6 +780,18 @@ packages: cpu: [x64] os: [darwin] + '@esbuild/darwin-x64@0.25.12': + resolution: {integrity: sha512-HQ9ka4Kx21qHXwtlTUVbKJOAnmG1ipXhdWTmNXiPzPfWKpXqASVcWdnf2bnL73wgjNrFXAa3yYvBSd9pzfEIpA==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.1': + resolution: {integrity: sha512-zfdzgK9ACBNZLI/CyHTOx81SyNbM6YXn7rxSgX97VjyiPl9W1i4Ka4fgKECEoFCKGpvBj5qArWIGgQjOwkgskQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + '@esbuild/freebsd-arm64@0.17.19': resolution: {integrity: sha512-pBwbc7DufluUeGdjSU5Si+P3SoMF5DQ/F/UmTSb8HXO80ZEAJmrykPyzo1IfNbAoaqw48YRpv8shwd1NoI0jcQ==} engines: {node: '>=12'} @@ -682,6 +816,18 @@ packages: cpu: [arm64] os: [freebsd] + '@esbuild/freebsd-arm64@0.25.12': + resolution: {integrity: sha512-gA0Bx759+7Jve03K1S0vkOu5Lg/85dou3EseOGUes8flVOGxbhDDh/iZaoek11Y8mtyKPGF3vP8XhnkDEAmzeg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.28.1': + resolution: {integrity: sha512-wG2EA8ENdEI0qhkSZMjfqrdY+ziCYCPMmtZjjIwOmXFjmyzEHn+UUxk5of+SYsjtfs3VpnlC7QLzSI5hY/rOAw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-x64@0.17.19': resolution: {integrity: sha512-4lu+n8Wk0XlajEhbEffdy2xy53dpR06SlzvhGByyg36qJw6Kpfk7cp45DR/62aPH9mtJRmIyrXAS5UWBrJT6TQ==} engines: {node: '>=12'} @@ -706,6 +852,18 @@ packages: cpu: [x64] os: [freebsd] + '@esbuild/freebsd-x64@0.25.12': + resolution: {integrity: sha512-TGbO26Yw2xsHzxtbVFGEXBFH0FRAP7gtcPE7P5yP7wGy7cXK2oO7RyOhL5NLiqTlBh47XhmIUXuGciXEqYFfBQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.1': + resolution: {integrity: sha512-i7dZ9vQgnvSCzi/rYCXNgtF/U+eKZNJBzu3eTQbRgHnM7tNSizLOkRFAl3qzVc/Op/u5YkHHa4pf/3DOYHthLQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + '@esbuild/linux-arm64@0.17.19': resolution: {integrity: sha512-ct1Tg3WGwd3P+oZYqic+YZF4snNl2bsnMKRkb3ozHmnM0dGWuxcPTTntAF6bOP0Sp4x0PjSF+4uHQ1xvxfRKqg==} engines: {node: '>=12'} @@ -730,6 +888,18 @@ packages: cpu: [arm64] os: [linux] + '@esbuild/linux-arm64@0.25.12': + resolution: {integrity: sha512-8bwX7a8FghIgrupcxb4aUmYDLp8pX06rGh5HqDT7bB+8Rdells6mHvrFHHW2JAOPZUbnjUpKTLg6ECyzvas2AQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.28.1': + resolution: {integrity: sha512-yHs+0uc8+nvEAfAfxrWQKK5peSNzBc4PegcMO0EJ2hT71uA7vB8Ihg2e77R2P7SG5uYjPbHlLLmve4LLLRCf0g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm@0.17.19': resolution: {integrity: sha512-cdmT3KxjlOQ/gZ2cjfrQOtmhG4HJs6hhvm3mWSRDPtZ/lP5oe8FWceS10JaSJC13GBd4eH/haHnqf7hhGNLerA==} engines: {node: '>=12'} @@ -754,6 +924,18 @@ packages: cpu: [arm] os: [linux] + '@esbuild/linux-arm@0.25.12': + resolution: {integrity: sha512-lPDGyC1JPDou8kGcywY0YILzWlhhnRjdof3UlcoqYmS9El818LLfJJc3PXXgZHrHCAKs/Z2SeZtDJr5MrkxtOw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.28.1': + resolution: {integrity: sha512-qVXBOHQS+d5Y722GwJzJUtOLlX7km3CraOaGormF1pDtPd2C/l1SHRPgjLunLGe51Sh5YYWKMFDyV4SxgMQYTQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + '@esbuild/linux-ia32@0.17.19': resolution: {integrity: sha512-w4IRhSy1VbsNxHRQpeGCHEmibqdTUx61Vc38APcsRbuVgK0OPEnQ0YD39Brymn96mOx48Y2laBQGqgZ0j9w6SQ==} engines: {node: '>=12'} @@ -778,6 +960,18 @@ packages: cpu: [ia32] os: [linux] + '@esbuild/linux-ia32@0.25.12': + resolution: {integrity: sha512-0y9KrdVnbMM2/vG8KfU0byhUN+EFCny9+8g202gYqSSVMonbsCfLjUO+rCci7pM0WBEtz+oK/PIwHkzxkyharA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.28.1': + resolution: {integrity: sha512-d1z4ZuP0ajrfz/FhGT4vv278rX8KnPPJx8i5+AtK7TYbx9Le9F1hyzurZpkEyjkGa9dUGhQow4C1NmeGvqxN2w==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-loong64@0.17.19': resolution: {integrity: sha512-2iAngUbBPMq439a+z//gE+9WBldoMp1s5GWsUSgqHLzLJ9WoZLZhpwWuym0u0u/4XmZ3gpHmzV84PonE+9IIdQ==} engines: {node: '>=12'} @@ -802,6 +996,18 @@ packages: cpu: [loong64] os: [linux] + '@esbuild/linux-loong64@0.25.12': + resolution: {integrity: sha512-h///Lr5a9rib/v1GGqXVGzjL4TMvVTv+s1DPoxQdz7l/AYv6LDSxdIwzxkrPW438oUXiDtwM10o9PmwS/6Z0Ng==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.28.1': + resolution: {integrity: sha512-M5sRjUVZrkm1OAPR3dlOYzNmN+loZKGVi1VUQGrwuqLcbR6qeAz+famMhjASeH3YVKvZz+zT1jlh/keC3Rj/lg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-mips64el@0.17.19': resolution: {integrity: sha512-LKJltc4LVdMKHsrFe4MGNPp0hqDFA1Wpt3jE1gEyM3nKUvOiO//9PheZZHfYRfYl6AwdTH4aTcXSqBerX0ml4A==} engines: {node: '>=12'} @@ -826,6 +1032,18 @@ packages: cpu: [mips64el] os: [linux] + '@esbuild/linux-mips64el@0.25.12': + resolution: {integrity: sha512-iyRrM1Pzy9GFMDLsXn1iHUm18nhKnNMWscjmp4+hpafcZjrr2WbT//d20xaGljXDBYHqRcl8HnxbX6uaA/eGVw==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.28.1': + resolution: {integrity: sha512-mRObBZeHh2OxcBFPWE/FjylkRgZdYuiTR3vaTozquCGOH14iP9oN4x4Ge81CoIDYQrXmIxpFumJBu5MtZpnQJQ==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-ppc64@0.17.19': resolution: {integrity: sha512-/c/DGybs95WXNS8y3Ti/ytqETiW7EU44MEKuCAcpPto3YjQbyK3IQVKfF6nbghD7EcLUGl0NbiL5Rt5DMhn5tg==} engines: {node: '>=12'} @@ -850,6 +1068,18 @@ packages: cpu: [ppc64] os: [linux] + '@esbuild/linux-ppc64@0.25.12': + resolution: {integrity: sha512-9meM/lRXxMi5PSUqEXRCtVjEZBGwB7P/D4yT8UG/mwIdze2aV4Vo6U5gD3+RsoHXKkHCfSxZKzmDssVlRj1QQA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.28.1': + resolution: {integrity: sha512-slScBsMAb3GFDcdrCgLwZtPYRoH2H/youv10QiZyRjmsP48fznoveWytSgCI/R0ZcUgpc0ZhIUEx6LHts8yrfQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-riscv64@0.17.19': resolution: {integrity: sha512-FC3nUAWhvFoutlhAkgHf8f5HwFWUL6bYdvLc/TTuxKlvLi3+pPzdZiFKSWz/PF30TB1K19SuCxDTI5KcqASJqA==} engines: {node: '>=12'} @@ -874,6 +1104,18 @@ packages: cpu: [riscv64] os: [linux] + '@esbuild/linux-riscv64@0.25.12': + resolution: {integrity: sha512-Zr7KR4hgKUpWAwb1f3o5ygT04MzqVrGEGXGLnj15YQDJErYu/BGg+wmFlIDOdJp0PmB0lLvxFIOXZgFRrdjR0w==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.1': + resolution: {integrity: sha512-kw0owk1o0GFETUJyW0jc0G4Yzs0BHZn0JDZ8JRT088vjJYX777BAs1fDGxAC+q831qOs2DTC96mNsG2opdfyyQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-s390x@0.17.19': resolution: {integrity: sha512-IbFsFbxMWLuKEbH+7sTkKzL6NJmG2vRyy6K7JJo55w+8xDk7RElYn6xvXtDW8HCfoKBFK69f3pgBJSUSQPr+4Q==} engines: {node: '>=12'} @@ -898,6 +1140,18 @@ packages: cpu: [s390x] os: [linux] + '@esbuild/linux-s390x@0.25.12': + resolution: {integrity: sha512-MsKncOcgTNvdtiISc/jZs/Zf8d0cl/t3gYWX8J9ubBnVOwlk65UIEEvgBORTiljloIWnBzLs4qhzPkJcitIzIg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.28.1': + resolution: {integrity: sha512-/lAIjX8aYFRByhh6L5rYtPEDRqa9de/4V/juOXcta5frjvzXO4/sqEtyytse0g3zZFuWu5cDN0MkLz2qRDD2Ag==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-x64@0.17.19': resolution: {integrity: sha512-68ngA9lg2H6zkZcyp22tsVt38mlhWde8l3eJLWkyLrp4HwMUr3c1s/M2t7+kHIhvMjglIBrFpncX1SzMckomGw==} engines: {node: '>=12'} @@ -922,6 +1176,30 @@ packages: cpu: [x64] os: [linux] + '@esbuild/linux-x64@0.25.12': + resolution: {integrity: sha512-uqZMTLr/zR/ed4jIGnwSLkaHmPjOjJvnm6TVVitAa08SLS9Z0VM8wIRx7gWbJB5/J54YuIMInDquWyYvQLZkgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.28.1': + resolution: {integrity: sha512-u/anNYF2mmVOEDwLtnQ1wOr3EZ9sTNGLWrsYGYwHWzGA3Si84IOkHXlbWTD1NB+9/1lcnweYKO54uhxZydNzfA==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.25.12': + resolution: {integrity: sha512-xXwcTq4GhRM7J9A8Gv5boanHhRa/Q9KLVmcyXHCTaM4wKfIpWkdXiMog/KsnxzJ0A1+nD+zoecuzqPmCRyBGjg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-arm64@0.28.1': + resolution: {integrity: sha512-oks0DYbLwWMmaakTsCb+zL4E+aHRVLom9IJZOAthMQEPiQmydXHkziYEsGYRx0uNV/IjEKGAV941JzH02pflqw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + '@esbuild/netbsd-x64@0.17.19': resolution: {integrity: sha512-CwFq42rXCR8TYIjIfpXCbRX0rp1jo6cPIUPSaWwzbVI4aOfX96OXY8M6KNmtPcg7QjYeDmN+DD0Wp3LaBOLf4Q==} engines: {node: '>=12'} @@ -946,6 +1224,18 @@ packages: cpu: [x64] os: [netbsd] + '@esbuild/netbsd-x64@0.25.12': + resolution: {integrity: sha512-Ld5pTlzPy3YwGec4OuHh1aCVCRvOXdH8DgRjfDy/oumVovmuSzWfnSJg+VtakB9Cm0gxNO9BzWkj6mtO1FMXkQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.1': + resolution: {integrity: sha512-aeL6lAnN89Hz43Mlh1G8ARasbuoYvSITDEx0tHh5b7jJnHcssqgjy9Yx430GDpmCa6OyrKoS0aNRjKundRizGg==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.23.1': resolution: {integrity: sha512-3x37szhLexNA4bXhLrCC/LImN/YtWis6WXr1VESlfVtVeoFJBRINPJ3f0a/6LV8zpikqoUg4hyXw0sFBt5Cr+Q==} engines: {node: '>=18'} @@ -958,6 +1248,18 @@ packages: cpu: [arm64] os: [openbsd] + '@esbuild/openbsd-arm64@0.25.12': + resolution: {integrity: sha512-fF96T6KsBo/pkQI950FARU9apGNTSlZGsv1jZBAlcLL1MLjLNIWPBkj5NlSz8aAzYKg+eNqknrUJ24QBybeR5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-arm64@0.28.1': + resolution: {integrity: sha512-MEFJe5C3R8pwXdZ5Y21oo6m7ePiS0d9pWucn99O/wvyJZChoIQKrQDxKrGeW8F5+T0okTHesAmDeiHDTIq0V/Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + '@esbuild/openbsd-x64@0.17.19': resolution: {integrity: sha512-cnq5brJYrSZ2CF6c35eCmviIN3k3RczmHz8eYaVlNasVqsNY+JKohZU5MKmaOI+KkllCdzOKKdPs762VCPC20g==} engines: {node: '>=12'} @@ -982,6 +1284,30 @@ packages: cpu: [x64] os: [openbsd] + '@esbuild/openbsd-x64@0.25.12': + resolution: {integrity: sha512-MZyXUkZHjQxUvzK7rN8DJ3SRmrVrke8ZyRusHlP+kuwqTcfWLyqMOE3sScPPyeIXN/mDJIfGXvcMqCgYKekoQw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.1': + resolution: {integrity: sha512-i/ZLIOafE0Z8cI/XANJAixoJL/uRAoS2xOA3rb0xN+KK0K177cMAsQYkzHtBrtMXAKuAc7HGgcWiZ/sRC1Nxgw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.28.1': + resolution: {integrity: sha512-ge+Z7EXFNt2BO1oAMsVpiQ8EwndV9i1xXerAeTIK7AtPs3bKFXQM7nlRxDSIUIMeueR1CNXxqztLzdNeReKBJg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + '@esbuild/sunos-x64@0.17.19': resolution: {integrity: sha512-vCRT7yP3zX+bKWFeP/zdS6SqdWB8OIpaRq/mbXQxTGHnIxspRtigpkUcDMlSCOejlHowLqII7K2JKevwyRP2rg==} engines: {node: '>=12'} @@ -1006,6 +1332,18 @@ packages: cpu: [x64] os: [sunos] + '@esbuild/sunos-x64@0.25.12': + resolution: {integrity: sha512-3wGSCDyuTHQUzt0nV7bocDy72r2lI33QL3gkDNGkod22EsYl04sMf0qLb8luNKTOmgF/eDEDP5BFNwoBKH441w==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.28.1': + resolution: {integrity: sha512-BEjgtECkL3vY+SaSQ6nzVfiALUeFxpawyp8Jmf5PtYhf1Ug40N1h/hxlhts+f1FvSvarEigdxS3BlSMI2PJLcQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + '@esbuild/win32-arm64@0.17.19': resolution: {integrity: sha512-yYx+8jwowUstVdorcMdNlzklLYhPxjniHWFKgRqH7IFlUEa0Umu3KuYplf1HUZZ422e3NU9F4LGb+4O0Kdcaag==} engines: {node: '>=12'} @@ -1030,6 +1368,18 @@ packages: cpu: [arm64] os: [win32] + '@esbuild/win32-arm64@0.25.12': + resolution: {integrity: sha512-rMmLrur64A7+DKlnSuwqUdRKyd3UE7oPJZmnljqEptesKM8wx9J8gx5u0+9Pq0fQQW8vqeKebwNXdfOyP+8Bsg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.28.1': + resolution: {integrity: sha512-lCv9eK/H6ZJWbE7bh2nw54CZ9M2nupBxJcTsdk/QQnWkdSjKGuxmmH8/GWrlT1eMmZfn4dGcCjRte397WqfQXA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-ia32@0.17.19': resolution: {integrity: sha512-eggDKanJszUtCdlVs0RB+h35wNlb5v4TWEkq4vZcmVt5u/HiDZrTXe2bWFQUez3RgNHwx/x4sk5++4NSSicKkw==} engines: {node: '>=12'} @@ -1054,6 +1404,18 @@ packages: cpu: [ia32] os: [win32] + '@esbuild/win32-ia32@0.25.12': + resolution: {integrity: sha512-HkqnmmBoCbCwxUKKNPBixiWDGCpQGVsrQfJoVGYLPT41XWF8lHuE5N6WhVia2n4o5QK5M4tYr21827fNhi4byQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.28.1': + resolution: {integrity: sha512-zvb/mB2bSCoJOpoCBgYKKpX6YM6mJBlBUVUtVj41DlZJVEB6/0CKlRYxP5wWl1C1ILiCoAU5wZZ4q1P3qeS6Eg==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-x64@0.17.19': resolution: {integrity: sha512-lAhycmKnVOuRYNtRtatQR1LPQf2oYCkRGkSFnseDAKPl8lu5SOsK/e1sXe5a0Pc5kHIHe6P2I/ilntNv2xf3cA==} engines: {node: '>=12'} @@ -1078,6 +1440,18 @@ packages: cpu: [x64] os: [win32] + '@esbuild/win32-x64@0.25.12': + resolution: {integrity: sha512-alJC0uCZpTFrSL0CCDjcgleBXPnCrEAhTBILpeAp7M/OFgoqtAetfBzX0xM00MUsVVPpVjlPuMbREqnZCXaTnA==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.28.1': + resolution: {integrity: sha512-bm4Mowrv+GXMlpWX++EcXw/iLyd1o3+bJkC2DkWXYVvgZCqD/bSj9ctZeAMC3cIxgjRVR2Dufaiu4YPxr5gW1A==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@eslint-community/eslint-utils@4.4.0': resolution: {integrity: sha512-1/sA4dwrzBAyeUoQ6oxahHKmrZvsnLCg4RfxW3ZFGGmQkSNQPFNLV9CUEFQP1x9EYXHTo5p6xdhZM1Ne9p/AfA==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} @@ -1113,6 +1487,143 @@ packages: resolution: {integrity: sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==} deprecated: Use @eslint/object-schema instead + '@img/colour@1.1.0': + resolution: {integrity: sha512-Td76q7j57o/tLVdgS746cYARfSyxk8iEfRxewL9h4OMzYhbW4TAcppl0mT4eyqXddh6L/jwoM75mo7ixa/pCeQ==} + engines: {node: '>=18'} + + '@img/sharp-darwin-arm64@0.34.5': + resolution: {integrity: sha512-imtQ3WMJXbMY4fxb/Ndp6HBTNVtWCUI0WdobyheGf5+ad6xX8VIDO8u2xE4qc/fr08CKG/7dDseFtn6M6g/r3w==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [darwin] + + '@img/sharp-darwin-x64@0.34.5': + resolution: {integrity: sha512-YNEFAF/4KQ/PeW0N+r+aVVsoIY0/qxxikF2SWdp+NRkmMB7y9LBZAVqQ4yhGCm/H3H270OSykqmQMKLBhBJDEw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-darwin-arm64@1.2.4': + resolution: {integrity: sha512-zqjjo7RatFfFoP0MkQ51jfuFZBnVE2pRiaydKJ1G/rHZvnsrHAOcQALIi9sA5co5xenQdTugCvtb1cuf78Vf4g==} + cpu: [arm64] + os: [darwin] + + '@img/sharp-libvips-darwin-x64@1.2.4': + resolution: {integrity: sha512-1IOd5xfVhlGwX+zXv2N93k0yMONvUlANylbJw1eTah8K/Jtpi15KC+WSiaX/nBmbm2HxRM1gZ0nSdjSsrZbGKg==} + cpu: [x64] + os: [darwin] + + '@img/sharp-libvips-linux-arm64@1.2.4': + resolution: {integrity: sha512-excjX8DfsIcJ10x1Kzr4RcWe1edC9PquDRRPx3YVCvQv+U5p7Yin2s32ftzikXojb1PIFc/9Mt28/y+iRklkrw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linux-arm@1.2.4': + resolution: {integrity: sha512-bFI7xcKFELdiNCVov8e44Ia4u2byA+l3XtsAj+Q8tfCwO6BQ8iDojYdvoPMqsKDkuoOo+X6HZA0s0q11ANMQ8A==} + cpu: [arm] + os: [linux] + + '@img/sharp-libvips-linux-ppc64@1.2.4': + resolution: {integrity: sha512-FMuvGijLDYG6lW+b/UvyilUWu5Ayu+3r2d1S8notiGCIyYU/76eig1UfMmkZ7vwgOrzKzlQbFSuQfgm7GYUPpA==} + cpu: [ppc64] + os: [linux] + + '@img/sharp-libvips-linux-riscv64@1.2.4': + resolution: {integrity: sha512-oVDbcR4zUC0ce82teubSm+x6ETixtKZBh/qbREIOcI3cULzDyb18Sr/Wcyx7NRQeQzOiHTNbZFF1UwPS2scyGA==} + cpu: [riscv64] + os: [linux] + + '@img/sharp-libvips-linux-s390x@1.2.4': + resolution: {integrity: sha512-qmp9VrzgPgMoGZyPvrQHqk02uyjA0/QrTO26Tqk6l4ZV0MPWIW6LTkqOIov+J1yEu7MbFQaDpwdwJKhbJvuRxQ==} + cpu: [s390x] + os: [linux] + + '@img/sharp-libvips-linux-x64@1.2.4': + resolution: {integrity: sha512-tJxiiLsmHc9Ax1bz3oaOYBURTXGIRDODBqhveVHonrHJ9/+k89qbLl0bcJns+e4t4rvaNBxaEZsFtSfAdquPrw==} + cpu: [x64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + resolution: {integrity: sha512-FVQHuwx1IIuNow9QAbYUzJ+En8KcVm9Lk5+uGUQJHaZmMECZmOlix9HnH7n1TRkXMS0pGxIJokIVB9SuqZGGXw==} + cpu: [arm64] + os: [linux] + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + resolution: {integrity: sha512-+LpyBk7L44ZIXwz/VYfglaX/okxezESc6UxDSoyo2Ks6Jxc4Y7sGjpgU9s4PMgqgjj1gZCylTieNamqA1MF7Dg==} + cpu: [x64] + os: [linux] + + '@img/sharp-linux-arm64@0.34.5': + resolution: {integrity: sha512-bKQzaJRY/bkPOXyKx5EVup7qkaojECG6NLYswgktOZjaXecSAeCWiZwwiFf3/Y+O1HrauiE3FVsGxFg8c24rZg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linux-arm@0.34.5': + resolution: {integrity: sha512-9dLqsvwtg1uuXBGZKsxem9595+ujv0sJ6Vi8wcTANSFpwV/GONat5eCkzQo/1O6zRIkh0m/8+5BjrRr7jDUSZw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm] + os: [linux] + + '@img/sharp-linux-ppc64@0.34.5': + resolution: {integrity: sha512-7zznwNaqW6YtsfrGGDA6BRkISKAAE1Jo0QdpNYXNMHu2+0dTrPflTLNkpc8l7MUP5M16ZJcUvysVWWrMefZquA==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ppc64] + os: [linux] + + '@img/sharp-linux-riscv64@0.34.5': + resolution: {integrity: sha512-51gJuLPTKa7piYPaVs8GmByo7/U7/7TZOq+cnXJIHZKavIRHAP77e3N2HEl3dgiqdD/w0yUfiJnII77PuDDFdw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [riscv64] + os: [linux] + + '@img/sharp-linux-s390x@0.34.5': + resolution: {integrity: sha512-nQtCk0PdKfho3eC5MrbQoigJ2gd1CgddUMkabUj+rBevs8tZ2cULOx46E7oyX+04WGfABgIwmMC0VqieTiR4jg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [s390x] + os: [linux] + + '@img/sharp-linux-x64@0.34.5': + resolution: {integrity: sha512-MEzd8HPKxVxVenwAa+JRPwEC7QFjoPWuS5NZnBt6B3pu7EG2Ge0id1oLHZpPJdn3OQK+BQDiw9zStiHBTJQQQQ==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-linuxmusl-arm64@0.34.5': + resolution: {integrity: sha512-fprJR6GtRsMt6Kyfq44IsChVZeGN97gTD331weR1ex1c1rypDEABN6Tm2xa1wE6lYb5DdEnk03NZPqA7Id21yg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [linux] + + '@img/sharp-linuxmusl-x64@0.34.5': + resolution: {integrity: sha512-Jg8wNT1MUzIvhBFxViqrEhWDGzqymo3sV7z7ZsaWbZNDLXRJZoRGrjulp60YYtV4wfY8VIKcWidjojlLcWrd8Q==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [linux] + + '@img/sharp-wasm32@0.34.5': + resolution: {integrity: sha512-OdWTEiVkY2PHwqkbBI8frFxQQFekHaSSkUIJkwzclWZe64O1X4UlUjqqqLaPbUpMOQk6FBu/HtlGXNblIs0huw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [wasm32] + + '@img/sharp-win32-arm64@0.34.5': + resolution: {integrity: sha512-WQ3AgWCWYSb2yt+IG8mnC6Jdk9Whs7O0gxphblsLvdhSpSTtmu69ZG1Gkb6NuvxsNACwiPV6cNSZNzt0KPsw7g==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [arm64] + os: [win32] + + '@img/sharp-win32-ia32@0.34.5': + resolution: {integrity: sha512-FV9m/7NmeCmSHDD5j4+4pNI8Cp3aW+JvLoXcTUo0IqyjSfAZJ8dIUmijx1qaJsIiU+Hosw6xM5KijAWRJCSgNg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [ia32] + os: [win32] + + '@img/sharp-win32-x64@0.34.5': + resolution: {integrity: sha512-+29YMsqY2/9eFEiW93eqWnuLcWcufowXewwSNIT6UwZdUUCrM3oFjMWH/Z6/TMmb4hlFenmfAVbpWeup2jryCw==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + cpu: [x64] + os: [win32] + '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -1136,6 +1647,9 @@ packages: '@jridgewell/sourcemap-codec@1.5.0': resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==} + '@jridgewell/sourcemap-codec@1.5.5': + resolution: {integrity: sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==} + '@jridgewell/trace-mapping@0.3.25': resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==} @@ -1165,6 +1679,15 @@ packages: '@popperjs/core@2.11.8': resolution: {integrity: sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==} + '@poppinss/colors@4.1.6': + resolution: {integrity: sha512-H9xkIdFswbS8n1d6vmRd8+c10t2Qe+rZITbbDHHkQixH5+2x1FDGmi/0K+WgWiqQFKPSlIYB7jlH6Kpfn6Fleg==} + + '@poppinss/dumper@0.6.5': + resolution: {integrity: sha512-NBdYIb90J7LfOI32dOewKI1r7wnkiH6m920puQ3qHUeZkxNkQiFnXVWoE6YtFSv6QOiPPf7ys6i+HWWecDz7sw==} + + '@poppinss/exception@1.2.3': + resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + '@preact/preset-vite@2.9.1': resolution: {integrity: sha512-JecWzrOx7ogFhklSMhY+aH/24pajL0Vx+beEgau3WDMUUAo32cpUo/UqerPhLOyhCKXlxK9a3cRoa8g68ZAp5g==} peerDependencies: @@ -1197,90 +1720,228 @@ packages: cpu: [arm] os: [android] + '@rollup/rollup-android-arm-eabi@4.62.2': + resolution: {integrity: sha512-6o7ZLZK+BeenkZCFNDXqpbjw9bD6nuWonvS/lwQJp7NoVVxm6p3qE7qQ5jGuBjiFsgvqjD8mZAU5oWxTmbOeOg==} + cpu: [arm] + os: [android] + '@rollup/rollup-android-arm64@4.24.0': resolution: {integrity: sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA==} cpu: [arm64] os: [android] + '@rollup/rollup-android-arm64@4.62.2': + resolution: {integrity: sha512-BaH7BllCACHoH1LguOU56UItGfUWjujlO65kS9LAodViaN4bwIKd7oeW/ZHJ/4ljr/7MIiENnNy3HJ0zXv8Zkw==} + cpu: [arm64] + os: [android] + '@rollup/rollup-darwin-arm64@4.24.0': resolution: {integrity: sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA==} cpu: [arm64] os: [darwin] + '@rollup/rollup-darwin-arm64@4.62.2': + resolution: {integrity: sha512-v39RCCvj4He82I9sFmk+M1VZ0PLM9sfsLVikjfx2hYBNALhrrOR2D3JjQA6AhlaSOgcR+RzrKY7e1+bT6SUO/A==} + cpu: [arm64] + os: [darwin] + '@rollup/rollup-darwin-x64@4.24.0': resolution: {integrity: sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ==} cpu: [x64] os: [darwin] + '@rollup/rollup-darwin-x64@4.62.2': + resolution: {integrity: sha512-yl0y2vq3S3lHeuXhEdss6TWfKW8vkujImO12tn4ZkG/4oghr09LvdYm2RElVjokTQiUvDUGXLGsYeLqUMCKpGA==} + cpu: [x64] + os: [darwin] + + '@rollup/rollup-freebsd-arm64@4.62.2': + resolution: {integrity: sha512-tT4pvt4qXD+vEoezupCWi+a1F0vvDiksiHc+PxRlYTOH1I6/X4id9jPxTP+Fg+545euaFT1jJVs4CEdHZAU1vw==} + cpu: [arm64] + os: [freebsd] + + '@rollup/rollup-freebsd-x64@4.62.2': + resolution: {integrity: sha512-6nU5F2wCW+qvCBhTn1pdIU3bzsIoF7EUwsCDRxilWGprQR6yd508YnH9+OKFCwpfS8pjZqDUmnCAr7exax0XCg==} + cpu: [x64] + os: [freebsd] + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': resolution: {integrity: sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + resolution: {integrity: sha512-n1GJHPOvpIfhi3TmrCeh6S6URt9BFCt0KQE3qvexyGCTAKpR4Lg+eWvNZEqu7epxwus/8ElT3hacYEucm49SZg==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.24.0': resolution: {integrity: sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw==} cpu: [arm] os: [linux] + '@rollup/rollup-linux-arm-musleabihf@4.62.2': + resolution: {integrity: sha512-JqgflS8wEB+UXV/vS1RpRbifGBeN4D5lz8D8oOFbFZw4vedvdOgCFAjfBmIMdW3yL10XpQQ0Ambepw6MXrhOnA==} + cpu: [arm] + os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.24.0': resolution: {integrity: sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-gnu@4.62.2': + resolution: {integrity: sha512-wnFJkogWvN4jm/hQRF2UBaeUmk20j5+DmHvoyWii2b8HJDyvz1MF2OU/6ynXt2KR63rbZLWkFpoytpdc/yBuSA==} + cpu: [arm64] + os: [linux] + '@rollup/rollup-linux-arm64-musl@4.24.0': resolution: {integrity: sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw==} cpu: [arm64] os: [linux] + '@rollup/rollup-linux-arm64-musl@4.62.2': + resolution: {integrity: sha512-HVu2bp0zhvJ8xHEV9+UUs7S90VadmBSY3LcIMvozbPo4AuMGDWlz3ymHLHZPX4hR67TKTt8Qp5PJ5RBg/i+RMQ==} + cpu: [arm64] + os: [linux] + + '@rollup/rollup-linux-loong64-gnu@4.62.2': + resolution: {integrity: sha512-mQqqAV8QaoSgr9I2fKDLY2BAVvmKjWoGiu/cSYQonsLvtqwEn1E4QYfnCOcp5zoEqNhsDYin1s6jx/VJmrxlZg==} + cpu: [loong64] + os: [linux] + + '@rollup/rollup-linux-loong64-musl@4.62.2': + resolution: {integrity: sha512-IxKLoxCQ2IWi6bT2akyDUBGsOImDKB+sPp4EsTmwFQ/fMwpCKm8uLSSgP/Kx/QYUgKis6SEZ5/Nlhup0DIA0PQ==} + cpu: [loong64] + os: [linux] + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': resolution: {integrity: sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw==} cpu: [ppc64] os: [linux] + '@rollup/rollup-linux-ppc64-gnu@4.62.2': + resolution: {integrity: sha512-Mk5ha2RQSgyFfmYYLkBpPnUk8D8FriBxesO1u9O75X0mHgXL1UQcH5Itl2lurWL2tj0RxV9b9tJgipac0hRY9A==} + cpu: [ppc64] + os: [linux] + + '@rollup/rollup-linux-ppc64-musl@4.62.2': + resolution: {integrity: sha512-CjvEnqJL/0/TQ3TXX3OPIJ/kmBellrWd4heXUmHeJlTnmwjKpSJzoehLaL6Xk0ZnMHBu9dZuFADNOrtjF4v+2w==} + cpu: [ppc64] + os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.24.0': resolution: {integrity: sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg==} cpu: [riscv64] os: [linux] + '@rollup/rollup-linux-riscv64-gnu@4.62.2': + resolution: {integrity: sha512-1SiZbzwdkaDURsew/tSOrooKiYy7EQGT6m8ufavAi9NEyQb/6VuIxFXAL1fqa4iZe3g4NbNk4P7J32z2tw5Mgg==} + cpu: [riscv64] + os: [linux] + + '@rollup/rollup-linux-riscv64-musl@4.62.2': + resolution: {integrity: sha512-nQts12zJ3NQRoE6uYljOH89v7szzLDvG2JD/vsX+vGXU8w/At1GowTZ5/7qeFQ8m7L55rpR8Okugnuo5bgjy2Q==} + cpu: [riscv64] + os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.24.0': resolution: {integrity: sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g==} cpu: [s390x] os: [linux] + '@rollup/rollup-linux-s390x-gnu@4.62.2': + resolution: {integrity: sha512-E9/ll019jhPIJgpzfZoIkBGhcz+kKNgVWYRY0zr9srBdPPFVpvOKW8VaJKUbeK+eZXyQF9ltME+Kk6affeaPgg==} + cpu: [s390x] + os: [linux] + '@rollup/rollup-linux-x64-gnu@4.24.0': resolution: {integrity: sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-gnu@4.62.2': + resolution: {integrity: sha512-5BqxR/pshjey51iliyzTD5Xi3EN0aLmQ2lZ3lvefVV9c82BvrLo2/6OT55iifpWBufs6kdwWbuOKS841DrmK9A==} + cpu: [x64] + os: [linux] + '@rollup/rollup-linux-x64-musl@4.24.0': resolution: {integrity: sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ==} cpu: [x64] os: [linux] + '@rollup/rollup-linux-x64-musl@4.62.2': + resolution: {integrity: sha512-uNN83XxQrRAh/w0/pmAfibcwyb6YWt4gP+dpnQKPVJshAloQ785ii8CT8ZCIxkGg9opVsvAlGhFitSm6D1Jjpg==} + cpu: [x64] + os: [linux] + + '@rollup/rollup-openbsd-x64@4.62.2': + resolution: {integrity: sha512-srjEIxSH3LRnJN6THczDHWQplqEMFiAJrTab0msUryh9kwNpkICf3Ea6q6MN/2cZwRFUNx5w+h6Hpi4QuHS6Zg==} + cpu: [x64] + os: [openbsd] + + '@rollup/rollup-openharmony-arm64@4.62.2': + resolution: {integrity: sha512-8hOJnxgbyObnCm5AlRA3A931xX19xq80RjVTKgJOvEKWqJruP/Uf12IbAOaDjjEXYRewwHLfmF0YRIdK3OwKWA==} + cpu: [arm64] + os: [openharmony] + '@rollup/rollup-win32-arm64-msvc@4.24.0': resolution: {integrity: sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ==} cpu: [arm64] os: [win32] + '@rollup/rollup-win32-arm64-msvc@4.62.2': + resolution: {integrity: sha512-mmF4AY1i0hG/bLWUctUq59gtmgaSIRa3cu/A3JFRp/sCNEme2bgDEiDS22P9FbnJB8NJNF4jPJiSP5RHQpUTDg==} + cpu: [arm64] + os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.24.0': resolution: {integrity: sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ==} cpu: [ia32] os: [win32] + '@rollup/rollup-win32-ia32-msvc@4.62.2': + resolution: {integrity: sha512-DZgkknc6jhHrk46V25vbAM0zZkyP0nSDkJB8/dRkLTxv470dOmWDqGoEJl/9A0dFfS7yE3REOwNDxpHwSLSt0Q==} + cpu: [ia32] + os: [win32] + + '@rollup/rollup-win32-x64-gnu@4.62.2': + resolution: {integrity: sha512-T6xr6ucWSFto+VGajA8YH26LdpHRuP4YLHEKAtCWvJDOlnmWcDZVCI2Jmjr+IFHDlt2zRaTAKE4tfjTaWLgJBg==} + cpu: [x64] + os: [win32] + '@rollup/rollup-win32-x64-msvc@4.24.0': resolution: {integrity: sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw==} cpu: [x64] os: [win32] + '@rollup/rollup-win32-x64-msvc@4.62.2': + resolution: {integrity: sha512-BfzEnDJOt9T8M989/lA37EcJgat01wLRnoi5dQf3QzOH7jzpqTAzdDbVfRljVr5r+jzKqpbHeyOfAaXxAd0PAA==} + cpu: [x64] + os: [win32] + + '@sindresorhus/is@7.2.0': + resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} + engines: {node: '>=18'} + '@socket.io/component-emitter@3.1.2': resolution: {integrity: sha512-9BCxFwvbGg/RsZK9tjXd8s4UcwR0MWeFQ1XEKIQVVvAGJyINdrqKMcTRyLoK8Rse1GjzLV9cwjWV1olXRWEXVA==} + '@speed-highlight/core@1.2.17': + resolution: {integrity: sha512-Z92FwKpCtfaW1V0jTU/fh3QzYEZN8wDwrzRIBoADCJfn4mJCNcJN/XegifX7BDrQ8/h9Xh/JnbyMchL0FqXrkg==} + + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + '@tsconfig/strictest@2.0.5': resolution: {integrity: sha512-ec4tjL2Rr0pkZ5hww65c+EEPYwxOi4Ryv+0MtjeaSQRJyq322Q27eOQiFbuNgw2hpL4hB1/W/HBGk3VKS43osg==} '@types/base64id@2.0.2': resolution: {integrity: sha512-L/KwKcOKG3PPFXBsXJnBsvPKn5LxOpL7eO1Fwq4il1iGiMNYbEapPVqOONPMzxB08WUJOLWcLHL7y8kLUgDp2Q==} + '@types/chai@5.2.3': + resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/cookie@0.4.1': resolution: {integrity: sha512-XW/Aa8APYr6jSVVA1y/DEIZX0/GMKLEVekNG727R8cs56ahETkRAy/3DR7+fJyh7oUgGwNQaRfXCun0+KbWY7Q==} @@ -1290,9 +1951,15 @@ packages: '@types/debug@4.1.12': resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==} + '@types/deep-eql@4.0.2': + resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree@1.0.6': resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} + '@types/estree@1.0.9': + resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/hammerjs@2.0.45': resolution: {integrity: sha512-qkcUlZmX6c4J8q45taBKTL3p+LbITgyx7qhlPYOdOHZB7B31K0mXbP5YA7i7SgDeEGuI9MnumiKPEMrxg8j3KQ==} @@ -1392,6 +2059,36 @@ packages: '@ungap/structured-clone@1.2.0': resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==} + deprecated: Potential CWE-502 - Update to 1.3.1 or higher + + '@vitest/expect@4.1.10': + resolution: {integrity: sha512-YsCn+qAk1GWjQOWFEsEcL2gNQ0zmVmQu3T03qP6UyjhtmdtwtbuI+DASn/7iQB3HGTXkdBwGddzxPlmiql5vlA==} + + '@vitest/mocker@4.1.10': + resolution: {integrity: sha512-v0xaezt+DKEmKfaxg133ldzADrwLGd7Ze1MfQQTYfvs8OqZIwbxyxaYURivwV7sWy5fqn3rH5uOrSp07bp44Ow==} + peerDependencies: + msw: ^2.4.9 + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + msw: + optional: true + vite: + optional: true + + '@vitest/pretty-format@4.1.10': + resolution: {integrity: sha512-W1HsjSH4MXQ9YfmmhLAoIYf1HRfekQCGngeIgcei6MP5QQGWUe0gkopdZQaVCFO+JDJMrAJGwa5pRpNpvy4P8Q==} + + '@vitest/runner@4.1.10': + resolution: {integrity: sha512-IKI6kpIH+LmpROplyLwBBaCfMgOZOMsygVa6BARD6ahA04VRuJSa6OaVG7kRvSEMD870Vd91rSSw0eegtWyLGg==} + + '@vitest/snapshot@4.1.10': + resolution: {integrity: sha512-xRkfOT1qpTAi/Ti4Y1LtfRc3kEuqxGw59eN2jN9pRWMtS/XDevekhcFSqvQqjUNGksfjMJu3Y+oJ+4Ypn2OaJw==} + + '@vitest/spy@4.1.10': + resolution: {integrity: sha512-PLf/Ugvoq5wO/b4rwYCR1h2PSIdXz7wnkQFMiUpLdtM7l6pqVFcQIBEHyT1+l+cj7mNwAfZHzqXqDyjvOuwbDw==} + + '@vitest/utils@4.1.10': + resolution: {integrity: sha512-fy9am/HWxbaGt/Sawrp90vt6Y6jQwf1RX77cz3uwoJwJVMli/e1IEwRPnMNJ7vKfPTwo0diXifkpPvwH9v7nGA==} accepts@1.3.8: resolution: {integrity: sha512-PYAthTa2m2VKxuvSD3DPC/Gy+U+sOA1LAuT8mkmRuvw+NACSaeXEQ+NHcVF7rONl6qcaxV3Uuemwawk+7+SJLw==} @@ -1462,6 +2159,10 @@ packages: as-table@1.0.55: resolution: {integrity: sha512-xvsWESUJn0JN421Xb9MQw6AsMHRCUknCe0Wjlxvjud80mU4E6hQf1A6NzQKcYNmYw62MfzEtXc+badstZP3JpQ==} + assertion-error@2.0.1: + resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} + engines: {node: '>=12'} + autoprefixer@10.4.20: resolution: {integrity: sha512-XY25y5xSv/wEoqzDyXXME4AFfkZI0P23z6Fs3YgymDnKJkCGOnkL0iTxCa85UTqaSgfcqyf3UA6+c7wUvx/16g==} engines: {node: ^10 || ^12 || >=14} @@ -1537,6 +2238,10 @@ packages: capnp-ts@0.7.0: resolution: {integrity: sha512-XKxXAC3HVPv7r674zP0VC3RTXz+/JKhfyw94ljvF80yynK6VkTnqE3jMuN8b3dUVmmc43TjyxjW4KTsmB3c86g==} + chai@6.2.2: + resolution: {integrity: sha512-NUPRluOfOiTKBKvWPtSD4PhFvWCqOi0BGStNWs57X9js7XGTprSmFoz5F0tWhR4WPjNeR9jXqdC7/UpSJTnlRg==} + engines: {node: '>=18'} + chalk@2.4.2: resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} engines: {node: '>=4'} @@ -1559,6 +2264,9 @@ packages: resolution: {integrity: sha512-n8enUVCED/KVRQlab1hr3MVpcVMvxtZjmEa956u+4YijlmQED223XMSYj2tLuKvr4jcCTzNNMpQDUer72MMmzA==} engines: {node: '>= 14.16.0'} + cjs-module-lexer@1.2.3: + resolution: {integrity: sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==} + classnames@2.5.1: resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==} @@ -1618,6 +2326,10 @@ packages: resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} engines: {node: '>= 0.6'} + cookie@1.1.1: + resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} + engines: {node: '>=18'} + cors@2.8.5: resolution: {integrity: sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==} engines: {node: '>= 0.10'} @@ -1667,6 +2379,10 @@ packages: defu@6.1.4: resolution: {integrity: sha512-mEQCMmwJu317oSz8CwdIOdwf3xMif1ttiM8LTufzc3g6kR+9Pe236twL8j3IYT1F7GfRgGcW6MWxzZjLIkuHIg==} + detect-libc@2.1.2: + resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} + engines: {node: '>=8'} + didyoumean@1.2.2: resolution: {integrity: sha512-gxtyfqMg7GKyhQmb056K7M3xszy/myH8w+B4RT+QXBQsvAOdc3XymqDDPHx1BgPgsdAA5SIifona89YtRATDzw==} @@ -1737,6 +2453,12 @@ packages: error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} + error-stack-parser-es@1.0.5: + resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + + es-module-lexer@2.3.1: + resolution: {integrity: sha512-shc1dbU90Yl/xq1QrC7QRtfcwURZuVRfPhZbDoldJ1cn1gzDvBaBWlv0eFolj5+0znnPJz5TXLxsN77X/12KTA==} + esbuild@0.17.19: resolution: {integrity: sha512-XQ0jAPFkK/u3LcVRcvVHQcTIqD6E2H1fvZMA5dQPSOWb3suUbWbfbRf94pjc0bNzRYLfIrDRQXr7X+LHIm5oHw==} engines: {node: '>=12'} @@ -1757,6 +2479,16 @@ packages: engines: {node: '>=18'} hasBin: true + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.28.1: + resolution: {integrity: sha512-HrJrvZv5ayxBzPfwphOoNzkzOIIlifzk0KJrGK2c8R4+LKpMtpYLQeUdjnwjWv/LZlkH2laZk+4w78pi99D4Vw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} @@ -1834,6 +2566,7 @@ packages: eslint@8.57.0: resolution: {integrity: sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + deprecated: This version is no longer supported. Please see https://eslint.org/version-support for other options. hasBin: true espree@9.6.1: @@ -1862,6 +2595,9 @@ packages: estree-walker@2.0.2: resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} + estree-walker@3.0.3: + resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + esutils@2.0.3: resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} engines: {node: '>=0.10.0'} @@ -1874,6 +2610,10 @@ packages: resolution: {integrity: sha512-eNTPlAD67BmP31LDINZ3U7HSF8l57TxOY2PmBJ1shpCvpnxBF93mWCE8YHBnXs8qiUZJc9WDcWIeC3a2HIAMfw==} engines: {node: '>=6'} + expect-type@1.4.0: + resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} + engines: {node: '>=12.0.0'} + external-editor@3.1.0: resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} engines: {node: '>=4'} @@ -1897,6 +2637,15 @@ packages: fastq@1.17.1: resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==} + fdir@6.5.0: + resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} + engines: {node: '>=12.0.0'} + peerDependencies: + picomatch: ^3 || ^4 + peerDependenciesMeta: + picomatch: + optional: true + figures@3.2.0: resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} engines: {node: '>=8'} @@ -1998,11 +2747,12 @@ packages: glob@10.4.5: resolution: {integrity: sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==} + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me hasBin: true glob@7.2.3: resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - deprecated: Glob versions prior to v9 are no longer supported + deprecated: Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me globals@11.12.0: resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} @@ -2183,6 +2933,10 @@ packages: resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} engines: {node: '>=0.10.0'} + kleur@4.1.5: + resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} + engines: {node: '>=6'} + kolorist@1.8.0: resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} @@ -2235,6 +2989,9 @@ packages: magic-string@0.25.9: resolution: {integrity: sha512-RmF0AsMzgt25qzqqLc1+MbHmhdx0ojF2Fvs4XnOqz2ZOBXzzkEwc/dJQZCYHAn7v1jbVOjAZfK8msRn4BxO4VQ==} + magic-string@0.30.21: + resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@0.30.5: resolution: {integrity: sha512-7xlpfBaQaP/T6Vh8MO/EqXSW5En6INHEvEXQiuff7Gku0PWjU3uf6w/j9o7O+SpB5fOAkrI5HeoNgwjEO0pFsA==} engines: {node: '>=12'} @@ -2288,6 +3045,11 @@ packages: engines: {node: '>=16.13'} hasBin: true + miniflare@4.20260708.1: + resolution: {integrity: sha512-c94O9zRDISdqO18EHt6l0iF/fWgWt8p18PJvRsA/L/NJZ9Cfke3s/F5Blg1XXF7WDutVRzWVWy8Vy4LaT5ifsA==} + engines: {node: '>=22.0.0'} + hasBin: true + minimatch@3.1.2: resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} @@ -2316,6 +3078,11 @@ packages: mz@2.7.0: resolution: {integrity: sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==} + nanoid@3.3.16: + resolution: {integrity: sha512-bzlKTyNJ7+LdGIIwy8ijFpIqEQIvafahV7eYykJ8Cvh42EdJeODoJ6gUJXpQJvej1BddH8OqTXZNE/KfbWAu8Q==} + engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} + hasBin: true + nanoid@3.3.7: resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==} engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} @@ -2381,6 +3148,10 @@ packages: resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} + obug@2.1.3: + resolution: {integrity: sha512-9miFgM2OFba7hB+pRgvtV84pYTBaoTHohvmIgiRt6dRIzbwEOIaNaP+dIlGs2fNFoB0SeISs0Jz5WFVRid6Xyg==} + engines: {node: '>=12.20.0'} + ohash@1.1.4: resolution: {integrity: sha512-FlDryZAahJmEF3VR3w1KogSEdWX3WhA5GPakFx4J81kEAiHyLMpdLLElS8n8dfNadMgAne/MywcvmogzscVt4g==} @@ -2468,13 +3239,23 @@ packages: pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} + pathe@2.0.3: + resolution: {integrity: sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==} + picocolors@1.1.0: resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==} + picocolors@1.1.1: + resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} + picomatch@4.0.5: + resolution: {integrity: sha512-RvwwcruNjI1ncT5xRakeyS9Lf8lcItv34KD+aif+VH9kduAyfYBipGh12274xtenIPZ119/R9BdTBa8gAwSh0A==} + engines: {node: '>=12'} + pify@2.3.0: resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} engines: {node: '>=0.10.0'} @@ -2528,6 +3309,10 @@ packages: resolution: {integrity: sha512-56rxCq7G/XfB4EkXq9Egn5GCqugWvDFjafDOThIdMBsI15iqPqR5r15TfSr1YPYeEI19YeaXMCbY6u88Y76GLQ==} engines: {node: ^10 || ^12 || >=14} + postcss@8.5.19: + resolution: {integrity: sha512-Mz8SaolMd8nB+G13WkORcxQKHZ/NE4xXevtkJHVuG+guo9/wYKlIMTKAqGdEmYOXR2ijPjTYNHssizdaVSUNdQ==} + engines: {node: ^10 || ^12 || >=14} + preact-router@4.1.2: resolution: {integrity: sha512-uICUaUFYh+XQ+6vZtQn1q+X6rSqwq+zorWOCLWPF5FAsQh3EJ+RsDQ9Ee+fjk545YWQHfUxhrBAaemfxEnMOUg==} peerDependencies: @@ -2689,6 +3474,11 @@ packages: engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + rollup@4.62.2: + resolution: {integrity: sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==} + engines: {node: '>=18.0.0', npm: '>=8.0.0'} + hasBin: true + run-async@2.4.1: resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} engines: {node: '>=0.12.0'} @@ -2731,6 +3521,11 @@ packages: engines: {node: '>=10'} hasBin: true + semver@7.8.5: + resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} + engines: {node: '>=10'} + hasBin: true + sentence-case@3.0.4: resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==} @@ -2740,6 +3535,10 @@ packages: set-blocking@2.0.0: resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} + sharp@0.34.5: + resolution: {integrity: sha512-Ou9I5Ft9WNcCbXrU9cMgPBcCK8LiwLqcbywW3t4oDV37n1pzpuNLsYiAV8eODnjbtQlSDwZ2cUEeQz4E54Hltg==} + engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -2748,6 +3547,9 @@ packages: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} + siginfo@2.0.0: + resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -2805,9 +3607,15 @@ packages: resolution: {integrity: sha512-2ztBJRek8IVofG9DBJqdy2N5kulaacX30Nz7xmkYF6ale9WBVmIy6mFBchvGX7Vx/MyjBhx+Rcxqrj+dbOnQ6A==} engines: {node: '>=16'} + stackback@0.0.2: + resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + stacktracey@2.1.8: resolution: {integrity: sha512-Kpij9riA+UNg7TnphqjH7/CzctQ/owJGNbFkfEeve4Z4uxT5+JapVLFXcsurIfN34gnTWZNJ/f7NMG0E8JDzTw==} + std-env@4.2.0: + resolution: {integrity: sha512-oCUKSupKTHX53EyjDtuZQ64pjLJ6yYCtpmEw0goYxtjG9KpbRe8KAsl2tBUGU9DyMcJ0RwJ8GqJAFzMXcXW1Rw==} + stoppable@1.1.0: resolution: {integrity: sha512-KXDYZ9dszj6bzvnEMRYvxgeTHU74QBFL54XKtP3nyMuJ81CFYtABZ3bAzL2EdFUaEwJOBOgENyFj3R7oTzDyyw==} engines: {node: '>=4', npm: '>=6'} @@ -2845,6 +3653,10 @@ 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@5.5.0: resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} engines: {node: '>=4'} @@ -2879,6 +3691,21 @@ packages: through@2.3.8: resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + tinybench@2.9.0: + resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + + tinyexec@1.2.4: + resolution: {integrity: sha512-SHf/r48b7vOrjve9PxJo3MN5v5yuyjHvdUcrQffT3WXMUfnGmHDVbC4k3sHJaJTgZCwpUplIaAo5ANtMyp3YHg==} + engines: {node: '>=18'} + + tinyglobby@0.2.17: + resolution: {integrity: sha512-wXR/dYpcqKmfWpEdZjiKJOwCNFndD0DMnrW/cYjVGttEkBfVgcLFHoNrlj47mjOVic9yyNu65alsgF4NQyTa2g==} + engines: {node: '>=12.0.0'} + + tinyrainbow@3.1.0: + resolution: {integrity: sha512-Bf+ILmBgretUrdJxzXM0SgXLZ3XfiaUuOj/IKQHuTXip+05Xn+uyEYdVg0kYDipTBcLrCVyUzAPz7QmArb0mmw==} + engines: {node: '>=14.0.0'} + tmp@0.0.33: resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} engines: {node: '>=0.6.0'} @@ -2957,9 +3784,16 @@ packages: resolution: {integrity: sha512-72RFADWFqKmUb2hmmvNODKL3p9hcB6Gt2DOQMis1SEBaV6a4MH8soBvzg+95CYhCKPFedut2JY9bMfrDl9D23g==} engines: {node: '>=14.0'} + undici@7.28.0: + resolution: {integrity: sha512-cRZYrTDwWznlnRiPjggAGxZXanty6M8RV1ff8Wm4LWXBp7/IG8v5DnOm74DtUBp9OONpK75YlPnIjQqX0dBDtA==} + engines: {node: '>=20.18.1'} + unenv-nightly@2.0.0-20240919-125358-9a64854: resolution: {integrity: sha512-XjsgUTrTHR7iw+k/SRTNjh6EQgwpC9voygnoCJo5kh4hKqsSDHUW84MhL9EsHTNfLctvVBHaSw8e2k3R2fKXsQ==} + unenv@2.0.0-rc.24: + resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + update-browserslist-db@1.1.1: resolution: {integrity: sha512-R8UzCaa9Az+38REPiJ1tXlImTJXlVfgHZsglwBD/k6nj76ctsH1E3q4doGrukiLQd3sGQYu56r5+lo5r94l29A==} hasBin: true @@ -3021,6 +3855,87 @@ packages: terser: optional: true + vite@6.4.3: + resolution: {integrity: sha512-NTKlcQjlAK7MlQoyb6LgaqHc8sso/pVyUJYWMws3jg21uTJw/LddqIFPcPqP6PzpgbIcZyKI85sFE4HBrQDA8A==} + engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + hasBin: true + peerDependencies: + '@types/node': ^20 + jiti: '>=1.21.0' + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + jiti: + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitest@4.1.10: + resolution: {integrity: sha512-R9jUTe5S4Qb0HCd4TNqpC7oGcrMssMRGXLW80ubjWsW9VH5GF8y1Y0SFLY9AbqSk6nt0PnOx4H4WNJYZ13GUPw==} + engines: {node: ^20.0.0 || ^22.0.0 || >=24.0.0} + hasBin: true + peerDependencies: + '@edge-runtime/vm': '*' + '@opentelemetry/api': ^1.9.0 + '@types/node': ^20 + '@vitest/browser-playwright': 4.1.10 + '@vitest/browser-preview': 4.1.10 + '@vitest/browser-webdriverio': 4.1.10 + '@vitest/coverage-istanbul': 4.1.10 + '@vitest/coverage-v8': 4.1.10 + '@vitest/ui': 4.1.10 + happy-dom: '*' + jsdom: '*' + vite: ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + '@edge-runtime/vm': + optional: true + '@opentelemetry/api': + optional: true + '@types/node': + optional: true + '@vitest/browser-playwright': + optional: true + '@vitest/browser-preview': + optional: true + '@vitest/browser-webdriverio': + optional: true + '@vitest/coverage-istanbul': + optional: true + '@vitest/coverage-v8': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + warning@4.0.3: resolution: {integrity: sha512-rpJyN222KWIvHJ/F53XSZv0Zl/accqHR8et1kpaMTD/fLCRxtV8iX8czMzY7sVZupTI3zcUTg8eycS2kNF9l6w==} @@ -3032,6 +3947,11 @@ packages: engines: {node: '>= 8'} hasBin: true + why-is-node-running@2.3.0: + resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} + engines: {node: '>=8'} + hasBin: true + word-wrap@1.2.5: resolution: {integrity: sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==} engines: {node: '>=0.10.0'} @@ -3041,6 +3961,11 @@ packages: engines: {node: '>=16'} hasBin: true + workerd@1.20260708.1: + resolution: {integrity: sha512-WAK+Kt/VVCSldH2qSr8lx46XCJ4Q+bdlHNaFqUtOHthBEIB8C1N8HVW+VOLrxDoTCk0NGNv0zajnBeQK4JOB9w==} + engines: {node: '>=16'} + hasBin: true + wrangler@3.80.0: resolution: {integrity: sha512-c9aN7Buf7XgTPpQkw1d0VjNRI4qg3m35PTg70Tg4mOeHwHGjsd74PAsP1G8BjpdqDjfWtsua7tj1g4M3/5dYNQ==} engines: {node: '>=16.17.0'} @@ -3051,6 +3976,16 @@ packages: '@cloudflare/workers-types': optional: true + wrangler@4.110.0: + resolution: {integrity: sha512-xZeXKYi7hxQRF5anL+v77RkufJNpF9f3Eqeyqq2QBsETpLZgh0Agj0jJ6JPtkbgn6ukZdh8OK5egsGPWIditgg==} + engines: {node: '>=22.0.0'} + hasBin: true + peerDependencies: + '@cloudflare/workers-types': ^5.20260708.1 + peerDependenciesMeta: + '@cloudflare/workers-types': + optional: true + wrap-ansi@6.2.0: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} @@ -3082,6 +4017,18 @@ packages: utf-8-validate: optional: true + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} + 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 + xmlhttprequest-ssl@2.1.1: resolution: {integrity: sha512-ptjR8YSJIXoA3Mbv5po7RtSYHO6mZr8s7i5VGmEk7QY2pQWyT1o0N+W1gKbOyJPUCGXGnuw0wqe8f0L6Y0ny7g==} engines: {node: '>=0.4.0'} @@ -3119,12 +4066,21 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + youch-core@0.3.3: + resolution: {integrity: sha512-ho7XuGjLaJ2hWHoK8yFnsUGy2Y5uDpqSTq1FkHLK4/oqKtyUU1AFbOOxY4IpC9f0fTLjwYbslUz0Po5BpD1wrA==} + youch@3.3.3: resolution: {integrity: sha512-qSFXUk3UZBLfggAW3dJKg0BMblG5biqSF8M34E06o5CSsZtH92u9Hqmj2RzGiHDi64fhe83+4tENFP2DB6t6ZA==} + youch@4.1.0-beta.10: + resolution: {integrity: sha512-rLfVLB4FgQneDr0dv1oddCVZmKjcJ6yX6mS4pU82Mq/Dt9a3cLZQ62pDBL4AUO+uVrCvtWz3ZFUL2HFAFJ/BXQ==} + zod@3.23.8: resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==} + zod@3.25.76: + resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + snapshots: '@alloc/quick-lru@5.2.0': {} @@ -3314,21 +4270,59 @@ snapshots: dependencies: mime: 3.0.0 + '@cloudflare/kv-asset-handler@0.5.0': {} + + '@cloudflare/unenv-preset@2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260708.1)': + dependencies: + unenv: 2.0.0-rc.24 + optionalDependencies: + workerd: 1.20260708.1 + + '@cloudflare/vitest-pool-workers@0.18.4(@cloudflare/workers-types@4.20241004.0)(@vitest/runner@4.1.10)(@vitest/snapshot@4.1.10)(vitest@4.1.10(@types/node@20.16.10)(vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1)))': + dependencies: + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + cjs-module-lexer: 1.2.3 + esbuild: 0.28.1 + miniflare: 4.20260708.1 + vitest: 4.1.10(@types/node@20.16.10)(vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1)) + wrangler: 4.110.0(@cloudflare/workers-types@4.20241004.0) + zod: 3.25.76 + transitivePeerDependencies: + - '@cloudflare/workers-types' + - bufferutil + - utf-8-validate + '@cloudflare/workerd-darwin-64@1.20240925.0': optional: true + '@cloudflare/workerd-darwin-64@1.20260708.1': + optional: true + '@cloudflare/workerd-darwin-arm64@1.20240925.0': optional: true + '@cloudflare/workerd-darwin-arm64@1.20260708.1': + optional: true + '@cloudflare/workerd-linux-64@1.20240925.0': optional: true + '@cloudflare/workerd-linux-64@1.20260708.1': + optional: true + '@cloudflare/workerd-linux-arm64@1.20240925.0': optional: true + '@cloudflare/workerd-linux-arm64@1.20260708.1': + optional: true + '@cloudflare/workerd-windows-64@1.20240925.0': optional: true + '@cloudflare/workerd-windows-64@1.20260708.1': + optional: true + '@cloudflare/workers-shared@0.5.4': dependencies: mime: 3.0.0 @@ -3364,6 +4358,11 @@ snapshots: '@dprint/win32-x64@0.47.2': optional: true + '@emnapi/runtime@1.11.2': + dependencies: + tslib: 2.7.0 + optional: true + '@esbuild-plugins/node-globals-polyfill@0.2.3(esbuild@0.17.19)': dependencies: esbuild: 0.17.19 @@ -3383,6 +4382,12 @@ snapshots: '@esbuild/aix-ppc64@0.24.0': optional: true + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/aix-ppc64@0.28.1': + optional: true + '@esbuild/android-arm64@0.17.19': optional: true @@ -3395,6 +4400,12 @@ snapshots: '@esbuild/android-arm64@0.24.0': optional: true + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.28.1': + optional: true + '@esbuild/android-arm@0.17.19': optional: true @@ -3407,6 +4418,12 @@ snapshots: '@esbuild/android-arm@0.24.0': optional: true + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-arm@0.28.1': + optional: true + '@esbuild/android-x64@0.17.19': optional: true @@ -3419,6 +4436,12 @@ snapshots: '@esbuild/android-x64@0.24.0': optional: true + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/android-x64@0.28.1': + optional: true + '@esbuild/darwin-arm64@0.17.19': optional: true @@ -3431,6 +4454,12 @@ snapshots: '@esbuild/darwin-arm64@0.24.0': optional: true + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.28.1': + optional: true + '@esbuild/darwin-x64@0.17.19': optional: true @@ -3443,6 +4472,12 @@ snapshots: '@esbuild/darwin-x64@0.24.0': optional: true + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.28.1': + optional: true + '@esbuild/freebsd-arm64@0.17.19': optional: true @@ -3455,6 +4490,12 @@ snapshots: '@esbuild/freebsd-arm64@0.24.0': optional: true + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.28.1': + optional: true + '@esbuild/freebsd-x64@0.17.19': optional: true @@ -3467,6 +4508,12 @@ snapshots: '@esbuild/freebsd-x64@0.24.0': optional: true + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.28.1': + optional: true + '@esbuild/linux-arm64@0.17.19': optional: true @@ -3479,6 +4526,12 @@ snapshots: '@esbuild/linux-arm64@0.24.0': optional: true + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.28.1': + optional: true + '@esbuild/linux-arm@0.17.19': optional: true @@ -3491,6 +4544,12 @@ snapshots: '@esbuild/linux-arm@0.24.0': optional: true + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-arm@0.28.1': + optional: true + '@esbuild/linux-ia32@0.17.19': optional: true @@ -3503,6 +4562,12 @@ snapshots: '@esbuild/linux-ia32@0.24.0': optional: true + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.28.1': + optional: true + '@esbuild/linux-loong64@0.17.19': optional: true @@ -3515,6 +4580,12 @@ snapshots: '@esbuild/linux-loong64@0.24.0': optional: true + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.28.1': + optional: true + '@esbuild/linux-mips64el@0.17.19': optional: true @@ -3527,6 +4598,12 @@ snapshots: '@esbuild/linux-mips64el@0.24.0': optional: true + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.28.1': + optional: true + '@esbuild/linux-ppc64@0.17.19': optional: true @@ -3539,6 +4616,12 @@ snapshots: '@esbuild/linux-ppc64@0.24.0': optional: true + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.28.1': + optional: true + '@esbuild/linux-riscv64@0.17.19': optional: true @@ -3551,6 +4634,12 @@ snapshots: '@esbuild/linux-riscv64@0.24.0': optional: true + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.28.1': + optional: true + '@esbuild/linux-s390x@0.17.19': optional: true @@ -3563,6 +4652,12 @@ snapshots: '@esbuild/linux-s390x@0.24.0': optional: true + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.28.1': + optional: true + '@esbuild/linux-x64@0.17.19': optional: true @@ -3572,7 +4667,19 @@ snapshots: '@esbuild/linux-x64@0.23.1': optional: true - '@esbuild/linux-x64@0.24.0': + '@esbuild/linux-x64@0.24.0': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/linux-x64@0.28.1': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.28.1': optional: true '@esbuild/netbsd-x64@0.17.19': @@ -3587,12 +4694,24 @@ snapshots: '@esbuild/netbsd-x64@0.24.0': optional: true + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.28.1': + optional: true + '@esbuild/openbsd-arm64@0.23.1': optional: true '@esbuild/openbsd-arm64@0.24.0': optional: true + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.28.1': + optional: true + '@esbuild/openbsd-x64@0.17.19': optional: true @@ -3605,6 +4724,18 @@ snapshots: '@esbuild/openbsd-x64@0.24.0': optional: true + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.28.1': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.28.1': + optional: true + '@esbuild/sunos-x64@0.17.19': optional: true @@ -3617,6 +4748,12 @@ snapshots: '@esbuild/sunos-x64@0.24.0': optional: true + '@esbuild/sunos-x64@0.25.12': + optional: true + + '@esbuild/sunos-x64@0.28.1': + optional: true + '@esbuild/win32-arm64@0.17.19': optional: true @@ -3629,6 +4766,12 @@ snapshots: '@esbuild/win32-arm64@0.24.0': optional: true + '@esbuild/win32-arm64@0.25.12': + optional: true + + '@esbuild/win32-arm64@0.28.1': + optional: true + '@esbuild/win32-ia32@0.17.19': optional: true @@ -3641,6 +4784,12 @@ snapshots: '@esbuild/win32-ia32@0.24.0': optional: true + '@esbuild/win32-ia32@0.25.12': + optional: true + + '@esbuild/win32-ia32@0.28.1': + optional: true + '@esbuild/win32-x64@0.17.19': optional: true @@ -3653,6 +4802,12 @@ snapshots: '@esbuild/win32-x64@0.24.0': optional: true + '@esbuild/win32-x64@0.25.12': + optional: true + + '@esbuild/win32-x64@0.28.1': + optional: true + '@eslint-community/eslint-utils@4.4.0(eslint@8.57.0)': dependencies: eslint: 8.57.0 @@ -3690,6 +4845,102 @@ snapshots: '@humanwhocodes/object-schema@2.0.3': {} + '@img/colour@1.1.0': {} + + '@img/sharp-darwin-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-arm64': 1.2.4 + optional: true + + '@img/sharp-darwin-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-darwin-x64': 1.2.4 + optional: true + + '@img/sharp-libvips-darwin-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-darwin-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-arm@1.2.4': + optional: true + + '@img/sharp-libvips-linux-ppc64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-riscv64@1.2.4': + optional: true + + '@img/sharp-libvips-linux-s390x@1.2.4': + optional: true + + '@img/sharp-libvips-linux-x64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-arm64@1.2.4': + optional: true + + '@img/sharp-libvips-linuxmusl-x64@1.2.4': + optional: true + + '@img/sharp-linux-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm64': 1.2.4 + optional: true + + '@img/sharp-linux-arm@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-arm': 1.2.4 + optional: true + + '@img/sharp-linux-ppc64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-ppc64': 1.2.4 + optional: true + + '@img/sharp-linux-riscv64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-riscv64': 1.2.4 + optional: true + + '@img/sharp-linux-s390x@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-s390x': 1.2.4 + optional: true + + '@img/sharp-linux-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linux-x64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-arm64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + optional: true + + '@img/sharp-linuxmusl-x64@0.34.5': + optionalDependencies: + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + optional: true + + '@img/sharp-wasm32@0.34.5': + dependencies: + '@emnapi/runtime': 1.11.2 + optional: true + + '@img/sharp-win32-arm64@0.34.5': + optional: true + + '@img/sharp-win32-ia32@0.34.5': + optional: true + + '@img/sharp-win32-x64@0.34.5': + optional: true + '@isaacs/cliui@8.0.2': dependencies: string-width: 5.1.2 @@ -3715,6 +4966,8 @@ snapshots: '@jridgewell/sourcemap-codec@1.5.0': {} + '@jridgewell/sourcemap-codec@1.5.5': {} + '@jridgewell/trace-mapping@0.3.25': dependencies: '@jridgewell/resolve-uri': 3.1.2 @@ -3744,6 +4997,18 @@ snapshots: '@popperjs/core@2.11.8': {} + '@poppinss/colors@4.1.6': + dependencies: + kleur: 4.1.5 + + '@poppinss/dumper@0.6.5': + dependencies: + '@poppinss/colors': 4.1.6 + '@sindresorhus/is': 7.2.0 + supports-color: 10.2.2 + + '@poppinss/exception@1.2.3': {} + '@preact/preset-vite@2.9.1(@babel/core@7.25.7)(preact@10.24.2)(vite@5.4.8(@types/node@20.16.10)(sass@1.79.4))': dependencies: '@babel/code-frame': 7.25.7 @@ -3792,59 +5057,145 @@ snapshots: '@rollup/rollup-android-arm-eabi@4.24.0': optional: true + '@rollup/rollup-android-arm-eabi@4.62.2': + optional: true + '@rollup/rollup-android-arm64@4.24.0': optional: true + '@rollup/rollup-android-arm64@4.62.2': + optional: true + '@rollup/rollup-darwin-arm64@4.24.0': optional: true + '@rollup/rollup-darwin-arm64@4.62.2': + optional: true + '@rollup/rollup-darwin-x64@4.24.0': optional: true + '@rollup/rollup-darwin-x64@4.62.2': + optional: true + + '@rollup/rollup-freebsd-arm64@4.62.2': + optional: true + + '@rollup/rollup-freebsd-x64@4.62.2': + optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.24.0': optional: true + '@rollup/rollup-linux-arm-gnueabihf@4.62.2': + optional: true + '@rollup/rollup-linux-arm-musleabihf@4.24.0': optional: true + '@rollup/rollup-linux-arm-musleabihf@4.62.2': + optional: true + '@rollup/rollup-linux-arm64-gnu@4.24.0': optional: true + '@rollup/rollup-linux-arm64-gnu@4.62.2': + optional: true + '@rollup/rollup-linux-arm64-musl@4.24.0': optional: true + '@rollup/rollup-linux-arm64-musl@4.62.2': + optional: true + + '@rollup/rollup-linux-loong64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-loong64-musl@4.62.2': + optional: true + '@rollup/rollup-linux-powerpc64le-gnu@4.24.0': optional: true + '@rollup/rollup-linux-ppc64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-ppc64-musl@4.62.2': + optional: true + '@rollup/rollup-linux-riscv64-gnu@4.24.0': optional: true + '@rollup/rollup-linux-riscv64-gnu@4.62.2': + optional: true + + '@rollup/rollup-linux-riscv64-musl@4.62.2': + optional: true + '@rollup/rollup-linux-s390x-gnu@4.24.0': optional: true + '@rollup/rollup-linux-s390x-gnu@4.62.2': + optional: true + '@rollup/rollup-linux-x64-gnu@4.24.0': optional: true + '@rollup/rollup-linux-x64-gnu@4.62.2': + optional: true + '@rollup/rollup-linux-x64-musl@4.24.0': optional: true + '@rollup/rollup-linux-x64-musl@4.62.2': + optional: true + + '@rollup/rollup-openbsd-x64@4.62.2': + optional: true + + '@rollup/rollup-openharmony-arm64@4.62.2': + optional: true + '@rollup/rollup-win32-arm64-msvc@4.24.0': optional: true + '@rollup/rollup-win32-arm64-msvc@4.62.2': + optional: true + '@rollup/rollup-win32-ia32-msvc@4.24.0': optional: true + '@rollup/rollup-win32-ia32-msvc@4.62.2': + optional: true + + '@rollup/rollup-win32-x64-gnu@4.62.2': + optional: true + '@rollup/rollup-win32-x64-msvc@4.24.0': optional: true + '@rollup/rollup-win32-x64-msvc@4.62.2': + optional: true + + '@sindresorhus/is@7.2.0': {} + '@socket.io/component-emitter@3.1.2': {} + '@speed-highlight/core@1.2.17': {} + + '@standard-schema/spec@1.1.0': {} + '@tsconfig/strictest@2.0.5': {} '@types/base64id@2.0.2': dependencies: '@types/node': 20.16.10 + '@types/chai@5.2.3': + dependencies: + '@types/deep-eql': 4.0.2 + assertion-error: 2.0.1 + '@types/cookie@0.4.1': {} '@types/cors@2.8.17': @@ -3855,8 +5206,12 @@ snapshots: dependencies: '@types/ms': 0.7.34 + '@types/deep-eql@4.0.2': {} + '@types/estree@1.0.6': {} + '@types/estree@1.0.9': {} + '@types/hammerjs@2.0.45': {} '@types/json-schema@7.0.15': {} @@ -3980,6 +5335,47 @@ snapshots: '@ungap/structured-clone@1.2.0': {} + '@vitest/expect@4.1.10': + dependencies: + '@standard-schema/spec': 1.1.0 + '@types/chai': 5.2.3 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + chai: 6.2.2 + tinyrainbow: 3.1.0 + + '@vitest/mocker@4.1.10(vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1))': + dependencies: + '@vitest/spy': 4.1.10 + estree-walker: 3.0.3 + magic-string: 0.30.21 + optionalDependencies: + vite: 6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1) + + '@vitest/pretty-format@4.1.10': + dependencies: + tinyrainbow: 3.1.0 + + '@vitest/runner@4.1.10': + dependencies: + '@vitest/utils': 4.1.10 + pathe: 2.0.3 + + '@vitest/snapshot@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + '@vitest/utils': 4.1.10 + magic-string: 0.30.21 + pathe: 2.0.3 + + '@vitest/spy@4.1.10': {} + + '@vitest/utils@4.1.10': + dependencies: + '@vitest/pretty-format': 4.1.10 + convert-source-map: 2.0.0 + tinyrainbow: 3.1.0 + accepts@1.3.8: dependencies: mime-types: 2.1.35 @@ -4039,6 +5435,8 @@ snapshots: dependencies: printable-characters: 1.0.42 + assertion-error@2.0.1: {} + autoprefixer@10.4.20(postcss@8.4.47): dependencies: browserslist: 4.24.0 @@ -4119,6 +5517,8 @@ snapshots: transitivePeerDependencies: - supports-color + chai@6.2.2: {} + chalk@2.4.2: dependencies: ansi-styles: 3.2.1 @@ -4163,6 +5563,8 @@ snapshots: dependencies: readdirp: 4.0.2 + cjs-module-lexer@1.2.3: {} + classnames@2.5.1: {} cli-cursor@3.1.0: @@ -4211,6 +5613,8 @@ snapshots: cookie@0.7.2: {} + cookie@1.1.1: {} + cors@2.8.5: dependencies: object-assign: 4.1.1 @@ -4253,6 +5657,8 @@ snapshots: defu@6.1.4: {} + detect-libc@2.1.2: {} + didyoumean@1.2.2: {} dijkstrajs@1.0.3: {} @@ -4351,6 +5757,10 @@ snapshots: dependencies: is-arrayish: 0.2.1 + error-stack-parser-es@1.0.5: {} + + es-module-lexer@2.3.1: {} + esbuild@0.17.19: optionalDependencies: '@esbuild/android-arm': 0.17.19 @@ -4456,6 +5866,64 @@ snapshots: '@esbuild/win32-ia32': 0.24.0 '@esbuild/win32-x64': 0.24.0 + esbuild@0.25.12: + optionalDependencies: + '@esbuild/aix-ppc64': 0.25.12 + '@esbuild/android-arm': 0.25.12 + '@esbuild/android-arm64': 0.25.12 + '@esbuild/android-x64': 0.25.12 + '@esbuild/darwin-arm64': 0.25.12 + '@esbuild/darwin-x64': 0.25.12 + '@esbuild/freebsd-arm64': 0.25.12 + '@esbuild/freebsd-x64': 0.25.12 + '@esbuild/linux-arm': 0.25.12 + '@esbuild/linux-arm64': 0.25.12 + '@esbuild/linux-ia32': 0.25.12 + '@esbuild/linux-loong64': 0.25.12 + '@esbuild/linux-mips64el': 0.25.12 + '@esbuild/linux-ppc64': 0.25.12 + '@esbuild/linux-riscv64': 0.25.12 + '@esbuild/linux-s390x': 0.25.12 + '@esbuild/linux-x64': 0.25.12 + '@esbuild/netbsd-arm64': 0.25.12 + '@esbuild/netbsd-x64': 0.25.12 + '@esbuild/openbsd-arm64': 0.25.12 + '@esbuild/openbsd-x64': 0.25.12 + '@esbuild/openharmony-arm64': 0.25.12 + '@esbuild/sunos-x64': 0.25.12 + '@esbuild/win32-arm64': 0.25.12 + '@esbuild/win32-ia32': 0.25.12 + '@esbuild/win32-x64': 0.25.12 + + esbuild@0.28.1: + 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 + escalade@3.2.0: {} escape-string-regexp@1.0.5: {} @@ -4583,6 +6051,10 @@ snapshots: estree-walker@2.0.2: {} + estree-walker@3.0.3: + dependencies: + '@types/estree': 1.0.6 + esutils@2.0.3: {} execa@5.1.1: @@ -4599,6 +6071,8 @@ snapshots: exit-hook@2.2.1: {} + expect-type@1.4.0: {} + external-editor@3.1.0: dependencies: chardet: 0.7.0 @@ -4625,6 +6099,10 @@ snapshots: dependencies: reusify: 1.0.4 + fdir@6.5.0(picomatch@4.0.5): + optionalDependencies: + picomatch: 4.0.5 + figures@3.2.0: dependencies: escape-string-regexp: 1.0.5 @@ -4894,6 +6372,8 @@ snapshots: kind-of@6.0.3: {} + kleur@4.1.5: {} + kolorist@1.8.0: {} levn@0.4.1: @@ -4941,6 +6421,10 @@ snapshots: dependencies: sourcemap-codec: 1.4.8 + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.5.5 + magic-string@0.30.5: dependencies: '@jridgewell/sourcemap-codec': 1.5.0 @@ -5004,6 +6488,18 @@ snapshots: - supports-color - utf-8-validate + miniflare@4.20260708.1: + dependencies: + '@cspotcode/source-map-support': 0.8.1 + sharp: 0.34.5 + undici: 7.28.0 + workerd: 1.20260708.1 + ws: 8.21.0 + youch: 4.1.0-beta.10 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + minimatch@3.1.2: dependencies: brace-expansion: 1.1.11 @@ -5032,6 +6528,8 @@ snapshots: object-assign: 4.1.1 thenify-all: 1.6.0 + nanoid@3.3.16: {} + nanoid@3.3.7: {} natural-compare-lite@1.4.0: {} @@ -5088,6 +6586,8 @@ snapshots: object-hash@3.0.0: {} + obug@2.1.3: {} + ohash@1.1.4: {} once@1.4.0: @@ -5174,10 +6674,16 @@ snapshots: pathe@1.1.2: {} + pathe@2.0.3: {} + picocolors@1.1.0: {} + picocolors@1.1.1: {} + picomatch@2.3.1: {} + picomatch@4.0.5: {} + pify@2.3.0: {} pirates@4.0.6: {} @@ -5221,6 +6727,12 @@ snapshots: picocolors: 1.1.0 source-map-js: 1.2.1 + postcss@8.5.19: + dependencies: + nanoid: 3.3.16 + picocolors: 1.1.1 + source-map-js: 1.2.1 + preact-router@4.1.2(preact@10.24.2): dependencies: preact: 10.24.2 @@ -5388,6 +6900,37 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.24.0 fsevents: 2.3.3 + rollup@4.62.2: + dependencies: + '@types/estree': 1.0.9 + optionalDependencies: + '@rollup/rollup-android-arm-eabi': 4.62.2 + '@rollup/rollup-android-arm64': 4.62.2 + '@rollup/rollup-darwin-arm64': 4.62.2 + '@rollup/rollup-darwin-x64': 4.62.2 + '@rollup/rollup-freebsd-arm64': 4.62.2 + '@rollup/rollup-freebsd-x64': 4.62.2 + '@rollup/rollup-linux-arm-gnueabihf': 4.62.2 + '@rollup/rollup-linux-arm-musleabihf': 4.62.2 + '@rollup/rollup-linux-arm64-gnu': 4.62.2 + '@rollup/rollup-linux-arm64-musl': 4.62.2 + '@rollup/rollup-linux-loong64-gnu': 4.62.2 + '@rollup/rollup-linux-loong64-musl': 4.62.2 + '@rollup/rollup-linux-ppc64-gnu': 4.62.2 + '@rollup/rollup-linux-ppc64-musl': 4.62.2 + '@rollup/rollup-linux-riscv64-gnu': 4.62.2 + '@rollup/rollup-linux-riscv64-musl': 4.62.2 + '@rollup/rollup-linux-s390x-gnu': 4.62.2 + '@rollup/rollup-linux-x64-gnu': 4.62.2 + '@rollup/rollup-linux-x64-musl': 4.62.2 + '@rollup/rollup-openbsd-x64': 4.62.2 + '@rollup/rollup-openharmony-arm64': 4.62.2 + '@rollup/rollup-win32-arm64-msvc': 4.62.2 + '@rollup/rollup-win32-ia32-msvc': 4.62.2 + '@rollup/rollup-win32-x64-gnu': 4.62.2 + '@rollup/rollup-win32-x64-msvc': 4.62.2 + fsevents: 2.3.3 + run-async@2.4.1: {} run-parallel@1.2.0: @@ -5425,6 +6968,8 @@ snapshots: semver@7.6.3: {} + semver@7.8.5: {} + sentence-case@3.0.4: dependencies: no-case: 3.0.4 @@ -5435,12 +6980,45 @@ snapshots: set-blocking@2.0.0: {} + sharp@0.34.5: + dependencies: + '@img/colour': 1.1.0 + detect-libc: 2.1.2 + semver: 7.8.5 + optionalDependencies: + '@img/sharp-darwin-arm64': 0.34.5 + '@img/sharp-darwin-x64': 0.34.5 + '@img/sharp-libvips-darwin-arm64': 1.2.4 + '@img/sharp-libvips-darwin-x64': 1.2.4 + '@img/sharp-libvips-linux-arm': 1.2.4 + '@img/sharp-libvips-linux-arm64': 1.2.4 + '@img/sharp-libvips-linux-ppc64': 1.2.4 + '@img/sharp-libvips-linux-riscv64': 1.2.4 + '@img/sharp-libvips-linux-s390x': 1.2.4 + '@img/sharp-libvips-linux-x64': 1.2.4 + '@img/sharp-libvips-linuxmusl-arm64': 1.2.4 + '@img/sharp-libvips-linuxmusl-x64': 1.2.4 + '@img/sharp-linux-arm': 0.34.5 + '@img/sharp-linux-arm64': 0.34.5 + '@img/sharp-linux-ppc64': 0.34.5 + '@img/sharp-linux-riscv64': 0.34.5 + '@img/sharp-linux-s390x': 0.34.5 + '@img/sharp-linux-x64': 0.34.5 + '@img/sharp-linuxmusl-arm64': 0.34.5 + '@img/sharp-linuxmusl-x64': 0.34.5 + '@img/sharp-wasm32': 0.34.5 + '@img/sharp-win32-arm64': 0.34.5 + '@img/sharp-win32-ia32': 0.34.5 + '@img/sharp-win32-x64': 0.34.5 + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 shebang-regex@3.0.0: {} + siginfo@2.0.0: {} + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -5503,11 +7081,15 @@ snapshots: stack-trace@1.0.0-pre2: {} + stackback@0.0.2: {} + stacktracey@2.1.8: dependencies: as-table: 1.0.55 get-source: 2.0.12 + std-env@4.2.0: {} + stoppable@1.1.0: {} string-width@4.2.3: @@ -5548,6 +7130,8 @@ snapshots: pirates: 4.0.6 ts-interface-checker: 0.1.13 + supports-color@10.2.2: {} + supports-color@5.5.0: dependencies: has-flag: 3.0.0 @@ -5602,6 +7186,17 @@ snapshots: through@2.3.8: {} + tinybench@2.9.0: {} + + tinyexec@1.2.4: {} + + tinyglobby@0.2.17: + dependencies: + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + + tinyrainbow@3.1.0: {} + tmp@0.0.33: dependencies: os-tmpdir: 1.0.2 @@ -5658,6 +7253,8 @@ snapshots: dependencies: '@fastify/busboy': 2.1.1 + undici@7.28.0: {} + unenv-nightly@2.0.0-20240919-125358-9a64854: dependencies: defu: 6.1.4 @@ -5665,6 +7262,10 @@ snapshots: pathe: 1.1.2 ufo: 1.5.4 + unenv@2.0.0-rc.24: + dependencies: + pathe: 2.0.3 + update-browserslist-db@1.1.1(browserslist@4.24.0): dependencies: browserslist: 4.24.0 @@ -5706,6 +7307,49 @@ snapshots: fsevents: 2.3.3 sass: 1.79.4 + vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1): + dependencies: + esbuild: 0.25.12 + fdir: 6.5.0(picomatch@4.0.5) + picomatch: 4.0.5 + postcss: 8.5.19 + rollup: 4.62.2 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 20.16.10 + fsevents: 2.3.3 + jiti: 1.21.6 + sass: 1.79.4 + tsx: 4.19.1 + yaml: 2.5.1 + + vitest@4.1.10(@types/node@20.16.10)(vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1)): + dependencies: + '@vitest/expect': 4.1.10 + '@vitest/mocker': 4.1.10(vite@6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1)) + '@vitest/pretty-format': 4.1.10 + '@vitest/runner': 4.1.10 + '@vitest/snapshot': 4.1.10 + '@vitest/spy': 4.1.10 + '@vitest/utils': 4.1.10 + es-module-lexer: 2.3.1 + expect-type: 1.4.0 + magic-string: 0.30.21 + obug: 2.1.3 + pathe: 2.0.3 + picomatch: 4.0.5 + std-env: 4.2.0 + tinybench: 2.9.0 + tinyexec: 1.2.4 + tinyglobby: 0.2.17 + tinyrainbow: 3.1.0 + vite: 6.4.3(@types/node@20.16.10)(jiti@1.21.6)(sass@1.79.4)(tsx@4.19.1)(yaml@2.5.1) + why-is-node-running: 2.3.0 + optionalDependencies: + '@types/node': 20.16.10 + transitivePeerDependencies: + - msw + warning@4.0.3: dependencies: loose-envify: 1.4.0 @@ -5716,6 +7360,11 @@ snapshots: dependencies: isexe: 2.0.0 + why-is-node-running@2.3.0: + dependencies: + siginfo: 2.0.0 + stackback: 0.0.2 + word-wrap@1.2.5: {} workerd@1.20240925.0: @@ -5726,6 +7375,14 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20240925.0 '@cloudflare/workerd-windows-64': 1.20240925.0 + workerd@1.20260708.1: + optionalDependencies: + '@cloudflare/workerd-darwin-64': 1.20260708.1 + '@cloudflare/workerd-darwin-arm64': 1.20260708.1 + '@cloudflare/workerd-linux-64': 1.20260708.1 + '@cloudflare/workerd-linux-arm64': 1.20260708.1 + '@cloudflare/workerd-windows-64': 1.20260708.1 + wrangler@3.80.0(@cloudflare/workers-types@4.20241004.0): dependencies: '@cloudflare/kv-asset-handler': 0.3.4 @@ -5753,6 +7410,23 @@ snapshots: - supports-color - utf-8-validate + wrangler@4.110.0(@cloudflare/workers-types@4.20241004.0): + dependencies: + '@cloudflare/kv-asset-handler': 0.5.0 + '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260708.1) + blake3-wasm: 2.1.5 + esbuild: 0.28.1 + miniflare: 4.20260708.1 + path-to-regexp: 6.3.0 + unenv: 2.0.0-rc.24 + workerd: 1.20260708.1 + optionalDependencies: + '@cloudflare/workers-types': 4.20241004.0 + fsevents: 2.3.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + wrap-ansi@6.2.0: dependencies: ansi-styles: 4.3.0 @@ -5780,6 +7454,8 @@ snapshots: ws@8.17.1: {} + ws@8.21.0: {} + xmlhttprequest-ssl@2.1.1: {} xxhash-wasm@1.0.2: {} @@ -5815,10 +7491,25 @@ 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@3.3.3: dependencies: cookie: 0.5.0 mustache: 4.2.0 stacktracey: 2.1.8 + youch@4.1.0-beta.10: + dependencies: + '@poppinss/colors': 4.1.6 + '@poppinss/dumper': 0.6.5 + '@speed-highlight/core': 1.2.17 + cookie: 1.1.1 + youch-core: 0.3.3 + zod@3.23.8: {} + + zod@3.25.76: {} From 150f81d7bffd213b9622334c6baea7faae8096ec Mon Sep 17 00:00:00 2001 From: Wang Guan Date: Wed, 15 Jul 2026 00:24:59 +0900 Subject: [PATCH 3/6] ci: add test workflow running integration tests in workerd via Miniflare Checkout submodules, fetch the socket.io@4.8.1 tag so make patch-upstream resolves, build the library, then run pnpm run --filter ./demo-server test. Also fix the pnpm filter in AGENTS.md (--filter ./demo-server by directory, not by package name). --- .github/workflows/test.yaml | 41 +++++++++++++++++++++++++++++++++++++ AGENTS.md | 4 ++-- 2 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/test.yaml diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..a68fcd7 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,41 @@ +name: test + +on: + push: + branches: [main] + pull_request: {} + workflow_dispatch: {} + +jobs: + test: + runs-on: ubuntu-latest + timeout-minutes: 10 + steps: + - uses: actions/checkout@v4 + + # init submodule (pinned to the socket.io@4.8.1 tag commit) and fetch the + # tag ref so `make patch-upstream` (which runs `git reset --hard socket.io@4.8.1`) + # can resolve it. + - run: git submodule update --init + - run: git -C socket.io fetch --depth 1 origin socket.io@4.8.1 + + - uses: pnpm/action-setup@v4 + with: + version: 9.12.0 + + - uses: actions/setup-node@v4 + with: + node-version: "20" + cache: pnpm + + - run: pnpm install + + - name: Patch upstream socket.io and build library + run: make patch-upstream lib-build + + - name: Typecheck library (non-blocking, pre-existing upstream errors) + continue-on-error: true + run: pnpm --filter socket.io-serverless run typecheck + + - name: Run integration tests + run: pnpm run --filter ./demo-server test \ No newline at end of file diff --git a/AGENTS.md b/AGENTS.md index 1f73162..9ce5a12 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -86,8 +86,8 @@ The tests use `@cloudflare/vitest-pool-workers` to spin up the real `workerd` ru ```bash make lib-build # the Worker imports the bundled library, so build it first -pnpm run --filter demo-server test # vitest run -pnpm run --filter demo-server test:watch # vitest watch +pnpm run --filter ./demo-server test # vitest run +pnpm run --filter ./demo-server test:watch # vitest watch ``` Available test APIs (imported from `cloudflare:test` / `cloudflare:workers`): From 742a6de25673becd7f50756f640c075a72e7536e Mon Sep 17 00:00:00 2001 From: Wang Guan Date: Wed, 15 Jul 2026 01:35:25 +0900 Subject: [PATCH 4/6] ci: rename workflow to 'check' and run all available checks Rename test.yaml -> check.yaml. The job now runs: - make patch-upstream lib-build - dprint check on socket.io-serverless - tsc --noEmit on library (non-blocking, pre-existing upstream errors) - wrangler deploy --dry-run on demo-server - vite build on demo-client - vitest integration tests on demo-server Also apply dprint fmt to socket.io-serverless/build.mjs (target: "es2023" -> 'es2023') so 'dprint check' passes clean. --- .github/workflows/{test.yaml => check.yaml} | 15 ++++++++++++--- socket.io-serverless/build.mjs | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) rename .github/workflows/{test.yaml => check.yaml} (71%) diff --git a/.github/workflows/test.yaml b/.github/workflows/check.yaml similarity index 71% rename from .github/workflows/test.yaml rename to .github/workflows/check.yaml index a68fcd7..b2510d3 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/check.yaml @@ -1,4 +1,4 @@ -name: test +name: check on: push: @@ -7,7 +7,7 @@ on: workflow_dispatch: {} jobs: - test: + check: runs-on: ubuntu-latest timeout-minutes: 10 steps: @@ -33,9 +33,18 @@ jobs: - name: Patch upstream socket.io and build library run: make patch-upstream lib-build + - name: Format check (library) + run: pnpm --filter ./socket.io-serverless exec dprint check + - name: Typecheck library (non-blocking, pre-existing upstream errors) continue-on-error: true - run: pnpm --filter socket.io-serverless run typecheck + run: pnpm --filter ./socket.io-serverless run typecheck + + - name: Build demo-server Worker (wrangler dry-run) + run: pnpm run --filter ./demo-server build:cf + + - name: Build demo-client (vite build) + run: pnpm run --filter ./demo-client build - name: Run integration tests run: pnpm run --filter ./demo-server test \ No newline at end of file diff --git a/socket.io-serverless/build.mjs b/socket.io-serverless/build.mjs index ec3a02d..a3912ae 100644 --- a/socket.io-serverless/build.mjs +++ b/socket.io-serverless/build.mjs @@ -167,7 +167,7 @@ const cfBuildContext = { entryPoints: ['src/cf/index.ts'], bundle: true, platform: 'neutral', - target: "es2023", + target: 'es2023', format: 'esm', metafile: true, outfile: 'dist/cf.js', From 3ec3f7a9415c5203ba3990919e0275d5d5ebaf81 Mon Sep 17 00:00:00 2001 From: Wang Guan Date: Wed, 15 Jul 2026 01:56:15 +0900 Subject: [PATCH 5/6] chore: upgrade upstream socket.io from 4.8.1 to 4.8.3 Update the git submodule pin, regenerate the patch against the new tag, and adjust make patch-upstream to fetch the tag before resetting. Notable upstream change: socket.io/lib/client.ts already uses 'import x from "..."' syntax, so that hunk is no longer needed in the patch. The remaining patch hunks (removing export maps from package.json files and stripping module.exports from index.ts) still apply cleanly. All 8 integration tests pass against 4.8.3. --- .github/workflows/check.yaml | 2 +- AGENTS.md | 2 +- Makefile | 2 +- ...01-workarounds-to-upstream-socket.io.patch | 75 ++++++++---------- pnpm-lock.yaml | 76 ++++++++++++------- socket.io | 2 +- 6 files changed, 87 insertions(+), 72 deletions(-) diff --git a/.github/workflows/check.yaml b/.github/workflows/check.yaml index b2510d3..8370c61 100644 --- a/.github/workflows/check.yaml +++ b/.github/workflows/check.yaml @@ -17,7 +17,7 @@ jobs: # tag ref so `make patch-upstream` (which runs `git reset --hard socket.io@4.8.1`) # can resolve it. - run: git submodule update --init - - run: git -C socket.io fetch --depth 1 origin socket.io@4.8.1 + - run: git -C socket.io fetch --depth 1 origin socket.io@4.8.3 - uses: pnpm/action-setup@v4 with: diff --git a/AGENTS.md b/AGENTS.md index 9ce5a12..dd244b6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -40,7 +40,7 @@ A **Worker entrypoint** (thin HTTP handler) forwards upgrade requests to `Engine - pnpm 9.12.0 - Node.js 20+ - The `socket.io` git submodule must be initialized: `git submodule update --init` -- Then patch it: `make patch-upstream` (or `cd socket.io && git reset --hard socket.io@4.8.1 && git reset . && git checkout -- . && git apply < ../patches/0001-workarounds-to-upstream-socket.io.patch`) +- Then patch it: `make patch-upstream` (or `cd socket.io && git fetch --depth 1 origin socket.io@4.8.3 && git reset --hard FETCH_HEAD && git reset . && git checkout -- . && git apply < ../patches/0001-workarounds-to-upstream-socket.io.patch`) ### Install ```bash diff --git a/Makefile b/Makefile index e0a51f0..0f133d9 100644 --- a/Makefile +++ b/Makefile @@ -14,4 +14,4 @@ demo-server-bundle: pnpm run --filter ./demo-server build:cf patch-upstream: - cd socket.io && git reset --hard socket.io@4.8.1 && git reset . && git checkout -- . && git apply < ../patches/0001-workarounds-to-upstream-socket.io.patch + cd socket.io && git fetch --depth 1 origin socket.io@4.8.3 && git reset --hard FETCH_HEAD && git reset . && git checkout -- . && git apply < ../patches/0001-workarounds-to-upstream-socket.io.patch diff --git a/patches/0001-workarounds-to-upstream-socket.io.patch b/patches/0001-workarounds-to-upstream-socket.io.patch index 636b334..f9f3433 100644 --- a/patches/0001-workarounds-to-upstream-socket.io.patch +++ b/patches/0001-workarounds-to-upstream-socket.io.patch @@ -1,22 +1,8 @@ -From 1f4a58f306ae0522da74bda2a449031296b3d967 Mon Sep 17 00:00:00 2001 -From: Wang Guan -Date: Sun, 13 Oct 2024 01:41:00 +0800 -Subject: [PATCH] commit again - ---- - packages/engine.io-client/package.json | 10 +++++----- - packages/engine.io-parser/package.json | 9 +-------- - packages/engine.io/package.json | 5 ----- - packages/socket.io/lib/client.ts | 4 ++-- - packages/socket.io/lib/index.ts | 5 ----- - packages/socket.io/package.json | 5 ----- - 6 files changed, 8 insertions(+), 30 deletions(-) - diff --git a/packages/engine.io-client/package.json b/packages/engine.io-client/package.json -index 0a76e8c..bbf25c6 100644 +index 197aa40..85d04fb 100644 --- a/packages/engine.io-client/package.json +++ b/packages/engine.io-client/package.json -@@ -71,13 +71,13 @@ +@@ -72,13 +72,13 @@ "prepack": "npm run compile" }, "browser": { @@ -35,8 +21,15 @@ index 0a76e8c..bbf25c6 100644 }, "homepage": "https://github.com/socketio/socket.io/tree/main/packages/engine.io-client#readme", "repository": { +@@ -92,4 +92,4 @@ + "build/", + "dist/" + ] +-} ++} +\ No newline at end of file diff --git a/packages/engine.io-parser/package.json b/packages/engine.io-parser/package.json -index d661db3..6066cbd 100644 +index f7926d8..0c721f9 100644 --- a/packages/engine.io-parser/package.json +++ b/packages/engine.io-parser/package.json @@ -5,10 +5,6 @@ @@ -50,7 +43,7 @@ index d661db3..6066cbd 100644 "types": "build/esm/index.d.ts", "scripts": { "compile": "rimraf ./build && tsc && tsc -p tsconfig.esm.json && ./postcompile.sh", -@@ -31,11 +27,8 @@ +@@ -31,13 +27,10 @@ "build/" ], "browser": { @@ -63,8 +56,12 @@ index d661db3..6066cbd 100644 }, "engines": { "node": ">=10.0.0" + } +-} ++} +\ No newline at end of file diff --git a/packages/engine.io/package.json b/packages/engine.io/package.json -index ccd64cf..e707790 100644 +index 0a8ba65..59a84aa 100644 --- a/packages/engine.io/package.json +++ b/packages/engine.io/package.json @@ -5,11 +5,6 @@ @@ -79,24 +76,18 @@ index ccd64cf..e707790 100644 "author": "Guillermo Rauch ", "contributors": [ { -diff --git a/packages/socket.io/lib/client.ts b/packages/socket.io/lib/client.ts -index 6ca7b77..c148c2d 100644 ---- a/packages/socket.io/lib/client.ts -+++ b/packages/socket.io/lib/client.ts -@@ -1,6 +1,6 @@ - import { Decoder, Encoder, Packet, PacketType } from "socket.io-parser"; --import debugModule = require("debug"); --import url = require("url"); -+import debugModule from "debug"; -+import url from "url"; - import type { IncomingMessage } from "http"; - import type { Server } from "./index"; - import type { Namespace } from "./namespace"; +@@ -67,4 +62,4 @@ + "engines": { + "node": ">=10.2.0" + } +-} ++} +\ No newline at end of file diff --git a/packages/socket.io/lib/index.ts b/packages/socket.io/lib/index.ts -index b77b8fd..ec527ea 100644 +index 6027859..307d6f1 100644 --- a/packages/socket.io/lib/index.ts +++ b/packages/socket.io/lib/index.ts -@@ -1163,11 +1163,6 @@ emitterMethods.forEach(function (fn) { +@@ -1181,11 +1181,6 @@ emitterMethods.forEach(function (fn) { }; }); @@ -109,21 +100,21 @@ index b77b8fd..ec527ea 100644 Socket, DisconnectReason, diff --git a/packages/socket.io/package.json b/packages/socket.io/package.json -index 8c52110..49a1e18 100644 +index a1a683b..f60cc97 100644 --- a/packages/socket.io/package.json +++ b/packages/socket.io/package.json -@@ -25,11 +25,6 @@ +@@ -25,14 +25,6 @@ }, "type": "commonjs", "main": "./dist/index.js", - "exports": { -- "types": "./dist/index.d.ts", -- "import": "./wrapper.mjs", -- "require": "./dist/index.js" +- ".": { +- "types": "./dist/index.d.ts", +- "import": "./wrapper.mjs", +- "require": "./dist/index.js" +- }, +- "./package.json": "./package.json" - }, "types": "./dist/index.d.ts", "license": "MIT", "homepage": "https://github.com/socketio/socket.io/tree/main/packages/socket.io#readme", --- -2.39.5 - diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 174de44..e034bf7 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -224,9 +224,6 @@ importers: socket.io/packages/engine.io: dependencies: - '@types/cookie': - specifier: ^0.4.1 - version: 0.4.1 '@types/cors': specifier: ^2.8.12 version: 2.8.17 @@ -246,14 +243,14 @@ importers: specifier: ~2.8.5 version: 2.8.5 debug: - specifier: ~4.3.1 - version: 4.3.7 + specifier: ~4.4.1 + version: 4.4.3 engine.io-parser: specifier: ~5.2.1 version: 5.2.3 ws: - specifier: ~8.17.1 - version: 8.17.1 + specifier: ~8.18.3 + version: 8.18.3 socket.io/packages/engine.io-parser: {} @@ -269,8 +266,8 @@ importers: specifier: ~2.8.5 version: 2.8.5 debug: - specifier: ~4.3.2 - version: 4.3.7 + specifier: ~4.4.1 + version: 4.4.3 engine.io: specifier: ~6.6.0 version: 6.6.1 @@ -284,11 +281,11 @@ importers: socket.io/packages/socket.io-adapter: dependencies: debug: - specifier: ~4.3.4 - version: 4.3.7 + specifier: ~4.4.1 + version: 4.4.3 ws: - specifier: ~8.17.1 - version: 8.17.1 + specifier: ~8.18.3 + version: 8.18.3 socket.io/packages/socket.io-parser: dependencies: @@ -296,8 +293,8 @@ importers: specifier: ~3.1.0 version: 3.1.2 debug: - specifier: ~4.3.1 - version: 4.3.7 + specifier: ~4.4.1 + version: 4.4.3 packages: @@ -2365,6 +2362,15 @@ packages: supports-color: optional: true + debug@4.4.3: + resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} + engines: {node: '>=6.0'} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} engines: {node: '>=0.10.0'} @@ -4017,6 +4023,18 @@ packages: utf-8-validate: optional: true + ws@8.18.3: + resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + 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 + ws@8.21.0: resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} @@ -4110,7 +4128,7 @@ snapshots: '@babel/traverse': 7.25.7 '@babel/types': 7.25.7 convert-source-map: 2.0.0 - debug: 4.3.7 + debug: 4.4.3 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -4224,7 +4242,7 @@ snapshots: '@babel/parser': 7.25.7 '@babel/template': 7.25.7 '@babel/types': 7.25.7 - debug: 4.3.7 + debug: 4.4.3 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -4818,7 +4836,7 @@ snapshots: '@eslint/eslintrc@2.1.4': dependencies: ajv: 6.12.6 - debug: 4.3.7 + debug: 4.4.3 espree: 9.6.1 globals: 13.24.0 ignore: 5.3.2 @@ -4836,7 +4854,7 @@ snapshots: '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 - debug: 4.3.7 + debug: 4.4.3 minimatch: 3.1.2 transitivePeerDependencies: - supports-color @@ -5256,7 +5274,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/type-utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) - debug: 4.3.7 + debug: 4.4.3 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.2 @@ -5273,7 +5291,7 @@ snapshots: '@typescript-eslint/scope-manager': 5.62.0 '@typescript-eslint/types': 5.62.0 '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.2) - debug: 4.3.7 + debug: 4.4.3 eslint: 8.57.0 optionalDependencies: typescript: 5.6.2 @@ -5289,7 +5307,7 @@ snapshots: dependencies: '@typescript-eslint/typescript-estree': 5.62.0(typescript@5.6.2) '@typescript-eslint/utils': 5.62.0(eslint@8.57.0)(typescript@5.6.2) - debug: 4.3.7 + debug: 4.4.3 eslint: 8.57.0 tsutils: 3.21.0(typescript@5.6.2) optionalDependencies: @@ -5303,7 +5321,7 @@ snapshots: dependencies: '@typescript-eslint/types': 5.62.0 '@typescript-eslint/visitor-keys': 5.62.0 - debug: 4.3.7 + debug: 4.4.3 globby: 11.1.0 is-glob: 4.0.3 semver: 7.6.3 @@ -5512,7 +5530,7 @@ snapshots: capnp-ts@0.7.0: dependencies: - debug: 4.3.7 + debug: 4.4.3 tslib: 2.7.0 transitivePeerDependencies: - supports-color @@ -5646,6 +5664,10 @@ snapshots: dependencies: ms: 2.1.3 + debug@4.4.3: + dependencies: + ms: 2.1.3 + decamelize-keys@1.1.1: dependencies: decamelize: 1.2.0 @@ -5999,7 +6021,7 @@ snapshots: ajv: 6.12.6 chalk: 4.1.2 cross-spawn: 7.0.3 - debug: 4.3.7 + debug: 4.4.3 doctrine: 3.0.0 escape-string-regexp: 4.0.0 eslint-scope: 7.2.2 @@ -6480,7 +6502,7 @@ snapshots: stoppable: 1.1.0 undici: 5.28.4 workerd: 1.20240925.0 - ws: 8.17.1 + ws: 8.18.3 youch: 3.3.3 zod: 3.23.8 transitivePeerDependencies: @@ -7454,6 +7476,8 @@ snapshots: ws@8.17.1: {} + ws@8.18.3: {} + ws@8.21.0: {} xmlhttprequest-ssl@2.1.1: {} diff --git a/socket.io b/socket.io index 91e1c8b..9978574 160000 --- a/socket.io +++ b/socket.io @@ -1 +1 @@ -Subproject commit 91e1c8b3584054db6072046404a24e79a17c1367 +Subproject commit 9978574e4f1d4e21593497f94c40053cd0fff359 From 628c0f16d6d1c424636ee7de29aa611d51068171 Mon Sep 17 00:00:00 2001 From: Wang Guan Date: Wed, 15 Jul 2026 02:17:02 +0900 Subject: [PATCH 6/6] docs: add terraform-migration reference for switching deploy tool Add docs/terraform-migration.md explaining the concrete differences between wrangler and terraform, a full wrangler.toml -> HCL field mapping, required repo changes (Makefile, package.json, CI), local-dev options, DO migration semantics, and a ready-to-adapt main.tf. --- docs/terraform-migration.md | 323 ++++++++++++++++++++++++++++++++++++ 1 file changed, 323 insertions(+) create mode 100644 docs/terraform-migration.md diff --git a/docs/terraform-migration.md b/docs/terraform-migration.md new file mode 100644 index 0000000..dd2548b --- /dev/null +++ b/docs/terraform-migration.md @@ -0,0 +1,323 @@ +# Migrating Deployments from Wrangler to Terraform + +This document explains the concrete differences between deploying this repo +with `wrangler` (today) and with the `cloudflare/cloudflare` Terraform provider, +and enumerates the changes that the switch would require. + +It is a reference for when we actually make the switch. + +## 1. What stays the same + +Switching the deploy tool does **not** change the runtime shape of the project: + +- **Library build** (`socket.io-serverless/build.mjs`, `make lib-build`). + esbuild still bundles `dist/cf.js`; Terraform uploads those same bytes. +- **Worker source** (`demo-server/src/cf/main.ts`). + The default-exported `fetch` handler, the `EngineActor` / `SocketActor` + factory calls, and the `WorkerBindings` interface are unchanged. +- **Durable Object code** (`src/cf/eio/EngineActorBase.ts`, + `src/cf/sio/SocketActorBase.ts`). + Hibernatable WebSocket API, `state.storage` persistence, and `AlarmTimer` + are runtime APIs — independent of the deploy tool. +- **Integration tests** (`demo-server/test/*.spec.ts`). + `@cloudflare/vitest-pool-workers` runs the Worker in `workerd` via + Miniflare. It reads `wrangler.toml` at test time, but that is a Miniflare + convention — the tests never invoke `wrangler` or Terraform. +- **Submodule patching** (`make patch-upstream`). + Operating on the `socket.io` submodule is orthogonal to deployment. + +## 2. Where the two paths diverge + +Both `wrangler deploy` and `terraform apply` end at the same Cloudflare REST +endpoint: + +``` +PUT /accounts/{account_id}/workers/scripts/{script_name} +Content-Type: multipart/form-data; boundary=… +``` + +The multipart body has two parts: + +1. `metadata` — JSON containing `compatibility_date`, `compatibility_flags`, + `bindings`, `migrations`, `main_module`, `observability`, etc. +2. One or more JS modules (`application/javascript+module`) referenced by + `main_module`. + +Wrangler assembles that multipart in Rust after bundling `src/cf/main.ts` +with esbuild. The Terraform provider assembles it in Go +([`WorkersScriptModel.MarshalMultipart`](https://github.com/cloudflare/terraform-provider-cloudflare/blob/v5.22.0/internal/services/workers_script/model.go)) +**from bytes you supply**. Terraform does not bundle. + +That single difference — *who runs the bundler* — is the root of every other +divergence below. + +## 3. Concrete field mapping + +Every key currently in `demo-server/wrangler.toml` has a counterpart on the +`cloudflare_workers_script` resource. The table is exhaustive for this repo. + +| `wrangler.toml` | `cloudflare_workers_script` (HCL) | Notes | +|---|---|---| +| `name = "sio-serverless-demo"` | `script_name = "sio-serverless-demo"` | | +| `main = "src/cf/main.ts"` | `main_module = "cf.js"` + `content = file("${path.module}/dist/cf.js")` | TF does not bundle; you point `content` at the **already-built** `dist/cf.js` from `make lib-build`. | +| `compatibility_date = "2024-08-21"` | `compatibility_date = "2024-08-21"` | Same value. | +| `compatibility_flags = ["nodejs_compat_v2"]` | `compatibility_flags = ["nodejs_compat_v2"]` | Same list. | +| `workers_dev = true` | (delete, or add `cloudflare_workers_subdomain` separately) | TF does not model `workers.dev` subdomain on the script resource. | +| `[observability] enabled = true` | `observability = { enabled = true }` | Nested block. | +| `[dev] port = 18787` | — | No local-dev server in TF. See §5. | +| `[durable_objects] bindings = [{name="engineActor", class_name="EngineActor"}, ...]` | `bindings = [{name="engineActor", type="durable_object_namespace", class_name="EngineActor"}, ...]` | Same data; TF requires the explicit `type`. | +| `[vars]` | `bindings = [{name="MY_VAR", type="plain_text", text="…"}]` | Plain vars become `plain_text` bindings in TF. | +| `[[migrations]] tag="v1" new_classes=["EngineActor","SocketActor"]` | `migrations = { old_tag="v1", new_tag="v1", new_classes=["EngineActor","SocketActor"] }` | TF requires **both** `old_tag` and `new_tag`. See §6. | + +## 4. Required changes to the repo + +### 4.1 New files + +- `demo-server/infra/main.tf` — the `cloudflare_workers_script` resource, + `terraform { required_providers { cloudflare = … } }`, and any + `variable` declarations (`account_id`, `api_token`). +- `demo-server/infra/terraform.tfvars` — or pull `account_id` / + `api_token` from the `CLOUDFLARE_API_TOKEN` / `CLOUDflare_ACCOUNT_ID` + environment variables (recommended). +- `demo-server/infra/.gitignore` — ignore `.terraform/`, `*.tfstate`, + `*.tfstate.backup`, `.terraform.lock.hcl`. + +### 4.2 Makefile + +Add targets that wrap Terraform through `make` so the invocation stays +consistent with the rest of the repo: + +```make +tf-init: + cd demo-server/infra && terraform init + +tf-plan: + make lib-build + cd demo-server/infra && terraform plan + +tf-apply: + make lib-build + cd demo-server/infra && terraform apply -auto-approve + +tf-destroy: + cd demo-server/infra && terraform destroy +``` + +`tf-apply` and `tf-plan` both depend on `make lib-build` so the +`dist/cf.js` they read via `file("${path.module}/../socket.io-serverless/dist/cf.js")` +is always fresh. This mirrors the current contract where +`make lib-build` must run before `wrangler deploy`. + +### 4.3 `demo-server/package.json` + +| Script | Current | After the switch | +|---|---|---| +| `deploy:cf` | `wrangler deploy` | `make tf-apply` (or `cd infra && terraform apply`) | +| `build:cf` | `wrangler deploy --dry-run --outdir ./build` | `make tf-plan` (validates config; does NOT bundle — bundling is now `make lib-build`'s job) | +| `dev:cf` | `wrangler dev` | **Unchanged** — keep `wrangler dev` for local dev (see §5) | + +`wrangler` would remain a `devDependency` for `wrangler dev` and `wrangler types` +even after the switch. The deploy-script would no longer call it. + +### 4.4 `.github/workflows/check.yaml` + +The "Build demo-server Worker (wrangler dry-run)" step would be replaced: + +```yaml +- name: Build demo-server Worker (terraform plan) + run: make tf-plan +``` + +…with the caveat that `terraform plan` calls the Cloudflare API to fetch +current remote state. Unlike `wrangler deploy --dry-run` which bundles and +validates locally without a network call, `terraform plan` requires +`CLOUDFLARE_API_TOKEN` to be present in CI secrets. A purely-local alternative +is `terraform validate` (does not hit the API, but also does not compare +against the deployed version). + +### 4.5 `wrangler.toml` + +Two options: + +- **(a)** Delete it and lose `wrangler dev` (not recommended — local dev + ergonomics are valuable). +- **(b)** Keep it for `wrangler dev` and `wrangler types` only. Accept that + `wrangler.toml` and `main.tf` describe the same Worker and must be kept in + sync by hand. + +Option (b) is the path the Cloudflare docs recommend for mixed setups. The +duplicated surface is small for this repo (2 DO bindings, 1 migration, 2 +compat flags) so the maintenance cost is low. + +## 5. Local development + +Terraform is deploy-only — it has no `wrangler dev` equivalent. Three ways +to keep local dev working: + +1. **Keep `wrangler dev`** (recommended). `wrangler dev` reads `wrangler.toml` + which you keep in the repo for this purpose. The Terraform path is used + only for `prod` / `staging` deploys. This is the cheapest option: no + duplication of effort, and the two configs only need to agree on bindings + and migrations (a small surface). + +2. **Use Miniflare directly** via a small `dev.mjs` script that imports + `@miniflare/core`. This drops the `wrangler` dependency entirely but + requires re-implementing what `wrangler dev` does (reload on file change, + bind the DO classes, honour the `[dev] port`). Not worth the effort for + this project. + +3. **Rely on the integration tests** (`pnpm run --filter ./demo-server test`). + The tests already run inside `workerd` via Miniflare and exercise the + full Worker → EngineActor → SocketActor pipeline. For pure code work + (not interactive debugging) this is sufficient. `wrangler dev` is still + useful for ad-hoc manual testing against a real WebSocket client. + +## 6. Durable Object migrations + +Wrangler's migration model is forgiving: you declare a `[[migrations]]` block +once, and `wrangler deploy` applies it idempotently. Removing the block (once +the DO classes exist on the account) has no effect. + +Terraform's `migrations` block is stricter: + +```hcl +migrations = { + old_tag = "v1" + new_tag = "v2" + new_classes = ["EngineActor", "SocketActor"] +} +``` + +- `old_tag` **must** match the remote current tag, or the upload is rejected. +- Bumping `old_tag → new_tag` is how you signal a new migration step. +- `class_name` renames require explicit `renamed_classes { from = "…" + to = "…" }` entries. +- Removing `migrations` from HCL is not harmful (the remote keeps its state), + but adding the block back with the wrong `old_tag` will fail the next + `terraform apply`. + +For this repo's current single `v1` migration with two classes, the overhead +is negligible. It becomes more meaningful when you introduce class renames +or SQLite-backed DOs (`new_sqlite_classes`). + +## 7. Things Terraform gives you that wrangler does not + +- **State drift detection.** `terraform plan` shows a diff if the deployed + Worker's bindings / compat flags / migrations have drifted from the HCL + (e.g. someone changed them via the dashboard). +- **Reasoned dependency ordering.** If you later add a KV namespace, R2 + bucket, or D1 database, those become separate `cloudflare_*` resources + that Terraform creates before the Worker in the same `apply`. With + `wrangler.toml` you create them out-of-band and paste IDs into the config. +- **Reusable modules.** The HCL can be packaged as a `module` and reused + across prod / staging / preview environments with different `var.*` + values. `wrangler.toml` has `--env` sections but no module system. +- **Reviewable deploys.** `terraform plan` output in a PR is a concrete + diff that a reviewer can read; `wrangler deploy --dry-run` output is + a bundle-size summary, not a config diff. + +## 8. Things you lose + +- **Zero-config bundling.** Wrangler reads `main = "src/cf/main.ts"`, + runs esbuild, and uploads. Terraform expects you to run `make lib-build` + first. (We already do this in CI — the `check.yaml` workflow runs + `make lib-build` before `build:cf` — but the contract becomes explicit.) +- **`wrangler types`.** Generates `worker-configuration.d.ts` from + bindings. Under TF, you'd maintain the `WorkerBindings` interface by + hand, which is already what `demo-server/src/cf/main.ts:68-73` does. +- **One-file config.** `wrangler.toml` is a single 25-line file. Terraform + requires `main.tf`, `variables.tf` (optional), `terraform.tfvars` + (recommended), and `terraform.tfstate` (gitignored). +- **Network-free dry-run.** `wrangler deploy --dry-run` works offline; + `terraform plan` calls the Cloudflare API to fetch current state. + +## 9. Reference HCL + +A minimal-but-complete `main.tf` for this repo as of socket.io@4.8.3: + +```hcl +terraform { + required_providers { + cloudflare = { + source = "cloudflare/cloudflare" + version = "~> 5" + } + } +} + +provider "cloudflare" { + # reads CLOUDFLARE_API_TOKEN from env +} + +variable "account_id" { + type = string + description = "Cloudflare account ID to deploy into" +} + +variable "script_name" { + type = string + default = "sio-serverless-demo" +} + +resource "cloudflare_workers_script" "demo" { + account_id = var.account_id + script_name = var.script_name + compatibility_date = "2024-08-21" + compatibility_flags = ["nodejs_compat_v2"] + + # The Worker source, bundled by `make lib-build` into dist/cf.js + main_module = "cf.js" + content = file("${path.module}/../../socket.io-serverless/dist/cf.js") + + bindings = [ + { + name = "engineActor" + type = "durable_object_namespace" + class_name = "EngineActor" + }, + { + name = "socketActor" + type = "durable_object_namespace" + class_name = "SocketActor" + }, + ] + + migrations = { + old_tag = "v1" + new_tag = "v1" + new_classes = ["EngineActor", "SocketActor"] + } + + observability = { + enabled = true + } +} +``` + +Run with: + +```bash +export CLOUDFLARE_API_TOKEN=… +export TF_VAR_account_id=… + +make lib-build # produce dist/cf.js +cd demo-server/infra +terraform init +terraform plan # diff against the deployed Worker +terraform apply # PUT the multipart to the Workers API +``` + +## 10. Recommended migration path + +1. Add `demo-server/infra/main.tf` alongside the existing `wrangler.toml`. +2. Add `make tf-plan` / `tf-apply` targets to the Makefile. +3. In CI, run `terraform validate` (no API needed) as part of `check.yaml`. + `"Build demo-server Worker"` step; promote to `terraform plan` once a + `CLOUDFLARE_API_TOKEN` secret is set on the repo. +4. Make `terraform apply` the deploy command for `staging` (off the + `opencode-ify` branch or a separate account). Smoke test. +5. Once comfortable, switch `deploy:cf` in `demo-server/package.json` from + `wrangler deploy` to `make tf-apply`. +6. Keep `wrangler.toml` indefinitely for `wrangler dev` and `wrangler types`. + The duplication between `wrangler.toml` and `main.tf` is two bindings and + one migration block — cheap to keep in sync by eye. \ No newline at end of file