diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ead0e7..17b45d7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,10 +16,11 @@ All notable changes to this project will be documented in this file. The format ### Changed - [#366](https://github.com/mohanagy/miftah/issues/366) Completed the capability-gated MRTR confirmation boundary with packaged modern-client evidence, authenticated profile-context binding, deterministic one-time replay rejection, explicit cancelled audit outcomes, request-scoped upstream cleanup, and documented safe fallbacks. The experimental Tasks extension remains unimplemented after evaluating startup, OAuth, diagnostics, audit export, and recovery; Miftah makes no Tasks interoperability claim. -- [#363](https://github.com/mohanagy/miftah/issues/363) Replaced the monolithic MCP TypeScript SDK v1 dependency with the stable v2 split packages and migrated runtime schemas to Zod 4. Runtime consumers receive only `client`, `core`, and `server`; the Node adapter and frozen legacy server remain build/test dependencies. Direct consumers of the old monolithic SDK deep imports must move to the corresponding split package. The CLI bundles the v2 Node adapter with patched `@hono/node-server` and Hono builds so a fresh Miftah install does not inherit the Node package's still-vulnerable 1.x adapter range; custom embedding hosts own their direct Node adapter version. Confirmation-required tools, resources, prompts, and profile transitions now use the v2 `input_required` flow with integrity-bound one-time continuation state across request-scoped modern HTTP instances, while the SDK legacy shim preserves form elicitation for initialized clients. Native OAuth callback completion now carries the authorization-server issuer required by the v2 provider contract; Miftah continues to validate and round-trip that issuer without exposing tokens or client secrets. +- [#363](https://github.com/mohanagy/miftah/issues/363) Replaced Miftah's runtime use of the monolithic MCP TypeScript SDK v1 with the stable v2 split packages and migrated runtime schemas to Zod 4. The compatible monolithic SDK remains an installed dependency solely for the documented v1 `createMiftahRuntime(...).connect(new StdioServerTransport())` host path through the 1.x line; its removal remains deferred to the evidence-backed major-version gate [#388](https://github.com/mohanagy/miftah/issues/388). The frozen legacy server remains a build/test dependency. The published package pins patched `@hono/node-server` and Hono releases so the retained v1 SDK cannot resolve the unsafe 1.x adapter range, and the CLI bundles those same patched builds; custom embedding hosts own their direct `@modelcontextprotocol/node` version. Confirmation-required tools, resources, prompts, and profile transitions now use the v2 `input_required` flow with integrity-bound one-time continuation state across request-scoped modern HTTP instances, while the SDK legacy shim preserves form elicitation for initialized clients. Native OAuth callback completion now carries the authorization-server issuer required by the v2 provider contract; Miftah continues to validate and round-trip that issuer without exposing tokens or client secrets. ### Fixed +- [#391](https://github.com/mohanagy/miftah/issues/391) Preserved the documented v1 library STDIO host path through 1.x by retaining the compatible MCP SDK v1 package alongside Miftah's v2 runtime packages and compiling the exact legacy `StdioServerTransport` consumer from a freshly installed release tarball. Exact patched Hono and Node adapter runtime dependencies prevent the retained SDK from selecting its unsafe 1.x adapter range. The v2 `createMiftahServerFactory` path remains preferred; removal of the v1 host dependency requires the future major-version gate [#388](https://github.com/mohanagy/miftah/issues/388). - [#384](https://github.com/mohanagy/miftah/issues/384) Made continuation tamper coverage deterministic by mutating a decoded signature byte and re-encoding it canonically, so every test input changes authenticated bytes rather than possibly changing only unused base64url padding bits. ### Security diff --git a/docs/library-api.md b/docs/library-api.md index 10bc9bb..4b7ed0c 100644 --- a/docs/library-api.md +++ b/docs/library-api.md @@ -24,7 +24,7 @@ | `generateConfigSchema` | Generates the editor-facing JSON Schema for the configuration contract. | | `presetConfig` | Creates a supported configuration preset in memory. | -`createMiftahRuntime` returns `MiftahRuntime`, which exposes the resolved `config`, `connect(transport)`, and `close()` methods for hosts that own a specific transport lifecycle. `createMiftahServerFactory` is the preferred boundary for the SDK v2 serving entries because every factory invocation creates a fresh prepared Miftah server whose upstreams close with that server. Both functions accept `MiftahRuntimeOptions`, including the modern profile-context boundary described below. The removed monolithic `@modelcontextprotocol/sdk` package is not part of the supported dependency surface. Miftah's CLI bundles the v2 Node adapter with its patched Hono adapter because `@modelcontextprotocol/node@2.0.0` still advertises an unsafe 1.x adapter range; embedding hosts import and version their own `@modelcontextprotocol/node` package when adapting a custom Node HTTP server. +`createMiftahRuntime` returns `MiftahRuntime`, which exposes the resolved `config`, `connect(transport)`, and `close()` methods for hosts that own a specific transport lifecycle. The documented SDK v1 `StdioServerTransport` path remains supported through the 1.x line, and Miftah retains the compatible monolithic SDK dependency for that path. Its removal is deferred to the evidence-backed major-version gate [#388](https://github.com/mohanagy/miftah/issues/388). The package also pins patched `@hono/node-server` and Hono runtime releases so that retained SDK cannot select its unsafe 1.x adapter range. `createMiftahServerFactory` is the preferred boundary for SDK v2 serving because every factory invocation creates a fresh prepared Miftah server whose upstreams close with that server. Both functions accept `MiftahRuntimeOptions`, including the modern profile-context boundary described below. Miftah's CLI bundles the same patched Hono adapter; embedding hosts import and version their own `@modelcontextprotocol/node` package when adapting a custom Node HTTP server. ```ts import { serveStdio } from "@modelcontextprotocol/server/stdio"; @@ -36,6 +36,16 @@ const server = serveStdio(createMiftahServerFactory("./miftah.json")); await server.close(); ``` +Existing v1 library hosts may retain their 1.0 integration through the 1.x line: + +```ts +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { createMiftahRuntime } from "@lubab/miftah"; + +const runtime = await createMiftahRuntime("./miftah.json"); +await runtime.connect(new StdioServerTransport()); +``` + For a custom HTTP host, pass the same factory to `createMcpHandler` from `@modelcontextprotocol/server` and adapt the web handler with `toNodeHandler` from `@modelcontextprotocol/node` when using Node's HTTP server. ## MCP protocol compatibility matrix diff --git a/package-lock.json b/package-lock.json index e8a2dbc..0803d15 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,11 +9,14 @@ "version": "1.0.0", "license": "MIT", "dependencies": { + "@hono/node-server": "2.0.10", "@modelcontextprotocol/client": "^2.0.0", "@modelcontextprotocol/core": "^2.0.0", + "@modelcontextprotocol/sdk": "^1.30.0", "@modelcontextprotocol/server": "^2.0.0", "@napi-rs/keyring": "1.3.0", "dotenv": "^17.4.2", + "hono": "4.12.34", "zod": "^4.2.0", "zod-to-json-schema": "3.25.2" }, @@ -22,14 +25,12 @@ }, "devDependencies": { "@eslint/js": "^10.0.1", - "@hono/node-server": "2.0.10", "@modelcontextprotocol/node": "^2.0.0", "@modelcontextprotocol/server-legacy": "^2.0.0", "@types/node": "^22.15.30", "@vitest/coverage-v8": "^3.2.7", "esbuild": "0.28.1", "eslint": "^10.8.0", - "hono": "4.12.34", "tsup": "^8.5.0", "typescript": "^5.8.3", "typescript-eslint": "^8.65.0", @@ -687,7 +688,6 @@ "version": "2.0.10", "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-2.0.10.tgz", "integrity": "sha512-ZcnNVhKTmyDJeg0UlnZjvM73JBsTAuhrH/J4fjwGOw59PwOW51r4J+p6CsKZWXdKSme4MFqU62CZMOsdDrU4CA==", - "dev": true, "license": "MIT", "engines": { "node": ">=20" @@ -863,6 +863,46 @@ } } }, + "node_modules/@modelcontextprotocol/sdk": { + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.30.0.tgz", + "integrity": "sha512-xKd8OIzlqNzcqcNumGAa6g+PW2kjD5vrpcKOnfldAUPP3j7lnqMPwlTXQm8gF+UwH72z0lqaRbjr9hqGz0eITA==", + "license": "MIT", + "dependencies": { + "@hono/node-server": "^1.19.9 || ^2.0.5", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", + "content-type": "^1.0.5", + "cors": "^2.8.5", + "cross-spawn": "^7.0.5", + "eventsource": "^3.0.2", + "eventsource-parser": "^3.0.0", + "express": "^5.2.1", + "express-rate-limit": "^8.2.1", + "hono": "^4.11.4", + "jose": "^6.1.3", + "json-schema-typed": "^8.0.2", + "pkce-challenge": "^5.0.0", + "raw-body": "^3.0.0", + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.1" + }, + "engines": { + "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } + } + }, "node_modules/@modelcontextprotocol/server": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@modelcontextprotocol/server/-/server-2.0.0.tgz", @@ -1959,9 +1999,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz", "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "mime-types": "^3.0.0", "negotiator": "^1.0.0" @@ -1993,6 +2031,39 @@ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, + "node_modules/ajv": { + "version": "8.20.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz", + "integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==", + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/ajv-formats": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", + "integrity": "sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==", + "license": "MIT", + "dependencies": { + "ajv": "^8.0.0" + }, + "peerDependencies": { + "ajv": "^8.0.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -2036,9 +2107,7 @@ "version": "2.3.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.3.0.tgz", "integrity": "sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "bytes": "^3.1.2", "content-type": "^2.0.0", @@ -2062,9 +2131,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2093,7 +2160,6 @@ "version": "3.1.2", "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -2113,9 +2179,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz", "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" @@ -2128,9 +2192,7 @@ "version": "1.0.4", "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz", "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" @@ -2216,9 +2278,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.1.0.tgz", "integrity": "sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -2231,7 +2291,6 @@ "version": "1.0.5", "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz", "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.6" @@ -2241,9 +2300,7 @@ "version": "0.7.2", "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz", "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -2252,9 +2309,7 @@ "version": "1.2.2", "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz", "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=6.6.0" } @@ -2263,7 +2318,6 @@ "version": "2.8.6", "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz", "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==", - "dev": true, "license": "MIT", "dependencies": { "object-assign": "^4", @@ -2295,7 +2349,6 @@ "version": "4.4.3", "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", - "dev": true, "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -2330,7 +2383,6 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -2352,9 +2404,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", @@ -2368,17 +2418,13 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==", - "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/encodeurl": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz", "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -2387,9 +2433,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz", "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -2398,9 +2442,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -2416,9 +2458,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.2.tgz", "integrity": "sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0" }, @@ -2472,9 +2512,7 @@ "version": "1.0.3", "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz", "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==", - "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/escape-string-regexp": { "version": "4.0.0", @@ -2682,9 +2720,7 @@ "version": "1.8.1", "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz", "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -2724,9 +2760,7 @@ "version": "5.2.1", "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "accepts": "^2.0.0", "body-parser": "^2.2.1", @@ -2769,7 +2803,6 @@ "version": "8.5.2", "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-8.5.2.tgz", "integrity": "sha512-5Kb34ipNX694DH48vN9irak1Qx30nb0PLYHXfJgw4YEjiC3ZEmZJhwOp+VfiCYwFzvFTdB9QkArYS5kXa2cx2A==", - "dev": true, "license": "MIT", "dependencies": { "ip-address": "^10.2.0" @@ -2788,7 +2821,6 @@ "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true, "license": "MIT" }, "node_modules/fast-json-stable-stringify": { @@ -2805,6 +2837,22 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-uri": { + "version": "3.1.5", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.5.tgz", + "integrity": "sha512-gHwA1O9LDIcKunMKhObS/HimwtehO1nPUECKAu5TpKgaO19fcWEl4bliWe1jWxVFvIXztJjjQ4L8XQ1EU9f7Jw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], + "license": "BSD-3-Clause" + }, "node_modules/fdir": { "version": "6.5.0", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz", @@ -2840,9 +2888,7 @@ "version": "2.1.1", "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.4.0", "encodeurl": "^2.0.0", @@ -2913,9 +2959,7 @@ "version": "0.2.0", "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz", "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -2924,9 +2968,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz", "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -2950,9 +2992,7 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, "license": "MIT", - "peer": true, "funding": { "url": "https://github.com/sponsors/ljharb" } @@ -2961,9 +3001,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz", "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", @@ -2987,9 +3025,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz", "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" @@ -3033,9 +3069,7 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz", "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -3057,9 +3091,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz", "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -3071,9 +3103,7 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.4.tgz", "integrity": "sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "function-bind": "^1.1.2" }, @@ -3085,7 +3115,6 @@ "version": "4.12.34", "resolved": "https://registry.npmjs.org/hono/-/hono-4.12.34.tgz", "integrity": "sha512-GqXJqY/xJkJmuloTrnV1ZEXG3fqte+VjkUqoRNZXcrUidiUOP4fMSIHHY4tsqZBK++kVyWmt/AAfSUuy57/eSA==", - "dev": true, "license": "MIT", "engines": { "node": ">=16.9.0" @@ -3102,7 +3131,6 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz", "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==", - "dev": true, "license": "MIT", "dependencies": { "depd": "~2.0.0", @@ -3123,7 +3151,6 @@ "version": "0.7.3", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.3.tgz", "integrity": "sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==", - "dev": true, "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -3160,14 +3187,12 @@ "version": "2.0.4", "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", - "dev": true, "license": "ISC" }, "node_modules/ip-address": { "version": "10.3.1", "resolved": "https://registry.npmjs.org/ip-address/-/ip-address-10.3.1.tgz", "integrity": "sha512-1e9d3kb97NHJTIJDZW9rKqW2h6+dFa50Dy0fpPSMQp2ADje5gvKsXmdiK6dwY5t76TaTt5+P5N1Y/LoToIxP6g==", - "dev": true, "license": "MIT", "engines": { "node": ">= 12" @@ -3177,9 +3202,7 @@ "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.10" } @@ -3211,9 +3234,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz", "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==", - "dev": true, - "license": "MIT", - "peer": true + "license": "MIT" }, "node_modules/isexe": { "version": "2.0.0", @@ -3308,6 +3329,18 @@ "dev": true, "license": "MIT" }, + "node_modules/json-schema-traverse": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" + }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", @@ -3444,9 +3477,7 @@ "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" } @@ -3455,9 +3486,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.1.tgz", "integrity": "sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" }, @@ -3470,9 +3499,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz", "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -3484,9 +3511,7 @@ "version": "1.54.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz", "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -3495,9 +3520,7 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "mime-db": "^1.54.0" }, @@ -3565,7 +3588,6 @@ "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, "license": "MIT" }, "node_modules/mz": { @@ -3610,9 +3632,7 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz", "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" } @@ -3621,7 +3641,6 @@ "version": "4.1.1", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.10.0" @@ -3631,9 +3650,7 @@ "version": "1.13.4", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz", "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.4" }, @@ -3645,9 +3662,7 @@ "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "ee-first": "1.1.1" }, @@ -3659,9 +3674,7 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", - "dev": true, "license": "ISC", - "peer": true, "dependencies": { "wrappy": "1" } @@ -3720,9 +3733,7 @@ "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.8" } @@ -3767,9 +3778,7 @@ "version": "8.4.2", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.4.2.tgz", "integrity": "sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==", - "dev": true, "license": "MIT", - "peer": true, "funding": { "type": "opencollective", "url": "https://opencollective.com/express" @@ -3929,9 +3938,7 @@ "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "forwarded": "0.2.0", "ipaddr.js": "1.9.1" @@ -3954,9 +3961,7 @@ "version": "6.15.3", "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.3.tgz", "integrity": "sha512-O9gl3zCl5h5blw1KGUzQKhA5oUXSl8rwUIM5o0S3nCXMliSvy5Dzx7/DJcI+SwgICv+IneSZwhBh1oSyEHA71A==", - "dev": true, "license": "BSD-3-Clause", - "peer": true, "dependencies": { "es-define-property": "^1.0.1", "side-channel": "^1.1.1" @@ -3972,9 +3977,7 @@ "version": "1.3.0", "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.3.0.tgz", "integrity": "sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">= 0.6" }, @@ -3987,7 +3990,6 @@ "version": "3.0.2", "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz", "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==", - "dev": true, "license": "MIT", "dependencies": { "bytes": "~3.1.2", @@ -4013,6 +4015,15 @@ "url": "https://paulmillr.com/funding/" } }, + "node_modules/require-from-string": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", + "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", + "license": "MIT", + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/resolve-from": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", @@ -4072,9 +4083,7 @@ "version": "2.2.0", "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz", "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.4.0", "depd": "^2.0.0", @@ -4090,7 +4099,6 @@ "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, "license": "MIT" }, "node_modules/semver": { @@ -4110,9 +4118,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "debug": "^4.4.3", "encodeurl": "^2.0.0", @@ -4138,9 +4144,7 @@ "version": "2.2.1", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "encodeurl": "^2.0.0", "escape-html": "^1.0.3", @@ -4159,7 +4163,6 @@ "version": "1.2.0", "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz", "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==", - "dev": true, "license": "ISC" }, "node_modules/shebang-command": { @@ -4187,9 +4190,7 @@ "version": "1.1.1", "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.1.tgz", "integrity": "sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4", @@ -4208,9 +4209,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.1.tgz", "integrity": "sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "es-errors": "^1.3.0", "object-inspect": "^1.13.4" @@ -4226,9 +4225,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz", "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -4246,9 +4243,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz", "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "call-bound": "^1.0.2", "es-errors": "^1.3.0", @@ -4301,7 +4296,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz", "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -4473,7 +4467,6 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==", - "dev": true, "license": "MIT", "engines": { "node": ">=0.6" @@ -4579,9 +4572,7 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.1.0.tgz", "integrity": "sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==", - "dev": true, "license": "MIT", - "peer": true, "dependencies": { "content-type": "^2.0.0", "media-typer": "^1.1.0", @@ -4599,9 +4590,7 @@ "version": "2.0.0", "resolved": "https://registry.npmjs.org/content-type/-/content-type-2.0.0.tgz", "integrity": "sha512-j/O/d7GcZCyNl7/hwZAb606rzqkyvaDctLmckbxLzHvFBzTJHuGEdodATcP3yIRoDrLHkIATJuvzbFlp/ki2cQ==", - "dev": true, "license": "MIT", - "peer": true, "engines": { "node": ">=18" }, @@ -4666,7 +4655,6 @@ "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -4686,7 +4674,6 @@ "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==", - "dev": true, "license": "MIT", "engines": { "node": ">= 0.8" @@ -4909,9 +4896,7 @@ "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", - "dev": true, - "license": "ISC", - "peer": true + "license": "ISC" }, "node_modules/yocto-queue": { "version": "0.1.0", diff --git a/package.json b/package.json index d2b9ac5..6c9b01c 100644 --- a/package.json +++ b/package.json @@ -63,24 +63,25 @@ "node": ">=20" }, "dependencies": { + "@hono/node-server": "2.0.10", "@modelcontextprotocol/client": "^2.0.0", "@modelcontextprotocol/core": "^2.0.0", "@modelcontextprotocol/server": "^2.0.0", + "@modelcontextprotocol/sdk": "^1.30.0", "@napi-rs/keyring": "1.3.0", "dotenv": "^17.4.2", + "hono": "4.12.34", "zod": "^4.2.0", "zod-to-json-schema": "3.25.2" }, "devDependencies": { "@eslint/js": "^10.0.1", - "@hono/node-server": "2.0.10", "@modelcontextprotocol/node": "^2.0.0", "@modelcontextprotocol/server-legacy": "^2.0.0", "@types/node": "^22.15.30", "@vitest/coverage-v8": "^3.2.7", "esbuild": "0.28.1", "eslint": "^10.8.0", - "hono": "4.12.34", "tsup": "^8.5.0", "typescript": "^5.8.3", "typescript-eslint": "^8.65.0", diff --git a/tests/mcp-v2-migration-contract.test.ts b/tests/mcp-v2-migration-contract.test.ts index d328f8c..6a28581 100644 --- a/tests/mcp-v2-migration-contract.test.ts +++ b/tests/mcp-v2-migration-contract.test.ts @@ -7,23 +7,24 @@ interface PackageManifest { } describe("MCP TypeScript SDK v2 migration contract", () => { - it("ships only the stable split SDK packages required by Miftah", async () => { + it("ships the split v2 runtime packages and the retained v1 host compatibility package", async () => { const manifest = JSON.parse(await readFile(new URL("../package.json", import.meta.url), "utf8")) as PackageManifest; const dependencies = manifest.dependencies ?? {}; - expect(dependencies).not.toHaveProperty("@modelcontextprotocol/sdk"); + expect(dependencies).not.toHaveProperty("@modelcontextprotocol/node"); expect(dependencies).not.toHaveProperty("@modelcontextprotocol/server-legacy"); expect(dependencies).toMatchObject({ + "@hono/node-server": "2.0.10", "@modelcontextprotocol/client": "^2.0.0", "@modelcontextprotocol/core": "^2.0.0", "@modelcontextprotocol/server": "^2.0.0", + "@modelcontextprotocol/sdk": "^1.30.0", + hono: "4.12.34", zod: "^4.2.0" }); expect(manifest.devDependencies).toMatchObject({ - "@hono/node-server": "2.0.10", "@modelcontextprotocol/node": "^2.0.0", - "@modelcontextprotocol/server-legacy": "^2.0.0", - hono: "4.12.34" + "@modelcontextprotocol/server-legacy": "^2.0.0" }); }); }); diff --git a/tests/package-contract.test.ts b/tests/package-contract.test.ts index 3d9c700..2dcc03c 100644 --- a/tests/package-contract.test.ts +++ b/tests/package-contract.test.ts @@ -787,7 +787,7 @@ describe("package metadata contract", () => { expect(manifest.overrides?.[packageName]).toBe(expectedVersion); assertPatchedTransitiveLockEntries(lock, packageName, expectedVersion); } - expect(manifest.devDependencies?.hono).toBe("4.12.34"); + expect(manifest.dependencies?.hono).toBe("4.12.34"); expect(manifest.overrides).not.toHaveProperty("hono"); assertPatchedTransitiveLockEntries(lock, "hono", "4.12.34"); }); @@ -796,17 +796,18 @@ describe("package metadata contract", () => { const manifest = readPackageManifest(); const lock = JSON.parse(readFileSync(new URL("../package-lock.json", import.meta.url), "utf8")) as PackageLock; - expect(manifest.dependencies).not.toHaveProperty("@modelcontextprotocol/sdk"); expect(manifest.dependencies).toMatchObject({ + "@hono/node-server": "2.0.10", "@modelcontextprotocol/client": "^2.0.0", "@modelcontextprotocol/core": "^2.0.0", - "@modelcontextprotocol/server": "^2.0.0" + "@modelcontextprotocol/server": "^2.0.0", + "@modelcontextprotocol/sdk": "^1.30.0", + hono: "4.12.34" }); + expect(manifest.dependencies).not.toHaveProperty("@modelcontextprotocol/node"); expect(manifest.devDependencies).toMatchObject({ - "@hono/node-server": "2.0.10", "@modelcontextprotocol/node": "^2.0.0", - "@modelcontextprotocol/server-legacy": "^2.0.0", - hono: "4.12.34" + "@modelcontextprotocol/server-legacy": "^2.0.0" }); expect(manifest.overrides?.["@hono/node-server"]).toBe("2.0.10"); assertPatchedHonoNodeServerLockEntries(lock); @@ -1097,8 +1098,14 @@ describe("packed artifact contract", () => { ) as PackageManifest; expect(installedManifest.dependencies).toEqual(readPackageManifest().dependencies); expect(existsSync(join(directory, "node_modules", "@modelcontextprotocol", "node"))).toBe(false); - expect(existsSync(join(directory, "node_modules", "@hono", "node-server"))).toBe(false); - expect(existsSync(join(directory, "node_modules", "hono"))).toBe(false); + const installedHonoNodeServer = JSON.parse( + await readFile(join(directory, "node_modules", "@hono", "node-server", "package.json"), "utf8") + ) as PackageManifest; + const installedHono = JSON.parse( + await readFile(join(directory, "node_modules", "hono", "package.json"), "utf8") + ) as PackageManifest; + expect(installedHonoNodeServer.version).toBe("2.0.10"); + expect(installedHono.version).toBe("4.12.34"); const consumerPath = join(directory, "consumer.mjs"); const configPath = join(directory, "miftah.json"); @@ -1291,6 +1298,7 @@ describe("packed artifact contract", () => { typeConsumerPath, [ 'import { AuthenticatedRequestContextError, InMemoryProfileContextRevocationStore, PROFILE_CONTEXT_ARGUMENT, PROFILE_CONTEXT_META_KEY, ProfileContextHandleError, ProfileContextHandleService, createAuthenticatedRequestContextBoundary, createMiftahRuntime, createMiftahServerFactory, requireAuthenticatedRequestContext, CURRENT_CONFIG_VERSION, MIFTAH_VERSION, type ActiveProfileStateScope, type AuthenticatedRequestContext, type AuthenticatedRequestContextBoundary, type AuthenticatedRequestContextBoundaryOptions, type AuthenticatedRequestContextErrorCode, type AuditConfig, type AuditIntegrityConfig, type AuditRotationConfig, type ConfigDiagnostic, type GitHubProfileRoutingMatch, type IdentityConfig, type IdentityFingerprint, type IdentityProbeConfig, type JiraProfileRoutingMatch, type LinearProfileRoutingMatch, type MiftahConfig, type MiftahConfigVersion, type MiftahErrorCode, type MiftahErrorDetails, type MiftahRuntime, type MiftahRuntimeOptions, type MintedProfileContext, type ModernProfileContextRuntimeOptions, type PluginConfig, type PluginKind, type PluginsConfig, type PolicyConfig, type PostHogProfileRoutingMatch, type ProcessConfig, type ProfileConfig, type ProfileContextHandleErrorCode, type ProfileContextHandleServiceOptions, type ProfileContextKeyEpoch, type ProfileContextKeyringProvider, type ProfileContextKeyringSnapshot, type ProfileContextReplacementAudit, type ProfileContextRevocationStore, type ProfileIsolationConfig, type ProfileIsolationContainerVolume, type ProfileIsolationFile, type ProfileLeaseConfig, type ProfileRoutingConfig, type ProfileRoutingMatchConfig, type ProfileUpstreamOverride, type ResolvedProfileContext, type RiskLevel, type RoutingConfig, type RoutingMatcherPluginConfig, type RoutingRule, type SecurityConfig, type SentryProfileRoutingMatch, type SecretProviderPluginConfig, type StateConfig, type ToolDiscoveryMode, type ToolingConfig, type TransportType, type UnknownToolRisk, type UpstreamConfig, type ValidatedRoutingConfig, type VerifiedHttpRequestClaims, type VerifiedHttpRequestClaimsProvider } from "@lubab/miftah";', + 'import { StdioServerTransport as LegacyStdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";', 'import { MIFTAH_PLUGIN_API_VERSION, type MiftahPlugin, type RoutingMatcherPlugin, type RoutingMatcherPluginRequest, type RoutingMatcherPluginResult, type RoutingMatcherPluginSignal, type SecretProviderPlugin, type SecretProviderPluginRequest, type SecretProviderPluginResult } from "@lubab/miftah/plugin-api";', "", "type SupportedTypes = [", @@ -1305,6 +1313,9 @@ describe("packed artifact contract", () => { "const version: string = MIFTAH_VERSION;", 'const pluginApiVersion: "1" = MIFTAH_PLUGIN_API_VERSION;', 'const runtime: Promise = createMiftahRuntime("./miftah.json");', + "declare const legacyRuntime: MiftahRuntime;", + "declare const legacyStdioTransport: LegacyStdioServerTransport;", + "const legacyConnect: Promise = legacyRuntime.connect(legacyStdioTransport);", 'const serverFactory = createMiftahServerFactory("./miftah.json");', 'const authError: AuthenticatedRequestContextError = new AuthenticatedRequestContextError("AUTH_CONTEXT_UNAVAILABLE");', 'const profileContextError: ProfileContextHandleError = new ProfileContextHandleError("PROFILE_CONTEXT_UNAVAILABLE");', @@ -1397,7 +1408,7 @@ describe("packed artifact contract", () => { ' tool: "identity", resultFormat: "json",', ' provider: "github"', "};", - "void [types, version, pluginApiVersion, runtime, authError, profileContextError, profileContextArgument, profileContextMetaKey, profileContextRevocations, profileContextServiceConstructor, authContext, secretPluginRequest, secretPluginResult, secretPlugin, routingSignal, routingPluginRequest, routingPluginResult, routingPlugin, plugin, pluginKind, secretPluginConfig, routingPluginConfig, pluginConfig, pluginsConfig, globalScope, validState, auditRotation, auditIntegrity, validSessionState, validProfileLease, isolatedFile, isolatedVolume, isolation, invalidDuplicateProfileLease, unknownRisk, invalidState, validTextIdentity, mismatchedTextProviderIdentity, validDestructiveIdentity, validWriteThenDestructiveIdentity, validDestructiveThenWriteIdentity, invalidDuplicateRiskIdentity, invalidTextIdentity, invalidTextOrganization, invalidTextProviderWithoutProbeProvider, invalidJsonStaticProvider, invalidJsonEmptyExpected, invalidJsonProbe];" + "void [types, version, pluginApiVersion, runtime, legacyConnect, authError, profileContextError, profileContextArgument, profileContextMetaKey, profileContextRevocations, profileContextServiceConstructor, authContext, secretPluginRequest, secretPluginResult, secretPlugin, routingSignal, routingPluginRequest, routingPluginResult, routingPlugin, plugin, pluginKind, secretPluginConfig, routingPluginConfig, pluginConfig, pluginsConfig, globalScope, validState, auditRotation, auditIntegrity, validSessionState, validProfileLease, isolatedFile, isolatedVolume, isolation, invalidDuplicateProfileLease, unknownRisk, invalidState, validTextIdentity, mismatchedTextProviderIdentity, validDestructiveIdentity, validWriteThenDestructiveIdentity, validDestructiveThenWriteIdentity, invalidDuplicateRiskIdentity, invalidTextIdentity, invalidTextOrganization, invalidTextProviderWithoutProbeProvider, invalidJsonStaticProvider, invalidJsonEmptyExpected, invalidJsonProbe];" ].join("\n") ); const typecheck = spawnSync( diff --git a/tests/release-config.test.ts b/tests/release-config.test.ts index 382fdf9..0b8068f 100644 --- a/tests/release-config.test.ts +++ b/tests/release-config.test.ts @@ -34,6 +34,14 @@ function readPackageDevelopmentDependencies(): Record { return packageJson.devDependencies; } +function readPackageDependencies(): Record { + const packageJson = JSON.parse(readRepositoryFile("package.json")) as { + dependencies?: Record; + }; + if (!packageJson.dependencies) throw new Error("package.json does not define dependencies."); + return packageJson.dependencies; +} + function readLockedPackages(): Record { const lockfile = JSON.parse(readRepositoryFile("package-lock.json")) as { packages?: Record; @@ -156,6 +164,7 @@ describe("continuous integration workflow contract", () => { it("pins patched transitive test-toolchain dependencies", () => { const overrides = readPackageOverrides(); + const dependencies = readPackageDependencies(); const developmentDependencies = readPackageDevelopmentDependencies(); const lockedPackages = readLockedPackages(); @@ -181,10 +190,12 @@ describe("continuous integration workflow contract", () => { for (const name of ["glob", "postcss"]) { expect(overrides).not.toHaveProperty(name); } - expect(developmentDependencies).toMatchObject({ + expect(dependencies).toMatchObject({ "@hono/node-server": "2.0.10", hono: "4.12.34" }); + expect(developmentDependencies).not.toHaveProperty("@hono/node-server"); + expect(developmentDependencies).not.toHaveProperty("hono"); expect(lockedPackages["node_modules/minimatch/node_modules/brace-expansion"]).toMatchObject({ version: "5.0.9", dev: true