diff --git a/.changeset/sdk-framework-agnostic-server.md b/.changeset/sdk-framework-agnostic-server.md new file mode 100644 index 0000000..01c97e6 --- /dev/null +++ b/.changeset/sdk-framework-agnostic-server.md @@ -0,0 +1,13 @@ +--- +"radius-sdk": minor +--- + +Accept payments from any HTTP stack, not just Hono. New `radius-sdk/server` entry point: + +- `radiusPayments()` is a web-standard handler (`Request` in, `Response` out) for Cloudflare Workers without a framework, Bun, Deno, Node 18+, and Next.js / SvelteKit / Remix route handlers. Paid handlers receive the settled receipt as a second argument. +- `createRadiusServer()` exposes the Radius x402 resource server and a `routes()` builder that plug straight into the upstream adapters: `paymentMiddleware(radius.routes({ … }), radius.server)` with `@x402/express`, `@x402/next` or `@x402/hono`. +- `onSettled` is registered on the resource server, so it fires whichever adapter served the request (it receives the x402 request context; `requestOf(context)` returns the `Request` for the SDK's own adapters). Errors thrown by `onSettled` are logged by x402 core instead of failing the request. +- Paid responses stream through in the default `settle: 'before'` flow instead of being buffered (the previous Hono middleware buffered every paid response, stalling SSE and token streams). +- **Breaking:** `radius-sdk/hono` is now a thin wrapper over the web-standard handler with the same options. `RadiusHonoAdapter` is removed; `RequestAdapter` from `radius-sdk/server` (an x402 `HTTPAdapter` over a web-standard `Request`) replaces it. +- `@x402/core` / `@x402/evm` bumped to 2.27.0 (the version line the upstream adapters require). +- New examples: `examples/worker-plain` (no framework), `examples/express-seller` (`@x402/express`) and `examples/astro-seller` (validate before charging in an Astro API route). diff --git a/README.md b/README.md index b0a27b1..cceff48 100644 --- a/README.md +++ b/README.md @@ -5,15 +5,15 @@ Tools for the [Radius Network](https://radiustech.xyz), managed as one pnpm work | Package | What | | --- | --- | | [`packages/cli`](./packages/cli) | [`radius-cli`](https://www.npmjs.com/package/radius-cli) — CLI wallet for Radius, modeled on Foundry's `cast`; `wallet x402` pays through `radius-sdk` | -| [`packages/sdk`](./packages/sdk) | [`radius-sdk`](https://www.npmjs.com/package/radius-sdk) — accept and make Radius payments over x402 v2 (Hono / Cloudflare Workers first), plus balance and settlement helpers | +| [`packages/sdk`](./packages/sdk) | [`radius-sdk`](https://www.npmjs.com/package/radius-sdk) — accept and make Radius payments over x402 v2 from any web-standard runtime, Hono, or the upstream x402 framework adapters (Express, Next.js), plus balance and settlement helpers | ```bash npx radius-cli wallet balance # the CLI -pnpm add radius-sdk hono # SDK, seller side +pnpm add radius-sdk # SDK, seller side (add hono, or @x402/express + express, for those stacks) pnpm add radius-sdk viem # SDK, buyer / agent side ``` -Runnable SDK examples (seller worker, agent buyer, browser demo dapp) are in [`packages/sdk/examples`](./packages/sdk/examples). +Runnable SDK examples (seller workers with and without Hono, an Express seller, agent buyer, browser demo dapp) are in [`packages/sdk/examples`](./packages/sdk/examples). ## Agent skills diff --git a/packages/sdk/README.md b/packages/sdk/README.md index ca9d5f5..b073ba7 100644 --- a/packages/sdk/README.md +++ b/packages/sdk/README.md @@ -1,14 +1,17 @@ # radius-sdk Accept and make [Radius](https://radiustech.xyz) payments over standard [x402 v2](https://x402.org). -Hono and Cloudflare Workers first. SBC is the default currency, mainnet the default network. +Sellers run on any stack that speaks web-standard `Request`/`Response` (Cloudflare Workers, Bun, +Deno, Node, Next.js and SvelteKit route handlers), on Hono, or on Express / Next.js through the +upstream x402 adapters. SBC is the default currency, mainnet the default network. Pre-1.0: minor versions may change the API. Release notes are in [CHANGELOG.md](./CHANGELOG.md). | Entry point | What | Needs | | --- | --- | --- | | `radius-sdk` | networks, amounts, receipts, errors, `radiusEnv` (no viem at runtime) | — | -| `radius-sdk/hono` | `radiusPayments()` seller middleware | `hono` | +| `radius-sdk/server` | `radiusPayments()` web-standard seller handler; `createRadiusServer()` for the upstream `@x402/*` adapters | — | +| `radius-sdk/hono` | `radiusPayments()` Hono middleware (wraps `radius-sdk/server`) | `hono` | | `radius-sdk/client` | `createRadiusFetch()` paying fetch, balance and settlement actions | `viem` | ## Install @@ -16,16 +19,22 @@ Pre-1.0: minor versions may change the API. Release notes are in [CHANGELOG.md]( Install the peer dependencies for the entry point you use: ```sh -# Hono seller +# Seller on Workers / Bun / Deno / Node / route handlers +pnpm add radius-sdk + +# Seller on Hono pnpm add radius-sdk hono +# Seller on Express (or Next.js with @x402/next) +pnpm add radius-sdk @x402/express express + # Buyer / agent (including applications that also accept payments) pnpm add radius-sdk viem ``` Hono and viem are optional peer dependencies. The `radius-sdk/hono` entry point requires Hono; -`radius-sdk/client` requires viem `^2.48.11`. Root and Hono entry points do not load viem at -runtime. Network definitions remain compatible with viem's `Chain` type; TypeScript consumers +`radius-sdk/client` requires viem `^2.48.11`. Root, server and Hono entry points do not load +viem at runtime. Network definitions remain compatible with viem's `Chain` type; TypeScript consumers that resolve those declarations may also need viem installed for its types. Applications already using a compatible viem version can use that installation for the SDK's @@ -39,27 +48,86 @@ across the full dependency tree depends on compatible ranges and the package man ## Accept payments (seller) -```ts -import { Hono } from 'hono'; -import { radiusPayments, type RadiusPaymentVariables } from 'radius-sdk/hono'; +The payment configuration is the same everywhere; only the wrapper changes. -type Env = { Bindings: { PAY_TO: `0x${string}` }; Variables: RadiusPaymentVariables }; -const app = new Hono(); +**Any web-standard runtime** (Cloudflare Workers without a framework, Bun, Deno, Node 18+, +Next.js / SvelteKit / Remix route handlers): a handler that takes a `Request` and returns a +`Response`. Paid handlers receive the settled receipt. -app.use('/api/*', radiusPayments({ +```ts +import { radiusPayments } from 'radius-sdk/server'; + +const pay = radiusPayments({ network: 'testnet', // default 'mainnet'; or a custom instance, see below - payTo: (c) => c.env.PAY_TO, // or a literal address + payTo: '0xYourWallet', // or (request) => … routes: { 'GET /api/lookup': { price: '$0.001', description: 'One lookup' }, 'POST /api/query': '$0.01', // shorthand 'GET /api/raw': { price: { amount: '100' } }, // atomic units (6 decimals for SBC) }, +}); + +export default { + fetch: pay.wrap((request, payment) => Response.json({ ok: true, paidBy: payment?.payer })), +}; +// or, with your own router: `pay(request, (request, payment) => router.handle(request))` +``` + +**Validate, then pay.** With the default `settle: 'before'`, funds move before your handler runs, +so anything the handler discovers afterwards (missing record, failed lookup) is a paid error. +Do fallible work before calling `pay`, return the unpaid 404 there, and hand the prepared result +to the paid handler. `examples/astro-seller` shows this in an Astro API route: + +```ts +export const GET: APIRoute = async ({ request, params }) => { + const article = await loadArticle(params.slug); + if (!article) return new Response('Not found', { status: 404 }); // nothing charged + return pay(request, () => Response.json(article)); // charge, then deliver +}; +``` + +**Hono** (`pnpm add hono`): the same options as middleware; dynamic `payTo`/`price` and +`onSettled` receive the Hono context and paid handlers read `c.get('radiusPayment')`. + +```ts +import { Hono } from 'hono'; +import { radiusPayments, type RadiusPaymentVariables } from 'radius-sdk/hono'; + +type Env = { Bindings: { PAY_TO: `0x${string}` }; Variables: RadiusPaymentVariables }; +const app = new Hono(); + +app.use('/api/*', radiusPayments({ + network: 'testnet', + payTo: (c) => c.env.PAY_TO, + routes: { 'GET /api/lookup': { price: '$0.001', description: 'One lookup' } }, })); app.get('/api/lookup', (c) => c.json({ ok: true, paidBy: c.get('radiusPayment')?.payer })); export default app; ``` +**Express, Next.js, or any other framework with an upstream x402 adapter**: the SDK provides +the Radius resource server and routes, the adapter provides the middleware. + +```ts +import express from 'express'; +import { paymentMiddleware } from '@x402/express'; // or `paymentProxy` from '@x402/next' +import { createRadiusServer } from 'radius-sdk/server'; + +const radius = createRadiusServer({ network: 'testnet' }); +const app = express(); +app.use(paymentMiddleware( + radius.routes({ payTo: '0xYourWallet', routes: { 'GET /api/lookup': '$0.001' } }), + radius.server, +)); +app.get('/api/lookup', (_req, res) => res.json({ ok: true })); +``` + +`radius.routes()` accepts the same route specs; dynamic `payTo`/`price` receive the x402 request +context. `radius.http(...)` returns an `x402HTTPResourceServer` for adapters' `…FromHTTPServer` +variants, and `radius.server` can be used with any `HTTPAdapter` of your own for stacks nobody +has an adapter for yet. + What you get, on the wire, with no Radius-specific client knowledge required: - Unpaid request → `402` with a `PAYMENT-REQUIRED` header: `exact` scheme, SBC via Permit2, @@ -67,14 +135,24 @@ What you get, on the wire, with no Radius-specific client knowledge required: - Paid request (`PAYMENT-SIGNATURE`) → settled on Radius through the Radius facilitator **before** your handler runs (`settle: 'after'` switches to the x402 default flow), then a `PAYMENT-RESPONSE` header with the transaction hash. -- `c.get('radiusPayment')` in the handler, and `onSettled(receipt, c)` for logging. +- The receipt in the handler (second argument / `c.get('radiusPayment')`), and `onSettled` for + logging with every adapter: it receives the `Request` (web-standard handler), the Hono context, + or the x402 request context (`createRadiusServer`). `onSettled` records settlement, not + delivery: in the default flow it fires before the handler, and errors it throws are logged, not + surfaced. Keep the receipt and the delivery outcome separately, and reconcile a paid 5xx (or an + uncertain 502) against the transaction before the buyer pays again. - `eip2612GasSponsoring` is declared only when the facilitator's `/supported` lists it (`gasSponsoring: true | false` overrides), so clients never send a permit nobody will honour. -- No I/O at module scope (Workers-safe): the facilitator's `/supported` is fetched lazily on the - first paid request after each cold start. Server bundle is ~65 KiB gzipped, no viem. +- No I/O at module scope (Workers-safe): the SDK's handlers fetch the facilitator's `/supported` + lazily on the first paid request after each cold start. The upstream adapters fetch it at + construction by default (fine on Node; pass their `syncFacilitatorOnStart: false` and call + `radius.server.initialize()` yourself where module-scope I/O is forbidden). Server bundle is + ~65 KiB gzipped, no viem. -Any x402 v2 client can pay it: verified with the pre-SDK `radius-cli wallet x402` 0.1.5 as well as -`createRadiusFetch` (which `radius-cli` uses from 0.2.0) paying a local `wrangler dev` worker on testnet. +Any x402 v2 client can pay it: verified with `radius-cli wallet x402` (which uses +`createRadiusFetch` from 0.2.0, and paid the SDK's 402s with its hand-rolled client before that) +against `examples/worker-plain` under `wrangler dev`, `examples/express-seller` on Node, and the +Hono `examples/worker-seller`, all on testnet. ## Make payments (buyer / agent) @@ -323,8 +401,11 @@ self-hosted facilitator with your own auth or routing. | Path | What | | --- | --- | -| `src/` | `networks`, `balances`, `erc20`, `permit2`, `amounts`, `receipt`, `settlement`, `schemes`, `env`, `errors`; `hono/` (server); `client/` (buyer) | -| `examples/worker-seller` | Hono worker: free `/`, paid `/api/lookup` and `/api/query` (`pnpm --filter radius-worker-seller dev`) | +| `src/` | `networks`, `balances`, `erc20`, `permit2`, `amounts`, `receipt`, `settlement`, `schemes`, `env`, `errors`; `server/` (seller core: web-standard handler, x402 resource server, facilitator, scheme); `hono/` (Hono wrapper); `client/` (buyer) | +| `examples/worker-plain` | Worker with no framework, the web-standard handler: free `/`, paid `/api/lookup` and `/api/query` (`pnpm --filter radius-worker-plain dev`, port 8788) | +| `examples/worker-seller` | Same API on Hono (`pnpm --filter radius-worker-seller dev`) | +| `examples/express-seller` | Same API on Express through `@x402/express` (`pnpm --filter radius-express-seller start`, port 8789) | +| `examples/astro-seller` | Astro API route: validate the article before charging, then deliver it paid (`pnpm --filter radius-astro-seller dev`, port 8790) | | `examples/agent-buyer` | `buy.mjs` (pay a URL), `fresh-wallet.mjs` (gasless proof from a new wallet), `permit2-pull.mjs` (sign a Permit2 transfer off-chain, pull it from another account) | | `examples/demo-dapp` | Test-dapp style page exercising both sides in the browser (burner wallet or MetaMask) | | `test/` | unit tests (facilitator and RPC mocked; `client-parity.test.ts` pins the wire format against radius-cli's; `balances.test.ts` runs the native-balance init code in a real EVM; `erc20.semantics.test.ts` runs the ERC-20 actions against `evmNode.ts`, a JSON-RPC node backed by @ethereumjs/evm executing the forge-compiled `fixtures/TestToken` (rebuild with `fixtures/build.sh` after editing the .sol; the artifact is committed because CI has no forge)); `test/e2e` real settlement, balance reconciliation and ERC-20 round trips on testnet or mainnet (`RADIUS_E2E=1 RADIUS_PRIVATE_KEY=… [RADIUS_NETWORK=mainnet] pnpm test:e2e`) | diff --git a/packages/sdk/examples/astro-seller/.astro/content.d.ts b/packages/sdk/examples/astro-seller/.astro/content.d.ts new file mode 100644 index 0000000..2bf13df --- /dev/null +++ b/packages/sdk/examples/astro-seller/.astro/content.d.ts @@ -0,0 +1,159 @@ +declare module 'astro:content' { + export interface RenderResult { + Content: import('astro/runtime/server/index.js').AstroComponentFactory; + headings: import('astro').MarkdownHeading[]; + remarkPluginFrontmatter: Record; + } + interface Render { + '.md': Promise; + } + + export interface RenderedContent { + html: string; + metadata?: { + imagePaths: Array; + [key: string]: unknown; + }; + } + + type Flatten = T extends { [K: string]: infer U } ? U : never; + + export type CollectionKey = keyof DataEntryMap; + export type CollectionEntry = Flatten; + + type AllValuesOf = T extends any ? T[keyof T] : never; + + export type ReferenceDataEntry< + C extends CollectionKey, + E extends keyof DataEntryMap[C] = string, + > = { + collection: C; + id: E; + }; + + export type ReferenceLiveEntry = { + collection: C; + id: string; + }; + + export function getCollection>( + collection: C, + filter?: (entry: CollectionEntry) => entry is E, + ): Promise; + export function getCollection( + collection: C, + filter?: (entry: CollectionEntry) => unknown, + ): Promise[]>; + + export function getLiveCollection( + collection: C, + filter?: LiveLoaderCollectionFilterType, + ): Promise< + import('astro').LiveDataCollectionResult, LiveLoaderErrorType> + >; + + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + entry: ReferenceDataEntry, + ): E extends keyof DataEntryMap[C] + ? Promise + : Promise | undefined>; + export function getEntry< + C extends keyof DataEntryMap, + E extends keyof DataEntryMap[C] | (string & {}), + >( + collection: C, + id: E, + ): E extends keyof DataEntryMap[C] + ? string extends keyof DataEntryMap[C] + ? Promise | undefined + : Promise + : Promise | undefined>; + export function getLiveEntry( + collection: C, + filter: string | LiveLoaderEntryFilterType, + ): Promise, LiveLoaderErrorType>>; + + /** Resolve an array of entry references from the same collection */ + export function getEntries( + entries: ReferenceDataEntry[], + ): Promise[]>; + + export function render( + entry: DataEntryMap[C][string], + ): Promise; + + export function render( + entry: import('astro').LiveDataEntry>, + ): Promise; + + export function reference< + C extends + | keyof DataEntryMap + // Allow generic `string` to avoid excessive type errors in the config + // if `dev` is not running to update as you edit. + // Invalid collection names will be caught at build time. + | (string & {}), + >( + collection: C, + ): import('astro/zod').ZodPipe< + import('astro/zod').ZodString, + import('astro/zod').ZodTransform< + C extends keyof DataEntryMap + ? { + collection: C; + id: string; + } + : never, + string + > + >; + + type ReturnTypeOrOriginal = T extends (...args: any[]) => infer R ? R : T; + type InferEntrySchema = import('astro/zod').infer< + ReturnTypeOrOriginal['schema']> + >; + type ExtractLoaderConfig = T extends { loader: infer L } ? L : never; + type InferLoaderSchema< + C extends keyof DataEntryMap, + L = ExtractLoaderConfig, + > = L extends { schema: import('astro/zod').ZodSchema } + ? import('astro/zod').infer + : any; + + type DataEntryMap = { + + }; + + type ExtractLoaderTypes = T extends import('astro/loaders').LiveLoader< + infer TData, + infer TEntryFilter, + infer TCollectionFilter, + infer TError + > + ? { data: TData; entryFilter: TEntryFilter; collectionFilter: TCollectionFilter; error: TError } + : { data: never; entryFilter: never; collectionFilter: never; error: never }; + type ExtractEntryFilterType = ExtractLoaderTypes['entryFilter']; + type ExtractCollectionFilterType = ExtractLoaderTypes['collectionFilter']; + type ExtractErrorType = ExtractLoaderTypes['error']; + type ExtractDataType = ExtractLoaderTypes['data']; + + type LiveLoaderDataType = + LiveContentConfig['collections'][C]['schema'] extends undefined + ? ExtractDataType + : import('astro/zod').infer< + Exclude + >; + type LiveLoaderEntryFilterType = + ExtractEntryFilterType; + type LiveLoaderCollectionFilterType = + ExtractCollectionFilterType; + type LiveLoaderErrorType = ExtractErrorType< + LiveContentConfig['collections'][C]['loader'] + >; + + export type ContentConfig = never; + export type LiveContentConfig = never; +} diff --git a/packages/sdk/examples/astro-seller/.astro/dev.json b/packages/sdk/examples/astro-seller/.astro/dev.json new file mode 100644 index 0000000..9e8dc03 --- /dev/null +++ b/packages/sdk/examples/astro-seller/.astro/dev.json @@ -0,0 +1,14 @@ +{ + "pid": 1653295, + "port": 8790, + "url": "http://localhost:8790", + "urls": { + "local": [ + "http://localhost:8790/" + ], + "network": [], + "networkInterfaceNames": [] + }, + "background": true, + "startedAt": "2026-10-07T08:54:03.841Z" +} \ No newline at end of file diff --git a/packages/sdk/examples/astro-seller/.astro/settings.json b/packages/sdk/examples/astro-seller/.astro/settings.json new file mode 100644 index 0000000..ded2a92 --- /dev/null +++ b/packages/sdk/examples/astro-seller/.astro/settings.json @@ -0,0 +1,5 @@ +{ + "_variables": { + "lastUpdateCheck": 1791363245540 + } +} \ No newline at end of file diff --git a/packages/sdk/examples/astro-seller/.astro/types.d.ts b/packages/sdk/examples/astro-seller/.astro/types.d.ts new file mode 100644 index 0000000..f964fe0 --- /dev/null +++ b/packages/sdk/examples/astro-seller/.astro/types.d.ts @@ -0,0 +1 @@ +/// diff --git a/packages/sdk/examples/astro-seller/astro.config.mjs b/packages/sdk/examples/astro-seller/astro.config.mjs new file mode 100644 index 0000000..0aaeeb3 --- /dev/null +++ b/packages/sdk/examples/astro-seller/astro.config.mjs @@ -0,0 +1,7 @@ +import { defineConfig } from 'astro/config'; +import node from '@astrojs/node'; + +export default defineConfig({ + output: 'server', + adapter: node({ mode: 'standalone' }), +}); diff --git a/packages/sdk/examples/astro-seller/package.json b/packages/sdk/examples/astro-seller/package.json new file mode 100644 index 0000000..3f1df69 --- /dev/null +++ b/packages/sdk/examples/astro-seller/package.json @@ -0,0 +1,20 @@ +{ + "name": "radius-astro-seller", + "private": true, + "type": "module", + "scripts": { + "dev": "astro dev --port 8790", + "build": "astro build", + "preview": "astro preview --port 8790", + "typecheck": "astro check" + }, + "dependencies": { + "@astrojs/node": "^11.1.7", + "astro": "^7.3.6", + "radius-sdk": "workspace:*" + }, + "devDependencies": { + "@astrojs/check": "^0.9.6", + "typescript": "^5.9.0" + } +} diff --git a/packages/sdk/examples/astro-seller/src/lib/articles.ts b/packages/sdk/examples/astro-seller/src/lib/articles.ts new file mode 100644 index 0000000..51c7d1d --- /dev/null +++ b/packages/sdk/examples/astro-seller/src/lib/articles.ts @@ -0,0 +1,8 @@ +// Stand-in for a CMS or content collection lookup. +const ARTICLES: Record = { + 'hello-radius': { title: 'Hello, Radius', body: 'Paid content delivered after settlement.' }, +}; + +export async function loadArticle(slug: string | undefined) { + return slug ? ARTICLES[slug] : undefined; +} diff --git a/packages/sdk/examples/astro-seller/src/lib/payments.ts b/packages/sdk/examples/astro-seller/src/lib/payments.ts new file mode 100644 index 0000000..7ad0352 --- /dev/null +++ b/packages/sdk/examples/astro-seller/src/lib/payments.ts @@ -0,0 +1,11 @@ +import { radiusPayments } from 'radius-sdk/server'; + +const PAY_TO = (import.meta.env.PAY_TO ?? '0x1eF420190c299D4d133fE9227F780D7d5cE91BeE') as `0x${string}`; +const NETWORK = (import.meta.env.RADIUS_NETWORK ?? 'testnet') as 'mainnet' | 'testnet'; + +export const pay = radiusPayments({ + network: NETWORK, + payTo: PAY_TO, + routes: { 'GET /articles/*': { price: '$0.001', description: 'One article' } }, + onSettled: (receipt, request) => console.log('settled', receipt.transaction, receipt.payer, new URL(request.url).pathname), +}); diff --git a/packages/sdk/examples/astro-seller/src/pages/articles/[slug].ts b/packages/sdk/examples/astro-seller/src/pages/articles/[slug].ts new file mode 100644 index 0000000..c540a2b --- /dev/null +++ b/packages/sdk/examples/astro-seller/src/pages/articles/[slug].ts @@ -0,0 +1,12 @@ +// Validate, then pay: with the default `settle: 'before'`, funds move before the paid handler +// runs, so a lookup that can fail belongs before `pay()`. A missing article is an unpaid 404; +// a real one is charged, then delivered. +import type { APIRoute } from 'astro'; +import { loadArticle } from '../../lib/articles'; +import { pay } from '../../lib/payments'; + +export const GET: APIRoute = async ({ request, params }) => { + const article = await loadArticle(params.slug); + if (!article) return new Response('Not found', { status: 404 }); + return pay(request, (_request, payment) => Response.json({ ...article, paidBy: payment?.payer, tx: payment?.transaction })); +}; diff --git a/packages/sdk/examples/astro-seller/src/pages/index.ts b/packages/sdk/examples/astro-seller/src/pages/index.ts new file mode 100644 index 0000000..7e07a2d --- /dev/null +++ b/packages/sdk/examples/astro-seller/src/pages/index.ts @@ -0,0 +1,3 @@ +import type { APIRoute } from 'astro'; + +export const GET: APIRoute = () => Response.json({ ok: true, paid: ['GET /articles/hello-radius $0.001'], unpaid404: 'GET /articles/missing' }); diff --git a/packages/sdk/examples/astro-seller/tsconfig.json b/packages/sdk/examples/astro-seller/tsconfig.json new file mode 100644 index 0000000..6c56c69 --- /dev/null +++ b/packages/sdk/examples/astro-seller/tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "astro/tsconfigs/strict", + "include": [".astro/types.d.ts", "src/**/*"] +} diff --git a/packages/sdk/examples/express-seller/package.json b/packages/sdk/examples/express-seller/package.json new file mode 100644 index 0000000..025da19 --- /dev/null +++ b/packages/sdk/examples/express-seller/package.json @@ -0,0 +1,19 @@ +{ + "name": "radius-express-seller", + "private": true, + "type": "module", + "scripts": { + "start": "node --experimental-strip-types src/index.ts", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "@x402/express": "2.27.0", + "express": "^5.2.1", + "radius-sdk": "workspace:*" + }, + "devDependencies": { + "@types/express": "^5.0.6", + "@types/node": "^24.0.0", + "typescript": "^5.9.0" + } +} diff --git a/packages/sdk/examples/express-seller/src/index.ts b/packages/sdk/examples/express-seller/src/index.ts new file mode 100644 index 0000000..9275e64 --- /dev/null +++ b/packages/sdk/examples/express-seller/src/index.ts @@ -0,0 +1,44 @@ +// A paid API on Express using the upstream x402 adapter. The SDK supplies the Radius +// resource server (facilitator, SBC pricing, gas sponsoring); `@x402/express` supplies +// the middleware. `@x402/next` and `@x402/hono` take the same two arguments. +import express from 'express'; +import { paymentMiddleware } from '@x402/express'; +import { createRadiusServer } from 'radius-sdk/server'; + +const PAY_TO = (process.env.PAY_TO ?? '0x1eF420190c299D4d133fE9227F780D7d5cE91BeE') as `0x${string}`; +const NETWORK = (process.env.RADIUS_NETWORK ?? 'testnet') as 'mainnet' | 'testnet'; +const PORT = Number(process.env.PORT ?? 8789); + +const radius = createRadiusServer({ + network: NETWORK, + onSettled: (receipt) => console.log('settled', receipt.transaction, receipt.payer), +}); + +const app = express(); +app.get('/', (_req, res) => { + res.json({ ok: true, paid: ['GET /api/lookup?ip=… $0.001', 'POST /api/query $0.01'] }); +}); + +app.use( + paymentMiddleware( + radius.routes({ + payTo: PAY_TO, + routes: { + 'GET /api/lookup': { price: '$0.001', description: 'Synthetic threat-intel lookup for one IP' }, + 'POST /api/query': { price: '$0.01', description: 'Batch query' }, + }, + }), + radius.server, + ), +); + +// Handlers only run after the payment has settled on Radius (the SDK defaults to settling first). +app.get('/api/lookup', (req, res) => { + const ip = typeof req.query.ip === 'string' ? req.query.ip : '0.0.0.0'; + res.json({ ip, reputation: ip.startsWith('10.') ? 'private' : 'clean', score: 7 }); +}); +app.post('/api/query', express.json(), (req, res) => { + res.json({ received: req.body ?? {}, results: [] }); +}); + +app.listen(PORT, () => console.log(`radius-express-seller on http://localhost:${PORT} (${NETWORK}, pay to ${PAY_TO})`)); diff --git a/packages/sdk/examples/express-seller/tsconfig.json b/packages/sdk/examples/express-seller/tsconfig.json new file mode 100644 index 0000000..40f044d --- /dev/null +++ b/packages/sdk/examples/express-seller/tsconfig.json @@ -0,0 +1,14 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "verbatimModuleSyntax": true, + "erasableSyntaxOnly": true, + "types": ["node"] + }, + "include": ["src"] +} diff --git a/packages/sdk/examples/worker-plain/package.json b/packages/sdk/examples/worker-plain/package.json new file mode 100644 index 0000000..f00843d --- /dev/null +++ b/packages/sdk/examples/worker-plain/package.json @@ -0,0 +1,18 @@ +{ + "name": "radius-worker-plain", + "private": true, + "type": "module", + "scripts": { + "dev": "wrangler dev --port 8788", + "deploy": "wrangler deploy", + "typecheck": "tsc --noEmit" + }, + "dependencies": { + "radius-sdk": "workspace:*" + }, + "devDependencies": { + "@cloudflare/workers-types": "^5.20260910.1", + "typescript": "^5.9.0", + "wrangler": "^4.131.0" + } +} diff --git a/packages/sdk/examples/worker-plain/src/index.ts b/packages/sdk/examples/worker-plain/src/index.ts new file mode 100644 index 0000000..b821089 --- /dev/null +++ b/packages/sdk/examples/worker-plain/src/index.ts @@ -0,0 +1,41 @@ +// A paid API on Cloudflare Workers with no framework: the SDK's web-standard handler +// takes a `Request` and returns a `Response`. The same code runs on Bun, Deno, Node 18+ +// (`Bun.serve({ fetch })`, `Deno.serve(fetch)`) and in Next.js / SvelteKit route handlers. +import { radiusPayments, type PaymentHandler } from 'radius-sdk/server'; + +type Env = { PAY_TO: `0x${string}`; RADIUS_NETWORK: 'mainnet' | 'testnet' }; + +let pay: PaymentHandler | undefined; + +// Built on the first request so config can come from bindings (Workers forbid I/O at +// module scope; the handler does none, but env is only available per request). +function payments(env: Env): PaymentHandler { + return (pay ??= radiusPayments({ + network: env.RADIUS_NETWORK, + payTo: env.PAY_TO, + routes: { + 'GET /api/lookup': { price: '$0.001', description: 'Synthetic threat-intel lookup for one IP' }, + 'POST /api/query': { price: '$0.01', description: 'Batch query' }, + }, + onSettled: (receipt, request) => console.log('settled', receipt.transaction, receipt.payer, new URL(request.url).pathname), + })); +} + +export default { + fetch(request: Request, env: Env): Promise { + // `payment` is the settled receipt: handlers only run for money already received. + return payments(env)(request, async (request, payment) => { + const url = new URL(request.url); + if (url.pathname === '/') return Response.json({ ok: true, paid: ['GET /api/lookup?ip=… $0.001', 'POST /api/query $0.01'] }); + if (url.pathname === '/api/lookup') { + const ip = url.searchParams.get('ip') ?? '0.0.0.0'; + return Response.json({ ip, reputation: ip.startsWith('10.') ? 'private' : 'clean', score: 7, paidBy: payment?.payer, tx: payment?.transaction }); + } + if (url.pathname === '/api/query' && request.method === 'POST') { + const body = await request.json().catch(() => ({})); + return Response.json({ received: body, results: [] }); + } + return Response.json({ error: 'not_found' }, { status: 404 }); + }); + }, +}; diff --git a/packages/sdk/examples/worker-plain/tsconfig.json b/packages/sdk/examples/worker-plain/tsconfig.json new file mode 100644 index 0000000..a0d7de0 --- /dev/null +++ b/packages/sdk/examples/worker-plain/tsconfig.json @@ -0,0 +1,12 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "ESNext", + "moduleResolution": "Bundler", + "strict": true, + "noEmit": true, + "skipLibCheck": true, + "types": ["@cloudflare/workers-types"] + }, + "include": ["src"] +} diff --git a/packages/sdk/examples/worker-plain/wrangler.toml b/packages/sdk/examples/worker-plain/wrangler.toml new file mode 100644 index 0000000..5536d05 --- /dev/null +++ b/packages/sdk/examples/worker-plain/wrangler.toml @@ -0,0 +1,8 @@ +name = "radius-worker-plain" +main = "src/index.ts" +compatibility_date = "2026-09-01" + +[vars] +RADIUS_NETWORK = "testnet" +# Set PAY_TO to your wallet address (or put it in .dev.vars locally / `wrangler secret put` in prod). +PAY_TO = "0x1eF420190c299D4d133fE9227F780D7d5cE91BeE" diff --git a/packages/sdk/package.json b/packages/sdk/package.json index 092bc99..cc64149 100644 --- a/packages/sdk/package.json +++ b/packages/sdk/package.json @@ -1,7 +1,7 @@ { "name": "radius-sdk", "version": "0.3.0", - "description": "Accept and make Radius payments over x402 v2 \u2014 Hono / Cloudflare Workers first", + "description": "Accept and make Radius payments over x402 v2 \u2014 any web-standard runtime, Hono, or the upstream x402 framework adapters", "type": "module", "license": "MIT", "engines": { @@ -17,6 +17,10 @@ "types": "./dist/index.d.ts", "default": "./dist/index.js" }, + "./server": { + "types": "./dist/server/index.d.ts", + "default": "./dist/server/index.js" + }, "./hono": { "types": "./dist/hono/index.d.ts", "default": "./dist/hono/index.js" @@ -35,8 +39,8 @@ "test:imports": "pnpm run build && node --test scripts/imports.test.mjs" }, "dependencies": { - "@x402/core": "2.25.0", - "@x402/evm": "2.25.0" + "@x402/core": "2.27.0", + "@x402/evm": "2.27.0" }, "peerDependencies": { "hono": "^4.0.0", @@ -55,11 +59,14 @@ "@ethereumjs/evm": "10.1.3", "@ethereumjs/statemanager": "10.1.3", "@ethereumjs/util": "10.1.3", + "@types/express": "^5.0.6", + "@x402/express": "2.27.0", + "express": "^5.2.1", "hono": "^4.13.7", "typescript": "^5.9.0", + "viem": "^2.48.11", "vitest": "^3.2.0", - "wrangler": "^4.131.0", - "viem": "^2.48.11" + "wrangler": "^4.131.0" }, "repository": { "type": "git", diff --git a/packages/sdk/scripts/imports.test.mjs b/packages/sdk/scripts/imports.test.mjs index 205dcaa..e377fe8 100644 --- a/packages/sdk/scripts/imports.test.mjs +++ b/packages/sdk/scripts/imports.test.mjs @@ -53,6 +53,30 @@ test('root and Hono seller work with buyer dependency imports blocked', () => { `, true); }); +test('web-standard server handler works with buyer dependency imports blocked', () => { + run(` + import assert from 'node:assert/strict'; + import { radiusPayments, createRadiusServer } from 'radius-sdk/server'; + + const pay = radiusPayments({ + network: 'testnet', + payTo: '0x1111111111111111111111111111111111111111', + routes: { 'GET /paid': '0.001 SBC' }, + facilitator: { live: false }, + }); + let called = false; + const response = await pay(new Request('http://localhost/paid'), () => { called = true; return new Response('paid'); }); + assert.equal(response.status, 402); + assert.equal(called, false); + const challenge = JSON.parse(Buffer.from(response.headers.get('PAYMENT-REQUIRED'), 'base64')); + assert.equal(challenge.accepts[0].network, 'eip155:72344'); + assert.equal(challenge.accepts[0].amount, '1000'); + const radius = createRadiusServer({ network: 'testnet', facilitator: { live: false } }); + assert.equal(typeof radius.server.initialize, 'function'); + assert.ok('GET /paid' in radius.routes({ payTo: '0x1111111111111111111111111111111111111111', routes: { 'GET /paid': '$1' } })); + `, true); +}); + test('buyer initializes with the installed viem peer', () => { run(` import assert from 'node:assert/strict'; diff --git a/packages/sdk/src/hono/index.ts b/packages/sdk/src/hono/index.ts index 39e03d4..660443f 100644 --- a/packages/sdk/src/hono/index.ts +++ b/packages/sdk/src/hono/index.ts @@ -1,69 +1,23 @@ import type { Context, Env, MiddlewareHandler } from 'hono'; -import { - FacilitatorResponseError, - type FacilitatorClient, - SETTLEMENT_OVERRIDES_HEADER, - getFacilitatorResponseError, - withPrivateCacheControl, - x402HTTPResourceServer, - x402ResourceServer, - type HTTPAdapter, - type HTTPRequestContext, - type HTTPResponseInstructions, - type RouteConfig, - type RoutesConfig, -} from '@x402/core/server'; -import type { SettleResponse } from '@x402/core/types'; -import { resolveNetwork, type Address, type NetworkInput, type NetworkOverrides, type RadiusNetwork } from '../networks.js'; -import { resolvePrice, type Price } from '../amounts.js'; -import { explorerTxUrl } from '../networks.js'; +import type { HTTPRequestContext } from '@x402/core/server'; import type { PaymentReceipt } from '../receipt.js'; -import { RadiusFacilitatorClient, withUnknownOutcomes, type FacilitatorOptions } from './facilitator.js'; -import { RadiusExactScheme, type GasSponsoringMode, type SettleMode } from './scheme.js'; +import { RadiusServer, createPaymentHandler, requestOf, type PayTo as ServerPayTo, type RadiusServerOptions, type RouteSpec as ServerRouteSpec, type RouteSpecs } from '../server/index.js'; -export { RadiusFacilitatorClient, staticSupported, type FacilitatorOptions } from './facilitator.js'; -export { RadiusExactScheme, type GasSponsoringMode, type SettleMode } from './scheme.js'; +export { RadiusFacilitatorClient, staticSupported, withUnknownOutcomes, type FacilitatorOptions } from '../server/facilitator.js'; +export { RadiusExactScheme, type GasSponsoringMode, type SettleMode } from '../server/scheme.js'; +export { RadiusServer, createRadiusServer, RequestAdapter, toReceipt, type RadiusServerOptions } from '../server/index.js'; -export type PayTo = Address | ((c: Context) => Address | Promise
); +export type PayTo = ServerPayTo>; +export type RouteSpec = ServerRouteSpec>; -export interface RouteSpec { - /** "$0.01", "0.01", 0.01 (USD == SBC), or { amount: "10000" } atomic units. */ - price: Price | ((c: Context) => Price | Promise); - description?: string; - mimeType?: string; - /** Seconds the signed payment stays valid. Default 300. */ - maxTimeoutSeconds?: number; - /** Per-route recipient override. */ - payTo?: PayTo; -} - -export interface RadiusPaymentsOptions extends NetworkOverrides { - /** 'mainnet' (default), 'testnet', a preset, or a custom instance. */ - network?: NetworkInput; +export interface RadiusPaymentsOptions extends Omit { /** Recipient of every payment (unless a route overrides it). May read `c.env`. */ payTo: PayTo; /** * Protected routes keyed "METHOD /path" (Hono-style `*` wildcards allowed, e.g. * "GET /api/*"). A bare price is shorthand for `{ price }`. */ - routes: Record | Price>; - /** - * Which facilitator verifies and settles. Defaults to the Radius facilitator for - * the network. Pass `{ url, apiKey }` for another hosted facilitator, or your own - * `FacilitatorClient` (from `@x402/core/server`) for a self-hosted one. - */ - facilitator?: FacilitatorOptions | FacilitatorClient; - /** - * 'before' (default): verify and settle on-chain, then run the handler — the - * handler only ever runs for money already received. - * 'after': verify, run the handler, settle if it succeeded (x402 default flow). - */ - settle?: SettleMode; - /** - * Whether 402s declare `eip2612GasSponsoring` (lets first-time wallets pay without an - * approval transaction). 'auto' (default): only when the facilitator supports it. - */ - gasSponsoring?: GasSponsoringMode; + routes: RouteSpecs>; /** Called once per settled payment. */ onSettled?: (receipt: PaymentReceipt, c: Context) => void | Promise; } @@ -71,253 +25,31 @@ export interface RadiusPaymentsOptions extends NetworkOverr /** Hono context variable set for paid requests: `c.get('radiusPayment')`. */ export type RadiusPaymentVariables = { radiusPayment?: PaymentReceipt }; -/** Adapter over Hono's context that also carries the context for dynamic payTo/price. */ -export class RadiusHonoAdapter implements HTTPAdapter { - constructor(readonly c: Context) {} - getHeader(name: string): string | undefined { - return this.c.req.header(name); - } - getMethod(): string { - return this.c.req.method; - } - getPath(): string { - return this.c.req.path; - } - getUrl(): string { - return this.c.req.url; - } - getAcceptHeader(): string { - return this.c.req.header('accept') ?? ''; - } - getUserAgent(): string { - return this.c.req.header('user-agent') ?? ''; - } - getQueryParams(): Record { - return this.c.req.queries() as Record; - } - getQueryParam(name: string): string | string[] | undefined { - const all = this.c.req.queries(name); - if (!all || all.length === 0) return undefined; - return all.length === 1 ? all[0] : all; - } - async getBody(): Promise { - try { - return await this.c.req.raw.clone().json(); - } catch { - return undefined; - } - } -} - -const GAS_SPONSORING_DECLARATION = { - eip2612GasSponsoring: { - info: { - description: 'The facilitator accepts EIP-2612 gasless Permit to `Permit2` canonical contract.', - version: '1', - }, - schema: { - $schema: 'https://json-schema.org/draft/2020-12/schema', - type: 'object', - properties: { - from: { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$' }, - asset: { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$' }, - spender: { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$' }, - amount: { type: 'string', pattern: '^[0-9]+$' }, - nonce: { type: 'string', pattern: '^[0-9]+$' }, - deadline: { type: 'string', pattern: '^[0-9]+$' }, - signature: { type: 'string', pattern: '^0x[a-fA-F0-9]+$' }, - version: { type: 'string', pattern: '^[0-9]+(\\.[0-9]+)*$' }, - }, - required: ['from', 'asset', 'spender', 'amount', 'nonce', 'deadline', 'signature', 'version'], - }, - }, -} as const; - -function isFacilitatorClient(v: unknown): v is FacilitatorClient { - return typeof v === 'object' && v !== null && typeof (v as FacilitatorClient).settle === 'function' && typeof (v as FacilitatorClient).getSupported === 'function'; -} - -function contextOf(ctx: HTTPRequestContext): Context { - const adapter = ctx.adapter as RadiusHonoAdapter; - if (!adapter.c) throw new Error('radius-sdk: expected RadiusHonoAdapter'); - return adapter.c; -} - -function toReceipt(r: SettleResponse, network: RadiusNetwork, requirements: { amount: string }): PaymentReceipt { - const transaction = r.transaction && r.transaction.length > 0 ? r.transaction : undefined; - return { - success: r.success, - transaction, - network: r.network, - payer: r.payer, - // `exact` settles precisely the requested amount; facilitators only report `amount` - // for schemes (like `upto`) where it can differ. - amount: r.amount ?? (r.success ? requirements.amount : undefined), - errorReason: r.errorReason, - errorMessage: r.errorMessage, - explorerUrl: transaction ? explorerTxUrl(network, transaction) : undefined, - }; -} - -function applyInstructions(c: Context, r: HTTPResponseInstructions): Response { - for (const [k, v] of Object.entries(r.headers)) c.header(k, v); - if (r.isHtml) return c.html(String(r.body ?? ''), r.status as 402); - return c.json((r.body ?? {}) as object, r.status as 402); -} - -function facilitatorErrorResponse(c: Context, error: FacilitatorResponseError): Response { - return c.json({ error: 'facilitator_error', message: error.message }, 502); -} - -function internalErrorResponse(c: Context, error: unknown): Response { - const message = error instanceof Error ? error.message : String(error); - return c.json({ error: 'payment_processing_error', message }, 500); -} - /** - * Hono middleware that charges for routes with Radius x402 payments. - * - * Standard x402 v2 on the wire: unpaid requests get a 402 with a `PAYMENT-REQUIRED` - * header; paid requests carry `PAYMENT-SIGNATURE`, are verified and settled through - * the Radius facilitator, and get a `PAYMENT-RESPONSE` header back. + * Hono middleware that charges for routes with Radius x402 payments. A thin wrapper + * over the web-standard handler in `radius-sdk/server`: dynamic `payTo`/`price` and + * `onSettled` receive the Hono context, and paid handlers can read the receipt with + * `c.get('radiusPayment')` (when `settle` is 'before', the default). */ export function radiusPayments(options: RadiusPaymentsOptions): MiddlewareHandler { - const network = resolveNetwork(options.network, options); - const settle: SettleMode = options.settle ?? 'before'; - const facilitator = withUnknownOutcomes( - isFacilitatorClient(options.facilitator) ? options.facilitator : new RadiusFacilitatorClient(network, options.facilitator), - ); - const resourceServer = new x402ResourceServer(facilitator).register(network.network, new RadiusExactScheme(network, settle, options.gasSponsoring ?? 'auto')); - - const resolvePayTo = (spec: PayTo) => - typeof spec === 'function' ? (ctx: HTTPRequestContext) => spec(contextOf(ctx)) : spec; - - const routes: RoutesConfig = {}; - for (const [pattern, specOrPrice] of Object.entries(options.routes)) { - const spec: RouteSpec = - typeof specOrPrice === 'object' && specOrPrice !== null && 'price' in specOrPrice - ? (specOrPrice as RouteSpec) - : { price: specOrPrice as Price }; - const price = spec.price; - const normalise = (p: Price) => resolvePrice(p, network.asset); - const route: RouteConfig & { extensions?: Record } = { - accepts: { - scheme: 'exact', - network: network.network, - payTo: resolvePayTo(spec.payTo ?? options.payTo), - price: typeof price === 'function' ? async (ctx: HTTPRequestContext) => normalise(await price(contextOf(ctx))) : normalise(price), - maxTimeoutSeconds: spec.maxTimeoutSeconds ?? 300, - }, - description: spec.description, - mimeType: spec.mimeType, - extensions: { ...GAS_SPONSORING_DECLARATION }, - }; - routes[pattern] = route; - } - - const httpServer = new x402HTTPResourceServer(resourceServer, routes); - - // Lazy, request-time initialisation: Workers forbid I/O at module scope, and the - // static facilitator answer means this is normally just bookkeeping anyway. - let initPromise: Promise | undefined; - const ensureInitialized = () => - (initPromise ??= httpServer.initialize().catch((e) => { - initPromise = undefined; - throw e; - })); - + const { payTo, routes, onSettled, ...serverOptions } = options; + const contexts = new WeakMap>(); + const contextOf = (ctx: HTTPRequestContext | undefined): Context => { + const c = contexts.get(requestOf(ctx) as Request); + if (!c) throw new Error('radius-sdk/hono: request was not served through this middleware'); + return c; + }; + const radius = new RadiusServer({ + ...serverOptions, + onSettled: onSettled && ((receipt, ctx) => onSettled(receipt, contextOf(ctx))), + }); + const handler = createPaymentHandler(radius, radius.buildRoutes({ payTo, routes }, contextOf)); return async (c, next) => { - const adapter = new RadiusHonoAdapter(c); - const context: HTTPRequestContext = { - adapter, - path: c.req.path, - method: c.req.method, - paymentHeader: adapter.getHeader('payment-signature') ?? adapter.getHeader('x-payment'), - }; - if (!httpServer.requiresPayment(context)) return next(); - - try { - await ensureInitialized(); - } catch (error) { - const fe = getFacilitatorResponseError(error); - return fe ? facilitatorErrorResponse(c, fe) : internalErrorResponse(c, error); - } - - let result: Awaited>; - try { - result = await httpServer.processHTTPRequest(context); - } catch (error) { - if (error instanceof FacilitatorResponseError) return facilitatorErrorResponse(c, error); - return internalErrorResponse(c, error); - } - - if (result.type === 'no-payment-required') return next(); - if (result.type === 'payment-error') return applyInstructions(c, result.response); - - const { cancellationDispatcher, beforeHandlerSettlement, paymentPayload, paymentRequirements, declaredExtensions } = result; - let notified = false; - const notify = async (r: SettleResponse) => { - if (notified) return; - notified = true; - const receipt = toReceipt(r, network, paymentRequirements); - c.set('radiusPayment' as never, receipt as never); - if (options.onSettled) await options.onSettled(receipt, c); - }; - if (beforeHandlerSettlement) await notify(beforeHandlerSettlement.result); - - try { + contexts.set(c.req.raw, c); + c.res = await handler(c.req.raw, async (_request, payment) => { + if (payment) c.set('radiusPayment' as never, payment as never); await next(); - } catch (error) { - const cancelSettlement = await cancellationDispatcher.cancel({ reason: 'handler_threw', error: error as Error }); - if (!beforeHandlerSettlement && !cancelSettlement) throw error; - const res = internalErrorResponse(c, error); - const headers = httpServer.createFailurePathSettlementHeaders(cancelSettlement, beforeHandlerSettlement, paymentPayload, res.headers.get('Cache-Control')); - if (headers) for (const [k, v] of Object.entries(headers)) res.headers.set(k, v); - c.res = res; - return; - } - - let res = c.res; - if (res.status >= 400) { - const cancelSettlement = await cancellationDispatcher.cancel({ reason: 'handler_failed', responseStatus: res.status }); - res.headers.delete(SETTLEMENT_OVERRIDES_HEADER); - const headers = httpServer.createFailurePathSettlementHeaders(cancelSettlement, beforeHandlerSettlement, paymentPayload, res.headers.get('Cache-Control')); - if (headers) for (const [k, v] of Object.entries(headers)) res.headers.set(k, v); - return; - } - - const responseBody = new Uint8Array(await res.clone().arrayBuffer()); - const responseHeaders: Record = {}; - res.headers.forEach((v, k) => { - responseHeaders[k] = v; + return c.res; }); - c.res = undefined; - try { - const settleResult = await httpServer.processSettlement( - paymentPayload, - paymentRequirements, - declaredExtensions, - { request: context, responseBody, responseHeaders }, - undefined, - beforeHandlerSettlement, - ); - if (!settleResult.success) { - const r = settleResult.response; - res = new Response(r.isHtml ? String(r.body ?? '') : JSON.stringify(r.body ?? {}), { status: r.status, headers: r.headers }); - } else { - for (const [k, v] of Object.entries(settleResult.headers)) res.headers.set(k, v); - res.headers.set('Cache-Control', withPrivateCacheControl(res.headers.get('Cache-Control'))); - res.headers.delete(SETTLEMENT_OVERRIDES_HEADER); - await notify(settleResult); - } - } catch (error) { - if (error instanceof FacilitatorResponseError) { - c.res = facilitatorErrorResponse(c, error); - return; - } - console.error(error); - res = c.json({ error: 'settlement_error' }, 402); - } - c.res = res; }; } diff --git a/packages/sdk/src/server/adapter.ts b/packages/sdk/src/server/adapter.ts new file mode 100644 index 0000000..fed2e8b --- /dev/null +++ b/packages/sdk/src/server/adapter.ts @@ -0,0 +1,85 @@ +import type { HTTPAdapter, HTTPRequestContext } from '@x402/core/server'; + +/** + * x402 `HTTPAdapter` over a web-standard `Request`. Works anywhere `Request`/`Response` + * exist: Cloudflare Workers, Bun, Deno, Node 18+, Next.js route handlers, and + * frameworks built on them (Hono, SvelteKit, Remix, Astro). + */ +export class RequestAdapter implements HTTPAdapter { + readonly url: URL; + + constructor(readonly request: Request) { + this.url = new URL(request.url); + } + + getHeader(name: string): string | undefined { + return this.request.headers.get(name) ?? undefined; + } + getMethod(): string { + return this.request.method; + } + getPath(): string { + return this.url.pathname; + } + getUrl(): string { + return this.request.url; + } + getAcceptHeader(): string { + return this.request.headers.get('accept') ?? ''; + } + getUserAgent(): string { + return this.request.headers.get('user-agent') ?? ''; + } + getQueryParams(): Record { + const out: Record = {}; + for (const [key, value] of this.url.searchParams) { + const existing = out[key]; + if (existing === undefined) out[key] = value; + else if (Array.isArray(existing)) existing.push(value); + else out[key] = [existing, value]; + } + return out; + } + getQueryParam(name: string): string | string[] | undefined { + const all = this.url.searchParams.getAll(name); + if (all.length === 0) return undefined; + return all.length === 1 ? all[0] : all; + } + async getBody(): Promise { + try { + return await this.request.clone().json(); + } catch { + return undefined; + } + } +} + +function decodePath(pathname: string): string | undefined { + try { + return decodeURIComponent(pathname); + } catch { + return undefined; + } +} + +/** Build the x402 request context for a web-standard `Request`. */ +export function requestContext(request: Request): HTTPRequestContext { + const adapter = new RequestAdapter(request); + return { + adapter, + path: adapter.getPath(), + decodedPath: decodePath(adapter.getPath()), + method: request.method, + paymentHeader: adapter.getHeader('payment-signature') ?? adapter.getHeader('x-payment'), + }; +} + +/** + * The `Request` behind an x402 request context, when it was produced by this SDK's + * adapter (the web-standard handler and the Hono middleware). `undefined` for + * requests served through a third-party adapter such as `@x402/express`. + */ +export function requestOf(context: HTTPRequestContext | undefined): Request | undefined { + const adapter = context?.adapter; + return adapter instanceof RequestAdapter ? adapter.request : undefined; +} diff --git a/packages/sdk/src/hono/facilitator.ts b/packages/sdk/src/server/facilitator.ts similarity index 100% rename from packages/sdk/src/hono/facilitator.ts rename to packages/sdk/src/server/facilitator.ts diff --git a/packages/sdk/src/server/index.ts b/packages/sdk/src/server/index.ts new file mode 100644 index 0000000..84a7c4a --- /dev/null +++ b/packages/sdk/src/server/index.ts @@ -0,0 +1,387 @@ +import { + FacilitatorResponseError, + type FacilitatorClient, + SETTLEMENT_OVERRIDES_HEADER, + getFacilitatorResponseError, + withPrivateCacheControl, + x402HTTPResourceServer, + x402ResourceServer, + type HTTPRequestContext, + type HTTPResponseInstructions, + type RouteConfig, + type RoutesConfig, +} from '@x402/core/server'; +import type { SettleResponse } from '@x402/core/types'; +import { resolveNetwork, explorerTxUrl, type Address, type NetworkInput, type NetworkOverrides, type RadiusNetwork } from '../networks.js'; +import { resolvePrice, type Price } from '../amounts.js'; +import type { PaymentReceipt } from '../receipt.js'; +import { RadiusFacilitatorClient, withUnknownOutcomes, type FacilitatorOptions } from './facilitator.js'; +import { RadiusExactScheme, type GasSponsoringMode, type SettleMode } from './scheme.js'; +import { requestContext, requestOf } from './adapter.js'; + +export { RadiusFacilitatorClient, staticSupported, withUnknownOutcomes, type FacilitatorOptions } from './facilitator.js'; +export { RadiusExactScheme, type GasSponsoringMode, type SettleMode } from './scheme.js'; +export { RequestAdapter, requestContext, requestOf } from './adapter.js'; +export type { HTTPRequestContext, RoutesConfig, FacilitatorClient } from '@x402/core/server'; + +/** Recipient address, or a function of the request. */ +export type PayTo = Address | ((ctx: Ctx) => Address | Promise
); + +export interface RouteSpec { + /** "$0.01", "0.01", 0.01 (USD == SBC), or { amount: "10000" } atomic units. */ + price: Price | ((ctx: Ctx) => Price | Promise); + description?: string; + mimeType?: string; + /** Seconds the signed payment stays valid. Default 300. */ + maxTimeoutSeconds?: number; + /** Per-route recipient override. */ + payTo?: PayTo; +} + +/** + * Protected routes keyed "METHOD /path" (`*` wildcards allowed, e.g. "GET /api/*"). + * A bare price is shorthand for `{ price }`. + */ +export type RouteSpecs = Record | Price>; + +export interface RoutesOptions { + /** Recipient of every payment (unless a route overrides it). */ + payTo: PayTo; + routes: RouteSpecs; +} + +export interface RadiusServerOptions extends NetworkOverrides { + /** 'mainnet' (default), 'testnet', a preset, or a custom instance. */ + network?: NetworkInput; + /** + * Which facilitator verifies and settles. Defaults to the Radius facilitator for + * the network. Pass `{ url, apiKey }` for another hosted facilitator, or your own + * `FacilitatorClient` (from `@x402/core/server`) for a self-hosted one. + */ + facilitator?: FacilitatorOptions | FacilitatorClient; + /** + * 'before' (default): verify and settle on-chain, then run the handler — the + * handler only ever runs for money already received. + * 'after': verify, run the handler, settle if it succeeded (x402 default flow). + */ + settle?: SettleMode; + /** + * Whether 402s declare `eip2612GasSponsoring` (lets first-time wallets pay without an + * approval transaction). 'auto' (default): only when the facilitator supports it. + */ + gasSponsoring?: GasSponsoringMode; + /** + * Called once per settled payment, whichever adapter served the request. `context` + * is the x402 request context; `requestOf(context)` gives the `Request` when the + * SDK's own adapter handled it. + * + * Records settlement, not delivery: with `settle: 'before'` it fires before the handler + * runs, and the handler may still fail or return an error. Errors thrown here are logged + * by x402 core, not surfaced to the buyer. Persist the receipt and the delivery outcome + * separately so a paid 5xx (or an uncertain 502) can be reconciled before the buyer pays again. + */ + onSettled?: (receipt: PaymentReceipt, context: HTTPRequestContext | undefined) => void | Promise; +} + +const GAS_SPONSORING_DECLARATION = { + eip2612GasSponsoring: { + info: { + description: 'The facilitator accepts EIP-2612 gasless Permit to `Permit2` canonical contract.', + version: '1', + }, + schema: { + $schema: 'https://json-schema.org/draft/2020-12/schema', + type: 'object', + properties: { + from: { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$' }, + asset: { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$' }, + spender: { type: 'string', pattern: '^0x[a-fA-F0-9]{40}$' }, + amount: { type: 'string', pattern: '^[0-9]+$' }, + nonce: { type: 'string', pattern: '^[0-9]+$' }, + deadline: { type: 'string', pattern: '^[0-9]+$' }, + signature: { type: 'string', pattern: '^0x[a-fA-F0-9]+$' }, + version: { type: 'string', pattern: '^[0-9]+(\\.[0-9]+)*$' }, + }, + required: ['from', 'asset', 'spender', 'amount', 'nonce', 'deadline', 'signature', 'version'], + }, + }, +} as const; + +function isFacilitatorClient(v: unknown): v is FacilitatorClient { + return typeof v === 'object' && v !== null && typeof (v as FacilitatorClient).settle === 'function' && typeof (v as FacilitatorClient).getSupported === 'function'; +} + +/** Turn a facilitator settle result into the receipt handed to application code. */ +export function toReceipt(r: SettleResponse, network: RadiusNetwork, requirements: { amount: string }): PaymentReceipt { + const transaction = r.transaction && r.transaction.length > 0 ? r.transaction : undefined; + return { + success: r.success, + transaction, + network: r.network, + payer: r.payer, + // `exact` settles precisely the requested amount; facilitators only report `amount` + // for schemes (like `upto`) where it can differ. + amount: r.amount ?? (r.success ? requirements.amount : undefined), + errorReason: r.errorReason, + errorMessage: r.errorMessage, + explorerUrl: transaction ? explorerTxUrl(network, transaction) : undefined, + }; +} + +/** + * Radius payments for any HTTP stack. Holds the x402 resource server (Radius scheme, + * facilitator, gas-sponsoring rules) independently of how requests arrive: + * + * - `server` + `routes()` plug into the upstream adapters (`@x402/express`, + * `@x402/next`, `@x402/hono`): `paymentMiddleware(radius.routes({...}), radius.server)`. + * - `handler()` serves web-standard `Request` → `Response` directly (Workers, Bun, + * Deno, Node, route handlers). `radius-sdk/hono` wraps it for Hono. + */ +export class RadiusServer { + readonly network: RadiusNetwork; + /** The facilitator, wrapped so calls that fail without its own answer surface as 502 (`withUnknownOutcomes`). */ + readonly facilitator: FacilitatorClient; + readonly scheme: RadiusExactScheme; + /** The x402 resource server, for upstream framework adapters. */ + readonly server: x402ResourceServer; + + constructor(options: RadiusServerOptions = {}) { + this.network = resolveNetwork(options.network, options); + this.facilitator = withUnknownOutcomes(isFacilitatorClient(options.facilitator) ? options.facilitator : new RadiusFacilitatorClient(this.network, options.facilitator)); + this.scheme = new RadiusExactScheme(this.network, options.settle ?? 'before', options.gasSponsoring ?? 'auto'); + this.server = new x402ResourceServer(this.facilitator).register(this.network.network, this.scheme); + if (options.onSettled) this.onSettled(options.onSettled); + } + + /** Register a settlement listener (see `RadiusServerOptions.onSettled`). */ + onSettled(hook: NonNullable): this { + this.server.onAfterSettle(async (ctx) => { + if (!ctx.result.success) return; + const transport = ctx.transportContext as { request?: HTTPRequestContext } | undefined; + await hook(toReceipt(ctx.result as SettleResponse, this.network, ctx.requirements), transport?.request); + }); + return this; + } + + /** + * x402 `RoutesConfig` with Radius pricing (USD/SBC display units or atomic amounts) + * and the gas-sponsoring declaration. Dynamic `payTo`/`price` receive the x402 + * request context. + */ + routes(options: RoutesOptions): RoutesConfig { + return this.buildRoutes(options, (ctx) => ctx); + } + + /** `routes()` with dynamic functions receiving a framework-specific context. @internal */ + buildRoutes(options: RoutesOptions, contextOf: (ctx: HTTPRequestContext) => Ctx): RoutesConfig { + const network = this.network; + const resolvePayTo = (spec: PayTo) => (typeof spec === 'function' ? (ctx: HTTPRequestContext) => spec(contextOf(ctx)) : spec); + const normalise = (p: Price) => resolvePrice(p, network.asset); + const routes: RoutesConfig = {}; + for (const [pattern, specOrPrice] of Object.entries(options.routes)) { + const spec: RouteSpec = + typeof specOrPrice === 'object' && specOrPrice !== null && 'price' in specOrPrice ? (specOrPrice as RouteSpec) : { price: specOrPrice as Price }; + const price = spec.price; + const route: RouteConfig & { extensions?: Record } = { + accepts: { + scheme: 'exact', + network: network.network, + payTo: resolvePayTo(spec.payTo ?? options.payTo), + price: typeof price === 'function' ? async (ctx: HTTPRequestContext) => normalise(await price(contextOf(ctx))) : normalise(price), + maxTimeoutSeconds: spec.maxTimeoutSeconds ?? 300, + }, + description: spec.description, + mimeType: spec.mimeType, + extensions: { ...GAS_SPONSORING_DECLARATION }, + }; + routes[pattern] = route; + } + return routes; + } + + /** An `x402HTTPResourceServer` for these routes (`paymentMiddlewareFromHTTPServer` in upstream adapters). */ + http(options: RoutesOptions): x402HTTPResourceServer { + return new x402HTTPResourceServer(this.server, this.routes(options)); + } + + /** Web-standard handler for these routes; dynamic `payTo`/`price` receive the `Request`. */ + handler(options: RoutesOptions): PaymentHandler { + return createPaymentHandler(this, this.buildRoutes(options, (ctx) => requestOf(ctx) ?? missingRequest())); + } +} + +function missingRequest(): never { + throw new Error('radius-sdk: request context was not produced by RequestAdapter'); +} + +export function createRadiusServer(options: RadiusServerOptions = {}): RadiusServer { + return new RadiusServer(options); +} + +/** The application handler behind a paid route. `payment` is set when settlement ran before the handler (`settle: 'before'`, the default). */ +export type NextHandler = (request: Request, payment?: PaymentReceipt) => Response | Promise; + +export interface PaymentHandler { + /** Charge for `request` if it matches a paid route, then call `next` (or answer 402 / errors). */ + (request: Request, next: NextHandler): Promise; + /** `handler => request => Response`, for runtimes that take a single fetch function. */ + wrap(next: NextHandler): (request: Request) => Promise; + /** True when `request` matches a paid route (cheap, no network). */ + requiresPayment(request: Request): boolean; + readonly radius: RadiusServer; +} + +export interface RadiusPaymentsOptions extends Omit, RoutesOptions { + /** Called once per settled payment with the `Request` that paid. */ + onSettled?: (receipt: PaymentReceipt, request: Request) => void | Promise; +} + +/** + * Charge for routes with Radius x402 payments, for any runtime that speaks + * web-standard `Request`/`Response`: + * + * ```ts + * const pay = radiusPayments({ network: 'testnet', payTo: '0x…', routes: { 'GET /api/lookup': '$0.001' } }); + * export default { fetch: pay.wrap((request, payment) => Response.json({ paidBy: payment?.payer })) }; + * ``` + * + * Standard x402 v2 on the wire: unpaid requests get a 402 with a `PAYMENT-REQUIRED` + * header; paid requests carry `PAYMENT-SIGNATURE`, are verified and settled through + * the facilitator, and get a `PAYMENT-RESPONSE` header back. + */ +export function radiusPayments(options: RadiusPaymentsOptions): PaymentHandler { + const { payTo, routes, onSettled, ...serverOptions } = options; + const radius = new RadiusServer({ + ...serverOptions, + onSettled: onSettled && ((receipt, ctx) => onSettled(receipt, requestOf(ctx) ?? missingRequest())), + }); + return radius.handler({ payTo, routes }); +} + +function jsonResponse(body: unknown, status: number): Response { + return Response.json(body, { status }); +} + +function instructionsToResponse(r: HTTPResponseInstructions): Response { + const res = r.isHtml ? new Response(String(r.body ?? ''), { status: r.status, headers: { 'Content-Type': 'text/html; charset=UTF-8' } }) : jsonResponse(r.body ?? {}, r.status); + for (const [k, v] of Object.entries(r.headers)) res.headers.set(k, v); + return res; +} + +function facilitatorErrorResponse(error: FacilitatorResponseError): Response { + return jsonResponse({ error: 'facilitator_error', message: error.message }, 502); +} + +function internalErrorResponse(error: unknown): Response { + const message = error instanceof Error ? error.message : String(error); + return jsonResponse({ error: 'payment_processing_error', message }, 500); +} + +function errorResponse(error: unknown): Response { + const fe = getFacilitatorResponseError(error); + return fe ? facilitatorErrorResponse(fe) : internalErrorResponse(error); +} + +function setHeaders(res: Response, headers: Record | undefined): void { + if (headers) for (const [k, v] of Object.entries(headers)) res.headers.set(k, v); +} + +/** A copy of `res` whose headers are mutable (responses from `fetch()` have immutable headers). */ +function mutable(res: Response, body: BodyInit | null = res.body): Response { + return new Response(body, { status: res.status, statusText: res.statusText, headers: res.headers }); +} + +/** Web-standard handler for an already-built x402 `RoutesConfig` (see `RadiusServer.buildRoutes`). @internal */ +export function createPaymentHandler(radius: RadiusServer, routes: RoutesConfig): PaymentHandler { + const { network } = radius; + const httpServer = new x402HTTPResourceServer(radius.server, routes); + + // Lazy, request-time initialisation: Workers forbid I/O at module scope, and the + // static facilitator answer means this is normally just bookkeeping anyway. + let initPromise: Promise | undefined; + const ensureInitialized = () => + (initPromise ??= httpServer.initialize().catch((e) => { + initPromise = undefined; + throw e; + })); + + const handle = async (request: Request, next: NextHandler): Promise => { + const context = requestContext(request); + if (!httpServer.requiresPayment(context)) return next(request); + + try { + await ensureInitialized(); + } catch (error) { + return errorResponse(error); + } + + let result: Awaited>; + try { + result = await httpServer.processHTTPRequest(context); + } catch (error) { + return errorResponse(error); + } + + if (result.type === 'no-payment-required') return next(request); + if (result.type === 'payment-error') return instructionsToResponse(result.response); + + const { cancellationDispatcher, beforeHandlerSettlement, paymentPayload, paymentRequirements, declaredExtensions } = result; + const payment = beforeHandlerSettlement ? toReceipt(beforeHandlerSettlement.result, network, paymentRequirements) : undefined; + + let res: Response; + try { + res = await next(request, payment); + } catch (error) { + const cancelSettlement = await cancellationDispatcher.cancel({ reason: 'handler_threw', error: error as Error }); + if (!beforeHandlerSettlement && !cancelSettlement) throw error; + const failure = internalErrorResponse(error); + setHeaders(failure, httpServer.createFailurePathSettlementHeaders(cancelSettlement, beforeHandlerSettlement, paymentPayload, failure.headers.get('Cache-Control'))); + return failure; + } + + if (res.status >= 400) { + const cancelSettlement = await cancellationDispatcher.cancel({ reason: 'handler_failed', responseStatus: res.status }); + const failure = mutable(res); + failure.headers.delete(SETTLEMENT_OVERRIDES_HEADER); + setHeaders(failure, httpServer.createFailurePathSettlementHeaders(cancelSettlement, beforeHandlerSettlement, paymentPayload, failure.headers.get('Cache-Control'))); + return failure; + } + + // Settlement already happened in the 'before' flow: core only echoes its headers, so the + // handler's body streams through untouched. The 'after' flow settles on the finished + // response and needs the body in hand. + const responseBody = beforeHandlerSettlement ? undefined : new Uint8Array(await res.arrayBuffer()); + const responseHeaders: Record = {}; + res.headers.forEach((v, k) => { + responseHeaders[k] = v; + }); + try { + const settleResult = await httpServer.processSettlement( + paymentPayload, + paymentRequirements, + declaredExtensions, + { request: context, responseBody, responseHeaders }, + undefined, + beforeHandlerSettlement, + ); + if (!settleResult.success) return instructionsToResponse(settleResult.response); + const out = mutable(res, responseBody ?? res.body); + setHeaders(out, settleResult.headers); + out.headers.set('Cache-Control', withPrivateCacheControl(out.headers.get('Cache-Control'))); + out.headers.delete(SETTLEMENT_OVERRIDES_HEADER); + return out; + } catch (error) { + if (error instanceof FacilitatorResponseError) return facilitatorErrorResponse(error); + console.error(error); + return jsonResponse({ error: 'settlement_error' }, 402); + } + }; + + const handler = handle as PaymentHandler; + Object.defineProperties(handler, { + radius: { value: radius, enumerable: true }, + wrap: { value: (next: NextHandler) => (request: Request) => handle(request, next), enumerable: true }, + requiresPayment: { value: (request: Request) => httpServer.requiresPayment(requestContext(request)), enumerable: true }, + }); + return handler; +} diff --git a/packages/sdk/src/hono/scheme.ts b/packages/sdk/src/server/scheme.ts similarity index 100% rename from packages/sdk/src/hono/scheme.ts rename to packages/sdk/src/server/scheme.ts diff --git a/packages/sdk/test/e2e/server.test.ts b/packages/sdk/test/e2e/server.test.ts new file mode 100644 index 0000000..260d10d --- /dev/null +++ b/packages/sdk/test/e2e/server.test.ts @@ -0,0 +1,48 @@ +/** + * End-to-end for the web-standard handler against the real Radius facilitator: the + * seller is `radiusPayments()` from `radius-sdk/server` called directly with a + * `Request`, the buyer is `createRadiusFetch`. Same env as settlement.test.ts. + */ +import { beforeAll, describe, expect, it } from 'vitest'; +import { privateKeyToAccount } from 'viem/accounts'; +import { radiusPayments } from '../../src/server/index.js'; +import { createRadiusFetch } from '../../src/client/index.js'; +import { getPaymentReceipt } from '../../src/receipt.js'; +import { resolveNetwork } from '../../src/networks.js'; + +const NET = (process.env.RADIUS_NETWORK ?? 'testnet') as 'mainnet' | 'testnet'; +const network = resolveNetwork(NET); +const KEY = process.env.RADIUS_PRIVATE_KEY as `0x${string}` | undefined; +const run = process.env.RADIUS_E2E && KEY ? describe : describe.skip; + +run(`${NET} e2e (web-standard handler)`, () => { + const payer = privateKeyToAccount(KEY!); + const PAY_TO = (process.env.PAY_TO as `0x${string}`) ?? payer.address; + const settled: { tx?: string; path: string }[] = []; + const pay = radiusPayments({ + network: NET, + payTo: PAY_TO, + routes: { 'GET /api/lookup': '$0.001' }, + onSettled: (r, request) => { settled.push({ tx: r.transaction, path: new URL(request.url).pathname }); }, + }); + const app = pay.wrap((_request, payment) => Response.json({ ok: true, payer: payment?.payer, tx: payment?.transaction })); + const serverFetch: typeof fetch = (input, init) => app(new Request(input, init)); + const buyer = createRadiusFetch({ network: NET, signer: KEY!, maxPerRequest: '$0.01', fetch: serverFetch }); + + beforeAll(async () => { + const { atomic } = await buyer.balance(); + expect(atomic, `payer needs at least 0.001 SBC on ${NET}`).toBeGreaterThanOrEqual(1000n); + }); + + it('pays a lookup with real settlement; the handler and onSettled both see the receipt', async () => { + const res = await buyer('http://seller.test/api/lookup'); + expect(res.status).toBe(200); + const body = (await res.json()) as { ok: boolean; payer: string; tx: string }; + expect(body.ok).toBe(true); + expect(body.payer).toBe(payer.address); + expect(body.tx).toMatch(/^0x[0-9a-f]{64}$/); + const receipt = getPaymentReceipt(res, buyer.network)!; + expect(receipt).toMatchObject({ success: true, transaction: body.tx, network: network.network }); + expect(settled).toEqual([{ tx: body.tx, path: '/api/lookup' }]); + }, 60_000); +}); diff --git a/packages/sdk/test/server.test.ts b/packages/sdk/test/server.test.ts new file mode 100644 index 0000000..36f0ec7 --- /dev/null +++ b/packages/sdk/test/server.test.ts @@ -0,0 +1,364 @@ +import { afterEach, describe, expect, it, vi } from 'vitest'; +import { decodePaymentRequiredHeader, encodePaymentSignatureHeader } from '@x402/core/http'; +import { createRadiusServer, radiusPayments, requestOf, type PaymentHandler } from '../src/server/index.js'; +import { getPaymentReceipt } from '../src/receipt.js'; + +const PAY_TO = '0x1eF420190c299D4d133fE9227F780D7d5cE91BeE'; + +function makeHandler(opts: Partial[0]> = {}) { + return radiusPayments({ + network: 'testnet', + payTo: PAY_TO, + facilitator: { live: false }, + routes: { + 'GET /api/lookup': { price: '$0.001', description: 'Lookup' }, + 'POST /api/query': '0.01', + 'GET /api/atomic': { price: { amount: '42' } }, + }, + ...opts, + }); +} + +/** A minimal app: free `/health`, paid `/api/*`, echoing the receipt the handler received. */ +function makeApp(pay: PaymentHandler) { + return pay.wrap((request, payment) => { + const { pathname } = new URL(request.url); + if (pathname === '/health') return Response.json({ ok: true }); + if (pathname === '/api/lookup') return Response.json({ data: 'secret', payment }); + if (pathname === '/api/fail') return Response.json({ error: 'nope' }, { status: 500 }); + if (pathname === '/api/throw') throw new Error('boom'); + return Response.json({ data: pathname }); + }); +} + +afterEach(() => vi.restoreAllMocks()); + +async function payloadFor(app: (r: Request) => Promise, url = 'http://seller.test/api/lookup') { + const challenge = await app(new Request(url)); + const pr = decodePaymentRequiredHeader(challenge.headers.get('payment-required')!); + const accepted = pr.accepts[0]; + const { paymentFlow: _pf, ...extra } = accepted.extra as Record; + return encodePaymentSignatureHeader({ + x402Version: 2, + resource: pr.resource, + accepted: { ...accepted, extra }, + payload: { signature: '0xsig', permit2Authorization: {} }, + }); +} + +function mockFacilitator(settle: { success: boolean; transaction?: string; errorReason?: string }) { + const calls: string[] = []; + vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => { + const url = String(input instanceof Request ? input.url : input); + calls.push(url); + if (url.endsWith('/verify')) return Response.json({ isValid: true, payer: '0xabc' }); + if (url.endsWith('/settle')) return Response.json({ success: settle.success, transaction: settle.transaction ?? '', network: 'eip155:72344', payer: '0xabc', errorReason: settle.errorReason }); + throw new Error(`unexpected fetch ${url}`); + }); + return calls; +} + +describe('radiusPayments (web-standard handler): 402 challenge', () => { + it('leaves unprotected routes alone and reports requiresPayment without I/O', async () => { + const pay = makeHandler(); + const res = await makeApp(pay)(new Request('http://seller.test/health')); + expect(res.status).toBe(200); + expect(pay.requiresPayment(new Request('http://seller.test/health'))).toBe(false); + expect(pay.requiresPayment(new Request('http://seller.test/api/lookup'))).toBe(true); + expect(pay.requiresPayment(new Request('http://seller.test/api/lookup', { method: 'POST' }))).toBe(false); + }); + + it('returns a standard x402 v2 challenge for SBC via Permit2 with gas sponsoring declared', async () => { + const res = await makeHandler()(new Request('http://seller.test/api/lookup?q=1'), () => Response.json({ leaked: true })); + expect(res.status).toBe(402); + expect(res.headers.get('content-type')).toContain('application/json'); + const pr = decodePaymentRequiredHeader(res.headers.get('payment-required')!); + expect(pr.x402Version).toBe(2); + expect(pr.resource.url).toBe('http://seller.test/api/lookup?q=1'); + expect(pr.resource.description).toBe('Lookup'); + expect(pr.accepts[0]).toMatchObject({ + scheme: 'exact', + network: 'eip155:72344', + amount: '1000', + asset: '0x33ad9e4BD16B69B5BFdED37D8B5D9fF9aba014Fb', + payTo: PAY_TO, + maxTimeoutSeconds: 300, + extra: { assetTransferMethod: 'permit2', name: 'Stable Coin', version: '1', paymentFlow: 'upfront' }, + }); + expect(pr.extensions).toHaveProperty('eip2612GasSponsoring'); + expect(await res.text()).not.toContain('leaked'); + }); + + it('supports shorthand and atomic prices', async () => { + const app = makeApp(makeHandler()); + const post = await app(new Request('http://seller.test/api/query', { method: 'POST' })); + expect(decodePaymentRequiredHeader(post.headers.get('payment-required')!).accepts[0].amount).toBe('10000'); + const atomic = await app(new Request('http://seller.test/api/atomic')); + expect(decodePaymentRequiredHeader(atomic.headers.get('payment-required')!).accepts[0].amount).toBe('42'); + }); + + it('resolves payTo and price dynamically from the Request', async () => { + const pay = radiusPayments({ + network: 'testnet', + facilitator: { live: false }, + payTo: (request) => request.headers.get('x-pay-to') as `0x${string}`, + routes: { 'GET /p': { price: (request) => `$${new URL(request.url).searchParams.get('n')}` } }, + }); + const res = await pay(new Request('http://seller.test/p?n=2', { headers: { 'x-pay-to': PAY_TO } }), () => new Response('x')); + const accepted = decodePaymentRequiredHeader(res.headers.get('payment-required')!).accepts[0]; + expect(accepted.payTo).toBe(PAY_TO); + expect(accepted.amount).toBe('2000000'); + }); + + it('serves browsers an HTML paywall page', async () => { + const res = await makeHandler()(new Request('http://seller.test/api/lookup', { headers: { accept: 'text/html', 'user-agent': 'Mozilla/5.0' } }), () => new Response('x')); + expect(res.status).toBe(402); + expect(res.headers.get('content-type')).toContain('text/html'); + }); +}); + +describe('radiusPayments (web-standard handler): paid flow (facilitator mocked)', () => { + it('settles before the handler, passes the receipt to it, and attaches PAYMENT-RESPONSE', async () => { + const calls = mockFacilitator({ success: true, transaction: '0xdeadbeef' }); + const settled: { receipt: unknown; url: string }[] = []; + const app = makeApp(makeHandler({ onSettled: (receipt, request) => { settled.push({ receipt, url: request.url }); } })); + const sig = await payloadFor(app); + const res = await app(new Request('http://seller.test/api/lookup', { headers: { 'PAYMENT-SIGNATURE': sig } })); + expect(res.status).toBe(200); + const body = (await res.json()) as { data: string; payment: { transaction: string; amount: string } }; + expect(body.data).toBe('secret'); + expect(body.payment).toMatchObject({ success: true, transaction: '0xdeadbeef', amount: '1000', payer: '0xabc' }); + expect(calls.filter((u) => u.endsWith('/verify'))).toHaveLength(0); + expect(calls.filter((u) => u.endsWith('/settle'))).toHaveLength(1); + expect(getPaymentReceipt(res)).toMatchObject({ success: true, transaction: '0xdeadbeef', network: 'eip155:72344' }); + expect(res.headers.get('cache-control')).toContain('private'); + expect(settled).toEqual([{ receipt: expect.objectContaining({ transaction: '0xdeadbeef' }), url: 'http://seller.test/api/lookup' }]); + }); + + it('settle: "after" runs the handler first, then settles; the handler sees no receipt', async () => { + const calls = mockFacilitator({ success: true, transaction: '0xafter' }); + const seen: unknown[] = []; + const app = makeHandler({ settle: 'after' }).wrap((_r, payment) => { + seen.push(payment); + return Response.json({ ok: true }); + }); + const sig = await payloadFor(app); + const res = await app(new Request('http://seller.test/api/lookup', { headers: { 'PAYMENT-SIGNATURE': sig } })); + expect(res.status).toBe(200); + expect(seen).toEqual([undefined]); + expect(calls.filter((u) => u.endsWith('/verify'))).toHaveLength(1); + expect(calls.filter((u) => u.endsWith('/settle'))).toHaveLength(1); + expect(getPaymentReceipt(res)?.transaction).toBe('0xafter'); + }); + + it('withholds the resource when settlement fails and does not call onSettled', async () => { + mockFacilitator({ success: false, errorReason: 'insufficient_funds' }); + const settled: unknown[] = []; + const app = makeApp(makeHandler({ onSettled: (r) => { settled.push(r); } })); + const sig = await payloadFor(app); + const res = await app(new Request('http://seller.test/api/lookup', { headers: { 'PAYMENT-SIGNATURE': sig } })); + expect(res.status).toBe(402); + expect(await res.text()).not.toContain('secret'); + expect(settled).toHaveLength(0); + }); + + it('rejects a malformed payment header without calling the facilitator', async () => { + const calls = mockFacilitator({ success: true }); + const res = await makeApp(makeHandler())(new Request('http://seller.test/api/lookup', { headers: { 'PAYMENT-SIGNATURE': 'not-base64-json' } })); + expect(res.status).toBe(402); + expect(calls).toHaveLength(0); + }); + + it('streams the handler response through in settle-before mode', async () => { + mockFacilitator({ success: true, transaction: '0xstream' }); + let release!: () => void; + const gate = new Promise((r) => { release = r; }); + const app = makeHandler().wrap(() => { + const stream = new ReadableStream({ + async start(controller) { + controller.enqueue(new TextEncoder().encode('first,')); + await gate; + controller.enqueue(new TextEncoder().encode('second')); + controller.close(); + }, + }); + return new Response(stream, { headers: { 'content-type': 'text/event-stream' } }); + }); + const sig = await payloadFor(app); + const res = await app(new Request('http://seller.test/api/lookup', { headers: { 'PAYMENT-SIGNATURE': sig } })); + expect(res.status).toBe(200); + expect(getPaymentReceipt(res)?.transaction).toBe('0xstream'); + // The response (and its first chunk) arrive while the handler is still producing the rest. + const reader = res.body!.getReader(); + const first = await reader.read(); + expect(new TextDecoder().decode(first.value)).toBe('first,'); + release(); + const second = await reader.read(); + expect(new TextDecoder().decode(second.value)).toBe('second'); + expect((await reader.read()).done).toBe(true); + }); + + it('handles responses with immutable headers (e.g. proxied from fetch)', async () => { + mockFacilitator({ success: true, transaction: '0x1' }); + const pay = makeHandler(); + const app = pay.wrap(async () => { + const upstream = new Response('proxied', { headers: { 'x-upstream': '1' } }); + // Simulate `fetch()`'s immutable headers guard. + Object.defineProperty(upstream, 'headers', { value: new Proxy(upstream.headers, { get: (t, k) => (k === 'set' || k === 'delete' ? () => { throw new TypeError('immutable'); } : Reflect.get(t, k).bind(t)) }) }); + return upstream; + }); + const sig = await payloadFor(app); + const res = await app(new Request('http://seller.test/api/lookup', { headers: { 'PAYMENT-SIGNATURE': sig } })); + expect(res.status).toBe(200); + expect(await res.text()).toBe('proxied'); + expect(res.headers.get('x-upstream')).toBe('1'); + expect(getPaymentReceipt(res)?.transaction).toBe('0x1'); + }); + + it('returns the handler error with the settlement receipt when a paid handler fails', async () => { + mockFacilitator({ success: true, transaction: '0x2' }); + const app = makeApp(makeHandler({ routes: { 'GET /api/fail': '$0.001', 'GET /api/throw': '$0.001' } })); + const sig = await payloadFor(app, 'http://seller.test/api/fail'); + const failed = await app(new Request('http://seller.test/api/fail', { headers: { 'PAYMENT-SIGNATURE': sig } })); + expect(failed.status).toBe(500); + expect(getPaymentReceipt(failed)?.transaction).toBe('0x2'); + const sig2 = await payloadFor(app, 'http://seller.test/api/throw'); + const threw = await app(new Request('http://seller.test/api/throw', { headers: { 'PAYMENT-SIGNATURE': sig2 } })); + expect(threw.status).toBe(500); + expect(await threw.json()).toMatchObject({ error: 'payment_processing_error', message: 'boom' }); + expect(getPaymentReceipt(threw)?.transaction).toBe('0x2'); + }); +}); + +describe('radiusPayments (web-standard handler) when the facilitator gives no answer', () => { + function mockFacilitator(respond: (path: 'verify' | 'settle') => Response | Promise) { + vi.spyOn(globalThis, 'fetch').mockImplementation(async (input) => { + const url = String(input instanceof Request ? input.url : input); + if (url.endsWith('/verify')) return respond('verify'); + if (url.endsWith('/settle')) return respond('settle'); + throw new Error(`unexpected fetch ${url}`); + }); + } + const gatewayTimeout = () => new Response('504 Gateway Time-out', { status: 504, headers: { 'content-type': 'text/html' } }); + const verified = () => Response.json({ isValid: true, payer: '0xabc' }); + + async function pay(app: (r: Request) => Promise) { + const sig = await payloadFor(app); + return app(new Request('http://seller.test/api/lookup', { headers: { 'PAYMENT-SIGNATURE': sig } })); + } + + it('answers 502 when settle returns an error page', async () => { + mockFacilitator(gatewayTimeout); + const res = await pay(makeApp(makeHandler())); + expect(res.status).toBe(502); + expect(await res.json()).toMatchObject({ error: 'facilitator_error' }); + }); + + it('answers 502 when the settle connection fails', async () => { + mockFacilitator(() => { + throw new TypeError('fetch failed'); + }); + const res = await pay(makeApp(makeHandler())); + expect(res.status).toBe(502); + expect(await res.text()).not.toContain('secret'); + }); + + it('answers 502 when settle fails after the handler (settle: "after")', async () => { + mockFacilitator((path) => (path === 'verify' ? verified() : gatewayTimeout())); + const res = await pay(makeApp(makeHandler({ settle: 'after' }))); + expect(res.status).toBe(502); + expect(await res.text()).not.toContain('secret'); + }); + + it('answers 502 when verify returns an error page (settle: "after")', async () => { + mockFacilitator(gatewayTimeout); + const res = await pay(makeApp(makeHandler({ settle: 'after' }))); + expect(res.status).toBe(502); + }); + + it("keeps 402 for the facilitator's own settle rejection", async () => { + mockFacilitator(() => Response.json({ success: false, errorReason: 'insufficient_funds', transaction: '', network: 'eip155:72344' }, { status: 400 })); + const res = await pay(makeApp(makeHandler())); + expect(res.status).toBe(402); + }); +}); + +describe('createRadiusServer', () => { + it('builds upstream-compatible routes and a resource server that answers 402s through @x402/express', async () => { + const { paymentMiddleware } = await import('@x402/express'); + const express = (await import('express')).default; + const seen: string[] = []; + const radius = createRadiusServer({ network: 'testnet', facilitator: { live: false }, onSettled: (r, ctx) => { seen.push(`${r.transaction}:${requestOf(ctx) ? 'request' : 'express'}`); } }); + const app = express(); + app.use(paymentMiddleware(radius.routes({ payTo: PAY_TO, routes: { 'GET /api/lookup': '$0.001' } }), radius.server)); + app.get('/api/lookup', (_req, res) => { res.json({ data: 'secret' }); }); + const server = app.listen(0); + const port = (server.address() as { port: number }).port; + const base = `http://127.0.0.1:${port}`; + try { + const challenge = await fetch(`${base}/api/lookup`); + expect(challenge.status).toBe(402); + const pr = decodePaymentRequiredHeader(challenge.headers.get('payment-required')!); + expect(pr.accepts[0]).toMatchObject({ scheme: 'exact', network: 'eip155:72344', amount: '1000', payTo: PAY_TO, extra: { assetTransferMethod: 'permit2', paymentFlow: 'upfront' } }); + expect(pr.extensions).toHaveProperty('eip2612GasSponsoring'); + + const realFetch = globalThis.fetch; + vi.spyOn(globalThis, 'fetch').mockImplementation(async (input, init) => { + const url = String(input instanceof Request ? input.url : input); + if (url.endsWith('/settle')) return Response.json({ success: true, transaction: '0xexpress', network: 'eip155:72344', payer: '0xabc' }); + return realFetch(input, init); + }); + const accepted = pr.accepts[0]; + const { paymentFlow: _pf, ...extra } = accepted.extra as Record; + const sig = encodePaymentSignatureHeader({ x402Version: 2, resource: pr.resource, accepted: { ...accepted, extra }, payload: { signature: '0xsig', permit2Authorization: {} } }); + const paid = await fetch(`${base}/api/lookup`, { headers: { 'PAYMENT-SIGNATURE': sig } }); + expect(paid.status).toBe(200); + expect(await paid.json()).toEqual({ data: 'secret' }); + expect(getPaymentReceipt(paid)?.transaction).toBe('0xexpress'); + expect(seen).toEqual(['0xexpress:express']); + } finally { + server.close(); + } + }); + + it('settle: "after" and failed handlers behave the same through @x402/express', async () => { + const { paymentMiddleware } = await import('@x402/express'); + const express = (await import('express')).default; + const seen: string[] = []; + const radius = createRadiusServer({ network: 'testnet', facilitator: { live: false }, settle: 'after', onSettled: (r) => { seen.push(r.transaction!); } }); + const app = express(); + app.use(paymentMiddleware(radius.routes({ payTo: PAY_TO, routes: { 'GET /api/lookup': '$0.001', 'GET /api/fail': '$0.001' } }), radius.server)); + app.get('/api/lookup', (_req, res) => { res.json({ data: 'secret' }); }); + app.get('/api/fail', (_req, res) => { res.status(500).json({ error: 'nope' }); }); + const server = app.listen(0); + const base = `http://127.0.0.1:${(server.address() as { port: number }).port}`; + const realFetch = globalThis.fetch; + const facilitatorCalls: string[] = []; + vi.spyOn(globalThis, 'fetch').mockImplementation(async (input, init) => { + const url = String(input instanceof Request ? input.url : input); + if (url.endsWith('/verify')) { facilitatorCalls.push('verify'); return Response.json({ isValid: true, payer: '0xabc' }); } + if (url.endsWith('/settle')) { facilitatorCalls.push('settle'); return Response.json({ success: true, transaction: '0xafter', network: 'eip155:72344', payer: '0xabc' }); } + return realFetch(input, init); + }); + const payloadFor = async (path: string) => { + const pr = decodePaymentRequiredHeader((await fetch(`${base}${path}`)).headers.get('payment-required')!); + expect(pr.accepts[0].extra).not.toHaveProperty('paymentFlow'); + return encodePaymentSignatureHeader({ x402Version: 2, resource: pr.resource, accepted: pr.accepts[0], payload: { signature: '0xsig', permit2Authorization: {} } }); + }; + try { + const paid = await fetch(`${base}/api/lookup`, { headers: { 'PAYMENT-SIGNATURE': await payloadFor('/api/lookup') } }); + expect(paid.status).toBe(200); + expect(getPaymentReceipt(paid)?.transaction).toBe('0xafter'); + expect(facilitatorCalls).toEqual(['verify', 'settle']); + expect(seen).toEqual(['0xafter']); + + const failed = await fetch(`${base}/api/fail`, { headers: { 'PAYMENT-SIGNATURE': await payloadFor('/api/fail') } }); + expect(failed.status).toBe(500); + // Verified but never settled: the handler failed first, so no funds moved. + expect(facilitatorCalls).toEqual(['verify', 'settle', 'verify']); + expect(seen).toEqual(['0xafter']); + } finally { + server.close(); + } + }); +}); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 6dcd1ce..34b2c62 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -28,7 +28,7 @@ importers: version: link:../sdk viem: specifier: ^2.21.0 - version: 2.56.5(typescript@5.9.3)(zod@3.25.76) + version: 2.56.5(typescript@5.9.3)(zod@4.6.5) devDependencies: '@types/node': specifier: ^22.0.0 @@ -38,16 +38,16 @@ importers: version: 5.9.3 vitest: specifier: ^2.1.0 - version: 2.1.9(@types/node@22.20.3) + version: 2.1.9(@types/node@22.20.3)(lightningcss@1.33.0) packages/sdk: dependencies: '@x402/core': - specifier: 2.25.0 - version: 2.25.0 + specifier: 2.27.0 + version: 2.27.0 '@x402/evm': - specifier: 2.25.0 - version: 2.25.0(typescript@5.9.3) + specifier: 2.27.0 + version: 2.27.0(typescript@5.9.3) devDependencies: '@cloudflare/workers-types': specifier: ^5.20260910.1 @@ -61,6 +61,15 @@ importers: '@ethereumjs/util': specifier: 10.1.3 version: 10.1.3 + '@types/express': + specifier: ^5.0.6 + version: 5.0.6 + '@x402/express': + specifier: 2.27.0 + version: 2.27.0(ethers@6.17.0)(express@5.2.1)(typescript@5.9.3) + express: + specifier: ^5.2.1 + version: 5.2.1 hono: specifier: ^4.13.7 version: 4.13.8 @@ -69,13 +78,13 @@ importers: version: 5.9.3 viem: specifier: ^2.48.11 - version: 2.56.5(typescript@5.9.3)(zod@3.25.76) + version: 2.56.5(typescript@5.9.3)(zod@4.6.5) vitest: specifier: ^3.2.0 - version: 3.2.7(@types/node@22.20.3) + version: 3.2.7(@types/node@24.19.0)(lightningcss@1.33.0) wrangler: specifier: ^4.131.0 - version: 4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@22.20.3) + version: 4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@24.19.0) packages/sdk/examples/agent-buyer: dependencies: @@ -87,7 +96,26 @@ importers: version: link:../.. viem: specifier: ^2.48.11 - version: 2.56.5(typescript@5.9.3)(zod@3.25.76) + version: 2.56.5(typescript@5.9.3)(zod@4.6.5) + + packages/sdk/examples/astro-seller: + dependencies: + '@astrojs/node': + specifier: ^11.1.7 + version: 11.1.7(astro@7.3.6(@types/node@24.19.0)(yaml@2.9.1)) + astro: + specifier: ^7.3.6 + version: 7.3.6(@types/node@24.19.0)(yaml@2.9.1) + radius-sdk: + specifier: workspace:* + version: link:../.. + devDependencies: + '@astrojs/check': + specifier: ^0.9.6 + version: 0.9.10(@emnapi/runtime@1.11.3)(prettier@3.9.9)(typescript@5.9.3) + typescript: + specifier: ^5.9.0 + version: 5.9.3 packages/sdk/examples/demo-dapp: dependencies: @@ -99,7 +127,7 @@ importers: version: link:../.. viem: specifier: ^2.48.11 - version: 2.56.5(typescript@5.9.3)(zod@3.25.76) + version: 2.56.5(typescript@5.9.3)(zod@4.6.5) devDependencies: '@cloudflare/workers-types': specifier: ^5.20260910.1 @@ -112,7 +140,45 @@ importers: version: 5.9.3 wrangler: specifier: ^4.131.0 - version: 4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@22.20.3) + version: 4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@24.19.0) + + packages/sdk/examples/express-seller: + dependencies: + '@x402/express': + specifier: 2.27.0 + version: 2.27.0(ethers@6.17.0)(express@5.2.1)(typescript@5.9.3) + express: + specifier: ^5.2.1 + version: 5.2.1 + radius-sdk: + specifier: workspace:* + version: link:../.. + devDependencies: + '@types/express': + specifier: ^5.0.6 + version: 5.0.6 + '@types/node': + specifier: ^24.0.0 + version: 24.19.0 + typescript: + specifier: ^5.9.0 + version: 5.9.3 + + packages/sdk/examples/worker-plain: + dependencies: + radius-sdk: + specifier: workspace:* + version: link:../.. + devDependencies: + '@cloudflare/workers-types': + specifier: ^5.20260910.1 + version: 5.20260915.1 + typescript: + specifier: ^5.9.0 + version: 5.9.3 + wrangler: + specifier: ^4.131.0 + version: 4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@24.19.0) packages/sdk/examples/worker-seller: dependencies: @@ -131,13 +197,198 @@ importers: version: 5.9.3 wrangler: specifier: ^4.131.0 - version: 4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@22.20.3) + version: 4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@24.19.0) packages: '@adraffy/ens-normalize@1.11.1': resolution: {integrity: sha512-nhCBV3quEgesuf7c7KYfperqSS14T8bYuvJ8PcLJp6znkZpFc0AuW4qBtr8eKVyPPe/8RSr7sglCWPU5eaxwKQ==} + '@astrojs/astro2tsx@0.1.2': + resolution: {integrity: sha512-Uj/M9zbrhu5cIZEvWAGTbQJRKSxXWJ/E59BZwt7F+chrKhbfttW+9rkS/l+1QxoJP1KU3UnpM62M7yszfAI0WA==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@astrojs/check@0.9.10': + resolution: {integrity: sha512-zgx/UQMozdjOa3bOxjgeCFdtpE3c9rRX6xHwa+2QXvy8z8Akifu2AtubHyv/zzC2znO8dl8fFWL4K+Ba9kS8HQ==} + hasBin: true + peerDependencies: + typescript: ^5.0.0 || ^6.0.0 + + '@astrojs/compiler-binding-android-arm64@0.5.1': + resolution: {integrity: sha512-nMb2nMIJtcWLNH+fV75Enmi+jp4tIOYOfsv4XtpgdOWkqc9P4uSSdK5u1xb340AzrXo5V18SxLl/nc3vcqtamQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@astrojs/compiler-binding-darwin-arm64@0.5.1': + resolution: {integrity: sha512-5k4+nZ/WRt+dcVow4z7rBuI7iv9A58h/uQ91YJe1PrTivbcCkq3u2Ynx/AZJwII4CsZawBCeGpojkFjutZBhBQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@astrojs/compiler-binding-darwin-x64@0.5.1': + resolution: {integrity: sha512-0Buw+YST9Ff2EqQyhRMQujuFq/dijLw3zXWhsvI0dJ2pGrT38iVoxTEca2eBX/PfhlwkVWSRJEKO5gMqKHyeHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@astrojs/compiler-binding-linux-arm64-gnu@0.5.1': + resolution: {integrity: sha512-x5LRpyCoMKuu3INr18cn42YhwSOaRpp9b5Ny3eJJ/sWVeejC16Zeshu1JlvlSmEZACLeWxU5JM0RX6T6nI+YyA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@astrojs/compiler-binding-linux-arm64-musl@0.5.1': + resolution: {integrity: sha512-mL7tQEuDk3rGfaKmrO63nw6WBy1TPVioQGmVyjcAr+C+a/k3SVMYBytNSMqH9mZPT/Swj30JaZ2N842Z1NnOEQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@astrojs/compiler-binding-linux-x64-gnu@0.5.1': + resolution: {integrity: sha512-uLGc9jtxwiDe4cQyhNPQim4ECiB/YzbWlXssfLAv8r374kArfTwBHjwR2+j+XVyF71yCx5mF9YNRclRqdNBgeg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@astrojs/compiler-binding-linux-x64-musl@0.5.1': + resolution: {integrity: sha512-G0cywinaQUc8v1MrytvYKUX7svTDMmYtOCZfxjwKPbJi59zIqM+Ll0rWgO0GQWLZH3XoPYo19ZwlP3Xt9ep9YA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@astrojs/compiler-binding-wasm32-wasi@0.5.1': + resolution: {integrity: sha512-yMhLL8asmLydoAdnEZxAw6eLfNDs3YJl6jqn0pjPt6zrb2U5qIDLnii4/twThpIFODKkQ6YDpBRTOz/vSfZCxw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [wasm32] + + '@astrojs/compiler-binding-win32-arm64-msvc@0.5.1': + resolution: {integrity: sha512-aClIG6poFt3Wf/bZykrEAX2nAnKvBHW6RXiKUa69QjBtWH0/FOlOAjnFcxRNlhej2AMWNYFx0o+LGjwMcH8P7Q==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@astrojs/compiler-binding-win32-x64-msvc@0.5.1': + resolution: {integrity: sha512-/E6uBCagY70YpWqssBC+/FuniNSloeQPRgj7l3LDWiqjxIyTLnIgX1sTt18FU7jrigetpSnC9cHAM6b6IxSgPw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@astrojs/compiler-binding@0.5.1': + resolution: {integrity: sha512-oczyolLUl9mNrtuBuNjuvn5thpHrFLXAHAWGTRg0JDHQ8cGVsVeFekOu2uSoQGgainJIi+A3/9m0DyYwz3Nlnw==} + engines: {node: ^20.19.0 || >=22.12.0} + + '@astrojs/compiler-rs@0.5.1': + resolution: {integrity: sha512-1k1acnX7DepIiea9U9/Y+d1hdAFfylu1ZQQkkYgRSwBOBAsXInolyZuh/2tax+83vu/A+hOYP6P3+265RvMTvw==} + engines: {node: '>=22.12.0'} + + '@astrojs/internal-helpers@0.12.0': + resolution: {integrity: sha512-pKPuwCDtO0L7zgmt1JGd9X4Aes1+0SX3IEBSqBNPHsScYdPMlfmed3Y7DTbXyF7E+8ylnb563o/0OzGQPOFehw==} + + '@astrojs/language-server@2.17.1': + resolution: {integrity: sha512-gG7bvMVNIXgoSe1pM9dI1HsSDLU1EIc/dSAYQ0DuReLyLkOBjsiqvaRYgQltWaldLxh0bNEqjgreLfjd9OnUxQ==} + hasBin: true + peerDependencies: + prettier: ^3.0.0 + prettier-plugin-astro: '>=0.11.0' + peerDependenciesMeta: + prettier: + optional: true + prettier-plugin-astro: + optional: true + + '@astrojs/markdown-satteri@0.4.3': + resolution: {integrity: sha512-PFbEHPnwUlLvpXd7RXrrKM+j12akF4bG+DSuNuoN+3eiwjOwp4HaPi+QQdbkBV7QEYXmzyKca50OJsmGxhNIUA==} + + '@astrojs/node@11.1.7': + resolution: {integrity: sha512-IXmBthgAMuYSTcOeIM20CpHrUkYxYhI3uJW0b9jOiaZtCXquFinstQ0WWZnYaA1kzCfgSkjmISKkEH6fwDPmbg==} + peerDependencies: + astro: ^7.2.1 + + '@astrojs/prism@4.0.2': + resolution: {integrity: sha512-KTivpmnz6lDsC6o9H4+DNm2SrE/GHzw8cNAvEJwAvUT+eoaEnn/4NtbDNfRRaxaJHdp15gf+tfHAWiXR4wB3BA==} + engines: {node: '>=22.12.0'} + + '@astrojs/telemetry@3.3.3': + resolution: {integrity: sha512-C1TLn5sPJr0x4vk56piHWKbnqlEB8BKyte5Y45V02U+D7BGO5eMqZDH5aPjnkXQWJggvmsTXxH03QMZ9NgWLzQ==} + engines: {node: 18.20.8 || ^20.3.0 || >=22.0.0} + + '@astrojs/yaml2ts@0.2.4': + resolution: {integrity: sha512-8oddpOae35pJsXPQXhTkM0ypfKPskVsh2bCxRtbf7e+/Epw2nReakFYpLKjZMEr75CsoF203PMnCocpfz0s69A==} + + '@babel/helper-string-parser@7.29.7': + resolution: {integrity: sha512-Pb5ijPrZ89GDH8223L4UP8i6QApWxs04RbPQJTeWDV0/keR2E36MeKnyr6LYmUUvqRRI+Iv87SuF1W6ErINzYw==} + engines: {node: '>=6.9.0'} + + '@babel/helper-validator-identifier@7.29.7': + resolution: {integrity: sha512-qehxGkRj55h/ff8EMaJ+cYhyaKlHIxqYDn682wQD7RNp9UujOQsHog2uS0r2vzr4pW+sXf90NeeayjcNaX3fFg==} + engines: {node: '>=6.9.0'} + + '@babel/parser@7.29.9': + resolution: {integrity: sha512-CjXrNHTnvqBVqHgdBysY3vk2T8tpJHb5/RMeHJBTyVa9xgugCB0CJTx/3oO8RV2QRQP391RWpB7D6hLjm8V9uA==} + engines: {node: '>=6.0.0'} + hasBin: true + + '@babel/types@7.29.8': + resolution: {integrity: sha512-Vj1jF3cPfxg7OAfoI7QnVKLoILlm2JF9pnVHrX8qx7AHMiYWT+NDAA7jChlNgRS4WTLc/fD1lXLmPixluj+3Gg==} + engines: {node: '>=6.9.0'} + + '@bruits/satteri-darwin-arm64@0.10.5': + resolution: {integrity: sha512-27KTVl4TJkVahMy/ohyA7qd4938G5UNneFUz/PsScYfpIhj0IVAS23mpcJXdPF44sa6nva198lmV/cKIb2YPyA==} + cpu: [arm64] + os: [darwin] + + '@bruits/satteri-darwin-x64@0.10.5': + resolution: {integrity: sha512-IjnLe3nKspq6qaeqGgjT7MT8VrTV74yWRlaag7ZdNsI8TDAYZ0iPxMCo+9KQZHUk5EyVB+reBI/PFWL5KuFw9Q==} + cpu: [x64] + os: [darwin] + + '@bruits/satteri-linux-arm64-gnu@0.10.5': + resolution: {integrity: sha512-glkYXZCJywjP13v67eAyAMSJdF+ncvEbYvgi/wOtffL9tQ27lr/zsyzUfgs+ovjJ9d8JNQKiXeiArJcX8PJL9w==} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@bruits/satteri-linux-arm64-musl@0.10.5': + resolution: {integrity: sha512-yWdgG1g17Nh2QyGVlFUxGRa3FEFwiMcpZEyMNWkbM3deC94cmVc+/i9OuyFpdKuWo3GkgoCtYVOoxk1uCnCZIA==} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@bruits/satteri-linux-x64-gnu@0.10.5': + resolution: {integrity: sha512-FVaLoPT1fBgGl0J+AYebyyXJYBachGl8Oyyrf1lye4RTqCB4S0Gwkj1uM9RJyThUOvx5VUmAT1CnNh1SFHA+kw==} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@bruits/satteri-linux-x64-musl@0.10.5': + resolution: {integrity: sha512-EHpVAx2bqW3GINHTKkljtxVfQmVDGWIuwOYOP5YghTj+0PkBa2o8oKPRtQ9Kbsr1Fye8jtUcDjhwj2jMNugZKg==} + cpu: [x64] + os: [linux] + libc: [musl] + + '@bruits/satteri-wasm32-wasi@0.10.5': + resolution: {integrity: sha512-ypz8c/Zmipxp4IoeDa228Gstv6TLzVmNs3yC6wKCoNSOjx1iwpgzu87Y3hTkXFdwChVGU85qeUDuOIarGUZQLw==} + engines: {node: '>=14.0.0'} + cpu: [wasm32] + + '@bruits/satteri-win32-arm64-msvc@0.10.5': + resolution: {integrity: sha512-siTV88nb0LRqNpkL2gXboqCwVdq95sLtzMHS1/3eONV2gLbB3NAK46wmSMvCO/yquBvI2lvaFIfd8P12ecsxBw==} + cpu: [arm64] + os: [win32] + + '@bruits/satteri-win32-x64-msvc@0.10.5': + resolution: {integrity: sha512-C3IfPvfvMXmlzBxaMPKFS1XiuV9pu2mC7YqkPk7PSvTgPZ8gbdASIpHpztDLvTTQjqZ0z1Ol8tK5X+V6XXC0wQ==} + cpu: [x64] + os: [win32] + + '@capsizecss/unpack@4.0.1': + resolution: {integrity: sha512-CuNiSqg7+e1cO/GjffyMOm5Tt2jUF9CWHHnvQ/UkqvtkGfHdgwEC0wpmq7fkN3gxwpRnrAN0WzO3vREKmNolMQ==} + engines: {node: '>=18'} + '@changesets/apply-release-plan@8.1.1': resolution: {integrity: sha512-nk2Hbq3M9NeHMdaIRBDvawKrQJzXB9sGyBUE5yWnIKtvdcNCPj75zBekJYr0gTT2ecJH3eFeTrc8eisPImcv0Q==} engines: {node: ^22.11 || ^24 || >=26} @@ -257,9 +508,45 @@ packages: resolution: {integrity: sha512-IchNf6dN4tHoMFIn/7OE8LWZ19Y6q/67Bmf6vnGREv8RSbBVb9LPJxEcnwrcwX6ixSvaiGoomAUvu4YSxXrVgw==} engines: {node: '>=12'} + '@emmetio/abbreviation@2.3.3': + resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==} + + '@emmetio/css-abbreviation@2.1.8': + resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==} + + '@emmetio/css-parser@0.4.1': + resolution: {integrity: sha512-2bC6m0MV/voF4CTZiAbG5MWKbq5EBmDPKu9Sb7s7nVcEzNQlrZP6mFFFlIaISM8X6514H9shWMme1fCm8cWAfQ==} + + '@emmetio/html-matcher@1.3.0': + resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==} + + '@emmetio/scanner@1.0.4': + resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==} + + '@emmetio/stream-reader-utils@0.1.0': + resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==} + + '@emmetio/stream-reader@2.2.0': + resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==} + + '@emnapi/core@1.11.1': + resolution: {integrity: sha512-RSvbQmHzdKzNsLYa/wHrbc3KN4sYLKAdPZxqiM2HATqv/SBk2/ENSHpvXGaLOMcsAyz0poEGqkmmKYG3OWiJEQ==} + + '@emnapi/core@1.11.3': + resolution: {integrity: sha512-zLpS5asjEb7lq8jYLq37N6XKaE41DIexlY1rF/z4/tIl3wo13Sqm28fRyfIsKZD+NZ8mM5RoKkpW/rBcuoSZSg==} + + '@emnapi/runtime@1.11.1': + resolution: {integrity: sha512-vgj7R3y3Wgx24IQaGPA/R6YFXLHVMOZ0uVEyIQPaWs+rd1AzfEMXlAC22FYwO1XkKR6NPsq7mUandH8oIRdZFw==} + '@emnapi/runtime@1.11.3': resolution: {integrity: sha512-Xz4Tpyki7XyrpbUK1jR1AhdAdaXyhhY4lZ3neLodmhpuWfy2PAQN5B46sAiU4liOXGLkHypn/qU+jvfWSCYYLA==} + '@emnapi/wasi-threads@1.2.2': + resolution: {integrity: sha512-c95qOXkHdydNKhscBTebqEC1CVAZpyqOfVfBzQ1qgzyl3gfeldUjIggDbIZgDKsHLgnsM+igH7TJ/eAasaVuMA==} + + '@emnapi/wasi-threads@1.2.3': + resolution: {integrity: sha512-ELEBe8PsLvvJ6QMr0zLt8ffvOHW/dc1m3CEzNMg7aJUv3bMaoDtw2TXyDAwkYBuroxxuHEwhRTLJSe5sya547g==} + '@esbuild/aix-ppc64@0.21.5': resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==} engines: {node: '>=12'} @@ -1065,6 +1352,20 @@ packages: os: [linux] libc: [glibc] + '@napi-rs/wasm-runtime@1.2.4': + resolution: {integrity: sha512-AJxoUD2/15ESHbvpcyjU274nsAPLuOtPHCk0vKJM5pj//Fg/B1FXNWjPnXTT9PymCYYiHo4zPj0ZomXBKhoy7g==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + + '@napi-rs/wasm-runtime@1.2.5': + resolution: {integrity: sha512-HshSvXzmBxNzqejd3k/KemgQ3hdREUYFRRrgxOZ+gPljDIsO2SDZrVZMd4Z/HsxudQbE62OVyVFE8z9BCurfjA==} + engines: {node: ^20.19.0 || ^22.13.0 || >=23.5.0} + peerDependencies: + '@emnapi/core': ^1.7.1 || ^2.0.0-alpha.4 + '@emnapi/runtime': ^1.7.1 || ^2.0.0-alpha.4 + '@noble/ciphers@1.3.0': resolution: {integrity: sha512-2I0gnIVPtfnMw9ee9h1dJG7tp81+8Ob3OJb3Mv37rx5L40/b0i7djjCVvGOVqc9AEIQyvyu1i6ypKdFw8R8gQw==} engines: {node: ^14.21.3 || >=16} @@ -1092,6 +1393,12 @@ packages: resolution: {integrity: sha512-X5XaVWZIBCT7HHZGm5I7ZQXDwLG+bGXuSrMQAW+7Zvl87h1kmc1ZB1VSRJcpUfoUrGQp4Fkoxm5kZ+Ms+aW+eA==} engines: {node: '>= 20.19.0'} + '@oslojs/encoding@1.1.0': + resolution: {integrity: sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==} + + '@oxc-project/types@0.152.0': + resolution: {integrity: sha512-oM/5rLBm2tPkg0iBgkH/FOeR3PCDpY19GTgAZjMFM8h9WI9VW7cLgzp6nwtarYKmovavIQZ+Fe/RKX/8C8O/Rw==} + '@pnpm/deps.graph-sequencer@1100.0.1': resolution: {integrity: sha512-pOr5+q1fLYKwFN3LAJuGZEnfXDcQ73zqgDHMtGy+K+uIoUqyY+6MeDCWFwfu+4EFuq76I5EPFofoNAI+Bmmq4A==} engines: {node: '>=22.13'} @@ -1105,6 +1412,105 @@ packages: '@poppinss/exception@1.2.3': resolution: {integrity: sha512-dCED+QRChTVatE9ibtoaxc+WkdzOSjYTKi/+uacHWIsfodVfpsueo3+DKpgU5Px8qXjgmXkSvhXvSCz3fnP9lw==} + '@rolldown/binding-android-arm-eabi@1.2.12': + resolution: {integrity: sha512-dB/a1214qKfHMXCpgqR4OZT+jS4kTyEXbQGJPqzobt5EwH5rX080pxE37alt3RzvR1bf1Yz/yGqRfrYAxuPw0A==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [android] + + '@rolldown/binding-android-arm64@1.2.12': + resolution: {integrity: sha512-7KHFgQ5VJxIHcLlrwrc3Xbds7oTNQT7Pgi9gQCJKrd2VGab/UksIOYp6VD8MzCstGxOKMgNamPwUCfxPdP1OHg==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [android] + + '@rolldown/binding-darwin-arm64@1.2.12': + resolution: {integrity: sha512-3YIhqHD96nA5SaYNRBR16HnGv4oavZvXfD/ayHM+oYZ0WD/8lBAtf6zQua4kEyAvpqrluKXl0lnOBoiNby7x9w==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [darwin] + + '@rolldown/binding-darwin-x64@1.2.12': + resolution: {integrity: sha512-UuuJ35MFw4gmFOrE9pEqIV+K3syIKveph+Qc1/ljHZVdoDW4pz/JHR/eMVom+TZGl/5OOvGJOWaOCVt3ZfqhxA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [darwin] + + '@rolldown/binding-freebsd-x64@1.2.12': + resolution: {integrity: sha512-uMvssit0a4W+/7D8CbHUvG719mH3R2jwXAlh/XcPvuHTE0g++LymF88DCGNX0HM2rBOn0xrzgXktIB6fLSJBTQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [freebsd] + + '@rolldown/binding-linux-arm-gnueabihf@1.2.12': + resolution: {integrity: sha512-XcFu0R0xWnwzSf4IQgFH1rJIckPN1pLy2R+4r9IDB7Yfu/ys9cVqfa4pBrMHj7a3gl8mIR4nRNPg0e5IvEVs6g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm] + os: [linux] + + '@rolldown/binding-linux-arm64-gnu@1.2.12': + resolution: {integrity: sha512-260UrKgn8tz39ak+SMDOirKzr7V04M9dWPw5llW00SwBivCZoWcRBKV1d8cXnRkUmSZA3BdiUmBHWk7734Ulpw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-arm64-musl@1.2.12': + resolution: {integrity: sha512-5YK1I9SqDkbPgc1IA8BgDl34suqUS2q0KWnBrirm0E51YjOs6eo6dV6jbQfNE/argHRSvd0QUGgtpIoYx+WWpw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [linux] + libc: [musl] + + '@rolldown/binding-linux-ppc64-gnu@1.2.12': + resolution: {integrity: sha512-Rkcrmp7eFRg74yL5fXEU91JEWbdEPLevWwGtXpmhbjlD1StScbWTmO94Bhly+Mo+ketKYkdmM1vNUKeWSlx8cQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [ppc64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-s390x-gnu@1.2.12': + resolution: {integrity: sha512-qvK4DuAsQc2BSjlx+Xr+IzOIvvxbGZqxFwdWfG6F518Erj0GGISyQbJ6pIappnOxlNPzNHvo/L0BwB30GZ+zVw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [s390x] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-gnu@1.2.12': + resolution: {integrity: sha512-Q9uLBO53Xd4QIq1WOycVQyPP1O4HhraEV2qqb3uTrnVw6QZih9duY4vNXOivL1xoUS1/z+W8eF4NMfl2a8Sdjw==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [glibc] + + '@rolldown/binding-linux-x64-musl@1.2.12': + resolution: {integrity: sha512-3IBxWFMjbOZskDPKv8Lf9BCnahlKuHthWkYnyIxOH/QcJrFcS4EmcenthApkwr/5+nEqZlLzeYbxeMaX7A5u4g==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [linux] + libc: [musl] + + '@rolldown/binding-openharmony-arm64@1.2.12': + resolution: {integrity: sha512-xtX61xg4LKPkPWilZU1ynKClz5Gj4bf74LML4r3eVLWumKnGjoEr1OSHQhMdbBDoYTi+yjrujvpZe2pUnqCrrA==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [openharmony] + + '@rolldown/binding-win32-arm64-msvc@1.2.12': + resolution: {integrity: sha512-At7fPB6PCaIjzgIhEZFxuT+BBFqiQibJDT4d3PhiR3f4E7bbMZF4aKblbFfEM3sETRDd1YiQx/+U/g/B/ou5Ew==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [arm64] + os: [win32] + + '@rolldown/binding-win32-x64-msvc@1.2.12': + resolution: {integrity: sha512-WIw2haVKwjuYdXkHaoC0mF8Le71TuCBxjrdKqLbJGctbBABj+ClfmNvtbOnzpq3RokNo5+V1qhtSzJyXorsklQ==} + engines: {node: ^20.19.0 || >=22.12.0} + cpu: [x64] + os: [win32] + + '@rolldown/pluginutils@1.0.1': + resolution: {integrity: sha512-2j9bGt5Jh8hj+vPtgzPtl72j0yRxHAyumoo6TNfAjsLB04UtpSvPbPcDcBMxz7n+9CYB0c1GxQFxYRg2jimqGw==} + '@rollup/rollup-android-arm-eabi@4.63.3': resolution: {integrity: sha512-w3Jnvi1ocaVm/c7yVPpfB98XeSRBMyzp6njL5MVVbGyXjpmUkN+s6Hp4t0PqhGCCaI1ZHMKXt/w0lA1RCaLVcw==} cpu: [arm] @@ -1252,6 +1658,51 @@ packages: '@scure/bip39@1.6.0': resolution: {integrity: sha512-+lF0BbLiJNwVlev4eKelw1WWLaiKXw7sSl8T6FvBlWkdX+94aGJ4o8XjUdlyhTCjd8c+B3KT3JfS8P0bLRNU6A==} + '@shikijs/core@4.5.0': + resolution: {integrity: sha512-6CIgwq+bt2JZ3OSjb/nBkkwEf/CfpHcbam+Mg5Pllco7HAGRQ2/EFhZrrJtbyNTgKwknfVS+llsXGygiDGwJWw==} + engines: {node: '>=20'} + + '@shikijs/engine-javascript@4.5.0': + resolution: {integrity: sha512-Ed6UdEj84LyYkwnxM5CvSMWAD+id9ExTYri0/+x41U9zrgNifPSS9lZm0JqBP0VfYI8yr8tY5nbNq9+p9R0kFA==} + engines: {node: '>=20'} + + '@shikijs/engine-oniguruma@4.5.0': + resolution: {integrity: sha512-dKVmbJecVdB9recl8a/CU4jdpNXyjJQrIcesIkpS70s5HS02ohpnCSpMUbotPnEUzbAcLQ+S4hwZYbkBBiTcJw==} + engines: {node: '>=20'} + + '@shikijs/langs@4.5.0': + resolution: {integrity: sha512-wwBTqwduXSz0X4v9Qa2EWeFaYJEw1clCncWjoRNQRbVDu3SPRTRWucnouYapKj3b8Q+sk/41Vbc4B5c8nuYzLA==} + engines: {node: '>=20'} + + '@shikijs/primitive@4.5.0': + resolution: {integrity: sha512-UM7ShlA8oz0OWxLLO8BmO9Ip6fVqdkt8yF0EH7nOCqHfrx1eEAzF0ZUVK7L+I8NEgeu1PEWSRlxaiPPeCb4iDg==} + engines: {node: '>=20'} + + '@shikijs/themes@4.5.0': + resolution: {integrity: sha512-zGb87H3UBbpuI4yoh5UguB1XbU+2BDU3kflM7UfZ+Cy2hWo9lBtqjSVK20gmLY6ukYl040hAypGXMgud9vul8Q==} + engines: {node: '>=20'} + + '@shikijs/types@4.5.0': + resolution: {integrity: sha512-drtPrtD8N0DENyD2cyt6Ajy+IWsiCLgMxODwLTpvH1UsN6a9jf90tNTPjqwHvA+0Lzu9e0txk8DjfqH1p9UJRw==} + engines: {node: '>=20'} + + '@shikijs/vscode-textmate@10.0.2': + resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + + '@signinwithethereum/siwe-parser@4.2.1': + resolution: {integrity: sha512-GAdwNiBaRpUMTiFfPrbQ3e/RBhPbEhRRN1sZmDMLgLEZuKqKwO7V0ksVzCerE9l8HFKTNw5R/q3kPDCWJRz4zA==} + + '@signinwithethereum/siwe@4.2.1': + resolution: {integrity: sha512-CQEQhCIgN9blil1YpaGR+wvGPdsBVK6zed5DBu03s1IdbSO3kA/n7Zp+SAkZGiHy3HY6OJm1Su0/Bd33vKK6nQ==} + peerDependencies: + ethers: ^5.7.0 || ^6.13.0 + viem: ^2.7.0 + peerDependenciesMeta: + ethers: + optional: true + viem: + optional: true + '@sindresorhus/is@7.2.0': resolution: {integrity: sha512-P1Cz1dWaFfR4IR+U13mqqiGsLFf1KbayybWwdd2vfctdV6hDpUkgCY0nKOLLTMSoRd/jJNjtbqzf13K8DCCXQw==} engines: {node: '>=18'} @@ -1259,21 +1710,72 @@ packages: '@speed-highlight/core@1.2.24': resolution: {integrity: sha512-qeW2e1l78afw8VhRPfPQ1Gjj+KU5XFQ/OFV5ti6eTa9bruO7mJyZtA4vw0ofqmA3tKCkROE9xLk3VZoeRc98nw==} + '@tybys/wasm-util@0.10.4': + resolution: {integrity: sha512-W3c4gRigFS0T/Ma4qIYF3GDAc5AQdHb1yL5znJT1Zv1YaD9Kitx656wBjvr19qbiosmZT8lWDM5BEMynUqX65A==} + + '@types/body-parser@1.19.6': + resolution: {integrity: sha512-HLFeCYgz89uk22N5Qg3dvGvsv46B8GLvKKo1zKG4NybA8U2DiEO3w9lqGg29t/tfLRJpJ6iQxnVw4OnB7MoM9g==} + '@types/chai@5.2.3': resolution: {integrity: sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==} + '@types/connect@3.4.38': + resolution: {integrity: sha512-K6uROf1LD88uDQqJCktA4yzL1YYAK6NgfsI0v/mTgyPKWsX1CnJ0XPSDhViejru1GcRkLWb8RlzFYJRqGUbaug==} + '@types/deep-eql@4.0.2': resolution: {integrity: sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==} + '@types/estree-jsx@1.0.5': + resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==} + '@types/estree@1.0.9': resolution: {integrity: sha512-GhdPgy1el4/ImP05X05Uw4cw2/M93BCUmnEvWZNStlCzEKME4Fkk+YpoA5OiHNQmoS7Cafb8Xa3Pya8m1Qrzeg==} + '@types/express-serve-static-core@5.1.3': + resolution: {integrity: sha512-dPfW8NFiOF4wOHc7+N/QSxlY9cfSsenewGbAz8C8U/MULPd/YZ27LvJUIlzaXie7e6Ove9YunJGgC9tbHD2cKw==} + + '@types/express@5.0.6': + resolution: {integrity: sha512-sKYVuV7Sv9fbPIt/442koC7+IIwK5olP1KWeD88e/idgoJqDm3JV/YUiPwkoKK92ylff2MGxSz1CSjsXelx0YA==} + + '@types/hast@3.0.5': + resolution: {integrity: sha512-rp/ezSWaD1m44dPKICGhiskI13nVr7qTloFwDa/IYkhhf5nzwP+zIQcIJh3WIFSBOy/H1PzB40jPjMDksN4F+g==} + + '@types/http-errors@2.0.5': + resolution: {integrity: sha512-r8Tayk8HJnX0FztbZN7oVqGccWgw98T/0neJphO91KkmOzug1KkofZURD4UaD5uH8AqcFLfdPErnBod0u71/qg==} + + '@types/mdast@4.0.4': + resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==} + + '@types/nlcst@2.0.3': + resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==} + '@types/node@22.20.3': resolution: {integrity: sha512-DZmzkmwHzXrLPAXPyKNDzlIwMMUZCVacoD25ywdy5YTKGbOx/2ld+Q38Im2zJ0vBuZP5Prd3VZutKZyXwkOS8A==} '@types/node@22.7.5': resolution: {integrity: sha512-jML7s2NAzMWc//QSJ1a3prpk78cOPchGvXJsC3C6R6PSMoooztvRVQEz89gmBTBY1SPMaqo5teB4uNHPdetShQ==} + '@types/node@24.19.0': + resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==} + + '@types/qs@6.15.1': + resolution: {integrity: sha512-GZHUBZR9hckSUhrxmp1nG6NwdpM9fCunJwyThLW1X3AyHgd9IlHb6VANpQQqDr2o/qQp6McZ3y/IA2rVzKzSbw==} + + '@types/range-parser@1.2.7': + resolution: {integrity: sha512-hKormJbkJqzQGhziax5PItDUTMAM9uE2XXQmM37dyd4hVM+5aVl7oVxMVUiVQn2oCQFN/LKCZdvSM0pFRqbSmQ==} + + '@types/send@1.2.1': + resolution: {integrity: sha512-arsCikDvlU99zl1g69TcAB3mzZPpxgw0UQnaHeC1Nwb015xp8bknZv5rIfri9xTOcMuaVgvabfIRA7PSZVuZIQ==} + + '@types/serve-static@2.2.0': + resolution: {integrity: sha512-8mam4H1NHLtu7nmtalF7eyBH14QyOASmcxHhSfEoRyr0nP/YdoesEtU+uSRvMe96TW/HPTtkoKqQLl53N7UXMQ==} + + '@types/unist@3.0.3': + resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} + + '@ungap/structured-clone@1.4.0': + resolution: {integrity: sha512-1mEZtMKPM09vDmQt5y7YvmN2+DFTP7Tg0EWXdic8/C6VRnpb33e4ghisCIE3WZjsE2N8mf+QV1Zqh7ZFYLWInQ==} + '@vitest/expect@2.1.9': resolution: {integrity: sha512-UJCIkTBenHeKT1TTlKMJWy1laZewsRIzYighyYiJKZreqtdxSos/S1t+ktRMQWu2CKqaarrkeszJx1cgC5tGZw==} @@ -1332,11 +1834,49 @@ packages: '@vitest/utils@3.2.7': resolution: {integrity: sha512-x6BDOd7dyo3PFLY3I9/HJ25X/6OurhGXk2/B9gOZNPF7XDVjeBK4k01lQE5uvDpbuheErh91qYuE1E2OEjK3Rw==} - '@x402/core@2.25.0': - resolution: {integrity: sha512-5Ys0XYz3FKutxVKoXC46R/XPT/oaAbuj7ahzrlVHwQxZJPH9u6u91IOh0ztz+7G/zYGsaXR8l3ety205QtEnUw==} + '@volar/kit@2.4.28': + resolution: {integrity: sha512-cKX4vK9dtZvDRaAzeoUdaAJEew6IdxHNCRrdp5Kvcl6zZOqb6jTOfk3kXkIkG3T7oTFXguEMt5+9ptyqYR84Pg==} + peerDependencies: + typescript: '*' + + '@volar/language-core@2.4.28': + resolution: {integrity: sha512-w4qhIJ8ZSitgLAkVay6AbcnC7gP3glYM3fYwKV3srj8m494E3xtrCv6E+bWviiK/8hs6e6t1ij1s2Endql7vzQ==} + + '@volar/language-server@2.4.28': + resolution: {integrity: sha512-NqcLnE5gERKuS4PUFwlhMxf6vqYo7hXtbMFbViXcbVkbZ905AIVWhnSo0ZNBC2V127H1/2zP7RvVOVnyITFfBw==} + + '@volar/language-service@2.4.28': + resolution: {integrity: sha512-Rh/wYCZJrI5vCwMk9xyw/Z+MsWxlJY1rmMZPsxUoJKfzIRjS/NF1NmnuEcrMbEVGja00aVpCsInJfixQTMdvLw==} + + '@volar/source-map@2.4.28': + resolution: {integrity: sha512-yX2BDBqJkRXfKw8my8VarTyjv48QwxdJtvRgUpNE5erCsgEUdI2DsLbpa+rOQVAJYshY99szEcRDmyHbF10ggQ==} + + '@volar/typescript@2.4.28': + resolution: {integrity: sha512-Ja6yvWrbis2QtN4ClAKreeUZPVYMARDYZl9LMEv1iQ1QdepB6wn0jTRxA9MftYmYa4DQ4k/DaSZpFPUfxl8giw==} - '@x402/evm@2.25.0': - resolution: {integrity: sha512-EmnL4MyGW8weEUlq0qC1uJUeoBmtp9GWGwyPl+qkC0CYItRHn748puhYAxK8GsrofscQrt63HsFCB0Gp3iEROA==} + '@vscode/emmet-helper@2.11.0': + resolution: {integrity: sha512-QLxjQR3imPZPQltfbWRnHU6JecWTF1QSWhx3GAKQpslx7y3Dp6sIIXhKjiUJ/BR9FX8PVthjr9PD6pNwOJfAzw==} + + '@vscode/l10n@0.0.18': + resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==} + + '@x402/core@2.27.0': + resolution: {integrity: sha512-UbxCKnoTsg5nQX9fYER3g9tt5l80jHm1IZOmDczQRqE0cwskls5r+VAAj0iUQfHVshnpv0qo/rLFI7UntqL96g==} + + '@x402/evm@2.27.0': + resolution: {integrity: sha512-WKVFq5VaSrDJfo6lHNG7/4hT0iZdpsmd53W/a+gZqmE1CiVT8wyRpwIPue4f/YKqNfgHHhZ00AcfPho0xLr2eQ==} + + '@x402/express@2.27.0': + resolution: {integrity: sha512-73eGihL7BLHrFOH48pJdVPhHTvzRaFKcimzcRYR/0+VVfPLTfYyLwxCu414aoDokKGTU5u8AIYwf2LpcpaYX7w==} + peerDependencies: + '@x402/paywall': ^2.27.0 + express: ^4.0.0 || ^5.0.0 + peerDependenciesMeta: + '@x402/paywall': + optional: true + + '@x402/extensions@2.27.0': + resolution: {integrity: sha512-eGBZZCTNtJsbzYoOe72Mfo/HN7Ir4i8+gmBUQ3ScrTiO91Q0bscO6LjGg2d3oJiFQ6g+YVXn+5fLxCEwoqgFsA==} abitype@1.2.3: resolution: {integrity: sha512-Ofer5QUnuUdTFsBRwARMoWKOH1ND5ehwYhJ3OJ/BQO+StkwQjHw0XyVh4vDttzHB7QOFhPHa/o413PJ82gU/Tg==} @@ -1349,24 +1889,95 @@ packages: zod: optional: true + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + aes-js@4.0.0-beta.5: resolution: {integrity: sha512-G965FqalsNyrPqgEGON7nIx1e/OVENSgiEIzyC63haUMuvNnwIgIjMs52hlTCKhkBny7A2ORNlfY9Zu+jmGk1Q==} - ansi-regex@5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} + ajv-draft-04@1.0.0: + resolution: {integrity: sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==} + peerDependencies: + ajv: ^8.5.0 + peerDependenciesMeta: + ajv: + optional: true - ansi-styles@4.3.0: + ajv-i18n@4.2.0: + resolution: {integrity: sha512-v/ei2UkCEeuKNXh8RToiFsUclmU+G57LO1Oo22OagNMENIw+Yb8eMwvHu7Vn9fmkjJyv6XclhJ8TbuigSglPkg==} + peerDependencies: + ajv: ^8.0.0-beta.0 + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + + am-i-vibing@0.5.0: + resolution: {integrity: sha512-KLcsDhqf1XRrJmJr+9I/C0EX2K+sGrAGZFgkmd84c8TJO9zJBu+/kFInjazu1KfJWFhWDKdRWkpBzEs7s35DVA==} + hasBin: true + + ansi-regex@5.0.1: + resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} + engines: {node: '>=8'} + + ansi-regex@6.4.0: + resolution: {integrity: sha512-KzTVk2tCWAHtYrvvvaP8bJKJq2pVinhLcGEQdtLIYPbmNGNyYe8QwNaTUYQp2J7/vIsUKt5QCqAfUkYyG9DkOw==} + engines: {node: '>=12'} + + ansi-styles@4.3.0: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} + ansi-styles@6.2.3: + resolution: {integrity: sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==} + engines: {node: '>=12'} + + anymatch@3.1.3: + resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==} + engines: {node: '>= 8'} + + apg-js@4.4.0: + resolution: {integrity: sha512-fefmXFknJmtgtNEXfPwZKYkMFX4Fyeyz+fNF6JWp87biGOPslJbCBVU158zvKRZfHBKnJDy8CMM40oLFGkXT8Q==} + + aria-query@5.3.2: + resolution: {integrity: sha512-COROpnaoap1E2F000S62r6A60uHZnmlvomhfyT2DlTcrY1OrBKn2UhH7qn5wTC9zMvD0AY7csdPSNwKP+7WiQw==} + engines: {node: '>= 0.4'} + assertion-error@2.0.1: resolution: {integrity: sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==} engines: {node: '>=12'} + astro@7.3.6: + resolution: {integrity: sha512-3q0MKxfE4cpr5IoQ9EWrN0gwxeT5tkCaSVe3SrGlLR5fnTIywHqjVqFokQkQiZexfwpNtB9dtBdUcXV9FuD+4w==} + engines: {node: '>=22.12.0', npm: '>=9.6.5', pnpm: '>=7.1.0'} + hasBin: true + peerDependencies: + '@astrojs/markdown-remark': ^7.3.0 + peerDependenciesMeta: + '@astrojs/markdown-remark': + optional: true + + axobject-query@4.1.0: + resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==} + engines: {node: '>= 0.4'} + + bail@2.0.2: + resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==} + blake3-wasm@2.1.5: resolution: {integrity: sha512-F1+K8EbfOZE49dtoPtmxUQrpXaBIl3ICvasLh+nJta0xkz+9kF/7uet9fLnwKqhDrmj6g+6K3Tw9yQPUg2ka5g==} + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + + boolbase@1.0.0: + resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} + + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + cac@6.7.14: resolution: {integrity: sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==} engines: {node: '>=8'} @@ -1375,10 +1986,27 @@ packages: resolution: {integrity: sha512-tixWYgm5ZoOD+3g6UTea91eow5z6AAHaho3g0V9CNSNb45gM8SmflpAc+GRd1InC4AqN/07Unrgp56Y94N9hJQ==} engines: {node: '>=20.19.0'} + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + + ccount@2.0.1: + resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==} + chai@5.3.3: resolution: {integrity: sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==} engines: {node: '>=18'} + character-entities-html4@2.1.0: + resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==} + + character-entities-legacy@3.0.0: + resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==} + chardet@2.2.0: resolution: {integrity: sha512-rddelWYNPRrXq6PtNEN2S3f6t9ILzvqaN5pVgi4kqt9jHQaXIial9PznB5iSPVlQSLNaaH22ItWz3EJtQ10+OA==} @@ -1386,10 +2014,30 @@ packages: resolution: {integrity: sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==} engines: {node: '>= 16'} + chokidar@4.0.3: + resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} + engines: {node: '>= 14.16.0'} + + chokidar@5.0.0: + resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} + engines: {node: '>= 20.19.0'} + + ci-info@4.4.0: + resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} + engines: {node: '>=8'} + cli-width@4.1.0: resolution: {integrity: sha512-ouuZd4/dm2Sw5Gmqy6bGyNNNe1qt9RpmxveLSO7KcgsTnU7RXfsw+/bukWGo1abgBiMAic068rclZsO4IWmmxQ==} engines: {node: '>= 12'} + cliui@9.0.1: + resolution: {integrity: sha512-k7ndgKhwoQveBL+/1tqGJYNz097I7WOvwbmmU2AR5+magtbjPWQTS1C5vzGkBC8Ym8UWRzfKUzUUqFLypY4Q+w==} + engines: {node: '>=20'} + + clsx@2.1.1: + resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==} + engines: {node: '>=6'} + color-convert@2.0.1: resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} engines: {node: '>=7.0.0'} @@ -1397,14 +2045,74 @@ packages: color-name@1.1.4: resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} + comma-separated-tokens@2.0.3: + resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==} + + commander@11.1.0: + resolution: {integrity: sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==} + engines: {node: '>=16'} + commander@12.1.0: resolution: {integrity: sha512-Vw8qHK3bZM9y/P10u3Vib8o/DdkvA2OtPtZvD871QKjy74Wj1WSKFILMPRPSdUSx5RFK1arlJzEtA4PkFgnbuA==} engines: {node: '>=18'} + common-ancestor-path@2.0.0: + resolution: {integrity: sha512-dnN3ibLeoRf2HNC+OlCiNc5d2zxbLJXOtiZUudNFSXZrNSydxcCsSpRzXwfu7BBWCIfHPw+xTayeBvJCP/D8Ng==} + engines: {node: '>= 18'} + + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + + cookie-es@1.2.3: + resolution: {integrity: sha512-lXVyvUvrNXblMqzIRrxHb57UUVmqsSWlxqt3XIjCkUP0wDAf6uicO6KMbEgYrMNtEvWgWHwe42CKxPu9MYAnWw==} + + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + cookie@1.1.1: resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==} engines: {node: '>=18'} + cookie@2.0.1: + resolution: {integrity: sha512-yuToqVvRrj6pfDXREyQAAv8SkAEk/8GS3jQRTiUMm66TVtBYmqQeoEjL2Lmq8Rpo6271vH76InTChTitEAm65w==} + engines: {node: '>=22'} + + crossws@0.3.5: + resolution: {integrity: sha512-ojKiDvcmByhwa8YYqbQI/hg7MEU0NC03+pSdEq4ZUnZR9xXpwk7E43SMNGkn+JxJGPFtNvQ48+vV2p+P1ml5PA==} + + css-select@6.0.0: + resolution: {integrity: sha512-rZZVSLle8v0+EY8QAkDWrKhpgt6SA5OtHsgBnsj6ZaLb5dmDVOWUDtQitd9ydxxvEjhewNudS6eTVU7uOyzvXw==} + + css-tree@2.2.1: + resolution: {integrity: sha512-OA0mILzGc1kCOCSJerOeqDxDQ4HOh+G8NbOJFOTgOCzpw7fCBubk0fEyxp8AgOL/jvLgYA/uV0cMbe43ElF1JA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + + css-tree@3.2.1: + resolution: {integrity: sha512-X7sjQzceUhu1u7Y/ylrRZFU2FS6LRiFVp6rKLPg23y3x3c3DOKAwuXGDp+PAGjh6CSnCjYeAul8pcT8bAl+lSA==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0} + + css-what@7.0.0: + resolution: {integrity: sha512-wD5oz5xibMOPHzy13CyGmogB3phdvcDaB5t0W/Nr5Z2O/agcB8YwOz6e2Lsp10pNDzBoDO9nVa3RGs/2BttpHQ==} + engines: {node: '>= 6'} + + csso@5.0.5: + resolution: {integrity: sha512-0LrrStPOdJj+SPCCrGhzryycLjwcgUSHBtxNA8aIDxf0GLsRh1cKYhB00Gd1lDOS4yGH69+SNn13+TWbVHETFQ==} + engines: {node: ^10 || ^12.20.0 || ^14.13.0 || >=15.0.0, npm: '>=7.0.0'} + debug@4.4.3: resolution: {integrity: sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==} engines: {node: '>=6.0'} @@ -1418,19 +2126,96 @@ packages: resolution: {integrity: sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==} engines: {node: '>=6'} + defu@6.1.7: + resolution: {integrity: sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==} + + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + + dequal@2.0.3: + resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} + engines: {node: '>=6'} + + destr@2.0.5: + resolution: {integrity: sha512-ugFTXCtDZunbzasqBxrK93Ik/DRYsO6S/fedkWEMKqt04xZ4csmnmwGDBAb07QWNaGMAmnTIemsYZCksjATwsA==} + detect-libc@2.1.2: resolution: {integrity: sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==} engines: {node: '>=8'} + devalue@5.9.4: + resolution: {integrity: sha512-sPAT4pztbu6586/hrhOnMKS17IJrvg12mXiSPSS3W5qDeN2RGgvZ0diZCm31dBbnevfVmujNO3IM2wrS4Y2Rhg==} + + devlop@1.1.0: + resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + + diff@9.0.0: + resolution: {integrity: sha512-svtcdpS8CgJyqAjEQIXdb3OjhFVVYjzGAPO8WGCmRbrml64SPw/jJD4GoE98aR7r25A0XcgrK3F02yw9R/vhQw==} + engines: {node: '>=0.3.1'} + + dom-serializer@2.0.0: + resolution: {integrity: sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==} + + domelementtype@2.3.0: + resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} + + domhandler@5.0.3: + resolution: {integrity: sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==} + engines: {node: '>= 4'} + + domutils@3.2.2: + resolution: {integrity: sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==} + + dset@3.1.4: + resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==} + engines: {node: '>=4'} + + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + + emmet@2.4.11: + resolution: {integrity: sha512-23QPJB3moh/U9sT4rQzGgeyyGIrcM+GH5uVYg2C6wZIxAIJq7Ng3QLT79tl8FUwDXhyq9SusfknOrofAKqvgyQ==} + + emoji-regex@10.6.0: + resolution: {integrity: sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==} + emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + + entities@4.5.0: + resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} + engines: {node: '>=0.12'} + error-stack-parser-es@1.0.5: resolution: {integrity: sha512-5qucVt2XcuGMcEGgWI7i+yZpmpByQ8J1lHhcL7PwqCwu9FPP3VUXzT4ltHe5i2z9dePwEHcDVOAfSnHsOlCXRA==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + es-module-lexer@1.7.0: resolution: {integrity: sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==} + es-module-lexer@3.0.3: + resolution: {integrity: sha512-yWGe1O/j+almnV4hOYrmZo8u58JdnmXEMneRQAYkWtqSiT86yoMIEKF4rpqEDj52tbYl3xceBD3DQIBwcsC9Pw==} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + esbuild@0.21.5: resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==} engines: {node: '>=12'} @@ -1446,9 +2231,20 @@ packages: engines: {node: '>=18'} hasBin: true + escalade@3.2.0: + resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} + engines: {node: '>=6'} + + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + estree-walker@3.0.3: resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + ethers@6.17.0: resolution: {integrity: sha512-BpyrpIPJ3ydEVow8zGaz1DuPS7YU8DcWxuBnY9a0UA/lvAPwrMr+EPXsfrul628SRaekPNeIM4UFh/91GWZang==} engines: {node: '>=14.0.0'} @@ -1456,16 +2252,32 @@ packages: eventemitter3@5.0.1: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} + eventemitter3@5.0.4: + resolution: {integrity: sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==} + expect-type@1.4.0: resolution: {integrity: sha512-KfYbmpRm0VbLjEvVa9yGwCi9GI34xvi7A/HXYWQO65CSD2u3MczUJSuwXKFIxlGsgBQizV9q5J9NHj4VG0n+pA==} engines: {node: '>=12.0.0'} + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + + extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-string-truncated-width@3.0.3: resolution: {integrity: sha512-0jjjIEL6+0jag3l2XWWizO64/aZVtpiGE3t0Zgqxv0DPuxiMjvB3M24fCyhZUO4KomJQPj3LTSUnDP3GpdwC0g==} fast-string-width@3.0.2: resolution: {integrity: sha512-gX8LrtNEI5hq8DVUfRQMbr5lpaS4nMIWV+7XEbXk2b8kiQIizgnlr12B4dA3ZEx3308ze0O4Q1R+cHts8kyUJg==} + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} + fast-wrap-ansi@0.2.2: resolution: {integrity: sha512-7F2Fl+TjRSenLqlU3UjSH0iyqopqoZIu7eZVpEirP2g1GtWa2G/ecEmBdgz31+Mxr+ELclgg6sokpSFIQiZ02Q==} @@ -1478,15 +2290,102 @@ packages: picomatch: optional: true + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + + find-proc@0.2.0: + resolution: {integrity: sha512-a6h2nTrgB3g5Wrn4au9Ux4kMk7IJtyF6oA8uGn+mk3weLZssUtc1cp6meHIzzuW2o1srrBAxzkmXLbqjRkgB6w==} + engines: {node: ^20.19.0 || >=22.12.0} + + flattie@1.1.1: + resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==} + engines: {node: '>=8'} + + fontace@0.4.1: + resolution: {integrity: sha512-lDMvbAzSnHmbYMTEld5qdtvNH2/pWpICOqpean9IgC7vUbUJc3k+k5Dokp85CegamqQpFbXf0rAVkbzpyTA8aw==} + + fontkitten@1.0.3: + resolution: {integrity: sha512-Wp1zXWPVUPBmfoa3Cqc9ctaKuzKAV6uLstRqlR56kSjplf5uAce+qeyYym7F+PHbGTk+tCEdkCW6RD7DX/gBZw==} + engines: {node: '>=20'} + + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fsevents@2.3.3: resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + + get-caller-file@2.0.5: + resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} + engines: {node: 6.* || 8.* || >= 10.*} + + get-east-asian-width@1.7.0: + resolution: {integrity: sha512-XjH1AECxf0giL2V1aU8vKyRR2ppRUb5c0EvT7zuJTokQ74bNo52zOtghqdWIqrhUD79fo3x0WfKZdOqxF6LG1Q==} + engines: {node: '>=18'} + + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + + get-tsconfig@5.0.0-beta.6: + resolution: {integrity: sha512-X6fBC0pmImC70gvX2zm56go9hx0MyoGVdG0tUCkg/D+Xnh5TJsOZ7iDbOdI3PvmtrDxnu1YdDufpK2QJX1Meqw==} + engines: {node: '>=20.20.0'} + + github-slugger@2.0.0: + resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==} + + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + + h3@1.15.11: + resolution: {integrity: sha512-L3THSe2MPeBwgIZVSH5zLdBBU90TOxarvhK9d04IDY2AmVS8j2Jz2LIWtwsGOU3lu2I5jCN7FNvVfY2+XyF+mg==} + + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + + hast-util-to-html@9.0.5: + resolution: {integrity: sha512-OguPdidb+fbHQSU4Q4ZiLKnzWo8Wwsf5bZfbvu7//a9oTYoqD/fWpe96NuHkoS9h0ccGOTe0C4NGXdtS0iObOw==} + + hast-util-whitespace@3.0.0: + resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==} + hono@4.13.8: resolution: {integrity: sha512-/Gng7NfoykZl2pjukW5Z6+8Yxm3BPRf86GTbQnt0SbySkvax4fyL4H3HhY1cCpBGmiW9XDRFzRV+CXK2W8QudQ==} engines: {node: '>=16.9.0'} + html-escaper@3.0.3: + resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==} + + html-void-elements@3.0.0: + resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + + http-cache-semantics@4.3.0: + resolution: {integrity: sha512-M5t5LlJpS1UHMjvwRQVdFHvPISGeLAxNcrWuJkeGh0KxsqCHZ1O3NXZU/8x7cD0BDcGW8kapxMKTvwlqrNkHkA==} + + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + human-id@4.2.1: resolution: {integrity: sha512-zPGsiS+dWoTZtZ4AtpA9Y+BdSFSNWvnouNlWNoUFyAM6xHOHmdCvqO3k8AIbdamCOv4gUFUVNPf6rJFfc4UiJw==} hasBin: true @@ -1498,10 +2397,32 @@ packages: import-meta-resolve@4.2.0: resolution: {integrity: sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==} + inherits@2.0.4: + resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + + iron-webcrypto@1.2.1: + resolution: {integrity: sha512-feOM6FaSr6rEABp/eDfVseKyTMDt+KGpeB35SkVn9Tyn0CqvVsY3EwI0v5i8nMHyJnzCIQf7nsy3p41TPkJZhg==} + + is-docker@4.0.0: + resolution: {integrity: sha512-LHE+wROyG/Y/0ZnbktRCoTix2c1RhgWaZraMZ8o1Q7zCh0VSrICJQO5oqIIISrcSBtrXv0o233w1IYwsWCjTzA==} + engines: {node: '>=20'} + hasBin: true + is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} engines: {node: '>=8'} + is-plain-obj@4.1.0: + resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} + engines: {node: '>=12'} + + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + isows@1.0.7: resolution: {integrity: sha512-I1fSfDCZL5P0v33sVqeTDSpcstAg/N+wF5HS033mogOVIp4B+oHC7oOCsA3axAbBSGTJ8QubbNmnIRN/h8U7hg==} peerDependencies: @@ -1510,9 +2431,18 @@ packages: jju@1.4.0: resolution: {integrity: sha512-8wb9Yw966OSxApiCt0K3yNJL8pnNeIv+OEq2YMidz4FKP6nonSRoOXc80iXY4JaN2FC11B9qsNmDsm+ZOfMROA==} + jose@5.10.0: + resolution: {integrity: sha512-s+3Al/p9g32Iq+oqXxkW//7jk2Vig6FF1CFqzVXoTUXt2qz89YWbL+OwS17NFYEvxC35n0FKeGO2LGYSxeM2Gg==} + js-tokens@9.0.1: resolution: {integrity: sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + jsonc-parser@2.3.1: + resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==} + jsonc-parser@3.3.1: resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==} @@ -1523,6 +2453,80 @@ packages: launch-editor@2.14.1: resolution: {integrity: sha512-QWBrQsMpH7gPr965dsKD/3cKWiNoTjpATQf++Xq63N6sKRGMwlVXz41O1IZTMfZQgBctD/K5Zt06+/I6pP6+HA==} + lightningcss-android-arm64@1.33.0: + resolution: {integrity: sha512-gEpRTalKdosp4Bb8qWtc2iOgE5SeIHlpS1up9bFq2wAyYhl1UdTObYiHe98zEM9SQvSoqQZ1IQD0JNpg3Ml5pg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [android] + + lightningcss-darwin-arm64@1.33.0: + resolution: {integrity: sha512-Sciaz8eenNTKn9b3t7+xr0ipTp9YxKQY4npwQ3mrRuL0BAVHBLyZxofhaKBAVtzmtRZ/zTyo0/to4B1uWG/Djg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [darwin] + + lightningcss-darwin-x64@1.33.0: + resolution: {integrity: sha512-Z5UPAxzrjlWNNyGy6i65cJzzvgJ5D3T6wMvs+gWpY9d7qRhANrxqAp6LhxIgZhWEw18RfJTGcRxjuLIBr+m8XQ==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [darwin] + + lightningcss-freebsd-x64@1.33.0: + resolution: {integrity: sha512-QQM/Ti/hQajJwCY+RiWuCZ9sdtI/XQk7nDK5vC8kkdwixezOlDgvDx7+RT+QjK6FcFT4MpsuoBnHIo/O3StRRg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [freebsd] + + lightningcss-linux-arm-gnueabihf@1.33.0: + resolution: {integrity: sha512-N7FVBe6iS24MlM6R/4RBTxGhQheZGs7tiQ9U32UtF75NzP5Q7xWPRqLBCKxlRQRk3rY1jCIPLzx7WzOhuUIRLQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm] + os: [linux] + + lightningcss-linux-arm64-gnu@1.33.0: + resolution: {integrity: sha512-j2v/itmy4HlNxlc6voKXYgBqNi0Ng2LShg4z7GufpEgs05P+2suBVyi9I6YHq5uoVFx9ETin3eCEhLVyXGQnKg==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [glibc] + + lightningcss-linux-arm64-musl@1.33.0: + resolution: {integrity: sha512-yiO5ROMuYQgXbC60yjZU5CYSFZGKXL0HFATXt9mHJn1+zW55oCtMI9NfcVhYLMFDL7gV7oBPon/EmMMGg2OvtQ==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [linux] + libc: [musl] + + lightningcss-linux-x64-gnu@1.33.0: + resolution: {integrity: sha512-ar+Ju7LmcN0Jo4FpL4hpFybwNG9/3A/Br5KW2n2jyODg3MEZXaDYADdemoNS+BDNfMgKvylJLj4S5tyRActuAg==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [glibc] + + lightningcss-linux-x64-musl@1.33.0: + resolution: {integrity: sha512-RYiYbkokw0trfKqqzfF55lginwEPrD3OJDfTuJzFs1MK6iFnDenaz1fqLLtX4ITG3OktJQXOeTaw1awrBAlZPw==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [linux] + libc: [musl] + + lightningcss-win32-arm64-msvc@1.33.0: + resolution: {integrity: sha512-1K+MPfLSFVpphzpdbfkhlWk6wBrTObBzS2T6db10PNOZgR9GoVsAWzwNyuhUYYbTp23j+4RrncfujZ4uAzXvwA==} + engines: {node: '>= 12.0.0'} + cpu: [arm64] + os: [win32] + + lightningcss-win32-x64-msvc@1.33.0: + resolution: {integrity: sha512-OlEICDx/Xl0FqSp4bry8zFnCvGpig3Gl4gCquvYwHuqJKEC1+n9NgDniFvqHGmMv1ZkqDJrDqKKSykTDX+ehuA==} + engines: {node: '>= 12.0.0'} + cpu: [x64] + os: [win32] + + lightningcss@1.33.0: + resolution: {integrity: sha512-WkUDrojuJs0xkgGf2udWxa3yGBRxPtxUkB79i6aCZLRgc7PM8fZe9TosfPDcvEpQZbuFASnHYmRLBLUbmLOIIA==} + engines: {node: '>= 12.0.0'} + loupe@3.2.1: resolution: {integrity: sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==} @@ -1530,16 +2534,77 @@ packages: resolution: {integrity: sha512-123qHRfJBmo2jXDbo/a5YOQrJoHF/GNQTLzQ5+IdK5pWpceK17yRc6ozlWd25FxvGKQbIUs91fDFkXmDHTKcyA==} engines: {node: 20 || >=22} + lru-cache@11.5.3: + resolution: {integrity: sha512-U4N8FgzmWxc8k1VH8Kr6lQg18U7Fjvby6wXHVRX/ZZ7IwWbRMgrRbP0Wrb5q5NVinryp4SQampHKdvtecItxUg==} + engines: {node: 20 || >=22} + magic-string@0.30.21: resolution: {integrity: sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==} + magic-string@1.4.3: + resolution: {integrity: sha512-z12OxmaPGE0F4xlpGdjuAUckipLpQlTAuAmyGhNoD7ODpYUzvDfvtxUbjM/jwznyP178oju/KDdyi220wNJ0RQ==} + + magicast@0.5.5: + resolution: {integrity: sha512-UicdXN8zQ3JHlxVq+28afMXPr1z7WNY6+7EJnzTdQWkTAlMLF5fNCCKxJHBQwGaNGR11581EiQmQzx73+MvszA==} + + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + + mdast-util-to-hast@13.2.1: + resolution: {integrity: sha512-cctsq2wp5vTsLIcaymblUriiTcZd0CwWtCbLvrOzYCDZoWyMNV8sZ7krj09FSnsiJi3WVsHLM4k6Dq/yaPyCXA==} + + mdn-data@2.0.28: + resolution: {integrity: sha512-aylIc7Z9y4yzHYAJNuESG3hfhC+0Ibp/MAMiaOZgNv4pmEdFyfZhhhny4MNiAfWdBQ1RQ2mfDWmM1x8SvGyp8g==} + + mdn-data@2.27.1: + resolution: {integrity: sha512-9Yubnt3e8A0OKwxYSXyhLymGW4sCufcLG6VdiDdUGVkPhpqLxlvP5vl1983gQjJl3tqbrM731mjaZaP68AgosQ==} + + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + + micromark-util-character@2.1.1: + resolution: {integrity: sha512-wv8tdUTJ3thSFFFJKtpYKOYiGP2+v96Hvk4Tu8KpCAsTMs6yi+nVmGh1syvSCsaxz45J6Jbw+9DD6g97+NV67Q==} + + micromark-util-encode@2.0.1: + resolution: {integrity: sha512-c3cVx2y4KqUnwopcO9b/SCdo2O67LwJJ/UyqGfbigahfegL9myoEFoDYZgkT7f36T0bLrM9hZTAaAyH+PCAXjw==} + + micromark-util-sanitize-uri@2.0.1: + resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} + + micromark-util-symbol@2.0.1: + resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} + + micromark-util-types@2.0.3: + resolution: {integrity: sha512-oxB2Ik03hI0gv+VNn9tnh1t1YEe9MDPptViAEgfdf3YQHsn0pzGTgCdlSCJXcwhqm8phaEuM7zeEu3QQzVBrPg==} + + mime-db@1.54.0: + resolution: {integrity: sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==} + engines: {node: '>= 0.6'} + + mime-types@3.0.2: + resolution: {integrity: sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==} + engines: {node: '>=18'} + miniflare@5.20260915.0-alpha: resolution: {integrity: sha512-ApLsq9X2jbpkLAPXx89afGvuNxAFzd1rUK+nzfBSLu+34YWc2Q2YlgH6f3kSEEQYZ2gAlC5Q5IP6tDNNg/1KqQ==} engines: {node: '>=22.0.0'} + mrmime@2.0.1: + resolution: {integrity: sha512-Y3wQdFg2Va6etvQ5I82yUhGdsKrcYox6p7FfL1LbK2J4V01F9TGlepTIhnK24t7koZibmg82KGglhA1XK5IsLQ==} + engines: {node: '>=10'} + ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} + muggle-string@0.4.1: + resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==} + mute-stream@2.0.0: resolution: {integrity: sha512-WWdIxpyjEn+FhQJQQv9aQAYlHoNVdzIzUySNV1gHUPDSdZJ3yZn7pAAbQcV7B56Mvu881q9FZV+0Vx2xC44VWA==} engines: {node: ^18.17.0 || >=20.5.0} @@ -1549,6 +2614,57 @@ packages: engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1} hasBin: true + negotiator@1.1.0: + resolution: {integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==} + engines: {node: '>=18'} + + neotraverse@1.0.1: + resolution: {integrity: sha512-WmmLty1YWwJl9yZi77v2dVIV6X2kuYV8YYBI/G3LWGKdGHmHUvL1z7FW0iDvEvGAwNEoc5x1tOOOyDnf5jJw/w==} + engines: {node: '>= 10'} + + nlcst-to-string@4.0.0: + resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==} + + node-fetch-native@1.6.7: + resolution: {integrity: sha512-g9yhqoedzIUm0nTnTqAQvueMPVOuIY16bqgAJJC8XOOubYFNwz6IER9qs0Gq2Xd0+CecCKFjtdDTMA4u4xG06Q==} + + node-mock-http@1.0.5: + resolution: {integrity: sha512-KQyt/wLjG3TAc7DOUhpqWzgd4ERxR80JOlTK5VE5R1S12IaPVN5qkj4klBce9HPG1Njuup4Sb5bljaT34lIyjw==} + + normalize-path@3.0.0: + resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} + engines: {node: '>=0.10.0'} + + nth-check@2.1.1: + resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + obug@3.0.0: + resolution: {integrity: sha512-5vvB5+W7ePv+p3uqxi+RcW1XAzLW0/hxt3/4X4Lc4qHudzOhmBiBwOY6DRob4WnanAEGvNcLjF+KNOufrUoEQw==} + engines: {node: '>=12.20.0'} + + ofetch@1.5.1: + resolution: {integrity: sha512-2W4oUZlVaqAPAil6FUg/difl6YhqhUR7x2eZY4bQCko22UXg3hptq9KLQdqFClV+Wu85UX7hNtdGTngi/1BxcA==} + + ohash@2.0.12: + resolution: {integrity: sha512-65S/5gk9YSsaRjcyf7Nfa6h/d3E8/1gslpXfI4W7Dxn/oap8IKRuNT5VXkLQ1YFKIEg4apRY4Pj6aiwFzrDdmw==} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + + once@1.4.0: + resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} + + oniguruma-parser@0.12.2: + resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} + + oniguruma-to-es@4.3.6: + resolution: {integrity: sha512-csuQ9x3Yr0cEIs/Zgx/OEt9iBw9vqIunAPQkx19R/fiMq2oGVTgcMqO/V3Ybqefr1TBvosI6jU539ksaBULJyA==} + ox@0.14.44: resolution: {integrity: sha512-O54qXXHEk4ySamMSyBpI0AeBegS5frxU6+LA6Jb9Sf6kMOxcTNaxYmwZfpOu22DIQsdKfgQxHq8EsAGaoBQScA==} peerDependencies: @@ -1557,12 +2673,34 @@ packages: typescript: optional: true + p-limit@7.3.3: + resolution: {integrity: sha512-SKgVvDU5TNIxQ4r30U75BNLC6a+6GOEjngrk/ysM5+Zu3oJuk1SC5ApzIzY/7PjCEjoVPMWJ0zho/4QUiEB7TQ==} + engines: {node: '>=20'} + + p-queue@9.3.3: + resolution: {integrity: sha512-NXAOdnEe5FsZJfT4oK84lE1Y5cFFdWlRuOo5tww8DyNMxyRXwn39fIkUtNLKppcPC+UYU/bXujNCUGDv01y7CA==} + engines: {node: '>=20'} + + p-timeout@7.0.2: + resolution: {integrity: sha512-prbX4Z3YszrFNgH+MW5Zoeq3baXrMtP/MQnFeET90UB/GtGcGDQ5Usg9OCy6ETjTTntOw1SL2z9fMPUppN3Guw==} + engines: {node: '>=20'} + package-manager-detector@1.8.0: resolution: {integrity: sha512-yQA4H19AmPEoMUeavPMDIe1higySl/gH/yaQrkT/s07Qp+7pp2hYz30N3z2l5BkjVkF9Ow6o0wjJamm2y7Sn0A==} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + + path-browserify@1.0.1: + resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==} + path-to-regexp@6.3.0: resolution: {integrity: sha512-Yhpw4T9C6hPpgPeA28us07OJeqZ5EzQTkbfwuhsUg0c237RomFoETJgmp2sa3F/41gfLE6G5cqcYwznmeEeOlQ==} + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + pathe@1.1.2: resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==} @@ -1573,9 +2711,16 @@ packages: resolution: {integrity: sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==} engines: {node: '>= 14.16'} + piccolore@0.1.3: + resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} + picocolors@1.1.1: resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==} + picomatch@2.3.2: + resolution: {integrity: sha512-V7+vQEJ06Z+c5tSye8S+nHUfI51xoXIXjHQ99cQtKUkQqqO1kO/KCJUfZXuB47h/YBlDhah2H3hdUGXn8ie0oA==} + engines: {node: '>=8.6'} + picomatch@4.0.7: resolution: {integrity: sha512-qcJu88Q2IWqJsDD529JKMdwGm/dvInW4HvQnRwiH9JtihJvzGOscDtHE3x1pBKeUOTysQ8kVmLnJ2kJu7yhcGA==} engines: {node: '>=12'} @@ -1584,19 +2729,117 @@ packages: resolution: {integrity: sha512-RRuzqDtt5Y9h3quz5hWhK+TPnsmVs6WwSU6LkJMeY4HstUEDuYTG8UJSdawMRzmzAtV+KEoG8N3Qg2qLy5vM/A==} engines: {node: ^10 || ^12 || >=14} + prettier@3.9.9: + resolution: {integrity: sha512-Z/CJHIkdujO/OtN7nXUii0Rf3VT5SRuhjBA82Xvu2XhBUgX3nhP67T0LHceBdQLex7OOFGTox+Q5Yg8Jk2Qivg==} + engines: {node: '>=14'} + hasBin: true + + prismjs@1.30.0: + resolution: {integrity: sha512-DEvV2ZF2r2/63V+tK8hQvrR2ZGn10srHbXviTlcv7Kpzw8jWiNTqbVgjO3IY8RxrrOUF8VPMQQFysYYYv0YZxw==} + engines: {node: '>=6'} + + process-ancestry@0.1.0: + resolution: {integrity: sha512-tGqJW/UnclpYASFcM6Xh8D8l/BMtaQ9+CSG0vlJSJTcdMM4lDRv4c6H0Pdcsfted+bVczdYSfk2fdukg2gQkZg==} + engines: {node: '>=18.0.0'} + + property-information@7.2.0: + resolution: {integrity: sha512-IAtzIB6sUiWaJYrX9smp3V46pBGbBeLFRGdh25kg1334VcBlD8HzhPeNIWQH9zhGmo2itIe25EHt9dQP7G5hmg==} + + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} + engines: {node: '>= 0.10'} + + qs@6.16.0: + resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} + engines: {node: '>=0.6'} + + radix3@1.1.2: + resolution: {integrity: sha512-b484I/7b8rDEdSDKckSSBA8knMpcdsXudlE/LNL639wFoHKwLbEkQFZHWEYwDC0wa0FKUcCY+GAF73Z7wxNVFA==} + + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + + readdirp@4.1.2: + resolution: {integrity: sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==} + engines: {node: '>= 14.18.0'} + + readdirp@5.1.1: + resolution: {integrity: sha512-Kko+Y5XQ6fM+Ce3dq3m9YGxnacYZYl9cA1wZjaF3Vbry2L3i1qVg8+CAgNPsXRArPMUMCaOR7oa9Nqntc43JKA==} + engines: {node: '>= 20.19.0'} + + regex-recursion@6.0.2: + resolution: {integrity: sha512-0YCaSCq2VRIebiaUviZNs0cBz1kg5kVS2UKUfNIx8YVs1cN3AV7NTctO5FOKBA+UT2BPJIWZauYHPqJODG50cg==} + + regex-utilities@2.3.0: + resolution: {integrity: sha512-8VhliFJAWRaUiVvREIiW2NXXTmHs4vMNnSzuJVhscgmGav3g9VDxLrQndI3dZZVVdp0ZO/5v0xmX516/7M9cng==} + + regex@6.1.0: + resolution: {integrity: sha512-6VwtthbV4o/7+OaAF9I5L5V3llLEsoPyq9P1JVXkedTP33c7MfCG0/5NOPcSJn0TzXcG9YUrR0gQSWioew3LDg==} + + request-light@0.5.8: + resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==} + + request-light@0.7.0: + resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==} + + require-from-string@2.0.2: + 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==} + + retext-smartypants@6.2.0: + resolution: {integrity: sha512-kk0jOU7+zGv//kfjXEBjdIryL1Acl4i9XNkHxtM7Tm5lFiCog576fjNC9hjoR7LTKQ0DsPWy09JummSsH1uqfQ==} + + rolldown@1.2.12: + resolution: {integrity: sha512-8wafseiaG80xmXSfqidUNqZcylTlhmPZZt+za2m+js2sFZ8dTNlhIOV2WcbIPx2hgwPBJpEUGFAMZ9bgBBLTSQ==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + rollup@4.63.3: resolution: {integrity: sha512-1i2XreiAoMMXuPGD6Msj2xWrMMkHojNRKivInxGQcg7/1KuPuYlfUutLyh4drnOxUTHX9cHI4wFoat8D/NKaBw==} engines: {node: '>=18.0.0', npm: '>=8.0.0'} hasBin: true + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + safer-buffer@2.1.2: resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} + satteri@0.10.5: + resolution: {integrity: sha512-Ao1LKpAEa9Wdg0otgbVKViZHEq9ebdXe4DMrp3s9vQAU0HNIuHnFEuMuOcm0ZIXyV0Yzxj91NvhLpvXZJO/5ZQ==} + + sax@1.6.1: + resolution: {integrity: sha512-42tBVwLWnaQvW5zc4HbZrTuWccECCZfBi92FDuwtqxasH+JbPB3/FOKb1m222K42R4WxuxzzMsTswfzgtSu64Q==} + engines: {node: '>=11.0.0'} + semver@7.8.5: resolution: {integrity: sha512-Y7/KDsb8LjooZpwaqGyulO6DQlksgCncchHGk+sZIY4SBvUocMBEFH5Ur1fI4dV+Jvl0w6cjvucaIi40puRioA==} engines: {node: '>=10'} hasBin: true + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + server-destroy@1.0.1: + resolution: {integrity: sha512-rb+9B5YBIEzYcD6x2VKidaa+cqYBJQKnU4oe4E3ANwRRN56yk/ua1YCJT1n21NTS8w6CcOclAKNP3PhdCXKYtQ==} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.35.4: resolution: {integrity: sha512-n++8XWcj+jCOr2IOl7h8LbKnGBDY4aPbmprMONBNFdn0ImXqpGVv5zliDs0V9HbmbCQLpbuo2ej9rAoOQTvMDA==} engines: {node: '>=20.9.0'} @@ -1610,6 +2853,26 @@ packages: resolution: {integrity: sha512-w1aiOKwKuRgtwAReIIj89puqg+I7GvX4IbLrvmhXbzQsj1+Zwi4VO3+fa6ZF91TWSjIxoEkKnMeHcLEODK5ZXA==} engines: {node: '>= 0.4'} + shiki@4.5.0: + resolution: {integrity: sha512-OcRW72ngQvc+MSVWBRIovC/BTW589iUE/Vxav7VeM4RcY9MUjqB+IR6ILG1k9nuW6LiG/nct9uma4/MBtnZbmQ==} + engines: {node: '>=20'} + + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + siginfo@2.0.0: resolution: {integrity: sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==} @@ -1620,13 +2883,24 @@ packages: sisteransi@1.0.5: resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==} + smol-toml@1.9.0: + resolution: {integrity: sha512-hpd+HLON7HdZXqYchMM/+LaTTbdK0AU3NngIJ4KVyWbY9bfQqdL9cD+4yf6dUoU2Ap4VsU0JkQi6FxAI1B2mXQ==} + engines: {node: '>= 18'} + source-map-js@1.2.1: resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==} engines: {node: '>=0.10.0'} + space-separated-tokens@2.0.2: + resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==} + stackback@0.0.2: resolution: {integrity: sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + std-env@3.10.0: resolution: {integrity: sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==} @@ -1634,10 +2908,25 @@ packages: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} engines: {node: '>=8'} + string-width@7.2.0: + resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==} + engines: {node: '>=18'} + + string-width@8.3.0: + resolution: {integrity: sha512-ZbmZM0JCihQN91dWnxoipT2KOEyHqEyfRXUyjuRhW8b/xnqPDoq4gWEVApTVa9db2wN8mmoikgFBbjh71+cGeQ==} + engines: {node: '>=20'} + + stringify-entities@4.0.4: + resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==} + strip-ansi@6.0.1: resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} engines: {node: '>=8'} + strip-ansi@7.2.0: + resolution: {integrity: sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==} + engines: {node: '>=12'} + strip-literal@3.1.0: resolution: {integrity: sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==} @@ -1645,9 +2934,21 @@ packages: resolution: {integrity: sha512-SS+jx45GF1QjgEXQx4NJZV9ImqmO2NPz5FNsIHrsDjh2YsHnawpan7SNQ1o8NuhrbHZy9AZhIoCUiCeaW/C80g==} engines: {node: '>=18'} + svgo@4.1.0: + resolution: {integrity: sha512-bkxnTg1kSU0guhIBmibA6UUhrQmPVA1XsQLN+ylCd+UWzbnLkySOcXpyk1mrl05f+pcaCx2eHb+sp6BgMZWX+Q==} + engines: {node: '>=16'} + hasBin: true + + tiny-inflate@1.0.3: + resolution: {integrity: sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==} + tinybench@2.9.0: resolution: {integrity: sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==} + tinyclip@1.0.3: + resolution: {integrity: sha512-nTv2raKFMzGG6JJp0lpNDsRPdfFE6UHlu2rVEjXo8vkx1ZS3LW2CVXqIaLu8xZlu+6tbFs9V58Qc/Jmk/Ii7wA==} + engines: {node: ^16.14.0 || >= 17.3.0} + tinyexec@0.3.2: resolution: {integrity: sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==} @@ -1679,27 +2980,167 @@ packages: resolution: {integrity: sha512-u8KszXvGfU68hVcZpRHKG28T0krMuv2G5nDhiHaMLen/gIuFEgIJhaJuO69qjnXg5paSrbPMFfx3brNuN8eVSg==} engines: {node: '>=14.0.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + + trim-lines@3.0.1: + resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} + + trough@2.2.0: + resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==} + tslib@2.7.0: resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==} + tweetnacl@1.0.3: + resolution: {integrity: sha512-6rt+RN7aOi1nGMyC4Xa5DdYiukl2UWCbcJft7YhxReBGQD7OAM8Pbxw6YMo4r2diNEA8FEmu32YOn9rhaiE5yw==} + + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + + typesafe-path@0.2.2: + resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==} + + typescript-auto-import-cache@0.3.6: + resolution: {integrity: sha512-RpuHXrknHdVdK7wv/8ug3Fr0WNsNi5l5aB8MYYuXhq2UH5lnEB1htJ1smhtD5VeCsGr2p8mUDtd83LCQDFVgjQ==} + typescript@5.9.3: resolution: {integrity: sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==} engines: {node: '>=14.17'} hasBin: true + ufo@1.6.4: + resolution: {integrity: sha512-JFNbkD1Svwe0KvGi8GOeLcP4kAWQ609twvCdcHxq1oSL8svv39ZuSvajcD8B+5D0eL4+s1Is2D/O6KN3qcTeRA==} + + ultrahtml@1.7.0: + resolution: {integrity: sha512-2xRd0VHoAQE4M+vF/DvFFB7pUV0ZxTW1TLi7lHQWnF/Sb5TPeEUV/l+hxcNnGO00ZXGnR0voCMmYRKQf+rvJ2g==} + + uncrypto@0.1.3: + resolution: {integrity: sha512-Ql87qFHB3s/De2ClA9e0gsnS6zXG27SkTiSJwjCc9MebbfapQfuPzumMIUMi38ezPZVNFcHI9sUIepeQfw8J8Q==} + undici-types@6.19.8: resolution: {integrity: sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==} undici-types@6.21.0: resolution: {integrity: sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==} + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + undici@7.29.0: resolution: {integrity: sha512-IDxfleLmmbSskfWSUATiN1nfn2rDuvnMOqb5CWR92iIfojA0Ud+ulOAAEQ57LPr9rWmsreUyf5lwyao+7GNNVw==} engines: {node: '>=20.18.1'} + undici@8.11.2: + resolution: {integrity: sha512-u4UB2/IrKdU6lFxumHmmo1a3fCQO5tzQllRorfoRS63txhrB7xTpSn1PftwC4qEHkOaqP95fCWW4lJzwErwzhQ==} + engines: {node: '>=22.19.0'} + unenv@2.0.0-rc.24: resolution: {integrity: sha512-i7qRCmY42zmCwnYlh9H2SvLEypEFGye5iRmEMKjcGi7zk9UquigRjFtTLz0TYqr0ZGLZhaMHl/foy1bZR+Cwlw==} + unified@11.0.5: + resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} + + unifont@0.7.5: + resolution: {integrity: sha512-ULe/Cs+ZIsq+dcFofNkhqielCrUJnb5mr+Yc4EBM2VlL+6OZR6+cjtI2mT1bJvRBrVncqHAbLURxmPLcCXzWMg==} + + unist-util-is@6.0.1: + resolution: {integrity: sha512-LsiILbtBETkDz8I9p1dQ0uyRUWuaQzd/cuEeS1hoRSyW5E5XGmTzlwY1OrNzzakGowI9Dr/I8HVaw4hTtnxy8g==} + + unist-util-position@5.0.0: + resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==} + + unist-util-stringify-position@4.0.0: + resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==} + + unist-util-visit-parents@6.0.2: + resolution: {integrity: sha512-goh1s1TBrqSqukSc8wrjwWhL0hiJxgA8m4kFxGlQ+8FYQ3C/m11FcTs4YYem7V664AhHVvgoQLk890Ssdsr2IQ==} + + unist-util-visit@5.1.0: + resolution: {integrity: sha512-m+vIdyeCOpdr/QeQCu2EzxX/ohgS8KbnPDgFni4dQsfSCtpz8UqDyY5GjRru8PDKuYn7Fq19j1CQ+nJSsGKOzg==} + + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + + unstorage@1.17.5: + resolution: {integrity: sha512-0i3iqvRfx29hkNntHyQvJTpf5W9dQ9ZadSoRU8+xVlhVtT7jAX57fazYO9EHvcRCfBCyi5YRya7XCDOsbTgkPg==} + peerDependencies: + '@azure/app-configuration': ^1.8.0 + '@azure/cosmos': ^4.2.0 + '@azure/data-tables': ^13.3.0 + '@azure/identity': ^4.6.0 + '@azure/keyvault-secrets': ^4.9.0 + '@azure/storage-blob': ^12.26.0 + '@capacitor/preferences': ^6 || ^7 || ^8 + '@deno/kv': '>=0.9.0' + '@netlify/blobs': ^6.5.0 || ^7.0.0 || ^8.1.0 || ^9.0.0 || ^10.0.0 + '@planetscale/database': ^1.19.0 + '@upstash/redis': ^1.34.3 + '@vercel/blob': '>=0.27.1' + '@vercel/functions': ^2.2.12 || ^3.0.0 + '@vercel/kv': ^1 || ^2 || ^3 + aws4fetch: ^1.0.20 + db0: '>=0.2.1' + idb-keyval: ^6.2.1 + ioredis: ^5.4.2 + uploadthing: ^7.4.4 + peerDependenciesMeta: + '@azure/app-configuration': + optional: true + '@azure/cosmos': + optional: true + '@azure/data-tables': + optional: true + '@azure/identity': + optional: true + '@azure/keyvault-secrets': + optional: true + '@azure/storage-blob': + optional: true + '@capacitor/preferences': + optional: true + '@deno/kv': + optional: true + '@netlify/blobs': + optional: true + '@planetscale/database': + optional: true + '@upstash/redis': + optional: true + '@vercel/blob': + optional: true + '@vercel/functions': + optional: true + '@vercel/kv': + optional: true + aws4fetch: + optional: true + db0: + optional: true + idb-keyval: + optional: true + ioredis: + optional: true + uploadthing: + optional: true + + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + + verkit@0.5.0: + resolution: {integrity: sha512-u4J1hr6Y+C/hit34GwL3eIcUf3wngT8TlYUjK7tk0jxydKLAq3sYvifjdTDA6U3KCKRcQCQDGf/srjxfZF3l7g==} + engines: {node: '>=18.12.0'} + + vfile-message@4.0.3: + resolution: {integrity: sha512-QTHzsGd1EhbZs4AsQ20JX1rC3cOlt/IWJruk893DfLRr57lcnOeMaWG4K0JrRta4mIJZKth2Au3mM3u03/JWKw==} + + vfile@6.0.3: + resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==} + viem@2.56.5: resolution: {integrity: sha512-GuEf/oee0PHgy4D6JIA8u0rY1g+sM5nF+p7HyMHO3vjlHC5G/ljfrgnUOnrES9m5Ny/P3RwWCHjDuN2T6HUWzQ==} peerDependencies: @@ -1749,6 +3190,57 @@ packages: terser: optional: true + vite@8.3.3: + resolution: {integrity: sha512-cTAldKPImjg6c+gk48U19POPn3GCBzZwpdsN8ZMEEcbpes+6/wvfqUd0C2y3qYY4wsj8PwgFwrZ/1jBPVttMSg==} + engines: {node: ^20.19.0 || >=22.12.0} + hasBin: true + peerDependencies: + '@types/node': ^20.19.0 || >=22.12.0 + '@vitejs/devtools': ^0.7.1 + esbuild: ^0.27.0 || ^0.28.0 + jiti: '>=1.21.0' + less: ^4.0.0 + sass: ^1.70.0 + sass-embedded: ^1.70.0 + stylus: '>=0.54.8' + sugarss: ^5.0.0 + terser: ^5.16.0 + tsx: ^4.8.1 + yaml: ^2.4.2 + peerDependenciesMeta: + '@types/node': + optional: true + '@vitejs/devtools': + optional: true + esbuild: + optional: true + jiti: + optional: true + less: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + tsx: + optional: true + yaml: + optional: true + + vitefu@1.1.3: + resolution: {integrity: sha512-ub4okH7Z5KLjb6hDyjqrGXqWtWvoYdU3IGm/NorpgHncKoLTCfRIbvlhBm7r0YstIaQRYlp4yEbFqDcKSzXSSg==} + peerDependencies: + vite: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + vite: + optional: true + vitest@2.1.9: resolution: {integrity: sha512-MSmPM9REYqDGBI8439mA4mWhV5sKmDlBKWIYbA3lRb2PTHACE0mgKwA8yQ2xq9vxDTuk4iPrECBAEW2aoFXY0Q==} engines: {node: ^18.0.0 || >=20.0.0} @@ -1791,17 +3283,119 @@ packages: optional: true '@types/debug': optional: true - '@types/node': + '@types/node': + optional: true + '@vitest/browser': + optional: true + '@vitest/ui': + optional: true + happy-dom: + optional: true + jsdom: + optional: true + + volar-service-css@0.0.71: + resolution: {integrity: sha512-wRRFt9BpjMKCazcgOh67MSjUjiWUCAh99DyYSDIOTuxaRjEtDC7PpB0k1Y1wbJIW/pVtMUSVbpPo3UGSm0Byxw==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-emmet@0.0.71: + resolution: {integrity: sha512-zqjzt6bN95e3CUstBm0PBFAJnrfz0ZAARka87fart46/gNCLLuP3Vujy8V/J8HEziTFLnfkgIASLFYPUhonJcA==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-html@0.0.71: + resolution: {integrity: sha512-e8tHPhgQ7ooLfudAEIku+kgd9pWkq3SSz8RbnQDI1+Eb8wbenkLGHqoirLqz5ORLV6wIMr2Iv08RWBG5eOcgpw==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': + optional: true + + volar-service-prettier@0.0.71: + resolution: {integrity: sha512-Rz7JVH3qD108UCdmIEiZvOBNljMt2nLFdbN8AXcDfn7xD9F5I2aCIsDVqBbXw21PsnxG0b7MfwtNF+zPS/NKUg==} + peerDependencies: + '@volar/language-service': ~2.4.0 + prettier: ^2.2 || ^3.0 + peerDependenciesMeta: + '@volar/language-service': optional: true - '@vitest/browser': + prettier: optional: true - '@vitest/ui': + + volar-service-typescript-twoslash-queries@0.0.71: + resolution: {integrity: sha512-9K2k72s4n7rV9s4bX0MyjbX9iBribvKZbBJKuEmTCZfeWJXs6Yh7bGpY4eoc7UufAjvpheBqwyZCOIPBvxCv0A==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': optional: true - happy-dom: + + volar-service-typescript@0.0.71: + resolution: {integrity: sha512-yTtM/BVT6hoyEYnDtaCyAtNhdNeS/mhTTABlBOdw3NNiRBUin3IznFJpgfjer4c6RYopiPjjQjc9VFhxVl1mLw==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': optional: true - jsdom: + + volar-service-yaml@0.0.71: + resolution: {integrity: sha512-qYGWGuVpUTnZGu5P/CR4KLK4aIR8RrcVnmfZ2eRcj9q/I8VZCoC5yy9FtEvfNvnDp4MU17yhdJcvpQPIqhJS2Q==} + peerDependencies: + '@volar/language-service': ~2.4.0 + peerDependenciesMeta: + '@volar/language-service': optional: true + vscode-css-languageservice@6.3.10: + resolution: {integrity: sha512-eq5N9Er3fC4vA9zd9EFhyBG90wtCCuXgRSpAndaOgXMh1Wgep5lBgRIeDgjZBW9pa+332yC9+49cZMW8jcL3MA==} + + vscode-html-languageservice@5.6.2: + resolution: {integrity: sha512-ulCrSnFnfQ16YzvwnYUgEbUEl/ZG7u2eV27YhvLObSHKkb8fw1Z9cgsnUwjTEeDIdJDoTDTDpxuhQwoenoLNMg==} + + vscode-json-languageservice@4.1.8: + resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==} + engines: {npm: '>=7.0.0'} + + vscode-jsonrpc@8.2.0: + resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==} + engines: {node: '>=14.0.0'} + + vscode-jsonrpc@9.0.3: + resolution: {integrity: sha512-qETYf9PCl1lVfwR+oBmMfc4vP2nqLNA35ABxorw3j06+xlKRgDVxbLgKm4Y/xPL0YWdeDjLoI4ImICIT3nB0zQ==} + engines: {node: '>=14.0.0'} + + vscode-languageserver-protocol@3.17.5: + resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==} + + vscode-languageserver-protocol@3.18.4: + resolution: {integrity: sha512-CCXbyr99dafRJzJH/0Ryk7ly5T8XPmSR0//OuF2w4m+9JiOin7zcAT5iET8GRE7Z9taFBejb3GbM0a0mbjdbrg==} + + vscode-languageserver-textdocument@1.0.15: + resolution: {integrity: sha512-Gsfr9S8LU3S6885cS+NaleasJ0n3V5y/SOTqHCifQiXWFw3G9w9/YItDfwHrlCz+dSZWWZ8ilYVMcJe7Sz7Sxw==} + + vscode-languageserver-types@3.17.5: + resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==} + + vscode-languageserver-types@3.18.4: + resolution: {integrity: sha512-nQsacoiijvl0fRf2q28uFDrAVwRhdCa3QveiF7/CX0r18mLR5FU/1WskSsCKOjmEbtteKUnY8x8Yzxop+k0zwg==} + + vscode-languageserver@9.0.1: + resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==} + hasBin: true + + vscode-nls@5.2.0: + resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==} + + vscode-uri@3.2.0: + resolution: {integrity: sha512-m2gXo3bn0G1kT9InzMf07fTbqMbGtyckj3bH5ktLO+1Ssv+yiATZ4dhwaQv9UZWxJh6E9IFGnQyjgWVDWVBDrg==} + why-is-node-running@2.3.0: resolution: {integrity: sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==} engines: {node: '>=8'} @@ -1826,6 +3420,13 @@ packages: resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} engines: {node: '>=8'} + wrap-ansi@9.0.2: + resolution: {integrity: sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==} + engines: {node: '>=18'} + + wrappy@1.0.2: + resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + ws@8.21.0: resolution: {integrity: sha512-Vsp28b7DRcimFQvrqu2Wek3z1iYxDCWqHYB8Qsnk/S4RfaCQzPGPyBNuVjJV3cd6UiKtUtp6sNM77gWvzcCH+g==} engines: {node: '>=10.0.0'} @@ -1838,11 +3439,39 @@ packages: utf-8-validate: optional: true + xxhash-wasm@1.1.0: + resolution: {integrity: sha512-147y/6YNh+tlp6nd/2pWq38i9h6mz/EuQ6njIrmW8D1BS5nCqs0P6DG+m6zTGnNz5I+uhZ0SHxBs9BsPrwcKDA==} + + y18n@5.0.8: + resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} + engines: {node: '>=10'} + + yaml-language-server@1.23.0: + resolution: {integrity: sha512-3qVyCOexLCWw06PQa5kRPwvMWMZ/eZeCRWUvgD6a0OkqL/4iCnxy2WumbWifa937Uo5xhyWJ0uxlU39ljhNh7A==} + hasBin: true + + yaml@2.8.3: + resolution: {integrity: sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==} + engines: {node: '>= 14.6'} + hasBin: true + yaml@2.9.1: resolution: {integrity: sha512-3NxN8+78OdzbT7C/WjGsyfPAtJaN3FNDsWxv7Y7mcDsT/oOmgW8BpyQQFFBnvZE3j9Y2Sdz1ULFLezL7Eb2yFw==} engines: {node: '>= 14.6'} hasBin: true + yargs-parser@22.0.0: + resolution: {integrity: sha512-rwu/ClNdSMpkSrUb+d6BRsSkLUq1fmfsY6TOpYzTwvwkg1/NRG85KBy3kq++A8LKQwX6lsu+aWad+2khvuXrqw==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yargs@18.2.0: + resolution: {integrity: sha512-9OpKOLeaoNFecEp7P6iYbzze/5CqWoH7N3SMs/6y1XF4nMvFMspEGZzJ6uFi9MmQwXhyzqYoSEKO3tvA3Z/o2w==} + engines: {node: ^20.19.0 || ^22.12.0 || >=23} + + yocto-queue@1.2.2: + resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} + engines: {node: '>=12.20'} + yoctocolors-cjs@2.1.3: resolution: {integrity: sha512-U/PBtDf35ff0D8X8D0jfdzHYEPFxAI7jJlxZXwCSez5M3190m+QobIfh+sWDWSHMCWWJN2AWamkegn6vr6YBTw==} engines: {node: '>=18'} @@ -1856,10 +3485,201 @@ packages: zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} + zod@4.6.5: + resolution: {integrity: sha512-v5l/aFXZQeai4awLbOpSoHecE9UiMrnfx75tEXLjNonXVARxQ5mOeipTjROUchszUNCqnE+hqAMujRsRHsut2Q==} + + zwitch@2.0.4: + resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} + snapshots: '@adraffy/ens-normalize@1.11.1': {} + '@astrojs/astro2tsx@0.1.2(@emnapi/runtime@1.11.3)': + dependencies: + '@emnapi/core': 1.11.3 + '@napi-rs/wasm-runtime': 1.2.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3) + transitivePeerDependencies: + - '@emnapi/runtime' + + '@astrojs/check@0.9.10(@emnapi/runtime@1.11.3)(prettier@3.9.9)(typescript@5.9.3)': + dependencies: + '@astrojs/language-server': 2.17.1(@emnapi/runtime@1.11.3)(prettier@3.9.9)(typescript@5.9.3) + chokidar: 4.0.3 + kleur: 4.1.5 + typescript: 5.9.3 + yargs: 18.2.0 + transitivePeerDependencies: + - '@emnapi/runtime' + - prettier + - prettier-plugin-astro + + '@astrojs/compiler-binding-android-arm64@0.5.1': + optional: true + + '@astrojs/compiler-binding-darwin-arm64@0.5.1': + optional: true + + '@astrojs/compiler-binding-darwin-x64@0.5.1': + optional: true + + '@astrojs/compiler-binding-linux-arm64-gnu@0.5.1': + optional: true + + '@astrojs/compiler-binding-linux-arm64-musl@0.5.1': + optional: true + + '@astrojs/compiler-binding-linux-x64-gnu@0.5.1': + optional: true + + '@astrojs/compiler-binding-linux-x64-musl@0.5.1': + optional: true + + '@astrojs/compiler-binding-wasm32-wasi@0.5.1': + dependencies: + '@emnapi/core': 1.11.3 + '@emnapi/runtime': 1.11.3 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3) + optional: true + + '@astrojs/compiler-binding-win32-arm64-msvc@0.5.1': + optional: true + + '@astrojs/compiler-binding-win32-x64-msvc@0.5.1': + optional: true + + '@astrojs/compiler-binding@0.5.1': + optionalDependencies: + '@astrojs/compiler-binding-android-arm64': 0.5.1 + '@astrojs/compiler-binding-darwin-arm64': 0.5.1 + '@astrojs/compiler-binding-darwin-x64': 0.5.1 + '@astrojs/compiler-binding-linux-arm64-gnu': 0.5.1 + '@astrojs/compiler-binding-linux-arm64-musl': 0.5.1 + '@astrojs/compiler-binding-linux-x64-gnu': 0.5.1 + '@astrojs/compiler-binding-linux-x64-musl': 0.5.1 + '@astrojs/compiler-binding-wasm32-wasi': 0.5.1 + '@astrojs/compiler-binding-win32-arm64-msvc': 0.5.1 + '@astrojs/compiler-binding-win32-x64-msvc': 0.5.1 + + '@astrojs/compiler-rs@0.5.1': + dependencies: + '@astrojs/compiler-binding': 0.5.1 + + '@astrojs/internal-helpers@0.12.0': + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + picomatch: 4.0.7 + retext-smartypants: 6.2.0 + shiki: 4.5.0 + smol-toml: 1.9.0 + unified: 11.0.5 + yaml: 2.9.1 + + '@astrojs/language-server@2.17.1(@emnapi/runtime@1.11.3)(prettier@3.9.9)(typescript@5.9.3)': + dependencies: + '@astrojs/astro2tsx': 0.1.2(@emnapi/runtime@1.11.3) + '@astrojs/yaml2ts': 0.2.4 + '@volar/kit': 2.4.28(typescript@5.9.3) + '@volar/language-core': 2.4.28 + '@volar/language-server': 2.4.28 + '@volar/language-service': 2.4.28 + muggle-string: 0.4.1 + tinyglobby: 0.2.17 + volar-service-css: 0.0.71(@volar/language-service@2.4.28) + volar-service-emmet: 0.0.71(@volar/language-service@2.4.28) + volar-service-html: 0.0.71(@volar/language-service@2.4.28) + volar-service-prettier: 0.0.71(@volar/language-service@2.4.28)(prettier@3.9.9) + volar-service-typescript: 0.0.71(@volar/language-service@2.4.28) + volar-service-typescript-twoslash-queries: 0.0.71(@volar/language-service@2.4.28) + volar-service-yaml: 0.0.71(@volar/language-service@2.4.28) + vscode-html-languageservice: 5.6.2 + vscode-uri: 3.2.0 + optionalDependencies: + prettier: 3.9.9 + transitivePeerDependencies: + - '@emnapi/runtime' + - typescript + + '@astrojs/markdown-satteri@0.4.3': + dependencies: + '@astrojs/internal-helpers': 0.12.0 + '@astrojs/prism': 4.0.2 + github-slugger: 2.0.0 + satteri: 0.10.5 + + '@astrojs/node@11.1.7(astro@7.3.6(@types/node@24.19.0)(yaml@2.9.1))': + dependencies: + '@astrojs/internal-helpers': 0.12.0 + astro: 7.3.6(@types/node@24.19.0)(yaml@2.9.1) + send: 1.2.1 + server-destroy: 1.0.1 + transitivePeerDependencies: + - supports-color + + '@astrojs/prism@4.0.2': + dependencies: + prismjs: 1.30.0 + + '@astrojs/telemetry@3.3.3': + dependencies: + ci-info: 4.4.0 + dset: 3.1.4 + is-docker: 4.0.0 + package-manager-detector: 1.8.0 + + '@astrojs/yaml2ts@0.2.4': + dependencies: + yaml: 2.9.1 + + '@babel/helper-string-parser@7.29.7': {} + + '@babel/helper-validator-identifier@7.29.7': {} + + '@babel/parser@7.29.9': + dependencies: + '@babel/types': 7.29.8 + + '@babel/types@7.29.8': + dependencies: + '@babel/helper-string-parser': 7.29.7 + '@babel/helper-validator-identifier': 7.29.7 + + '@bruits/satteri-darwin-arm64@0.10.5': + optional: true + + '@bruits/satteri-darwin-x64@0.10.5': + optional: true + + '@bruits/satteri-linux-arm64-gnu@0.10.5': + optional: true + + '@bruits/satteri-linux-arm64-musl@0.10.5': + optional: true + + '@bruits/satteri-linux-x64-gnu@0.10.5': + optional: true + + '@bruits/satteri-linux-x64-musl@0.10.5': + optional: true + + '@bruits/satteri-wasm32-wasi@0.10.5': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@napi-rs/wasm-runtime': 1.2.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1) + optional: true + + '@bruits/satteri-win32-arm64-msvc@0.10.5': + optional: true + + '@bruits/satteri-win32-x64-msvc@0.10.5': + optional: true + + '@capsizecss/unpack@4.0.1': + dependencies: + fontkitten: 1.0.3 + '@changesets/apply-release-plan@8.1.1': dependencies: '@changesets/config': 4.0.1 @@ -2005,11 +3825,58 @@ snapshots: dependencies: '@jridgewell/trace-mapping': 0.3.9 + '@emmetio/abbreviation@2.3.3': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/css-abbreviation@2.1.8': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/css-parser@0.4.1': + dependencies: + '@emmetio/stream-reader': 2.2.0 + '@emmetio/stream-reader-utils': 0.1.0 + + '@emmetio/html-matcher@1.3.0': + dependencies: + '@emmetio/scanner': 1.0.4 + + '@emmetio/scanner@1.0.4': {} + + '@emmetio/stream-reader-utils@0.1.0': {} + + '@emmetio/stream-reader@2.2.0': {} + + '@emnapi/core@1.11.1': + dependencies: + '@emnapi/wasi-threads': 1.2.2 + tslib: 2.7.0 + optional: true + + '@emnapi/core@1.11.3': + dependencies: + '@emnapi/wasi-threads': 1.2.3 + tslib: 2.7.0 + + '@emnapi/runtime@1.11.1': + dependencies: + tslib: 2.7.0 + optional: true + '@emnapi/runtime@1.11.3': dependencies: tslib: 2.7.0 + + '@emnapi/wasi-threads@1.2.2': + dependencies: + tslib: 2.7.0 optional: true + '@emnapi/wasi-threads@1.2.3': + dependencies: + tslib: 2.7.0 + '@esbuild/aix-ppc64@0.21.5': optional: true @@ -2554,6 +4421,26 @@ snapshots: '@napi-rs/lzma-linux-x64-gnu@1.5.1': optional: true + '@napi-rs/wasm-runtime@1.2.4(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)': + dependencies: + '@emnapi/core': 1.11.3 + '@emnapi/runtime': 1.11.3 + '@tybys/wasm-util': 0.10.4 + + '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.11.1)(@emnapi/runtime@1.11.1)': + dependencies: + '@emnapi/core': 1.11.1 + '@emnapi/runtime': 1.11.1 + '@tybys/wasm-util': 0.10.4 + optional: true + + '@napi-rs/wasm-runtime@1.2.5(@emnapi/core@1.11.3)(@emnapi/runtime@1.11.3)': + dependencies: + '@emnapi/core': 1.11.3 + '@emnapi/runtime': 1.11.3 + '@tybys/wasm-util': 0.10.4 + optional: true + '@noble/ciphers@1.3.0': {} '@noble/curves@1.2.0': @@ -2574,6 +4461,10 @@ snapshots: '@noble/hashes@2.4.0': {} + '@oslojs/encoding@1.1.0': {} + + '@oxc-project/types@0.152.0': {} + '@pnpm/deps.graph-sequencer@1100.0.1': {} '@poppinss/colors@4.1.6': @@ -2588,6 +4479,53 @@ snapshots: '@poppinss/exception@1.2.3': {} + '@rolldown/binding-android-arm-eabi@1.2.12': + optional: true + + '@rolldown/binding-android-arm64@1.2.12': + optional: true + + '@rolldown/binding-darwin-arm64@1.2.12': + optional: true + + '@rolldown/binding-darwin-x64@1.2.12': + optional: true + + '@rolldown/binding-freebsd-x64@1.2.12': + optional: true + + '@rolldown/binding-linux-arm-gnueabihf@1.2.12': + optional: true + + '@rolldown/binding-linux-arm64-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-arm64-musl@1.2.12': + optional: true + + '@rolldown/binding-linux-ppc64-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-s390x-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-x64-gnu@1.2.12': + optional: true + + '@rolldown/binding-linux-x64-musl@1.2.12': + optional: true + + '@rolldown/binding-openharmony-arm64@1.2.12': + optional: true + + '@rolldown/binding-win32-arm64-msvc@1.2.12': + optional: true + + '@rolldown/binding-win32-x64-msvc@1.2.12': + optional: true + + '@rolldown/pluginutils@1.0.1': {} + '@rollup/rollup-android-arm-eabi@4.63.3': optional: true @@ -2676,19 +4614,115 @@ snapshots: '@noble/hashes': 1.8.0 '@scure/base': 1.2.6 + '@shikijs/core@4.5.0': + dependencies: + '@shikijs/primitive': 4.5.0 + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + hast-util-to-html: 9.0.5 + + '@shikijs/engine-javascript@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + oniguruma-to-es: 4.3.6 + + '@shikijs/engine-oniguruma@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + + '@shikijs/langs@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + + '@shikijs/primitive@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/themes@4.5.0': + dependencies: + '@shikijs/types': 4.5.0 + + '@shikijs/types@4.5.0': + dependencies: + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + '@shikijs/vscode-textmate@10.0.2': {} + + '@signinwithethereum/siwe-parser@4.2.1': + dependencies: + '@noble/hashes': 1.8.0 + apg-js: 4.4.0 + + '@signinwithethereum/siwe@4.2.1(ethers@6.17.0)(viem@2.56.5(typescript@5.9.3)(zod@4.6.5))': + dependencies: + '@signinwithethereum/siwe-parser': 4.2.1 + optionalDependencies: + ethers: 6.17.0 + viem: 2.56.5(typescript@5.9.3)(zod@4.6.5) + '@sindresorhus/is@7.2.0': {} '@speed-highlight/core@1.2.24': {} + '@tybys/wasm-util@0.10.4': + dependencies: + tslib: 2.7.0 + + '@types/body-parser@1.19.6': + dependencies: + '@types/connect': 3.4.38 + '@types/node': 24.19.0 + '@types/chai@5.2.3': dependencies: '@types/deep-eql': 4.0.2 assertion-error: 2.0.1 + '@types/connect@3.4.38': + dependencies: + '@types/node': 24.19.0 + '@types/deep-eql@4.0.2': {} + '@types/estree-jsx@1.0.5': + dependencies: + '@types/estree': 1.0.9 + '@types/estree@1.0.9': {} + '@types/express-serve-static-core@5.1.3': + dependencies: + '@types/node': 24.19.0 + '@types/qs': 6.15.1 + '@types/range-parser': 1.2.7 + '@types/send': 1.2.1 + + '@types/express@5.0.6': + dependencies: + '@types/body-parser': 1.19.6 + '@types/express-serve-static-core': 5.1.3 + '@types/serve-static': 2.2.0 + + '@types/hast@3.0.5': + dependencies: + '@types/unist': 3.0.3 + + '@types/http-errors@2.0.5': {} + + '@types/mdast@4.0.4': + dependencies: + '@types/unist': 3.0.3 + + '@types/nlcst@2.0.3': + dependencies: + '@types/unist': 3.0.3 + '@types/node@22.20.3': dependencies: undici-types: 6.21.0 @@ -2697,6 +4731,27 @@ snapshots: dependencies: undici-types: 6.19.8 + '@types/node@24.19.0': + dependencies: + undici-types: 7.24.6 + + '@types/qs@6.15.1': {} + + '@types/range-parser@1.2.7': {} + + '@types/send@1.2.1': + dependencies: + '@types/node': 24.19.0 + + '@types/serve-static@2.2.0': + dependencies: + '@types/http-errors': 2.0.5 + '@types/node': 24.19.0 + + '@types/unist@3.0.3': {} + + '@ungap/structured-clone@1.4.0': {} + '@vitest/expect@2.1.9': dependencies: '@vitest/spy': 2.1.9 @@ -2712,21 +4767,21 @@ snapshots: chai: 5.3.3 tinyrainbow: 2.0.0 - '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.20.3))': + '@vitest/mocker@2.1.9(vite@5.4.21(@types/node@22.20.3)(lightningcss@1.33.0))': dependencies: '@vitest/spy': 2.1.9 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 5.4.21(@types/node@22.20.3) + vite: 5.4.21(@types/node@22.20.3)(lightningcss@1.33.0) - '@vitest/mocker@3.2.7(vite@5.4.21(@types/node@22.20.3))': + '@vitest/mocker@3.2.7(vite@5.4.21(@types/node@24.19.0)(lightningcss@1.33.0))': dependencies: '@vitest/spy': 3.2.7 estree-walker: 3.0.3 magic-string: 0.30.21 optionalDependencies: - vite: 5.4.21(@types/node@22.20.3) + vite: 5.4.21(@types/node@24.19.0)(lightningcss@1.33.0) '@vitest/pretty-format@2.1.9': dependencies: @@ -2779,17 +4834,95 @@ snapshots: loupe: 3.2.1 tinyrainbow: 2.0.0 - '@x402/core@2.25.0': + '@volar/kit@2.4.28(typescript@5.9.3)': dependencies: + '@volar/language-service': 2.4.28 + '@volar/typescript': 2.4.28 + typesafe-path: 0.2.2 + typescript: 5.9.3 + vscode-languageserver-textdocument: 1.0.15 + vscode-uri: 3.2.0 + + '@volar/language-core@2.4.28': + dependencies: + '@volar/source-map': 2.4.28 + + '@volar/language-server@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + '@volar/language-service': 2.4.28 + '@volar/typescript': 2.4.28 + path-browserify: 1.0.1 + request-light: 0.7.0 + vscode-languageserver: 9.0.1 + vscode-languageserver-protocol: 3.18.4 + vscode-languageserver-textdocument: 1.0.15 + vscode-uri: 3.2.0 + + '@volar/language-service@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + vscode-languageserver-protocol: 3.18.4 + vscode-languageserver-textdocument: 1.0.15 + vscode-uri: 3.2.0 + + '@volar/source-map@2.4.28': {} + + '@volar/typescript@2.4.28': + dependencies: + '@volar/language-core': 2.4.28 + path-browserify: 1.0.1 + vscode-uri: 3.2.0 + + '@vscode/emmet-helper@2.11.0': + dependencies: + emmet: 2.4.11 + jsonc-parser: 2.3.1 + vscode-languageserver-textdocument: 1.0.15 + vscode-languageserver-types: 3.18.4 + vscode-uri: 3.2.0 + + '@vscode/l10n@0.0.18': {} + + '@x402/core@2.27.0': + dependencies: + zod: 3.25.76 + + '@x402/evm@2.27.0(typescript@5.9.3)': + dependencies: + '@x402/core': 2.27.0 + viem: 2.56.5(typescript@5.9.3)(zod@3.25.76) zod: 3.25.76 + transitivePeerDependencies: + - bufferutil + - typescript + - utf-8-validate + + '@x402/express@2.27.0(ethers@6.17.0)(express@5.2.1)(typescript@5.9.3)': + dependencies: + '@x402/core': 2.27.0 + '@x402/extensions': 2.27.0(ethers@6.17.0)(typescript@5.9.3) + express: 5.2.1 + transitivePeerDependencies: + - bufferutil + - ethers + - typescript + - utf-8-validate - '@x402/evm@2.25.0(typescript@5.9.3)': + '@x402/extensions@2.27.0(ethers@6.17.0)(typescript@5.9.3)': dependencies: - '@x402/core': 2.25.0 + '@noble/curves': 1.9.1 + '@scure/base': 1.2.6 + '@signinwithethereum/siwe': 4.2.1(ethers@6.17.0)(viem@2.56.5(typescript@5.9.3)(zod@4.6.5)) + '@x402/core': 2.27.0 + ajv: 8.20.0 + jose: 5.10.0 + tweetnacl: 1.0.3 viem: 2.56.5(typescript@5.9.3)(zod@3.25.76) zod: 3.25.76 transitivePeerDependencies: - bufferutil + - ethers - typescript - utf-8-validate @@ -2798,22 +4931,187 @@ snapshots: typescript: 5.9.3 zod: 3.25.76 + abitype@1.2.3(typescript@5.9.3)(zod@4.6.5): + optionalDependencies: + typescript: 5.9.3 + zod: 4.6.5 + + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.1.0 + aes-js@4.0.0-beta.5: {} + ajv-draft-04@1.0.0(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv-i18n@4.2.0(ajv@8.20.0): + dependencies: + ajv: 8.20.0 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.8 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + + am-i-vibing@0.5.0: + dependencies: + process-ancestry: 0.1.0 + ansi-regex@5.0.1: {} + ansi-regex@6.4.0: {} + ansi-styles@4.3.0: dependencies: color-convert: 2.0.1 + ansi-styles@6.2.3: {} + + anymatch@3.1.3: + dependencies: + normalize-path: 3.0.0 + picomatch: 2.3.2 + + apg-js@4.4.0: {} + + aria-query@5.3.2: {} + assertion-error@2.0.1: {} + astro@7.3.6(@types/node@24.19.0)(yaml@2.9.1): + dependencies: + '@astrojs/compiler-rs': 0.5.1 + '@astrojs/internal-helpers': 0.12.0 + '@astrojs/markdown-satteri': 0.4.3 + '@astrojs/telemetry': 3.3.3 + '@capsizecss/unpack': 4.0.1 + '@clack/prompts': 1.8.1 + '@oslojs/encoding': 1.1.0 + am-i-vibing: 0.5.0 + aria-query: 5.3.2 + axobject-query: 4.1.0 + ci-info: 4.4.0 + clsx: 2.1.1 + common-ancestor-path: 2.0.0 + cookie: 2.0.1 + devalue: 5.9.4 + diff: 9.0.0 + dset: 3.1.4 + es-module-lexer: 3.0.3 + esbuild: 0.28.1 + find-proc: 0.2.0 + flattie: 1.1.1 + fontace: 0.4.1 + get-tsconfig: 5.0.0-beta.6 + github-slugger: 2.0.0 + html-escaper: 3.0.3 + http-cache-semantics: 4.3.0 + jsonc-parser: 3.3.1 + magic-string: 1.4.3 + magicast: 0.5.5 + mrmime: 2.0.1 + neotraverse: 1.0.1 + obug: 3.0.0 + p-limit: 7.3.3 + p-queue: 9.3.3 + package-manager-detector: 1.8.0 + piccolore: 0.1.3 + picomatch: 4.0.7 + rolldown: 1.2.12 + shiki: 4.5.0 + smol-toml: 1.9.0 + svgo: 4.1.0 + tinyclip: 1.0.3 + tinyexec: 1.3.1 + tinyglobby: 0.2.17 + ultrahtml: 1.7.0 + unifont: 0.7.5 + unstorage: 1.17.5 + verkit: 0.5.0 + vite: 8.3.3(@types/node@24.19.0)(esbuild@0.28.1)(yaml@2.9.1) + vitefu: 1.1.3(vite@8.3.3(@types/node@24.19.0)(esbuild@0.28.1)(yaml@2.9.1)) + xxhash-wasm: 1.1.0 + yargs-parser: 22.0.0 + zod: 4.6.5 + optionalDependencies: + sharp: 0.35.4(@types/node@24.19.0) + transitivePeerDependencies: + - '@azure/app-configuration' + - '@azure/cosmos' + - '@azure/data-tables' + - '@azure/identity' + - '@azure/keyvault-secrets' + - '@azure/storage-blob' + - '@capacitor/preferences' + - '@deno/kv' + - '@netlify/blobs' + - '@planetscale/database' + - '@types/node' + - '@upstash/redis' + - '@vercel/blob' + - '@vercel/functions' + - '@vercel/kv' + - '@vitejs/devtools' + - aws4fetch + - db0 + - idb-keyval + - ioredis + - jiti + - less + - sass + - sass-embedded + - stylus + - sugarss + - terser + - tsx + - uploadthing + - yaml + + axobject-query@4.1.0: {} + + bail@2.0.2: {} + blake3-wasm@2.1.5: {} + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.1.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.16.0 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + + boolbase@1.0.0: {} + + bytes@3.1.2: {} + cac@6.7.14: {} cac@7.0.0: {} + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + + ccount@2.0.1: {} + chai@5.3.3: dependencies: assertion-error: 2.0.1 @@ -2822,36 +5120,171 @@ snapshots: loupe: 3.2.1 pathval: 2.0.1 + character-entities-html4@2.1.0: {} + + character-entities-legacy@3.0.0: {} + chardet@2.2.0: {} check-error@2.1.3: {} + chokidar@4.0.3: + dependencies: + readdirp: 4.1.2 + + chokidar@5.0.0: + dependencies: + readdirp: 5.1.1 + + ci-info@4.4.0: {} + cli-width@4.1.0: {} + cliui@9.0.1: + dependencies: + string-width: 7.2.0 + strip-ansi: 7.2.0 + wrap-ansi: 9.0.2 + + clsx@2.1.1: {} + color-convert@2.0.1: dependencies: color-name: 1.1.4 color-name@1.1.4: {} + comma-separated-tokens@2.0.3: {} + + commander@11.1.0: {} + commander@12.1.0: {} + common-ancestor-path@2.0.0: {} + + content-disposition@1.1.0: {} + + content-type@1.0.5: {} + + content-type@2.1.0: {} + + cookie-es@1.2.3: {} + + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + cookie@1.1.1: {} + cookie@2.0.1: {} + + crossws@0.3.5: + dependencies: + uncrypto: 0.1.3 + + css-select@6.0.0: + dependencies: + boolbase: 1.0.0 + css-what: 7.0.0 + domhandler: 5.0.3 + domutils: 3.2.2 + nth-check: 2.1.1 + + css-tree@2.2.1: + dependencies: + mdn-data: 2.0.28 + source-map-js: 1.2.1 + + css-tree@3.2.1: + dependencies: + mdn-data: 2.27.1 + source-map-js: 1.2.1 + + css-what@7.0.0: {} + + csso@5.0.5: + dependencies: + css-tree: 2.2.1 + debug@4.4.3: dependencies: ms: 2.1.3 deep-eql@5.0.2: {} + defu@6.1.7: {} + + depd@2.0.0: {} + + dequal@2.0.3: {} + + destr@2.0.5: {} + detect-libc@2.1.2: {} + devalue@5.9.4: {} + + devlop@1.1.0: + dependencies: + dequal: 2.0.3 + + diff@9.0.0: {} + + dom-serializer@2.0.0: + dependencies: + domelementtype: 2.3.0 + domhandler: 5.0.3 + entities: 4.5.0 + + domelementtype@2.3.0: {} + + domhandler@5.0.3: + dependencies: + domelementtype: 2.3.0 + + domutils@3.2.2: + dependencies: + dom-serializer: 2.0.0 + domelementtype: 2.3.0 + domhandler: 5.0.3 + + dset@3.1.4: {} + + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + + ee-first@1.1.1: {} + + emmet@2.4.11: + dependencies: + '@emmetio/abbreviation': 2.3.3 + '@emmetio/css-abbreviation': 2.1.8 + + emoji-regex@10.6.0: {} + emoji-regex@8.0.0: {} + encodeurl@2.0.0: {} + + entities@4.5.0: {} + error-stack-parser-es@1.0.5: {} + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + es-module-lexer@1.7.0: {} + es-module-lexer@3.0.3: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + esbuild@0.21.5: optionalDependencies: '@esbuild/aix-ppc64': 0.21.5 @@ -2936,10 +5369,16 @@ snapshots: '@esbuild/win32-ia32': 0.28.1 '@esbuild/win32-x64': 0.28.1 + escalade@3.2.0: {} + + escape-html@1.0.3: {} + estree-walker@3.0.3: dependencies: '@types/estree': 1.0.9 + etag@1.8.1: {} + ethers@6.17.0: dependencies: '@adraffy/ens-normalize': 1.11.1 @@ -2955,14 +5394,55 @@ snapshots: eventemitter3@5.0.1: {} + eventemitter3@5.0.4: {} + expect-type@1.4.0: {} + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.8 + qs: 6.16.0 + range-parser: 1.3.0 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + + extend@3.0.2: {} + + fast-deep-equal@3.1.3: {} + fast-string-truncated-width@3.0.3: {} fast-string-width@3.0.2: dependencies: fast-string-truncated-width: 3.0.3 + fast-uri@3.1.8: {} + fast-wrap-ansi@0.2.2: dependencies: fast-string-width: 3.0.2 @@ -2971,11 +5451,120 @@ snapshots: optionalDependencies: picomatch: 4.0.7 + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + find-proc@0.2.0: {} + + flattie@1.1.1: {} + + fontace@0.4.1: + dependencies: + fontkitten: 1.0.3 + + fontkitten@1.0.3: + dependencies: + tiny-inflate: 1.0.3 + + forwarded@0.2.0: {} + + fresh@2.0.0: {} + fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + + get-caller-file@2.0.5: {} + + get-east-asian-width@1.7.0: {} + + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + + get-tsconfig@5.0.0-beta.6: + dependencies: + resolve-pkg-maps: 1.0.0 + + github-slugger@2.0.0: {} + + gopd@1.2.0: {} + + h3@1.15.11: + dependencies: + cookie-es: 1.2.3 + crossws: 0.3.5 + defu: 6.1.7 + destr: 2.0.5 + iron-webcrypto: 1.2.1 + node-mock-http: 1.0.5 + radix3: 1.1.2 + ufo: 1.6.4 + uncrypto: 0.1.3 + + has-symbols@1.1.0: {} + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + + hast-util-to-html@9.0.5: + dependencies: + '@types/hast': 3.0.5 + '@types/unist': 3.0.3 + ccount: 2.0.1 + comma-separated-tokens: 2.0.3 + hast-util-whitespace: 3.0.0 + html-void-elements: 3.0.0 + mdast-util-to-hast: 13.2.1 + property-information: 7.2.0 + space-separated-tokens: 2.0.2 + stringify-entities: 4.0.4 + zwitch: 2.0.4 + + hast-util-whitespace@3.0.0: + dependencies: + '@types/hast': 3.0.5 + hono@4.13.8: {} + html-escaper@3.0.3: {} + + html-void-elements@3.0.0: {} + + http-cache-semantics@4.3.0: {} + + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + human-id@4.2.1: {} iconv-lite@0.7.3: @@ -2984,37 +5573,161 @@ snapshots: import-meta-resolve@4.2.0: {} + inherits@2.0.4: {} + + ipaddr.js@1.9.1: {} + + iron-webcrypto@1.2.1: {} + + is-docker@4.0.0: {} + is-fullwidth-code-point@3.0.0: {} + is-plain-obj@4.1.0: {} + + is-promise@4.0.0: {} + isows@1.0.7(ws@8.21.0): dependencies: ws: 8.21.0 jju@1.4.0: {} + jose@5.10.0: {} + js-tokens@9.0.1: {} + json-schema-traverse@1.0.0: {} + + jsonc-parser@2.3.1: {} + jsonc-parser@3.3.1: {} - kleur@4.1.5: {} + kleur@4.1.5: {} + + launch-editor@2.14.1: + dependencies: + picocolors: 1.1.1 + shell-quote: 1.10.0 + + lightningcss-android-arm64@1.33.0: + optional: true + + lightningcss-darwin-arm64@1.33.0: + optional: true + + lightningcss-darwin-x64@1.33.0: + optional: true + + lightningcss-freebsd-x64@1.33.0: + optional: true + + lightningcss-linux-arm-gnueabihf@1.33.0: + optional: true + + lightningcss-linux-arm64-gnu@1.33.0: + optional: true + + lightningcss-linux-arm64-musl@1.33.0: + optional: true + + lightningcss-linux-x64-gnu@1.33.0: + optional: true + + lightningcss-linux-x64-musl@1.33.0: + optional: true + + lightningcss-win32-arm64-msvc@1.33.0: + optional: true + + lightningcss-win32-x64-msvc@1.33.0: + optional: true + + lightningcss@1.33.0: + dependencies: + detect-libc: 2.1.2 + optionalDependencies: + lightningcss-android-arm64: 1.33.0 + lightningcss-darwin-arm64: 1.33.0 + lightningcss-darwin-x64: 1.33.0 + lightningcss-freebsd-x64: 1.33.0 + lightningcss-linux-arm-gnueabihf: 1.33.0 + lightningcss-linux-arm64-gnu: 1.33.0 + lightningcss-linux-arm64-musl: 1.33.0 + lightningcss-linux-x64-gnu: 1.33.0 + lightningcss-linux-x64-musl: 1.33.0 + lightningcss-win32-arm64-msvc: 1.33.0 + lightningcss-win32-x64-msvc: 1.33.0 + + loupe@3.2.1: {} + + lru-cache@11.0.2: {} + + lru-cache@11.5.3: {} + + magic-string@0.30.21: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + magic-string@1.4.3: + dependencies: + '@jridgewell/sourcemap-codec': 1.6.0 + + magicast@0.5.5: + dependencies: + '@babel/parser': 7.29.9 + '@babel/types': 7.29.8 + source-map-js: 1.2.1 + + math-intrinsics@1.1.0: {} + + mdast-util-to-hast@13.2.1: + dependencies: + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@ungap/structured-clone': 1.4.0 + devlop: 1.1.0 + micromark-util-sanitize-uri: 2.0.1 + trim-lines: 3.0.1 + unist-util-position: 5.0.0 + unist-util-visit: 5.1.0 + vfile: 6.0.3 + + mdn-data@2.0.28: {} + + mdn-data@2.27.1: {} + + media-typer@1.1.1: {} + + merge-descriptors@2.0.0: {} + + micromark-util-character@2.1.1: + dependencies: + micromark-util-symbol: 2.0.1 + micromark-util-types: 2.0.3 + + micromark-util-encode@2.0.1: {} - launch-editor@2.14.1: + micromark-util-sanitize-uri@2.0.1: dependencies: - picocolors: 1.1.1 - shell-quote: 1.10.0 + micromark-util-character: 2.1.1 + micromark-util-encode: 2.0.1 + micromark-util-symbol: 2.0.1 - loupe@3.2.1: {} + micromark-util-symbol@2.0.1: {} - lru-cache@11.0.2: {} + micromark-util-types@2.0.3: {} - magic-string@0.30.21: + mime-db@1.54.0: {} + + mime-types@3.0.2: dependencies: - '@jridgewell/sourcemap-codec': 1.6.0 + mime-db: 1.54.0 - miniflare@5.20260915.0-alpha(@types/node@22.20.3): + miniflare@5.20260915.0-alpha(@types/node@24.19.0): dependencies: '@cspotcode/source-map-support': 0.8.1 - sharp: 0.35.4(@types/node@22.20.3) + sharp: 0.35.4(@types/node@24.19.0) undici: 7.29.0 workerd: 1.20260915.1 ws: 8.21.0 @@ -3024,12 +5737,64 @@ snapshots: - bufferutil - utf-8-validate + mrmime@2.0.1: {} + ms@2.1.3: {} + muggle-string@0.4.1: {} + mute-stream@2.0.0: {} nanoid@3.3.19: {} + negotiator@1.1.0: + dependencies: + content-type: 2.1.0 + + neotraverse@1.0.1: {} + + nlcst-to-string@4.0.0: + dependencies: + '@types/nlcst': 2.0.3 + + node-fetch-native@1.6.7: {} + + node-mock-http@1.0.5: {} + + normalize-path@3.0.0: {} + + nth-check@2.1.1: + dependencies: + boolbase: 1.0.0 + + object-inspect@1.13.4: {} + + obug@3.0.0: {} + + ofetch@1.5.1: + dependencies: + destr: 2.0.5 + node-fetch-native: 1.6.7 + ufo: 1.6.4 + + ohash@2.0.12: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + + once@1.4.0: + dependencies: + wrappy: 1.0.2 + + oniguruma-parser@0.12.2: {} + + oniguruma-to-es@4.3.6: + dependencies: + oniguruma-parser: 0.12.2 + regex: 6.1.0 + regex-recursion: 6.0.2 + ox@0.14.44(typescript@5.9.3)(zod@3.25.76): dependencies: '@adraffy/ens-normalize': 1.11.1 @@ -3045,18 +5810,54 @@ snapshots: transitivePeerDependencies: - zod + ox@0.14.44(typescript@5.9.3)(zod@4.6.5): + 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@5.9.3)(zod@4.6.5) + eventemitter3: 5.0.1 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - zod + + p-limit@7.3.3: + dependencies: + yocto-queue: 1.2.2 + + p-queue@9.3.3: + dependencies: + eventemitter3: 5.0.4 + p-timeout: 7.0.2 + + p-timeout@7.0.2: {} + package-manager-detector@1.8.0: {} + parseurl@1.3.3: {} + + path-browserify@1.0.1: {} + path-to-regexp@6.3.0: {} + path-to-regexp@8.4.2: {} + pathe@1.1.2: {} pathe@2.0.3: {} pathval@2.0.1: {} + piccolore@0.1.3: {} + picocolors@1.1.1: {} + picomatch@2.3.2: {} + picomatch@4.0.7: {} postcss@8.5.28: @@ -3065,6 +5866,84 @@ snapshots: picocolors: 1.1.1 source-map-js: 1.2.1 + prettier@3.9.9: {} + + prismjs@1.30.0: {} + + process-ancestry@0.1.0: {} + + property-information@7.2.0: {} + + proxy-addr@2.0.8: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + qs@6.16.0: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + + radix3@1.1.2: {} + + range-parser@1.3.0: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + + readdirp@4.1.2: {} + + readdirp@5.1.1: {} + + regex-recursion@6.0.2: + dependencies: + regex-utilities: 2.3.0 + + regex-utilities@2.3.0: {} + + regex@6.1.0: + dependencies: + regex-utilities: 2.3.0 + + request-light@0.5.8: {} + + request-light@0.7.0: {} + + require-from-string@2.0.2: {} + + resolve-pkg-maps@1.0.0: {} + + retext-smartypants@6.2.0: + dependencies: + '@types/nlcst': 2.0.3 + nlcst-to-string: 4.0.0 + unist-util-visit: 5.1.0 + + rolldown@1.2.12: + dependencies: + '@oxc-project/types': 0.152.0 + '@rolldown/pluginutils': 1.0.1 + optionalDependencies: + '@rolldown/binding-android-arm-eabi': 1.2.12 + '@rolldown/binding-android-arm64': 1.2.12 + '@rolldown/binding-darwin-arm64': 1.2.12 + '@rolldown/binding-darwin-x64': 1.2.12 + '@rolldown/binding-freebsd-x64': 1.2.12 + '@rolldown/binding-linux-arm-gnueabihf': 1.2.12 + '@rolldown/binding-linux-arm64-gnu': 1.2.12 + '@rolldown/binding-linux-arm64-musl': 1.2.12 + '@rolldown/binding-linux-ppc64-gnu': 1.2.12 + '@rolldown/binding-linux-s390x-gnu': 1.2.12 + '@rolldown/binding-linux-x64-gnu': 1.2.12 + '@rolldown/binding-linux-x64-musl': 1.2.12 + '@rolldown/binding-openharmony-arm64': 1.2.12 + '@rolldown/binding-win32-arm64-msvc': 1.2.12 + '@rolldown/binding-win32-x64-msvc': 1.2.12 + rollup@4.63.3: dependencies: '@types/estree': 1.0.9 @@ -3097,11 +5976,69 @@ snapshots: '@rollup/rollup-win32-x64-msvc': 4.63.3 fsevents: 2.3.3 + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + safer-buffer@2.1.2: {} + satteri@0.10.5: + dependencies: + '@types/estree-jsx': 1.0.5 + '@types/hast': 3.0.5 + '@types/mdast': 4.0.4 + '@types/unist': 3.0.3 + optionalDependencies: + '@bruits/satteri-darwin-arm64': 0.10.5 + '@bruits/satteri-darwin-x64': 0.10.5 + '@bruits/satteri-linux-arm64-gnu': 0.10.5 + '@bruits/satteri-linux-arm64-musl': 0.10.5 + '@bruits/satteri-linux-x64-gnu': 0.10.5 + '@bruits/satteri-linux-x64-musl': 0.10.5 + '@bruits/satteri-wasm32-wasi': 0.10.5 + '@bruits/satteri-win32-arm64-msvc': 0.10.5 + '@bruits/satteri-win32-x64-msvc': 0.10.5 + + sax@1.6.1: {} + semver@7.8.5: {} - sharp@0.35.4(@types/node@22.20.3): + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + server-destroy@1.0.1: {} + + setprototypeof@1.2.0: {} + + sharp@0.35.4(@types/node@24.19.0): dependencies: '@img/colour': 1.1.0 detect-libc: 2.1.2 @@ -3132,20 +6069,65 @@ snapshots: '@img/sharp-win32-arm64': 0.35.4 '@img/sharp-win32-ia32': 0.35.4 '@img/sharp-win32-x64': 0.35.4 - '@types/node': 22.20.3 + '@types/node': 24.19.0 shell-quote@1.10.0: {} + shiki@4.5.0: + dependencies: + '@shikijs/core': 4.5.0 + '@shikijs/engine-javascript': 4.5.0 + '@shikijs/engine-oniguruma': 4.5.0 + '@shikijs/langs': 4.5.0 + '@shikijs/themes': 4.5.0 + '@shikijs/types': 4.5.0 + '@shikijs/vscode-textmate': 10.0.2 + '@types/hast': 3.0.5 + + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + siginfo@2.0.0: {} signal-exit@4.1.0: {} sisteransi@1.0.5: {} + smol-toml@1.9.0: {} + source-map-js@1.2.1: {} + space-separated-tokens@2.0.2: {} + stackback@0.0.2: {} + statuses@2.0.2: {} + std-env@3.10.0: {} string-width@4.2.3: @@ -3154,18 +6136,52 @@ snapshots: is-fullwidth-code-point: 3.0.0 strip-ansi: 6.0.1 + string-width@7.2.0: + dependencies: + emoji-regex: 10.6.0 + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + string-width@8.3.0: + dependencies: + get-east-asian-width: 1.7.0 + strip-ansi: 7.2.0 + + stringify-entities@4.0.4: + dependencies: + character-entities-html4: 2.1.0 + character-entities-legacy: 3.0.0 + strip-ansi@6.0.1: dependencies: ansi-regex: 5.0.1 + strip-ansi@7.2.0: + dependencies: + ansi-regex: 6.4.0 + strip-literal@3.1.0: dependencies: js-tokens: 9.0.1 supports-color@10.2.2: {} + svgo@4.1.0: + dependencies: + commander: 11.1.0 + css-select: 6.0.0 + css-tree: 3.2.1 + css-what: 7.0.0 + csso: 5.0.5 + picocolors: 1.1.1 + sax: 1.6.1 + + tiny-inflate@1.0.3: {} + tinybench@2.9.0: {} + tinyclip@1.0.3: {} + tinyexec@0.3.2: {} tinyexec@1.3.1: {} @@ -3185,20 +6201,116 @@ snapshots: tinyspy@4.0.6: {} + toidentifier@1.0.1: {} + + trim-lines@3.0.1: {} + + trough@2.2.0: {} + tslib@2.7.0: {} + tweetnacl@1.0.3: {} + + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + + typesafe-path@0.2.2: {} + + typescript-auto-import-cache@0.3.6: + dependencies: + semver: 7.8.5 + typescript@5.9.3: {} + ufo@1.6.4: {} + + ultrahtml@1.7.0: {} + + uncrypto@0.1.3: {} + undici-types@6.19.8: {} undici-types@6.21.0: {} + undici-types@7.24.6: {} + undici@7.29.0: {} + undici@8.11.2: {} + unenv@2.0.0-rc.24: dependencies: pathe: 2.0.3 + unified@11.0.5: + dependencies: + '@types/unist': 3.0.3 + bail: 2.0.2 + devlop: 1.1.0 + extend: 3.0.2 + is-plain-obj: 4.1.0 + trough: 2.2.0 + vfile: 6.0.3 + + unifont@0.7.5: + dependencies: + css-tree: 3.2.1 + ohash: 2.0.12 + undici: 8.11.2 + + unist-util-is@6.0.1: + dependencies: + '@types/unist': 3.0.3 + + unist-util-position@5.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-stringify-position@4.0.0: + dependencies: + '@types/unist': 3.0.3 + + unist-util-visit-parents@6.0.2: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + + unist-util-visit@5.1.0: + dependencies: + '@types/unist': 3.0.3 + unist-util-is: 6.0.1 + unist-util-visit-parents: 6.0.2 + + unpipe@1.0.0: {} + + unstorage@1.17.5: + dependencies: + anymatch: 3.1.3 + chokidar: 5.0.0 + destr: 2.0.5 + h3: 1.15.11 + lru-cache: 11.5.3 + node-fetch-native: 1.6.7 + ofetch: 1.5.1 + ufo: 1.6.4 + + vary@1.1.2: {} + + verkit@0.5.0: {} + + vfile-message@4.0.3: + dependencies: + '@types/unist': 3.0.3 + unist-util-stringify-position: 4.0.0 + + vfile@6.0.3: + dependencies: + '@types/unist': 3.0.3 + vfile-message: 4.0.3 + viem@2.56.5(typescript@5.9.3)(zod@3.25.76): dependencies: '@noble/curves': 1.9.1 @@ -3216,13 +6328,30 @@ snapshots: - utf-8-validate - zod - vite-node@2.1.9(@types/node@22.20.3): + viem@2.56.5(typescript@5.9.3)(zod@4.6.5): + 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@5.9.3)(zod@4.6.5) + isows: 1.0.7(ws@8.21.0) + ox: 0.14.44(typescript@5.9.3)(zod@4.6.5) + ws: 8.21.0 + optionalDependencies: + typescript: 5.9.3 + transitivePeerDependencies: + - bufferutil + - utf-8-validate + - zod + + vite-node@2.1.9(@types/node@22.20.3)(lightningcss@1.33.0): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 1.1.2 - vite: 5.4.21(@types/node@22.20.3) + vite: 5.4.21(@types/node@22.20.3)(lightningcss@1.33.0) transitivePeerDependencies: - '@types/node' - less @@ -3234,13 +6363,13 @@ snapshots: - supports-color - terser - vite-node@3.2.4(@types/node@22.20.3): + vite-node@3.2.4(@types/node@24.19.0)(lightningcss@1.33.0): dependencies: cac: 6.7.14 debug: 4.4.3 es-module-lexer: 1.7.0 pathe: 2.0.3 - vite: 5.4.21(@types/node@22.20.3) + vite: 5.4.21(@types/node@24.19.0)(lightningcss@1.33.0) transitivePeerDependencies: - '@types/node' - less @@ -3252,7 +6381,7 @@ snapshots: - supports-color - terser - vite@5.4.21(@types/node@22.20.3): + vite@5.4.21(@types/node@22.20.3)(lightningcss@1.33.0): dependencies: esbuild: 0.21.5 postcss: 8.5.28 @@ -3260,11 +6389,39 @@ snapshots: optionalDependencies: '@types/node': 22.20.3 fsevents: 2.3.3 + lightningcss: 1.33.0 + + vite@5.4.21(@types/node@24.19.0)(lightningcss@1.33.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.5.28 + rollup: 4.63.3 + optionalDependencies: + '@types/node': 24.19.0 + fsevents: 2.3.3 + lightningcss: 1.33.0 + + vite@8.3.3(@types/node@24.19.0)(esbuild@0.28.1)(yaml@2.9.1): + dependencies: + lightningcss: 1.33.0 + picomatch: 4.0.7 + postcss: 8.5.28 + rolldown: 1.2.12 + tinyglobby: 0.2.17 + optionalDependencies: + '@types/node': 24.19.0 + esbuild: 0.28.1 + fsevents: 2.3.3 + yaml: 2.9.1 + + vitefu@1.1.3(vite@8.3.3(@types/node@24.19.0)(esbuild@0.28.1)(yaml@2.9.1)): + optionalDependencies: + vite: 8.3.3(@types/node@24.19.0)(esbuild@0.28.1)(yaml@2.9.1) - vitest@2.1.9(@types/node@22.20.3): + vitest@2.1.9(@types/node@22.20.3)(lightningcss@1.33.0): dependencies: '@vitest/expect': 2.1.9 - '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.20.3)) + '@vitest/mocker': 2.1.9(vite@5.4.21(@types/node@22.20.3)(lightningcss@1.33.0)) '@vitest/pretty-format': 2.1.9 '@vitest/runner': 2.1.9 '@vitest/snapshot': 2.1.9 @@ -3280,8 +6437,8 @@ snapshots: tinyexec: 0.3.2 tinypool: 1.1.1 tinyrainbow: 1.2.0 - vite: 5.4.21(@types/node@22.20.3) - vite-node: 2.1.9(@types/node@22.20.3) + vite: 5.4.21(@types/node@22.20.3)(lightningcss@1.33.0) + vite-node: 2.1.9(@types/node@22.20.3)(lightningcss@1.33.0) why-is-node-running: 2.3.0 optionalDependencies: '@types/node': 22.20.3 @@ -3296,11 +6453,11 @@ snapshots: - supports-color - terser - vitest@3.2.7(@types/node@22.20.3): + vitest@3.2.7(@types/node@24.19.0)(lightningcss@1.33.0): dependencies: '@types/chai': 5.2.3 '@vitest/expect': 3.2.7 - '@vitest/mocker': 3.2.7(vite@5.4.21(@types/node@22.20.3)) + '@vitest/mocker': 3.2.7(vite@5.4.21(@types/node@24.19.0)(lightningcss@1.33.0)) '@vitest/pretty-format': 3.2.7 '@vitest/runner': 3.2.7 '@vitest/snapshot': 3.2.7 @@ -3318,11 +6475,11 @@ snapshots: tinyglobby: 0.2.17 tinypool: 1.1.1 tinyrainbow: 2.0.0 - vite: 5.4.21(@types/node@22.20.3) - vite-node: 3.2.4(@types/node@22.20.3) + vite: 5.4.21(@types/node@24.19.0)(lightningcss@1.33.0) + vite-node: 3.2.4(@types/node@24.19.0)(lightningcss@1.33.0) why-is-node-running: 2.3.0 optionalDependencies: - '@types/node': 22.20.3 + '@types/node': 24.19.0 transitivePeerDependencies: - less - lightningcss @@ -3334,6 +6491,112 @@ snapshots: - supports-color - terser + volar-service-css@0.0.71(@volar/language-service@2.4.28): + dependencies: + vscode-css-languageservice: 6.3.10 + vscode-languageserver-textdocument: 1.0.15 + vscode-uri: 3.2.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + + volar-service-emmet@0.0.71(@volar/language-service@2.4.28): + dependencies: + '@emmetio/css-parser': 0.4.1 + '@emmetio/html-matcher': 1.3.0 + '@vscode/emmet-helper': 2.11.0 + vscode-uri: 3.2.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + + volar-service-html@0.0.71(@volar/language-service@2.4.28): + dependencies: + vscode-html-languageservice: 5.6.2 + vscode-languageserver-textdocument: 1.0.15 + vscode-uri: 3.2.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + + volar-service-prettier@0.0.71(@volar/language-service@2.4.28)(prettier@3.9.9): + dependencies: + vscode-uri: 3.2.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + prettier: 3.9.9 + + volar-service-typescript-twoslash-queries@0.0.71(@volar/language-service@2.4.28): + dependencies: + vscode-uri: 3.2.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + + volar-service-typescript@0.0.71(@volar/language-service@2.4.28): + dependencies: + path-browserify: 1.0.1 + semver: 7.8.5 + typescript-auto-import-cache: 0.3.6 + vscode-languageserver-textdocument: 1.0.15 + vscode-nls: 5.2.0 + vscode-uri: 3.2.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + + volar-service-yaml@0.0.71(@volar/language-service@2.4.28): + dependencies: + vscode-uri: 3.2.0 + yaml-language-server: 1.23.0 + optionalDependencies: + '@volar/language-service': 2.4.28 + + vscode-css-languageservice@6.3.10: + dependencies: + '@vscode/l10n': 0.0.18 + vscode-languageserver-textdocument: 1.0.15 + vscode-languageserver-types: 3.17.5 + vscode-uri: 3.2.0 + + vscode-html-languageservice@5.6.2: + dependencies: + '@vscode/l10n': 0.0.18 + vscode-languageserver-textdocument: 1.0.15 + vscode-languageserver-types: 3.18.4 + vscode-uri: 3.2.0 + + vscode-json-languageservice@4.1.8: + dependencies: + jsonc-parser: 3.3.1 + vscode-languageserver-textdocument: 1.0.15 + vscode-languageserver-types: 3.18.4 + vscode-nls: 5.2.0 + vscode-uri: 3.2.0 + + vscode-jsonrpc@8.2.0: {} + + vscode-jsonrpc@9.0.3: {} + + vscode-languageserver-protocol@3.17.5: + dependencies: + vscode-jsonrpc: 8.2.0 + vscode-languageserver-types: 3.17.5 + + vscode-languageserver-protocol@3.18.4: + dependencies: + vscode-jsonrpc: 9.0.3 + vscode-languageserver-types: 3.18.4 + + vscode-languageserver-textdocument@1.0.15: {} + + vscode-languageserver-types@3.17.5: {} + + vscode-languageserver-types@3.18.4: {} + + vscode-languageserver@9.0.1: + dependencies: + vscode-languageserver-protocol: 3.17.5 + + vscode-nls@5.2.0: {} + + vscode-uri@3.2.0: {} + why-is-node-running@2.3.0: dependencies: siginfo: 2.0.0 @@ -3347,13 +6610,13 @@ snapshots: '@cloudflare/workerd-linux-arm64': 1.20260915.1 '@cloudflare/workerd-windows-64': 1.20260915.1 - wrangler@4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@22.20.3): + wrangler@4.132.0(@cloudflare/workers-types@5.20260915.1)(@types/node@24.19.0): dependencies: '@cloudflare/kv-asset-handler': 0.5.0 '@cloudflare/unenv-preset': 2.16.1(unenv@2.0.0-rc.24)(workerd@1.20260915.1) blake3-wasm: 2.1.5 esbuild: 0.28.1 - miniflare: 5.20260915.0-alpha(@types/node@22.20.3) + miniflare: 5.20260915.0-alpha(@types/node@24.19.0) path-to-regexp: 6.3.0 unenv: 2.0.0-rc.24 workerd: 1.20260915.1 @@ -3371,10 +6634,52 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 + wrap-ansi@9.0.2: + dependencies: + ansi-styles: 6.2.3 + string-width: 7.2.0 + strip-ansi: 7.2.0 + + wrappy@1.0.2: {} + ws@8.21.0: {} + xxhash-wasm@1.1.0: {} + + y18n@5.0.8: {} + + yaml-language-server@1.23.0: + dependencies: + '@vscode/l10n': 0.0.18 + ajv: 8.20.0 + ajv-draft-04: 1.0.0(ajv@8.20.0) + ajv-i18n: 4.2.0(ajv@8.20.0) + prettier: 3.9.9 + request-light: 0.5.8 + vscode-json-languageservice: 4.1.8 + vscode-languageserver: 9.0.1 + vscode-languageserver-textdocument: 1.0.15 + vscode-languageserver-types: 3.18.4 + vscode-uri: 3.2.0 + yaml: 2.8.3 + + yaml@2.8.3: {} + yaml@2.9.1: {} + yargs-parser@22.0.0: {} + + yargs@18.2.0: + dependencies: + cliui: 9.0.1 + escalade: 3.2.0 + get-caller-file: 2.0.5 + string-width: 8.3.0 + y18n: 5.0.8 + yargs-parser: 22.0.0 + + yocto-queue@1.2.2: {} + yoctocolors-cjs@2.1.3: {} youch-core@0.3.3: @@ -3391,3 +6696,7 @@ snapshots: youch-core: 0.3.3 zod@3.25.76: {} + + zod@4.6.5: {} + + zwitch@2.0.4: {}