diff --git a/.agents/skills/incur/SKILL.md b/.agents/skills/incur/SKILL.md new file mode 100644 index 0000000..6bb33bf --- /dev/null +++ b/.agents/skills/incur/SKILL.md @@ -0,0 +1,1045 @@ +--- +name: incur +description: incur is a TypeScript framework for building CLIs that work for both AI agents and humans. Use when creating new CLIs. +command: incur +--- + +# incur + +TypeScript framework for building CLIs for agents and human consumption. Strictly typed schemas for arguments and options, structured output envelopes, auto-generated skill files, and agent discovery via Skills, MCP, and `--llms`. + +## Install + +```sh +npm i incur +``` + +```sh +pnpm i incur +``` + +```sh +bun i incur +``` + +## Quick Start + +```ts +import { Cli, z } from 'incur' + +const cli = Cli.create('greet', { + description: 'A greeting CLI', + args: z.object({ + name: z.string().describe('Name to greet'), + }), + run({ args }) { + return { message: `hello ${args.name}` } + }, +}) + +cli.serve() +``` + +```sh +greet world +# → message: hello world +``` + +## Creating a CLI + +`Cli.create()` is the entry point. It has two modes: + +### Single-command CLI + +Pass `run` to create a CLI with no subcommands: + +```ts +const cli = Cli.create('tool', { + description: 'Does one thing', + args: z.object({ file: z.string() }), + run({ args, options }) { + return { processed: args.file } + }, +}) +``` + +### Router CLI (subcommands) + +Omit `run` to create a CLI that registers subcommands via `.command()`: + +```ts +const cli = Cli.create('gh', { + version: '1.0.0', + description: 'GitHub CLI', +}) + +cli.command('status', { + description: 'Show repo status', + run() { + return { clean: true } + }, +}) + +cli.serve() +``` + +## Commands + +### Registering commands + +```ts +cli.command('install', { + description: 'Install a package', + args: z.object({ + package: z.string().optional().describe('Package name'), + }), + options: z.object({ + saveDev: z.boolean().optional().describe('Save as dev dependency'), + global: z.boolean().optional().describe('Install globally'), + }), + alias: { saveDev: 'D', global: 'g' }, + output: z.object({ + added: z.number(), + packages: z.number(), + }), + examples: [ + { args: { package: 'express' }, description: 'Install a package' }, + { + args: { package: 'vitest' }, + options: { saveDev: true }, + description: 'Install as dev dependency', + }, + ], + run({ args, options }) { + return { added: 1, packages: 451 } + }, +}) +``` + +`.command()` is chainable — it returns the CLI instance: + +```ts +cli + .command('ping', { run: () => ({ pong: true }) }) + .command('version', { run: () => ({ version: '1.0.0' }) }) +``` + +### Subcommand groups + +Create a sub-CLI and mount it as a command group: + +```ts +const cli = Cli.create('gh', { description: 'GitHub CLI' }) + +const pr = Cli.create('pr', { description: 'Pull request commands' }) + +pr.command('list', { + description: 'List pull requests', + options: z.object({ + state: z.enum(['open', 'closed', 'all']).default('open'), + }), + run({ options }) { + return { prs: [], state: options.state } + }, +}) + +pr.command('view', { + description: 'View a pull request', + args: z.object({ number: z.number() }), + run({ args }) { + return { number: args.number, title: 'Fix bug' } + }, +}) + +// Mount onto the parent CLI +cli.command(pr) + +cli.serve() +``` + +```sh +gh pr list --state closed +gh pr view 42 +``` + +Groups nest arbitrarily: + +```ts +const cli = Cli.create('gh', { description: 'GitHub CLI' }) +const pr = Cli.create('pr', { description: 'Pull requests' }) +const review = Cli.create('review', { description: 'Review commands' }) + +review.command('approve', { run: () => ({ approved: true }) }) +pr.command(review) +cli.command(pr) +// → gh pr review approve +``` + +### Fetch API + +Mount an HTTP server as a command with `.command('name', { fetch })`. Argv is translated into HTTP requests using curl-style flags: + +```ts +import { Cli } from 'incur' +import { Hono } from 'hono' + +const app = new Hono() +app.get('/users', (c) => c.json({ users: [{ id: 1, name: 'Alice' }] })) +app.post('/users', async (c) => c.json({ created: true, ...(await c.req.json()) }, 201)) + +Cli.create('my-cli', { description: 'My CLI' }).command('api', { fetch: app.fetch }).serve() +``` + +```sh +my-cli api users # GET /users +my-cli api users -X POST -d '{"name":"Bob"}' # POST /users +my-cli api users --limit 5 # GET /users?limit=5 +``` + +### Fetch API + OpenAPI + +Pass an OpenAPI spec alongside `fetch` to generate typed subcommands with args, options, and descriptions from the spec: + +```ts +Cli.create('my-cli', { description: 'My CLI' }) + .command('api', { fetch: app.fetch, openapi: spec }) + .serve() +``` + +```sh +my-cli api listUsers --limit 5 # GET /users?limit=5 +my-cli api getUser 42 # GET /users/42 +my-cli api createUser --name Bob # POST /users with body +my-cli api --help # shows typed subcommands +``` + +Works with any `(Request) => Response` handler — Hono, Elysia, etc. Specs from `@hono/zod-openapi` are supported directly. + +### Serve CLI as Fetch API + +Expose your CLI as a standard Fetch API handler with `cli.fetch`. Works with Bun, Cloudflare Workers, Deno, Hono, and anything that accepts `(req: Request) => Response`. + +```ts +import { Cli, z } from 'incur' + +const cli = Cli.create('my-cli', { version: '1.0.0' }).command('users', { + args: z.object({ id: z.coerce.number().optional() }), + options: z.object({ limit: z.coerce.number().default(10) }), + run(c) { + if (c.args.id) return { id: c.args.id, name: 'Alice' } + return { users: [{ id: 1, name: 'Alice' }], limit: c.options.limit } + }, +}) +``` + +```ts +Bun.serve(cli) // Bun +Deno.serve(cli.fetch) // Deno +export default cli // Cloudflare Workers +app.all('*', (c) => cli.fetch(c.request)) // Elysia +app.use((c) => cli.fetch(c.req.raw)) // Hono +export const GET = cli.fetch // Next.js +export const POST = cli.fetch +``` + +Request mapping: + +| HTTP | CLI equivalent | +| ---------------------------- | ---------------------------------- | +| `GET /users?limit=5` | `my-cli users --limit 5` | +| `GET /users/42` | `my-cli users 42` (positional arg) | +| `POST /users` with JSON body | `my-cli users --name Bob` | +| `GET /` | root command (or 404) | + +Responses are JSON envelopes: `{ "ok": true, "data": { ... }, "meta": { "command": "users", "duration": "3ms" } }`. + +Error status codes: 400 for validation errors, 404 for unknown commands, 500 for thrown errors. + +Async generator commands stream as NDJSON (`application/x-ndjson`). Middleware runs the same as `serve()`. + +#### Fetch gateways + +If a resolved command is a fetch gateway (`.command('api', { fetch })`), the request is forwarded to the nested handler. + +#### MCP over HTTP + +The fetch handler exposes an MCP endpoint at `/mcp`. Agents can discover and call commands as MCP tools over HTTP: + +``` +POST /mcp { "jsonrpc": "2.0", "method": "initialize", ... } +POST /mcp { "jsonrpc": "2.0", "method": "tools/list", ... } +POST /mcp { "jsonrpc": "2.0", "method": "tools/call", "params": { "name": "users", ... } } +``` + +The MCP server is initialized lazily on the first `/mcp` request. Non-`/mcp` paths route to the command API as usual. + +## Arguments & Options + +All schemas use Zod. Arguments are positional (assigned by schema key order). Options are named flags. + +### Arguments + +```ts +args: z.object({ + repo: z.string().describe('Repository in owner/repo format'), + branch: z.string().optional().describe('Branch name'), +}) +``` + +```sh +tool clone owner/repo main +# ^^^^^^^^^^ ^^^^ +# repo branch +``` + +### Options + +```ts +options: z.object({ + state: z.enum(['open', 'closed']).default('open').describe('Filter by state'), + limit: z.number().default(30).describe('Max results'), + label: z.array(z.string()).optional().describe('Filter by labels'), + verbose: z.boolean().optional().describe('Show details'), +}) +``` + +Supported parsing: + +- `--flag value` and `--flag=value` +- `-f value` short aliases (via `alias` property) +- `--verbose` boolean flags (`true`), `--no-verbose` (`false`) +- `--label bug --label feature` array options +- Automatic type coercion (string → number, string → boolean) +- Defaults from `.default()`, optionality from `.optional()` + +### Aliases + +```ts +alias: { state: 's', limit: 'l' } +``` + +```sh +tool list -s closed -l 10 +``` + +### Deprecated options + +Mark options as deprecated with `.meta({ deprecated: true })`. Shows `[deprecated]` in `--help`, `**Deprecated.**` in skill docs, `deprecated: true` in JSON Schema, and emits a stderr warning in TTY mode: + +```ts +options: z.object({ + zone: z.string().optional().describe('Availability zone').meta({ deprecated: true }), + region: z.string().optional().describe('Target region'), +}) +``` + +### Environment variables + +```ts +env: z.object({ + NPM_TOKEN: z.string().optional().describe('Auth token'), + NPM_REGISTRY: z.string().default('https://registry.npmjs.org').describe('Registry URL'), +}) +``` + +Environment variables are parsed from `process.env` and validated against the Zod schema. + +### Usage patterns + +Define alternative usage patterns to show in `--help` instead of the auto-generated synopsis: + +```ts +Cli.create('curl.md', { + args: z.object({ url: z.string() }), + options: z.object({ objective: z.string().optional() }), + usage: [ + { args: { url: true } }, + { args: { url: true }, options: { objective: true } }, + { prefix: 'cat file.txt |', suffix: '| head' }, + ], + run({ args }) { + return { content: '...' } + }, +}) +``` + +Renders in help as: + +``` +Usage: curl.md + curl.md --objective + cat file.txt | curl.md | head +``` + +Each usage entry supports: + +| Property | Type | Description | +| --------- | ---------------------------- | ------------------------------------------------ | +| `args` | `Partial>` | Argument keys to include as `` placeholders | +| `options` | `Partial>` | Option keys to include as `--key ` flags | +| `prefix` | `string` | Text prepended before the command (e.g. piping) | +| `suffix` | `string` | Text appended after the command | + +Both `args` and `options` are strictly typed from the Zod schemas — only valid keys are allowed. + +Usage patterns also work on subcommands via `.command()`. + +## Output + +Every command returns data. incur wraps it in a structured envelope and serializes to the requested format. + +### Output schema + +Define `output` to declare the return shape: + +```ts +cli.command('info', { + output: z.object({ + name: z.string(), + version: z.string(), + }), + run() { + return { name: 'express', version: '4.21.2' } + }, +}) +``` + +When `output` is provided, TypeScript enforces that `run()` returns the correct shape. + +### Formats + +Control with `--format ` or `--json`: + +| Flag | Format | Description | +| --------------- | -------- | -------------------------------------------- | +| _(default)_ | TOON | Token-efficient, ~40% fewer tokens than JSON | +| `--format json` | JSON | `JSON.parse()`-safe | +| `--format yaml` | YAML | Human-readable | +| `--format md` | Markdown | Tables for docs/issues | + +### Envelope + +With `--full-output`, the full envelope is emitted: + +```sh +tool info express --full-output +``` + +``` +ok: true +data: + name: express + version: 4.21.2 +meta: + command: info + duration: 12ms +``` + +Without `--full-output`, only `data` is emitted. On errors, only the `error` block is emitted. + +### Filtering output + +Use `--filter-output` to prune command output to specific keys. Supports dot-notation for nested access, array slices with `[start,end]`, and comma-separated paths: + +```ts +cli.command('users', { + description: 'List users', + run() { + return { + users: [ + { name: 'Alice', email: 'alice@example.com', role: 'admin' }, + { name: 'Bob', email: 'bob@example.com', role: 'user' }, + { name: 'Carol', email: 'carol@example.com', role: 'user' }, + ], + } + }, +}) +``` + +```sh +tool users --filter-output users.name +# → [3]: Alice,Bob,Carol + +tool users --filter-output users[0,2].name +# → users[2]{name}: +# → Alice +# → Bob +``` + +### Token pagination + +Use `--token-count`, `--token-limit`, and `--token-offset` to manage large outputs. Tokens are estimated using LLM tokenization rules (~96% accuracy). + +```sh +# Check token count +tool users --token-count +# → 42 + +# Limit to first 20 tokens +tool users --token-limit 20 + +# Paginate with offset +tool users --token-offset 20 --token-limit 20 +``` + +With `--full-output`, truncated output includes `meta.nextOffset` for programmatic pagination. + +### Command schema + +Use `--schema` to print the JSON Schema for a command's arguments, environment variables, options, and output: + +```ts +cli.command('install', { + description: 'Install a package', + args: z.object({ + package: z.string().describe('Package name'), + }), + options: z.object({ + saveDev: z.boolean().optional().describe('Save as dev dependency'), + }), + run({ args }) { + return { added: 1 } + }, +}) +``` + +```sh +tool install --schema +# → args: +# → type: object +# → properties: +# → package: +# → type: string +# → options: +# → type: object +# → properties: +# → saveDev: +# → type: boolean +``` + +Use `--schema --format json` for machine-readable output. Not supported on fetch commands. + +### TTY detection + +incur adapts output based on whether stdout is a TTY: + +| Scenario | TTY (human) | Non-TTY (agent/pipe) | +| --------------------- | ----------------------- | -------------------- | +| Command output | Formatted data only | TOON envelope | +| Errors | Human-readable message | Error envelope | +| `--help` | Pretty help text | Same | +| `--json` / `--format` | Overrides to structured | Same | + +## Run Context + +### `agent` boolean + +The `run` context includes `agent` — `true` when stdout is not a TTY (piped or consumed by an agent), `false` when running in a terminal: + +```ts +cli.command('deploy', { + run(c) { + if (!c.agent) console.log('Deploying...') + return { status: 'ok' } + }, +}) +``` + +### `ok()` and `error()` helpers + +Use the context helpers for explicit result control: + +```ts +run(c) { + const item = await db.find(c.args.id) + if (!item) + return error({ + code: 'NOT_FOUND', + message: `Item ${c.args.id} not found`, + retryable: false, + }) + return c.ok(item) +} +``` + +### CTAs (Call to Action) + +Suggest next commands to guide agents on success: + +```ts +run(c) { + const result = { id: 42, name: c.args.name } + return c.ok(result, { + cta: { + description: 'Suggested commands:', + commands: [ + { command: 'get', args: { id: 42 }, description: 'View the item' }, + 'list', + ], + }, + }) +} +``` + +Or on errors, to help agents self-correct: + +```ts +run(c) { + const token = process.env.GH_TOKEN + if (!token) + return c.error({ + code: 'NOT_AUTHENTICATED', + message: 'GitHub token not found', + retryable: true, + cta: { + description: 'To authenticate:', + commands: [ + { command: 'auth login', description: 'Log in to GitHub' }, + { command: 'config set', options: { token: true }, description: 'Set token manually' }, + ], + }, + }) + // ... +} +``` + +## Agent Discovery + +### MCP Server + +Every incur CLI has built-in Model Context Protocol (MCP) support — exposing commands as MCP tools that agents can call directly. + +#### `mcp add` built-in command + +Register the CLI as an MCP server for your agents: + +```sh +my-cli mcp add +``` + +This registers the CLI with your agent's MCP config. Works with Claude Code, Cursor, Amp, and others out of the box. + +Options: + +| Flag | Description | +| ----------------- | -------------------------------------------------------- | +| `-c`, `--command` | Override the command agents will run to start the server | +| `--agent ` | Target a specific agent (e.g. `claude-code`, `cursor`) | +| `--no-global` | Install to project instead of globally | + +#### `--mcp` flag + +Start the CLI as an MCP stdio server: + +```sh +my-cli --mcp +``` + +This exposes all commands as MCP tools over stdin/stdout. Command groups are flattened with underscores (e.g. `pr_list`, `pr_view`). Arguments and options are merged into a single flat input schema. + +### Skills + +All incur-based CLIs can auto-generate and install agent skill files with `skills add`: + +```sh +my-cli skills add +``` + +This generates Markdown skill files from your command definitions and installs them so agents discover your CLI automatically. + +#### Configuration + +It is also possible to configure `skills add`: + +```ts +const cli = Cli.create('my-cli', { + sync: { + depth: 1, + include: ['_root'], + suggestions: ['install react as a dependency', 'check for outdated packages'], + }, +}) +``` + +| Option | Type | Description | +| ------------- | ---------- | ---------------------------------------------------------------------------------------------------- | +| `depth` | `number` | Grouping depth for skill files. `0` = single file, `1` = one per top-level command. Default: `1` | +| `include` | `string[]` | Glob patterns for additional SKILL.md files to include. Use `'_root'` for the project-level SKILL.md | +| `suggestions` | `string[]` | Example prompts shown after sync to help users get started | + +### `--llms` flag + +Every incur CLI gets a built-in `--llms` flag that outputs a machine-readable manifest of all commands: + +```sh +tool --llms +``` + +Outputs Markdown skill documentation by default. + +```md +# tool install + +Install a package + +## Arguments + +| Name | Type | Required | Description | +| --------- | -------- | -------- | ----------------------- | +| `package` | `string` | no | Package name to install | + +## Options + +| Flag | Type | Default | Description | +| ----------- | --------- | ------- | ---------------------- | +| `--saveDev` | `boolean` | | Save as dev dependency | +| `--global` | `boolean` | | Install globally | +``` + +Use `--llms --format json` for JSON schema manifest: + +```json +{ + "version": "incur.v1", + "commands": [ + { + "name": "install", + "description": "Install a package", + "schema": { + "args": { "type": "object", "properties": { "package": { "type": "string" } } }, + "options": { "type": "object", "properties": { "saveDev": { "type": "boolean" } } }, + "output": { "type": "object", "properties": { "added": { "type": "number" } } } + } + } + ] +} +``` + +## Built-in Flags + +| Flag | Description | +| ---------------- | -------------------------------------------- | +| `--help`, `-h` | Show help for the CLI or a specific command | +| `--version` | Print CLI version | +| `--llms` | Output agent-readable command manifest | +| `--mcp` | Start as an MCP stdio server | +| `--json` | Shorthand for `--format json` | +| `--format ` | Output format: `toon`, `json`, `yaml`, `md` | +| `--full-output` | Include full envelope (`ok`, `data`, `meta`) | + +## Examples + +### Typed examples on commands + +```ts +cli.command('deploy', { + args: z.object({ env: z.enum(['staging', 'production']) }), + options: z.object({ force: z.boolean().optional() }), + examples: [ + { args: { env: 'staging' }, description: 'Deploy to staging' }, + { args: { env: 'production' }, options: { force: true }, description: 'Force deploy to prod' }, + ], + run({ args }) { + return { deployed: args.env } + }, +}) +``` + +Examples appear in `--help` output and generated skill files. + +### Hints + +```ts +cli.command('publish', { + hint: 'Requires NPM_TOKEN to be set in your environment.', + // ... +}) +``` + +Hints are displayed after examples in help output and included in skill files. + +### Output policy + +Control whether output data is displayed to humans. `'all'` (default) shows output to everyone. `'agent-only'` suppresses data in human/TTY mode while still returning it via `--json`, `--format`, or `--full-output`. + +```ts +cli.command('deploy', { + outputPolicy: 'agent-only', + run() { + return { id: 'deploy-123', url: 'https://staging.example.com' } + }, +}) +``` + +Set on a group or root CLI to inherit across children. Children can override: + +```ts +const sub = Cli.create('internal', { outputPolicy: 'agent-only' }) +sub.command('sync', { run: () => ({ synced: true }) }) // inherits agent-only +sub.command('status', { outputPolicy: 'all', run: () => ({}) }) // overrides +``` + +## Middleware + +Register composable before/after hooks with `cli.use()`. Middleware executes in registration order, onion-style. Each calls `await next()` to proceed. + +```ts +const cli = Cli.create('deploy-cli', { description: 'Deploy tools' }) + .use(async (c, next) => { + const start = Date.now() + await next() + console.log(`took ${Date.now() - start}ms`) + }) + .command('deploy', { + run() { + return { deployed: true } + }, + }) +``` + +```sh +$ deploy-cli deploy +# → deployed: true +# took 12ms +``` + +Middleware on a sub-CLI only applies to its commands: + +```ts +const admin = Cli.create('admin', { description: 'Admin commands' }) + .use(async (c, next) => { + if (!isAdmin()) throw new Error('forbidden') + await next() + }) + .command('reset', { run: () => ({ reset: true }) }) + +cli.command(admin) // middleware only runs for `my-cli admin reset` +``` + +```sh +$ my-cli admin reset +# → reset: true + +$ my-cli other-cmd +# middleware does not run +``` + +Per-command middleware runs after root and group middleware, and only for that command: + +```ts +import { Cli, middleware, z } from 'incur' + +const cli = Cli.create('my-cli', { + description: 'My CLI', + vars: z.object({ user: z.custom<{ id: string }>() }), +}) + +const requireAuth = middleware((c, next) => { + if (!c.var.user) throw new Error('must be logged in') + return next() +}) + +cli.command('deploy', { + middleware: [requireAuth], + run() { + return { deployed: true } + }, +}) +``` + +```sh +$ my-cli deploy +# Error: must be logged in + +$ my-cli other-cmd +# per-command middleware does not run +``` + +### Vars — typed dependency injection + +Declare a `vars` schema on `create()` to inject typed variables. Middleware sets them with `c.set()`, handlers read them via `c.var`. Use `.default()` for vars that don't need middleware: + +```ts +const cli = Cli.create('my-cli', { + description: 'My CLI', + vars: z.object({ + user: z.custom<{ id: string; name: string }>(), + requestId: z.string(), + debug: z.boolean().default(false), + }), +}) + +cli.use(async (c, next) => { + c.set('user', await authenticate()) + c.set('requestId', crypto.randomUUID()) + await next() +}) + +cli.command('whoami', { + run(c) { + return { user: c.var.user, requestId: c.var.requestId, debug: c.var.debug } + }, +}) +``` + +```sh +$ my-cli whoami +# → user: +# → id: u_123 +# → name: Alice +# → requestId: 550e8400-e29b-41d4-a716-446655440000 +# → debug: false +``` + +Middleware does **not** run for built-in commands (`--help`, `--llms`, `--mcp`, `mcp add`, `skills add`). + +## Serving + +Call `.serve()` to parse `process.argv` and run: + +```ts +cli.serve() +``` + +For testing, pass custom argv and DI overrides: + +```ts +let output = '' +await cli.serve(['install', 'express', '--json'], { + stdout(s) { + output += s + }, + exit() {}, +}) +``` + +### `serve()` options + +| Option | Type | Description | +| -------- | ------------------------------------- | ------------------------------ | +| `stdout` | `(s: string) => void` | Override stdout writer | +| `exit` | `(code: number) => void` | Override exit handler | +| `env` | `Record` | Override environment variables | + +### `cli.fetch(req: Request): Promise` + +Expose the CLI as a Fetch API handler. See [Serve CLI as Fetch API](#serve-cli-as-fetch-api) for full details. + +```ts +Bun.serve(cli) +``` + +## Streaming + +Use `async *run` to stream chunks incrementally. Yield objects for structured data or plain strings for text: + +```ts +cli.command('logs', { + description: 'Tail logs', + async *run() { + yield 'connecting...' + yield 'streaming logs' + yield 'done' + }, +}) +``` + +Each yielded value is written as a line in human/TOON mode. With `--format jsonl`, each chunk becomes `{"type":"chunk","data":"..."}`. You can also yield objects: + +```ts +async *run() { + yield { progress: 50 } + yield { progress: 100 } +} +``` + +Use `ok()` or `error()` as the return value to attach CTAs or signal failure: + +```ts +async *run({ ok }) { + yield { step: 1 } + yield { step: 2 } + return ok(undefined, { cta: { commands: ['status'] } }) +} +``` + +## Type Generation + +Generate type definitions for your CLI's command map to get typed CTAs: + +```sh +incur gen +``` + +This creates a `incur.generated.ts` file that registers your commands on the `Cli.Commands` type, enabling autocomplete on CTA command names, args, and options. + +## Full Example + +```ts +import { Cli, z } from 'incur' + +const cli = Cli.create('npm', { + version: '10.9.2', + description: 'The package manager for JavaScript.', + sync: { + suggestions: ['install react as a dependency', 'check for outdated packages'], + }, +}) + +cli.command('install', { + description: 'Install a package', + args: z.object({ + package: z.string().optional().describe('Package name to install'), + }), + options: z.object({ + saveDev: z.boolean().optional().describe('Save as dev dependency'), + global: z.boolean().optional().describe('Install globally'), + }), + alias: { saveDev: 'D', global: 'g' }, + output: z.object({ + added: z.number().describe('Number of packages added'), + packages: z.number().describe('Total packages'), + }), + examples: [ + { args: { package: 'express' }, description: 'Install a package' }, + { + args: { package: 'vitest' }, + options: { saveDev: true }, + description: 'Install as dev dependency', + }, + ], + run({ args }) { + if (!args.package) return { added: 120, packages: 450 } + return { added: 1, packages: 451 } + }, +}) + +cli.command('outdated', { + description: 'Check for outdated packages', + options: z.object({ + global: z.boolean().describe('Check global packages'), + }), + alias: { global: 'g' }, + output: z.object({ + packages: z.array( + z.object({ + name: z.string(), + current: z.string(), + wanted: z.string(), + latest: z.string(), + }), + ), + }), + run() { + return { + packages: [{ name: 'express', current: '4.18.0', wanted: '4.21.2', latest: '4.21.2' }], + } + }, +}) + +cli.serve() + +export default cli +``` + +> Always `export default cli` so that `incur gen` can import it and generate types. diff --git a/.vscode/settings.json b/.vscode/settings.json index 24ab77e..21089a7 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -32,5 +32,6 @@ "[mdx]": { "editor.defaultFormatter": "DavidAnson.vscode-markdownlint" }, - "markdown.validate.enabled": false + "markdown.validate.enabled": false, + "typescript.tsdk": "node_modules/typescript/lib" } diff --git a/apps/ponder/package.json b/apps/ponder/package.json index 057e0d3..5667641 100644 --- a/apps/ponder/package.json +++ b/apps/ponder/package.json @@ -26,7 +26,7 @@ "devDependencies": { "@biomejs/biome": "catalog:", "@types/node": "catalog:", - "drizzle-orm": "catalog:", + "drizzle-orm": "^0.45.2", "typescript": "catalog:" } } diff --git a/package.json b/package.json index cf8cff4..fe90765 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,6 @@ "lint:fix": "biome check --fix .", "test": "pnpm -r --filter='./packages/*' --if-present run test", "check:repo": "pnpx sherif@latest -r root-package-manager-field", - "update:msw": "pnpm -r --filter='./packages/*' --if-present run update:msw", "clean": "rm -rf node_modules pnpm-lock.yaml package-lock.json packages/*/{.wireit,pnpm-lock.yaml,package-lock.json,dist,node_modules} apps/*/{.wireit,pnpm-lock.yaml,package-lock.json,dist,node_modules}", "clean:cache": "rm -rf packages/*/{.wireit,dist} apps/*/{.wireit,dist}" }, @@ -20,15 +19,6 @@ "typescript": "catalog:", "wireit": "^0.14.12" }, - "pnpm": { - "overrides": { - "@hono/node-server": "^1.19.13", - "drizzle-orm": "^0.45.2", - "esbuild": "^0.25.0", - "kysely": "^0.28.14", - "vite": "^6.4.2" - } - }, "packageManager": "pnpm@10.33.0", "devEngines": { "runtime": { diff --git a/packages/repair-cli/AGENTS.md b/packages/repair-cli/AGENTS.md new file mode 100644 index 0000000..4972406 --- /dev/null +++ b/packages/repair-cli/AGENTS.md @@ -0,0 +1,22 @@ +# Early repair CLI (`@filoz/repair-cli`) + +CLI for preparing and running early repair jobs that move pieces away from a faulty Filecoin service provider and into a target PDP provider. + +The package is built with [incur](https://www.npmjs.com/package/incur), Drizzle ORM, and `@filoz/synapse-core`. It uses the indexer Postgres database as a read-only catalog of providers, datasets, and pieces, plus a local SQLite database for repair jobs and per-piece operation state. + +## Conventions + +- Prefer existing command, middleware, and DB helper patterns over new abstractions. +- Extract reusable indexer queries and local database mutations under `src/db/`. +- Keep command files focused on CLI arguments, context wiring, and response shaping. +- Add JSDoc on exported functions/types; use inline comments only for non-obvious logic such as dedupe, pagination, or on-chain state sync. +- Repairs use one IPFS-enabled target dataset with CDN disabled. Do not add per-operation dataset grouping. +- Use `contextMiddleware` for commands that need config, wallet client, indexer DB, or local DB access. +- Do not document or preserve compatibility with unshipped in-progress behavior; update docs to match the current implementation. + +## Build And Lint + +```bash +pnpm --filter @filoz/repair-cli build +pnpm --filter @filoz/repair-cli lint +``` diff --git a/packages/repair-cli/package.json b/packages/repair-cli/package.json index b66e5b0..426bf5e 100644 --- a/packages/repair-cli/package.json +++ b/packages/repair-cli/package.json @@ -102,26 +102,34 @@ ] } }, - "dependencies": {}, + "dependencies": { + "@clack/prompts": "^1.5.1", + "@filoz/repair-db": "workspace:*", + "@filoz/synapse-core": "^0.6.0", + "@libsql/client": "^0.17.3", + "conf": "^15.1.0", + "drizzle-kit": "^0.31.10", + "drizzle-orm": "catalog:", + "incur": "^0.4.6", + "iso-base": "^4.4.0", + "iso-web": "^3.1.2", + "p-all": "^5.0.1", + "p-locate": "^7.0.0", + "p-map": "^7.0.4", + "p-queue": "^9.3.0", + "pg": "^8.21.0", + "terminal-link": "^5.0.0" + }, "devDependencies": { "@biomejs/biome": "catalog:", - "@types/assert": "^1.5.11", - "@types/mocha": "catalog:", "@types/node": "catalog:", - "assert": "^2.1.0", - "mocha": "catalog:", - "msw": "catalog:", + "@types/pg": "^8.20.0", "playwright-test": "^14.1.12", - "type-fest": "^5.4.3", + "type-fest": "^5.7.0", "typescript": "catalog:", "viem": "catalog:" }, "publishConfig": { "access": "public" - }, - "msw": { - "workerDirectory": [ - "test/mocks" - ] } } diff --git a/packages/repair-cli/readme.md b/packages/repair-cli/readme.md index 1cc0d0f..4f74874 100644 --- a/packages/repair-cli/readme.md +++ b/packages/repair-cli/readme.md @@ -4,15 +4,243 @@ > Early repair for faulty service providers and datasets +The `repair` CLI helps prepare and run repair jobs that move pieces away from a faulty Filecoin service provider and into a target PDP provider. It uses: + +- an indexer Postgres database as the read-only source of providers, datasets, and pieces +- a local SQLite database to track repair jobs and per-piece operations +- a configured Filecoin wallet to create datasets and submit on-chain add-piece transactions + ## Installation ```bash -pnpm install @filoz/repair-cli +pnpm add -g @filoz/repair-cli +``` + +The package exposes the `repair` binary. + +```bash +repair --help +``` + +## Setup + +Run setup before using any command that talks to the indexer, local database, or wallet. + +```bash +repair setup +``` + +Setup prompts for: + +- private key for the repair wallet +- mainnet indexer Postgres URL +- calibration indexer Postgres URL +- chain, either Filecoin Mainnet `314` or Filecoin Calibration `314159` +- local SQLite database path + +The command stores these values in the CLI config and runs the local SQLite schema migration. It returns the configured wallet address. + +Most commands also accept: + +```bash +--debug +``` + +Use `--debug` when you want extra error output from wallet operations. + +## Command Reference + +### `repair setup` + +Interactive configuration and local database setup. + +```bash +repair setup +``` + +Use this whenever you need to initialize the CLI, change the active chain, update indexer URLs, or move the local SQLite database. + +### `repair wallet fund` + +Funds the configured wallet from the Filecoin Calibration faucet. + +```bash +repair wallet fund +``` + +This command only works on Calibration. It claims faucet tokens, waits for the transaction to be mined, and returns the wallet address and FIL balance. + +### `repair wallet balance` + +Shows wallet and payment account balances. + +```bash +repair wallet balance +``` + +The output includes the wallet address, FIL balance, USDFC balance, and Filecoin Pay account summary fields such as funds, available funds, debt, lockup rates, lockup totals, runway, and current epoch. + +### `repair wallet deposit ` + +Deposits USDFC from the configured wallet into the wallet's Filecoin Pay account. + +```bash +repair wallet deposit 100 +``` + +`amount` is a positive USDFC amount. The command submits the deposit and approval transaction, then waits for it to be mined. + +### `repair wallet withdraw ` + +Withdraws USDFC from the wallet's Filecoin Pay account. + +```bash +repair wallet withdraw 25 +``` + +`amount` is a positive USDFC amount. The command submits the withdraw transaction and waits for it to be mined. + +### `repair providers list` + +Lists PDP providers from the configured indexer. + +```bash +repair providers list +``` + +By default, the command returns active PDP providers that are approved or endorsed. Each provider includes: + +- `id` +- `name` +- `serviceUrl` +- `approved` +- `endorsed` +- `pieceCount`, the number of active indexed pieces for that provider +- `totalSize`, the sum of active piece raw sizes formatted in decimal GB + +Use `--all` to include every active PDP provider, even if it is not approved or endorsed. + +```bash +repair providers list --all +``` + +### `repair datasets list` + +Lists datasets owned by the configured repair wallet. + +```bash +repair datasets list +``` + +Each dataset includes its ID, CDN/IPFS indexing flags, source, provider URL, PDP end epoch, and piece count. + +Filter by provider ID: + +```bash +repair datasets list --provider-id 123 +``` + +### `repair repair create` + +Creates a local repair plan for a source provider and a target provider. + +```bash +repair repair create --provider-id 101 --target-provider-id 202 +``` + +`--provider-id` is the faulty provider whose pieces should be repaired. + +`--target-provider-id` is the provider that should receive the repaired pieces. It must be different from `--provider-id`. + +The command snapshots the current chain block number, creates a local repair row, scans active pieces for the source provider, deduplicates them by CID, and creates local `add_piece` operations. Pieces with no alternate provider are marked `skipped`. The command returns a `repairId`. + +### `repair repair list` + +Lists local repair jobs. + +```bash +repair repair list +``` + +Each repair includes: + +- repair ID and status +- source provider ID +- target provider ID and target provider URL +- target dataset ID, when one has been created or found +- block number used when the repair was created +- total operations and counts by `pending`, `failed`, `completed`, and `skipped` + +### `repair repair run ` + +Runs a pending repair. + +```bash +repair repair run 1 +``` + +The command first ensures the target repair dataset exists for the configured wallet and target provider. If no matching dataset exists, it creates one with IPFS indexing enabled and CDN disabled. Then it processes pending `add_piece` operations by pulling pieces from alternate providers into the target provider and committing them on-chain. + +Options: + +- `--concurrency ` controls how many pull batches run at once. Defaults to `4`. +- `--batch-size ` controls the maximum number of `add_piece` operations per batch. Defaults to `40`. +- `--reset` retries failed `add_piece` operations as well as pending operations. + +Example: + +```bash +repair repair run 1 --concurrency 8 --batch-size 100 --reset +``` + +### `repair repair delete ` + +Deletes a local repair and its operations. + +```bash +repair repair delete 1 +``` + +This only deletes local SQLite state. It does not delete on-chain datasets or remove pieces from a provider. + +## Typical Workflow + +1. Configure the CLI. + +```bash +repair setup +``` + +1. On Calibration, fund the wallet if needed. + +```bash +repair wallet fund +``` + +1. Check balances and deposit USDFC into the payment account. + +```bash +repair wallet balance +repair wallet deposit 100 +``` + +1. Pick source and target providers. + +```bash +repair providers list +``` + +1. Create, inspect, and run the repair. + +```bash +repair repair create --provider-id 101 --target-provider-id 202 +repair repair list +repair repair run 1 ``` ## Contributing -Read contributing [guidelines](../../.github/CONTRIBUTING.md). +Read contributing [guidelines](../../.github/CONTRIBUTING.md). [![Open in GitHub Codespaces](https://github.com/codespaces/badge.svg)](https://codespaces.new/FilOzone/early-repair) diff --git a/packages/repair-cli/src/cli.ts b/packages/repair-cli/src/cli.ts old mode 100644 new mode 100755 index 70b786d..a74846f --- a/packages/repair-cli/src/cli.ts +++ b/packages/repair-cli/src/cli.ts @@ -1 +1,20 @@ -// TODO +#!/usr/bin/env node +import { Cli } from 'incur' +import { datasets } from './commands/datasets.ts' +import { providers } from './commands/providers.ts' +import { repair } from './commands/repair.ts' +import { setup } from './commands/setup.ts' +import { wallet } from './commands/wallet.ts' +import { version } from './utils.ts' + +const cli = Cli.create('repair', { + version, + description: 'Early repair for faulty service providers and datasets', +}) + +cli.command(setup) +cli.command(wallet) +cli.command(repair) +cli.command(datasets) +cli.command(providers) +cli.serve() diff --git a/packages/repair-cli/src/commands/datasets.ts b/packages/repair-cli/src/commands/datasets.ts new file mode 100644 index 0000000..3bf9b89 --- /dev/null +++ b/packages/repair-cli/src/commands/datasets.ts @@ -0,0 +1,62 @@ +import { and, eq } from 'drizzle-orm' +import { Cli, z } from 'incur' +import { contextMiddleware, contextSchema } from '../middleware.ts' +import { globalOptions } from '../utils.ts' +export const datasets = Cli.create('datasets', { + description: 'Dataset commands', + options: globalOptions, + vars: contextSchema, +}) + +datasets.command('list', { + description: 'List all datasets owned by the repair wallet', + options: globalOptions.extend({ + providerId: z.coerce.bigint().optional().describe('Filter datasets by provider ID'), + }), + middleware: [contextMiddleware], + run: async (c) => { + try { + const schema = c.var.indexerDb._.fullSchema + const conditions = [ + eq(schema.dataSets.deleted, false), + eq(schema.dataSets.payer, c.var.client.account.address.toLowerCase()), + ] + if (c.options.providerId != null) { + conditions.push(eq(schema.dataSets.providerId, c.options.providerId)) + } + + const datasets = await c.var.indexerDb.query.dataSets.findMany({ + where: and(...conditions), + with: { + provider: true, + pieces: true, + }, + }) + + const datasetsFlattened = datasets.map((dataset) => { + const { provider, pieces } = dataset + return { + id: dataset.dataSetId, + withCdn: dataset.withCdn, + withIpfsIndexing: dataset.withIpfsIndexing, + source: dataset.source, + provider: provider.serviceUrl, + pdpEndEpoch: dataset.pdpEndEpoch, + pieces: pieces.length, + // metadata: JSON.stringify(dataset.metadata), + } + }) + + return c.ok({ + datasets: datasetsFlattened, + }) + } catch (error) { + console.error(error) + return c.error({ + code: 'DATASETS_FAILED', + message: error instanceof Error ? error.message : 'Failed to list datasets', + retryable: true, + }) + } + }, +}) diff --git a/packages/repair-cli/src/commands/providers.ts b/packages/repair-cli/src/commands/providers.ts new file mode 100644 index 0000000..c3e791d --- /dev/null +++ b/packages/repair-cli/src/commands/providers.ts @@ -0,0 +1,99 @@ +import { and, asc, count, eq, inArray, isNull, lte, or, type SQLWrapper, sum } from 'drizzle-orm' +import { Cli, z } from 'incur' +import { getBlockNumber } from 'viem/actions' +import { contextMiddleware, contextSchema } from '../middleware.ts' +import { globalOptions } from '../utils.ts' + +/** Format byte count as decimal gigabytes with two fractional digits. */ +function formatBytesAsGb(bytes: bigint): string { + const scaled = (bytes * 100n) / 1_000_000_000n + const whole = scaled / 100n + const fraction = scaled % 100n + return `${whole}.${fraction.toString().padStart(2, '0')} GB` +} + +export const providers = Cli.create('providers', { + description: 'Provider commands', + options: globalOptions, + vars: contextSchema, +}) + +providers.command('list', { + description: 'List all providers from the indexer', + options: globalOptions.extend({ + all: z.boolean().optional().default(false).describe('Include all providers'), + }), + middleware: [contextMiddleware], + run: async (c) => { + try { + const schema = c.var.indexerDb._.fullSchema + const filters: (SQLWrapper | undefined)[] = [ + eq(schema.providers.providerActive, true), + eq(schema.providers.pdpProductActive, true), + // or(eq(schema.providers.approved, true), eq(schema.providers.endorsed, true)), + ] + if (!c.options.all) { + filters.push(or(eq(schema.providers.approved, true), eq(schema.providers.endorsed, true))) + } + const blockNumber = await getBlockNumber(c.var.client) + const rows = await c.var.indexerDb.query.providers.findMany({ + orderBy: [asc(schema.providers.providerId)], + where: and(...filters), + }) + + const providerIds = rows.map((provider) => provider.providerId) + const statsByProviderId = new Map() + + if (providerIds.length > 0) { + const stats = await c.var.indexerDb + .select({ + providerId: schema.dataSets.providerId, + pieceCount: count(schema.pieces.pieceId), + totalSize: sum(schema.pieces.rawSize), + }) + .from(schema.pieces) + .innerJoin(schema.dataSets, eq(schema.pieces.dataSetId, schema.dataSets.dataSetId)) + .where( + and( + inArray(schema.dataSets.providerId, providerIds), + eq(schema.dataSets.deleted, false), + or(isNull(schema.dataSets.pdpEndEpoch), lte(schema.dataSets.pdpEndEpoch, blockNumber)), + eq(schema.pieces.removed, false) + ) + ) + .groupBy(schema.dataSets.providerId) + + for (const stat of stats) { + statsByProviderId.set(stat.providerId, { + pieceCount: stat.pieceCount, + totalSize: stat.totalSize == null ? 0n : BigInt(stat.totalSize), + }) + } + } + + const providersFlattened = rows.map((provider) => { + const stats = statsByProviderId.get(provider.providerId) + return { + id: provider.providerId, + name: provider.name, + serviceUrl: provider.serviceUrl, + approved: provider.approved, + endorsed: provider.endorsed, + pieceCount: stats?.pieceCount ?? 0, + totalSize: formatBytesAsGb(stats?.totalSize ?? 0n), + } + }) + + return c.ok({ + providers: providersFlattened, + }) + } catch (error) { + console.error(error) + return c.error({ + code: 'PROVIDERS_FAILED', + message: error instanceof Error ? error.message : 'Failed to list providers', + retryable: true, + }) + } + }, +}) diff --git a/packages/repair-cli/src/commands/repair.ts b/packages/repair-cli/src/commands/repair.ts new file mode 100644 index 0000000..9469e35 --- /dev/null +++ b/packages/repair-cli/src/commands/repair.ts @@ -0,0 +1,177 @@ +import { and, desc, eq, inArray } from 'drizzle-orm' +import { Cli, z } from 'incur' +import { repairCreate } from '../db/repair-create.ts' +import { repairDelete } from '../db/repair-delete.ts' +import { contextMiddleware, contextSchema } from '../middleware.ts' +import { ensureRepairDataset } from '../pipeline/create-datasets.ts' +import { runPullPiecesPhase } from '../pipeline/pull.ts' +import { globalOptions } from '../utils.ts' +export const repair = Cli.create('repair', { + description: 'Repair commands', + vars: contextSchema, +}) + +repair.command('create', { + description: 'Create a new repair', + options: globalOptions.extend({ + providerId: z.coerce.bigint().describe('Provider ID to repair'), + targetProviderId: z.coerce.bigint().describe('Target provider ID for repair'), + }), + middleware: [contextMiddleware], + run: async (c) => { + try { + const { providerId, targetProviderId } = c.options + + const repairId = await repairCreate({ + ...c.var, + repairProviderId: providerId, + targetProviderId, + }) + + return c.ok({ + repairId, + }) + } catch (error) { + console.error(error) + return c.error({ + code: 'REPAIR_FAILED', + message: error instanceof Error ? error.message : 'Failed to repair the dataset', + retryable: true, + }) + } + }, +}) + +repair.command('list', { + description: 'List all repairs', + options: globalOptions, + middleware: [contextMiddleware], + run: async (c) => { + try { + const localSchema = c.var.localDb._.fullSchema + const repairs = await c.var.localDb.query.repairs.findMany({ + orderBy: [desc(localSchema.repairs.createdAt)], + with: { + operations: true, + }, + }) + + const repairFlattened = repairs.map((repair) => { + const { operations, ...repairWithoutOperations } = repair + return { + id: repairWithoutOperations.id, + status: repairWithoutOperations.status, + repairProviderId: repairWithoutOperations.repairProviderId, + targetProviderId: repairWithoutOperations.targetProviderId, + targetProviderUrl: repairWithoutOperations.targetProviderUrl, + targetDataSetId: repairWithoutOperations.targetDataSetId, + blockNumber: repairWithoutOperations.blockNumber, + operations: operations.length, + pending: operations.filter((operation) => operation.status === 'pending').length, + failed: operations.filter((operation) => operation.status === 'failed').length, + completed: operations.filter((operation) => operation.status === 'completed').length, + skipped: operations.filter((operation) => operation.status === 'skipped').length, + } + }) + + return c.ok({ + repairs: repairFlattened, + }) + } catch (error) { + console.error(error) + return c.error({ + code: 'REPAIR_FAILED', + message: error instanceof Error ? error.message : 'Failed to repair the dataset', + retryable: true, + }) + } + }, +}) + +repair.command('delete', { + description: 'Delete a repair', + args: z.object({ + repairId: z.coerce.number().describe('Repair ID to delete'), + }), + options: globalOptions, + middleware: [contextMiddleware], + run: async (c) => { + try { + const { deleted, operationsDeleted } = await repairDelete({ + localDb: c.var.localDb, + repairId: c.args.repairId, + }) + + if (!deleted) { + return c.error({ + code: 'REPAIR_NOT_FOUND', + message: 'Repair not found', + retryable: false, + }) + } + + return c.ok({ + repairId: c.args.repairId, + operationsDeleted, + }) + } catch (error) { + console.error(error) + return c.error({ + code: 'REPAIR_FAILED', + message: error instanceof Error ? error.message : 'Failed to delete the repair', + retryable: true, + }) + } + }, +}) + +repair.command('run', { + description: 'Run a repair', + args: z.object({ + repairId: z.coerce.number().describe('Repair ID to run'), + }), + options: globalOptions.extend({ + concurrency: z.coerce.number().default(4).describe('Concurrency level'), + batchSize: z.coerce.number().default(40).describe('Max add_piece operations per pull batch'), + reset: z.boolean().default(false).describe('Reset the repair'), + }), + middleware: [contextMiddleware], + run: async (c) => { + try { + const schema = c.var.localDb._.fullSchema + const repair = await c.var.localDb.query.repairs.findFirst({ + where: and(eq(schema.repairs.id, c.args.repairId), inArray(schema.repairs.status, ['pending'])), + }) + if (!repair) { + return c.error({ + code: 'REPAIR_NOT_FOUND', + message: 'Repair not found, it may have already been run or completed', + retryable: false, + }) + } + + await ensureRepairDataset({ + ...c.var, + repair, + }) + + await runPullPiecesPhase({ + ...c.var, + repair, + concurrency: c.options.concurrency, + batchSize: c.options.batchSize, + reset: c.options.reset, + }) + return c.ok({ + repairId: repair.id, + }) + } catch (error) { + console.error(error) + return c.error({ + code: 'REPAIR_FAILED', + message: error instanceof Error ? error.message : 'Failed to repair the dataset', + retryable: true, + }) + } + }, +}) diff --git a/packages/repair-cli/src/commands/setup.ts b/packages/repair-cli/src/commands/setup.ts new file mode 100644 index 0000000..e627ebc --- /dev/null +++ b/packages/repair-cli/src/commands/setup.ts @@ -0,0 +1,142 @@ +import * as p from '@clack/prompts' +import { Cli, z } from 'incur' +import path from 'path' +import type { Hash } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import { config, createLocalDatabase, globalOptions, migrateLocalDatabase } from '../utils.ts' + +function validatePostgresUrl(value: string) { + let url: URL + try { + url = new URL(value) + } catch { + return false + } + + if (url.protocol !== 'postgresql:' && url.protocol !== 'postgres:') { + return false + } + + return Boolean(url.hostname && url.username && url.password && url.pathname.length > 1) +} + +export const setup = Cli.create('setup', { + description: 'Setup the CLI', + options: globalOptions.extend({ + privateKey: z.string().optional().describe('Private key to use'), + }), + run: async (c) => { + try { + // Private key + const pk = await p.text({ + message: 'Enter your private key', + validate(value) { + if (!value || !/^0x[a-fA-F0-9]{64}$/.test(value)) { + return `Invalid private key!` + } + }, + initialValue: config.get('privateKey'), + withGuide: false, + }) + if (p.isCancel(pk)) { + return c.error({ + code: 'SETUP_CANCELLED', + message: 'Setup cancelled', + retryable: false, + }) + } + + // Indexer URL + const indexerMainnetUrl = await p.text({ + message: 'Enter your Mainnet Indexer Postgres URL', + validate(value) { + if (!value || !validatePostgresUrl(value)) { + return `Invalid postgres URL!` + } + }, + initialValue: config.get('indexerMainnetUrl'), + withGuide: false, + }) + if (p.isCancel(indexerMainnetUrl)) { + return c.error({ + code: 'SETUP_CANCELLED', + message: 'Setup cancelled', + retryable: false, + }) + } + const indexerCalibrationUrl = await p.text({ + message: 'Enter your Calibration Indexer Postgres URL', + validate(value) { + if (!value || !validatePostgresUrl(value)) { + return `Invalid postgres URL!` + } + }, + initialValue: config.get('indexerCalibrationUrl'), + withGuide: false, + }) + if (p.isCancel(indexerCalibrationUrl)) { + return c.error({ + code: 'SETUP_CANCELLED', + message: 'Setup cancelled', + retryable: false, + }) + } + + // Chain + const chainId = await p.select({ + message: 'Select your chain', + options: [ + { value: 314, label: 'Mainnet' }, + { value: 314159, label: 'Calibration' }, + ], + withGuide: false, + initialValue: config.get('chainId'), + }) + if (p.isCancel(chainId)) { + return c.error({ + code: 'SETUP_CANCELLED', + message: 'Setup cancelled', + retryable: false, + }) + } + + // DB path + const dbPath = await p.text({ + message: 'Enter your DB path', + initialValue: config.get('dbPath') || path.join(path.dirname(config.path), 'sqlite.db'), + withGuide: false, + }) + if (p.isCancel(dbPath)) { + return c.error({ + code: 'SETUP_CANCELLED', + message: 'Setup cancelled', + retryable: false, + }) + } + + // Set config + config.set('privateKey', pk) + config.set('indexerMainnetUrl', indexerMainnetUrl) + config.set('indexerCalibrationUrl', indexerCalibrationUrl) + config.set('chainId', chainId) + config.set('dbPath', dbPath) + + // setup database + const db = await createLocalDatabase(dbPath) + await migrateLocalDatabase(db) + + const account = privateKeyToAccount(pk as Hash) + + return c.ok({ + address: account.address, + }) + } catch (error) { + console.error(error) + return c.error({ + code: 'SETUP_FAILED', + message: error instanceof Error ? error.message : 'Failed to setup the CLI', + retryable: true, + }) + } + }, +}) diff --git a/packages/repair-cli/src/commands/wallet.ts b/packages/repair-cli/src/commands/wallet.ts new file mode 100644 index 0000000..46ced09 --- /dev/null +++ b/packages/repair-cli/src/commands/wallet.ts @@ -0,0 +1,159 @@ +/** biome-ignore-all lint/suspicious/noConsole: cli */ +import { calibration } from '@filoz/synapse-core/chains' +import * as ERC20 from '@filoz/synapse-core/erc20' +import * as Pay from '@filoz/synapse-core/pay' +import { claimTokens, formatBalance, formatFraction, parseUnits } from '@filoz/synapse-core/utils' +import { Cli, z } from 'incur' +import { getBalance, waitForTransactionReceipt } from 'viem/actions' +import { contextMiddleware, contextSchema } from '../middleware.ts' +import { globalOptions, hashLink } from '../utils.ts' + +export const wallet = Cli.create('wallet', { + description: 'Wallet commands', + vars: contextSchema, +}) + +wallet.command('fund', { + description: 'Fund a calibration wallet from a faucet', + options: globalOptions, + middleware: [contextMiddleware], + async *run(c) { + const { client, chain } = c.var + + if (chain.id !== calibration.id) { + return c.error({ + code: 'INVALID_CHAIN', + message: `Wallet fund is only available on Filecoin Calibration (chain ID ${calibration.id})`, + }) + } + + yield 'Funding wallet...' + try { + const hashes = await claimTokens({ address: client.account.address }) + + yield `Waiting for tx ${hashLink(hashes[0].tx_hash, chain)} to be mined...` + await waitForTransactionReceipt(client, { + hash: hashes[0].tx_hash, + }) + const balance = await getBalance(client, { + address: client.account.address, + }) + yield { + address: client.account.address, + balance: formatBalance({ value: balance }), + } + } catch (error) { + if (c.options.debug) { + console.error(error) + } + return c.error({ + code: 'FAILED_TO_FUND_WALLET', + message: 'Failed to fund wallet', + }) + } + }, +}) + +wallet.command('balance', { + description: 'Get wallet and pay account summary', + options: globalOptions, + middleware: [contextMiddleware], + async run(c) { + const { client } = c.var + const balanceFIL = await getBalance(client, { + address: client.account.address, + }) + + const balanceUSDFC = await ERC20.balance(client, { + address: client.account.address, + }) + + const summary = await Pay.getAccountSummary(client, { + address: client.account.address, + }) + return { + address: client.account.address, + fil: formatBalance({ value: balanceFIL }), + usdfc: formatBalance({ value: balanceUSDFC.value }), + pay: { + funds: formatBalance({ value: summary.funds }), + availableFunds: formatBalance({ value: summary.availableFunds }), + debt: formatBalance({ value: summary.debt }), + lockupRatePerEpoch: formatFraction({ value: summary.lockupRatePerEpoch }), + lockupRatePerMonth: formatBalance({ value: summary.lockupRatePerMonth }), + totalLockup: formatBalance({ value: summary.totalLockup }), + totalFixedLockup: formatBalance({ value: summary.totalFixedLockup }), + totalRateBasedLockup: formatBalance({ value: summary.totalRateBasedLockup }), + runwayInEpochs: summary.runwayInEpochs, + grossCoverageInEpochs: summary.grossCoverageInEpochs, + epoch: summary.epoch, + }, + } + }, +}) + +wallet.command('deposit', { + description: 'Deposit wallet funds to a pay account', + args: z.object({ + amount: z.coerce.number().gt(0).describe('Amount of USDFC to deposit'), + }), + options: globalOptions, + middleware: [contextMiddleware], + async *run(c) { + const { client, chain } = c.var + + try { + yield `Depositing ${c.args.amount} tokens to wallet...` + const hash = await Pay.depositAndApprove(client, { + amount: parseUnits(c.args.amount), + }) + yield `Waiting for tx ${hashLink(hash, chain)} to be mined...` + await waitForTransactionReceipt(client, { + hash, + }) + yield `Deposit successful` + return + } catch (error) { + if (c.options.debug) { + console.error(error) + } + return c.error({ + code: 'FAILED_TO_DEPOSIT', + message: (error as Error).message, + }) + } + }, +}) + +wallet.command('withdraw', { + description: 'Withdraw wallet funds from a pay account', + args: z.object({ + amount: z.coerce.number().gt(0).describe('Amount of USDFC to withdraw'), + }), + options: globalOptions, + middleware: [contextMiddleware], + async *run(c) { + const { client, chain } = c.var + + try { + yield `Withdrawing ${c.args.amount} USDFC from pay account...` + const hash = await Pay.withdraw(client, { + amount: parseUnits(c.args.amount), + }) + yield `Waiting for tx ${hashLink(hash, chain)} to be mined...` + await waitForTransactionReceipt(client, { + hash, + }) + yield `Withdrawal successful` + return + } catch (error) { + if (c.options.debug) { + console.error(error) + } + return c.error({ + code: 'FAILED_TO_WITHDRAW', + message: (error as Error).message, + }) + } + }, +}) diff --git a/packages/repair-cli/src/db/get-pieces.ts b/packages/repair-cli/src/db/get-pieces.ts new file mode 100644 index 0000000..6e0f1f1 --- /dev/null +++ b/packages/repair-cli/src/db/get-pieces.ts @@ -0,0 +1,189 @@ +import * as Piece from '@filoz/synapse-core/piece' +import { and, asc, eq, isNull, lte, or } from 'drizzle-orm' +import pMap from 'p-map' +import type { OperationInsert } from '../local-schema.ts' +import type { IndexerDatabase } from '../types.ts' +import { getProvidersByCid } from './get-providers-by-cid.ts' + +/** Default page size when paginating pieces from the indexer. */ +export const DEFAULT_PIECES_PAGE_SIZE = 3000 + +/** Options for fetching one page of `add_piece` operations for a repair. */ +export type GetPiecesPageOptions = { + indexerDb: IndexerDatabase + /** Source provider whose pieces are being repaired. */ + providerId: bigint + /** Local repair row to attach operations to. */ + repairId: number + /** Chain block number captured when the repair was created. */ + blockNumber: bigint + /** Max indexer rows per page. Defaults to {@link DEFAULT_PIECES_PAGE_SIZE}. */ + limit?: number + /** SQL offset for the indexer query. */ + offset?: number + /** + * CIDs already emitted across prior pages. Pass the value returned from the previous call + * so the same CID is not queued twice when it appears in multiple source datasets. + */ + seenCids?: Set +} + +/** Result of a single {@link getPiecesPage} call. */ +export type GetPiecesPageResult = { + /** `add_piece` operations ready to insert for this page (may include `skipped` rows). */ + operations: OperationInsert[] + /** Whether another indexer page may exist after this one. */ + hasMore: boolean + /** Offset to pass as `offset` on the next page. */ + nextOffset: number + /** Updated dedupe set; pass into the next {@link getPiecesPage} call. */ + seenCids: Set +} + +/** Options for {@link forEachPiecesPage}; pagination state is managed internally. */ +export type ForEachPiecesPageOptions = Omit + +type PieceForOperation = { + cid: string + metadata: Record | null +} + +/** Empty CID set for starting a paginated piece walk. */ +export function emptySeenCids(): Set { + return new Set() +} + +/** + * Fetch one page of pieces for a provider at the repair block and map them to `add_piece` operations. + * + * Pieces are read from the indexer in stable dataset/piece order. CIDs are deduped globally so a + * piece stored under multiple source datasets is queued once into the single IPFS repair dataset. + * Alternate providers are resolved in one batch per page; operations without alternates are + * inserted as `skipped` with a descriptive error. + * + * Pass `seenCids` and `nextOffset` from the prior result to continue pagination. + * + * @param options - Indexer connection, repair context, and optional pagination state. + * @returns Operations for this page plus pagination cursors. + */ +export async function getPiecesPage({ + indexerDb, + providerId, + repairId, + blockNumber, + limit = DEFAULT_PIECES_PAGE_SIZE, + offset = 0, + seenCids = emptySeenCids(), +}: GetPiecesPageOptions): Promise { + const schema = indexerDb._.fullSchema + const rows = await indexerDb + .select({ + cid: schema.pieces.cid, + metadata: schema.pieces.metadata, + }) + .from(schema.pieces) + .innerJoin(schema.dataSets, eq(schema.pieces.dataSetId, schema.dataSets.dataSetId)) + .where( + and( + eq(schema.dataSets.providerId, providerId), + eq(schema.dataSets.deleted, false), + or(isNull(schema.dataSets.pdpEndEpoch), lte(schema.dataSets.pdpEndEpoch, blockNumber)), + eq(schema.pieces.removed, false) + ) + ) + .orderBy(asc(schema.pieces.dataSetId), asc(schema.pieces.pieceId)) + .limit(limit) + .offset(offset) + + const now = Date.now() + const pieces: PieceForOperation[] = [] + + for (const { cid, metadata } of rows) { + // Same CID can appear on multiple source datasets; only repair it once. + if (seenCids.has(cid)) continue + seenCids.add(cid) + + pieces.push({ cid, metadata }) + } + + // Resolve pull sources in one query per page; exclude the provider being repaired from alternates. + const providersByCid = await getProvidersByCid({ + indexerDb, + cids: pieces.map((piece) => piece.cid), + excludedProviderIds: [], + blockNumber, + }) + + const operations: OperationInsert[] = await pMap( + pieces, + async ({ cid, metadata }) => { + const alternateProviders = providersByCid[cid]?.map((provider) => provider.serviceUrl) ?? [] + let skippedMessage = '' + let validProvider: string | undefined + if (alternateProviders.length > 0) { + validProvider = await Piece.findPieceOnProviders(alternateProviders, Piece.from(cid)) + + if (!validProvider) { + skippedMessage = `Found ${alternateProviders.length} alternate providers, but none are valid. ${alternateProviders.join(', ')}` + } + } else { + skippedMessage = `No alternate providers found` + } + + return { + repairId, + type: 'add_piece', + // Cannot pull without another replica; mark skipped up front so run skips these ops. + status: validProvider ? 'pending' : 'skipped', + cid, + metadata: metadata ?? {}, + alternateProvider: validProvider ?? '', + error: validProvider ? undefined : skippedMessage, + createdAt: now, + updatedAt: now, + } + }, + { concurrency: 20 } + ) + + // ) + + return { + operations, + // A full page means there may be more rows; a short page ends pagination. + hasMore: rows.length === limit, + nextOffset: offset + rows.length, + seenCids, + } +} + +/** + * Walk every page of `add_piece` operations for a provider, invoking `onPage` per batch. + * + * Manages `offset` and `seenCids` across pages so callers only handle inserts. + * + * @param options - Same inputs as {@link getPiecesPage} except pagination cursors. + * @param onPage - Async handler for each page result (e.g. batch insert into local DB). + */ +export async function forEachPiecesPage( + options: ForEachPiecesPageOptions, + onPage: (page: GetPiecesPageResult) => Promise +): Promise { + let offset = 0 + let hasMore = true + let seenCids = emptySeenCids() + + while (hasMore) { + const page = await getPiecesPage({ + ...options, + offset, + seenCids, + }) + + await onPage(page) + + offset = page.nextOffset + seenCids = page.seenCids + hasMore = page.hasMore + } +} diff --git a/packages/repair-cli/src/db/get-providers-by-cid.ts b/packages/repair-cli/src/db/get-providers-by-cid.ts new file mode 100644 index 0000000..ad6b12a --- /dev/null +++ b/packages/repair-cli/src/db/get-providers-by-cid.ts @@ -0,0 +1,75 @@ +import { and, asc, eq, inArray, isNull, lte, notInArray, or } from 'drizzle-orm' +import type { IndexerDatabase, RepairProvider } from '../types.ts' + +export type GetProvidersByCidOptions = { + indexerDb: IndexerDatabase + cids: readonly string[] + excludedProviderIds: readonly bigint[] + blockNumber: bigint +} + +/** + * Map of piece CID to providers that store that CID at the repair block. + */ +export type ProvidersByCid = Record + +/** + * Find alternate providers for each CID, excluding the given provider IDs. + * + * Deleted datasets and removed pieces are ignored. Only approved or endorsed providers are + * included. Every requested CID is present in the result; CIDs with no alternate providers + * map to an empty array. + */ +export async function getProvidersByCid({ + indexerDb, + cids, + excludedProviderIds, + blockNumber, +}: GetProvidersByCidOptions): Promise { + const schema = indexerDb._.fullSchema + const providersByCid = Object.fromEntries(cids.map((cid) => [cid, []])) as ProvidersByCid + if (cids.length === 0) return providersByCid + + const filters = [ + inArray(schema.pieces.cid, [...cids]), + eq(schema.dataSets.deleted, false), + or(isNull(schema.dataSets.pdpEndEpoch), lte(schema.dataSets.pdpEndEpoch, blockNumber)), + eq(schema.pieces.removed, false), + // or(eq(schema.providers.approved, true), eq(schema.providers.endorsed, true)), + ] + if (excludedProviderIds.length > 0) { + filters.push(notInArray(schema.dataSets.providerId, [...excludedProviderIds])) + } + + // Join through datasets because providers own datasets, while pieces only reference dataset IDs. + const rows = await indexerDb + .selectDistinct({ + cid: schema.pieces.cid, + providerId: schema.providers.providerId, + providerAddress: schema.providers.providerAddress, + name: schema.providers.name, + serviceUrl: schema.providers.serviceUrl, + approved: schema.providers.approved, + endorsed: schema.providers.endorsed, + }) + .from(schema.pieces) + .innerJoin(schema.dataSets, eq(schema.pieces.dataSetId, schema.dataSets.dataSetId)) + .innerJoin(schema.providers, eq(schema.dataSets.providerId, schema.providers.providerId)) + .where(and(...filters)) + .orderBy(asc(schema.pieces.cid), asc(schema.providers.providerId)) + + for (const { cid, ...provider } of rows) { + if (provider.providerAddress && provider.serviceUrl && provider.name) { + providersByCid[cid]?.push({ + providerId: provider.providerId, + providerAddress: provider.providerAddress, + name: provider.name, + serviceUrl: provider.serviceUrl, + approved: provider.approved, + endorsed: provider.endorsed, + }) + } + } + + return providersByCid +} diff --git a/packages/repair-cli/src/db/get-repair-dataset.ts b/packages/repair-cli/src/db/get-repair-dataset.ts new file mode 100644 index 0000000..ec9bd60 --- /dev/null +++ b/packages/repair-cli/src/db/get-repair-dataset.ts @@ -0,0 +1,44 @@ +import { and, asc, eq, isNull } from 'drizzle-orm' +import type { Address } from 'viem' +import type { IndexerDatabase } from '../types.ts' +import { EARLY_REPAIR_SOURCE } from '../utils.ts' + +export type GetRepairDatasetOptions = { + indexerDb: IndexerDatabase + providerId: bigint + payer: Address +} + +/** + * Find one IPFS-enabled repair dataset for a provider at the repair block, if it exists. + * + * When multiple datasets match, the lowest `dataSetId` is returned. + */ +export async function getRepairDataset({ + indexerDb, + providerId, + payer, +}: GetRepairDatasetOptions): Promise { + const schema = indexerDb._.fullSchema + + const [row] = await indexerDb + .select({ + dataSetId: schema.dataSets.dataSetId, + }) + .from(schema.dataSets) + .where( + and( + eq(schema.dataSets.providerId, providerId), + eq(schema.dataSets.deleted, false), + isNull(schema.dataSets.pdpEndEpoch), + eq(schema.dataSets.payer, payer.toLowerCase()), + eq(schema.dataSets.source, EARLY_REPAIR_SOURCE), + eq(schema.dataSets.withCdn, false), + eq(schema.dataSets.withIpfsIndexing, true) + ) + ) + .orderBy(asc(schema.dataSets.dataSetId)) + .limit(1) + + return row.dataSetId ?? null +} diff --git a/packages/repair-cli/src/db/get-repair-provider.ts b/packages/repair-cli/src/db/get-repair-provider.ts new file mode 100644 index 0000000..650206b --- /dev/null +++ b/packages/repair-cli/src/db/get-repair-provider.ts @@ -0,0 +1,47 @@ +import { and, eq } from 'drizzle-orm' +import type { Context, RepairProvider } from '../types.ts' + +export interface GetRepairProviderOptions extends Pick { + providerId: bigint +} + +/** + * Load an active provider by ID for use as a repair target. + */ +export async function getRepairProvider({ + indexerDb, + providerId, +}: GetRepairProviderOptions): Promise { + const schema = indexerDb._.fullSchema + const [provider] = await indexerDb + .select({ + providerId: schema.providers.providerId, + providerAddress: schema.providers.providerAddress, + name: schema.providers.name, + serviceUrl: schema.providers.serviceUrl, + approved: schema.providers.approved, + endorsed: schema.providers.endorsed, + }) + .from(schema.providers) + .where( + and( + eq(schema.providers.providerId, providerId), + eq(schema.providers.providerActive, true), + eq(schema.providers.pdpProductActive, true) + ) + ) + .limit(1) + + if (!provider?.providerAddress || !provider?.serviceUrl || !provider?.name) { + return null + } + + return { + providerId: provider.providerId, + providerAddress: provider.providerAddress, + name: provider.name, + serviceUrl: provider.serviceUrl, + approved: provider.approved, + endorsed: provider.endorsed, + } +} diff --git a/packages/repair-cli/src/db/get-target-dataset.ts b/packages/repair-cli/src/db/get-target-dataset.ts new file mode 100644 index 0000000..99316e0 --- /dev/null +++ b/packages/repair-cli/src/db/get-target-dataset.ts @@ -0,0 +1,47 @@ +import { getDataSet } from '@filoz/synapse-core/warm-storage' +import { eq } from 'drizzle-orm' +import { MissingRepairDataSetError, RepairNotFoundError } from '../error.ts' +import type { LocalDatabase, WalletClient } from '../types.ts' + +const targetDatasetCache = new Map() + +/** + * Get the single IPFS-enabled target dataset for a repair. + * + * @param options - The options for getting the target dataset. + */ +export async function getTargetDataset({ + localDb, + repairId, + client, +}: { + localDb: LocalDatabase + repairId: number + client: WalletClient +}) { + const cached = targetDatasetCache.get(repairId) + if (cached) { + return cached + } + + const repair = await localDb.query.repairs.findFirst({ + where: eq(localDb._.fullSchema.repairs.id, repairId), + columns: { targetDataSetId: true }, + }) + if (!repair) { + throw new RepairNotFoundError(repairId) + } + + if (repair.targetDataSetId == null) { + throw new MissingRepairDataSetError() + } + + const dataSet = await getDataSet(client, { dataSetId: repair.targetDataSetId }) + if (!dataSet) { + throw new MissingRepairDataSetError() + } + + targetDatasetCache.set(repairId, dataSet) + + return dataSet +} diff --git a/packages/repair-cli/src/db/repair-create.ts b/packages/repair-cli/src/db/repair-create.ts new file mode 100644 index 0000000..78c36f6 --- /dev/null +++ b/packages/repair-cli/src/db/repair-create.ts @@ -0,0 +1,101 @@ +import { taskLog } from '@clack/prompts' +import { getBlockNumber } from 'viem/actions' +import { NoAlternateProviderError, RepairCreationError } from '../error.ts' +import type { Context } from '../types.ts' +import { forEachPiecesPage } from './get-pieces.ts' +import { getRepairProvider } from './get-repair-provider.ts' + +export interface RepairCreateOptions extends Context { + repairProviderId: bigint + targetProviderId: bigint +} + +/** + * Prepare a repair by selecting a target provider, creating the repair row, and + * inserting pending dataset and piece operations. + * + * @param {RepairCreateOptions} options - The options for creating a repair. + * @returns {Promise} The ID of the created repair. + */ +export async function repairCreate(options: RepairCreateOptions): Promise { + const { indexerDb, localDb, repairProviderId, targetProviderId, client } = options + const localSchema = localDb._.fullSchema + const now = Date.now() + const blockNumber = await getBlockNumber(client) + + const log = taskLog({ + title: 'Creating repair', + limit: 10, + retainLog: true, + }) + + // Load the explicit target provider. + if (targetProviderId === repairProviderId) { + throw new RepairCreationError('Target provider must differ from the provider being repaired') + } + const targetProvider = await getRepairProvider({ + indexerDb, + providerId: targetProviderId, + }) + + if (!targetProvider) { + throw new NoAlternateProviderError(targetProviderId) + } + + // Create the repair row + const [repair] = await localDb + .insert(localSchema.repairs) + .values({ + repairProviderId, + targetProviderId: targetProvider.providerId, + targetProviderUrl: targetProvider.serviceUrl, + targetDataSetId: null, + blockNumber, + createdAt: now, + updatedAt: now, + }) + .returning({ id: localSchema.repairs.id }) + + if (!repair) throw new RepairCreationError() + + // Add the pieces to the repair + let totalOperations = 0 + let totalPendingOperations = 0 + let totalSkippedOperations = 0 + const seenCids = new Set() + await forEachPiecesPage( + { + indexerDb, + providerId: repairProviderId, + repairId: repair.id, + blockNumber, + }, + async (page) => { + for (const operation of page.operations) { + if (seenCids.has(operation.cid)) { + continue + } + seenCids.add(operation.cid) + } + const pendingOperations = page.operations.filter((operation) => operation.status === 'pending').length + const skippedOperations = page.operations.filter((operation) => operation.status === 'skipped').length + totalOperations += page.operations.length + totalPendingOperations += pendingOperations + totalSkippedOperations += skippedOperations + + if (page.operations.length > 0) { + await localDb.insert(localSchema.operations).values(page.operations) + } + + log.message( + `Inserted ${page.operations.length} operations (${pendingOperations} pending, ${skippedOperations} skipped)` + ) + } + ) + + log.success( + `Created repair ${repair.id} with ${totalOperations} operations (${totalPendingOperations} pending, ${totalSkippedOperations} skipped)`, + { showLog: true } + ) + return repair.id +} diff --git a/packages/repair-cli/src/db/repair-delete.ts b/packages/repair-cli/src/db/repair-delete.ts new file mode 100644 index 0000000..3dac6cc --- /dev/null +++ b/packages/repair-cli/src/db/repair-delete.ts @@ -0,0 +1,39 @@ +import { eq } from 'drizzle-orm' +import * as localSchema from '../local-schema.ts' +import type { LocalDatabase } from '../types.ts' + +export type RepairDeleteOptions = { + localDb: LocalDatabase + repairId: number +} + +export type RepairDeleteResult = { + deleted: boolean + operationsDeleted: number +} + +/** + * Delete a repair and all of its operations from the local database. + */ +export async function repairDelete({ localDb, repairId }: RepairDeleteOptions): Promise { + const repair = await localDb.query.repairs.findFirst({ + where: eq(localSchema.repairs.id, repairId), + columns: { id: true }, + with: { + operations: { + columns: { id: true }, + }, + }, + }) + + if (!repair) { + return { deleted: false, operationsDeleted: 0 } + } + + const operationsDeleted = await localDb + .delete(localSchema.operations) + .where(eq(localSchema.operations.repairId, repairId)) + await localDb.delete(localSchema.repairs).where(eq(localSchema.repairs.id, repairId)) + + return { deleted: true, operationsDeleted: operationsDeleted.rowsAffected } +} diff --git a/packages/repair-cli/src/db/repair-update.ts b/packages/repair-cli/src/db/repair-update.ts new file mode 100644 index 0000000..4bbe1ad --- /dev/null +++ b/packages/repair-cli/src/db/repair-update.ts @@ -0,0 +1,20 @@ +import { eq } from 'drizzle-orm' +import type { RepairUpdate } from '../local-schema.ts' +import * as localSchema from '../local-schema.ts' +import type { LocalDatabase } from '../types.ts' + +export type RepairUpdateOptions = { + localDb: LocalDatabase + repairId: number + status?: localSchema.RepairStatus + targetDataSetId?: bigint | null +} + +export async function repairUpdate({ localDb, repairId, status, targetDataSetId }: RepairUpdateOptions) { + const update: RepairUpdate = { + updatedAt: Date.now(), + } + if (status) update.status = status + if (targetDataSetId !== undefined) update.targetDataSetId = targetDataSetId + await localDb.update(localSchema.repairs).set(update).where(eq(localSchema.repairs.id, repairId)) +} diff --git a/packages/repair-cli/src/db/sync-pieces-onchain.ts b/packages/repair-cli/src/db/sync-pieces-onchain.ts new file mode 100644 index 0000000..6daf476 --- /dev/null +++ b/packages/repair-cli/src/db/sync-pieces-onchain.ts @@ -0,0 +1,53 @@ +import { and, eq, inArray } from 'drizzle-orm' +import type { OperationInsert, OperationSelect } from '../local-schema.ts' +import type { IndexerDatabase, LocalDatabase } from '../types.ts' +import { upsertOperations } from './upsert-operations.ts' + +export type SyncPiecesOnchainOptions = { + indexerDb: IndexerDatabase + localDb: LocalDatabase + dataSetId: bigint + cidToOperation: Map +} + +/** + * Sync pieces onchain to avoid duplicates. + */ +export async function syncPiecesOnchain({ indexerDb, localDb, dataSetId, cidToOperation }: SyncPiecesOnchainOptions) { + const cids = Array.from(cidToOperation.keys()) + const schema = indexerDb._.fullSchema + let completedOperations = 0 + const rows = await indexerDb + .select({ cid: schema.pieces.cid }) + .from(schema.pieces) + .where( + and(eq(schema.pieces.dataSetId, dataSetId), eq(schema.pieces.removed, false), inArray(schema.pieces.cid, cids)) + ) + + const existingCids = new Set() + const completedOperation: OperationInsert[] = [] + + for (const row of rows) { + const operation = cidToOperation.get(row.cid) + if (!operation) { + continue + } + completedOperation.push({ + ...operation, + status: 'completed', + error: null, + }) + existingCids.add(row.cid) + cidToOperation.delete(row.cid) + completedOperations++ + } + + if (completedOperation.length > 0) { + await upsertOperations({ + localDb, + operations: completedOperation, + }) + } + + return completedOperations +} diff --git a/packages/repair-cli/src/db/update-operation.ts b/packages/repair-cli/src/db/update-operation.ts new file mode 100644 index 0000000..65fb739 --- /dev/null +++ b/packages/repair-cli/src/db/update-operation.ts @@ -0,0 +1,26 @@ +import { eq } from 'drizzle-orm' +import * as localSchema from '../local-schema.ts' +import type { LocalDatabase } from '../types.ts' + +export type UpdateOperationOptions = { + localDb: LocalDatabase + operationId: number + status: localSchema.OperationStatus + result?: localSchema.OperationResult | null + error?: string | null +} + +/** + * Updates an operation in the database. + */ +export async function updateOperation({ localDb, operationId, status, result, error }: UpdateOperationOptions) { + await localDb + .update(localSchema.operations) + .set({ + status, + result, + error: error ?? null, + updatedAt: Date.now(), + }) + .where(eq(localSchema.operations.id, operationId)) +} diff --git a/packages/repair-cli/src/db/upsert-operations.ts b/packages/repair-cli/src/db/upsert-operations.ts new file mode 100644 index 0000000..22aa861 --- /dev/null +++ b/packages/repair-cli/src/db/upsert-operations.ts @@ -0,0 +1,23 @@ +import type { OperationInsert } from '../local-schema.ts' +import * as localSchema from '../local-schema.ts' +import type { LocalDatabase } from '../types.ts' +import { buildConflictUpdateColumns } from '../utils.ts' + +export type UpsertOperationsOptions = { + localDb: LocalDatabase + operations: OperationInsert[] +} + +/** + * Upserts operations in the database. + */ +export async function upsertOperations({ localDb, operations }: UpsertOperationsOptions) { + const now = Date.now() + await localDb + .insert(localDb._.fullSchema.operations) + .values(operations.map((operation) => ({ ...operation, updatedAt: now }))) + .onConflictDoUpdate({ + target: localDb._.fullSchema.operations.id, + set: buildConflictUpdateColumns(localSchema.operations, ['status', 'error', 'updatedAt']), + }) +} diff --git a/packages/repair-cli/src/error.ts b/packages/repair-cli/src/error.ts new file mode 100644 index 0000000..42590b7 --- /dev/null +++ b/packages/repair-cli/src/error.ts @@ -0,0 +1,33 @@ +export class NoAlternateProviderError extends Error { + readonly providerId?: bigint + + /** + * @param providerId - When set, the explicit target provider was not found or inactive. + */ + constructor(providerId?: bigint) { + super(providerId == null ? 'No alternate provider found' : `Target provider ${providerId} not found or inactive`) + this.name = 'NoAlternateProviderError' + this.providerId = providerId + } +} + +export class RepairCreationError extends Error { + constructor(message = 'Failed to create repair row') { + super(message) + this.name = 'RepairCreationError' + } +} + +export class RepairNotFoundError extends Error { + constructor(repairId: number) { + super(`Repair ${repairId} not found`) + this.name = 'RepairNotFoundError' + } +} + +export class MissingRepairDataSetError extends Error { + constructor() { + super('Missing repair dataset ID') + this.name = 'MissingRepairDataSetError' + } +} diff --git a/packages/repair-cli/src/indexer-schema.ts b/packages/repair-cli/src/indexer-schema.ts new file mode 100644 index 0000000..80a752a --- /dev/null +++ b/packages/repair-cli/src/indexer-schema.ts @@ -0,0 +1,77 @@ +import { relations } from 'drizzle-orm' +import { bigint, boolean, index, jsonb, pgSchema, primaryKey, text } from 'drizzle-orm/pg-core' +import type { Address } from 'viem' + +export type JsonRecord = Record + +const schema = pgSchema('early-repair') + +export const providers = schema.table( + 'providers', + { + providerId: bigint('provider_id', { mode: 'bigint' }).primaryKey(), + providerAddress: text('provider_address').$type
(), + name: text('name'), + serviceUrl: text('service_url'), + providerActive: boolean('provider_active').notNull(), + pdpProductActive: boolean('pdp_product_active').notNull(), + approved: boolean('approved').notNull().default(false), + endorsed: boolean('endorsed').notNull().default(false), + createdAtBlock: bigint('created_at_block', { mode: 'bigint' }), + updatedAtBlock: bigint('updated_at_block', { mode: 'bigint' }).notNull(), + }, + (table) => [index('providers_provider_address_idx').on(table.providerAddress)] +) + +export const providersRelations = relations(providers, ({ many }) => ({ + dataSets: many(dataSets), +})) + +export const dataSets = schema.table( + 'data_sets', + { + dataSetId: bigint('data_set_id', { mode: 'bigint' }).primaryKey(), + providerId: bigint('provider_id', { mode: 'bigint' }).notNull(), + metadata: jsonb('metadata').$type(), + payer: text('payer').notNull(), + source: text('source'), + withCdn: boolean('with_cdn').notNull(), + withIpfsIndexing: boolean('with_ipfs_indexing').notNull(), + pdpEndEpoch: bigint('pdp_end_epoch', { mode: 'bigint' }).notNull(), + deleted: boolean('deleted').notNull(), + createdAtBlock: bigint('created_at_block', { mode: 'bigint' }).notNull(), + updatedAtBlock: bigint('updated_at_block', { mode: 'bigint' }).notNull(), + }, + (table) => [index('data_sets_provider_id_idx').on(table.providerId)] +) + +export const dataSetsRelations = relations(dataSets, ({ one, many }) => ({ + provider: one(providers, { + fields: [dataSets.providerId], + references: [providers.providerId], + }), + pieces: many(pieces), +})) + +export const pieces = schema.table( + 'pieces', + { + dataSetId: bigint('data_set_id', { mode: 'bigint' }).notNull(), + pieceId: bigint('piece_id', { mode: 'bigint' }).notNull(), + cid: text('cid').notNull(), + rawSize: bigint('raw_size', { mode: 'bigint' }).notNull(), + metadata: jsonb('metadata').$type(), + removed: boolean('removed').notNull(), + addedAtBlock: bigint('added_at_block', { mode: 'bigint' }).notNull(), + removedAtBlock: bigint('removed_at_block', { mode: 'bigint' }), + updatedAtBlock: bigint('updated_at_block', { mode: 'bigint' }).notNull(), + }, + (table) => [primaryKey({ columns: [table.dataSetId, table.pieceId] }), index('pieces_cid_idx').on(table.cid)] +) + +export const piecesRelations = relations(pieces, ({ one }) => ({ + dataSet: one(dataSets, { + fields: [pieces.dataSetId], + references: [dataSets.dataSetId], + }), +})) diff --git a/packages/repair-cli/src/local-schema.ts b/packages/repair-cli/src/local-schema.ts new file mode 100644 index 0000000..c929136 --- /dev/null +++ b/packages/repair-cli/src/local-schema.ts @@ -0,0 +1,91 @@ +import type { MetadataObject } from '@filoz/synapse-core' +import type * as SP from '@filoz/synapse-core/sp' +import { relations } from 'drizzle-orm' +import type { AnySQLiteColumn } from 'drizzle-orm/sqlite-core' +import * as t from 'drizzle-orm/sqlite-core' +import { customType, sqliteTable as table } from 'drizzle-orm/sqlite-core' +import * as Json from 'iso-base/json' + +export type RepairStatus = 'pending' | 'completed' | 'failed' +export type OperationStatus = 'pending' | 'completed' | 'failed' | 'skipped' +export type OperationType = 'create_dataset' | 'add_piece' + +export type OperationResult = Omit< + SP.AddPiecesSuccess, + 'txStatus' | 'addMessageOk' | 'piecesAdded' | 'pieceCount' | 'confirmedPieceIds' +> + +/** + * Custom type for JSON + * It will be used to store JSON data in the database + */ +export const jsonType = customType<{ data: unknown }>({ + dataType() { + return 'text' + }, + toDriver(value) { + return Json.stringify(value) + }, + fromDriver(value) { + return Json.parse(value as string) + }, +}) + +export const bigintType = customType<{ data: bigint }>({ + dataType() { + return 'text' + }, + toDriver(value) { + return value.toString() + }, + fromDriver(value) { + return BigInt(value as string) + }, +}) + +export type RepairInsert = typeof repairs.$inferInsert +export type RepairSelect = typeof repairs.$inferSelect +export type RepairUpdate = Partial + +export const repairs = table('repairs', { + id: t.int().primaryKey({ autoIncrement: true }), + status: t.text().$type().notNull().default('pending'), + repairProviderId: bigintType('repair_provider_id').notNull(), + targetProviderId: bigintType('target_provider_id').notNull(), + targetProviderUrl: t.text('target_provider_url').notNull(), + targetDataSetId: bigintType('target_data_set_id'), + blockNumber: bigintType('block_number').notNull(), + createdAt: t.integer('created_at').notNull(), + updatedAt: t.integer('updated_at').notNull(), +}) + +export type OperationInsert = typeof operations.$inferInsert +export type OperationSelect = typeof operations.$inferSelect + +export const operations = table('operations', { + id: t.int().primaryKey({ autoIncrement: true }), + repairId: t + .int('repair_id') + .references((): AnySQLiteColumn => repairs.id) + .notNull(), + type: t.text().$type().notNull(), + status: t.text().$type().notNull().default('pending'), + cid: t.text().notNull(), + metadata: jsonType().$type().notNull(), + alternateProvider: t.text('alternate_provider').notNull(), + result: jsonType().$type(), + error: t.text(), + createdAt: t.integer('created_at').notNull(), + updatedAt: t.integer('updated_at').notNull(), +}) + +export const repairRelations = relations(repairs, ({ many }) => ({ + operations: many(operations), +})) + +export const operationRelations = relations(operations, ({ one }) => ({ + repair: one(repairs, { + fields: [operations.repairId], + references: [repairs.id], + }), +})) diff --git a/packages/repair-cli/src/middleware.ts b/packages/repair-cli/src/middleware.ts new file mode 100644 index 0000000..a24a074 --- /dev/null +++ b/packages/repair-cli/src/middleware.ts @@ -0,0 +1,34 @@ +import type { Chain } from '@filoz/synapse-core/chains' +import { drizzle as drizzlePostgres } from 'drizzle-orm/node-postgres' +import { middleware, z } from 'incur' +import type { Account, Client, Transport } from 'viem' +import * as indexerSchema from './indexer-schema.ts' +import type { IndexerDatabase, LocalDatabase } from './types.ts' +import { config, createLocalDatabase, getClient } from './utils.ts' + +export const contextSchema = z.object({ + indexerDb: z.custom(), + localDb: z.custom(), + config: z.custom(), + client: z.custom>(), + chain: z.custom(), +}) + +export const contextMiddleware = middleware(async (c, next) => { + const { dbPath, chainId, indexerMainnetUrl, indexerCalibrationUrl } = config.store + const localDb = await createLocalDatabase(dbPath) + const indexerDb = drizzlePostgres(chainId === 314 ? indexerMainnetUrl : indexerCalibrationUrl, { + schema: indexerSchema, + }) + + const { client, chain } = getClient(chainId) + c.set('localDb', localDb) + c.set('indexerDb', indexerDb) + c.set('config', config) + c.set('client', client) + c.set('chain', chain) + await next() + + localDb.$client.close() + await indexerDb.$client.end() +}) diff --git a/packages/repair-cli/src/pipeline/create-datasets.ts b/packages/repair-cli/src/pipeline/create-datasets.ts new file mode 100644 index 0000000..37fbdd8 --- /dev/null +++ b/packages/repair-cli/src/pipeline/create-datasets.ts @@ -0,0 +1,70 @@ +import * as p from '@clack/prompts' +import * as SP from '@filoz/synapse-core/sp' +import { getPDPProvider } from '@filoz/synapse-core/sp-registry' +import { getRepairDataset } from '../db/get-repair-dataset.ts' +import { repairUpdate } from '../db/repair-update.ts' +import type { RepairSelect } from '../local-schema.ts' +import type { IndexerDatabase, LocalDatabase, WalletClient } from '../types.ts' +import { getRepairDatasetMetadata, hashLink } from '../utils.ts' + +export type EnsureRepairDatasetOptions = { + localDb: LocalDatabase + indexerDb: IndexerDatabase + client: WalletClient + repair: RepairSelect +} + +/** + * Ensure the repair dataset exists by creating it if it doesn't. + * + * @param options - The options for ensuring the repair dataset. + * @returns {Promise} - The ID of the created dataset. + */ +export async function ensureRepairDataset({ + localDb, + indexerDb, + client, + repair, +}: EnsureRepairDatasetOptions): Promise { + const log = p.taskLog({ + title: 'Ensuring repair dataset', + }) + const provider = await getPDPProvider(client, { + providerId: repair.targetProviderId, + }) + + if (!provider) throw new Error(`Target provider ${repair.targetProviderId} not found or inactive`) + + let datasetId: bigint | null = null + // check if dataset already exists + const existingDatasetId = await getRepairDataset({ + indexerDb, + providerId: repair.targetProviderId, + payer: client.account.address, + }) + + if (existingDatasetId) { + datasetId = existingDatasetId + log.success(`Data set #${datasetId} already exists at ${provider.pdp.serviceURL}`) + } else { + const { txHash, statusUrl } = await SP.createDataSet(client, { + payee: provider.payee, + serviceURL: provider.pdp.serviceURL, + payer: client.account.address, + cdn: false, + metadata: getRepairDatasetMetadata(), + }) + log.message(`Waiting for data to be created at ${provider.pdp.serviceURL} ${hashLink(txHash, client.chain)}...`) + const waitForResult = await SP.waitForCreateDataSet({ + statusUrl, + }) + datasetId = waitForResult.dataSetId + log.success(`Data set #${datasetId} created at ${provider.pdp.serviceURL}`) + } + await repairUpdate({ + localDb, + repairId: repair.id, + targetDataSetId: datasetId, + }) + return datasetId +} diff --git a/packages/repair-cli/src/pipeline/pull.ts b/packages/repair-cli/src/pipeline/pull.ts new file mode 100644 index 0000000..34b27d3 --- /dev/null +++ b/packages/repair-cli/src/pipeline/pull.ts @@ -0,0 +1,255 @@ +import { taskLog } from '@clack/prompts' +import * as Piece from '@filoz/synapse-core/piece' +import { createPieceUrlPDP } from '@filoz/synapse-core/piece' +import * as SP from '@filoz/synapse-core/sp' +import { and, asc, eq, gt, inArray } from 'drizzle-orm' +import PQueue from 'p-queue' +import { getTargetDataset } from '../db/get-target-dataset.ts' +import { syncPiecesOnchain } from '../db/sync-pieces-onchain.ts' +import { updateOperation } from '../db/update-operation.ts' +import { upsertOperations } from '../db/upsert-operations.ts' +import type { OperationSelect, RepairSelect } from '../local-schema.ts' +import type { IndexerDatabase, LocalDatabase, WalletClient } from '../types.ts' +import { hashLink } from '../utils.ts' + +/** Pending `add_piece` operations batched for a single pull job. */ +export type PullPiecesBatch = { + operations: OperationSelect[] +} + +export type RunPullPiecesPhaseOptions = { + localDb: LocalDatabase + indexerDb: IndexerDatabase + repair: RepairSelect + concurrency: number + batchSize: number + client: WalletClient + reset: boolean +} + +/** Mock pull worker: logs each batch and its piece CIDs. */ +export function createPullPiecesWorker({ + localDb, + indexerDb, + repair, + client, + state, + log, +}: { + localDb: LocalDatabase + indexerDb: IndexerDatabase + repair: RepairSelect + client: WalletClient + state: { + totalBatches: number + totalOperations: number + completedOperations: number + failedOperations: number + } + log: ReturnType +}) { + return async (batch: PullPiecesBatch, batchNumber: number) => { + let completedCids = 0 + let failedCids = 0 + const cidToOperation = new Map() + + const spin = log.group(`Batch ${batchNumber}/${state.totalBatches}`) + spin.message(`Pull 0 completed, 0 failed`) + + try { + const dataset = await getTargetDataset({ localDb, repairId: repair.id, client }) + + for (const operation of batch.operations) { + cidToOperation.set(operation.cid, operation) + } + + // sync pieces onchain to avoid duplicates + const completedOperations1 = await syncPiecesOnchain({ + indexerDb, + localDb, + dataSetId: dataset.dataSetId, + cidToOperation, + }) + state.completedOperations += completedOperations1 + completedCids += completedOperations1 + + // create pull pieces + const pullPieces: SP.PullPieceInput[] = [] + for (const [cid, operation] of cidToOperation) { + const pieceCid = Piece.from(cid) + const sourceUrl = createPieceUrlPDP({ + cid, + serviceURL: operation.alternateProvider, + }) + pullPieces.push({ pieceCid, sourceUrl }) + } + + if (pullPieces.length > 0) { + // wait for pull pieces + const pullResult = await SP.waitForPullPieces(client, { + serviceURL: repair.targetProviderUrl, + dataSetId: dataset.dataSetId, + clientDataSetId: dataset.clientDataSetId, + pieces: pullPieces, + timeout: 1000 * 60 * 30, + onStatus: (_status) => { + const completed = _status.pieces.filter((piece) => piece.status === 'complete').length + const failed = _status.pieces.filter((piece) => piece.status === 'failed').length + spin.message(`Pull ${completed} completed, ${failed} failed`) + }, + }) + + for (const { pieceCid, status } of pullResult.pieces) { + const cid = pieceCid.toString() + const operation = cidToOperation.get(cid) + if (!operation) { + console.log(`operation not found for cid ${cid}`) + continue + } + + if (status !== 'complete') { + state.failedOperations++ + failedCids++ + cidToOperation.delete(cid) + await updateOperation({ + localDb, + operationId: operation.id, + status: 'failed', + error: `pull failed with status ${status}`, + }) + } + } + } + + // sync against indexer to avoid duplicates + const completedOperations2 = await syncPiecesOnchain({ + indexerDb, + localDb, + dataSetId: dataset.dataSetId, + cidToOperation, + }) + state.completedOperations += completedOperations2 + completedCids += completedOperations2 + + const commitPieces: SP.addPieces.PieceType[] = [] + for (const [cid] of cidToOperation) { + commitPieces.push({ + pieceCid: Piece.from(cid), + }) + } + + if (commitPieces.length > 0) { + const addPiecesResult = await SP.addPieces(client, { + serviceURL: repair.targetProviderUrl, + dataSetId: dataset.dataSetId, + clientDataSetId: dataset.clientDataSetId, + pieces: commitPieces, + }) + + spin.message(`Waiting for add pieces ${hashLink(addPiecesResult.txHash, client.chain)}...`) + const addPiecesResult2 = await SP.waitForAddPieces(addPiecesResult) + state.completedOperations += cidToOperation.size + completedCids += cidToOperation.size + await upsertOperations({ + localDb, + operations: Array.from(cidToOperation.values()).map((operation) => ({ + ...operation, + status: 'completed', + error: null, + result: { dataSetId: addPiecesResult2.dataSetId, txHash: addPiecesResult2.txHash }, + })), + }) + } + spin.success(`Batch ${batchNumber}/${state.totalBatches} ${completedCids} added, ${failedCids} failed`) + } catch (error) { + state.failedOperations += cidToOperation.size + const message = error instanceof Error ? error.message : 'Unknown error' + spin.error(`Batch ${batchNumber}/${state.totalBatches} - ${message.replace(/\n/g, ' ')}`) + await upsertOperations({ + localDb, + operations: Array.from(cidToOperation.values()).map((operation) => ({ + ...operation, + status: 'failed', + error: message, + })), + }) + } + } +} + +/** + * Pull pending `add_piece` operations without loading the whole repair into memory. + * + * Pending piece operations are fetched lazily and queued with bounded backpressure. Failed piece + * operations are intentionally skipped unless `reset` is set. + */ +export async function runPullPiecesPhase({ + localDb, + indexerDb, + repair, + concurrency, + batchSize, + client, + reset, +}: RunPullPiecesPhaseOptions): Promise { + const localSchema = localDb._.fullSchema + const pullConcurrency = Math.max(1, concurrency) + const pullBatchSize = Math.max(1, batchSize) + let pullCursor = 0 + + const totalOperations = await localDb.$count( + localSchema.operations, + and( + eq(localSchema.operations.repairId, repair.id), + eq(localSchema.operations.type, 'add_piece'), + inArray(localSchema.operations.status, reset ? ['pending', 'failed'] : ['pending']) + ) + ) + let batchNumber = 0 + const state = { + totalBatches: Math.ceil(totalOperations / pullBatchSize), + totalOperations, + completedOperations: 0, + failedOperations: 0, + } + + const log = taskLog({ + title: 'Pulling pieces', + limit: 1, + }) + + async function getNextPullBatch(): Promise { + const operations = await localDb.query.operations.findMany({ + where: and( + eq(localSchema.operations.repairId, repair.id), + eq(localSchema.operations.type, 'add_piece'), + inArray(localSchema.operations.status, reset ? ['pending', 'failed'] : ['pending']), + gt(localSchema.operations.id, pullCursor) + ), + orderBy: [asc(localSchema.operations.id)], + limit: pullBatchSize, + }) + if (operations.length === 0) { + return null + } + + pullCursor = operations.at(-1)?.id ?? pullCursor + return { operations } + } + + const pullPiecesWorker = createPullPiecesWorker({ localDb, indexerDb, repair, client, state, log }) + const pullPiecesQueue = new PQueue({ concurrency: pullConcurrency }) + + while (true) { + await pullPiecesQueue.onSizeLessThan(pullConcurrency) + const batch = await getNextPullBatch() + if (!batch) break + batchNumber++ + const currentBatchNumber = batchNumber + pullPiecesQueue.add(() => pullPiecesWorker(batch, currentBatchNumber)).catch(console.error) + } + + await pullPiecesQueue.onIdle() + + log.success(`Pulled ${state.completedOperations} pieces, ${state.failedOperations} failed`) +} diff --git a/packages/repair-cli/src/types.ts b/packages/repair-cli/src/types.ts new file mode 100644 index 0000000..677ca91 --- /dev/null +++ b/packages/repair-cli/src/types.ts @@ -0,0 +1,41 @@ +import type { Chain } from '@filoz/synapse-core/chains' +import type { Client } from '@libsql/client' +import type { LibSQLDatabase } from 'drizzle-orm/libsql' +import type { NodePgDatabase } from 'drizzle-orm/node-postgres' +import type { z } from 'incur' +import type { Pool } from 'pg' +import type { Account, Address, Hex, Transport, Client as ViemClient } from 'viem' +import type * as indexerSchema from './indexer-schema.ts' +import type * as localSchema from './local-schema.ts' +import type { contextSchema } from './middleware.ts' +export type LocalDatabase = LibSQLDatabase & { + $client: Client +} + +export type IndexerDatabase = NodePgDatabase & { + $client: Pool +} + +export interface Config { + privateKey: Hex + indexerMainnetUrl: string + indexerCalibrationUrl: string + chainId: number + dbPath: string +} + +export type WalletClient = ViemClient + +export type Context = z.infer + +/** + * Provider details used for repair selection and CID replica lookup. + */ +export type RepairProvider = { + providerId: bigint + providerAddress: Address + name: string + serviceUrl: string + approved: boolean + endorsed: boolean +} diff --git a/packages/repair-cli/src/utils.ts b/packages/repair-cli/src/utils.ts new file mode 100644 index 0000000..aaabb5c --- /dev/null +++ b/packages/repair-cli/src/utils.ts @@ -0,0 +1,190 @@ +import type { MetadataObject } from '@filoz/synapse-core' +import { type Chain, getChain } from '@filoz/synapse-core/chains' +import Conf from 'conf' +import { pushSQLiteSchema } from 'drizzle-kit/api' +import { getTableColumns, type SQL, sql } from 'drizzle-orm' +import { drizzle } from 'drizzle-orm/libsql' +import type { PgTable } from 'drizzle-orm/pg-core' +import type { SQLiteTable } from 'drizzle-orm/sqlite-core' +import { z } from 'incur' +import { request } from 'iso-web/http' +import pLocate from 'p-locate' +import terminalLink from 'terminal-link' +import { createWalletClient, http } from 'viem' +import { privateKeyToAccount } from 'viem/accounts' +import packageJson from '../package.json' with { type: 'json' } +import * as schema from './local-schema.ts' +import type { Config, LocalDatabase } from './types.ts' + +export const EARLY_REPAIR_SOURCE = 'early-repair6' + +export const config = new Conf({ + projectName: packageJson.name, + projectSuffix: '', + schema: { + privateKey: { + type: 'string', + }, + dbPath: { + type: 'string', + }, + indexerMainnetUrl: { + type: 'string', + }, + indexerCalibrationUrl: { + type: 'string', + }, + chainId: { + type: 'number', + }, + }, +}) + +export const name = packageJson.name +export const version = packageJson.version + +function privateKeyFromConfig() { + const privateKey = config.get('privateKey') + if (!privateKey) { + throw new Error('Private key not found. Please run `repair-cli setup` first.') + } + return privateKey +} + +/** + * Create a private key client + * If the private key is not found, it will throw an error + * + * @param chainId - The chain ID to use + */ +export function getClient(chainId: number) { + const chain = getChain(chainId) + + const privateKey = privateKeyFromConfig() + + const account = privateKeyToAccount(privateKey) + const client = createWalletClient({ + account, + chain, + transport: http(), + }) + return { + client, + chain, + } +} + +/** + * Global options for the CLI + * - debug - Debug mode + */ +export const globalOptions = z.object({ + debug: z.boolean().optional().default(false).describe('Debug mode'), +}) + +export async function createLocalDatabase(dbPath: string): Promise { + const localDb = drizzle(`file:${dbPath}`, { + schema, + }) as LocalDatabase + + await localDb.$client.execute('PRAGMA journal_mode = WAL') + + return localDb +} + +export async function migrateLocalDatabase(db: LocalDatabase) { + // @ts-expect-error - TODO: fix this + const result = await pushSQLiteSchema(schema, db) + if (result.hasDataLoss) { + throw new Error('Data loss detected during migration') + } + if (result.warnings.length > 0) { + throw new Error(`Warnings detected during migration:\n${result.warnings.join('\n')}`) + } + + await result.apply() + return result +} + +/** + * Create a link to the hash on the block explorer + * + * @param hash - The hash to create a link for + * @param chain - The chain to use + * @returns The link + */ +export function hashLink(hash: string, chain: Chain) { + const link = terminalLink(hash, `${chain.blockExplorers?.default?.url}/tx/${hash}`) + return link +} + +/** Get metadata for the single IPFS-enabled repair dataset. */ +export function getRepairDatasetMetadata(): MetadataObject { + return { + source: EARLY_REPAIR_SOURCE, + withIPFSIndexing: '', + } +} + +/** + * Get a piece from a service URL + */ +export async function getPiece({ pieceCid, serviceUrl }: { pieceCid: string; serviceUrl: string }) { + const url = new URL(`/piece/${pieceCid}`, serviceUrl) + const response = await request.head(url, { + retry: { + retries: 2, + minTimeout: 250, + }, + timeout: 3000, + }) + + if (response.error) { + // console.log(response.error.message, url.toString()) + throw response.error + } + return pieceCid +} + +/** + * Find the piece on the providers + * + * @param providers - {@link string[]} + * @param pieceCid - {@link string} + * @returns The piece URL + */ +export async function findPieceOnProviders(providers: string[], pieceCid: string) { + const result = await pLocate( + providers.map((p) => + getPiece({ + serviceUrl: p, + pieceCid, + }).then( + () => p, + () => undefined + ) + ), + (p) => p !== undefined, + { concurrency: 5 } + ) + return result +} + +export const buildConflictUpdateColumns = ( + table: T, + columns?: Q[] +) => { + const cls = getTableColumns(table) + const cols = columns ?? (Object.keys(cls) as Q[]) + const r = cols.reduce( + (acc, column) => { + const colName = cls[column].name + + acc[column] = sql.raw(`excluded.${colName}`) + return acc + }, + {} as Record + ) + + return r +} diff --git a/packages/repair-cli/tsconfig.json b/packages/repair-cli/tsconfig.json index 28b5d94..df2f70c 100644 --- a/packages/repair-cli/tsconfig.json +++ b/packages/repair-cli/tsconfig.json @@ -2,8 +2,8 @@ "extends": "../../tsconfig.json", "compilerOptions": { "outDir": "./dist", - "types": ["mocha", "node"] + "types": ["node"] }, - "include": ["src", "test"], + "include": ["src", "package.json"], "exclude": ["node_modules", "dist"] } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2028bb1..dee6ba6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -7,33 +7,20 @@ settings: catalogs: default: '@biomejs/biome': - specifier: 2.4.11 - version: 2.4.11 - '@types/mocha': - specifier: ^10.0.10 - version: 10.0.10 + specifier: 2.4.16 + version: 2.4.16 '@types/node': - specifier: ^25.6.0 - version: 25.6.0 - mocha: - specifier: ^11.7.4 - version: 11.7.5 - msw: - specifier: 2.14.2 - version: 2.14.2 + specifier: ^25.9.2 + version: 25.9.2 + drizzle-orm: + specifier: ^0.45.2 + version: 0.45.2 typescript: specifier: 6.0.3 version: 6.0.3 viem: - specifier: ^2.47.17 - version: 2.48.8 - -overrides: - '@hono/node-server': ^1.19.13 - drizzle-orm: ^0.45.2 - esbuild: ^0.25.0 - kysely: ^0.28.14 - vite: ^6.4.2 + specifier: ^2.50.4 + version: 2.51.3 importers: @@ -41,10 +28,10 @@ importers: devDependencies: '@biomejs/biome': specifier: 'catalog:' - version: 2.4.11 + version: 2.4.16 node: specifier: runtime:^24.14.0 - version: runtime:24.15.0 + version: runtime:24.16.0 typescript: specifier: 'catalog:' version: 6.0.3 @@ -59,75 +46,112 @@ importers: version: link:../../packages/repair-db hono: specifier: ^4.12.18 - version: 4.12.18 + version: 4.12.23 multiformats: specifier: ^13 version: 13.4.2 ponder: specifier: npm:@rvagg/ponder@^0.16.6 - version: '@rvagg/ponder@0.16.6(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(hono@4.12.18)(typescript@6.0.3)(viem@2.48.8(typescript@6.0.3))' + version: '@rvagg/ponder@0.16.6(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/node@25.9.2)(@types/pg@8.20.0)(hono@4.12.23)(typescript@6.0.3)(viem@2.51.3(typescript@6.0.3))' viem: specifier: 'catalog:' - version: 2.48.8(typescript@6.0.3) + version: 2.51.3(typescript@6.0.3)(zod@4.4.3) devDependencies: '@biomejs/biome': specifier: 'catalog:' - version: 2.4.11 + version: 2.4.16 '@types/node': specifier: 'catalog:' - version: 25.6.0 + version: 25.9.2 drizzle-orm: specifier: ^0.45.2 - version: 0.45.2(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.1)(kysely@0.28.17)(pg@8.20.0) + version: 0.45.2(@electric-sql/pglite@0.2.13)(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(kysely@0.26.3)(pg@8.21.0) typescript: specifier: 'catalog:' version: 6.0.3 packages/repair-cli: + dependencies: + '@clack/prompts': + specifier: ^1.5.1 + version: 1.5.1 + '@filoz/repair-db': + specifier: workspace:* + version: link:../repair-db + '@filoz/synapse-core': + specifier: ^0.6.0 + version: 0.6.0(typescript@6.0.3)(viem@2.51.3(typescript@6.0.3)(zod@4.4.3)) + '@libsql/client': + specifier: ^0.17.3 + version: 0.17.3 + conf: + specifier: ^15.1.0 + version: 15.1.0 + drizzle-kit: + specifier: ^0.31.10 + version: 0.31.10 + drizzle-orm: + specifier: 'catalog:' + version: 0.45.2(@electric-sql/pglite@0.2.13)(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(kysely@0.29.2)(pg@8.21.0) + incur: + specifier: ^0.4.6 + version: 0.4.8 + iso-base: + specifier: ^4.4.0 + version: 4.4.0 + iso-web: + specifier: ^3.1.2 + version: 3.1.2 + p-all: + specifier: ^5.0.1 + version: 5.0.1 + p-locate: + specifier: ^7.0.0 + version: 7.0.0 + p-map: + specifier: ^7.0.4 + version: 7.0.4 + p-queue: + specifier: ^9.3.0 + version: 9.3.0 + pg: + specifier: ^8.21.0 + version: 8.21.0 + terminal-link: + specifier: ^5.0.0 + version: 5.0.0 devDependencies: '@biomejs/biome': specifier: 'catalog:' - version: 2.4.11 - '@types/assert': - specifier: ^1.5.11 - version: 1.5.11 - '@types/mocha': - specifier: 'catalog:' - version: 10.0.10 + version: 2.4.16 '@types/node': specifier: 'catalog:' - version: 25.6.0 - assert: - specifier: ^2.1.0 - version: 2.1.0 - mocha: - specifier: 'catalog:' - version: 11.7.5 - msw: - specifier: 'catalog:' - version: 2.14.2(@types/node@25.6.0)(typescript@6.0.3) + version: 25.9.2 + '@types/pg': + specifier: ^8.20.0 + version: 8.20.0 playwright-test: specifier: ^14.1.12 - version: 14.1.13 + version: 14.1.15 type-fest: - specifier: ^5.4.3 - version: 5.6.0 + specifier: ^5.7.0 + version: 5.7.0 typescript: specifier: 'catalog:' version: 6.0.3 viem: specifier: 'catalog:' - version: 2.48.8(typescript@6.0.3) + version: 2.51.3(typescript@6.0.3)(zod@4.4.3) packages/repair-db: dependencies: drizzle-orm: - specifier: ^0.45.2 - version: 0.45.2(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.1)(kysely@0.28.17)(pg@8.20.0) + specifier: 'catalog:' + version: 0.45.2(@electric-sql/pglite@0.2.13)(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(kysely@0.29.2)(pg@8.21.0) devDependencies: '@biomejs/biome': specifier: 'catalog:' - version: 2.4.11 + version: 2.4.16 typescript: specifier: 'catalog:' version: 6.0.3 @@ -141,80 +165,94 @@ packages: resolution: {integrity: sha512-UQFQ6SgyJ6LX42W8rHCs8KVc0JS0tzVL9ct4XYedJukskYVWTo49tNiMEK9C2HTyarbNiT/RVIRSY82vH+6sTg==} engines: {node: '>=4'} - '@babel/code-frame@7.29.0': - resolution: {integrity: sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==} + '@babel/code-frame@7.29.7': + resolution: {integrity: sha512-Aup7aUOfpbAUg2ROOJN6Iw5f9DMBlzu0mIkm/malLQFN/YQgO48wCj0Kxa3sEHJvPVFg7siR+qRInwXd2qhQKw==} engines: {node: '>=6.9.0'} - '@babel/helper-validator-identifier@7.28.5': - resolution: {integrity: sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==} + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} engines: {node: '>=6.9.0'} '@bcoe/v8-coverage@1.0.2': resolution: {integrity: sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==} engines: {node: '>=18'} - '@biomejs/biome@2.4.11': - resolution: {integrity: sha512-nWxHX8tf3Opb/qRgZpBbsTOqOodkbrkJ7S+JxJAruxOReaDPPmPuLBAGQ8vigyUgo0QBB+oQltNEAvalLcjggA==} + '@biomejs/biome@2.4.16': + resolution: {integrity: sha512-x9ajFh1zChVybCiM3TN6OD4phAqLgtPZjFrZF+aTMYCPjwBO+k529TX7PPsAqtGNLeV4UgzwQnowEgS7bGmzcA==} engines: {node: '>=14.21.3'} hasBin: true - '@biomejs/cli-darwin-arm64@2.4.11': - resolution: {integrity: sha512-wOt+ed+L2dgZanWyL6i29qlXMc088N11optzpo10peayObBaAshbTcxKUchzEMp9QSY8rh5h6VfAFE3WTS1rqg==} + '@biomejs/cli-darwin-arm64@2.4.16': + resolution: {integrity: sha512-wxPvu4XOA85YJk9ixSWUmq/QBHbid85BISbOAqqBM/5xQpPk9ayjk5375tOlSC0BeCwNSbPFafQBm+vBumXq0A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [darwin] - '@biomejs/cli-darwin-x64@2.4.11': - resolution: {integrity: sha512-gZ6zR8XmZlExfi/Pz/PffmdpWOQ8Qhy7oBztgkR8/ylSRyLwfRPSadmiVCV8WQ8PoJ2MWUy2fgID9zmtgUUJmw==} + '@biomejs/cli-darwin-x64@2.4.16': + resolution: {integrity: sha512-xFCqGPwYusQJp4N4NJLi1XJiZqjwFdjhT+KqtNy+Ug3qgfczqnTa6MSDvxJF6TkuDLoYJItMapz6tAf7kCekFw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [darwin] - '@biomejs/cli-linux-arm64-musl@2.4.11': - resolution: {integrity: sha512-+Sbo1OAmlegtdwqFE8iOxFIWLh1B3OEgsuZfBpyyN/kWuqZ8dx9ZEes6zVnDMo+zRHF2wLynRVhoQmV7ohxl2Q==} + '@biomejs/cli-linux-arm64-musl@2.4.16': + resolution: {integrity: sha512-oYxnW0ARfJkr72ezzF2OR8N/rtkgLUQeYtF8cFhVswbknHxtTcmzSsanVJP8yQKnGpGpc2ck6c5zLvHahL6Cbg==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [musl] - '@biomejs/cli-linux-arm64@2.4.11': - resolution: {integrity: sha512-avdJaEElXrKceK0va9FkJ4P5ci3N01TGkc6ni3P8l3BElqbOz42Wg2IyX3gbh0ZLEd4HVKEIrmuVu/AMuSeFFA==} + '@biomejs/cli-linux-arm64@2.4.16': + resolution: {integrity: sha512-2kFb4//jxfZaP6D+Rj5VkHkxgyD9EoRAVBEQb8PKRv+s4NO2zYNJKXFaJmK1CmhufJOWEfpHKaRbOja7qjmdhQ==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [linux] libc: [glibc] - '@biomejs/cli-linux-x64-musl@2.4.11': - resolution: {integrity: sha512-bexd2IklK7ZgPhrz6jXzpIL6dEAH9MlJU1xGTrypx+FICxrXUp4CqtwfiuoDKse+UlgAlWtzML3jrMqeEAHEhA==} + '@biomejs/cli-linux-x64-musl@2.4.16': + resolution: {integrity: sha512-iHDS+MCM65DPqWGu+ECC3uoALyj2H7F4nVUPxIPjz/PIl94EUu+EDfGZDzFP+NY1EOPVt9NQvwFqq7HdMmowdg==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [musl] - '@biomejs/cli-linux-x64@2.4.11': - resolution: {integrity: sha512-TagWV0iomp5LnEnxWFg4nQO+e52Fow349vaX0Q/PIcX6Zhk4GGBgp3qqZ8PVkpC+cuehRctMf3+6+FgQ8jCEFQ==} + '@biomejs/cli-linux-x64@2.4.16': + resolution: {integrity: sha512-NbcBbi/nJqn5baae6wqRXdS7Gadf2uRpehSh6vMSYpG8OhkXl/Xg8aorWrJ+9VWqAT5ml90alLvorkpMW0nBwQ==} engines: {node: '>=14.21.3'} cpu: [x64] os: [linux] libc: [glibc] - '@biomejs/cli-win32-arm64@2.4.11': - resolution: {integrity: sha512-RJhaTnY8byzxDt4bDVb7AFPHkPcjOPK3xBip4ZRTrN3TEfyhjLRm3r3mqknqydgVTB74XG8l4jMLwEACEeihVg==} + '@biomejs/cli-win32-arm64@2.4.16': + resolution: {integrity: sha512-0rgImMsNb5v/chhkIFe3wu7PEFClS6RBAYUijGL9UsYN3PanSaoK24HSSuSJb1pYbYYVjzAyZTl3gtjJ84BM8A==} engines: {node: '>=14.21.3'} cpu: [arm64] os: [win32] - '@biomejs/cli-win32-x64@2.4.11': - resolution: {integrity: sha512-A8D3JM/00C2KQgUV3oj8Ba15EHEYwebAGCy5Sf9GAjr5Y3+kJIYOiESoqRDeuRZueuMdCsbLZIUqmPhpYXJE9A==} + '@biomejs/cli-win32-x64@2.4.16': + resolution: {integrity: sha512-Kp85jgoBHa05gix6UIRjfCDiUV3w/8VIdZ247VyyO2gEjaw12WEVhdIjlxp/AMzXxqxQwbxNTDVZ3Mwd2RG5rw==} engines: {node: '>=14.21.3'} cpu: [x64] os: [win32] + '@cfworker/json-schema@4.1.1': + resolution: {integrity: sha512-gAmrUZSGtKc3AiBL71iNWxDsyUC5uMaKKGdvzYsBoTW/xi42JQHl7eKV2OYzCUqvc+D2RCcf7EXY2iCyFIk6og==} + + '@clack/core@1.4.1': + resolution: {integrity: sha512-FILJa1gGKEFTGZAJE9RpVhrjKz3c3h4ar60dSv6cGuDqufQ84YEIS3GAGvZiN+H6yaLbbvTFNejjCC4tXpZEuw==} + engines: {node: '>= 20.12.0'} + + '@clack/prompts@1.5.1': + resolution: {integrity: sha512-zccHj2z2oCCO4yrDiRSlFOxWerGqRiysP7a5jPK6uoI9URKAquwY42Dd/iUP8JWHxEzdRe4TlbvZCo8z1/mhrw==} + engines: {node: '>= 20.12.0'} + '@commander-js/extra-typings@12.1.0': resolution: {integrity: sha512-wf/lwQvWAA0goIghcb91dQYpkLBcyhOhQNqG/VgWhnKzgt+UOMvra7EX/2fv70arm5RW+PUHoQHHDa6/p77Eqg==} peerDependencies: commander: ~12.1.0 + '@drizzle-team/brocli@0.10.2': + resolution: {integrity: sha512-z33Il7l5dKjUgGULTqBsQBQwckHh5AbIuxhdsIxDDiZAzBOrZO6q9ogcWC65kU382AfynTfgNumVcNIjuIua6w==} + '@electric-sql/pglite@0.2.13': resolution: {integrity: sha512-YRY806NnScVqa21/1L1vaysSQ+0/cAva50z7vlwzaGiBOTS9JhdzIRHN0KfgMhobFAphbznZJ7urMso4RtMBIQ==} @@ -230,162 +268,752 @@ packages: resolution: {integrity: sha512-CsFmA3u3c2QoLDTfEpGr4t25fjMU31nyvse7IzWTvb0ZycuPjMjb0fjlheh+PbhBYb9YLugnT2uY6Mwcg1o+Zg==} engines: {node: '>=18.0.0'} + '@esbuild-kit/core-utils@3.3.2': + resolution: {integrity: sha512-sPRAnw9CdSsRmEtnsl2WXWdyquogVpB3yZ3dgwJfe8zrOzTsV7cJvmwrKVa+0ma5BoiGJ+BoqkMvawbayKUsqQ==} + deprecated: 'Merged into tsx: https://tsx.is' + + '@esbuild-kit/esm-loader@2.6.5': + resolution: {integrity: sha512-FxEMIkJKnodyA1OaCUoEvbYRkoZlLZ4d/eXFu9Fh8CbBBgP5EmZxrfTRyN0qpXZ4vOvqnE5YdRdcrmUUXuU+dA==} + deprecated: 'Merged into tsx: https://tsx.is' + + '@esbuild/aix-ppc64@0.21.5': + resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [aix] + '@esbuild/aix-ppc64@0.25.11': resolution: {integrity: sha512-Xt1dOL13m8u0WE8iplx9Ibbm+hFAO0GsU2P34UNoDGvZYkY8ifSiy6Zuc1lYxfG7svWE2fzqCUmFp5HCn51gJg==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-lhRUCeuOyJQURhTxl4WkpFTjIsbDayJHih5kZC1giwE+MhIzAb7mEsQMqMf18rHLsrb5qI1tafG20mLxEWcWlA==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.18.20': + resolution: {integrity: sha512-Nz4rJcchGDtENV0eMKUNa6L12zz2zBDXuhj/Vjh18zGqB44Bi7MBMSXjgunJgjRhCmKOjnPuZp4Mb6OKqtMHLQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm64@0.21.5': + resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [android] + '@esbuild/android-arm64@0.25.11': resolution: {integrity: sha512-9slpyFBc4FPPz48+f6jyiXOx/Y4v34TUeDDXJpZqAWQn/08lKGeD8aDp9TMn9jDz2CiEuHwfhRmGBvpnd/PWIQ==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-+WzIXQOSaGs33tLEgYPYe/yQHf0WTU0X42Jca3y8NWMbUVhp7rUnw+vAsRC/QiDrdD31IszMrZy+qwPOPjd+rw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.18.20': + resolution: {integrity: sha512-fyi7TDI/ijKKNZTUJAQqiG5T7YjJXgnzkURqmGj13C6dCqckZBLdl4h7bkhHt/t0WP+zO9/zwroDvANaOqO5Sw==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + + '@esbuild/android-arm@0.21.5': + resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==} + engines: {node: '>=12'} + cpu: [arm] + os: [android] + '@esbuild/android-arm@0.25.11': resolution: {integrity: sha512-uoa7dU+Dt3HYsethkJ1k6Z9YdcHjTrSb5NUy66ZfZaSV8hEYGD5ZHbEMXnqLFlbBflLsl89Zke7CAdDJ4JI+Gg==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-wqh0ByljabXLKHeWXYLqoJ5jKC4XBaw6Hk08OfMrCRd2nP2ZQ5eleDZC41XHyCNgktBGYMbqnrJKq/K/lzPMSQ==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.18.20': + resolution: {integrity: sha512-8GDdlePJA8D6zlZYJV/jnrRAi6rOiNaCC/JclcXpB+KIuvfBN4owLtgzY2bsxnx666XjJx2kDPUmnTtR8qKQUg==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + + '@esbuild/android-x64@0.21.5': + resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==} + engines: {node: '>=12'} + cpu: [x64] + os: [android] + '@esbuild/android-x64@0.25.11': resolution: {integrity: sha512-Sgiab4xBjPU1QoPEIqS3Xx+R2lezu0LKIEcYe6pftr56PqPygbB7+szVnzoShbx64MUupqoE0KyRlN7gezbl8g==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-+VJggoaKhk2VNNqVL7f6S189UzShHC/mR9EE8rDdSkdpN0KflSwWY/gWjDrNxxisg8Fp1ZCD9jLMo4m0OUfeUA==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.18.20': + resolution: {integrity: sha512-bxRHW5kHU38zS2lPTPOyuyTm+S+eobPUnTNkdJEfAddYgEcll4xkT8DB9d2008DtTbl7uJag2HuE5NZAZgnNEA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-arm64@0.21.5': + resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==} + engines: {node: '>=12'} + cpu: [arm64] + os: [darwin] + '@esbuild/darwin-arm64@0.25.11': resolution: {integrity: sha512-VekY0PBCukppoQrycFxUqkCojnTQhdec0vevUL/EDOCnXd9LKWqD/bHwMPzigIJXPhC59Vd1WFIL57SKs2mg4w==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-0T+A9WZm+bZ84nZBtk1ckYsOvyA3x7e2Acj1KdVfV4/2tdG4fzUp91YHx+GArWLtwqp77pBXVCPn2We7Letr0Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.18.20': + resolution: {integrity: sha512-pc5gxlMDxzm513qPGbCbDukOdsGtKhfxD1zJKXjCCcU7ju50O7MeAZ8c4krSJcOIJGFR+qx21yMMVYwiQvyTyQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + + '@esbuild/darwin-x64@0.21.5': + resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==} + engines: {node: '>=12'} + cpu: [x64] + os: [darwin] + '@esbuild/darwin-x64@0.25.11': resolution: {integrity: sha512-+hfp3yfBalNEpTGp9loYgbknjR695HkqtY3d3/JjSRUyPg/xd6q+mQqIb5qdywnDxRZykIHs3axEqU6l1+oWEQ==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-fyzLm/DLDl/84OCfp2f/XQ4flmORsjU7VKt8HLjvIXChJoFFOIL6pLJPH4Yhd1n1gGFF9mPwtlN5Wf82DZs+LQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.18.20': + resolution: {integrity: sha512-yqDQHy4QHevpMAaxhhIwYPMv1NECwOvIpGCZkECn8w2WFHXjEwrBn3CeNIYsibZ/iZEUemj++M26W3cNR5h+Tw==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-arm64@0.21.5': + resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==} + engines: {node: '>=12'} + cpu: [arm64] + os: [freebsd] + '@esbuild/freebsd-arm64@0.25.11': resolution: {integrity: sha512-CmKjrnayyTJF2eVuO//uSjl/K3KsMIeYeyN7FyDBjsR3lnSJHaXlVoAK8DZa7lXWChbuOk7NjAc7ygAwrnPBhA==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-l9GeW5UZBT9k9brBYI+0WDffcRxgHQD8ShN2Ur4xWq/NFzUKm3k5lsH4PdaRgb2w7mI9u61nr2gI2mLI27Nh3Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.18.20': + resolution: {integrity: sha512-tgWRPPuQsd3RmBZwarGVHZQvtzfEBOreNuxEMKFcd5DaDn2PbBxfwLcj4+aenoh7ctXcbXmOQIn8HI6mCSw5MQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.21.5': + resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [freebsd] + '@esbuild/freebsd-x64@0.25.11': resolution: {integrity: sha512-Dyq+5oscTJvMaYPvW3x3FLpi2+gSZTCE/1ffdwuM6G1ARang/mb3jvjxs0mw6n3Lsw84ocfo9CrNMqc5lTfGOw==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-BXoQai/A0wPO6Es3yFJ7APCiKGc1tdAEOgeTNy3SsB491S3aHn4S4r3e976eUnPdU+NbdtmBuLncYir2tMU9Nw==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.18.20': + resolution: {integrity: sha512-2YbscF+UL7SQAVIpnWvYwM+3LskyDmPhe31pE7/aoTMFKKzIc9lLbyGUpmmb8a8AixOL61sQ/mFh3jEjHYFvdA==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm64@0.21.5': + resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==} + engines: {node: '>=12'} + cpu: [arm64] + os: [linux] + '@esbuild/linux-arm64@0.25.11': resolution: {integrity: sha512-Qr8AzcplUhGvdyUF08A1kHU3Vr2O88xxP0Tm8GcdVOUm25XYcMPp2YqSVHbLuXzYQMf9Bh/iKx7YPqECs6ffLA==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-RVyzfb3FWsGA55n6WY0MEIEPURL1FcbhFE6BffZEMEekfCzCIMtB5yyDcFnVbTnwk+CLAgTujmV/Lgvih56W+A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.18.20': + resolution: {integrity: sha512-/5bHkMWnq1EgKr1V+Ybz3s1hWXok7mDFUMQ4cG10AfW3wL02PSZi5kFpYKrptDsgb2WAJIvRcDm+qIvXf/apvg==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-arm@0.21.5': + resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==} + engines: {node: '>=12'} + cpu: [arm] + os: [linux] + '@esbuild/linux-arm@0.25.11': resolution: {integrity: sha512-TBMv6B4kCfrGJ8cUPo7vd6NECZH/8hPpBHHlYI3qzoYFvWu2AdTvZNuU/7hsbKWqu/COU7NIK12dHAAqBLLXgw==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-CjaaREJagqJp7iTaNQjjidaNbCKYcd4IDkzbwwxtSvjI7NZm79qiHc8HqciMddQ6CKvJT6aBd8lO9kN/ZudLlw==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.18.20': + resolution: {integrity: sha512-P4etWwq6IsReT0E1KHU40bOnzMHoH73aXp96Fs8TIT6z9Hu8G6+0SHSw9i2isWrD2nbx2qo5yUqACgdfVGx7TA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-ia32@0.21.5': + resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==} + engines: {node: '>=12'} + cpu: [ia32] + os: [linux] + '@esbuild/linux-ia32@0.25.11': resolution: {integrity: sha512-TmnJg8BMGPehs5JKrCLqyWTVAvielc615jbkOirATQvWWB1NMXY77oLMzsUjRLa0+ngecEmDGqt5jiDC6bfvOw==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-KBnSTt1kxl9x70q+ydterVdl+Cn0H18ngRMRCEQfrbqdUuntQQ0LoMZv47uB97NljZFzY6HcfqEZ2SAyIUTQBQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.18.20': + resolution: {integrity: sha512-nXW8nqBTrOpDLPgPY9uV+/1DjxoQ7DoB2N8eocyq8I9XuqJ7BiAMDMf9n1xZM9TgW0J8zrquIb/A7s3BJv7rjg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-loong64@0.21.5': + resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==} + engines: {node: '>=12'} + cpu: [loong64] + os: [linux] + '@esbuild/linux-loong64@0.25.11': resolution: {integrity: sha512-DIGXL2+gvDaXlaq8xruNXUJdT5tF+SBbJQKbWy/0J7OhU8gOHOzKmGIlfTTl6nHaCOoipxQbuJi7O++ldrxgMw==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-zpSlUce1mnxzgBADvxKXX5sl8aYQHo2ezvMNI8I0lbblJtp8V4odlm3Yzlj7gPyt3T8ReksE6bK+pT3WD+aJRg==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.18.20': + resolution: {integrity: sha512-d5NeaXZcHp8PzYy5VnXV3VSd2D328Zb+9dEq5HE6bw6+N86JVPExrA6O68OPwobntbNJ0pzCpUFZTo3w0GyetQ==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-mips64el@0.21.5': + resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==} + engines: {node: '>=12'} + cpu: [mips64el] + os: [linux] + '@esbuild/linux-mips64el@0.25.11': resolution: {integrity: sha512-Osx1nALUJu4pU43o9OyjSCXokFkFbyzjXb6VhGIJZQ5JZi8ylCQ9/LFagolPsHtgw6himDSyb5ETSfmp4rpiKQ==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-2jIfP6mmjkdmeTlsX/9vmdmhBmKADrWqN7zcdtHIeNSCH1SqIoNI63cYsjQR8J+wGa4Y5izRcSHSm8K3QWmk3w==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.18.20': + resolution: {integrity: sha512-WHPyeScRNcmANnLQkq6AfyXRFr5D6N2sKgkFo2FqguP44Nw2eyDlbTdZwd9GYk98DZG9QItIiTlFLHJHjxP3FA==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-ppc64@0.21.5': + resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==} + engines: {node: '>=12'} + cpu: [ppc64] + os: [linux] + '@esbuild/linux-ppc64@0.25.11': resolution: {integrity: sha512-nbLFgsQQEsBa8XSgSTSlrnBSrpoWh7ioFDUmwo158gIm5NNP+17IYmNWzaIzWmgCxq56vfr34xGkOcZ7jX6CPw==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-bc0FE9wWeC0WBm49IQMPSPILRocGTQt3j5KPCA8os6VprfuJ7KD+5PzESSrJ6GmPIPJK965ZJHTUlSA6GNYEhg==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.18.20': + resolution: {integrity: sha512-WSxo6h5ecI5XH34KC7w5veNnKkju3zBRLEQNY7mv5mtBmrP/MjNBCAlsM2u5hDBlS3NGcTQpoBvRzqBcRtpq1A==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-riscv64@0.21.5': + resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==} + engines: {node: '>=12'} + cpu: [riscv64] + os: [linux] + '@esbuild/linux-riscv64@0.25.11': resolution: {integrity: sha512-HfyAmqZi9uBAbgKYP1yGuI7tSREXwIb438q0nqvlpxAOs3XnZ8RsisRfmVsgV486NdjD7Mw2UrFSw51lzUk1ww==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-SQPZOwoTTT/HXFXQJG/vBX8sOFagGqvZyXcgLA3NhIqcBv1BJU1d46c0rGcrij2B56Z2rNiSLaZOYW5cUk7yLQ==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.18.20': + resolution: {integrity: sha512-+8231GMs3mAEth6Ja1iK0a1sQ3ohfcpzpRLH8uuc5/KVDFneH6jtAJLFGafpzpMRO6DzJ6AvXKze9LfFMrIHVQ==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-s390x@0.21.5': + resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==} + engines: {node: '>=12'} + cpu: [s390x] + os: [linux] + '@esbuild/linux-s390x@0.25.11': resolution: {integrity: sha512-HjLqVgSSYnVXRisyfmzsH6mXqyvj0SA7pG5g+9W7ESgwA70AXYNpfKBqh1KbTxmQVaYxpzA/SvlB9oclGPbApw==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-SCfR0HN8CEEjnYnySJTd2cw0k9OHB/YFzt5zgJEwa+wL/T/raGWYMBqwDNAC6dqFKmJYZoQBRfHjgwLHGSrn3Q==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.18.20': + resolution: {integrity: sha512-UYqiqemphJcNsFEskc73jQ7B9jgwjWrSayxawS6UVFZGWrAAtkzjxSqnoclCXxWtfwLdzU+vTpcNYhpn43uP1w==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + + '@esbuild/linux-x64@0.21.5': + resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [linux] + '@esbuild/linux-x64@0.25.11': resolution: {integrity: sha512-HSFAT4+WYjIhrHxKBwGmOOSpphjYkcswF449j6EjsjbinTZbp8PJtjsVK1XFJStdzXdy/jaddAep2FGY+wyFAQ==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-us0dSb9iFxIi8srnpl931Nvs65it/Jd2a2K3qs7fz2WfGPHqzfzZTfec7oxZJRNPXPnNYZtanmRc4AL/JwVzHQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + '@esbuild/netbsd-arm64@0.25.11': resolution: {integrity: sha512-hr9Oxj1Fa4r04dNpWr3P8QKVVsjQhqrMSUzZzf+LZcYjZNqhA3IAfPQdEh1FLVUJSiu6sgAwp3OmwBfbFgG2Xg==} engines: {node: '>=18'} cpu: [arm64] os: [netbsd] + '@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.0': + resolution: {integrity: sha512-CR/RYotgtCKwtftMwJlUU7xCVNg3lMYZ0RzTmAHSfLCXw3NtZtNpswLEj/Kkf6kEL3Gw+BpOekRX0BYCtklhUw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.18.20': + resolution: {integrity: sha512-iO1c++VP6xUBUmltHZoMtCUdPlnPGdBom6IrO4gyKPFFVBKioIImVooR5I83nTew5UOYrk3gIJhbZh8X44y06A==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.21.5': + resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==} + engines: {node: '>=12'} + cpu: [x64] + os: [netbsd] + '@esbuild/netbsd-x64@0.25.11': resolution: {integrity: sha512-u7tKA+qbzBydyj0vgpu+5h5AeudxOAGncb8N6C9Kh1N4n7wU1Xw1JDApsRjpShRpXRQlJLb9wY28ELpwdPcZ7A==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-nU1yhmYutL+fQ71Kxnhg8uEOdC0pwEW9entHykTgEbna2pw2dkbFSMeqjjyHZoCmt8SBkOSvV+yNmm94aUrrqw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + '@esbuild/openbsd-arm64@0.25.11': resolution: {integrity: sha512-Qq6YHhayieor3DxFOoYM1q0q1uMFYb7cSpLD2qzDSvK1NAvqFi8Xgivv0cFC6J+hWVw2teCYltyy9/m/14ryHg==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-cXb5vApOsRsxsEl4mcZ1XY3D4DzcoMxR/nnc4IyqYs0rTI8ZKmW6kyyg+11Z8yvgMfAEldKzP7AdP64HnSC/6g==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.18.20': + resolution: {integrity: sha512-e5e4YSsuQfX4cxcygw/UCPIEP6wbIL+se3sxPdCiMbFLBWu0eiZOJ7WoD+ptCLrmjZBK1Wk7I6D/I3NglUGOxg==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.21.5': + resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==} + engines: {node: '>=12'} + cpu: [x64] + os: [openbsd] + '@esbuild/openbsd-x64@0.25.11': resolution: {integrity: sha512-CN+7c++kkbrckTOz5hrehxWN7uIhFFlmS/hqziSFVWpAzpWrQoAG4chH+nN3Be+Kzv/uuo7zhX716x3Sn2Jduw==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-8wZM2qqtv9UP3mzy7HiGYNH/zjTA355mpeuA+859TyR+e+Tc08IHYpLJuMsfpDJwoLo1ikIJI8jC3GFjnRClzA==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + '@esbuild/openharmony-arm64@0.25.11': resolution: {integrity: sha512-rOREuNIQgaiR+9QuNkbkxubbp8MSO9rONmwP5nKncnWJ9v5jQ4JxFnLu4zDSRPf3x4u+2VN4pM4RdyIzDty/wQ==} engines: {node: '>=18'} cpu: [arm64] os: [openharmony] + '@esbuild/openharmony-arm64@0.25.12': + resolution: {integrity: sha512-rm0YWsqUSRrjncSXGA7Zv78Nbnw4XL6/dzr20cyrQf7ZmRcsovpcRBdhD43Nuk3y7XIoW2OxMVvwuRvk9XdASg==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/openharmony-arm64@0.28.0': + resolution: {integrity: sha512-FLGfyizszcef5C3YtoyQDACyg95+dndv79i2EekILBofh5wpCa1KuBqOWKrEHZg3zrL3t5ouE5jgr94vA+Wb2w==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.18.20': + resolution: {integrity: sha512-kDbFRFp0YpTQVVrqUd5FTYmWo45zGaXe0X8E1G/LKFC0v8x0vWrhOWSLITcCn63lmZIxfOMXtCfti/RxN/0wnQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + + '@esbuild/sunos-x64@0.21.5': + resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==} + engines: {node: '>=12'} + cpu: [x64] + os: [sunos] + '@esbuild/sunos-x64@0.25.11': resolution: {integrity: sha512-nq2xdYaWxyg9DcIyXkZhcYulC6pQ2FuCgem3LI92IwMgIZ69KHeY8T4Y88pcwoLIjbed8n36CyKoYRDygNSGhA==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-1ZgjUoEdHZZl/YlV76TSCz9Hqj9h9YmMGAgAPYd+q4SicWNX3G5GCyx9uhQWSLcbvPW8Ni7lj4gDa1T40akdlw==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.18.20': + resolution: {integrity: sha512-ddYFR6ItYgoaq4v4JmQQaAI5s7npztfV4Ag6NrhiaW0RrnOXqBkgwZLofVTlq1daVTQNhtI5oieTvkRPfZrePg==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-arm64@0.21.5': + resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==} + engines: {node: '>=12'} + cpu: [arm64] + os: [win32] + '@esbuild/win32-arm64@0.25.11': resolution: {integrity: sha512-3XxECOWJq1qMZ3MN8srCJ/QfoLpL+VaxD/WfNRm1O3B4+AZ/BnLVgFbUV3eiRYDMXetciH16dwPbbHqwe1uU0Q==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-Q9StnDmQ/enxnpxCCLSg0oo4+34B9TdXpuyPeTedN/6+iXBJ4J+zwfQI28u/Jl40nOYAxGoNi7mFP40RUtkmUA==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.18.20': + resolution: {integrity: sha512-Wv7QBi3ID/rROT08SABTS7eV4hX26sVduqDOTe1MvGMjNd3EjOz4b7zeexIR62GTIEKrfJXKL9LFxTYgkyeu7g==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-ia32@0.21.5': + resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==} + engines: {node: '>=12'} + cpu: [ia32] + os: [win32] + '@esbuild/win32-ia32@0.25.11': resolution: {integrity: sha512-3ukss6gb9XZ8TlRyJlgLn17ecsK4NSQTmdIXRASVsiS2sQ6zPPZklNJT5GR5tE/MUarymmy8kCEf5xPCNCqVOA==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-zF3ag/gfiCe6U2iczcRzSYJKH1DCI+ByzSENHlM2FcDbEeo5Zd2C86Aq0tKUYAJJ1obRP84ymxIAksZUcdztHA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.18.20': + resolution: {integrity: sha512-kTdfRcSiDfQca/y9QIkng02avJ+NCaQvrMejlsB3RRv5sE9rRoeBPISaZpKxHELzRxZyLvNts1P27W3wV+8geQ==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + + '@esbuild/win32-x64@0.21.5': + resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==} + engines: {node: '>=12'} + cpu: [x64] + os: [win32] + '@esbuild/win32-x64@0.25.11': resolution: {integrity: sha512-D7Hpz6A2L4hzsRpPaCYkQnGOotdUpDzSGRIv9I+1ITdHROSFUWW95ZPZWQmGka1Fg7W3zFJowyn9WGwMJ0+KPA==} engines: {node: '>=18'} 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.0': + resolution: {integrity: sha512-pEl1bO9mfAmIC+tW5btTmrKaujg3zGtUmWNdCw/xs70FBjwAL3o9OEKNHvNmnyylD6ubxUERiEhdsL0xBQ9efw==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + '@escape.tech/graphql-armor-max-aliases@2.6.2': resolution: {integrity: sha512-SDk7pAzY6gutsdZ3NlyY55RrytrCPxJJxSN/DBfIGKphTrfBvKQWTnioQ9OlLP9kPjCE6XM5UWwGt7uqbpKSYA==} engines: {node: '>=18.0.0'} @@ -404,6 +1032,11 @@ packages: '@fastify/busboy@3.2.0': resolution: {integrity: sha512-m9FVDXU3GT2ITSe0UaMA5rU3QkfC/UXtCU8y0gSN/GugTqtVldOBWIB5V6V3sbmenVZUIpU6f+mPEO2+m5iTaA==} + '@filoz/synapse-core@0.6.0': + resolution: {integrity: sha512-+2sR5PQBuyNoEsaW5arBQvXzyvV7Rg9aIyHym/iCdFLLDDze8pMrnrpdG9OHctYzNI9MreFBkVOqSHFj81qjUw==} + peerDependencies: + viem: 2.x + '@graphql-tools/executor@1.5.3': resolution: {integrity: sha512-mgBFC0bsrZPZLu9EnydpMnAuQ8Iiq0CEbUcsmvXsm2/iYektGHDN/+bmb7hicA6dWZtdPfklYJmr21WD0GnOfA==} engines: {node: '>=16.0.0'} @@ -451,46 +1084,11 @@ packages: resolution: {integrity: sha512-ZpJxMqB+Qfe3rp6uszCQoag4nSw42icURnBRfFYSOmTgEeOe4rD0vYlbA8spvCu2TlCesNTlEN9BLWtQqLxabA==} engines: {node: '>=18.0.0'} - '@hono/node-server@1.19.14': - resolution: {integrity: sha512-GwtvgtXxnWsucXvbQXkRgqksiH2Qed37H9xHZocE5sA3N8O8O8/8FA3uclQXxXVzc9XBZuEOMK7+r02FmSpHtw==} + '@hono/node-server@1.19.5': + resolution: {integrity: sha512-iBuhh+uaaggeAuf+TftcjZyWh2GEgZcVGXkNtskLVoWaXhnJtC5HLHrU8W1KHDoucqO1MswwglmkWLFyiDn4WQ==} engines: {node: '>=18.14.1'} - peerDependencies: - hono: ^4 - - '@inquirer/ansi@2.0.5': - resolution: {integrity: sha512-doc2sWgJpbFQ64UflSVd17ibMGDuxO1yKgOgLMwavzESnXjFWJqUeG8saYosqKpHp4kWiM5x1nXvEjbpx90gzw==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - - '@inquirer/confirm@6.0.12': - resolution: {integrity: sha512-h9FgGun3QwVYNj5TWIZZ+slii73bMoBFjPfVIGtnFuL4t8gBiNDV9PcSfIzkuxvgquJKt9nr1QzszpBzTbH8Og==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/core@11.1.9': - resolution: {integrity: sha512-BDE4fG22uYh1bGSifcj7JSx119TVYNViMhMu85usp4Fswrzh6M0DV3yld64jA98uOAa2GSQ4Bg4bZRm2d2cwSg==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true - - '@inquirer/figures@2.0.5': - resolution: {integrity: sha512-NsSs4kzfm12lNetHwAn3GEuH317IzpwrMCbOuMIVytpjnJ90YYHNwdRgYGuKmVxwuIqSgqk3M5qqQt1cDk0tGQ==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - - '@inquirer/type@4.0.5': - resolution: {integrity: sha512-aetVUNeKNc/VriqXlw1NRSW0zhMBB0W4bNbWRJgzRl/3d0QNDQFfk0GO5SDdtjMZVg6o8ZKEiadd7SCCzoOn5Q==} - engines: {node: '>=23.5.0 || ^22.13.0 || ^21.7.0 || ^20.12.0'} - peerDependencies: - '@types/node': '>=18' - peerDependenciesMeta: - '@types/node': - optional: true + peerDependencies: + hono: ^4 '@isaacs/cliui@8.0.2': resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} @@ -510,9 +1108,74 @@ packages: '@jridgewell/trace-mapping@0.3.31': resolution: {integrity: sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==} - '@mswjs/interceptors@0.41.8': - resolution: {integrity: sha512-pRLMNKTSGRoLq+KnEB/7OY5vijw1XmcheAAOiv6pj7W1FG32kAGqj1C/RK/cqxRGr1Fh+zBi8sDur8kj3EQv6A==} - engines: {node: '>=18'} + '@libsql/client@0.17.3': + resolution: {integrity: sha512-HXk9wiAoJbKFbyBH4O+aEhN6ir5ERXuXvwE5OD2eR4/5RUa3Pw/8L9zrnVdU+iNJitRvisPWaIwmhkO3bH7giA==} + + '@libsql/core@0.17.3': + resolution: {integrity: sha512-2UjK1i7JBkMduJo4WdvvBxMMvVJ31pArBZNONyz/GCJJAH+1UHat2X6vn10S/WpY5fKzIT98WqYFl2vzWRLOfg==} + + '@libsql/darwin-arm64@0.5.29': + resolution: {integrity: sha512-K+2RIB1OGFPYQbfay48GakLhqf3ArcbHqPFu7EZiaUcRgFcdw8RoltsMyvbj5ix2fY0HV3Q3Ioa/ByvQdaSM0A==} + cpu: [arm64] + os: [darwin] + + '@libsql/darwin-x64@0.5.29': + resolution: {integrity: sha512-OtT+KFHsKFy1R5FVadr8FJ2Bb1mghtXTyJkxv0trocq7NuHntSki1eUbxpO5ezJesDvBlqFjnWaYYY516QNLhQ==} + cpu: [x64] + os: [darwin] + + '@libsql/hrana-client@0.10.0': + resolution: {integrity: sha512-OoA4EMqRAC7kn7V2P6EQqRcpZf2W+AjsNIyCizBg339Tq/aMC7sRnzs3SklderhmQWAqEzvv8A2vhxVmWpkVvw==} + + '@libsql/isomorphic-ws@0.1.5': + resolution: {integrity: sha512-DtLWIH29onUYR00i0GlQ3UdcTRC6EP4u9w/h9LxpUZJWRMARk6dQwZ6Jkd+QdwVpuAOrdxt18v0K2uIYR3fwFg==} + + '@libsql/linux-arm-gnueabihf@0.5.29': + resolution: {integrity: sha512-CD4n4zj7SJTHso4nf5cuMoWoMSS7asn5hHygsDuhRl8jjjCTT3yE+xdUvI4J7zsyb53VO5ISh4cwwOtf6k2UhQ==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm-musleabihf@0.5.29': + resolution: {integrity: sha512-2Z9qBVpEJV7OeflzIR3+l5yAd4uTOLxklScYTwpZnkm2vDSGlC1PRlueLaufc4EFITkLKXK2MWBpexuNJfMVcg==} + cpu: [arm] + os: [linux] + + '@libsql/linux-arm64-gnu@0.5.29': + resolution: {integrity: sha512-gURBqaiXIGGwFNEaUj8Ldk7Hps4STtG+31aEidCk5evMMdtsdfL3HPCpvys+ZF/tkOs2MWlRWoSq7SOuCE9k3w==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-arm64-musl@0.5.29': + resolution: {integrity: sha512-fwgYZ0H8mUkyVqXZHF3mT/92iIh1N94Owi/f66cPVNsk9BdGKq5gVpoKO+7UxaNzuEH1roJp2QEwsCZMvBLpqg==} + cpu: [arm64] + os: [linux] + + '@libsql/linux-x64-gnu@0.5.29': + resolution: {integrity: sha512-y14V0vY0nmMC6G0pHeJcEarcnGU2H6cm21ZceRkacWHvQAEhAG0latQkCtoS2njFOXiYIg+JYPfAoWKbi82rkg==} + cpu: [x64] + os: [linux] + + '@libsql/linux-x64-musl@0.5.29': + resolution: {integrity: sha512-gquqwA/39tH4pFl+J9n3SOMSymjX+6kZ3kWgY3b94nXFTwac9bnFNMffIomgvlFaC4ArVqMnOZD3nuJ3H3VO1w==} + cpu: [x64] + os: [linux] + + '@libsql/win32-x64-msvc@0.5.29': + resolution: {integrity: sha512-4/0CvEdhi6+KjMxMaVbFM2n2Z44escBRoEYpR+gZg64DdetzGnYm8mcNLcoySaDJZNaBd6wz5DNdgRmcI4hXcg==} + cpu: [x64] + os: [win32] + + '@modelcontextprotocol/server@2.0.0-alpha.2': + resolution: {integrity: sha512-gmLgdHzlYM8L7Aw/+VE0kxjT25WKamtUSLNhdOgrJq5CrESvqVSoAfWSJJeNPUXNTluQ+dYDGFbKVitdsJtbPA==} + engines: {node: '>=20'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + + '@neon-rs/load@0.0.4': + resolution: {integrity: sha512-kTPhdZyTQxB+2wpiRcFWrDcejc4JI6tkPuS7UZCG4l6Zvc5kU/gGQ/ozvHTh1XR5tS+UlfAfGuPajjzQjCiHCw==} '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} @@ -538,18 +1201,6 @@ packages: resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} engines: {node: '>= 8'} - '@open-draft/deferred-promise@2.2.0': - resolution: {integrity: sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==} - - '@open-draft/deferred-promise@3.0.0': - resolution: {integrity: sha512-XW375UK8/9SqUVNVa6M0yEy8+iTi4QN5VZ7aZuRFQmy76LRwI9wy5F4YIBU6T+eTe2/DNDo8tqu8RHlwLHM6RA==} - - '@open-draft/logger@0.3.0': - resolution: {integrity: sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==} - - '@open-draft/until@2.1.0': - resolution: {integrity: sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==} - '@opentelemetry/api@1.9.1': resolution: {integrity: sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==} engines: {node: '>=8.0.0'} @@ -576,141 +1227,141 @@ packages: '@repeaterjs/repeater@3.0.6': resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==} - '@rollup/rollup-android-arm-eabi@4.60.3': - resolution: {integrity: sha512-x35CNW/ANXG3hE/EZpRU8MXX1JDN86hBb2wMGAtltkz7pc6cxgjpy1OMMfDosOQ+2hWqIkag/fGok1Yady9nGw==} + '@rollup/rollup-android-arm-eabi@4.60.4': + resolution: {integrity: sha512-F5QXMSiFebS9hKZj02XhWLLnRpJ3B3AROP0tWbFBSj+6kCbg5m9j5JoHKd4mmSVy5mS/IMQloYgYxCuJC0fxEQ==} cpu: [arm] os: [android] - '@rollup/rollup-android-arm64@4.60.3': - resolution: {integrity: sha512-xw3xtkDApIOGayehp2+Rz4zimfkaX65r4t47iy+ymQB2G4iJCBBfj0ogVg5jpvjpn8UWn/+q9tprxleYeNp3Hw==} + '@rollup/rollup-android-arm64@4.60.4': + resolution: {integrity: sha512-GxxTKApUpzRhof7poWvCJHRF51C67u1R7D6DiluBE8wKU1u5GWE8t+v81JvJYtbawoBFX1hLv5Ei4eVjkWokaw==} cpu: [arm64] os: [android] - '@rollup/rollup-darwin-arm64@4.60.3': - resolution: {integrity: sha512-vo6Y5Qfpx7/5EaamIwi0WqW2+zfiusVihKatLvtN1VFVy3D13uERk/6gZLU1UiHRL6fDXqj/ELIeVRGnvcTE1g==} + '@rollup/rollup-darwin-arm64@4.60.4': + resolution: {integrity: sha512-tua0TaJxMOB1R0V0RS1jFZ/RpURFDJIOR2A6jWwQeawuFyS4gBW+rntLRaQd0EQ4bd6Vp44Z2rXW+YYDBsj6IA==} cpu: [arm64] os: [darwin] - '@rollup/rollup-darwin-x64@4.60.3': - resolution: {integrity: sha512-D+0QGcZhBzTN82weOnsSlY7V7+RMmPuF1CkbxyMAGE8+ZHeUjyb76ZiWmBlCu//AQQONvxcqRbwZTajZKqjuOw==} + '@rollup/rollup-darwin-x64@4.60.4': + resolution: {integrity: sha512-CSKq7MsP+5PFIcydhAiR1K0UhEI1A2jWXVKHPCBZ151yOutENwvnPocgVHkivu2kviURtCEB6zUQw0vs8RrhMg==} cpu: [x64] os: [darwin] - '@rollup/rollup-freebsd-arm64@4.60.3': - resolution: {integrity: sha512-6HnvHCT7fDyj6R0Ph7A6x8dQS/S38MClRWeDLqc0MdfWkxjiu1HSDYrdPhqSILzjTIC/pnXbbJbo+ft+gy/9hQ==} + '@rollup/rollup-freebsd-arm64@4.60.4': + resolution: {integrity: sha512-+O8OkVdyvXMtJEciu2wS/pzm1IxntEEQx3z5TAVy4l32G0etZn+RsA48ARRrFm6Ri8fvqPQfgrvNxSjKAbnd3g==} cpu: [arm64] os: [freebsd] - '@rollup/rollup-freebsd-x64@4.60.3': - resolution: {integrity: sha512-KHLgC3WKlUYW3ShFKnnosZDOJ0xjg9zp7au3sIm2bs/tGBeC2ipmvRh/N7JKi0t9Ue20C0dpEshi8WUubg+cnA==} + '@rollup/rollup-freebsd-x64@4.60.4': + resolution: {integrity: sha512-Iw3oMskH3AfNuhU0MSN7vNbdi4me/NiYo2azqPz/Le16zHSa+3RRmliCMWWQmh4lcndccU40xcJuTYJZxNo/lw==} cpu: [x64] os: [freebsd] - '@rollup/rollup-linux-arm-gnueabihf@4.60.3': - resolution: {integrity: sha512-DV6fJoxEYWJOvaZIsok7KrYl0tPvga5OZ2yvKHNNYyk/2roMLqQAbGhr78EQ5YhHpnhLKJD3S1WFusAkmUuV5g==} + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': + resolution: {integrity: sha512-EIPRXTVQpHyF8WOo219AD2yEltPehLTcTMz2fn6JsatLYSzQf00hj3rulF+yauOlF9/FtM2WpkT/hJh/KJFGhA==} cpu: [arm] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm-musleabihf@4.60.3': - resolution: {integrity: sha512-mQKoJAzvuOs6F+TZybQO4GOTSMUu7v0WdxEk24krQ/uUxXoPTtHjuaUuPmFhtBcM4K0ons8nrE3JyhTuCFtT/w==} + '@rollup/rollup-linux-arm-musleabihf@4.60.4': + resolution: {integrity: sha512-J3Yh9PzzF1Ovah2At+lHiGQdsYgArxBbXv/zHfSyaiFQEqvNv7DcW98pCrmdjCZBrqBiKrKKe2V+aaSGWuBe/w==} cpu: [arm] os: [linux] libc: [musl] - '@rollup/rollup-linux-arm64-gnu@4.60.3': - resolution: {integrity: sha512-Whjj2qoiJ6+OOJMGptTYazaJvjOJm+iKHpXQM1P3LzGjt7Ff++Tp7nH4N8J/BUA7R9IHfDyx4DJIflifwnbmIA==} + '@rollup/rollup-linux-arm64-gnu@4.60.4': + resolution: {integrity: sha512-BFDEZMYfUvLn37ONE1yMBojPxnMlTFsdyNoqncT0qFq1mAfllL+ATMMJd8TeuVMiX84s1KbcxcZbXInmcO2mRg==} cpu: [arm64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-arm64-musl@4.60.3': - resolution: {integrity: sha512-4YTNHKqGng5+yiZt3mg77nmyuCfmNfX4fPmyUapBcIk+BdwSwmCWGXOUxhXbBEkFHtoN5boLj/5NON+u5QC9tg==} + '@rollup/rollup-linux-arm64-musl@4.60.4': + resolution: {integrity: sha512-pc9EYOSlOgdQ2uPl1o9PF6/kLSgaUosia7gOuS8mB69IxJvlclko1MECXysjs5ryez1/5zjYqx3+xYU0TU6R1A==} cpu: [arm64] os: [linux] libc: [musl] - '@rollup/rollup-linux-loong64-gnu@4.60.3': - resolution: {integrity: sha512-SU3kNlhkpI4UqlUc2VXPGK9o886ZsSeGfMAX2ba2b8DKmMXq4AL7KUrkSWVbb7koVqx41Yczx6dx5PNargIrEA==} + '@rollup/rollup-linux-loong64-gnu@4.60.4': + resolution: {integrity: sha512-NxnomyxYerDh5n4iLrNa+sH+Z+U4BMEE46V2PgQ/hoB909i8gV1M5wPojWg9fk1jWpO3IQnOs20K4wyZuFLEFQ==} cpu: [loong64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-loong64-musl@4.60.3': - resolution: {integrity: sha512-6lDLl5h4TXpB1mTf2rQWnAk/LcXrx9vBfu/DT5TIPhvMhRWaZ5MxkIc8u4lJAmBo6klTe1ywXIUHFjylW505sg==} + '@rollup/rollup-linux-loong64-musl@4.60.4': + resolution: {integrity: sha512-nbJnQ8a3z1mtmrwImCYhc6BGpThAyYVRQxw9uKSKG4wR6aAYno9sVjJ0zaZcW9BPJX1GbrDPf+SvdWjgTuDmnw==} cpu: [loong64] os: [linux] libc: [musl] - '@rollup/rollup-linux-ppc64-gnu@4.60.3': - resolution: {integrity: sha512-BMo8bOw8evlup/8G+cj5xWtPyp93xPdyoSN16Zy90Q2QZ0ZYRhCt6ZJSwbrRzG9HApFabjwj2p25TUPDWrhzqQ==} + '@rollup/rollup-linux-ppc64-gnu@4.60.4': + resolution: {integrity: sha512-2EU6acNrQLd8tYvo/LXW535wupT3m6fo7HKo6lr7ktQoItxTyOL1ZCR/GfGCuXl2vR+zmfI6eRXkSemafv+iVg==} cpu: [ppc64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-ppc64-musl@4.60.3': - resolution: {integrity: sha512-E0L8X1dZN1/Rph+5VPF6Xj2G7JJvMACVXtamTJIDrVI44Y3K+G8gQaMEAavbqCGTa16InptiVrX6eM6pmJ+7qA==} + '@rollup/rollup-linux-ppc64-musl@4.60.4': + resolution: {integrity: sha512-WeBtoMuaMxiiIrO2IYP3xs6GMWkJP2C0EoT8beTLkUPmzV1i/UcOSVw1d5r9KBODtHKilG5yFxsGRnBbK3wJ4A==} cpu: [ppc64] os: [linux] libc: [musl] - '@rollup/rollup-linux-riscv64-gnu@4.60.3': - resolution: {integrity: sha512-oZJ/WHaVfHUiRAtmTAeo3DcevNsVvH8mbvodjZy7D5QKvCefO371SiKRpxoDcCxB3PTRTLayWBkvmDQKTcX/sw==} + '@rollup/rollup-linux-riscv64-gnu@4.60.4': + resolution: {integrity: sha512-FJHFfqpKUI3A10WrWKiFbBZ7yVbGT4q4B5o1qKFFojqpaYoh9LrQgqWCmmcxQzVSXYtyB5bzkXrYzlHTs21MYA==} cpu: [riscv64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-riscv64-musl@4.60.3': - resolution: {integrity: sha512-Dhbyh7j9FybM3YaTgaHmVALwA8AkUwTPccyCQ79TG9AJUsMQqgN1DDEZNr4+QUfwiWvLDumW5vdwzoeUF+TNxQ==} + '@rollup/rollup-linux-riscv64-musl@4.60.4': + resolution: {integrity: sha512-mcEl6CUT5IAUmQf1m9FYSmVqCJlpQ8r8eyftFUHG8i9OhY7BkBXSUdnLH5DOf0wCOjcP9v/QO93zpmF1SptCCw==} cpu: [riscv64] os: [linux] libc: [musl] - '@rollup/rollup-linux-s390x-gnu@4.60.3': - resolution: {integrity: sha512-cJd1X5XhHHlltkaypz1UcWLA8AcoIi1aWhsvaWDskD1oz2eKCypnqvTQ8ykMNI0RSmm7NkTdSqSSD7zM0xa6Ig==} + '@rollup/rollup-linux-s390x-gnu@4.60.4': + resolution: {integrity: sha512-ynt3JxVd2w2buzoKDWIyiV1pJW93xlQic1THVLXilz429oijRpSHivZAgp65KBu+cMcgf1eVVjdnTLvPxgCuoQ==} cpu: [s390x] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-gnu@4.60.3': - resolution: {integrity: sha512-DAZDBHQfG2oQuhY7mc6I3/qB4LU2fQCjRvxbDwd/Jdvb9fypP4IJ4qmtu6lNjes6B531AI8cg1aKC2di97bUxA==} + '@rollup/rollup-linux-x64-gnu@4.60.4': + resolution: {integrity: sha512-Boiz5+MsaROEWDf+GGEwF8VMHGhlUoQMtIPjOgA5fv4osupqTVnJteQNKJwUcnUog2G55jYXH7KZFFiJe0TEzQ==} cpu: [x64] os: [linux] libc: [glibc] - '@rollup/rollup-linux-x64-musl@4.60.3': - resolution: {integrity: sha512-cRxsE8c13mZOh3vP+wLDxpQBRrOHDIGOWyDL93Sy0Ga8y515fBcC2pjUfFwUe5T7tqvTvWbCpg1URM/AXdWIXA==} + '@rollup/rollup-linux-x64-musl@4.60.4': + resolution: {integrity: sha512-+qfSY27qIrFfI/Hom04KYFw3GKZSGU4lXus51wsb5EuySfFlWRwjkKWoE9emgRw/ukoT4Udsj4W/+xxG8VbPKg==} cpu: [x64] os: [linux] libc: [musl] - '@rollup/rollup-openbsd-x64@4.60.3': - resolution: {integrity: sha512-QaWcIgRxqEdQdhJqW4DJctsH6HCmo5vHxY0krHSX4jMtOqfzC+dqDGuHM87bu4H8JBeibWx7jFz+h6/4C8wA5Q==} + '@rollup/rollup-openbsd-x64@4.60.4': + resolution: {integrity: sha512-VpTfOPHgVXEBeeR8hZ2O0F3aSso+JDWqTWmTmzcQKted54IAdUVbxE+j/MVxUsKa8L20HJhv3vUezVPoquqWjA==} cpu: [x64] os: [openbsd] - '@rollup/rollup-openharmony-arm64@4.60.3': - resolution: {integrity: sha512-AaXwSvUi3QIPtroAUw1t5yHGIyqKEXwH54WUocFolZhpGDruJcs8c+xPNDRn4XiQsS7MEwnYsHW2l0MBLDMkWg==} + '@rollup/rollup-openharmony-arm64@4.60.4': + resolution: {integrity: sha512-IPOsh5aRYuLv/nkU51X10Bf75Bsf6+gZdx1X+QP5QM6lIJFHHqbHLG0uJn/hWthzo13UAc2umiUorqZy3axoZg==} cpu: [arm64] os: [openharmony] - '@rollup/rollup-win32-arm64-msvc@4.60.3': - resolution: {integrity: sha512-65LAKM/bAWDqKNEelHlcHvm2V+Vfb8C6INFxQXRHCvaVN1rJfwr4NvdP4FyzUaLqWfaCGaadf6UbTm8xJeYfEg==} + '@rollup/rollup-win32-arm64-msvc@4.60.4': + resolution: {integrity: sha512-4QzE9E81OohJ/HKzHhsqU+zcYYojVOXlFMs1DdyMT6qXl/niOH7AVElmmEdUNHHS/oRkc++d5k6Vy85zFs0DEw==} cpu: [arm64] os: [win32] - '@rollup/rollup-win32-ia32-msvc@4.60.3': - resolution: {integrity: sha512-EEM2gyhBF5MFnI6vMKdX1LAosE627RGBzIoGMdLloPZkXrUN0Ckqgr2Qi8+J3zip/8NVVro3/FjB+tjhZUgUHA==} + '@rollup/rollup-win32-ia32-msvc@4.60.4': + resolution: {integrity: sha512-zTPgT1YuHHcd+Tmx7h8aml0FWFVelV5N54oHow9SLj+GfoDy/huQ+UV396N/C7KpMDMiPspRktzM1/0r1usYEA==} cpu: [ia32] os: [win32] - '@rollup/rollup-win32-x64-gnu@4.60.3': - resolution: {integrity: sha512-E5Eb5H/DpxaoXH++Qkv28RcUJboMopmdDUALBczvHMf7hNIxaDZqwY5lK12UK1BHacSmvupoEWGu+n993Z0y1A==} + '@rollup/rollup-win32-x64-gnu@4.60.4': + resolution: {integrity: sha512-DRS4G7mi9lJxqEDezIkKCaUIKCrLUUDCUaCsTPCi/rtqaC6D/jjwslMQyiDU50Ka0JKpeXeRBFBAXwArY52vBw==} cpu: [x64] os: [win32] - '@rollup/rollup-win32-x64-msvc@4.60.3': - resolution: {integrity: sha512-hPt/bgL5cE+Qp+/TPHBqptcAgPzgj46mPcg/16zNUmbQk0j+mOEQV/+Lqu8QRtDV3Ek95Q6FeFITpuhl6OTsAA==} + '@rollup/rollup-win32-x64-msvc@4.60.4': + resolution: {integrity: sha512-QVTUovf40zgTqlFVrKA1uXMVvU2QWEFWfAH8Wdc48IxLvrJMQVMBRjuQyUpzZCDkakImib9eVazbWlC6ksWtJw==} cpu: [x64] os: [win32] @@ -726,6 +1377,10 @@ packages: typescript: optional: true + '@scalar/openapi-types@0.8.0': + resolution: {integrity: sha512-WmaxVSfvY5K/TwcG2B2TU1WOe1As1uc2s7myswtP6dBlcjU3hM08SApxv/jmyGaCE8t4gO5BBhmHY4pDUfmr2g==} + engines: {node: '>=22'} + '@scure/base@1.2.6': resolution: {integrity: sha512-g/nm5FgUa//MCj1gV09zTJTaM6KBAHqLN907YVQqf7zC49+DcO4B1so4ZX07Ef10Twr6nuqYEH9GEggFXA4Fmg==} @@ -742,8 +1397,11 @@ packages: resolution: {integrity: sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==} engines: {node: '>=18'} - '@types/assert@1.5.11': - resolution: {integrity: sha512-FjS1mxq2dlGr9N4z72/DO+XmyRS3ZZIoVn998MEopAN/OmyN28F4yumRL5pOw2z+hbFLuWGYuF2rrw5p11xM5A==} + '@standard-schema/spec@1.1.0': + resolution: {integrity: sha512-l2aFy5jALhniG5HgqrD6jXLi/rUWrKvqN/qJx6yoJsgKhblVd+iqqU4RCXavm/jPityDo5TCvKMnpjKnOriy0w==} + + '@toon-format/toon@2.3.0': + resolution: {integrity: sha512-/Ew9etdRQKVMnm9fDaCG0JjyAOK/O7T0M97oum1aW4W+UR8ZhVVPBanIV7oWgHBiGlnVxV9M55PWQCHofDV07w==} '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} @@ -751,17 +1409,14 @@ packages: '@types/istanbul-lib-coverage@2.0.6': resolution: {integrity: sha512-2QF/t/auWm0lsy8XtKVPG19v3sSOQlJe/YHZgfjb/KBBHOGSV+J2q/S671rcq9uTBrLAXmZpqJiaQbMT+zNU1w==} - '@types/mocha@10.0.10': - resolution: {integrity: sha512-xPyYSz1cMPnJQhl0CLMH68j3gprKZaTjG3s5Vi+fDgx+uhG9NOXwbVt52eFS8ECyXhyKcjDLCBEqBExKuiZb7Q==} - - '@types/node@25.6.0': - resolution: {integrity: sha512-+qIYRKdNYJwY3vRCZMdJbPLJAtGjQBudzZzdzwQYkEPQd+PJGixUL5QfvCLDaULoLv+RhT3LDkwEfKaAkgSmNQ==} + '@types/node@25.9.2': + resolution: {integrity: sha512-G05zqtJhcDLb8uslf5EjCxXg9G1KQxiV8OS0R26IC//Eoyitzqe8z37I7cqvnZlrlSfgocQRfSn/AHBZJJFyGw==} - '@types/set-cookie-parser@2.4.10': - resolution: {integrity: sha512-GGmQVGpQWUe5qglJozEjZV/5dyxbOOZ0LHe/lqyWssB88Y4svNfst0uqBVscdDeIKl5Jy5+aPSvy7mI9tYRguw==} + '@types/pg@8.20.0': + resolution: {integrity: sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==} - '@types/statuses@2.0.6': - resolution: {integrity: sha512-xMAgYwceFhRA2zY+XbEA7mxYbA093wdiW8Vu6gZPGWy9cmOyU9XesH1tNcEWsKFd5Vzrqx5T3D38PWx1FIIXkA==} + '@types/ws@8.18.1': + resolution: {integrity: sha512-ThVF6DCVhA8kUGy+aazFQ4kXQ7E1Ty7A3ypFOe0IcJV8O/M511G99AW24irKrW56Wt44yG9+ij8FaqoBGkuBXg==} '@whatwg-node/disposablestack@0.0.6': resolution: {integrity: sha512-LOtTn+JgJvX8WfBVJtF08TGrdjuFzGJc4mkP8EdDI8ADbvO7kiexYep1o8dwnt0okb0jYclCDXF13xU7Ge4zSw==} @@ -809,6 +1464,17 @@ packages: zod: optional: true + abitype@1.2.4: + resolution: {integrity: sha512-dpKH+N27vRjarMVTFFkeY445VTKftzGWpL0FiT7xmVmzQRKazZexzC5uHG0f6XKsVLAuUlndnbGau6lRejClxg==} + peerDependencies: + typescript: '>=5.0.4' + zod: ^3.22.0 || ^4.0.0 + peerDependenciesMeta: + typescript: + optional: true + zod: + optional: true + abort-controller@3.0.0: resolution: {integrity: sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==} engines: {node: '>=6.5'} @@ -830,6 +1496,14 @@ packages: ajv: optional: true + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + ajv@8.20.0: resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} @@ -857,9 +1531,6 @@ packages: resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} engines: {node: '>= 8'} - argparse@2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - assert@2.1.0: resolution: {integrity: sha512-eLHpSK/Y4nhMJ07gDaAzoX/XAKS8PSaojml3M0DM4JpV1LAi5JOJ/p6H/XWrl8L+DzVEvVCW1z3vWAaB9oTsQw==} @@ -888,6 +1559,10 @@ packages: base64-js@1.5.1: resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + bigint-mod-arith@3.3.1: + resolution: {integrity: sha512-pX/cYW3dCa87Jrzv6DAr8ivbbJRzEX5yGhdt8IutnX/PCIXfpx+mabWNK/M8qqh+zQ0J3thftUBHW0ByuUlG0w==} + engines: {node: '>=10.4.0'} + binary-extensions@2.3.0: resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==} engines: {node: '>=8'} @@ -895,24 +1570,21 @@ packages: bintrees@1.0.2: resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} - brace-expansion@2.1.0: - resolution: {integrity: sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==} + brace-expansion@2.1.1: + resolution: {integrity: sha512-WR1cURNjuvBLMZBMbqM0UoE+WAfdUcEV1ccD8PVBVOI+Z3ND4+SZbN8RsfT2bMuG1qwz5RFvPukSZm5fF2D5eA==} brace-expansion@4.0.1: resolution: {integrity: sha512-YClrbvTCXGe70pU2JiEiPLYXO9gQkyxYeKpJIQHVS/gOs6EWMQP2RYBwjFLNT322Ji8TOC3IMPfsYCedNpzKfA==} engines: {node: '>= 18'} - brace-expansion@5.0.5: - resolution: {integrity: sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==} + brace-expansion@5.0.6: + resolution: {integrity: sha512-kLpxurY4Z4r9sgMsyG0Z9uzsBlgiU/EFKhj/h91/8yHu0edo7XuixOIH3VcJ8kkxs6/jPzoI6U9Vj3WqbMQ94g==} engines: {node: 18 || 20 || >=22} braces@3.0.3: resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==} engines: {node: '>=8'} - browser-stdout@1.3.1: - resolution: {integrity: sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==} - buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} @@ -945,17 +1617,9 @@ packages: resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} engines: {node: '>= 0.4'} - camelcase@6.3.0: - resolution: {integrity: sha512-Gmy6FhYlCY7uOElZUSbxo2UCDH8owEk996gkbrpsgGtrJLM3J7jGxl9Ic7Qwwj4ivOE5AWZWRMecDdF7hqGjFA==} - engines: {node: '>=10'} - - camelcase@8.0.0: - resolution: {integrity: sha512-8WB3Jcas3swSvjIeA2yvCJ+Miyz5l1ZmB6HFb9R1317dt9LCQoswg/BGrmAmkWVEszSrrg4RwmO46qIm2OEnSA==} - engines: {node: '>=16'} - - chalk@4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} + camelcase@9.0.0: + resolution: {integrity: sha512-TO9xmyXTZ9HUHI8M1OnvExxYB0eYVS/1e5s7IDMTAoIcwUd+aNcFODs6Xk83mobk0velyHFQgA1yIrvYc6wclw==} + engines: {node: '>=20'} chalk@5.6.2: resolution: {integrity: sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==} @@ -977,10 +1641,6 @@ packages: resolution: {integrity: sha512-bXfOC4QcT1tKXGorxL3wbJm6XJPDqEnij2gQ2m7ESQuE+/z9YFIWnl/5RpTiKWbMq3EVKR4fRLJGn6DVfu0mpw==} engines: {node: '>=18.20'} - cli-width@4.1.0: - resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} - engines: {node: '>= 12'} - cliui@8.0.1: resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==} engines: {node: '>=12'} @@ -1000,13 +1660,13 @@ packages: resolution: {integrity: sha512-fIWyWUXrJ45cHCIQX+Ck1hrZDIf/9DR0P0Zewn3uNht28hbt5OfGUq8rRWsxi96pZWPyBEd0eY9ama01JTaknA==} engines: {node: '>=18'} + conf@15.1.0: + resolution: {integrity: sha512-Uy5YN9KEu0WWDaZAVJ5FAmZoaJt9rdK6kH+utItPyGsCqCgaTKkrmZx3zoE0/3q6S3bcp3Ihkk+ZqPxWxFK5og==} + engines: {node: '>=20'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} - cookie@1.1.1: - resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} - engines: {node: '>=18'} - copy-anything@4.0.5: resolution: {integrity: sha512-7Vv6asjS4gMOuILabD3l739tsaxFQmC+a7pLZm02zyvs8p977bL3zEgq3yDk5rn9B0PbYgIv++jmHcuUab4RhA==} engines: {node: '>=18'} @@ -1030,6 +1690,10 @@ packages: resolution: {integrity: sha512-Sr4SdOZ4vw6eQDvPYNxHogvrxmCIld/VenC5JbNrFwMiwd7lY/Z18ZFfo+EWNG4DD9nFlAujWAo/wGuOPHmy5A==} engines: {node: '>=12'} + debounce-fn@6.0.0: + resolution: {integrity: sha512-rBMW+F2TXryBwB54Q0d8drNEI+TfoS9JpNTAoVpukbWEhjXQq4rySFYLaqXMFXwdv61Zb2OHtj5bviSoimqxRQ==} + engines: {node: '>=18'} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1039,10 +1703,6 @@ packages: supports-color: optional: true - decamelize@4.0.0: - resolution: {integrity: sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==} - engines: {node: '>=10'} - define-data-property@1.1.4: resolution: {integrity: sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==} engines: {node: '>= 0.4'} @@ -1055,13 +1715,24 @@ packages: resolution: {integrity: sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==} engines: {node: '>=10'} + delay@7.0.0: + resolution: {integrity: sha512-C3vaGs818qzZjCvVJ98GQUMVyWeg7dr5w2Nwwb2t5K8G98jOyyVO2ti2bKYk5yoYElqH3F2yA53ykuEnwD6MCg==} + engines: {node: '>=20'} + + detect-libc@2.0.2: + resolution: {integrity: sha512-UX6sGumvvqSaXgdKGUsgZWqcUyIXZ/vZTrlRT/iobiKhGL0zL4d3osHj3uqllWJK+i+sixDS/3COVEOFbupFyw==} + engines: {node: '>=8'} + detect-package-manager@3.0.2: resolution: {integrity: sha512-8JFjJHutStYrfWwzfretQoyNGoZVW1Fsrp4JO9spa7h/fBfwgTMEIy4/LBzRDGsxwVPHU0q+T9YvwLDJoOApLQ==} engines: {node: '>=12'} - diff@7.0.0: - resolution: {integrity: sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw==} - engines: {node: '>=0.3.1'} + dnum@2.17.0: + resolution: {integrity: sha512-Abo8RU2ZoABVO2R051XlJEgDIXAlA8/ZjOT2F1uAWvm6Vb8TphmN4k7qgu5nWKSv/JUGLVty6QPEeLTvaxNRYQ==} + + dot-prop@10.1.0: + resolution: {integrity: sha512-MVUtAugQMOff5RnBy2d9N31iG0lNwg1qAoAOn7pOK5wf94WIaE3My2p3uwTQuvS2AcqchkcR3bHByjaM0mmi7Q==} + engines: {node: '>=20'} dot-prop@8.0.2: resolution: {integrity: sha512-xaBe6ZT4DHPkg0k4Ytbvn5xoxgpG0jOS1dYxSOwAHPuNLjP3/OzN0gH55SrLqpx8cBfSaVt91lXYkApjb+nYdQ==} @@ -1071,6 +1742,99 @@ packages: resolution: {integrity: sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==} engines: {node: '>=12'} + drizzle-kit@0.31.10: + resolution: {integrity: sha512-7OZcmQUrdGI+DUNNsKBn1aW8qSoKuTH7d0mYgSP8bAzdFzKoovxEFnoGQp2dVs82EOJeYycqRtciopszwUf8bw==} + hasBin: true + + drizzle-orm@0.41.0: + resolution: {integrity: sha512-7A4ZxhHk9gdlXmTdPj/lREtP+3u8KvZ4yEN6MYVxBzZGex5Wtdc+CWSbu7btgF6TB0N+MNPrvW7RKBbxJchs/Q==} + peerDependencies: + '@aws-sdk/client-rds-data': '>=3' + '@cloudflare/workers-types': '>=4' + '@electric-sql/pglite': '>=0.2.0' + '@libsql/client': '>=0.10.0' + '@libsql/client-wasm': '>=0.10.0' + '@neondatabase/serverless': '>=0.10.0' + '@op-engineering/op-sqlite': '>=2' + '@opentelemetry/api': ^1.4.1 + '@planetscale/database': '>=1' + '@prisma/client': '*' + '@tidbcloud/serverless': '*' + '@types/better-sqlite3': '*' + '@types/pg': '*' + '@types/sql.js': '*' + '@vercel/postgres': '>=0.8.0' + '@xata.io/client': '*' + better-sqlite3: '>=7' + bun-types: '*' + expo-sqlite: '>=14.0.0' + gel: '>=2' + knex: '*' + kysely: '*' + mysql2: '>=2' + pg: '>=8' + postgres: '>=3' + prisma: '*' + sql.js: '>=1' + sqlite3: '>=5' + peerDependenciesMeta: + '@aws-sdk/client-rds-data': + optional: true + '@cloudflare/workers-types': + optional: true + '@electric-sql/pglite': + optional: true + '@libsql/client': + optional: true + '@libsql/client-wasm': + optional: true + '@neondatabase/serverless': + optional: true + '@op-engineering/op-sqlite': + optional: true + '@opentelemetry/api': + optional: true + '@planetscale/database': + optional: true + '@prisma/client': + optional: true + '@tidbcloud/serverless': + optional: true + '@types/better-sqlite3': + optional: true + '@types/pg': + optional: true + '@types/sql.js': + optional: true + '@vercel/postgres': + optional: true + '@xata.io/client': + optional: true + better-sqlite3: + optional: true + bun-types: + optional: true + expo-sqlite: + optional: true + gel: + optional: true + knex: + optional: true + kysely: + optional: true + mysql2: + optional: true + pg: + optional: true + postgres: + optional: true + prisma: + optional: true + sql.js: + optional: true + sqlite3: + optional: true + drizzle-orm@0.45.2: resolution: {integrity: sha512-kY0BSaTNYWnoDMVoyY8uxmyHjpJW1geOmBMdSSicKo9CIIWkSxMIj2rkeSR51b8KAPB7m+qysjuHme5nKP+E5Q==} peerDependencies: @@ -1096,7 +1860,7 @@ packages: expo-sqlite: '>=14.0.0' gel: '>=2' knex: '*' - kysely: ^0.28.14 + kysely: '*' mysql2: '>=2' pg: '>=8' postgres: '>=3' @@ -1192,27 +1956,43 @@ packages: resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} engines: {node: '>= 0.4'} - es-object-atoms@1.1.1: - resolution: {integrity: sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==} + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} engines: {node: '>= 0.4'} esbuild-plugin-wasm@1.1.0: resolution: {integrity: sha512-0bQ6+1tUbySSnxzn5jnXHMDvYnT0cN/Wd4Syk8g/sqAIJUg7buTIi22svS3Qz6ssx895NT+TgLPb33xi1OkZig==} engines: {node: '>=0.10.0'} + esbuild@0.18.20: + resolution: {integrity: sha512-ceqxoedUrcayh7Y7ZX6NdbbDzGROiyVBgC4PriJThBKSVPWnnFHZAkfI1lJT8QFkOwH4qOS2SJkS4wvpGl8BpA==} + engines: {node: '>=12'} + hasBin: true + + esbuild@0.21.5: + resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} + engines: {node: '>=12'} + hasBin: true + esbuild@0.25.11: resolution: {integrity: sha512-KohQwyzrKTQmhXDW1PjCv3Tyspn9n5GcY2RTDqeORIdIJY8yKIF7sTSopFmn/wpMPW4rdPXI0UE5LJLuq3bx0Q==} engines: {node: '>=18'} hasBin: true + esbuild@0.25.12: + resolution: {integrity: sha512-bbPBYYrtZbkt6Os6FiTLCTFxvq4tt3JKall1vRwshA3fdVztsLAatFaZobhkBC8/BrPetoa0oksYoKXoG4ryJg==} + engines: {node: '>=18'} + hasBin: true + + esbuild@0.28.0: + resolution: {integrity: sha512-sNR9MHpXSUV/XB4zmsFKN+QgVG82Cc7+/aaxJ8Adi8hyOac+EXptIp45QBPaVyX3N70664wRbTcLTOemCAnyqw==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} - escape-string-regexp@4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - event-target-shim@5.0.1: resolution: {integrity: sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==} engines: {node: '>=6'} @@ -1220,6 +2000,9 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + events@3.3.0: resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} engines: {node: '>=0.8.x'} @@ -1260,8 +2043,8 @@ packages: fast-uri@3.1.2: resolution: {integrity: sha512-rVjf7ArG3LTk+FS6Yw81V1DLuZl1bRbNrev6Tmd/9RaroeeRRJhAt7jg/6YFxbvAQXUCavSoZhPPj6oOx+5KjQ==} - fast-wrap-ansi@0.2.0: - resolution: {integrity: sha512-rLV8JHxTyhVmFYhBJuMujcrHqOT2cnO5Zxj37qROj23CP39GXubJRBUFF0z8KFK77Uc0SukZUf7JZhsVEQ6n8w==} + fast-wrap-ansi@0.2.2: + resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -1287,10 +2070,6 @@ packages: resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} engines: {node: '>=10'} - flat@5.0.2: - resolution: {integrity: sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==} - hasBin: true - for-each@0.3.5: resolution: {integrity: sha512-dKx12eRCVIzqCxFGplyFKJMPvLEWgmNtUrpTiJIR5u97zEhRG8ySrtboPHZXx7daLxQVrl643cTzbab2tkQjxg==} engines: {node: '>= 0.4'} @@ -1299,6 +2078,9 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + from-exponential@1.1.1: + resolution: {integrity: sha512-VBE7f5OVnYwdgB3LHa+Qo29h8qVpxhVO9Trlc+AWm+/XNAgks1tAwMFHb33mjeiof77GglsJzeYF7OqXrROP/A==} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} @@ -1315,8 +2097,8 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} - get-east-asian-width@1.5.0: - resolution: {integrity: sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==} + get-east-asian-width@1.6.0: + resolution: {integrity: sha512-QRbvDIbx6YklUe6RxeTeleMR0yv3cYH6PsPZHcnVn7xv7zO1BHN8r0XETu8n6Ye3Q+ahtSarc3WgtNWmehIBfA==} engines: {node: '>=18'} get-intrinsic@1.3.0: @@ -1335,6 +2117,9 @@ packages: resolution: {integrity: sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==} engines: {node: '>=18'} + get-tsconfig@4.14.0: + resolution: {integrity: sha512-yTb+8DXzDREzgvYmh6s9vHsSVCHeC0G3PI5bEXNBHtmshPnO+S5O7qgLEOn0I5QvMy6kpZN8K1NKGyilLb93wA==} + glob-parent@5.1.2: resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} engines: {node: '>= 6'} @@ -1360,10 +2145,6 @@ packages: peerDependencies: graphql: ^15.2.0 || ^16.0.0 - graphql@16.11.0: - resolution: {integrity: sha512-mS1lbMsxgQj6hge1XZ6p7GPhbrtFwUFYi3wRzXAC/FmYnyXMTvvI3td3rjmQ2u8ewXueaSvRPWaEcgVVOT9Jnw==} - engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} - graphql@16.14.0: resolution: {integrity: sha512-BBvQ/406p+4CZbTpCbVPSxfzrZrbnuWSP1ELYgyS6B+hNeKzgrdB4JczCa5VZUBQrDa9hUngm0KnexY6pJRN5Q==} engines: {node: ^12.22.0 || ^14.16.0 || ^16.0.0 || >=17.0.0} @@ -1376,6 +2157,10 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-flag@5.0.1: + resolution: {integrity: sha512-CsNUt5x9LUdx6hnk/E2SZLsDyvfqANZSUq4+D3D8RzDJ2M+HDTIkF60ibS1vHaK55vzgiZw1bEPFG9yH7l33wA==} + engines: {node: '>=12'} + has-property-descriptors@1.0.2: resolution: {integrity: sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==} @@ -1391,15 +2176,8 @@ packages: resolution: {integrity: sha512-ej4AhfhfL2Q2zpMmLo7U1Uv9+PyhIZpgQLGT1F9miIGmiCJIoCgSmczFdrc97mWT4kVY72KA+WnnhJ5pghSvSg==} engines: {node: '>= 0.4'} - he@1.2.0: - resolution: {integrity: sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==} - hasBin: true - - headers-polyfill@5.0.1: - resolution: {integrity: sha512-1TJ6Fih/b8h5TIcv+1+Hw0PDQWJTKDKzFZzcKOiW1wJza3XoAQlkCuXLbymPYB8+ZQyw8mHvdw560e8zVFIWyA==} - - hono@4.12.18: - resolution: {integrity: sha512-RWzP96k/yv0PQfyXnWjs6zot20TqfpfsNXhOnev8d1InAxubW93L11/oNUc3tQqn2G0bSdAOBpX+2uDFHV7kdQ==} + hono@4.12.23: + resolution: {integrity: sha512-eIaZ9qDgu7XV0pxOCrg7/WhnQ6Ivm22UcxhXx/A3dcbqbbYgBEkc6e/J/s7j2tS96zoB0S9VBdLwQNCWwUo4LA==} engines: {node: '>=16.9.0'} html-escaper@2.0.2: @@ -1417,9 +2195,17 @@ packages: resolution: {integrity: sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==} engines: {node: '>=18.18.0'} + idb-keyval@6.2.5: + resolution: {integrity: sha512-eKQkTnS0relYsSOYomx8ozIbmdsQCKUdhyuIaQ2DZgKuaxtyQQMkyD/wlnQN32pO3yutN1b1L8uqwcDKaJd7/Q==} + ieee754@1.2.1: resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + incur@0.4.8: + resolution: {integrity: sha512-SjW2QNtY7Bcvqjj0KvOJ3qiuFATlC3mEpYQyUzWdLb9MAzakkQ1KQg5WZ/yy2tDGBmHLN/zUJNimIWEqkRfqdw==} + engines: {node: '>=22'} + hasBin: true + inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} @@ -1459,17 +2245,14 @@ packages: resolution: {integrity: sha512-E+zBKpQ2t6MEo1VsonYmluk9NxGrbzpeeLC2xIViuO2EjU2xsXsBPwTr3Ykv9l08UYEVEdWeRZNouaZqF6RN0w==} engines: {node: '>= 0.4'} - is-node-process@1.2.0: - resolution: {integrity: sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==} + is-network-error@1.3.2: + resolution: {integrity: sha512-PhBY86zaxNZUuWP6h13Vu5oFe0XY6/UlKzQnYFELzGVHygP3MxmvTfYSG7GN3aIab/iWudSMgjSnG9Dq+nHrgA==} + engines: {node: '>=16'} is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - is-path-inside@3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - is-plain-obj@2.1.0: resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} engines: {node: '>=8'} @@ -1498,10 +2281,6 @@ packages: resolution: {integrity: sha512-p3EcsicXjit7SaskXHs1hA91QxgTw46Fv6EFKKGS5DRFLD8yKnohjF3hxoju94b/OcMZoQukzpPpBE9uLVKzgQ==} engines: {node: '>= 0.4'} - is-unicode-supported@0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - is-unicode-supported@2.1.0: resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==} engines: {node: '>=18'} @@ -1513,6 +2292,15 @@ packages: isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} + iso-base@4.4.0: + resolution: {integrity: sha512-W4BJbRDBi66wcBFJ23ZlGnFOZ874CIut4y9PlsScMSYu7ckCX+MWNAaEoE0efTSYDoVEn1qy0FDVSjE8q0ieHw==} + + iso-kv@3.2.0: + resolution: {integrity: sha512-rMVXO7zDEecXOJEiDnbDqjZ7gSe7VqDn2FTkUFWeqkcYMmgMdmB7pDgUaZxiEyiL1+gO7RnbqEI2Ce3xIW4UBQ==} + + iso-web@3.1.2: + resolution: {integrity: sha512-OpWz+KNH4vYNVvpc6T1z/zkZtT6iTQXYjc0sIbkPDwYEM5Qurg0LYESrEHloxb6xj5T/2rrnsTtaYlUSIzgicg==} + isows@1.0.7: resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} peerDependencies: @@ -1533,13 +2321,12 @@ packages: jackspeak@3.4.3: resolution: {integrity: sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==} + js-base64@3.7.8: + resolution: {integrity: sha512-hNngCeKxIUQiEUN3GPJOkz4wF/YvdUdbNL9hsBcMQTkKzboD7T/q3OYOuuPZLUE6dBxSGpwhk5mwuDud7JVAow==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@4.1.0: - resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==} - hasBin: true - json-schema-traverse@1.0.0: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} @@ -1553,9 +2340,18 @@ packages: resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==} engines: {node: '>=6'} - kysely@0.28.17: - resolution: {integrity: sha512-nbD8lB9EB3wNdMhOCdx5Li8DxnLbvKByylRLcJ1h+4SkrowVeECAyZlyiKMThF7xFdRz0jSQ2MoJr+wXux2y0Q==} - engines: {node: '>=20.0.0'} + kysely@0.26.3: + resolution: {integrity: sha512-yWSgGi9bY13b/W06DD2OCDDHQmq1kwTGYlQ4wpZkMOJqMGCstVCFIvxCCVG4KfY1/3G0MhDAcZsip/Lw8/vJWw==} + engines: {node: '>=14.0.0'} + + kysely@0.29.2: + resolution: {integrity: sha512-s6WVJyEZrbm6jhBpiKHsGHyePMrVQKJ85wZCFCr9W4QHv6WTjWIrdvTmO9hDEA3bNK0xkrE2DqrHsXMLWuZpQg==} + engines: {node: '>=22.0.0'} + + libsql@0.5.29: + resolution: {integrity: sha512-8lMP8iMgiBzzoNbAPQ59qdVcj6UaE/Vnm+fiwX4doX4Narook0a4GPKWBEv+CR8a1OwbfkgL18uBfBjWdF0Fzg==} + cpu: [x64, arm64, wasm32, arm] + os: [darwin, linux, win32] lilconfig@3.1.3: resolution: {integrity: sha512-/vlFKAoH5Cgt3Ie+JLhRbwOsCQePABiU3tJ1egGvyQ+33R/vcwM2Zl2QR/LzjsBeItPt3oSVXapn+m4nQDvpzw==} @@ -1568,10 +2364,6 @@ packages: lodash@4.18.1: resolution: {integrity: sha512-dMInicTPVE8d1e5otfwmmjlxkZoUpiVLwyeTdUsi/Caj/gfzzblBcCE5sRHV/AsjuCmxWrte2TNGSYuCeCq+0Q==} - log-symbols@4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - log-symbols@7.0.1: resolution: {integrity: sha512-ja1E3yCr9i/0hmBVaM0bfwDjnGy8I/s6PP4DFp+yP+a+mrHO4Rm7DtmnqROTUkHIkqffC84YY7AeqX6oFk0WFg==} engines: {node: '>=18'} @@ -1630,11 +2422,6 @@ packages: resolution: {integrity: sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==} engines: {node: '>=16 || 14 >=14.17'} - mocha@11.7.5: - resolution: {integrity: sha512-mTT6RgopEYABzXWFx+GcJ+ZQ32kp4fMf0xvpZIIfSq9Z8lC/++MtcCnQ9t5FP2veYEP95FIYSvW+U9fV4xrlig==} - engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} - hasBin: true - mri@1.2.0: resolution: {integrity: sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==} engines: {node: '>=4'} @@ -1646,22 +2433,11 @@ packages: ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - msw@2.14.2: - resolution: {integrity: sha512-D2bTe0tpuf9nw4DA39wFaqUD/hRPKj0DKpo2lAqu+A47Ifg4+h0hbfn6QxVOsiUY2uhgEN6TTpGSHDsc+ysYNg==} - engines: {node: '>=18'} - hasBin: true - peerDependencies: - typescript: '>= 4.8.x' - peerDependenciesMeta: - typescript: - optional: true - multiformats@13.4.2: resolution: {integrity: sha512-eh6eHCrRi1+POZ3dA+Dq1C6jhP1GNtr9CRINMb67OKzqW9I5DUuZM/3jLPlzhgpGeiNUlEGEbkCYChXMCc/8DQ==} - mute-stream@3.0.0: - resolution: {integrity: sha512-dkEJPVvun4FryqBmZ5KhDo0K9iDXAwn08tMLDinNdRBNPcYEDiWYysLcc6k3mjTMlbP9KyylvRpd4wFtwrT9rw==} - engines: {node: ^20.17.0 || >=22.9.0} + multiformats@14.0.0: + resolution: {integrity: sha512-iWK1RrAS58p2NDfeZFuSUSv3ZPewTIhsGbh/5NgeGGJwJmRljLxGtjRR3nkn+loG3zl+IrfR/W1590QnrSK+Gg==} nanoid@3.3.12: resolution: {integrity: sha512-ZB9RH/39qpq5Vu6Y+NmUaFhQR6pp+M2Xt76XBnEwDaGcVAqhlvxrl3B2bKS5D3NH3QR76v3aSrKaF/Kiy7lEtQ==} @@ -1673,94 +2449,94 @@ packages: engines: {node: ^18 || >=20} hasBin: true - node@runtime:24.15.0: + node@runtime:24.16.0: resolution: type: variations variants: - resolution: archive: tarball bin: bin/node - integrity: sha256-3UvHfctfTJoslkNzm7WTUAzLCUE+xCyqD47w5e8RYJU= + integrity: sha256-MN/Y5EMiwnEoE/JeFjwlPK1TvkPgmJB7i1NIvxdKSWg= type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-aix-ppc64.tar.gz + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-aix-ppc64.tar.gz targets: - cpu: ppc64 os: aix - resolution: archive: tarball bin: bin/node - integrity: sha256-NyMxuWl3mrXRW5SYhPxur4jVr+h73ouogdZAC5EA/8Q= + integrity: sha256-ORidq07rFXBsQkrwrAijBEyeSPfbEqfXf2t6r8fdXfY= type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-darwin-arm64.tar.gz + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-darwin-arm64.tar.gz targets: - cpu: arm64 os: darwin - resolution: archive: tarball bin: bin/node - integrity: sha256-/9XuKTRnkn8+5zGlU+uI/R9Iz3TuvC10prq+SvIoZzs= + integrity: sha256-KYtMezy4B2XIcD5CuQMkpOzjtmNJR7iedpw8mAq1UYU= type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-darwin-x64.tar.gz + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-darwin-x64.tar.gz targets: - cpu: x64 os: darwin - resolution: archive: tarball bin: bin/node - integrity: sha256-c6/CNNVYwkkZh19RwtHqACoq2k6m+DYBo4OGn++mTu0= + integrity: sha256-WJ9bbdT8/uTf2nMBOQPJZquqir2T28nUNlRORytPDnQ= type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-arm64.tar.gz + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-linux-arm64.tar.gz targets: - cpu: arm64 os: linux - resolution: archive: tarball bin: bin/node - integrity: sha256-sfiJAKSxY2XqulYmkwT8Edp1gdvwNVLUSV+azh/AX20= + integrity: sha256-JStYIFNNwDBKKFQcmkRDfPpyAufyAiXSjUk5MsWOl6o= type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-ppc64le.tar.gz + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-linux-ppc64le.tar.gz targets: - cpu: ppc64le os: linux - resolution: archive: tarball bin: bin/node - integrity: sha256-+YVFVDnVL+m43mqPbQe/7MxzbepSfofqyv5ajXUWo4A= + integrity: sha256-Vnrwl1s0BVFrmx3cZEKaI+yMWi+mzwE5EmGkzHdOPt0= type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-s390x.tar.gz + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-linux-s390x.tar.gz targets: - cpu: s390x os: linux - resolution: archive: tarball bin: bin/node - integrity: sha256-RINoctmuxJ8ea1KpqSKHLbmisC0jWmFqVoG2qF/sjYk= + integrity: sha256-L69qOH6bYriI4hxU8BJJ+ydTf/7PGELyn0yRnQpZoP8= type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-linux-x64.tar.gz + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-linux-x64.tar.gz targets: - cpu: x64 os: linux - resolution: archive: zip bin: node.exe - integrity: sha256-yet0Au2ibiun5EtnJ/yFqN5WxQlbH3Hr0wYokiEaoRY= - prefix: node-v24.15.0-win-arm64 + integrity: sha256-FINGEdTGs8BgVOcAdzK5BHTBbgsy85XgW1Wlce9xxtI= + prefix: node-v24.16.0-win-arm64 type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-win-arm64.zip + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-win-arm64.zip targets: - cpu: arm64 os: win32 - resolution: archive: zip bin: node.exe - integrity: sha256-zFFJ6r1Td5zh573FQBZDYi0MfmgAreGJKKdn6UC7DmI= - prefix: node-v24.15.0-win-x64 + integrity: sha256-7aypvVjsjpIDfaxOh31S9rj0MLgcGLV+JktOL7ERzVY= + prefix: node-v24.16.0-win-x64 type: binary - url: https://nodejs.org/download/release/v24.15.0/node-v24.15.0-win-x64.zip + url: https://nodejs.org/download/release/v24.16.0/node-v24.16.0-win-x64.zip targets: - cpu: x64 os: win32 - version: 24.15.0 + version: 24.16.0 hasBin: true normalize-path@3.0.0: @@ -1806,17 +2582,26 @@ packages: resolution: {integrity: sha512-84cglkRILFxdtA8hAvLNdMrtBpPNBTrQ9/ulg0FA7xLMnD6mifv+enAIeRmvtv+WgdCE+LPGOfQmtJRrVaIVhQ==} engines: {node: '>=20'} - outvariant@1.4.3: - resolution: {integrity: sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==} + ox@0.14.25: + resolution: {integrity: sha512-8DoibKtxE8yw63Y2jjMhlbjaURev6WCx4QR4MWLusl2/qIaeTzMJMBIYIDl1KOF45+8H1Ur6eLTdPlUoO8PlRw==} + peerDependencies: + typescript: '>=5.4.0' + peerDependenciesMeta: + typescript: + optional: true - ox@0.14.20: - resolution: {integrity: sha512-rby38C3nDn8eQkf29Zgw4hkCZJ64Qqi0zRPWL8ENUQ7JVuoITqrVtwWQgM/He19SCMUEc7hS/Sjw0jIOSLJhOw==} + ox@0.14.29: + resolution: {integrity: sha512-M5j87Ec4V99MQdRct/g09eWXW60g6zhHTUs1lr4deUtrPDnezBdCJTgKd7pxqTpSZBFveV0ALi9jMMuT1qKyNg==} peerDependencies: typescript: '>=5.4.0' peerDependenciesMeta: typescript: optional: true + p-all@5.0.1: + resolution: {integrity: sha512-LMT7WX9ZSaq3J1zjloApkIVmtz0ZdMFSIqbuiEa3txGYPLjUPOvgOPOx3nFjo+f37ZYL+1aY666I2SG7GVwLOA==} + engines: {node: '>=16'} + p-finally@1.0.0: resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} engines: {node: '>=4'} @@ -1825,10 +2610,38 @@ packages: resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} engines: {node: '>=10'} + p-limit@7.3.0: + resolution: {integrity: sha512-7cIXg/Z0M5WZRblrsOla88S4wAK+zOQQWeBYfV3qJuJXMr+LnbYjaadrFaS0JILfEDPVqHyKnZ1Z/1d6J9VVUw==} + engines: {node: '>=20'} + p-locate@5.0.0: resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} engines: {node: '>=10'} + p-locate@7.0.0: + resolution: {integrity: sha512-FRPW2lT1b/B8/CNkCOZ/Xl4mz52CWzwb+/dLa0GcCrH7u7djFf36VftuRJ5w/eCr1YXtbTGPuGoEDVSk14EwNQ==} + engines: {node: '>=20'} + + p-map@6.0.0: + resolution: {integrity: sha512-T8BatKGY+k5rU+Q/GTYgrEf2r4xRMevAN5mtXc2aPc4rS1j3s+vWTaO2Wag94neXuCAUAs8cxBL9EeB5EA6diw==} + engines: {node: '>=16'} + + p-map@7.0.4: + resolution: {integrity: sha512-tkAQEw8ysMzmkhgw8k+1U/iPhWNhykKnSk4Rd5zLoPJCuJaGRPo6YposrZgaxHKzDHdDWWZvE/Sk7hsL2X/CpQ==} + engines: {node: '>=18'} + + p-queue@9.3.0: + resolution: {integrity: sha512-7NED7xhQ74Ngp4JP/2e0VZHp7vSWfJfqeiR92jPgxsz6m0Se4P03YoTKa9dDXyZ3r6P616gUXttrB6nnHYKang==} + engines: {node: '>=20'} + + p-retry@8.0.0: + resolution: {integrity: sha512-kFVqH1HxOHp8LupNsOys7bSV09VYTRLxarH/mokO4Rqhk6wGi70E0jh4VzvVGXfEVNggHoHLAMWsQqHyU1Ey9A==} + engines: {node: '>=22'} + + p-some@7.0.0: + resolution: {integrity: sha512-9ldWF6puBzuchsUq7M1THjwwmoiXesqRdpB4WH0D7urKXdGkIaDqVhQS2BSfRRYZ970j9gm3U4/h9hHQx2G1Ug==} + engines: {node: '>=20'} + p-timeout@3.2.0: resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} engines: {node: '>=8'} @@ -1837,6 +2650,10 @@ packages: resolution: {integrity: sha512-MyIV3ZA/PmyBN/ud8vV9XzwTrNtR4jFrObymZYnZqMmW0zA8Z17vnT0rBgFE/TlohB+YCHqXMgZzb3Csp49vqg==} engines: {node: '>=14.16'} + p-timeout@7.0.1: + resolution: {integrity: sha512-AxTM2wDGORHGEkPCt8yqxOTMgpfbEHqF51f/5fJCmwFC3C/zNcGT63SymH2ttOAaiIws2zVg4+izQCjrakcwHg==} + engines: {node: '>=20'} + p-wait-for@3.2.0: resolution: {integrity: sha512-wpgERjNkLrBiFmkMEjuZJEWKKDrNfHCKA1OhyN1wg1FrLkULbviEy6py1AyJUgZ72YWFbZ38FIpnqvVqAlDUwA==} engines: {node: '>=8'} @@ -1867,17 +2684,14 @@ packages: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} - path-to-regexp@6.3.0: - resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} - pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} - pg-cloudflare@1.3.0: - resolution: {integrity: sha512-6lswVVSztmHiRtD6I8hw4qP/nDm1EJbKMRhf3HCYaqud7frGysPv7FYJ5noZQdhQtN2xJnimfMtvQq21pdbzyQ==} + pg-cloudflare@1.4.0: + resolution: {integrity: sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==} - pg-connection-string@2.12.0: - resolution: {integrity: sha512-U7qg+bpswf3Cs5xLzRqbXbQl85ng0mfSV/J0nnA31MCLgvEaAo7CIhmeyrmJpOr7o+zm0rXK+hNnT5l9RHkCkQ==} + pg-connection-string@2.13.0: + resolution: {integrity: sha512-EMnU9E2fSULdsbErBbMaXJvFeD9B4+nPcM3f+4lsiCR0BHLPrLVjv3DbyM2hgQQviKJaTWIRRTjKjWlHg3p2ig==} pg-copy-streams@6.0.6: resolution: {integrity: sha512-Z+Dd2C2NIDTsjyFKmc6a9QLlpM8tjpERx+43RSx0WmL7j3uNChERi3xSvZUL0hWJ1oRUn4S3fhyt3apdSrTyKQ==} @@ -1886,13 +2700,13 @@ packages: resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==} engines: {node: '>=4.0.0'} - pg-pool@3.13.0: - resolution: {integrity: sha512-gB+R+Xud1gLFuRD/QgOIgGOBE2KCQPaPwkzBBGC9oG69pHTkhQeIuejVIk3/cnDyX39av2AxomQiyPT13WKHQA==} + pg-pool@3.14.0: + resolution: {integrity: sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==} peerDependencies: pg: '>=8.0' - pg-protocol@1.13.0: - resolution: {integrity: sha512-zzdvXfS6v89r6v7OcFCHfHlyG/wvry1ALxZo4LqgUoy7W9xhBDMaqOuMiF3qEV45VqsN6rdlcehHrfDtlCPc8w==} + pg-protocol@1.14.0: + resolution: {integrity: sha512-n5taZ1kO3s9ngDTVxsEznOqCyToTgz0FLuPq0B33COy5pPpuWJpY3/2oRBVETuOgzdqRXfWpM9HIhp2LBBT1BA==} pg-query-emscripten@5.1.0: resolution: {integrity: sha512-H1ZWOzLRddmHuE4GZqFjjo55hA9zMiePz/WDDGANA/EnvILCJps9pcRucyGd+MFvapeYOy6TWSYz6DbtBOaxRQ==} @@ -1901,8 +2715,8 @@ packages: resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==} engines: {node: '>=4'} - pg@8.20.0: - resolution: {integrity: sha512-ldhMxz2r8fl/6QkXnBD3CR9/xg694oT6DZQ2s6c/RI28OjtSOpxnPrUCGOBJ46RCUxcWdx3p6kw/xnDHjKvaRA==} + pg@8.21.0: + resolution: {integrity: sha512-AUP1EYJuHraQGsVoCQVIcM7TEJVGtDzxWtGFZd8rds9d+CCXlU5Js1rYgfLNvxy9iJrpHjGrRjoi/3BT9fRyiA==} engines: {node: '>= 16.0.0'} peerDependencies: pg-native: '>=3.0.1' @@ -1934,13 +2748,13 @@ packages: resolution: {integrity: sha512-ip4qdzjkAyDDZklUaZkcRFb2iA118H9SgRh8yzTkSQK8HilsOJF7rSY8HoW5+I0M46AZgX/pxbprf2vvzQCE0Q==} hasBin: true - playwright-core@1.58.2: - resolution: {integrity: sha512-yZkEtftgwS8CsfYo7nm0KE8jsvm6i/PTgVtB8DL726wNf6H2IMsDuxCpJj59KDaxCtSnrWan2AeDqM7JBaultg==} + playwright-core@1.60.0: + resolution: {integrity: sha512-9bW6zvX/m0lEbgTKJ6YppOKx8H3VOPBMOCFh2irXFOT4BbHgrx5hPjwJYLT40Lu+4qtD36qKc/Hn56StUW57IA==} engines: {node: '>=18'} hasBin: true - playwright-test@14.1.13: - resolution: {integrity: sha512-ozRXG7DXViuEbAAKE6jJ7MQYlgeKLI3EXJXrA3OE6oksinWbnfc4j6nONZdkzJ23BpnAZBCdHea/5WpP1oZy8g==} + playwright-test@14.1.15: + resolution: {integrity: sha512-JjioBl7/g84Mp4Q/KkwiMZJhqnycUpc5pMVM1rjJYXzzcekKJnlp4r3JBvkmMeIR/t1FwKr8rC/D0RIz6bLRbg==} engines: {node: '>=16.0.0'} hasBin: true @@ -1951,8 +2765,8 @@ packages: resolution: {integrity: sha512-/+5VFTchJDoVj3bhoqi6UeymcD00DAwb1nJwamzPvHEszJ4FpF6SNNbUbOS8yI56qHzdV8eK0qEfOSiodkTdxg==} engines: {node: '>= 0.4'} - postcss@8.5.14: - resolution: {integrity: sha512-SoSL4+OSEtR99LHFZQiJLkT59C5B1amGO1NzTwj7TT1qCUgUO6hxOvzkOYxD+vMrXBM3XJIKzokoERdqQq/Zmg==} + postcss@8.5.15: + resolution: {integrity: sha512-FfR8sjd4em2T6fb3I2MwAJU7HWVMr9zba+enmQeeWFfCbm+UOC/0X4DS8XtpUTMwWMGbjKYP7xjfNekzyGmB3A==} engines: {node: ^10 || ^12 || >=14} postgres-array@2.0.0: @@ -1991,6 +2805,9 @@ packages: resolution: {integrity: sha512-6ZiOBfCywsD4k1BN9IX0uZhF+tJkV8q8llP64G5Hajs4JOeVLPCwpPVcpXy3BwYiUGgyJzsJJQeOIv7+hDSq8g==} engines: {node: ^16 || ^18 || >=20} + promise-limit@2.7.0: + resolution: {integrity: sha512-7nJ6v5lnJsXwGprnGXga4wx6d1POjvi5Qmf1ivTRxTjH4Z/9Czja/UCMLVmB9N93GeWOU93XaFaEt6jbuoagNw==} + proper-lockfile@4.1.2: resolution: {integrity: sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==} @@ -2000,8 +2817,9 @@ packages: quick-format-unescaped@4.0.4: resolution: {integrity: sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==} - randombytes@2.1.0: - resolution: {integrity: sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==} + random-int@3.1.0: + resolution: {integrity: sha512-h8CRz8cpvzj0hC/iH/1Gapgcl2TQ6xtnCpyOI5WvWfXf/yrDx2DOU+tD9rX23j36IF11xg1KqB9W11Z18JPMdw==} + engines: {node: '>=12'} readable-stream@3.6.2: resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==} @@ -2031,6 +2849,9 @@ packages: resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} engines: {node: '>=0.10.0'} + resolve-pkg-maps@1.0.0: + resolution: {integrity: sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==} + restore-cursor@5.1.0: resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==} engines: {node: '>=18'} @@ -2039,19 +2860,16 @@ packages: resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} engines: {node: '>= 4'} - rettime@0.11.11: - resolution: {integrity: sha512-ILJRqVWBCTlg9r42fFgwVZx1gnFAcQF8mRoMkbgQfIrjEDf9nbBFDFx00oloOa+Q869FUtaYDXZvEfnecQSCoQ==} - reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - roarr@7.21.4: - resolution: {integrity: sha512-qvfUKCrpPzhWmQ4NxRYnuwhkI5lwmObhBU06BCK/lpj6PID9nL4Hk6XDwek2foKI+TMaV+Yw//XZshGF2Lox/Q==} + roarr@7.21.5: + resolution: {integrity: sha512-nvelZ4llbfodVanR/gG17H8jpnqgyPX01c4ekQYfoghjEKvAXn7aPPToVG8ngyxf4qtvTC1O5AxQe5PysnF4xg==} engines: {node: '>=18.0'} - rollup@4.60.3: - resolution: {integrity: sha512-pAQK9HalE84QSm4Po3EmWIZPd3FnjkShVkiMlz1iligWYkWQ7wHYd1PF/T7QZ5TVSD6uSTon5gBVMSM4JfBV+A==} + rollup@4.60.4: + resolution: {integrity: sha512-WHeFSbZYsPu3+bLoNRUuAO+wavNlocOPf3wSHTP7hcFKVnJeWsYlCDbr3mTS14FCizf9ccIxXA8sGL8zKeQN3g==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true @@ -2076,17 +2894,11 @@ packages: semver-compare@1.0.0: resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} - semver@7.7.4: - resolution: {integrity: sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==} + semver@7.8.1: + resolution: {integrity: sha512-rkVq3IXh+4FDGch+KwzX3aV9W3kO54GyEgpvBzSyctDA6Xtd7RJQV1xmXbeQp5v7+VzLOfVqiutSE6GICgPFvg==} engines: {node: '>=10'} hasBin: true - serialize-javascript@6.0.2: - resolution: {integrity: sha512-Saa1xPByTTq2gdeFZYLLo+RFE35NHZkAbqZeWNd3BpzppeVisAqpDjcp8dyf6uIvEqJRd46jemmyA4iFIeVk8g==} - - set-cookie-parser@3.1.0: - resolution: {integrity: sha512-kjnC1DXBHcxaOaOXBHBeRtltsDG2nUiUni+jP92M9gYdW12rsmx92UsfpH7o5tDRs7I1ZZPSQJQGv3UaRfCiuw==} - set-function-length@1.2.2: resolution: {integrity: sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==} engines: {node: '>= 0.4'} @@ -2110,6 +2922,9 @@ packages: resolution: {integrity: sha512-2wcC/oGxHis/BoHkkPwldgiPSYcpZK3JU28WoMVv55yHJgcZ8rlXvuG9iZggz+sU1d4bRgIGASwyWqjxu3FM0g==} engines: {node: '>=18'} + sisteransi@1.0.5: + resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + sonic-boom@3.8.1: resolution: {integrity: sha512-y4Z8LCDBuum+PBP3lSV7RHrXscqksve/bi0as7mhwVnBW+/wUqKT/2Kb7um8yqcFy0duYbbPxzt89Zy2nOCaxg==} @@ -2132,10 +2947,6 @@ packages: resolution: {integrity: sha512-WjlahMgHmCJpqzU8bIBy4qtsZdU9lRlcZE3Lvyej6t4tuOuv1vk57OW3MBrj6hXBFx/nNoC9MPMTcr5YA7NQbg==} engines: {node: '>=6'} - statuses@2.0.2: - resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} - engines: {node: '>= 0.8'} - stdin-discarder@0.3.2: resolution: {integrity: sha512-eCPu1qRxPVkl5605OTWF8Wz40b4Mf45NY5LQmVPQ599knfs5QhASUm9GbJ5BDMDOXgrnh0wyEdvzmL//YMlw0A==} engines: {node: '>=18'} @@ -2143,9 +2954,6 @@ packages: stream-browserify@3.0.0: resolution: {integrity: sha512-H73RAHsVBapbim0tU2JwwOiXUj+fikfiaoYAKHF3VJfA0pe2BCzkhAHBlLG6REzE+2WNZcxOXjK7lkso+9euLA==} - strict-event-emitter@0.5.1: - resolution: {integrity: sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==} - string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} @@ -2177,10 +2985,6 @@ packages: resolution: {integrity: sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==} engines: {node: '>=18'} - strip-json-comments@3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - stubborn-fs@2.0.0: resolution: {integrity: sha512-Y0AvSwDw8y+nlSNFXMm2g6L51rBGdAQT20J3YSOqxC53Lo3bjWRtr2BKcfYoAf352WYpsZSTURrA0tqhfgudPA==} @@ -2191,13 +2995,20 @@ packages: resolution: {integrity: sha512-H+ue8Zo4vJmV2nRjpx86P35lzwDT3nItnIsocgumgr0hHMQ+ZGq5vrERg9kJBo5AWGmxZDhzDo+WVIJqkB0cGA==} engines: {node: '>=16'} + supports-color@10.2.2: + resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} + engines: {node: '>=18'} + supports-color@7.2.0: resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} engines: {node: '>=8'} - supports-color@8.1.1: - resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} - engines: {node: '>=10'} + supports-hyperlinks@4.4.0: + resolution: {integrity: sha512-UKbpT93hN5Nr9go5UY7bopIB9YQlMz9nm/ct4IXt/irb5YRkn9WaqrOBJGZ5Pwvsd5FQzSVeYlGdXoCAPQZrPg==} + engines: {node: '>=20'} + + sync-multihash-sha2@1.0.0: + resolution: {integrity: sha512-A5gVpmtKF0ov+/XID0M0QRJqF2QxAsj3x/LlDC8yivzgoYCoWkV+XaZPfVu7Vj1T/hYzYS1tfjwboSbXjqocug==} tagged-tag@1.0.0: resolution: {integrity: sha512-yEFYrVhod+hdNyx7g5Bnkkb0G6si8HJurOoOEgC8B/O0uXLHlaey/65KRv6cuWBNhBgHKAROVpc7QyYqE5gFng==} @@ -2214,6 +3025,10 @@ packages: resolution: {integrity: sha512-d79HhZya5Djd7am0q+W4RTsSU+D/aJzM+4Y4AGJGuGlgM2L6sx5ZvOYTmZjqPhrDrV6xJTtRSm1JCLj6V6LHLQ==} engines: {node: '>=14.16'} + terminal-link@5.0.0: + resolution: {integrity: sha512-qFAy10MTMwjzjU8U16YS4YoZD+NQLHzLssFMNqgravjbvIPNiqkGFR4yjhJfmY9R5OFU7+yHxc6y+uGHkKwLRA==} + engines: {node: '>=20'} + terminal-size@4.0.1: resolution: {integrity: sha512-avMLDQpUI9I5XFrklECw1ZEUPJhqzcwSWsyyI8blhRLT+8N1jLJWLWWYQpB2q2xthq8xDvjZPISVh53T/+CLYQ==} engines: {node: '>=18'} @@ -2229,25 +3044,17 @@ packages: resolution: {integrity: sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==} engines: {node: '>=12.0.0'} - tldts-core@7.0.30: - resolution: {integrity: sha512-uiHN8PIB1VmWyS98eZYja4xzlYqeFZVjb4OuYlJQnZAuJhMw4PbKQOKgHKhBdJR3FE/t5mUQ1Kd80++B+qhD1Q==} - - tldts@7.0.30: - resolution: {integrity: sha512-ELrFxuqsDdHUwoh0XxDbxuLD3Wnz49Z57IFvTtvWy1hJdcMZjXLIuonjilCiWHlT2GbE4Wlv1wKVTzDFnXH1aw==} - hasBin: true - to-regex-range@5.0.1: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + tokenx@1.3.0: + resolution: {integrity: sha512-NLdXTEZkKiO0gZuLtMoZKjCXTREXeZZt8nnnNeyoXtNZAfG/GKGSbQtLU5STspc0rMSwcA+UJfWZkbNU01iKmQ==} + totalist@3.0.1: resolution: {integrity: sha512-sf4i37nQ2LBx4m3wB74y+ubopq6W/dIzXg0FDGjsYnZHVa1Da8FH853wlL2gtUhg+xJXjfk3kUZS3BRoQeoQBQ==} engines: {node: '>=6'} - tough-cookie@6.0.1: - resolution: {integrity: sha512-LktZQb3IeoUWB9lqR5EWTHgW/VTITCXg4D21M+lvybRVdylLrRMnqaIONLVb5mav8vM19m44HIcGq4qASeu2Qw==} - engines: {node: '>=16'} - trouter@2.0.1: resolution: {integrity: sha512-kr8SKKw94OI+xTGOkfsvwZQ8mWoikZDd2n8XZHjJVZUARZT+4/VV6cacRS6CLsH9bNm+HFIPU1Zx4CnNnb4qlQ==} engines: {node: '>=6'} @@ -2265,6 +3072,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.22.3: + resolution: {integrity: sha512-mdoNxBC/cSQObGGVQ5Bpn5i+yv7j68gk3Nfm3wFjcJg3Z0Mix9jzAFfP12prmm5eVGmDKtp0yyArrs0Q+8gZHg==} + engines: {node: '>=18.0.0'} + hasBin: true + type-fest@0.7.1: resolution: {integrity: sha512-Ne2YiiGN8bmrmJJEuTWTLJR32nh/JdL1+PSicowtNb0WFpn59GK8/lfD61bVtzguz7b3PBt74nxpv/Pw5po5Rg==} engines: {node: '>=8'} @@ -2281,8 +3093,8 @@ packages: resolution: {integrity: sha512-tLq3bSNx+xSpwvAJnzrK0Ep5CLNWjvFTOp71URMaAEWBfRb9nnJiBoUe0tF8bI4ZFO3omgBR6NvnbzVUT3Ly4g==} engines: {node: '>=14.16'} - type-fest@5.6.0: - resolution: {integrity: sha512-8ZiHFm91orbSAe2PSAiSVBVko18pbhbiB3U9GglSzF/zCGkR+rxpHx6sEMCUm4kxY4LjDIUGgCfUMtwfZfjfUA==} + type-fest@5.7.0: + resolution: {integrity: sha512-1URUxUqfHFM1c+zfSPsa3gnkO7Aq21qyH75SIduNYz4SzY964rn1X2vCMQaHSHhktiw+0kPa2iyb6PUpXqB6Vg==} engines: {node: '>=20'} typescript@6.0.3: @@ -2294,8 +3106,12 @@ packages: resolution: {integrity: sha512-erJsJwQ0tKdwuqI0359U8ijkFmfiTcq25JvvzRVc1VP+2son1NJRXhxcAKJmAW3ajM8JSGAfsAXye8g4s+znxA==} engines: {node: '>=18'} - undici-types@7.19.2: - resolution: {integrity: sha512-qYVnV5OEm2AW8cJMCpdV20CDyaN3g0AjDlOGf1OW4iaDEx8MwdtChUp4zu4H0VP3nDRF/8RKWH+IPp9uW0YGZg==} + uint8array-extras@1.5.0: + resolution: {integrity: sha512-rvKSBiC5zqCCiDZ9kAOszZcDvdAHwwIKJG33Ykj43OKcWsnmcBRL09YTU4nOeHZ8Y2a7l1MgTd08SBe9A8Qj6A==} + engines: {node: '>=18'} + + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} unicorn-magic@0.3.0: resolution: {integrity: sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==} @@ -2305,8 +3121,9 @@ packages: resolution: {integrity: sha512-VGXBUVwxKMBUznyffQweQABPRRW1vHZAbadFZud4pLFAqRGvv/96vafgjWFqzourzr8YonlQiPgH0YCJfawoGQ==} engines: {node: '>=12'} - until-async@3.0.2: - resolution: {integrity: sha512-IiSk4HlzAMqTUseHHe3VhIGyuFmN90zMTpD3Z3y8jeQbzLIq500MVM7Jq2vUAnTKAFPJrqwkzr6PoTcPhGcOiw==} + unlimited-timeout@0.1.0: + resolution: {integrity: sha512-D4g+mxFeQGQHzCfnvij+R35ukJ0658Zzudw7j16p4tBBbNasKkKM4SocYxqhwT5xA7a9JYWDzKkEFyMlRi5sng==} + engines: {node: '>=20'} urlpattern-polyfill@10.1.0: resolution: {integrity: sha512-IGjKp/o0NL3Bso1PymYURCJxMPNAf/ILOpendP9f5B6e1rTJgdgiOvgfoT8VxCAdY+Wisb9uhGaJJf3yZ2V9nw==} @@ -2321,8 +3138,8 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} - viem@2.48.8: - resolution: {integrity: sha512-Xj3Nrt66SKtn06kczU91ELn9Difr84ZM5A62BTlaisT5lpgt058i2mBkfMZCXHGb1ocOLjzC2ztPhD0Lvky7uQ==} + viem@2.51.3: + resolution: {integrity: sha512-DA4EbrsvatzzLo6MwcWWiv6kI6dIr3I9HH9B6qsJaClN/s0AjIDUz5RIxl+VmGrovIUCcIvG8744yuGH7d37zw==} peerDependencies: typescript: '>=5.0.4' peerDependenciesMeta: @@ -2337,32 +3154,27 @@ packages: vite-tsconfig-paths@4.3.1: resolution: {integrity: sha512-cfgJwcGOsIxXOLU/nELPny2/LUD/lcf1IbfyeKTv2bsupVbTH/xpFtdQlBmIP1GEK2CjjLxYhFfB+QODFAx5aw==} peerDependencies: - vite: ^6.4.2 + vite: '*' peerDependenciesMeta: vite: optional: true - vite@6.4.2: - resolution: {integrity: sha512-2N/55r4JDJ4gdrCvGgINMy+HH3iRpNIz8K6SFwVsA+JbQScLiC+clmAxBgwiSPgcG9U15QmvqCGWzMbqda5zGQ==} - engines: {node: ^18.0.0 || ^20.0.0 || >=22.0.0} + vite@5.4.21: + resolution: {integrity: sha512-o5a9xKjbtuhY6Bi5S3+HvbRERmouabWbyUcpXXUA1u+GNUKoROi9byOJ8M0nHbHYHkYICiMlqxkg1KkYmm25Sw==} + engines: {node: ^18.0.0 || >=20.0.0} hasBin: true peerDependencies: - '@types/node': ^18.0.0 || ^20.0.0 || >=22.0.0 - jiti: '>=1.21.0' + '@types/node': ^18.0.0 || >=20.0.0 less: '*' lightningcss: ^1.21.0 sass: '*' sass-embedded: '*' stylus: '*' sugarss: '*' - terser: ^5.16.0 - tsx: ^4.8.1 - yaml: ^2.4.2 + terser: ^5.4.0 peerDependenciesMeta: '@types/node': optional: true - jiti: - optional: true less: optional: true lightningcss: @@ -2377,16 +3189,12 @@ packages: optional: true terser: optional: true - tsx: - optional: true - yaml: - optional: true when-exit@2.1.5: resolution: {integrity: sha512-VGkKJ564kzt6Ms1dbgPP/yuIoQCrsFAnRbptpC5wOEsDaNsbCB2bnfnaA8i/vRs5tjUSEOtIuvl9/MyVsvQZCg==} - which-typed-array@1.1.20: - resolution: {integrity: sha512-LYfpUkmqwl0h9A2HL09Mms427Q1RZWuOHsukfVcKRq9q95iQxdw0ix1JQrqbcDR9PH1QDwf5Qo8OZb5lksZ8Xg==} + which-typed-array@1.1.21: + resolution: {integrity: sha512-zbRA8cVm6io/d5W8uIe2hblzN76/Wm3v/yiythQvr+dpBWeqhPSWIDNj4zOyHi4zKbMK6DN34Xsr9jPHJERAEw==} engines: {node: '>= 0.4'} which@2.0.2: @@ -2399,9 +3207,6 @@ packages: engines: {node: '>=18.0.0'} hasBin: true - workerpool@9.3.4: - resolution: {integrity: sha512-TmPRQYYSAnnDiEB0P/Ytip7bFGvqnSU6I2BcuSw7Hx+JSg/DsUi5ebYfc8GYaSdpuvOcEs6dXxPurOYpe9QFwg==} - wrap-ansi@7.0.0: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} @@ -2410,8 +3215,8 @@ packages: resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==} engines: {node: '>=12'} - ws@8.18.3: - resolution: {integrity: sha512-PEIGCY5tSlUt50cqyMXfCzX+oOPqN0vuGqWzbcJ2xvnkzkq46oOpz7dQaTDBdfICb4N14+GARUDw2XV2N4tvzg==} + ws@8.20.1: + resolution: {integrity: sha512-It4dO0K5v//JtTXuPkfEOaI3uUN87iYPnqo/ZzqCoG3g8uhA66QUMs/SrM0YK7/NAu+r4LMh/9dq2A7k+rHs+w==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -2422,8 +3227,8 @@ packages: utf-8-validate: optional: true - ws@8.20.0: - resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} + ws@8.21.0: + resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -2442,14 +3247,15 @@ packages: resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} engines: {node: '>=10'} + yaml@2.9.0: + resolution: {integrity: sha512-2AvhNX3mb8zd6Zy7INTtSpl1F15HW6Wnqj0srWlkKLcpYl/gMIMJiyuGq2KeI2YFxUPjdlB+3Lc10seMLtL4cA==} + engines: {node: '>= 14.6'} + hasBin: true + yargs-parser@21.1.1: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs-unparser@2.0.0: - resolution: {integrity: sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==} - engines: {node: '>=10'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -2458,65 +3264,88 @@ packages: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + yoctocolors@2.1.2: resolution: {integrity: sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug==} engines: {node: '>=18'} + zod@4.4.3: + resolution: {integrity: sha512-ytENFjIJFl2UwYglde2jchW2Hwm4GJFLDiSXWdTrJQBIN9Fcyp7n4DhxJEiWNAJMV1/BqWfW/kkg71UDcHJyTQ==} + snapshots: '@adraffy/ens-normalize@1.11.1': {} '@arr/every@1.0.1': {} - '@babel/code-frame@7.29.0': + '@babel/code-frame@7.29.7': dependencies: - '@babel/helper-validator-identifier': 7.28.5 + '@babel/helper-validator-identifier': 7.29.7 js-tokens: 4.0.0 picocolors: 1.1.1 - '@babel/helper-validator-identifier@7.28.5': {} + '@babel/helper-validator-identifier@7.29.7': {} '@bcoe/v8-coverage@1.0.2': {} - '@biomejs/biome@2.4.11': + '@biomejs/biome@2.4.16': optionalDependencies: - '@biomejs/cli-darwin-arm64': 2.4.11 - '@biomejs/cli-darwin-x64': 2.4.11 - '@biomejs/cli-linux-arm64': 2.4.11 - '@biomejs/cli-linux-arm64-musl': 2.4.11 - '@biomejs/cli-linux-x64': 2.4.11 - '@biomejs/cli-linux-x64-musl': 2.4.11 - '@biomejs/cli-win32-arm64': 2.4.11 - '@biomejs/cli-win32-x64': 2.4.11 - - '@biomejs/cli-darwin-arm64@2.4.11': + '@biomejs/cli-darwin-arm64': 2.4.16 + '@biomejs/cli-darwin-x64': 2.4.16 + '@biomejs/cli-linux-arm64': 2.4.16 + '@biomejs/cli-linux-arm64-musl': 2.4.16 + '@biomejs/cli-linux-x64': 2.4.16 + '@biomejs/cli-linux-x64-musl': 2.4.16 + '@biomejs/cli-win32-arm64': 2.4.16 + '@biomejs/cli-win32-x64': 2.4.16 + + '@biomejs/cli-darwin-arm64@2.4.16': optional: true - '@biomejs/cli-darwin-x64@2.4.11': + '@biomejs/cli-darwin-x64@2.4.16': optional: true - '@biomejs/cli-linux-arm64-musl@2.4.11': + '@biomejs/cli-linux-arm64-musl@2.4.16': optional: true - '@biomejs/cli-linux-arm64@2.4.11': + '@biomejs/cli-linux-arm64@2.4.16': optional: true - '@biomejs/cli-linux-x64-musl@2.4.11': + '@biomejs/cli-linux-x64-musl@2.4.16': optional: true - '@biomejs/cli-linux-x64@2.4.11': + '@biomejs/cli-linux-x64@2.4.16': optional: true - '@biomejs/cli-win32-arm64@2.4.11': + '@biomejs/cli-win32-arm64@2.4.16': optional: true - '@biomejs/cli-win32-x64@2.4.11': + '@biomejs/cli-win32-x64@2.4.16': optional: true + '@cfworker/json-schema@4.1.1': {} + + '@clack/core@1.4.1': + dependencies: + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + + '@clack/prompts@1.5.1': + dependencies: + '@clack/core': 1.4.1 + fast-string-width: 3.0.2 + fast-wrap-ansi: 0.2.2 + sisteransi: 1.0.5 + '@commander-js/extra-typings@12.1.0(commander@12.1.0)': dependencies: commander: 12.1.0 + '@drizzle-team/brocli@0.10.2': {} + '@electric-sql/pglite@0.2.13': {} '@envelop/core@5.5.1': @@ -2536,112 +3365,428 @@ snapshots: '@whatwg-node/promise-helpers': 1.3.2 tslib: 2.8.1 + '@esbuild-kit/core-utils@3.3.2': + dependencies: + esbuild: 0.18.20 + source-map-support: 0.5.21 + + '@esbuild-kit/esm-loader@2.6.5': + dependencies: + '@esbuild-kit/core-utils': 3.3.2 + get-tsconfig: 4.14.0 + + '@esbuild/aix-ppc64@0.21.5': + optional: true + '@esbuild/aix-ppc64@0.25.11': optional: true + '@esbuild/aix-ppc64@0.25.12': + optional: true + + '@esbuild/aix-ppc64@0.28.0': + optional: true + + '@esbuild/android-arm64@0.18.20': + optional: true + + '@esbuild/android-arm64@0.21.5': + optional: true + '@esbuild/android-arm64@0.25.11': optional: true + '@esbuild/android-arm64@0.25.12': + optional: true + + '@esbuild/android-arm64@0.28.0': + optional: true + + '@esbuild/android-arm@0.18.20': + optional: true + + '@esbuild/android-arm@0.21.5': + optional: true + '@esbuild/android-arm@0.25.11': optional: true + '@esbuild/android-arm@0.25.12': + optional: true + + '@esbuild/android-arm@0.28.0': + optional: true + + '@esbuild/android-x64@0.18.20': + optional: true + + '@esbuild/android-x64@0.21.5': + optional: true + '@esbuild/android-x64@0.25.11': optional: true + '@esbuild/android-x64@0.25.12': + optional: true + + '@esbuild/android-x64@0.28.0': + optional: true + + '@esbuild/darwin-arm64@0.18.20': + optional: true + + '@esbuild/darwin-arm64@0.21.5': + optional: true + '@esbuild/darwin-arm64@0.25.11': optional: true + '@esbuild/darwin-arm64@0.25.12': + optional: true + + '@esbuild/darwin-arm64@0.28.0': + optional: true + + '@esbuild/darwin-x64@0.18.20': + optional: true + + '@esbuild/darwin-x64@0.21.5': + optional: true + '@esbuild/darwin-x64@0.25.11': optional: true + '@esbuild/darwin-x64@0.25.12': + optional: true + + '@esbuild/darwin-x64@0.28.0': + optional: true + + '@esbuild/freebsd-arm64@0.18.20': + optional: true + + '@esbuild/freebsd-arm64@0.21.5': + optional: true + '@esbuild/freebsd-arm64@0.25.11': optional: true + '@esbuild/freebsd-arm64@0.25.12': + optional: true + + '@esbuild/freebsd-arm64@0.28.0': + optional: true + + '@esbuild/freebsd-x64@0.18.20': + optional: true + + '@esbuild/freebsd-x64@0.21.5': + optional: true + '@esbuild/freebsd-x64@0.25.11': optional: true - '@esbuild/linux-arm64@0.25.11': + '@esbuild/freebsd-x64@0.25.12': + optional: true + + '@esbuild/freebsd-x64@0.28.0': + optional: true + + '@esbuild/linux-arm64@0.18.20': + optional: true + + '@esbuild/linux-arm64@0.21.5': + optional: true + + '@esbuild/linux-arm64@0.25.11': + optional: true + + '@esbuild/linux-arm64@0.25.12': + optional: true + + '@esbuild/linux-arm64@0.28.0': + optional: true + + '@esbuild/linux-arm@0.18.20': + optional: true + + '@esbuild/linux-arm@0.21.5': + optional: true + + '@esbuild/linux-arm@0.25.11': + optional: true + + '@esbuild/linux-arm@0.25.12': + optional: true + + '@esbuild/linux-arm@0.28.0': + optional: true + + '@esbuild/linux-ia32@0.18.20': + optional: true + + '@esbuild/linux-ia32@0.21.5': + optional: true + + '@esbuild/linux-ia32@0.25.11': + optional: true + + '@esbuild/linux-ia32@0.25.12': + optional: true + + '@esbuild/linux-ia32@0.28.0': + optional: true + + '@esbuild/linux-loong64@0.18.20': + optional: true + + '@esbuild/linux-loong64@0.21.5': + optional: true + + '@esbuild/linux-loong64@0.25.11': + optional: true + + '@esbuild/linux-loong64@0.25.12': + optional: true + + '@esbuild/linux-loong64@0.28.0': + optional: true + + '@esbuild/linux-mips64el@0.18.20': + optional: true + + '@esbuild/linux-mips64el@0.21.5': + optional: true + + '@esbuild/linux-mips64el@0.25.11': + optional: true + + '@esbuild/linux-mips64el@0.25.12': + optional: true + + '@esbuild/linux-mips64el@0.28.0': + optional: true + + '@esbuild/linux-ppc64@0.18.20': + optional: true + + '@esbuild/linux-ppc64@0.21.5': + optional: true + + '@esbuild/linux-ppc64@0.25.11': + optional: true + + '@esbuild/linux-ppc64@0.25.12': + optional: true + + '@esbuild/linux-ppc64@0.28.0': + optional: true + + '@esbuild/linux-riscv64@0.18.20': + optional: true + + '@esbuild/linux-riscv64@0.21.5': + optional: true + + '@esbuild/linux-riscv64@0.25.11': + optional: true + + '@esbuild/linux-riscv64@0.25.12': + optional: true + + '@esbuild/linux-riscv64@0.28.0': + optional: true + + '@esbuild/linux-s390x@0.18.20': + optional: true + + '@esbuild/linux-s390x@0.21.5': + optional: true + + '@esbuild/linux-s390x@0.25.11': + optional: true + + '@esbuild/linux-s390x@0.25.12': + optional: true + + '@esbuild/linux-s390x@0.28.0': + optional: true + + '@esbuild/linux-x64@0.18.20': + optional: true + + '@esbuild/linux-x64@0.21.5': + optional: true + + '@esbuild/linux-x64@0.25.11': + optional: true + + '@esbuild/linux-x64@0.25.12': + optional: true + + '@esbuild/linux-x64@0.28.0': + optional: true + + '@esbuild/netbsd-arm64@0.25.11': + optional: true + + '@esbuild/netbsd-arm64@0.25.12': + optional: true + + '@esbuild/netbsd-arm64@0.28.0': + optional: true + + '@esbuild/netbsd-x64@0.18.20': + optional: true + + '@esbuild/netbsd-x64@0.21.5': + optional: true + + '@esbuild/netbsd-x64@0.25.11': + optional: true + + '@esbuild/netbsd-x64@0.25.12': + optional: true + + '@esbuild/netbsd-x64@0.28.0': + optional: true + + '@esbuild/openbsd-arm64@0.25.11': + optional: true + + '@esbuild/openbsd-arm64@0.25.12': + optional: true + + '@esbuild/openbsd-arm64@0.28.0': + optional: true + + '@esbuild/openbsd-x64@0.18.20': + optional: true + + '@esbuild/openbsd-x64@0.21.5': + optional: true + + '@esbuild/openbsd-x64@0.25.11': + optional: true + + '@esbuild/openbsd-x64@0.25.12': + optional: true + + '@esbuild/openbsd-x64@0.28.0': + optional: true + + '@esbuild/openharmony-arm64@0.25.11': + optional: true + + '@esbuild/openharmony-arm64@0.25.12': + optional: true + + '@esbuild/openharmony-arm64@0.28.0': + optional: true + + '@esbuild/sunos-x64@0.18.20': + optional: true + + '@esbuild/sunos-x64@0.21.5': + optional: true + + '@esbuild/sunos-x64@0.25.11': optional: true - '@esbuild/linux-arm@0.25.11': + '@esbuild/sunos-x64@0.25.12': optional: true - '@esbuild/linux-ia32@0.25.11': + '@esbuild/sunos-x64@0.28.0': optional: true - '@esbuild/linux-loong64@0.25.11': + '@esbuild/win32-arm64@0.18.20': optional: true - '@esbuild/linux-mips64el@0.25.11': + '@esbuild/win32-arm64@0.21.5': optional: true - '@esbuild/linux-ppc64@0.25.11': + '@esbuild/win32-arm64@0.25.11': optional: true - '@esbuild/linux-riscv64@0.25.11': + '@esbuild/win32-arm64@0.25.12': optional: true - '@esbuild/linux-s390x@0.25.11': + '@esbuild/win32-arm64@0.28.0': optional: true - '@esbuild/linux-x64@0.25.11': + '@esbuild/win32-ia32@0.18.20': optional: true - '@esbuild/netbsd-arm64@0.25.11': + '@esbuild/win32-ia32@0.21.5': optional: true - '@esbuild/netbsd-x64@0.25.11': + '@esbuild/win32-ia32@0.25.11': optional: true - '@esbuild/openbsd-arm64@0.25.11': + '@esbuild/win32-ia32@0.25.12': optional: true - '@esbuild/openbsd-x64@0.25.11': + '@esbuild/win32-ia32@0.28.0': optional: true - '@esbuild/openharmony-arm64@0.25.11': + '@esbuild/win32-x64@0.18.20': optional: true - '@esbuild/sunos-x64@0.25.11': + '@esbuild/win32-x64@0.21.5': optional: true - '@esbuild/win32-arm64@0.25.11': + '@esbuild/win32-x64@0.25.11': optional: true - '@esbuild/win32-ia32@0.25.11': + '@esbuild/win32-x64@0.25.12': optional: true - '@esbuild/win32-x64@0.25.11': + '@esbuild/win32-x64@0.28.0': optional: true '@escape.tech/graphql-armor-max-aliases@2.6.2': dependencies: - graphql: 16.11.0 + graphql: 16.14.0 optionalDependencies: '@envelop/core': 5.5.1 '@escape.tech/graphql-armor-types': 0.7.0 '@escape.tech/graphql-armor-max-depth@2.4.2': dependencies: - graphql: 16.11.0 + graphql: 16.14.0 optionalDependencies: '@envelop/core': 5.5.1 '@escape.tech/graphql-armor-types': 0.7.0 '@escape.tech/graphql-armor-max-tokens@2.5.1': dependencies: - graphql: 16.11.0 + graphql: 16.14.0 optionalDependencies: '@envelop/core': 5.5.1 '@escape.tech/graphql-armor-types': 0.7.0 '@escape.tech/graphql-armor-types@0.7.0': dependencies: - graphql: 16.11.0 + graphql: 16.14.0 optional: true '@fastify/busboy@3.2.0': {} + '@filoz/synapse-core@0.6.0(typescript@6.0.3)(viem@2.51.3(typescript@6.0.3)(zod@4.4.3))': + dependencies: + dnum: 2.17.0 + iso-web: 3.1.2 + multiformats: 14.0.0 + ox: 0.14.29(typescript@6.0.3)(zod@4.4.3) + p-locate: 7.0.0 + p-queue: 9.3.0 + p-some: 7.0.0 + sync-multihash-sha2: 1.0.0 + viem: 2.51.3(typescript@6.0.3)(zod@4.4.3) + zod: 4.4.3 + transitivePeerDependencies: + - typescript + '@graphql-tools/executor@1.5.3(graphql@16.8.2)': dependencies: '@graphql-tools/utils': 11.1.0(graphql@16.8.2) @@ -2701,36 +3846,9 @@ snapshots: '@repeaterjs/repeater': 3.0.6 tslib: 2.8.1 - '@hono/node-server@1.19.14(hono@4.12.18)': - dependencies: - hono: 4.12.18 - - '@inquirer/ansi@2.0.5': {} - - '@inquirer/confirm@6.0.12(@types/node@25.6.0)': + '@hono/node-server@1.19.5(hono@4.12.23)': dependencies: - '@inquirer/core': 11.1.9(@types/node@25.6.0) - '@inquirer/type': 4.0.5(@types/node@25.6.0) - optionalDependencies: - '@types/node': 25.6.0 - - '@inquirer/core@11.1.9(@types/node@25.6.0)': - dependencies: - '@inquirer/ansi': 2.0.5 - '@inquirer/figures': 2.0.5 - '@inquirer/type': 4.0.5(@types/node@25.6.0) - cli-width: 4.1.0 - fast-wrap-ansi: 0.2.0 - mute-stream: 3.0.0 - signal-exit: 4.1.0 - optionalDependencies: - '@types/node': 25.6.0 - - '@inquirer/figures@2.0.5': {} - - '@inquirer/type@4.0.5(@types/node@25.6.0)': - optionalDependencies: - '@types/node': 25.6.0 + hono: 4.12.23 '@isaacs/cliui@8.0.2': dependencies: @@ -2752,14 +3870,71 @@ snapshots: '@jridgewell/resolve-uri': 3.1.2 '@jridgewell/sourcemap-codec': 1.5.5 - '@mswjs/interceptors@0.41.8': + '@libsql/client@0.17.3': + dependencies: + '@libsql/core': 0.17.3 + '@libsql/hrana-client': 0.10.0 + js-base64: 3.7.8 + libsql: 0.5.29 + promise-limit: 2.7.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/core@0.17.3': + dependencies: + js-base64: 3.7.8 + + '@libsql/darwin-arm64@0.5.29': + optional: true + + '@libsql/darwin-x64@0.5.29': + optional: true + + '@libsql/hrana-client@0.10.0': + dependencies: + '@libsql/isomorphic-ws': 0.1.5 + js-base64: 3.7.8 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/isomorphic-ws@0.1.5': + dependencies: + '@types/ws': 8.18.1 + ws: 8.21.0 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + + '@libsql/linux-arm-gnueabihf@0.5.29': + optional: true + + '@libsql/linux-arm-musleabihf@0.5.29': + optional: true + + '@libsql/linux-arm64-gnu@0.5.29': + optional: true + + '@libsql/linux-arm64-musl@0.5.29': + optional: true + + '@libsql/linux-x64-gnu@0.5.29': + optional: true + + '@libsql/linux-x64-musl@0.5.29': + optional: true + + '@libsql/win32-x64-msvc@0.5.29': + optional: true + + '@modelcontextprotocol/server@2.0.0-alpha.2(@cfworker/json-schema@4.1.1)': dependencies: - '@open-draft/deferred-promise': 2.2.0 - '@open-draft/logger': 0.3.0 - '@open-draft/until': 2.1.0 - is-node-process: 1.2.0 - outvariant: 1.4.3 - strict-event-emitter: 0.5.1 + zod: 4.4.3 + optionalDependencies: + '@cfworker/json-schema': 4.1.1 + + '@neon-rs/load@0.0.4': {} '@noble/ciphers@1.3.0': {} @@ -2781,17 +3956,6 @@ snapshots: '@nodelib/fs.scandir': 2.1.5 fastq: 1.20.1 - '@open-draft/deferred-promise@2.2.0': {} - - '@open-draft/deferred-promise@3.0.0': {} - - '@open-draft/logger@0.3.0': - dependencies: - is-node-process: 1.2.0 - outvariant: 1.4.3 - - '@open-draft/until@2.1.0': {} - '@opentelemetry/api@1.9.1': {} '@pkgjs/parseargs@0.11.0': @@ -2801,99 +3965,99 @@ snapshots: '@polka/url@1.0.0-next.29': {} - '@ponder/utils@0.2.18(typescript@6.0.3)(viem@2.48.8(typescript@6.0.3))': + '@ponder/utils@0.2.18(typescript@6.0.3)(viem@2.51.3(typescript@6.0.3))': dependencies: - viem: 2.48.8(typescript@6.0.3) + viem: 2.51.3(typescript@6.0.3)(zod@4.4.3) optionalDependencies: typescript: 6.0.3 '@repeaterjs/repeater@3.0.6': {} - '@rollup/rollup-android-arm-eabi@4.60.3': + '@rollup/rollup-android-arm-eabi@4.60.4': optional: true - '@rollup/rollup-android-arm64@4.60.3': + '@rollup/rollup-android-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-arm64@4.60.3': + '@rollup/rollup-darwin-arm64@4.60.4': optional: true - '@rollup/rollup-darwin-x64@4.60.3': + '@rollup/rollup-darwin-x64@4.60.4': optional: true - '@rollup/rollup-freebsd-arm64@4.60.3': + '@rollup/rollup-freebsd-arm64@4.60.4': optional: true - '@rollup/rollup-freebsd-x64@4.60.3': + '@rollup/rollup-freebsd-x64@4.60.4': optional: true - '@rollup/rollup-linux-arm-gnueabihf@4.60.3': + '@rollup/rollup-linux-arm-gnueabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm-musleabihf@4.60.3': + '@rollup/rollup-linux-arm-musleabihf@4.60.4': optional: true - '@rollup/rollup-linux-arm64-gnu@4.60.3': + '@rollup/rollup-linux-arm64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-arm64-musl@4.60.3': + '@rollup/rollup-linux-arm64-musl@4.60.4': optional: true - '@rollup/rollup-linux-loong64-gnu@4.60.3': + '@rollup/rollup-linux-loong64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-loong64-musl@4.60.3': + '@rollup/rollup-linux-loong64-musl@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-gnu@4.60.3': + '@rollup/rollup-linux-ppc64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-ppc64-musl@4.60.3': + '@rollup/rollup-linux-ppc64-musl@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-gnu@4.60.3': + '@rollup/rollup-linux-riscv64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-riscv64-musl@4.60.3': + '@rollup/rollup-linux-riscv64-musl@4.60.4': optional: true - '@rollup/rollup-linux-s390x-gnu@4.60.3': + '@rollup/rollup-linux-s390x-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-gnu@4.60.3': + '@rollup/rollup-linux-x64-gnu@4.60.4': optional: true - '@rollup/rollup-linux-x64-musl@4.60.3': + '@rollup/rollup-linux-x64-musl@4.60.4': optional: true - '@rollup/rollup-openbsd-x64@4.60.3': + '@rollup/rollup-openbsd-x64@4.60.4': optional: true - '@rollup/rollup-openharmony-arm64@4.60.3': + '@rollup/rollup-openharmony-arm64@4.60.4': optional: true - '@rollup/rollup-win32-arm64-msvc@4.60.3': + '@rollup/rollup-win32-arm64-msvc@4.60.4': optional: true - '@rollup/rollup-win32-ia32-msvc@4.60.3': + '@rollup/rollup-win32-ia32-msvc@4.60.4': optional: true - '@rollup/rollup-win32-x64-gnu@4.60.3': + '@rollup/rollup-win32-x64-gnu@4.60.4': optional: true - '@rollup/rollup-win32-x64-msvc@4.60.3': + '@rollup/rollup-win32-x64-msvc@4.60.4': optional: true - '@rvagg/ponder@0.16.6(@opentelemetry/api@1.9.1)(@types/node@25.6.0)(hono@4.12.18)(typescript@6.0.3)(viem@2.48.8(typescript@6.0.3))': + '@rvagg/ponder@0.16.6(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/node@25.9.2)(@types/pg@8.20.0)(hono@4.12.23)(typescript@6.0.3)(viem@2.51.3(typescript@6.0.3))': dependencies: - '@babel/code-frame': 7.29.0 + '@babel/code-frame': 7.29.7 '@commander-js/extra-typings': 12.1.0(commander@12.1.0) '@electric-sql/pglite': 0.2.13 '@escape.tech/graphql-armor-max-aliases': 2.6.2 '@escape.tech/graphql-armor-max-depth': 2.4.2 '@escape.tech/graphql-armor-max-tokens': 2.5.1 - '@hono/node-server': 1.19.14(hono@4.12.18) - '@ponder/utils': 0.2.18(typescript@6.0.3)(viem@2.48.8(typescript@6.0.3)) + '@hono/node-server': 1.19.5(hono@4.12.23) + '@ponder/utils': 0.2.18(typescript@6.0.3)(viem@2.51.3(typescript@6.0.3)) abitype: 0.10.3(typescript@6.0.3) ansi-escapes: 7.3.0 commander: 12.1.0 @@ -2901,29 +4065,29 @@ snapshots: dataloader: 2.2.3 detect-package-manager: 3.0.2 dotenv: 16.6.1 - drizzle-orm: 0.45.2(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.1)(kysely@0.28.17)(pg@8.20.0) + drizzle-orm: 0.41.0(@electric-sql/pglite@0.2.13)(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(kysely@0.26.3)(pg@8.21.0) glob: 10.5.0 graphql: 16.8.2 graphql-yoga: 5.17.1(graphql@16.8.2) - hono: 4.12.18 + hono: 4.12.23 http-terminator: 3.2.0 - kysely: 0.28.17 - pg: 8.20.0 - pg-connection-string: 2.12.0 + kysely: 0.26.3 + pg: 8.21.0 + pg-connection-string: 2.13.0 pg-copy-streams: 6.0.6 pg-query-emscripten: 5.1.0 picocolors: 1.1.1 pino: 8.21.0 prom-client: 15.1.3 - semver: 7.7.4 + semver: 7.8.1 stacktrace-parser: 0.1.11 superjson: 2.2.6 terminal-size: 4.0.1 - viem: 2.48.8(typescript@6.0.3) - vite: 6.4.2(@types/node@25.6.0) - vite-node: 1.0.2(@types/node@25.6.0) - vite-tsconfig-paths: 4.3.1(typescript@6.0.3)(vite@6.4.2(@types/node@25.6.0)) - ws: 8.20.0 + viem: 2.51.3(typescript@6.0.3)(zod@4.4.3) + vite: 5.4.21(@types/node@25.9.2) + vite-node: 1.0.2(@types/node@25.9.2) + vite-tsconfig-paths: 4.3.1(typescript@6.0.3)(vite@5.4.21(@types/node@25.9.2)) + ws: 8.21.0 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -2941,7 +4105,6 @@ snapshots: - '@types/node' - '@types/pg' - '@types/sql.js' - - '@upstash/redis' - '@vercel/postgres' - '@xata.io/client' - better-sqlite3 @@ -2949,7 +4112,6 @@ snapshots: - bun-types - expo-sqlite - gel - - jiti - knex - less - lightningcss @@ -2965,11 +4127,11 @@ snapshots: - sugarss - supports-color - terser - - tsx - utf-8-validate - - yaml - zod + '@scalar/openapi-types@0.8.0': {} + '@scure/base@1.2.6': {} '@scure/bip32@1.7.0': @@ -2987,23 +4149,27 @@ snapshots: '@sindresorhus/merge-streams@4.0.0': {} - '@types/assert@1.5.11': {} + '@standard-schema/spec@1.1.0': {} + + '@toon-format/toon@2.3.0': {} '@types/estree@1.0.8': {} '@types/istanbul-lib-coverage@2.0.6': {} - '@types/mocha@10.0.10': {} - - '@types/node@25.6.0': + '@types/node@25.9.2': dependencies: - undici-types: 7.19.2 + undici-types: 7.24.6 - '@types/set-cookie-parser@2.4.10': + '@types/pg@8.20.0': dependencies: - '@types/node': 25.6.0 + '@types/node': 25.9.2 + pg-protocol: 1.14.0 + pg-types: 2.2.0 - '@types/statuses@2.0.6': {} + '@types/ws@8.18.1': + dependencies: + '@types/node': 25.9.2 '@whatwg-node/disposablestack@0.0.6': dependencies: @@ -3042,9 +4208,15 @@ snapshots: optionalDependencies: typescript: 6.0.3 - abitype@1.2.3(typescript@6.0.3): + abitype@1.2.3(typescript@6.0.3)(zod@4.4.3): + optionalDependencies: + typescript: 6.0.3 + zod: 4.4.3 + + abitype@1.2.4(typescript@6.0.3)(zod@4.4.3): optionalDependencies: typescript: 6.0.3 + zod: 4.4.3 abort-controller@3.0.0: dependencies: @@ -3060,6 +4232,10 @@ snapshots: optionalDependencies: ajv: 8.20.0 + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + ajv@8.20.0: dependencies: fast-deep-equal: 3.1.3 @@ -3086,8 +4262,6 @@ snapshots: normalize-path: 3.0.0 picomatch: 2.3.2 - argparse@2.0.1: {} - assert@2.1.0: dependencies: call-bind: 1.0.9 @@ -3115,11 +4289,13 @@ snapshots: base64-js@1.5.1: {} + bigint-mod-arith@3.3.1: {} + binary-extensions@2.3.0: {} bintrees@1.0.2: {} - brace-expansion@2.1.0: + brace-expansion@2.1.1: dependencies: balanced-match: 1.0.2 @@ -3127,7 +4303,7 @@ snapshots: dependencies: balanced-match: 3.0.1 - brace-expansion@5.0.5: + brace-expansion@5.0.6: dependencies: balanced-match: 4.0.4 @@ -3135,8 +4311,6 @@ snapshots: dependencies: fill-range: 7.1.1 - browser-stdout@1.3.1: {} - buffer-from@1.1.2: {} buffer@6.0.3: @@ -3177,14 +4351,7 @@ snapshots: call-bind-apply-helpers: 1.0.2 get-intrinsic: 1.3.0 - camelcase@6.3.0: {} - - camelcase@8.0.0: {} - - chalk@4.1.2: - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 + camelcase@9.0.0: {} chalk@5.6.2: {} @@ -3210,8 +4377,6 @@ snapshots: cli-spinners@3.4.0: {} - cli-width@4.1.0: {} - cliui@8.0.1: dependencies: string-width: 4.2.3 @@ -3235,12 +4400,22 @@ snapshots: dot-prop: 8.0.2 env-paths: 3.0.0 json-schema-typed: 8.0.2 - semver: 7.7.4 + semver: 7.8.1 uint8array-extras: 0.3.0 - convert-source-map@2.0.0: {} + conf@15.1.0: + dependencies: + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + atomically: 2.1.1 + debounce-fn: 6.0.0 + dot-prop: 10.1.0 + env-paths: 3.0.0 + json-schema-typed: 8.0.2 + semver: 7.8.1 + uint8array-extras: 1.5.0 - cookie@1.1.1: {} + convert-source-map@2.0.0: {} copy-anything@4.0.5: dependencies: @@ -3266,13 +4441,13 @@ snapshots: dependencies: mimic-fn: 4.0.0 - debug@4.4.3(supports-color@8.1.1): + debounce-fn@6.0.0: dependencies: - ms: 2.1.3 - optionalDependencies: - supports-color: 8.1.1 + mimic-function: 5.0.1 - decamelize@4.0.0: {} + debug@4.4.3: + dependencies: + ms: 2.1.3 define-data-property@1.1.4: dependencies: @@ -3288,11 +4463,24 @@ snapshots: delay@5.0.0: {} + delay@7.0.0: + dependencies: + random-int: 3.1.0 + unlimited-timeout: 0.1.0 + + detect-libc@2.0.2: {} + detect-package-manager@3.0.2: dependencies: execa: 5.1.1 - diff@7.0.0: {} + dnum@2.17.0: + dependencies: + from-exponential: 1.1.1 + + dot-prop@10.1.0: + dependencies: + type-fest: 5.7.0 dot-prop@8.0.2: dependencies: @@ -3300,12 +4488,39 @@ snapshots: dotenv@16.6.1: {} - drizzle-orm@0.45.2(@electric-sql/pglite@0.2.13)(@opentelemetry/api@1.9.1)(kysely@0.28.17)(pg@8.20.0): + drizzle-kit@0.31.10: + dependencies: + '@drizzle-team/brocli': 0.10.2 + '@esbuild-kit/esm-loader': 2.6.5 + esbuild: 0.25.12 + tsx: 4.22.3 + + drizzle-orm@0.41.0(@electric-sql/pglite@0.2.13)(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(kysely@0.26.3)(pg@8.21.0): + optionalDependencies: + '@electric-sql/pglite': 0.2.13 + '@libsql/client': 0.17.3 + '@opentelemetry/api': 1.9.1 + '@types/pg': 8.20.0 + kysely: 0.26.3 + pg: 8.21.0 + + drizzle-orm@0.45.2(@electric-sql/pglite@0.2.13)(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(kysely@0.26.3)(pg@8.21.0): + optionalDependencies: + '@electric-sql/pglite': 0.2.13 + '@libsql/client': 0.17.3 + '@opentelemetry/api': 1.9.1 + '@types/pg': 8.20.0 + kysely: 0.26.3 + pg: 8.21.0 + + drizzle-orm@0.45.2(@electric-sql/pglite@0.2.13)(@libsql/client@0.17.3)(@opentelemetry/api@1.9.1)(@types/pg@8.20.0)(kysely@0.29.2)(pg@8.21.0): optionalDependencies: '@electric-sql/pglite': 0.2.13 + '@libsql/client': 0.17.3 '@opentelemetry/api': 1.9.1 - kysely: 0.28.17 - pg: 8.20.0 + '@types/pg': 8.20.0 + kysely: 0.29.2 + pg: 8.21.0 dunder-proto@1.0.1: dependencies: @@ -3327,12 +4542,63 @@ snapshots: es-errors@1.3.0: {} - es-object-atoms@1.1.1: + es-object-atoms@1.1.2: dependencies: es-errors: 1.3.0 esbuild-plugin-wasm@1.1.0: {} + esbuild@0.18.20: + optionalDependencies: + '@esbuild/android-arm': 0.18.20 + '@esbuild/android-arm64': 0.18.20 + '@esbuild/android-x64': 0.18.20 + '@esbuild/darwin-arm64': 0.18.20 + '@esbuild/darwin-x64': 0.18.20 + '@esbuild/freebsd-arm64': 0.18.20 + '@esbuild/freebsd-x64': 0.18.20 + '@esbuild/linux-arm': 0.18.20 + '@esbuild/linux-arm64': 0.18.20 + '@esbuild/linux-ia32': 0.18.20 + '@esbuild/linux-loong64': 0.18.20 + '@esbuild/linux-mips64el': 0.18.20 + '@esbuild/linux-ppc64': 0.18.20 + '@esbuild/linux-riscv64': 0.18.20 + '@esbuild/linux-s390x': 0.18.20 + '@esbuild/linux-x64': 0.18.20 + '@esbuild/netbsd-x64': 0.18.20 + '@esbuild/openbsd-x64': 0.18.20 + '@esbuild/sunos-x64': 0.18.20 + '@esbuild/win32-arm64': 0.18.20 + '@esbuild/win32-ia32': 0.18.20 + '@esbuild/win32-x64': 0.18.20 + + esbuild@0.21.5: + optionalDependencies: + '@esbuild/aix-ppc64': 0.21.5 + '@esbuild/android-arm': 0.21.5 + '@esbuild/android-arm64': 0.21.5 + '@esbuild/android-x64': 0.21.5 + '@esbuild/darwin-arm64': 0.21.5 + '@esbuild/darwin-x64': 0.21.5 + '@esbuild/freebsd-arm64': 0.21.5 + '@esbuild/freebsd-x64': 0.21.5 + '@esbuild/linux-arm': 0.21.5 + '@esbuild/linux-arm64': 0.21.5 + '@esbuild/linux-ia32': 0.21.5 + '@esbuild/linux-loong64': 0.21.5 + '@esbuild/linux-mips64el': 0.21.5 + '@esbuild/linux-ppc64': 0.21.5 + '@esbuild/linux-riscv64': 0.21.5 + '@esbuild/linux-s390x': 0.21.5 + '@esbuild/linux-x64': 0.21.5 + '@esbuild/netbsd-x64': 0.21.5 + '@esbuild/openbsd-x64': 0.21.5 + '@esbuild/sunos-x64': 0.21.5 + '@esbuild/win32-arm64': 0.21.5 + '@esbuild/win32-ia32': 0.21.5 + '@esbuild/win32-x64': 0.21.5 + esbuild@0.25.11: optionalDependencies: '@esbuild/aix-ppc64': 0.25.11 @@ -3362,14 +4628,72 @@ snapshots: '@esbuild/win32-ia32': 0.25.11 '@esbuild/win32-x64': 0.25.11 - escalade@3.2.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.0: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.0 + '@esbuild/android-arm': 0.28.0 + '@esbuild/android-arm64': 0.28.0 + '@esbuild/android-x64': 0.28.0 + '@esbuild/darwin-arm64': 0.28.0 + '@esbuild/darwin-x64': 0.28.0 + '@esbuild/freebsd-arm64': 0.28.0 + '@esbuild/freebsd-x64': 0.28.0 + '@esbuild/linux-arm': 0.28.0 + '@esbuild/linux-arm64': 0.28.0 + '@esbuild/linux-ia32': 0.28.0 + '@esbuild/linux-loong64': 0.28.0 + '@esbuild/linux-mips64el': 0.28.0 + '@esbuild/linux-ppc64': 0.28.0 + '@esbuild/linux-riscv64': 0.28.0 + '@esbuild/linux-s390x': 0.28.0 + '@esbuild/linux-x64': 0.28.0 + '@esbuild/netbsd-arm64': 0.28.0 + '@esbuild/netbsd-x64': 0.28.0 + '@esbuild/openbsd-arm64': 0.28.0 + '@esbuild/openbsd-x64': 0.28.0 + '@esbuild/openharmony-arm64': 0.28.0 + '@esbuild/sunos-x64': 0.28.0 + '@esbuild/win32-arm64': 0.28.0 + '@esbuild/win32-ia32': 0.28.0 + '@esbuild/win32-x64': 0.28.0 - escape-string-regexp@4.0.0: {} + escalade@3.2.0: {} event-target-shim@5.0.1: {} eventemitter3@5.0.1: {} + eventemitter3@5.0.4: {} + events@3.3.0: {} execa@5.1.1: @@ -3423,7 +4747,7 @@ snapshots: fast-uri@3.1.2: {} - fast-wrap-ansi@0.2.0: + fast-wrap-ansi@0.2.2: dependencies: fast-string-width: 3.0.2 @@ -3448,8 +4772,6 @@ snapshots: locate-path: 6.0.0 path-exists: 4.0.0 - flat@5.0.2: {} - for-each@0.3.5: dependencies: is-callable: 1.2.7 @@ -3459,6 +4781,8 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + from-exponential@1.1.1: {} + fsevents@2.3.3: optional: true @@ -3468,14 +4792,14 @@ snapshots: get-caller-file@2.0.5: {} - get-east-asian-width@1.5.0: {} + get-east-asian-width@1.6.0: {} get-intrinsic@1.3.0: dependencies: call-bind-apply-helpers: 1.0.2 es-define-property: 1.0.1 es-errors: 1.3.0 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 function-bind: 1.1.2 get-proto: 1.0.1 gopd: 1.2.0 @@ -3486,7 +4810,7 @@ snapshots: get-proto@1.0.1: dependencies: dunder-proto: 1.0.1 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 get-stream@6.0.1: {} @@ -3495,6 +4819,10 @@ snapshots: '@sec-ant/readable-stream': 0.4.1 is-stream: 4.0.1 + get-tsconfig@4.14.0: + dependencies: + resolve-pkg-maps: 1.0.0 + glob-parent@5.1.2: dependencies: is-glob: 4.0.3 @@ -3530,14 +4858,14 @@ snapshots: lru-cache: 10.4.3 tslib: 2.8.1 - graphql@16.11.0: {} - graphql@16.14.0: {} graphql@16.8.2: {} has-flag@4.0.0: {} + has-flag@5.0.1: {} + has-property-descriptors@1.0.2: dependencies: es-define-property: 1.0.1 @@ -3552,14 +4880,7 @@ snapshots: dependencies: function-bind: 1.1.2 - he@1.2.0: {} - - headers-polyfill@5.0.1: - dependencies: - '@types/set-cookie-parser': 2.4.10 - set-cookie-parser: 3.1.0 - - hono@4.12.18: {} + hono@4.12.23: {} html-escaper@2.0.2: {} @@ -3567,15 +4888,27 @@ snapshots: dependencies: delay: 5.0.0 p-wait-for: 3.2.0 - roarr: 7.21.4 + roarr: 7.21.5 type-fest: 2.19.0 human-signals@2.1.0: {} human-signals@8.0.1: {} + idb-keyval@6.2.5: {} + ieee754@1.2.1: {} + incur@0.4.8: + dependencies: + '@cfworker/json-schema': 4.1.1 + '@modelcontextprotocol/server': 2.0.0-alpha.2(@cfworker/json-schema@4.1.1) + '@scalar/openapi-types': 0.8.0 + '@toon-format/toon': 2.3.0 + tokenx: 1.3.0 + yaml: 2.9.0 + zod: 4.4.3 + inherits@2.0.4: {} is-arguments@1.2.0: @@ -3612,12 +4945,10 @@ snapshots: call-bind: 1.0.9 define-properties: 1.2.1 - is-node-process@1.2.0: {} + is-network-error@1.3.2: {} is-number@7.0.0: {} - is-path-inside@3.0.3: {} - is-plain-obj@2.1.0: {} is-plain-obj@4.1.0: {} @@ -3637,9 +4968,7 @@ snapshots: is-typed-array@1.1.15: dependencies: - which-typed-array: 1.1.20 - - is-unicode-supported@0.1.0: {} + which-typed-array: 1.1.21 is-unicode-supported@2.1.0: {} @@ -3647,9 +4976,28 @@ snapshots: isexe@2.0.0: {} - isows@1.0.7(ws@8.18.3): + iso-base@4.4.0: + dependencies: + bigint-mod-arith: 3.3.1 + + iso-kv@3.2.0: + dependencies: + conf: 15.1.0 + idb-keyval: 6.2.5 + iso-base: 4.4.0 + kysely: 0.29.2 + + iso-web@3.1.2: + dependencies: + '@standard-schema/spec': 1.1.0 + delay: 7.0.0 + is-network-error: 1.3.2 + iso-kv: 3.2.0 + p-retry: 8.0.0 + + isows@1.0.7(ws@8.20.1): dependencies: - ws: 8.18.3 + ws: 8.20.1 istanbul-lib-coverage@3.2.2: {} @@ -3670,11 +5018,9 @@ snapshots: optionalDependencies: '@pkgjs/parseargs': 0.11.0 - js-tokens@4.0.0: {} + js-base64@3.7.8: {} - js-yaml@4.1.0: - dependencies: - argparse: 2.0.1 + js-tokens@4.0.0: {} json-schema-traverse@1.0.0: {} @@ -3684,7 +5030,24 @@ snapshots: kleur@4.1.5: {} - kysely@0.28.17: {} + kysely@0.26.3: {} + + kysely@0.29.2: {} + + libsql@0.5.29: + dependencies: + '@neon-rs/load': 0.0.4 + detect-libc: 2.0.2 + optionalDependencies: + '@libsql/darwin-arm64': 0.5.29 + '@libsql/darwin-x64': 0.5.29 + '@libsql/linux-arm-gnueabihf': 0.5.29 + '@libsql/linux-arm-musleabihf': 0.5.29 + '@libsql/linux-arm64-gnu': 0.5.29 + '@libsql/linux-arm64-musl': 0.5.29 + '@libsql/linux-x64-gnu': 0.5.29 + '@libsql/linux-x64-musl': 0.5.29 + '@libsql/win32-x64-msvc': 0.5.29 lilconfig@3.1.3: {} @@ -3694,11 +5057,6 @@ snapshots: lodash@4.18.1: {} - log-symbols@4.1.0: - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - log-symbols@7.0.1: dependencies: is-unicode-supported: 2.1.0 @@ -3708,7 +5066,7 @@ snapshots: make-dir@4.0.0: dependencies: - semver: 7.7.4 + semver: 7.8.1 matchit@1.1.0: dependencies: @@ -3737,78 +5095,29 @@ snapshots: minimatch@10.2.5: dependencies: - brace-expansion: 5.0.5 + brace-expansion: 5.0.6 minimatch@9.0.9: dependencies: - brace-expansion: 2.1.0 + brace-expansion: 2.1.1 minipass@7.1.3: {} - mocha@11.7.5: - dependencies: - browser-stdout: 1.3.1 - chokidar: 4.0.3 - debug: 4.4.3(supports-color@8.1.1) - diff: 7.0.0 - escape-string-regexp: 4.0.0 - find-up: 5.0.0 - glob: 10.5.0 - he: 1.2.0 - is-path-inside: 3.0.3 - js-yaml: 4.1.0 - log-symbols: 4.1.0 - minimatch: 9.0.9 - ms: 2.1.3 - picocolors: 1.1.1 - serialize-javascript: 6.0.2 - strip-json-comments: 3.1.1 - supports-color: 8.1.1 - workerpool: 9.3.4 - yargs: 17.7.2 - yargs-parser: 21.1.1 - yargs-unparser: 2.0.0 - mri@1.2.0: {} mrmime@2.0.1: {} ms@2.1.3: {} - msw@2.14.2(@types/node@25.6.0)(typescript@6.0.3): - dependencies: - '@inquirer/confirm': 6.0.12(@types/node@25.6.0) - '@mswjs/interceptors': 0.41.8 - '@open-draft/deferred-promise': 3.0.0 - '@types/statuses': 2.0.6 - cookie: 1.1.1 - graphql: 16.14.0 - headers-polyfill: 5.0.1 - is-node-process: 1.2.0 - outvariant: 1.4.3 - path-to-regexp: 6.3.0 - picocolors: 1.1.1 - rettime: 0.11.11 - statuses: 2.0.2 - strict-event-emitter: 0.5.1 - tough-cookie: 6.0.1 - type-fest: 5.6.0 - until-async: 3.0.2 - yargs: 17.7.2 - optionalDependencies: - typescript: 6.0.3 - transitivePeerDependencies: - - '@types/node' - multiformats@13.4.2: {} - mute-stream@3.0.0: {} + multiformats@14.0.0: {} nanoid@3.3.12: {} nanoid@5.1.11: {} - node@runtime:24.15.0: {} + node@runtime:24.16.0: {} normalize-path@3.0.0: {} @@ -3833,7 +5142,7 @@ snapshots: call-bind: 1.0.9 call-bound: 1.0.4 define-properties: 1.2.1 - es-object-atoms: 1.1.1 + es-object-atoms: 1.1.2 has-symbols: 1.1.0 object-keys: 1.1.1 @@ -3860,9 +5169,22 @@ snapshots: stdin-discarder: 0.3.2 string-width: 8.2.1 - outvariant@1.4.3: {} + ox@0.14.25(typescript@6.0.3)(zod@4.4.3): + dependencies: + '@adraffy/ens-normalize': 1.11.1 + '@noble/ciphers': 1.3.0 + '@noble/curves': 1.9.1 + '@noble/hashes': 1.8.0 + '@scure/bip32': 1.7.0 + '@scure/bip39': 1.6.0 + abitype: 1.2.3(typescript@6.0.3)(zod@4.4.3) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 6.0.3 + transitivePeerDependencies: + - zod - ox@0.14.20(typescript@6.0.3): + ox@0.14.29(typescript@6.0.3)(zod@4.4.3): dependencies: '@adraffy/ens-normalize': 1.11.1 '@noble/ciphers': 1.3.0 @@ -3870,29 +5192,58 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@6.0.3) + abitype: 1.2.4(typescript@6.0.3)(zod@4.4.3) eventemitter3: 5.0.1 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: - zod + p-all@5.0.1: + dependencies: + p-map: 6.0.0 + p-finally@1.0.0: {} p-limit@3.1.0: dependencies: yocto-queue: 0.1.0 + p-limit@7.3.0: + dependencies: + yocto-queue: 1.2.2 + p-locate@5.0.0: dependencies: p-limit: 3.1.0 + p-locate@7.0.0: + dependencies: + p-limit: 7.3.0 + + p-map@6.0.0: {} + + p-map@7.0.4: {} + + p-queue@9.3.0: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 7.0.1 + + p-retry@8.0.0: + dependencies: + is-network-error: 1.3.2 + + p-some@7.0.0: {} + p-timeout@3.2.0: dependencies: p-finally: 1.0.0 p-timeout@6.1.4: {} + p-timeout@7.0.1: {} + p-wait-for@3.2.0: dependencies: p-timeout: 3.2.0 @@ -3914,14 +5265,12 @@ snapshots: lru-cache: 10.4.3 minipass: 7.1.3 - path-to-regexp@6.3.0: {} - pathe@1.1.2: {} - pg-cloudflare@1.3.0: + pg-cloudflare@1.4.0: optional: true - pg-connection-string@2.12.0: {} + pg-connection-string@2.13.0: {} pg-copy-streams@6.0.6: dependencies: @@ -3929,11 +5278,11 @@ snapshots: pg-int8@1.0.1: {} - pg-pool@3.13.0(pg@8.20.0): + pg-pool@3.14.0(pg@8.21.0): dependencies: - pg: 8.20.0 + pg: 8.21.0 - pg-protocol@1.13.0: {} + pg-protocol@1.14.0: {} pg-query-emscripten@5.1.0: {} @@ -3945,15 +5294,15 @@ snapshots: postgres-date: 1.0.7 postgres-interval: 1.2.0 - pg@8.20.0: + pg@8.21.0: dependencies: - pg-connection-string: 2.12.0 - pg-pool: 3.13.0(pg@8.20.0) - pg-protocol: 1.13.0 + pg-connection-string: 2.13.0 + pg-pool: 3.14.0(pg@8.21.0) + pg-protocol: 1.14.0 pg-types: 2.2.0 pgpass: 1.0.5 optionalDependencies: - pg-cloudflare: 1.3.0 + pg-cloudflare: 1.4.0 pgpass@1.0.5: dependencies: @@ -3986,15 +5335,15 @@ snapshots: sonic-boom: 3.8.1 thread-stream: 2.7.0 - playwright-core@1.58.2: {} + playwright-core@1.60.0: {} - playwright-test@14.1.13: + playwright-test@14.1.15: dependencies: acorn-loose: 8.5.2 assert: 2.1.0 buffer: 6.0.3 c8: 10.1.3 - camelcase: 8.0.0 + camelcase: 9.0.0 chokidar: 4.0.3 esbuild: 0.25.11 esbuild-plugin-wasm: 1.1.0 @@ -4009,7 +5358,7 @@ snapshots: ora: 9.4.0 p-timeout: 6.1.4 path-browserify: 1.0.1 - playwright-core: 1.58.2 + playwright-core: 1.60.0 polka: 0.5.2 premove: 4.0.0 process: 0.11.10 @@ -4033,7 +5382,7 @@ snapshots: possible-typed-array-names@1.1.0: {} - postcss@8.5.14: + postcss@8.5.15: dependencies: nanoid: 3.3.12 picocolors: 1.1.1 @@ -4064,6 +5413,8 @@ snapshots: '@opentelemetry/api': 1.9.1 tdigest: 0.1.2 + promise-limit@2.7.0: {} + proper-lockfile@4.1.2: dependencies: graceful-fs: 4.2.11 @@ -4074,9 +5425,7 @@ snapshots: quick-format-unescaped@4.0.4: {} - randombytes@2.1.0: - dependencies: - safe-buffer: 5.2.1 + random-int@3.1.0: {} readable-stream@3.6.2: dependencies: @@ -4104,6 +5453,8 @@ snapshots: require-from-string@2.0.2: {} + resolve-pkg-maps@1.0.0: {} + restore-cursor@5.1.0: dependencies: onetime: 7.0.0 @@ -4111,45 +5462,43 @@ snapshots: retry@0.12.0: {} - rettime@0.11.11: {} - reusify@1.1.0: {} - roarr@7.21.4: + roarr@7.21.5: dependencies: fast-printf: 1.6.10 safe-stable-stringify: 2.5.0 semver-compare: 1.0.0 - rollup@4.60.3: + rollup@4.60.4: dependencies: '@types/estree': 1.0.8 optionalDependencies: - '@rollup/rollup-android-arm-eabi': 4.60.3 - '@rollup/rollup-android-arm64': 4.60.3 - '@rollup/rollup-darwin-arm64': 4.60.3 - '@rollup/rollup-darwin-x64': 4.60.3 - '@rollup/rollup-freebsd-arm64': 4.60.3 - '@rollup/rollup-freebsd-x64': 4.60.3 - '@rollup/rollup-linux-arm-gnueabihf': 4.60.3 - '@rollup/rollup-linux-arm-musleabihf': 4.60.3 - '@rollup/rollup-linux-arm64-gnu': 4.60.3 - '@rollup/rollup-linux-arm64-musl': 4.60.3 - '@rollup/rollup-linux-loong64-gnu': 4.60.3 - '@rollup/rollup-linux-loong64-musl': 4.60.3 - '@rollup/rollup-linux-ppc64-gnu': 4.60.3 - '@rollup/rollup-linux-ppc64-musl': 4.60.3 - '@rollup/rollup-linux-riscv64-gnu': 4.60.3 - '@rollup/rollup-linux-riscv64-musl': 4.60.3 - '@rollup/rollup-linux-s390x-gnu': 4.60.3 - '@rollup/rollup-linux-x64-gnu': 4.60.3 - '@rollup/rollup-linux-x64-musl': 4.60.3 - '@rollup/rollup-openbsd-x64': 4.60.3 - '@rollup/rollup-openharmony-arm64': 4.60.3 - '@rollup/rollup-win32-arm64-msvc': 4.60.3 - '@rollup/rollup-win32-ia32-msvc': 4.60.3 - '@rollup/rollup-win32-x64-gnu': 4.60.3 - '@rollup/rollup-win32-x64-msvc': 4.60.3 + '@rollup/rollup-android-arm-eabi': 4.60.4 + '@rollup/rollup-android-arm64': 4.60.4 + '@rollup/rollup-darwin-arm64': 4.60.4 + '@rollup/rollup-darwin-x64': 4.60.4 + '@rollup/rollup-freebsd-arm64': 4.60.4 + '@rollup/rollup-freebsd-x64': 4.60.4 + '@rollup/rollup-linux-arm-gnueabihf': 4.60.4 + '@rollup/rollup-linux-arm-musleabihf': 4.60.4 + '@rollup/rollup-linux-arm64-gnu': 4.60.4 + '@rollup/rollup-linux-arm64-musl': 4.60.4 + '@rollup/rollup-linux-loong64-gnu': 4.60.4 + '@rollup/rollup-linux-loong64-musl': 4.60.4 + '@rollup/rollup-linux-ppc64-gnu': 4.60.4 + '@rollup/rollup-linux-ppc64-musl': 4.60.4 + '@rollup/rollup-linux-riscv64-gnu': 4.60.4 + '@rollup/rollup-linux-riscv64-musl': 4.60.4 + '@rollup/rollup-linux-s390x-gnu': 4.60.4 + '@rollup/rollup-linux-x64-gnu': 4.60.4 + '@rollup/rollup-linux-x64-musl': 4.60.4 + '@rollup/rollup-openbsd-x64': 4.60.4 + '@rollup/rollup-openharmony-arm64': 4.60.4 + '@rollup/rollup-win32-arm64-msvc': 4.60.4 + '@rollup/rollup-win32-ia32-msvc': 4.60.4 + '@rollup/rollup-win32-x64-gnu': 4.60.4 + '@rollup/rollup-win32-x64-msvc': 4.60.4 fsevents: 2.3.3 run-parallel@1.2.0: @@ -4172,13 +5521,7 @@ snapshots: semver-compare@1.0.0: {} - semver@7.7.4: {} - - serialize-javascript@6.0.2: - dependencies: - randombytes: 2.1.0 - - set-cookie-parser@3.1.0: {} + semver@7.8.1: {} set-function-length@1.2.2: dependencies: @@ -4205,6 +5548,8 @@ snapshots: mrmime: 2.0.1 totalist: 3.0.1 + sisteransi@1.0.5: {} + sonic-boom@3.8.1: dependencies: atomic-sleep: 1.0.0 @@ -4224,8 +5569,6 @@ snapshots: dependencies: type-fest: 0.7.1 - statuses@2.0.2: {} - stdin-discarder@0.3.2: {} stream-browserify@3.0.0: @@ -4233,8 +5576,6 @@ snapshots: inherits: 2.0.4 readable-stream: 3.6.2 - strict-event-emitter@0.5.1: {} - string-width@4.2.3: dependencies: emoji-regex: 8.0.0 @@ -4249,7 +5590,7 @@ snapshots: string-width@8.2.1: dependencies: - get-east-asian-width: 1.5.0 + get-east-asian-width: 1.6.0 strip-ansi: 7.2.0 string_decoder@1.3.0: @@ -4268,8 +5609,6 @@ snapshots: strip-final-newline@4.0.0: {} - strip-json-comments@3.1.1: {} - stubborn-fs@2.0.0: dependencies: stubborn-utils: 1.0.2 @@ -4280,13 +5619,20 @@ snapshots: dependencies: copy-anything: 4.0.5 + supports-color@10.2.2: {} + supports-color@7.2.0: dependencies: has-flag: 4.0.0 - supports-color@8.1.1: + supports-hyperlinks@4.4.0: dependencies: - has-flag: 4.0.0 + has-flag: 5.0.1 + supports-color: 10.2.2 + + sync-multihash-sha2@1.0.0: + dependencies: + '@noble/hashes': 1.8.0 tagged-tag@1.0.0: {} @@ -4303,6 +5649,11 @@ snapshots: type-fest: 2.19.0 unique-string: 3.0.0 + terminal-link@5.0.0: + dependencies: + ansi-escapes: 7.3.0 + supports-hyperlinks: 4.4.0 + terminal-size@4.0.1: {} test-exclude@7.0.2: @@ -4320,21 +5671,13 @@ snapshots: fdir: 6.5.0(picomatch@4.0.4) picomatch: 4.0.4 - tldts-core@7.0.30: {} - - tldts@7.0.30: - dependencies: - tldts-core: 7.0.30 - to-regex-range@5.0.1: dependencies: is-number: 7.0.0 - totalist@3.0.1: {} + tokenx@1.3.0: {} - tough-cookie@6.0.1: - dependencies: - tldts: 7.0.30 + totalist@3.0.1: {} trouter@2.0.1: dependencies: @@ -4346,6 +5689,12 @@ snapshots: tslib@2.8.1: {} + tsx@4.22.3: + dependencies: + esbuild: 0.28.0 + optionalDependencies: + fsevents: 2.3.3 + type-fest@0.7.1: {} type-fest@1.4.0: {} @@ -4354,7 +5703,7 @@ snapshots: type-fest@3.13.1: {} - type-fest@5.6.0: + type-fest@5.7.0: dependencies: tagged-tag: 1.0.0 @@ -4362,7 +5711,9 @@ snapshots: uint8array-extras@0.3.0: {} - undici-types@7.19.2: {} + uint8array-extras@1.5.0: {} + + undici-types@7.24.6: {} unicorn-magic@0.3.0: {} @@ -4370,7 +5721,7 @@ snapshots: dependencies: crypto-random-string: 4.0.0 - until-async@3.0.2: {} + unlimited-timeout@0.1.0: {} urlpattern-polyfill@10.1.0: {} @@ -4382,7 +5733,7 @@ snapshots: is-arguments: 1.2.0 is-generator-function: 1.1.2 is-typed-array: 1.1.15 - which-typed-array: 1.1.20 + which-typed-array: 1.1.21 v8-to-istanbul@9.3.0: dependencies: @@ -4390,16 +5741,16 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 - viem@2.48.8(typescript@6.0.3): + viem@2.51.3(typescript@6.0.3)(zod@4.4.3): dependencies: '@noble/curves': 1.9.1 '@noble/hashes': 1.8.0 '@scure/bip32': 1.7.0 '@scure/bip39': 1.6.0 - abitype: 1.2.3(typescript@6.0.3) - isows: 1.0.7(ws@8.18.3) - ox: 0.14.20(typescript@6.0.3) - ws: 8.18.3 + abitype: 1.2.3(typescript@6.0.3)(zod@4.4.3) + isows: 1.0.7(ws@8.20.1) + ox: 0.14.25(typescript@6.0.3)(zod@4.4.3) + ws: 8.20.1 optionalDependencies: typescript: 6.0.3 transitivePeerDependencies: @@ -4407,16 +5758,15 @@ snapshots: - utf-8-validate - zod - vite-node@1.0.2(@types/node@25.6.0): + vite-node@1.0.2(@types/node@25.9.2): dependencies: cac: 6.7.14 - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 pathe: 1.1.2 picocolors: 1.1.1 - vite: 6.4.2(@types/node@25.6.0) + vite: 5.4.21(@types/node@25.9.2) transitivePeerDependencies: - '@types/node' - - jiti - less - lightningcss - sass @@ -4425,35 +5775,30 @@ snapshots: - sugarss - supports-color - terser - - tsx - - yaml - vite-tsconfig-paths@4.3.1(typescript@6.0.3)(vite@6.4.2(@types/node@25.6.0)): + vite-tsconfig-paths@4.3.1(typescript@6.0.3)(vite@5.4.21(@types/node@25.9.2)): dependencies: - debug: 4.4.3(supports-color@8.1.1) + debug: 4.4.3 globrex: 0.1.2 tsconfck: 3.1.6(typescript@6.0.3) optionalDependencies: - vite: 6.4.2(@types/node@25.6.0) + vite: 5.4.21(@types/node@25.9.2) transitivePeerDependencies: - supports-color - typescript - vite@6.4.2(@types/node@25.6.0): + vite@5.4.21(@types/node@25.9.2): dependencies: - esbuild: 0.25.11 - fdir: 6.5.0(picomatch@4.0.4) - picomatch: 4.0.4 - postcss: 8.5.14 - rollup: 4.60.3 - tinyglobby: 0.2.16 + esbuild: 0.21.5 + postcss: 8.5.15 + rollup: 4.60.4 optionalDependencies: - '@types/node': 25.6.0 + '@types/node': 25.9.2 fsevents: 2.3.3 when-exit@2.1.5: {} - which-typed-array@1.1.20: + which-typed-array@1.1.21: dependencies: available-typed-arrays: 1.0.7 call-bind: 1.0.9 @@ -4475,8 +5820,6 @@ snapshots: jsonc-parser: 3.3.1 proper-lockfile: 4.1.2 - workerpool@9.3.4: {} - wrap-ansi@7.0.0: dependencies: ansi-styles: 4.3.0 @@ -4489,22 +5832,17 @@ snapshots: string-width: 5.1.2 strip-ansi: 7.2.0 - ws@8.18.3: {} + ws@8.20.1: {} - ws@8.20.0: {} + ws@8.21.0: {} xtend@4.0.2: {} y18n@5.0.8: {} - yargs-parser@21.1.1: {} + yaml@2.9.0: {} - yargs-unparser@2.0.0: - dependencies: - camelcase: 6.3.0 - decamelize: 4.0.0 - flat: 5.0.2 - is-plain-obj: 2.1.0 + yargs-parser@21.1.1: {} yargs@17.7.2: dependencies: @@ -4518,4 +5856,8 @@ snapshots: yocto-queue@0.1.0: {} + yocto-queue@1.2.2: {} + yoctocolors@2.1.2: {} + + zod@4.4.3: {} diff --git a/pnpm-workspace.yaml b/pnpm-workspace.yaml index 630e862..7566d42 100644 --- a/pnpm-workspace.yaml +++ b/pnpm-workspace.yaml @@ -3,28 +3,19 @@ packages: - apps/* allowBuilds: + better-sqlite3: true esbuild: true msw: true blockExoticSubdeps: true catalog: - '@biomejs/biome': 2.4.11 + '@biomejs/biome': 2.4.16 '@types/mocha': ^10.0.10 - '@types/node': ^25.6.0 + '@types/node': ^25.9.2 drizzle-orm: ^0.45.2 mocha: ^11.7.4 - msw: 2.14.2 + msw: 2.14.6 typescript: 6.0.3 - viem: ^2.47.17 + viem: ^2.50.4 zod: ^4.3.5 - -minimumReleaseAge: 10080 - -minimumReleaseAgeExclude: [] - -trustPolicy: no-downgrade - -trustPolicyExclude: - - chokidar@4.0.3 - - vite@5.4.21