diff --git a/docs/transcription/index.html b/docs/transcription/index.html
index 0eb0653..cde8b37 100644
--- a/docs/transcription/index.html
+++ b/docs/transcription/index.html
@@ -96,7 +96,7 @@ Unit Test: Simple Transcription
});
it("returns simple transcription text", async () => {
- mock.onTranscription("audio.mp3", {
+ mock.onTranscription({
transcription: { text: "Hello, how are you today?" },
});
@@ -121,7 +121,7 @@ Unit Test: Verbose Response with Segments
transcription-verbose.test.ts ts
it("returns verbose transcription with words and segments", async () => {
- mock.onTranscription("meeting.wav", {
+ mock.onTranscription({
transcription: {
text: "Welcome to the meeting.",
words: [
diff --git a/docs/vertex-ai/index.html b/docs/vertex-ai/index.html
index 078ee98..0d46602 100644
--- a/docs/vertex-ai/index.html
+++ b/docs/vertex-ai/index.html
@@ -185,7 +185,7 @@ Fixture Examples
"toolCalls": [
{
"name": "analyze_data",
- "arguments": "{\"dataset\":\"sales_q4\"}"
+ "arguments": { "dataset": "sales_q4" }
}
]
}
diff --git a/fixtures/example-multi-turn.json b/fixtures/example-multi-turn.json
index 7976f60..abeb3d4 100644
--- a/fixtures/example-multi-turn.json
+++ b/fixtures/example-multi-turn.json
@@ -3,7 +3,7 @@
{
"match": { "userMessage": "change background to blue" },
"response": {
- "toolCalls": [{ "name": "change_background", "arguments": "{\"background\":\"blue\"}" }]
+ "toolCalls": [{ "name": "change_background", "arguments": { "background": "blue" } }]
}
},
{
diff --git a/fixtures/example-tool-call.json b/fixtures/example-tool-call.json
index 9ad26ab..3c376d4 100644
--- a/fixtures/example-tool-call.json
+++ b/fixtures/example-tool-call.json
@@ -6,7 +6,7 @@
"toolCalls": [
{
"name": "get_weather",
- "arguments": "{\"location\":\"San Francisco\",\"unit\":\"fahrenheit\"}"
+ "arguments": { "location": "San Francisco", "unit": "fahrenheit" }
}
]
}
diff --git a/fixtures/examples/adk/gemini-agent.json b/fixtures/examples/adk/gemini-agent.json
index 929f125..5222d9f 100644
--- a/fixtures/examples/adk/gemini-agent.json
+++ b/fixtures/examples/adk/gemini-agent.json
@@ -6,7 +6,7 @@
"toolCalls": [
{
"name": "get_weather",
- "arguments": "{\"city\":\"San Francisco\",\"unit\":\"fahrenheit\"}"
+ "arguments": { "city": "San Francisco", "unit": "fahrenheit" }
}
]
}
@@ -23,7 +23,7 @@
"toolCalls": [
{
"name": "google_search",
- "arguments": "{\"query\":\"latest AI news\"}"
+ "arguments": { "query": "latest AI news" }
}
]
}
@@ -34,11 +34,11 @@
"toolCalls": [
{
"name": "get_weather",
- "arguments": "{\"city\":\"New York\",\"unit\":\"celsius\"}"
+ "arguments": { "city": "New York", "unit": "celsius" }
},
{
"name": "get_time",
- "arguments": "{\"timezone\":\"America/New_York\"}"
+ "arguments": { "timezone": "America/New_York" }
}
]
}
diff --git a/fixtures/examples/langchain/agent-loop.json b/fixtures/examples/langchain/agent-loop.json
index 852e71f..8a4216d 100644
--- a/fixtures/examples/langchain/agent-loop.json
+++ b/fixtures/examples/langchain/agent-loop.json
@@ -12,7 +12,7 @@
"toolCalls": [
{
"name": "search_flights",
- "arguments": "{\"origin\":\"SFO\",\"dest\":\"NRT\"}"
+ "arguments": { "origin": "SFO", "dest": "NRT" }
}
]
}
diff --git a/fixtures/examples/mastra/agent-workflow.json b/fixtures/examples/mastra/agent-workflow.json
index 3ac6505..aa9a4d7 100644
--- a/fixtures/examples/mastra/agent-workflow.json
+++ b/fixtures/examples/mastra/agent-workflow.json
@@ -6,7 +6,7 @@
"toolCalls": [
{
"name": "search_flights",
- "arguments": "{\"origin\":\"SFO\",\"destination\":\"NRT\",\"date\":\"2025-03-15\"}"
+ "arguments": { "origin": "SFO", "destination": "NRT", "date": "2025-03-15" }
}
]
}
@@ -17,7 +17,7 @@
"toolCalls": [
{
"name": "search_hotels",
- "arguments": "{\"city\":\"Tokyo\",\"checkIn\":\"2025-03-15\",\"checkOut\":\"2025-03-22\"}"
+ "arguments": { "city": "Tokyo", "checkIn": "2025-03-15", "checkOut": "2025-03-22" }
}
]
}
diff --git a/fixtures/examples/pydanticai/structured-output.json b/fixtures/examples/pydanticai/structured-output.json
index 3cca151..c5c47d3 100644
--- a/fixtures/examples/pydanticai/structured-output.json
+++ b/fixtures/examples/pydanticai/structured-output.json
@@ -6,7 +6,7 @@
"toolCalls": [
{
"name": "final_result",
- "arguments": "{\"city\": \"SF\", \"temp\": 72, \"unit\": \"fahrenheit\"}"
+ "arguments": { "city": "SF", "temp": 72, "unit": "fahrenheit" }
}
]
}
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..1782bab
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,7134 @@
+{
+ "name": "@copilotkit/aimock",
+ "version": "1.14.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "@copilotkit/aimock",
+ "version": "1.14.0",
+ "license": "MIT",
+ "bin": {
+ "aimock": "dist/aimock-cli.js",
+ "llmock": "dist/cli.js"
+ },
+ "devDependencies": {
+ "@anthropic-ai/sdk": "^0.78.0",
+ "@arethetypeswrong/cli": "^0.17.3",
+ "@commitlint/cli": "^19.8.1",
+ "@commitlint/config-conventional": "^19.8.0",
+ "@eslint/js": "^9.30.0",
+ "@google/generative-ai": "^0.24.0",
+ "@types/node": "^22.0.0",
+ "@vitest/coverage-v8": "^3.2.4",
+ "eslint": "^9.30.0",
+ "eslint-config-prettier": "^10.1.5",
+ "husky": "^9.1.7",
+ "lint-staged": "^16.3.2",
+ "openai": "^4.0.0",
+ "prettier": "^3.6.2",
+ "publint": "^0.3.12",
+ "tsdown": "^0.12.5",
+ "tsx": "^4.19.0",
+ "typescript": "^5.8.3",
+ "typescript-eslint": "^8.35.1",
+ "vitest": "^3.2.1"
+ },
+ "engines": {
+ "node": ">=20.15.0"
+ }
+ },
+ "node_modules/@ampproject/remapping": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/@ampproject/remapping/-/remapping-2.3.0.tgz",
+ "integrity": "sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@jridgewell/gen-mapping": "^0.3.5",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@andrewbranch/untar.js": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/@andrewbranch/untar.js/-/untar.js-1.0.3.tgz",
+ "integrity": "sha512-Jh15/qVmrLGhkKJBdXlK1+9tY4lZruYjsgkDFj08ZmDiWVBLJcqkok7Z0/R0In+i1rScBpJlSvrTS2Lm41Pbnw==",
+ "dev": true
+ },
+ "node_modules/@anthropic-ai/sdk": {
+ "version": "0.78.0",
+ "resolved": "https://registry.npmjs.org/@anthropic-ai/sdk/-/sdk-0.78.0.tgz",
+ "integrity": "sha512-PzQhR715td/m1UaaN5hHXjYB8Gl2lF9UVhrrGrZeysiF6Rb74Wc9GCB8hzLdzmQtBd1qe89F9OptgB9Za1Ib5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-schema-to-ts": "^3.1.1"
+ },
+ "bin": {
+ "anthropic-ai-sdk": "bin/cli"
+ },
+ "peerDependencies": {
+ "zod": "^3.25.0 || ^4.0.0"
+ },
+ "peerDependenciesMeta": {
+ "zod": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@arethetypeswrong/cli": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@arethetypeswrong/cli/-/cli-0.17.4.tgz",
+ "integrity": "sha512-AeiKxtf67XD/NdOqXgBOE5TZWH3EOCt+0GkbUpekOzngc+Q/cRZ5azjWyMxISxxfp0EItgm5NoSld9p7BAA5xQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@arethetypeswrong/core": "0.17.4",
+ "chalk": "^4.1.2",
+ "cli-table3": "^0.6.3",
+ "commander": "^10.0.1",
+ "marked": "^9.1.2",
+ "marked-terminal": "^7.1.0",
+ "semver": "^7.5.4"
+ },
+ "bin": {
+ "attw": "dist/index.js"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@arethetypeswrong/cli/node_modules/@arethetypeswrong/core": {
+ "version": "0.17.4",
+ "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.17.4.tgz",
+ "integrity": "sha512-Izvir8iIoU+X4SKtDAa5kpb+9cpifclzsbA8x/AZY0k0gIfXYQ1fa1B6Epfe6vNA2YfDX8VtrZFgvnXB6aPEoQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@andrewbranch/untar.js": "^1.0.3",
+ "@loaderkit/resolve": "^1.0.2",
+ "cjs-module-lexer": "^1.2.3",
+ "fflate": "^0.8.2",
+ "lru-cache": "^10.4.3",
+ "semver": "^7.5.4",
+ "typescript": "5.6.1-rc",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@arethetypeswrong/cli/node_modules/typescript": {
+ "version": "5.6.1-rc",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.1-rc.tgz",
+ "integrity": "sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/@arethetypeswrong/core": {
+ "version": "0.18.2",
+ "resolved": "https://registry.npmjs.org/@arethetypeswrong/core/-/core-0.18.2.tgz",
+ "integrity": "sha512-GiwTmBFOU1/+UVNqqCGzFJYfBXEytUkiI+iRZ6Qx7KmUVtLm00sYySkfe203C9QtPG11yOz1ZaMek8dT/xnlgg==",
+ "extraneous": true,
+ "license": "MIT",
+ "dependencies": {
+ "@andrewbranch/untar.js": "^1.0.3",
+ "@loaderkit/resolve": "^1.0.2",
+ "cjs-module-lexer": "^1.2.3",
+ "fflate": "^0.8.2",
+ "lru-cache": "^11.0.1",
+ "semver": "^7.5.4",
+ "typescript": "5.6.1-rc",
+ "validate-npm-package-name": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/@arethetypeswrong/core/node_modules/lru-cache": {
+ "version": "11.3.5",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-11.3.5.tgz",
+ "integrity": "sha512-NxVFwLAnrd9i7KUBxC4DrUhmgjzOs+1Qm50D3oF1/oL+r1NpZ4gA7xvG0/zJ8evR7zIKn4vLf7qTNduWFtCrRw==",
+ "extraneous": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": "20 || >=22"
+ }
+ },
+ "node_modules/@arethetypeswrong/core/node_modules/typescript": {
+ "version": "5.6.1-rc",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.6.1-rc.tgz",
+ "integrity": "sha512-E3b2+1zEFu84jB0YQi9BORDjz9+jGbwwy1Zi3G0LUNw7a7cePUrHMRNy8aPh53nXpkFGVHSxIZo5vKTfYaFiBQ==",
+ "extraneous": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/@babel/code-frame": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.29.0.tgz",
+ "integrity": "sha512-9NhCeYjq9+3uxgdtp20LSiJXJvN0FeCtNGpJxuMFZ1Kv3cWUNb6DOhJwUvcVCzKGR66cw4njwM6hrJLqgOwbcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-validator-identifier": "^7.28.5",
+ "js-tokens": "^4.0.0",
+ "picocolors": "^1.1.1"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/code-frame/node_modules/js-tokens": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
+ "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@babel/generator": {
+ "version": "7.29.1",
+ "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.29.1.tgz",
+ "integrity": "sha512-qsaF+9Qcm2Qv8SRIMMscAvG4O3lJ0F1GuMo5HR/Bp02LopNgnZBC/EkbevHFeGs4ls/oPz9v+Bsmzbkbe+0dUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.29.0",
+ "@babel/types": "^7.29.0",
+ "@jridgewell/gen-mapping": "^0.3.12",
+ "@jridgewell/trace-mapping": "^0.3.28",
+ "jsesc": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-string-parser": {
+ "version": "7.27.1",
+ "resolved": "https://registry.npmjs.org/@babel/helper-string-parser/-/helper-string-parser-7.27.1.tgz",
+ "integrity": "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/helper-validator-identifier": {
+ "version": "7.28.5",
+ "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz",
+ "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/parser": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.29.2.tgz",
+ "integrity": "sha512-4GgRzy/+fsBa72/RZVJmGKPmZu9Byn8o4MoLpmNe1m8ZfYnz5emHLQz3U4gLud6Zwl0RZIcgiLD7Uq7ySFuDLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/types": "^7.29.0"
+ },
+ "bin": {
+ "parser": "bin/babel-parser.js"
+ },
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@babel/runtime": {
+ "version": "7.29.2",
+ "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.29.2.tgz",
+ "integrity": "sha512-JiDShH45zKHWyGe4ZNVRrCjBz8Nh9TMmZG1kh4QTK8hCBTWBi8Da+i7s1fJw7/lYpM4ccepSNfqzZ/QvABBi5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@babel/types": {
+ "version": "7.29.0",
+ "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.29.0.tgz",
+ "integrity": "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/helper-string-parser": "^7.27.1",
+ "@babel/helper-validator-identifier": "^7.28.5"
+ },
+ "engines": {
+ "node": ">=6.9.0"
+ }
+ },
+ "node_modules/@bcoe/v8-coverage": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/@bcoe/v8-coverage/-/v8-coverage-1.0.2.tgz",
+ "integrity": "sha512-6zABk/ECA/QYSCQ1NGiVwwbQerUCZ+TQbp64Q3AgmfNvurHH0j8TtXa1qbShXA6qqkpAj4V5W8pP6mLe1mcMqA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@braidai/lang": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/@braidai/lang/-/lang-1.1.2.tgz",
+ "integrity": "sha512-qBcknbBufNHlui137Hft8xauQMTZDKdophmLFv05r2eNmdIv/MlPuP4TdUknHG68UdWLgVZwgxVe735HzJNIwA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/@colors/colors": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/@colors/colors/-/colors-1.5.0.tgz",
+ "integrity": "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=0.1.90"
+ }
+ },
+ "node_modules/@commitlint/cli": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/cli/-/cli-19.8.1.tgz",
+ "integrity": "sha512-LXUdNIkspyxrlV6VDHWBmCZRtkEVRpBKxi2Gtw3J54cGWhLCTouVD/Q6ZSaSvd2YaDObWK8mDjrz3TIKtaQMAA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/format": "^19.8.1",
+ "@commitlint/lint": "^19.8.1",
+ "@commitlint/load": "^19.8.1",
+ "@commitlint/read": "^19.8.1",
+ "@commitlint/types": "^19.8.1",
+ "tinyexec": "^1.0.0",
+ "yargs": "^17.0.0"
+ },
+ "bin": {
+ "commitlint": "cli.js"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/config-conventional": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-conventional/-/config-conventional-19.8.1.tgz",
+ "integrity": "sha512-/AZHJL6F6B/G959CsMAzrPKKZjeEiAVifRyEwXxcT6qtqbPwGw+iQxmNS+Bu+i09OCtdNRW6pNpBvgPrtMr9EQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.1",
+ "conventional-changelog-conventionalcommits": "^7.0.2"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/config-validator": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/config-validator/-/config-validator-19.8.1.tgz",
+ "integrity": "sha512-0jvJ4u+eqGPBIzzSdqKNX1rvdbSU1lPNYlfQQRIFnBgLy26BtC0cFnr7c/AyuzExMxWsMOte6MkTi9I3SQ3iGQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.1",
+ "ajv": "^8.11.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/ensure": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/ensure/-/ensure-19.8.1.tgz",
+ "integrity": "sha512-mXDnlJdvDzSObafjYrOSvZBwkD01cqB4gbnnFuVyNpGUM5ijwU/r/6uqUmBXAAOKRfyEjpkGVZxaDsCVnHAgyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.1",
+ "lodash.camelcase": "^4.3.0",
+ "lodash.kebabcase": "^4.1.1",
+ "lodash.snakecase": "^4.1.1",
+ "lodash.startcase": "^4.4.0",
+ "lodash.upperfirst": "^4.3.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/execute-rule": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/execute-rule/-/execute-rule-19.8.1.tgz",
+ "integrity": "sha512-YfJyIqIKWI64Mgvn/sE7FXvVMQER/Cd+s3hZke6cI1xgNT/f6ZAz5heND0QtffH+KbcqAwXDEE1/5niYayYaQA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/format": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/format/-/format-19.8.1.tgz",
+ "integrity": "sha512-kSJj34Rp10ItP+Eh9oCItiuN/HwGQMXBnIRk69jdOwEW9llW9FlyqcWYbHPSGofmjsqeoxa38UaEA5tsbm2JWw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.1",
+ "chalk": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/format/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@commitlint/is-ignored": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/is-ignored/-/is-ignored-19.8.1.tgz",
+ "integrity": "sha512-AceOhEhekBUQ5dzrVhDDsbMaY5LqtN8s1mqSnT2Kz1ERvVZkNihrs3Sfk1Je/rxRNbXYFzKZSHaPsEJJDJV8dg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.1",
+ "semver": "^7.6.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/lint": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/lint/-/lint-19.8.1.tgz",
+ "integrity": "sha512-52PFbsl+1EvMuokZXLRlOsdcLHf10isTPlWwoY1FQIidTsTvjKXVXYb7AvtpWkDzRO2ZsqIgPK7bI98x8LRUEw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/is-ignored": "^19.8.1",
+ "@commitlint/parse": "^19.8.1",
+ "@commitlint/rules": "^19.8.1",
+ "@commitlint/types": "^19.8.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/load": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/load/-/load-19.8.1.tgz",
+ "integrity": "sha512-9V99EKG3u7z+FEoe4ikgq7YGRCSukAcvmKQuTtUyiYPnOd9a2/H9Ak1J9nJA1HChRQp9OA/sIKPugGS+FK/k1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/config-validator": "^19.8.1",
+ "@commitlint/execute-rule": "^19.8.1",
+ "@commitlint/resolve-extends": "^19.8.1",
+ "@commitlint/types": "^19.8.1",
+ "chalk": "^5.3.0",
+ "cosmiconfig": "^9.0.0",
+ "cosmiconfig-typescript-loader": "^6.1.0",
+ "lodash.isplainobject": "^4.0.6",
+ "lodash.merge": "^4.6.2",
+ "lodash.uniq": "^4.5.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/load/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@commitlint/message": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/message/-/message-19.8.1.tgz",
+ "integrity": "sha512-+PMLQvjRXiU+Ae0Wc+p99EoGEutzSXFVwQfa3jRNUZLNW5odZAyseb92OSBTKCu+9gGZiJASt76Cj3dLTtcTdg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/parse": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/parse/-/parse-19.8.1.tgz",
+ "integrity": "sha512-mmAHYcMBmAgJDKWdkjIGq50X4yB0pSGpxyOODwYmoexxxiUCy5JJT99t1+PEMK7KtsCtzuWYIAXYAiKR+k+/Jw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/types": "^19.8.1",
+ "conventional-changelog-angular": "^7.0.0",
+ "conventional-commits-parser": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/read": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/read/-/read-19.8.1.tgz",
+ "integrity": "sha512-03Jbjb1MqluaVXKHKRuGhcKWtSgh3Jizqy2lJCRbRrnWpcM06MYm8th59Xcns8EqBYvo0Xqb+2DoZFlga97uXQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/top-level": "^19.8.1",
+ "@commitlint/types": "^19.8.1",
+ "git-raw-commits": "^4.0.0",
+ "minimist": "^1.2.8",
+ "tinyexec": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/resolve-extends": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/resolve-extends/-/resolve-extends-19.8.1.tgz",
+ "integrity": "sha512-GM0mAhFk49I+T/5UCYns5ayGStkTt4XFFrjjf0L4S26xoMTSkdCf9ZRO8en1kuopC4isDFuEm7ZOm/WRVeElVg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/config-validator": "^19.8.1",
+ "@commitlint/types": "^19.8.1",
+ "global-directory": "^4.0.1",
+ "import-meta-resolve": "^4.0.0",
+ "lodash.mergewith": "^4.6.2",
+ "resolve-from": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/rules": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/rules/-/rules-19.8.1.tgz",
+ "integrity": "sha512-Hnlhd9DyvGiGwjfjfToMi1dsnw1EXKGJNLTcsuGORHz6SS9swRgkBsou33MQ2n51/boIDrbsg4tIBbRpEWK2kw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@commitlint/ensure": "^19.8.1",
+ "@commitlint/message": "^19.8.1",
+ "@commitlint/to-lines": "^19.8.1",
+ "@commitlint/types": "^19.8.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/to-lines": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/to-lines/-/to-lines-19.8.1.tgz",
+ "integrity": "sha512-98Mm5inzbWTKuZQr2aW4SReY6WUukdWXuZhrqf1QdKPZBCCsXuG87c+iP0bwtD6DBnmVVQjgp4whoHRVixyPBg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/top-level": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/top-level/-/top-level-19.8.1.tgz",
+ "integrity": "sha512-Ph8IN1IOHPSDhURCSXBz44+CIu+60duFwRsg6HqaISFHQHbmBtxVw4ZrFNIYUzEP7WwrNPxa2/5qJ//NK1FGcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "find-up": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/types": {
+ "version": "19.8.1",
+ "resolved": "https://registry.npmjs.org/@commitlint/types/-/types-19.8.1.tgz",
+ "integrity": "sha512-/yCrWGCoA1SVKOks25EGadP9Pnj0oAIHGpl2wH2M2Y46dPM2ueb8wyCVOD7O3WCTkaJ0IkKvzhl1JY7+uCT2Dw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/conventional-commits-parser": "^5.0.0",
+ "chalk": "^5.3.0"
+ },
+ "engines": {
+ "node": ">=v18"
+ }
+ },
+ "node_modules/@commitlint/types/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/@emnapi/core": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/core/-/core-1.9.2.tgz",
+ "integrity": "sha512-UC+ZhH3XtczQYfOlu3lNEkdW/p4dsJ1r/bP7H8+rhao3TTTMO1ATq/4DdIi23XuGoFY+Cz0JmCbdVl0hz9jZcA==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/wasi-threads": "1.2.1",
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/runtime": {
+ "version": "1.9.2",
+ "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.9.2.tgz",
+ "integrity": "sha512-3U4+MIWHImeyu1wnmVygh5WlgfYDtyf0k8AbLhMFxOipihf6nrWC4syIm/SwEeec0mNSafiiNnMJwbza/Is6Lw==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@emnapi/wasi-threads": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/@emnapi/wasi-threads/-/wasi-threads-1.2.1.tgz",
+ "integrity": "sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@esbuild/aix-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.7.tgz",
+ "integrity": "sha512-EKX3Qwmhz1eMdEJokhALr0YiD0lhQNwDqkPYyPhiSwKrh7/4KRjQc04sZ8db+5DVVnZ1LmbNDI1uAMPEUBnQPg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "aix"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.7.tgz",
+ "integrity": "sha512-jbPXvB4Yj2yBV7HUfE2KHe4GJX51QplCN1pGbYjvsyCZbQmies29EoJbkEc+vYuU5o45AfQn37vZlyXy4YJ8RQ==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.7.tgz",
+ "integrity": "sha512-62dPZHpIXzvChfvfLJow3q5dDtiNMkwiRzPylSCfriLvZeq0a1bWChrGx/BbUbPwOrsWKMn8idSllklzBy+dgQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/android-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.7.tgz",
+ "integrity": "sha512-x5VpMODneVDb70PYV2VQOmIUUiBtY3D3mPBG8NxVk5CogneYhkR7MmM3yR/uMdITLrC1ml/NV1rj4bMJuy9MCg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.7.tgz",
+ "integrity": "sha512-5lckdqeuBPlKUwvoCXIgI2D9/ABmPq3Rdp7IfL70393YgaASt7tbju3Ac+ePVi3KDH6N2RqePfHnXkaDtY9fkw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/darwin-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.7.tgz",
+ "integrity": "sha512-rYnXrKcXuT7Z+WL5K980jVFdvVKhCHhUwid+dDYQpH+qu+TefcomiMAJpIiC2EM3Rjtq0sO3StMV/+3w3MyyqQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-B48PqeCsEgOtzME2GbNM2roU29AMTuOIN91dsMO30t+Ydis3z/3Ngoj5hhnsOSSwNzS+6JppqWsuhTp6E82l2w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/freebsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.7.tgz",
+ "integrity": "sha512-jOBDK5XEjA4m5IJK3bpAQF9/Lelu/Z9ZcdhTRLf4cajlB+8VEhFFRjWgfy3M1O4rO2GQ/b2dLwCUGpiF/eATNQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.7.tgz",
+ "integrity": "sha512-RkT/YXYBTSULo3+af8Ib0ykH8u2MBh57o7q/DAs3lTJlyVQkgQvlrPTnjIzzRPQyavxtPtfg0EopvDyIt0j1rA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.7.tgz",
+ "integrity": "sha512-RZPHBoxXuNnPQO9rvjh5jdkRmVizktkT7TCDkDmQ0W2SwHInKCAV95GRuvdSvA7w4VMwfCjUiPwDi0ZO6Nfe9A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.7.tgz",
+ "integrity": "sha512-GA48aKNkyQDbd3KtkplYWT102C5sn/EZTY4XROkxONgruHPU72l+gW+FfF8tf2cFjeHaRbWpOYa/uRBz/Xq1Pg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-loong64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.7.tgz",
+ "integrity": "sha512-a4POruNM2oWsD4WKvBSEKGIiWQF8fZOAsycHOt6JBpZ+JN2n2JH9WAv56SOyu9X5IqAjqSIPTaJkqN8F7XOQ5Q==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-mips64el": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.7.tgz",
+ "integrity": "sha512-KabT5I6StirGfIz0FMgl1I+R1H73Gp0ofL9A3nG3i/cYFJzKHhouBV5VWK1CSgKvVaG4q1RNpCTR2LuTVB3fIw==",
+ "cpu": [
+ "mips64el"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-ppc64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.7.tgz",
+ "integrity": "sha512-gRsL4x6wsGHGRqhtI+ifpN/vpOFTQtnbsupUF5R5YTAg+y/lKelYR1hXbnBdzDjGbMYjVJLJTd2OFmMewAgwlQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-riscv64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.7.tgz",
+ "integrity": "sha512-hL25LbxO1QOngGzu2U5xeXtxXcW+/GvMN3ejANqXkxZ/opySAZMrc+9LY/WyjAan41unrR3YrmtTsUpwT66InQ==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-s390x": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.7.tgz",
+ "integrity": "sha512-2k8go8Ycu1Kb46vEelhu1vqEP+UeRVj2zY1pSuPdgvbd5ykAw82Lrro28vXUrRmzEsUV0NzCf54yARIK8r0fdw==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/linux-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.7.tgz",
+ "integrity": "sha512-hzznmADPt+OmsYzw1EE33ccA+HPdIqiCRq7cQeL1Jlq2gb1+OyWBkMCrYGBJ+sxVzve2ZJEVeePbLM2iEIZSxA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-b6pqtrQdigZBwZxAn1UpazEisvwaIDvdbMbmrly7cDTMFnw/+3lVxxCTGOrkPVnsYIosJJXAsILG9XcQS+Yu6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/netbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-OfatkLojr6U+WN5EDYuoQhtM+1xco+/6FSzJJnuWiUw5eVcicbyK3dq5EeV/QHT1uy6GoDhGbFpprUiHUYggrw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "netbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.7.tgz",
+ "integrity": "sha512-AFuojMQTxAz75Fo8idVcqoQWEHIXFRbOc1TrVcFSgCZtQfSdc1RXgB3tjOn/krRHENUB4j00bfGjyl2mJrU37A==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openbsd-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.7.tgz",
+ "integrity": "sha512-+A1NJmfM8WNDv5CLVQYJ5PshuRm/4cI6WMZRg1by1GwPIQPCTs1GLEUHwiiQGT5zDdyLiRM/l1G0Pv54gvtKIg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/openharmony-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.7.tgz",
+ "integrity": "sha512-+KrvYb/C8zA9CU/g0sR6w2RBw7IGc5J2BPnc3dYc5VJxHCSF1yNMxTV5LQ7GuKteQXZtspjFbiuW5/dOj7H4Yw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/sunos-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.7.tgz",
+ "integrity": "sha512-ikktIhFBzQNt/QDyOL580ti9+5mL/YZeUPKU2ivGtGjdTYoqz6jObj6nOMfhASpS4GU4Q/Clh1QtxWAvcYKamA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "sunos"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-arm64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.7.tgz",
+ "integrity": "sha512-7yRhbHvPqSpRUV7Q20VuDwbjW5kIMwTHpptuUzV+AA46kiPze5Z7qgt6CLCK3pWFrHeNfDd1VKgyP4O+ng17CA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-ia32": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.7.tgz",
+ "integrity": "sha512-SmwKXe6VHIyZYbBLJrhOoCJRB/Z1tckzmgTLfFYOfpMAx63BJEaL9ExI8x7v0oAO3Zh6D/Oi1gVxEYr5oUCFhw==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@esbuild/win32-x64": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.7.tgz",
+ "integrity": "sha512-56hiAJPhwQ1R4i+21FVF7V8kSD5zZTdHcVuRFMW0hn753vVfQN8xlx4uOPT4xoGH0Z/oVATuR82AiqSTDIpaHg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils": {
+ "version": "4.9.1",
+ "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.1.tgz",
+ "integrity": "sha512-phrYmNiYppR7znFEdqgfWHXR6NCkZEK7hwWDHZUjit/2/U0r6XvkDl0SYnoM51Hq7FhCGdLDT6zxCCOY1hexsQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eslint-visitor-keys": "^3.4.3"
+ },
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^6.0.0 || ^7.0.0 || >=8.0.0"
+ }
+ },
+ "node_modules/@eslint-community/eslint-utils/node_modules/eslint-visitor-keys": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz",
+ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^12.22.0 || ^14.17.0 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint-community/regexpp": {
+ "version": "4.12.2",
+ "resolved": "https://registry.npmjs.org/@eslint-community/regexpp/-/regexpp-4.12.2.tgz",
+ "integrity": "sha512-EriSTlt5OC9/7SXkRSCAhfSxxoSUgBm33OH+IkwbdpgoqsSsUg7y3uh+IICI/Qg4BBWr3U2i39RpmycbxMq4ew==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.0.0 || ^14.0.0 || >=16.0.0"
+ }
+ },
+ "node_modules/@eslint/config-array": {
+ "version": "0.21.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-array/-/config-array-0.21.2.tgz",
+ "integrity": "sha512-nJl2KGTlrf9GjLimgIru+V/mzgSK0ABCDQRvxw5BjURL7WfH5uoWmizbH7QB6MmnMBd8cIC9uceWnezL1VZWWw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/object-schema": "^2.1.7",
+ "debug": "^4.3.1",
+ "minimatch": "^3.1.5"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/config-helpers": {
+ "version": "0.4.2",
+ "resolved": "https://registry.npmjs.org/@eslint/config-helpers/-/config-helpers-0.4.2.tgz",
+ "integrity": "sha512-gBrxN88gOIf3R7ja5K9slwNayVcZgK6SOUORm2uBzTeIEfeVaIhOpCtTox3P6R7o2jLFwLFTLnC7kU/RGcYEgw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/core": {
+ "version": "0.17.0",
+ "resolved": "https://registry.npmjs.org/@eslint/core/-/core-0.17.0.tgz",
+ "integrity": "sha512-yL/sLrpmtDaFEiUj1osRP4TI2MDz1AddJL+jZ7KSqvBuliN4xqYY54IfdN8qD8Toa6g1iloph1fxQNkjOxrrpQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/json-schema": "^7.0.15"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/eslintrc": {
+ "version": "3.3.5",
+ "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-3.3.5.tgz",
+ "integrity": "sha512-4IlJx0X0qftVsN5E+/vGujTRIFtwuLbNsVUe7TO6zYPDR1O6nFwvwhIKEKSrl6dZchmYBITazxKoUYOjdtjlRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ajv": "^6.14.0",
+ "debug": "^4.3.2",
+ "espree": "^10.0.1",
+ "globals": "^14.0.0",
+ "ignore": "^5.2.0",
+ "import-fresh": "^3.2.1",
+ "js-yaml": "^4.1.1",
+ "minimatch": "^3.1.5",
+ "strip-json-comments": "^3.1.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/ajv": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@eslint/js": {
+ "version": "9.39.4",
+ "resolved": "https://registry.npmjs.org/@eslint/js/-/js-9.39.4.tgz",
+ "integrity": "sha512-nE7DEIchvtiFTwBw4Lfbu59PG+kCofhjsKaCWzxTpt4lfRjRMqG6uMBzKXuEcyXhOHoUp9riAm7/aWYGhXZ9cw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ }
+ },
+ "node_modules/@eslint/object-schema": {
+ "version": "2.1.7",
+ "resolved": "https://registry.npmjs.org/@eslint/object-schema/-/object-schema-2.1.7.tgz",
+ "integrity": "sha512-VtAOaymWVfZcmZbp6E2mympDIHvyjXs/12LqWYjVw6qjrfF+VK+fyG33kChz3nnK+SU5/NeHOqrTEHS8sXO3OA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@eslint/plugin-kit": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/@eslint/plugin-kit/-/plugin-kit-0.4.1.tgz",
+ "integrity": "sha512-43/qtrDUokr7LJqoF2c3+RInu/t4zfrpYdoSDfYyhg52rwLV6TnOvdG4fXm7IkSB3wErkcmJS9iEhjVtOSEjjA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@eslint/core": "^0.17.0",
+ "levn": "^0.4.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ }
+ },
+ "node_modules/@google/generative-ai": {
+ "version": "0.24.1",
+ "resolved": "https://registry.npmjs.org/@google/generative-ai/-/generative-ai-0.24.1.tgz",
+ "integrity": "sha512-MqO+MLfM6kjxcKoy0p1wRzG3b4ZZXtPI+z2IE26UogS2Cm/XHO+7gGRBh6gcJsOiIVoH93UwKvW4HdgiOZCy9Q==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/@humanfs/core": {
+ "version": "0.19.1",
+ "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
+ "integrity": "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanfs/node": {
+ "version": "0.16.7",
+ "resolved": "https://registry.npmjs.org/@humanfs/node/-/node-0.16.7.tgz",
+ "integrity": "sha512-/zUx+yOsIrG4Y43Eh2peDeKCxlRt/gET6aHfaKpuq267qXdYDFViVHfMaLyygZOnl0kGWxFIgsBy8QFuTLUXEQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@humanfs/core": "^0.19.1",
+ "@humanwhocodes/retry": "^0.4.0"
+ },
+ "engines": {
+ "node": ">=18.18.0"
+ }
+ },
+ "node_modules/@humanwhocodes/module-importer": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz",
+ "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.22"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@humanwhocodes/retry": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/@humanwhocodes/retry/-/retry-0.4.3.tgz",
+ "integrity": "sha512-bV0Tgo9K4hfPCek+aMAn81RppFKv2ySDQeMoSZuvTASywNTnVJCArCZE2FWqpvIatKu7VMRLWlR1EazvVhDyhQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=18.18"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/nzakas"
+ }
+ },
+ "node_modules/@isaacs/cliui": {
+ "version": "8.0.2",
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^5.1.2",
+ "string-width-cjs": "npm:string-width@^4.2.0",
+ "strip-ansi": "^7.0.1",
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
+ "wrap-ansi": "^8.1.0",
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
+ "version": "9.2.2",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "eastasianwidth": "^0.2.0",
+ "emoji-regex": "^9.2.2",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/@isaacs/cliui/node_modules/wrap-ansi": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.1.0",
+ "string-width": "^5.0.1",
+ "strip-ansi": "^7.0.1"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/@istanbuljs/schema": {
+ "version": "0.1.6",
+ "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.6.tgz",
+ "integrity": "sha512-+Sg6GCR/wy1oSmQDFq4LQDAhm3ETKnorxN+y5nbLULOR3P0c14f2Wurzj3/xqPXtasLFfHd5iRFQ7AJt4KH2cw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/@jridgewell/gen-mapping": {
+ "version": "0.3.13",
+ "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.13.tgz",
+ "integrity": "sha512-2kkt/7niJ6MgEPxF0bYdQ6etZaA+fQvDcLKckhy1yIQOzaoKjBBjSj63/aLVjYE3qhRt5dvM+uUyfCg6UKCBbA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.0",
+ "@jridgewell/trace-mapping": "^0.3.24"
+ }
+ },
+ "node_modules/@jridgewell/resolve-uri": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/@jridgewell/resolve-uri/-/resolve-uri-3.1.2.tgz",
+ "integrity": "sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.0.0"
+ }
+ },
+ "node_modules/@jridgewell/sourcemap-codec": {
+ "version": "1.5.5",
+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.5.tgz",
+ "integrity": "sha512-cYQ9310grqxueWbl+WuIUIaiUaDcj7WOq5fVhEljNVgRfOUhY9fy2zTvfoqWsnebh8Sl70VScFbICvJnLKB0Og==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@jridgewell/trace-mapping": {
+ "version": "0.3.31",
+ "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz",
+ "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/resolve-uri": "^3.1.0",
+ "@jridgewell/sourcemap-codec": "^1.4.14"
+ }
+ },
+ "node_modules/@loaderkit/resolve": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@loaderkit/resolve/-/resolve-1.0.4.tgz",
+ "integrity": "sha512-rJzYKVcV4dxJv+vW6jlvagF8zvGxHJ2+HTr1e2qOejfmGhAApgJHl8Aog4mMszxceTRiKTTbnpgmTO1bEZHV/A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@braidai/lang": "^1.0.0"
+ }
+ },
+ "node_modules/@napi-rs/wasm-runtime": {
+ "version": "1.1.3",
+ "resolved": "https://registry.npmjs.org/@napi-rs/wasm-runtime/-/wasm-runtime-1.1.3.tgz",
+ "integrity": "sha512-xK9sGVbJWYb08+mTJt3/YV24WxvxpXcXtP6B172paPZ+Ts69Re9dAr7lKwJoeIx8OoeuimEiRZ7umkiUVClmmQ==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@tybys/wasm-util": "^0.10.1"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/Brooooooklyn"
+ },
+ "peerDependencies": {
+ "@emnapi/core": "^1.7.1",
+ "@emnapi/runtime": "^1.7.1"
+ }
+ },
+ "node_modules/@oxc-project/types": {
+ "version": "0.124.0",
+ "resolved": "https://registry.npmjs.org/@oxc-project/types/-/types-0.124.0.tgz",
+ "integrity": "sha512-VBFWMTBvHxS11Z5Lvlr3IWgrwhMTXV+Md+EQF0Xf60+wAdsGFTBx7X7K/hP4pi8N7dcm1RvcHwDxZ16Qx8keUg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/Boshen"
+ }
+ },
+ "node_modules/@pkgjs/parseargs": {
+ "version": "0.11.0",
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/@publint/pack": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/@publint/pack/-/pack-0.1.4.tgz",
+ "integrity": "sha512-HDVTWq3H0uTXiU0eeSQntcVUTPP3GamzeXI41+x7uU9J65JgWQh3qWZHblR1i0npXfFtF+mxBiU2nJH8znxWnQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://bjornlu.com/sponsor"
+ }
+ },
+ "node_modules/@quansync/fs": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/@quansync/fs/-/fs-1.0.0.tgz",
+ "integrity": "sha512-4TJ3DFtlf1L5LDMaM6CanJ/0lckGNtJcMjQ1NAV6zDmA0tEHKZtxNKin8EgPaVX1YzljbxckyT2tJrpQKAtngQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "quansync": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/@rolldown/binding-android-arm64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-android-arm64/-/binding-android-arm64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-YYe6aWruPZDtHNpwu7+qAHEMbQ/yRl6atqb/AhznLTnD3UY99Q1jE7ihLSahNWkF4EqRPVC4SiR4O0UkLK02tA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-arm64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-arm64/-/binding-darwin-arm64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-oArR/ig8wNTPYsXL+Mzhs0oxhxfuHRfG7Ikw7jXsw8mYOtk71W0OkF2VEVh699pdmzjPQsTjlD1JIOoHkLP1Fg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-darwin-x64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-darwin-x64/-/binding-darwin-x64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-YzeVqOqjPYvUbJSWJ4EDL8ahbmsIXQpgL3JVipmN+MX0XnXMeWomLN3Fb+nwCmP/jfyqte5I3XRSm7OfQrbyxw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-freebsd-x64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-freebsd-x64/-/binding-freebsd-x64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-9Erhx956jeQ0nNTyif1+QWAXDRD38ZNjr//bSHrt6wDwB+QkAfl2q6Mn1k6OBPerznjRmbM10lgRb1Pli4xZPw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm-gnueabihf": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-1.0.0-rc.15.tgz",
+ "integrity": "sha512-cVwk0w8QbZJGTnP/AHQBs5yNwmpgGYStL88t4UIaqcvYJWBfS0s3oqVLZPwsPU6M0zlW4GqjP0Zq5MnAGwFeGA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-eBZ/u8iAK9SoHGanqe/jrPnY0JvBN6iXbVOsbO38mbz+ZJsaobExAm1Iu+rxa4S1l2FjG0qEZn4Rc6X8n+9M+w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-arm64-musl": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-arm64-musl/-/binding-linux-arm64-musl-1.0.0-rc.15.tgz",
+ "integrity": "sha512-ZvRYMGrAklV9PEkgt4LQM6MjQX2P58HPAuecwYObY2DhS2t35R0I810bKi0wmaYORt6m/2Sm+Z+nFgb0WhXNcQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-ppc64-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-VDpgGBzgfg5hLg+uBpCLoFG5kVvEyafmfxGUV0UHLcL5irxAK7PKNeC2MwClgk6ZAiNhmo9FLhRYgvMmedLtnQ==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-s390x-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-y1uXY3qQWCzcPgRJATPSOUP4tCemh4uBdY7e3EZbVwCJTY3gLJWnQABgeUetvED+bt1FQ01OeZwvhLS2bpNrAQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-gnu": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-gnu/-/binding-linux-x64-gnu-1.0.0-rc.15.tgz",
+ "integrity": "sha512-023bTPBod7J3Y/4fzAN6QtpkSABR0rigtrwaP+qSEabUh5zf6ELr9Nc7GujaROuPY3uwdSIXWrvhn1KxOvurWA==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-linux-x64-musl": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-linux-x64-musl/-/binding-linux-x64-musl-1.0.0-rc.15.tgz",
+ "integrity": "sha512-witB2O0/hU4CgfOOKUoeFgQ4GktPi1eEbAhaLAIpgD6+ZnhcPkUtPsoKKHRzmOoWPZue46IThdSgdo4XneOLYw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-openharmony-arm64": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-openharmony-arm64/-/binding-openharmony-arm64-1.0.0-rc.15.tgz",
+ "integrity": "sha512-UCL68NJ0Ud5zRipXZE9dF5PmirzJE4E4BCIOOssEnM7wLDsxjc6Qb0sGDxTNRTP53I6MZpygyCpY8Aa8sPfKPg==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-wasm32-wasi": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-wasm32-wasi/-/binding-wasm32-wasi-1.0.0-rc.15.tgz",
+ "integrity": "sha512-ApLruZq/ig+nhaE7OJm4lDjayUnOHVUa77zGeqnqZ9pn0ovdVbbNPerVibLXDmWeUZXjIYIT8V3xkT58Rm9u5Q==",
+ "cpu": [
+ "wasm32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "@emnapi/core": "1.9.2",
+ "@emnapi/runtime": "1.9.2",
+ "@napi-rs/wasm-runtime": "^1.1.3"
+ },
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-arm64-msvc": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-1.0.0-rc.15.tgz",
+ "integrity": "sha512-KmoUoU7HnN+Si5YWJigfTws1jz1bKBYDQKdbLspz0UaqjjFkddHsqorgiW1mxcAj88lYUE6NC/zJNwT+SloqtA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/binding-win32-x64-msvc": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/binding-win32-x64-msvc/-/binding-win32-x64-msvc-1.0.0-rc.15.tgz",
+ "integrity": "sha512-3P2A8L+x75qavWLe/Dll3EYBJLQmtkJN8rfh+U/eR3MqMgL/h98PhYI+JFfXuDPgPeCB7iZAKiqii5vqOvnA0g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ],
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ }
+ },
+ "node_modules/@rolldown/pluginutils": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-rc.15.tgz",
+ "integrity": "sha512-UromN0peaE53IaBRe9W7CjrZgXl90fqGpK+mIZbA3qSTeYqg3pqpROBdIPvOG3F5ereDHNwoHBI2e50n1BDr1g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@rollup/rollup-android-arm-eabi": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.60.1.tgz",
+ "integrity": "sha512-d6FinEBLdIiK+1uACUttJKfgZREXrF0Qc2SmLII7W2AD8FfiZ9Wjd+rD/iRuf5s5dWrr1GgwXCvPqOuDquOowA==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-android-arm64": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.60.1.tgz",
+ "integrity": "sha512-YjG/EwIDvvYI1YvYbHvDz/BYHtkY4ygUIXHnTdLhG+hKIQFBiosfWiACWortsKPKU/+dUwQQCKQM3qrDe8c9BA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "android"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-arm64": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.60.1.tgz",
+ "integrity": "sha512-mjCpF7GmkRtSJwon+Rq1N8+pI+8l7w5g9Z3vWj4T7abguC4Czwi3Yu/pFaLvA3TTeMVjnu3ctigusqWUfjZzvw==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-darwin-x64": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.60.1.tgz",
+ "integrity": "sha512-haZ7hJ1JT4e9hqkoT9R/19XW2QKqjfJVv+i5AGg57S+nLk9lQnJ1F/eZloRO3o9Scy9CM3wQ9l+dkXtcBgN5Ew==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-arm64": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.60.1.tgz",
+ "integrity": "sha512-czw90wpQq3ZsAVBlinZjAYTKduOjTywlG7fEeWKUA7oCmpA8xdTkxZZlwNJKWqILlq0wehoZcJYfBvOyhPTQ6w==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-freebsd-x64": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.60.1.tgz",
+ "integrity": "sha512-KVB2rqsxTHuBtfOeySEyzEOB7ltlB/ux38iu2rBQzkjbwRVlkhAGIEDiiYnO2kFOkJp+Z7pUXKyrRRFuFUKt+g==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "freebsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.60.1.tgz",
+ "integrity": "sha512-L+34Qqil+v5uC0zEubW7uByo78WOCIrBvci69E7sFASRl0X7b/MB6Cqd1lky/CtcSVTydWa2WZwFuWexjS5o6g==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.60.1.tgz",
+ "integrity": "sha512-n83O8rt4v34hgFzlkb1ycniJh7IR5RCIqt6mz1VRJD6pmhRi0CXdmfnLu9dIUS6buzh60IvACM842Ffb3xd6Gg==",
+ "cpu": [
+ "arm"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.60.1.tgz",
+ "integrity": "sha512-Nql7sTeAzhTAja3QXeAI48+/+GjBJ+QmAH13snn0AJSNL50JsDqotyudHyMbO2RbJkskbMbFJfIJKWA6R1LCJQ==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-arm64-musl": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.60.1.tgz",
+ "integrity": "sha512-+pUymDhd0ys9GcKZPPWlFiZ67sTWV5UU6zOJat02M1+PiuSGDziyRuI/pPue3hoUwm2uGfxdL+trT6Z9rxnlMA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-gnu": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.60.1.tgz",
+ "integrity": "sha512-VSvgvQeIcsEvY4bKDHEDWcpW4Yw7BtlKG1GUT4FzBUlEKQK0rWHYBqQt6Fm2taXS+1bXvJT6kICu5ZwqKCnvlQ==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-loong64-musl": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.60.1.tgz",
+ "integrity": "sha512-4LqhUomJqwe641gsPp6xLfhqWMbQV04KtPp7/dIp0nzPxAkNY1AbwL5W0MQpcalLYk07vaW9Kp1PBhdpZYYcEw==",
+ "cpu": [
+ "loong64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-gnu": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.60.1.tgz",
+ "integrity": "sha512-tLQQ9aPvkBxOc/EUT6j3pyeMD6Hb8QF2BTBnCQWP/uu1lhc9AIrIjKnLYMEroIz/JvtGYgI9dF3AxHZNaEH0rw==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-ppc64-musl": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.60.1.tgz",
+ "integrity": "sha512-RMxFhJwc9fSXP6PqmAz4cbv3kAyvD1etJFjTx4ONqFP9DkTkXsAMU4v3Vyc5BgzC+anz7nS/9tp4obsKfqkDHg==",
+ "cpu": [
+ "ppc64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.60.1.tgz",
+ "integrity": "sha512-QKgFl+Yc1eEk6MmOBfRHYF6lTxiiiV3/z/BRrbSiW2I7AFTXoBFvdMEyglohPj//2mZS4hDOqeB0H1ACh3sBbg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.60.1.tgz",
+ "integrity": "sha512-RAjXjP/8c6ZtzatZcA1RaQr6O1TRhzC+adn8YZDnChliZHviqIjmvFwHcxi4JKPSDAt6Uhf/7vqcBzQJy0PDJg==",
+ "cpu": [
+ "riscv64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.60.1.tgz",
+ "integrity": "sha512-wcuocpaOlaL1COBYiA89O6yfjlp3RwKDeTIA0hM7OpmhR1Bjo9j31G1uQVpDlTvwxGn2nQs65fBFL5UFd76FcQ==",
+ "cpu": [
+ "s390x"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-gnu": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.60.1.tgz",
+ "integrity": "sha512-77PpsFQUCOiZR9+LQEFg9GClyfkNXj1MP6wRnzYs0EeWbPcHs02AXu4xuUbM1zhwn3wqaizle3AEYg5aeoohhg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "glibc"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-linux-x64-musl": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.60.1.tgz",
+ "integrity": "sha512-5cIATbk5vynAjqqmyBjlciMJl1+R/CwX9oLk/EyiFXDWd95KpHdrOJT//rnUl4cUcskrd0jCCw3wpZnhIHdD9w==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "libc": [
+ "musl"
+ ],
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "linux"
+ ]
+ },
+ "node_modules/@rollup/rollup-openbsd-x64": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.60.1.tgz",
+ "integrity": "sha512-cl0w09WsCi17mcmWqqglez9Gk8isgeWvoUZ3WiJFYSR3zjBQc2J5/ihSjpl+VLjPqjQ/1hJRcqBfLjssREQILw==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openbsd"
+ ]
+ },
+ "node_modules/@rollup/rollup-openharmony-arm64": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.60.1.tgz",
+ "integrity": "sha512-4Cv23ZrONRbNtbZa37mLSueXUCtN7MXccChtKpUnQNgF010rjrjfHx3QxkS2PI7LqGT5xXyYs1a7LbzAwT0iCA==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "openharmony"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.60.1.tgz",
+ "integrity": "sha512-i1okWYkA4FJICtr7KpYzFpRTHgy5jdDbZiWfvny21iIKky5YExiDXP+zbXzm3dUcFpkEeYNHgQ5fuG236JPq0g==",
+ "cpu": [
+ "arm64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.60.1.tgz",
+ "integrity": "sha512-u09m3CuwLzShA0EYKMNiFgcjjzwqtUMLmuCJLeZWjjOYA3IT2Di09KaxGBTP9xVztWyIWjVdsB2E9goMjZvTQg==",
+ "cpu": [
+ "ia32"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-gnu": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.60.1.tgz",
+ "integrity": "sha512-k+600V9Zl1CM7eZxJgMyTUzmrmhB/0XZnF4pRypKAlAgxmedUA+1v9R+XOFv56W4SlHEzfeMtzujLJD22Uz5zg==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@rollup/rollup-win32-x64-msvc": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.60.1.tgz",
+ "integrity": "sha512-lWMnixq/QzxyhTV6NjQJ4SFo1J6PvOX8vUx5Wb4bBPsEb+8xZ89Bz6kOXpfXj9ak9AHTQVQzlgzBEc1SyM27xQ==",
+ "cpu": [
+ "x64"
+ ],
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "win32"
+ ]
+ },
+ "node_modules/@sindresorhus/is": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz",
+ "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sindresorhus/is?sponsor=1"
+ }
+ },
+ "node_modules/@tybys/wasm-util": {
+ "version": "0.10.1",
+ "resolved": "https://registry.npmjs.org/@tybys/wasm-util/-/wasm-util-0.10.1.tgz",
+ "integrity": "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg==",
+ "dev": true,
+ "license": "MIT",
+ "optional": true,
+ "dependencies": {
+ "tslib": "^2.4.0"
+ }
+ },
+ "node_modules/@types/chai": {
+ "version": "5.2.3",
+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz",
+ "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/deep-eql": "*",
+ "assertion-error": "^2.0.1"
+ }
+ },
+ "node_modules/@types/conventional-commits-parser": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/@types/conventional-commits-parser/-/conventional-commits-parser-5.0.2.tgz",
+ "integrity": "sha512-BgT2szDXnVypgpNxOK8aL5SGjUdaQbC++WZNjF1Qge3Og2+zhHj+RWhmehLhYyvQwqAmvezruVfOf8+3m74W+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*"
+ }
+ },
+ "node_modules/@types/deep-eql": {
+ "version": "4.0.2",
+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/estree": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
+ "integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/json-schema": {
+ "version": "7.0.15",
+ "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.15.tgz",
+ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/@types/node": {
+ "version": "22.19.17",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.19.17.tgz",
+ "integrity": "sha512-wGdMcf+vPYM6jikpS/qhg6WiqSV/OhG+jeeHT/KlVqxYfD40iYJf9/AE1uQxVWFvU7MipKRkRv8NSHiCGgPr8Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~6.21.0"
+ }
+ },
+ "node_modules/@types/node-fetch": {
+ "version": "2.6.13",
+ "resolved": "https://registry.npmjs.org/@types/node-fetch/-/node-fetch-2.6.13.tgz",
+ "integrity": "sha512-QGpRVpzSaUs30JBSGPjOg4Uveu384erbHBoT1zeONvyCfwQxIkUshLAOqN/k9EjGviPRmWTTe6aH2qySWKTVSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/node": "*",
+ "form-data": "^4.0.4"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-8.58.2.tgz",
+ "integrity": "sha512-aC2qc5thQahutKjP+cl8cgN9DWe3ZUqVko30CMSZHnFEHyhOYoZSzkGtAI2mcwZ38xeImDucI4dnqsHiOYuuCw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/regexpp": "^4.12.2",
+ "@typescript-eslint/scope-manager": "8.58.2",
+ "@typescript-eslint/type-utils": "8.58.2",
+ "@typescript-eslint/utils": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2",
+ "ignore": "^7.0.5",
+ "natural-compare": "^1.4.0",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "@typescript-eslint/parser": "^8.58.2",
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/eslint-plugin/node_modules/ignore": {
+ "version": "7.0.5",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-7.0.5.tgz",
+ "integrity": "sha512-Hs59xBNfUIunMFgWAbGX5cq6893IbWg4KnrjbYwX3tx0ztorVgTDA6B2sxf8ejHJ4wz8BqGUMYlnzNBer5NvGg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/@typescript-eslint/parser": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-8.58.2.tgz",
+ "integrity": "sha512-/Zb/xaIDfxeJnvishjGdcR4jmr7S+bda8PKNhRGdljDM+elXhlvN0FyPSsMnLmJUrVG9aPO6dof80wjMawsASg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/scope-manager": "8.58.2",
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/project-service": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/project-service/-/project-service-8.58.2.tgz",
+ "integrity": "sha512-Cq6UfpZZk15+r87BkIh5rDpi38W4b+Sjnb8wQCPPDDweS/LRCFjCyViEbzHk5Ck3f2QDfgmlxqSa7S7clDtlfg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/tsconfig-utils": "^8.58.2",
+ "@typescript-eslint/types": "^8.58.2",
+ "debug": "^4.4.3"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/scope-manager": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-8.58.2.tgz",
+ "integrity": "sha512-SgmyvDPexWETQek+qzZnrG6844IaO02UVyOLhI4wpo82dpZJY9+6YZCKAMFzXb7qhx37mFK1QcPQ18tud+vo6Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/tsconfig-utils": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/tsconfig-utils/-/tsconfig-utils-8.58.2.tgz",
+ "integrity": "sha512-3SR+RukipDvkkKp/d0jP0dyzuls3DbGmwDpVEc5wqk5f38KFThakqAAO0XMirWAE+kT00oTauTbzMFGPoAzB0A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/type-utils": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-8.58.2.tgz",
+ "integrity": "sha512-Z7EloNR/B389FvabdGeTo2XMs4W9TjtPiO9DAsmT0yom0bwlPyRjkJ1uCdW1DvrrrYP50AJZ9Xc3sByZA9+dcg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2",
+ "@typescript-eslint/utils": "8.58.2",
+ "debug": "^4.4.3",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/types": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-8.58.2.tgz",
+ "integrity": "sha512-9TukXyATBQf/Jq9AMQXfvurk+G5R2MwfqQGDR2GzGz28HvY/lXNKGhkY+6IOubwcquikWk5cjlgPvD2uAA7htQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-8.58.2.tgz",
+ "integrity": "sha512-ELGuoofuhhoCvNbQjFFiobFcGgcDCEm0ThWdmO4Z0UzLqPXS3KFvnEZ+SHewwOYHjM09tkzOWXNTv9u6Gqtyuw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/project-service": "8.58.2",
+ "@typescript-eslint/tsconfig-utils": "8.58.2",
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/visitor-keys": "8.58.2",
+ "debug": "^4.4.3",
+ "minimatch": "^10.2.2",
+ "semver": "^7.7.3",
+ "tinyglobby": "^0.2.15",
+ "ts-api-utils": "^2.5.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/brace-expansion": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
+ "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/@typescript-eslint/typescript-estree/node_modules/minimatch": {
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.5"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/@typescript-eslint/utils": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-8.58.2.tgz",
+ "integrity": "sha512-QZfjHNEzPY8+l0+fIXMvuQ2sJlplB4zgDZvA+NmvZsZv3EQwOcc1DuIU1VJUTWZ/RKouBMhDyNaBMx4sWvrzRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.9.1",
+ "@typescript-eslint/scope-manager": "8.58.2",
+ "@typescript-eslint/types": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-8.58.2.tgz",
+ "integrity": "sha512-f1WO2Lx8a9t8DARmcWAUPJbu0G20bJlj8L4z72K00TMeJAoyLr/tHhI/pzYBLrR4dXWkcxO1cWYZEOX8DKHTqA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/types": "8.58.2",
+ "eslint-visitor-keys": "^5.0.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ }
+ },
+ "node_modules/@typescript-eslint/visitor-keys/node_modules/eslint-visitor-keys": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-5.0.1.tgz",
+ "integrity": "sha512-tD40eHxA35h0PEIZNeIjkHoDR4YjjJp34biM0mDvplBe//mB+IHCqHDGV7pxF+7MklTvighcCPPZC7ynWyjdTA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^20.19.0 || ^22.13.0 || >=24"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/@vitest/coverage-v8": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz",
+ "integrity": "sha512-EyF9SXU6kS5Ku/U82E259WSnvg6c8KTjppUncuNdm5QHpe17mwREHnjDzozC8x9MZ0xfBUFSaLkRv4TMA75ALQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@ampproject/remapping": "^2.3.0",
+ "@bcoe/v8-coverage": "^1.0.2",
+ "ast-v8-to-istanbul": "^0.3.3",
+ "debug": "^4.4.1",
+ "istanbul-lib-coverage": "^3.2.2",
+ "istanbul-lib-report": "^3.0.1",
+ "istanbul-lib-source-maps": "^5.0.6",
+ "istanbul-reports": "^3.1.7",
+ "magic-string": "^0.30.17",
+ "magicast": "^0.3.5",
+ "std-env": "^3.9.0",
+ "test-exclude": "^7.0.1",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@vitest/browser": "3.2.4",
+ "vitest": "3.2.4"
+ },
+ "peerDependenciesMeta": {
+ "@vitest/browser": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/expect": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
+ "integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/mocker": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
+ "integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/spy": "3.2.4",
+ "estree-walker": "^3.0.3",
+ "magic-string": "^0.30.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "msw": "^2.4.9",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "peerDependenciesMeta": {
+ "msw": {
+ "optional": true
+ },
+ "vite": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/@vitest/pretty-format": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
+ "integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/runner": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
+ "integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/utils": "3.2.4",
+ "pathe": "^2.0.3",
+ "strip-literal": "^3.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/snapshot": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
+ "integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/spy": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
+ "integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tinyspy": "^4.0.3"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/@vitest/utils": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
+ "integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@vitest/pretty-format": "3.2.4",
+ "loupe": "^3.1.4",
+ "tinyrainbow": "^2.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/abort-controller": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz",
+ "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "event-target-shim": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=6.5"
+ }
+ },
+ "node_modules/acorn": {
+ "version": "8.16.0",
+ "resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
+ "integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "acorn": "bin/acorn"
+ },
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/acorn-jsx": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz",
+ "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==",
+ "dev": true,
+ "license": "MIT",
+ "peerDependencies": {
+ "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0"
+ }
+ },
+ "node_modules/agentkeepalive": {
+ "version": "4.6.0",
+ "resolved": "https://registry.npmjs.org/agentkeepalive/-/agentkeepalive-4.6.0.tgz",
+ "integrity": "sha512-kja8j7PjmncONqaTsB8fQ+wE2mSU2DJ9D4XKoJ5PFWIdRMa6SLSN1ff4mOr4jCbfRSsxR4keIiySJU0N9T5hIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "humanize-ms": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 8.0.0"
+ }
+ },
+ "node_modules/ajv": {
+ "version": "8.18.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.18.0.tgz",
+ "integrity": "sha512-PlXPeEWMXMZ7sPYOHqmDyCJzcfNrUr3fGNKtezX14ykXOEIvyK81d+qydx89KY5O71FKMPaQ2vBfBFI5NHR63A==",
+ "dev": true,
+ "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/ansi-escapes": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-7.3.0.tgz",
+ "integrity": "sha512-BvU8nYgGQBxcmMuEeUEmNTvrMVjJNSH7RgW24vXexN4Ven6qCvy4TntnvlnwnMLTVlcRQQdbRY8NKnaIoeWDNg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "environment": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz",
+ "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
+ }
+ },
+ "node_modules/ansi-styles": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-convert": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/ansis": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/ansis/-/ansis-4.2.0.tgz",
+ "integrity": "sha512-HqZ5rWlFjGiV0tDm3UxxgNRqsOTniqoKZu0pIAfh7TZQMGuZK+hH0drySty0si0QXj1ieop4+SkSfPZBPPkHig==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/any-promise": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz",
+ "integrity": "sha512-7UvmKalWRt1wgjL1RrGxoSJW/0QZFIegpeGvZG9kjp8vrRu55XTHbwnqq2GpXm9uLbcuhxm3IqX9OB4MZR1b2A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/argparse": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
+ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
+ "dev": true,
+ "license": "Python-2.0"
+ },
+ "node_modules/array-ify": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/array-ify/-/array-ify-1.0.0.tgz",
+ "integrity": "sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/assertion-error": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/ast-kit": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/ast-kit/-/ast-kit-2.2.0.tgz",
+ "integrity": "sha512-m1Q/RaVOnTp9JxPX+F+Zn7IcLYMzM8kZofDImfsKZd8MbR+ikdOzTeztStWqfrqIxZnYWryyI9ePm3NGjnZgGw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.28.5",
+ "pathe": "^2.0.3"
+ },
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ },
+ "node_modules/ast-v8-to-istanbul": {
+ "version": "0.3.12",
+ "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.12.tgz",
+ "integrity": "sha512-BRRC8VRZY2R4Z4lFIL35MwNXmwVqBityvOIwETtsCSwvjl0IdgFsy9NhdaA6j74nUdtJJlIypeRhpDam19Wq3g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.31",
+ "estree-walker": "^3.0.3",
+ "js-tokens": "^10.0.0"
+ }
+ },
+ "node_modules/asynckit": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
+ "integrity": "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/birpc": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/birpc/-/birpc-2.9.0.tgz",
+ "integrity": "sha512-KrayHS5pBi69Xi9JmvoqrIgYGDkD6mcSe/i6YKi3w5kekCLzrX4+nawcXqrj2tIp50Kw/mT/s3p+GVK0A0sKxw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.14",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.14.tgz",
+ "integrity": "sha512-MWPGfDxnyzKU7rNOW9SP/c50vi3xrmrua/+6hfPbCS2ABNWfx24vPidzvC7krjU/RTo235sV776ymlsMtGKj8g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/cac": {
+ "version": "6.7.14",
+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "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",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/callsites": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz",
+ "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/chai": {
+ "version": "5.3.3",
+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz",
+ "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "assertion-error": "^2.0.1",
+ "check-error": "^2.1.1",
+ "deep-eql": "^5.0.1",
+ "loupe": "^3.1.0",
+ "pathval": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/chalk": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz",
+ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.1.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/char-regex": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz",
+ "integrity": "sha512-kWWXztvZ5SBQV+eRgKFeh8q5sLuZY2+8WUIzlxWVTg+oGwY14qylx1KbKzHd8P6ZYkAg0xyIDU9JMHhyJMZ1jw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/check-error": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz",
+ "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/chokidar": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
+ "integrity": "sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "readdirp": "^4.0.1"
+ },
+ "engines": {
+ "node": ">= 14.16.0"
+ },
+ "funding": {
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/cjs-module-lexer": {
+ "version": "1.4.3",
+ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.4.3.tgz",
+ "integrity": "sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/cli-cursor": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-5.0.0.tgz",
+ "integrity": "sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "restore-cursor": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-highlight": {
+ "version": "2.1.11",
+ "resolved": "https://registry.npmjs.org/cli-highlight/-/cli-highlight-2.1.11.tgz",
+ "integrity": "sha512-9KDcoEVwyUXrjcJNvHD0NFc/hiwe/WPVYIleQh2O1N2Zro5gWJZ/K+3DGn8w8P/F6FxOgzyC5bxDyHIgCSPhGg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "chalk": "^4.0.0",
+ "highlight.js": "^10.7.1",
+ "mz": "^2.4.0",
+ "parse5": "^5.1.1",
+ "parse5-htmlparser2-tree-adapter": "^6.0.0",
+ "yargs": "^16.0.0"
+ },
+ "bin": {
+ "highlight": "bin/highlight"
+ },
+ "engines": {
+ "node": ">=8.0.0",
+ "npm": ">=5.0.0"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/cliui": {
+ "version": "7.0.4",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz",
+ "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.0",
+ "wrap-ansi": "^7.0.0"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/yargs": {
+ "version": "16.2.0",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz",
+ "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^7.0.2",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.0",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^20.2.2"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cli-highlight/node_modules/yargs-parser": {
+ "version": "20.2.9",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.9.tgz",
+ "integrity": "sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/cli-table3": {
+ "version": "0.6.5",
+ "resolved": "https://registry.npmjs.org/cli-table3/-/cli-table3-0.6.5.tgz",
+ "integrity": "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "string-width": "^4.2.0"
+ },
+ "engines": {
+ "node": "10.* || >= 12.*"
+ },
+ "optionalDependencies": {
+ "@colors/colors": "1.5.0"
+ }
+ },
+ "node_modules/cli-truncate": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/cli-truncate/-/cli-truncate-5.2.0.tgz",
+ "integrity": "sha512-xRwvIOMGrfOAnM1JYtqQImuaNtDEv9v6oIYAs4LIHwTiKee8uwvIi363igssOC0O5U04i4AlENs79LQLu9tEMw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "slice-ansi": "^8.0.0",
+ "string-width": "^8.2.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cli-truncate/node_modules/string-width": {
+ "version": "8.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-8.2.0.tgz",
+ "integrity": "sha512-6hJPQ8N0V0P3SNmP6h2J99RLuzrWz2gvT7VnK5tKvrNqJoyS9W4/Fb8mo31UiPvy00z7DQXkP2hnKBVav76thw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.5.0",
+ "strip-ansi": "^7.1.2"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/cliui": {
+ "version": "8.0.1",
+ "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
+ "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "string-width": "^4.2.0",
+ "strip-ansi": "^6.0.1",
+ "wrap-ansi": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/cliui/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/cliui/node_modules/wrap-ansi": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/color-convert": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "color-name": "~1.1.4"
+ },
+ "engines": {
+ "node": ">=7.0.0"
+ }
+ },
+ "node_modules/color-name": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/colorette": {
+ "version": "2.0.20",
+ "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz",
+ "integrity": "sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/combined-stream": {
+ "version": "1.0.8",
+ "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
+ "integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "delayed-stream": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/commander": {
+ "version": "10.0.1",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/compare-func": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/compare-func/-/compare-func-2.0.0.tgz",
+ "integrity": "sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "array-ify": "^1.0.0",
+ "dot-prop": "^5.1.0"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/conventional-changelog-angular": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-angular/-/conventional-changelog-angular-7.0.0.tgz",
+ "integrity": "sha512-ROjNchA9LgfNMTTFSIWPzebCwOGFdgkEq45EnvvrmSLvCtAw0HSmrCs7/ty+wAeYUZyNay0YMUNYFTRL72PkBQ==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-changelog-conventionalcommits": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/conventional-changelog-conventionalcommits/-/conventional-changelog-conventionalcommits-7.0.2.tgz",
+ "integrity": "sha512-NKXYmMR/Hr1DevQegFB4MwfM5Vv0m4UIxKZTTYuD98lpTknaZlSRrDOG4X7wIXpGkfsYxZTghUN+Qq+T0YQI7w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "compare-func": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/conventional-commits-parser": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/conventional-commits-parser/-/conventional-commits-parser-5.0.0.tgz",
+ "integrity": "sha512-ZPMl0ZJbw74iS9LuX9YIAiW8pfM5p3yh2o/NbXHbkFuZzY5jvdi5jFycEOkmBW5H5I7nA+D6f3UcsCLP2vvSEA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-text-path": "^2.0.0",
+ "JSONStream": "^1.3.5",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "conventional-commits-parser": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/cosmiconfig": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-9.0.1.tgz",
+ "integrity": "sha512-hr4ihw+DBqcvrsEDioRO31Z17x71pUYoNe/4h6Z0wB72p7MU7/9gH8Q3s12NFhHPfYBBOV3qyfUxmr/Yn3shnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "env-paths": "^2.2.1",
+ "import-fresh": "^3.3.0",
+ "js-yaml": "^4.1.0",
+ "parse-json": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/d-fischer"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.9.5"
+ },
+ "peerDependenciesMeta": {
+ "typescript": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/cosmiconfig-typescript-loader": {
+ "version": "6.3.0",
+ "resolved": "https://registry.npmjs.org/cosmiconfig-typescript-loader/-/cosmiconfig-typescript-loader-6.3.0.tgz",
+ "integrity": "sha512-Akr82WH1Wfqatyiqpj8HDkO2o2KmJRu1FhKfSNJP3K4IdXwHfEyL7MOb62i1AGQVLtIQM+iCE9CGOtrfhR+mmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "jiti": "2.6.1"
+ },
+ "engines": {
+ "node": ">=v18"
+ },
+ "peerDependencies": {
+ "@types/node": "*",
+ "cosmiconfig": ">=9",
+ "typescript": ">=5"
+ }
+ },
+ "node_modules/cross-spawn": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/dargs": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmjs.org/dargs/-/dargs-8.1.0.tgz",
+ "integrity": "sha512-wAV9QHOsNbwnWdNW2FYvE1P56wtgSbM+3SZcdGiWQILwVjACCXDCI3Ai8QlCjMDB8YK5zySiXZYBiwGmNY3lnw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/debug": {
+ "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"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/deep-eql": {
+ "version": "5.0.2",
+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/deep-is": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.4.tgz",
+ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/defu": {
+ "version": "6.1.7",
+ "resolved": "https://registry.npmjs.org/defu/-/defu-6.1.7.tgz",
+ "integrity": "sha512-7z22QmUWiQ/2d0KkdYmANbRUVABpZ9SNYyH5vx6PZ+nE5bcC0l7uFvEfHlyld/HcGBFTL536ClDt3DEcSlEJAQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/delayed-stream": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
+ "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.4.0"
+ }
+ },
+ "node_modules/diff": {
+ "version": "8.0.4",
+ "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.4.tgz",
+ "integrity": "sha512-DPi0FmjiSU5EvQV0++GFDOJ9ASQUVFh5kD+OzOnYdi7n3Wpm9hWWGfB/O2blfHcMVTL5WkQXSnRiK9makhrcnw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.3.1"
+ }
+ },
+ "node_modules/dot-prop": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/dot-prop/-/dot-prop-5.3.0.tgz",
+ "integrity": "sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-obj": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/dts-resolver": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/dts-resolver/-/dts-resolver-2.1.3.tgz",
+ "integrity": "sha512-bihc7jPC90VrosXNzK0LTE2cuLP6jr0Ro8jk+kMugHReJVLIpHz/xadeq3MhuwyO4TD4OA3L1Q8pBBFRc08Tsw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.19.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "oxc-resolver": ">=11.0.0"
+ },
+ "peerDependenciesMeta": {
+ "oxc-resolver": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/dunder-proto": {
+ "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",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/eastasianwidth": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/emoji-regex": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/emojilib": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/emojilib/-/emojilib-2.4.0.tgz",
+ "integrity": "sha512-5U0rVMU5Y2n2+ykNLQqMoqklN9ICBT/KsvC1Gz6vqHbz2AXXGkG+Pm5rMWk/8Vjrr/mY9985Hi8DYzn1F09Nyw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/empathic": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/empathic/-/empathic-2.0.0.tgz",
+ "integrity": "sha512-i6UzDscO/XfAcNYD75CfICkmfLedpyPDdozrLMmQc5ORaQcdMoc21OnlEylMIqI7U8eniKrPMxxtj8k0vhmJhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14"
+ }
+ },
+ "node_modules/env-paths": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz",
+ "integrity": "sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/environment": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/environment/-/environment-1.1.0.tgz",
+ "integrity": "sha512-xUtoPkMggbz0MPyPiIWr1Kp4aeWJjDZ6SMvURhimjdZgsRuDplF5/s9hcgGhyXMhs+6vpnuoiZ2kFiu3FMnS8Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/error-ex": {
+ "version": "1.3.4",
+ "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.4.tgz",
+ "integrity": "sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "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",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "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",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-module-lexer": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-set-tostringtag": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.1.0.tgz",
+ "integrity": "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.6",
+ "has-tostringtag": "^1.0.2",
+ "hasown": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/esbuild": {
+ "version": "0.27.7",
+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.7.tgz",
+ "integrity": "sha512-IxpibTjyVnmrIQo5aqNpCgoACA/dTKLTlhMHihVHhdkxKyPO1uBBthumT0rdHmcsk9uMonIWS0m4FljWzILh3w==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "bin": {
+ "esbuild": "bin/esbuild"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "optionalDependencies": {
+ "@esbuild/aix-ppc64": "0.27.7",
+ "@esbuild/android-arm": "0.27.7",
+ "@esbuild/android-arm64": "0.27.7",
+ "@esbuild/android-x64": "0.27.7",
+ "@esbuild/darwin-arm64": "0.27.7",
+ "@esbuild/darwin-x64": "0.27.7",
+ "@esbuild/freebsd-arm64": "0.27.7",
+ "@esbuild/freebsd-x64": "0.27.7",
+ "@esbuild/linux-arm": "0.27.7",
+ "@esbuild/linux-arm64": "0.27.7",
+ "@esbuild/linux-ia32": "0.27.7",
+ "@esbuild/linux-loong64": "0.27.7",
+ "@esbuild/linux-mips64el": "0.27.7",
+ "@esbuild/linux-ppc64": "0.27.7",
+ "@esbuild/linux-riscv64": "0.27.7",
+ "@esbuild/linux-s390x": "0.27.7",
+ "@esbuild/linux-x64": "0.27.7",
+ "@esbuild/netbsd-arm64": "0.27.7",
+ "@esbuild/netbsd-x64": "0.27.7",
+ "@esbuild/openbsd-arm64": "0.27.7",
+ "@esbuild/openbsd-x64": "0.27.7",
+ "@esbuild/openharmony-arm64": "0.27.7",
+ "@esbuild/sunos-x64": "0.27.7",
+ "@esbuild/win32-arm64": "0.27.7",
+ "@esbuild/win32-ia32": "0.27.7",
+ "@esbuild/win32-x64": "0.27.7"
+ }
+ },
+ "node_modules/escalade": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz",
+ "integrity": "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/escape-string-regexp": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz",
+ "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint": {
+ "version": "9.39.4",
+ "resolved": "https://registry.npmjs.org/eslint/-/eslint-9.39.4.tgz",
+ "integrity": "sha512-XoMjdBOwe/esVgEvLmNsD3IRHkm7fbKIUGvrleloJXUZgDHig2IPWNniv+GwjyJXzuNqVjlr5+4yVUZjycJwfQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@eslint-community/eslint-utils": "^4.8.0",
+ "@eslint-community/regexpp": "^4.12.1",
+ "@eslint/config-array": "^0.21.2",
+ "@eslint/config-helpers": "^0.4.2",
+ "@eslint/core": "^0.17.0",
+ "@eslint/eslintrc": "^3.3.5",
+ "@eslint/js": "9.39.4",
+ "@eslint/plugin-kit": "^0.4.1",
+ "@humanfs/node": "^0.16.6",
+ "@humanwhocodes/module-importer": "^1.0.1",
+ "@humanwhocodes/retry": "^0.4.2",
+ "@types/estree": "^1.0.6",
+ "ajv": "^6.14.0",
+ "chalk": "^4.0.0",
+ "cross-spawn": "^7.0.6",
+ "debug": "^4.3.2",
+ "escape-string-regexp": "^4.0.0",
+ "eslint-scope": "^8.4.0",
+ "eslint-visitor-keys": "^4.2.1",
+ "espree": "^10.4.0",
+ "esquery": "^1.5.0",
+ "esutils": "^2.0.2",
+ "fast-deep-equal": "^3.1.3",
+ "file-entry-cache": "^8.0.0",
+ "find-up": "^5.0.0",
+ "glob-parent": "^6.0.2",
+ "ignore": "^5.2.0",
+ "imurmurhash": "^0.1.4",
+ "is-glob": "^4.0.0",
+ "json-stable-stringify-without-jsonify": "^1.0.1",
+ "lodash.merge": "^4.6.2",
+ "minimatch": "^3.1.5",
+ "natural-compare": "^1.4.0",
+ "optionator": "^0.9.3"
+ },
+ "bin": {
+ "eslint": "bin/eslint.js"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://eslint.org/donate"
+ },
+ "peerDependencies": {
+ "jiti": "*"
+ },
+ "peerDependenciesMeta": {
+ "jiti": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/eslint-config-prettier": {
+ "version": "10.1.8",
+ "resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
+ "integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "eslint-config-prettier": "bin/cli.js"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint-config-prettier"
+ },
+ "peerDependencies": {
+ "eslint": ">=7.0.0"
+ }
+ },
+ "node_modules/eslint-scope": {
+ "version": "8.4.0",
+ "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-8.4.0.tgz",
+ "integrity": "sha512-sNXOfKCn74rt8RICKMvJS7XKV/Xk9kA7DyJr8mJik3S7Cwgy3qlkkmyS2uQB3jiJg6VNdZd/pDBJu0nvG2NlTg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "esrecurse": "^4.3.0",
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint-visitor-keys": {
+ "version": "4.2.1",
+ "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-4.2.1.tgz",
+ "integrity": "sha512-Uhdk5sfqcee/9H/rCOJikYz67o0a2Tw2hGRPOG2Y1R2dg7brRe1uG0yaNQDHu+TO/uQPF/5eCapvYSmHUjt7JQ==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/eslint/node_modules/ajv": {
+ "version": "6.14.0",
+ "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.14.0.tgz",
+ "integrity": "sha512-IWrosm/yrn43eiKqkfkHis7QioDleaXQHdDVPKg0FSwwd/DuvyX79TZnFOnYpB7dcsFAMmtFztZuXPDvSePkFw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fast-deep-equal": "^3.1.1",
+ "fast-json-stable-stringify": "^2.0.0",
+ "json-schema-traverse": "^0.4.1",
+ "uri-js": "^4.2.2"
+ },
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/epoberezkin"
+ }
+ },
+ "node_modules/eslint/node_modules/find-up": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz",
+ "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^6.0.0",
+ "path-exists": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/json-schema-traverse": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
+ "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/eslint/node_modules/locate-path": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz",
+ "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/p-limit": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz",
+ "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/p-locate": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz",
+ "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/eslint/node_modules/path-exists": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
+ "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/eslint/node_modules/yocto-queue": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz",
+ "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/espree": {
+ "version": "10.4.0",
+ "resolved": "https://registry.npmjs.org/espree/-/espree-10.4.0.tgz",
+ "integrity": "sha512-j6PAQ2uUr79PZhBjP5C5fhl8e39FmRnOjsD5lGnWrFU8i2G776tBK7+nP8KuQUTTyAZUwfQqXAgrVH5MbH9CYQ==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "acorn": "^8.15.0",
+ "acorn-jsx": "^5.3.2",
+ "eslint-visitor-keys": "^4.2.1"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/eslint"
+ }
+ },
+ "node_modules/esquery": {
+ "version": "1.7.0",
+ "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.7.0.tgz",
+ "integrity": "sha512-Ap6G0WQwcU/LHsvLwON1fAQX9Zp0A2Y6Y/cJBl9r/JbW90Zyg4/zbG6zzKa2OTALELarYHmKu0GhpM5EO+7T0g==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "estraverse": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=0.10"
+ }
+ },
+ "node_modules/esrecurse": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.3.0.tgz",
+ "integrity": "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "estraverse": "^5.2.0"
+ },
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estraverse": {
+ "version": "5.3.0",
+ "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-5.3.0.tgz",
+ "integrity": "sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=4.0"
+ }
+ },
+ "node_modules/estree-walker": {
+ "version": "3.0.3",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "^1.0.0"
+ }
+ },
+ "node_modules/esutils": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.3.tgz",
+ "integrity": "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/event-target-shim": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz",
+ "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/eventemitter3": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.4.tgz",
+ "integrity": "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/expect-type": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz",
+ "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "engines": {
+ "node": ">=12.0.0"
+ }
+ },
+ "node_modules/fast-deep-equal": {
+ "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": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz",
+ "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-levenshtein": {
+ "version": "2.0.6",
+ "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz",
+ "integrity": "sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/fast-uri": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz",
+ "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==",
+ "dev": true,
+ "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",
+ "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "peerDependencies": {
+ "picomatch": "^3 || ^4"
+ },
+ "peerDependenciesMeta": {
+ "picomatch": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/fflate": {
+ "version": "0.8.2",
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/file-entry-cache": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-8.0.0.tgz",
+ "integrity": "sha512-XXTUwCvisa5oacNGRP9SfNtYBNAMi+RPwBFmblZEF7N7swHYQS6/Zfk7SRwx4D5j3CH211YNRco1DEMNVfZCnQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flat-cache": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ }
+ },
+ "node_modules/find-up": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/find-up/-/find-up-7.0.0.tgz",
+ "integrity": "sha512-YyZM99iHrqLKjmt4LJDj58KI+fYyufRLBSYcqycxf//KpBk9FoewoGX0450m9nB44qrZnovzC2oeP5hUibxc/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "locate-path": "^7.2.0",
+ "path-exists": "^5.0.0",
+ "unicorn-magic": "^0.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/flat-cache": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-4.0.1.tgz",
+ "integrity": "sha512-f7ccFPK3SXFHpx15UIGyRJ/FJQctuKZ0zVuN3frBo4HnK3cay9VEW0R6yPYFHC0AgqhukPzKjq22t5DmAyqGyw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "flatted": "^3.2.9",
+ "keyv": "^4.5.4"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/flatted": {
+ "version": "3.4.2",
+ "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.4.2.tgz",
+ "integrity": "sha512-PjDse7RzhcPkIJwy5t7KPWQSZ9cAbzQXcafsetQoD7sOJRQlGikNbx7yZp2OotDnJyrDcbyRq3Ttb18iYOqkxA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/foreground-child": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "cross-spawn": "^7.0.6",
+ "signal-exit": "^4.0.1"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/form-data": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.5.tgz",
+ "integrity": "sha512-8RipRLol37bNs2bhoV67fiTEvdTrbMUYcFTiy3+wuuOnUog2QBHCZWXDRijWQfAkhBj2Uf5UnVaiWwA5vdd82w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "asynckit": "^0.4.0",
+ "combined-stream": "^1.0.8",
+ "es-set-tostringtag": "^2.1.0",
+ "hasown": "^2.0.2",
+ "mime-types": "^2.1.12"
+ },
+ "engines": {
+ "node": ">= 6"
+ }
+ },
+ "node_modules/form-data-encoder": {
+ "version": "1.7.2",
+ "resolved": "https://registry.npmjs.org/form-data-encoder/-/form-data-encoder-1.7.2.tgz",
+ "integrity": "sha512-qfqtYan3rxrnCk1VYaA4H+Ms9xdpPqvLZa6xmMgFvhO32x7/3J/ExcTd6qpxM0vH2GdMI+poehyBZvqfMTto8A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/formdata-node": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/formdata-node/-/formdata-node-4.4.1.tgz",
+ "integrity": "sha512-0iirZp3uVDjVGt9p49aTaqjk84TrglENEDuqfdlZQ1roC9CWlPk6Avf8EEnZNcAqPonwkG35x4n3ww/1THYAeQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "node-domexception": "1.0.0",
+ "web-streams-polyfill": "4.0.0-beta.3"
+ },
+ "engines": {
+ "node": ">= 12.20"
+ }
+ },
+ "node_modules/fsevents": {
+ "version": "2.3.3",
+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
+ "dev": true,
+ "hasInstallScript": true,
+ "license": "MIT",
+ "optional": true,
+ "os": [
+ "darwin"
+ ],
+ "engines": {
+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
+ }
+ },
+ "node_modules/function-bind": {
+ "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",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-caller-file": {
+ "version": "2.0.5",
+ "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+ "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "6.* || 8.* || >= 10.*"
+ }
+ },
+ "node_modules/get-east-asian-width": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/get-east-asian-width/-/get-east-asian-width-1.5.0.tgz",
+ "integrity": "sha512-CQ+bEO+Tva/qlmw24dCejulK5pMzVnUOFOijVogd3KQs07HnRIgp8TGipvCCRT06xeYEbpbgwaCxglFyiuIcmA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "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",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "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",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/get-tsconfig": {
+ "version": "4.13.8",
+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.8.tgz",
+ "integrity": "sha512-J87BxkLXykmisLQ+KA4x2+O6rVf+PJrtFUO8lGyiRg4lyxJLJ8/v0sRAKdVZQOy6tR6lMRAF1NqzCf9BQijm0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "resolve-pkg-maps": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
+ }
+ },
+ "node_modules/git-raw-commits": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/git-raw-commits/-/git-raw-commits-4.0.0.tgz",
+ "integrity": "sha512-ICsMM1Wk8xSGMowkOmPrzo2Fgmfo4bMHLNX6ytHjajRJUqvHOw/TFapQ+QG75c3X/tTDDhOSRPGC52dDbNM8FQ==",
+ "deprecated": "This package is no longer maintained. For the JavaScript API, please use @conventional-changelog/git-client instead.",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "dargs": "^8.0.0",
+ "meow": "^12.0.1",
+ "split2": "^4.0.0"
+ },
+ "bin": {
+ "git-raw-commits": "cli.mjs"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/glob": {
+ "version": "10.5.0",
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz",
+ "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==",
+ "deprecated": "Old versions of glob are not supported, and contain widely publicized security vulnerabilities, which have been fixed in the current version. Please update. Support for old versions may be purchased (at exorbitant rates) by contacting i@izs.me",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "foreground-child": "^3.1.0",
+ "jackspeak": "^3.1.2",
+ "minimatch": "^9.0.4",
+ "minipass": "^7.1.2",
+ "package-json-from-dist": "^1.0.0",
+ "path-scurry": "^1.11.1"
+ },
+ "bin": {
+ "glob": "dist/esm/bin.mjs"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/glob-parent": {
+ "version": "6.0.2",
+ "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz",
+ "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "is-glob": "^4.0.3"
+ },
+ "engines": {
+ "node": ">=10.13.0"
+ }
+ },
+ "node_modules/glob/node_modules/brace-expansion": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.1.0.tgz",
+ "integrity": "sha512-TN1kCZAgdgweJhWWpgKYrQaMNHcDULHkWwQIspdtjV4Y5aurRdZpjAqn6yX3FPqTA9ngHCc4hJxMAMgGfve85w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0"
+ }
+ },
+ "node_modules/glob/node_modules/minimatch": {
+ "version": "9.0.9",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.9.tgz",
+ "integrity": "sha512-OBwBN9AL4dqmETlpS2zasx+vTeWclWzkblfZk7KTA5j3jeOONz/tRCnZomUyvNg83wL5Zv9Ss6HMJXAgL8R2Yg==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^2.0.2"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/global-directory": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmjs.org/global-directory/-/global-directory-4.0.1.tgz",
+ "integrity": "sha512-wHTUcDUoZ1H5/0iVqEudYW4/kAlN5cZ3j/bXn0Dpbizl9iaUVeWSHqiOjsgk6OW2bkLclbBjzewBz6weQ1zA2Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ini": "4.1.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/globals": {
+ "version": "14.0.0",
+ "resolved": "https://registry.npmjs.org/globals/-/globals-14.0.0.tgz",
+ "integrity": "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-flag": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
+ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/has-symbols": {
+ "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",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-tostringtag": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.2.tgz",
+ "integrity": "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-symbols": "^1.0.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/highlight.js": {
+ "version": "10.7.3",
+ "resolved": "https://registry.npmjs.org/highlight.js/-/highlight.js-10.7.3.tgz",
+ "integrity": "sha512-tzcUFauisWKNHaRkN4Wjl/ZA07gENAjFl3J/c480dprkGTg5EQstgaNFqBfUqCq54kZRIEcreTsAgF/m2quD7A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/hookable": {
+ "version": "5.5.3",
+ "resolved": "https://registry.npmjs.org/hookable/-/hookable-5.5.3.tgz",
+ "integrity": "sha512-Yc+BQe8SvoXH1643Qez1zqLRmbA5rCL+sSmk6TVos0LWVfNIB7PGncdlId77WzLGSIB5KaWgTaNTs2lNVEI6VQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/html-escaper": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz",
+ "integrity": "sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/humanize-ms": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
+ "integrity": "sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.0.0"
+ }
+ },
+ "node_modules/husky": {
+ "version": "9.1.7",
+ "resolved": "https://registry.npmjs.org/husky/-/husky-9.1.7.tgz",
+ "integrity": "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "husky": "bin.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/typicode"
+ }
+ },
+ "node_modules/ignore": {
+ "version": "5.3.2",
+ "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
+ "integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 4"
+ }
+ },
+ "node_modules/import-fresh": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
+ "integrity": "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parent-module": "^1.0.0",
+ "resolve-from": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/import-fresh/node_modules/resolve-from": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz",
+ "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/import-meta-resolve": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-4.2.0.tgz",
+ "integrity": "sha512-Iqv2fzaTQN28s/FwZAoFq0ZSs/7hMAHJVX+w8PZl3cY19Pxk6jFFalxQoIfW2826i/fDLXv8IiEZRIT0lDuWcg==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "type": "github",
+ "url": "https://github.com/sponsors/wooorm"
+ }
+ },
+ "node_modules/imurmurhash": {
+ "version": "0.1.4",
+ "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz",
+ "integrity": "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.8.19"
+ }
+ },
+ "node_modules/ini": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.1.tgz",
+ "integrity": "sha512-QQnnxNyfvmHFIsj7gkPcYymR8Jdw/o7mp5ZFihxn6h8Ci6fh3Dx4E1gPjpQEpIuPo9XVNY/ZUwh4BPMjGyL01g==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-5.1.0.tgz",
+ "integrity": "sha512-5XHYaSyiqADb4RnZ1Bdad6cPp8Toise4TzEjcOYDHZkTCbKgiUl7WTUCpNWHuxmDt91wnsZBc9xinNzopv3JMQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "get-east-asian-width": "^1.3.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "is-extglob": "^2.1.1"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/is-obj": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-obj/-/is-obj-2.0.0.tgz",
+ "integrity": "sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/is-text-path": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-text-path/-/is-text-path-2.0.0.tgz",
+ "integrity": "sha512-+oDTluR6WEjdXEJMnC2z6A4FRwFoYuvShVVEGsS7ewc0UTi2QtAKMDJuL4BDEVt+5T7MjFo12RP8ghOM75oKJw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "text-extensions": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/istanbul-lib-coverage": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.2.2.tgz",
+ "integrity": "sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/istanbul-lib-report": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.1.tgz",
+ "integrity": "sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "istanbul-lib-coverage": "^3.0.0",
+ "make-dir": "^4.0.0",
+ "supports-color": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-lib-source-maps": {
+ "version": "5.0.6",
+ "resolved": "https://registry.npmjs.org/istanbul-lib-source-maps/-/istanbul-lib-source-maps-5.0.6.tgz",
+ "integrity": "sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "@jridgewell/trace-mapping": "^0.3.23",
+ "debug": "^4.1.1",
+ "istanbul-lib-coverage": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/istanbul-reports": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz",
+ "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "html-escaper": "^2.0.0",
+ "istanbul-lib-report": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/jackspeak": {
+ "version": "3.4.3",
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "@isaacs/cliui": "^8.0.2"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ },
+ "optionalDependencies": {
+ "@pkgjs/parseargs": "^0.11.0"
+ }
+ },
+ "node_modules/jiti": {
+ "version": "2.6.1",
+ "resolved": "https://registry.npmjs.org/jiti/-/jiti-2.6.1.tgz",
+ "integrity": "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jiti": "lib/jiti-cli.mjs"
+ }
+ },
+ "node_modules/js-tokens": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-10.0.0.tgz",
+ "integrity": "sha512-lM/UBzQmfJRo9ABXbPWemivdCW8V2G8FHaHdypQaIy523snUjog0W71ayWXTjiR+ixeMyVHN2XcpnTd/liPg/Q==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/js-yaml": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.1.tgz",
+ "integrity": "sha512-qQKT4zQxXl8lLwBtHMWwaTcGfFOZviOJet3Oy/xmGk2gZH677CJM9EvtfdSkgWcATZhj/55JZ0rmy3myCT5lsA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "argparse": "^2.0.1"
+ },
+ "bin": {
+ "js-yaml": "bin/js-yaml.js"
+ }
+ },
+ "node_modules/jsesc": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-3.1.0.tgz",
+ "integrity": "sha512-/sM3dO2FOzXjKQhJuo0Q173wf2KOo8t4I8vHy6lF9poUp7bKT0/NHE8fPX23PwfhnykfqnC2xRxOnVw5XuGIaA==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "jsesc": "bin/jsesc"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/json-buffer": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz",
+ "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-parse-even-better-errors": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
+ "integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/json-schema-to-ts": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/json-schema-to-ts/-/json-schema-to-ts-3.1.1.tgz",
+ "integrity": "sha512-+DWg8jCJG2TEnpy7kOm/7/AxaYoaRbjVB4LFZLySZlWn8exGs3A4OLJR966cVvU26N7X9TWxl+Jsw7dzAqKT6g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/runtime": "^7.18.3",
+ "ts-algebra": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "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==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "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",
+ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/jsonparse": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz",
+ "integrity": "sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==",
+ "dev": true,
+ "engines": [
+ "node >= 0.2.0"
+ ],
+ "license": "MIT"
+ },
+ "node_modules/JSONStream": {
+ "version": "1.3.5",
+ "resolved": "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz",
+ "integrity": "sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==",
+ "dev": true,
+ "license": "(MIT OR Apache-2.0)",
+ "dependencies": {
+ "jsonparse": "^1.2.0",
+ "through": ">=2.2.7 <3"
+ },
+ "bin": {
+ "JSONStream": "bin.js"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/keyv": {
+ "version": "4.5.4",
+ "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
+ "integrity": "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "json-buffer": "3.0.1"
+ }
+ },
+ "node_modules/levn": {
+ "version": "0.4.1",
+ "resolved": "https://registry.npmjs.org/levn/-/levn-0.4.1.tgz",
+ "integrity": "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1",
+ "type-check": "~0.4.0"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/lines-and-columns": {
+ "version": "1.2.4",
+ "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
+ "integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lint-staged": {
+ "version": "16.4.0",
+ "resolved": "https://registry.npmjs.org/lint-staged/-/lint-staged-16.4.0.tgz",
+ "integrity": "sha512-lBWt8hujh/Cjysw5GYVmZpFHXDCgZzhrOm8vbcUdobADZNOK/bRshr2kM3DfgrrtR1DQhfupW9gnIXOfiFi+bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "commander": "^14.0.3",
+ "listr2": "^9.0.5",
+ "picomatch": "^4.0.3",
+ "string-argv": "^0.3.2",
+ "tinyexec": "^1.0.4",
+ "yaml": "^2.8.2"
+ },
+ "bin": {
+ "lint-staged": "bin/lint-staged.js"
+ },
+ "engines": {
+ "node": ">=20.17"
+ },
+ "funding": {
+ "url": "https://opencollective.com/lint-staged"
+ }
+ },
+ "node_modules/lint-staged/node_modules/commander": {
+ "version": "14.0.3",
+ "resolved": "https://registry.npmjs.org/commander/-/commander-14.0.3.tgz",
+ "integrity": "sha512-H+y0Jo/T1RZ9qPP4Eh1pkcQcLRglraJaSLoyOtHxu6AapkjWVCy2Sit1QQ4x3Dng8qDlSsZEet7g5Pq06MvTgw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=20"
+ }
+ },
+ "node_modules/listr2": {
+ "version": "9.0.5",
+ "resolved": "https://registry.npmjs.org/listr2/-/listr2-9.0.5.tgz",
+ "integrity": "sha512-ME4Fb83LgEgwNw96RKNvKV4VTLuXfoKudAmm2lP8Kk87KaMK0/Xrx/aAkMWmT8mDb+3MlFDspfbCs7adjRxA2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cli-truncate": "^5.0.0",
+ "colorette": "^2.0.20",
+ "eventemitter3": "^5.0.1",
+ "log-update": "^6.1.0",
+ "rfdc": "^1.4.1",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ }
+ },
+ "node_modules/locate-path": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-7.2.0.tgz",
+ "integrity": "sha512-gvVijfZvn7R+2qyPX8mAuKcFGDf6Nc61GdvGafQsHL0sBIxfKzA+usWn4GFC/bk+QdwPUD4kWFJLhElipq+0VA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-locate": "^6.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/lodash.camelcase": {
+ "version": "4.3.0",
+ "resolved": "https://registry.npmjs.org/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz",
+ "integrity": "sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.isplainobject": {
+ "version": "4.0.6",
+ "resolved": "https://registry.npmjs.org/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz",
+ "integrity": "sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.kebabcase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz",
+ "integrity": "sha512-N8XRTIMMqqDgSy4VLKPnJ/+hpGZN+PHQiJnSenYqPaVV/NCqEogTnAdZLQiGKhxX+JCs8waWq2t1XHWKOmlY8g==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.merge": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz",
+ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.mergewith": {
+ "version": "4.6.2",
+ "resolved": "https://registry.npmjs.org/lodash.mergewith/-/lodash.mergewith-4.6.2.tgz",
+ "integrity": "sha512-GK3g5RPZWTRSeLSpgP8Xhra+pnjBC56q9FZYe1d5RN3TJ35dbkGy3YqBSMbyCrlbi+CM9Z3Jk5yTL7RCsqboyQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.snakecase": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz",
+ "integrity": "sha512-QZ1d4xoBHYUeuouhEq3lk3Uq7ldgyFXGBhg04+oRLnIz8o9T65Eh+8YdroUwn846zchkA9yDsDl5CVVaV2nqYw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.startcase": {
+ "version": "4.4.0",
+ "resolved": "https://registry.npmjs.org/lodash.startcase/-/lodash.startcase-4.4.0.tgz",
+ "integrity": "sha512-+WKqsK294HMSc2jEbNgpHpd0JfIBhp7rEV4aqXWqFr6AlXov+SlcgB1Fv01y2kGe3Gc8nMW7VA0SrGuSkRfIEg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.uniq": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz",
+ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lodash.upperfirst": {
+ "version": "4.3.1",
+ "resolved": "https://registry.npmjs.org/lodash.upperfirst/-/lodash.upperfirst-4.3.1.tgz",
+ "integrity": "sha512-sReKOYJIJf74dhJONhU4e0/shzi1trVbSWDOhKYE5XV2O+H7Sb2Dihwuc7xWxVl+DgFPyTqIN3zMfT9cq5iWDg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/log-update": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmjs.org/log-update/-/log-update-6.1.0.tgz",
+ "integrity": "sha512-9ie8ItPR6tjY5uYJh8K/Zrv/RMZ5VOlOWvtZdEHYSTFKZfIBPQa9tOAEeAWhd+AnIneLJ22w5fjOYtoutpWq5w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^7.0.0",
+ "cli-cursor": "^5.0.0",
+ "slice-ansi": "^7.1.0",
+ "strip-ansi": "^7.1.0",
+ "wrap-ansi": "^9.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/log-update/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/log-update/node_modules/slice-ansi": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-7.1.2.tgz",
+ "integrity": "sha512-iOBWFgUX7caIZiuutICxVgX1SdxwAVFFKwt1EvMYYec/NWO5meOJ6K5uQxhrYBdQJne4KxiqZc+KptFOWFSI9w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "is-fullwidth-code-point": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/loupe": {
+ "version": "3.2.1",
+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz",
+ "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/lru-cache": {
+ "version": "10.4.3",
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/magic-string": {
+ "version": "0.30.21",
+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz",
+ "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@jridgewell/sourcemap-codec": "^1.5.5"
+ }
+ },
+ "node_modules/magicast": {
+ "version": "0.3.5",
+ "resolved": "https://registry.npmjs.org/magicast/-/magicast-0.3.5.tgz",
+ "integrity": "sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/parser": "^7.25.4",
+ "@babel/types": "^7.25.4",
+ "source-map-js": "^1.2.0"
+ }
+ },
+ "node_modules/make-dir": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-4.0.0.tgz",
+ "integrity": "sha512-hXdUTZYIVOt1Ex//jAQi+wTZZpUpwBj/0QsOzqegb3rGMMeJiSEu5xLHnYfBrRV4RH2+OCSOO95Is/7x1WJ4bw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "semver": "^7.5.3"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/marked": {
+ "version": "9.1.6",
+ "resolved": "https://registry.npmjs.org/marked/-/marked-9.1.6.tgz",
+ "integrity": "sha512-jcByLnIFkd5gSXZmjNvS1TlmRhCXZjIzHYlaGkPlLIekG55JDR2Z4va9tZwCiP+/RDERiNhMOFu01xd6O5ct1Q==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "marked": "bin/marked.js"
+ },
+ "engines": {
+ "node": ">= 16"
+ }
+ },
+ "node_modules/marked-terminal": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/marked-terminal/-/marked-terminal-7.3.0.tgz",
+ "integrity": "sha512-t4rBvPsHc57uE/2nJOLmMbZCQ4tgAccAED3ngXQqW6g+TxA488JzJ+FK3lQkzBQOI1mRV/r/Kq+1ZlJ4D0owQw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-escapes": "^7.0.0",
+ "ansi-regex": "^6.1.0",
+ "chalk": "^5.4.1",
+ "cli-highlight": "^2.1.11",
+ "cli-table3": "^0.6.5",
+ "node-emoji": "^2.2.0",
+ "supports-hyperlinks": "^3.1.0"
+ },
+ "engines": {
+ "node": ">=16.0.0"
+ },
+ "peerDependencies": {
+ "marked": ">=1 <16"
+ }
+ },
+ "node_modules/marked-terminal/node_modules/chalk": {
+ "version": "5.6.2",
+ "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.2.tgz",
+ "integrity": "sha512-7NzBL0rN6fMUW+f7A6Io4h40qQlG+xGmtMxfbnH/K7TAtt8JQWVQK+6g0UXKMeVJoyV5EkkNsErQ8pVD3bLHbA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.17.0 || ^14.13 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/chalk?sponsor=1"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "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",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/meow": {
+ "version": "12.1.1",
+ "resolved": "https://registry.npmjs.org/meow/-/meow-12.1.1.tgz",
+ "integrity": "sha512-BhXM0Au22RwUneMPwSCnyhTOizdWoIEPU9sp0Aqa1PnDMR5Wv2FGXYDjuzJEIX+Eo2Rb8xuYe5jrnm5QowQFkw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=16.10"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.52.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz",
+ "integrity": "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "2.1.35",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.35.tgz",
+ "integrity": "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "1.52.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mimic-function": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/mimic-function/-/mimic-function-5.0.1.tgz",
+ "integrity": "sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.1.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.5.tgz",
+ "integrity": "sha512-VgjWUsnnT6n+NUk6eZq77zeFdpW2LWDzP6zFGrCbHXiYNul5Dzqk2HHQ5uFH2DNW5Xbp8+jVzaeNt94ssEEl4w==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/minipass": {
+ "version": "7.1.3",
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.3.tgz",
+ "integrity": "sha512-tEBHqDnIoM/1rXME1zgka9g6Q2lcoCkxHLuc7ODJ5BxbP5d4c2Z5cGgtXAku59200Cx7diuHTOYfSBD8n6mm8A==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=16 || 14 >=14.17"
+ }
+ },
+ "node_modules/mri": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz",
+ "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/ms": {
+ "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": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz",
+ "integrity": "sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0",
+ "object-assign": "^4.0.1",
+ "thenify-all": "^1.0.0"
+ }
+ },
+ "node_modules/nanoid": {
+ "version": "3.3.11",
+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "bin": {
+ "nanoid": "bin/nanoid.cjs"
+ },
+ "engines": {
+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
+ }
+ },
+ "node_modules/natural-compare": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz",
+ "integrity": "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/node-domexception": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
+ "deprecated": "Use your platform's native DOMException instead",
+ "dev": true,
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/jimmywarting"
+ },
+ {
+ "type": "github",
+ "url": "https://paypal.me/jimmywarting"
+ }
+ ],
+ "license": "MIT",
+ "engines": {
+ "node": ">=10.5.0"
+ }
+ },
+ "node_modules/node-emoji": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/node-emoji/-/node-emoji-2.2.0.tgz",
+ "integrity": "sha512-Z3lTE9pLaJF47NyMhd4ww1yFTAP8YhYI8SleJiHzM46Fgpm5cnNzSl9XfzFNqbaz+VlJrIj3fXQ4DeN1Rjm6cw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@sindresorhus/is": "^4.6.0",
+ "char-regex": "^1.0.2",
+ "emojilib": "^2.4.0",
+ "skin-tone": "^2.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/node-fetch": {
+ "version": "2.7.0",
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.7.0.tgz",
+ "integrity": "sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "whatwg-url": "^5.0.0"
+ },
+ "engines": {
+ "node": "4.x || >=6.0.0"
+ },
+ "peerDependencies": {
+ "encoding": "^0.1.0"
+ },
+ "peerDependenciesMeta": {
+ "encoding": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/object-assign": {
+ "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"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-7.0.0.tgz",
+ "integrity": "sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mimic-function": "^5.0.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/openai": {
+ "version": "4.104.0",
+ "resolved": "https://registry.npmjs.org/openai/-/openai-4.104.0.tgz",
+ "integrity": "sha512-p99EFNsA/yX6UhVO93f5kJsDRLAg+CTA2RBqdHK4RtK8u5IJw32Hyb2dTGKbnnFmnuoBv5r7Z2CURI9sGZpSuA==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "dependencies": {
+ "@types/node": "^18.11.18",
+ "@types/node-fetch": "^2.6.4",
+ "abort-controller": "^3.0.0",
+ "agentkeepalive": "^4.2.1",
+ "form-data-encoder": "1.7.2",
+ "formdata-node": "^4.3.2",
+ "node-fetch": "^2.6.7"
+ },
+ "bin": {
+ "openai": "bin/cli"
+ },
+ "peerDependencies": {
+ "ws": "^8.18.0",
+ "zod": "^3.23.8"
+ },
+ "peerDependenciesMeta": {
+ "ws": {
+ "optional": true
+ },
+ "zod": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/openai/node_modules/@types/node": {
+ "version": "18.19.130",
+ "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.130.tgz",
+ "integrity": "sha512-GRaXQx6jGfL8sKfaIDD6OupbIHBr9jv7Jnaml9tB7l4v068PAOXqfcujMMo5PhbIs6ggR1XODELqahT2R8v0fg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "undici-types": "~5.26.4"
+ }
+ },
+ "node_modules/openai/node_modules/undici-types": {
+ "version": "5.26.5",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+ "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/optionator": {
+ "version": "0.9.4",
+ "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz",
+ "integrity": "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "deep-is": "^0.1.3",
+ "fast-levenshtein": "^2.0.6",
+ "levn": "^0.4.1",
+ "prelude-ls": "^1.2.1",
+ "type-check": "^0.4.0",
+ "word-wrap": "^1.2.5"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/p-limit": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-4.0.0.tgz",
+ "integrity": "sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "yocto-queue": "^1.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/p-locate": {
+ "version": "6.0.0",
+ "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-6.0.0.tgz",
+ "integrity": "sha512-wPrq66Llhl7/4AGC6I+cqxT07LhXvWL08LNXz1fENOw0Ap4sRZZ/gZpTTJ5jpurzzzfS2W/Ge9BY3LgLjCShcw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "p-limit": "^4.0.0"
+ },
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/package-json-from-dist": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
+ "dev": true,
+ "license": "BlueOak-1.0.0"
+ },
+ "node_modules/package-manager-detector": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/package-manager-detector/-/package-manager-detector-1.6.0.tgz",
+ "integrity": "sha512-61A5ThoTiDG/C8s8UMZwSorAGwMJ0ERVGj2OjoW5pAalsNOg15+iQiPzrLJ4jhZ1HJzmC2PIHT2oEiH3R5fzNA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parent-module": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz",
+ "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "callsites": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/parse-json": {
+ "version": "5.2.0",
+ "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
+ "integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/code-frame": "^7.0.0",
+ "error-ex": "^1.3.1",
+ "json-parse-even-better-errors": "^2.3.0",
+ "lines-and-columns": "^1.1.6"
+ },
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-5.1.1.tgz",
+ "integrity": "sha512-ugq4DFI0Ptb+WWjAdOK16+u/nHfiIrcE+sh8kZMaM0WllQKLI9rOUq6c2b7cwPkXdzfQESqvoqK6ug7U/Yyzug==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-6.0.1.tgz",
+ "integrity": "sha512-qPuWvbLgvDGilKc5BoicRovlT4MtYT6JfJyBOMDsKoiT+GiuP5qyrPCnR9HcPECIJJmZh5jRndyNThnhhb/vlA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^6.0.1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter/node_modules/parse5": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz",
+ "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/path-exists": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-5.0.0.tgz",
+ "integrity": "sha512-RjhtfwJOxzcFmNOi6ltcbcu4Iu+FL3zEj83dk4kAS+fVpTxXLO1b38RvJgT/0QwvV/L3aY9TAnyv0EOqW4GoMQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
+ }
+ },
+ "node_modules/path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/path-scurry": {
+ "version": "1.11.1",
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "lru-cache": "^10.2.0",
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
+ },
+ "engines": {
+ "node": ">=16 || 14 >=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/pathe": {
+ "version": "2.0.3",
+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/pathval": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
+ "integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.16"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/picomatch": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
+ "integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/jonschlinkert"
+ }
+ },
+ "node_modules/postcss": {
+ "version": "8.5.9",
+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.9.tgz",
+ "integrity": "sha512-7a70Nsot+EMX9fFU3064K/kdHWZqGVY+BADLyXc8Dfv+mTLLVl6JzJpPaCZ2kQL9gIJvKXSLMHhqdRRjwQeFtw==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "opencollective",
+ "url": "https://opencollective.com/postcss/"
+ },
+ {
+ "type": "tidelift",
+ "url": "https://tidelift.com/funding/github/npm/postcss"
+ },
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/ai"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "nanoid": "^3.3.11",
+ "picocolors": "^1.1.1",
+ "source-map-js": "^1.2.1"
+ },
+ "engines": {
+ "node": "^10 || ^12 || >=14"
+ }
+ },
+ "node_modules/prelude-ls": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",
+ "integrity": "sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/prettier": {
+ "version": "3.8.2",
+ "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.8.2.tgz",
+ "integrity": "sha512-8c3mgTe0ASwWAJK+78dpviD+A8EqhndQPUBpNUIPt6+xWlIigCwfN01lWr9MAede4uqXGTEKeQWTvzb3vjia0Q==",
+ "dev": true,
+ "license": "MIT",
+ "bin": {
+ "prettier": "bin/prettier.cjs"
+ },
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/prettier/prettier?sponsor=1"
+ }
+ },
+ "node_modules/publint": {
+ "version": "0.3.18",
+ "resolved": "https://registry.npmjs.org/publint/-/publint-0.3.18.tgz",
+ "integrity": "sha512-JRJFeBTrfx4qLwEuGFPk+haJOJN97KnPuK01yj+4k/Wj5BgoOK5uNsivporiqBjk2JDaslg7qJOhGRnpltGeog==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@publint/pack": "^0.1.4",
+ "package-manager-detector": "^1.6.0",
+ "picocolors": "^1.1.1",
+ "sade": "^1.8.1"
+ },
+ "bin": {
+ "publint": "src/cli.js"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://bjornlu.com/sponsor"
+ }
+ },
+ "node_modules/punycode": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz",
+ "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/quansync": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/quansync/-/quansync-1.0.0.tgz",
+ "integrity": "sha512-5xZacEEufv3HSTPQuchrvV6soaiACMFnq1H8wkVioctoH3TRha9Sz66lOxRwPK/qZj7HPiSveih9yAyh98gvqA==",
+ "dev": true,
+ "funding": [
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/antfu"
+ },
+ {
+ "type": "individual",
+ "url": "https://github.com/sponsors/sxzz"
+ }
+ ],
+ "license": "MIT"
+ },
+ "node_modules/readdirp": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-4.1.2.tgz",
+ "integrity": "sha512-GDhwkLfywWL2s6vEjyhri+eXmfH6j1L7JE27WhqLeYzoh/A3DBaYGEj2H/HFZCn/kMfim73FXxEJTw06WtxQwg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14.18.0"
+ },
+ "funding": {
+ "type": "individual",
+ "url": "https://paulmillr.com/funding/"
+ }
+ },
+ "node_modules/require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "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==",
+ "dev": true,
+ "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",
+ "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/resolve-pkg-maps": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
+ "dev": true,
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "5.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-5.1.0.tgz",
+ "integrity": "sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^7.0.0",
+ "signal-exit": "^4.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/rfdc": {
+ "version": "1.4.1",
+ "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.4.1.tgz",
+ "integrity": "sha512-q1b3N5QkRUWUl7iyylaaj3kOpIT0N2i9MqIEQXP73GVsN9cw3fdx8X63cEmWhJGi2PPCF23Ijp7ktmd39rawIA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/rolldown": {
+ "version": "1.0.0-rc.15",
+ "resolved": "https://registry.npmjs.org/rolldown/-/rolldown-1.0.0-rc.15.tgz",
+ "integrity": "sha512-Ff31guA5zT6WjnGp0SXw76X6hzGRk/OQq2hE+1lcDe+lJdHSgnSX6nK3erbONHyCbpSj9a9E+uX/OvytZoWp2g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@oxc-project/types": "=0.124.0",
+ "@rolldown/pluginutils": "1.0.0-rc.15"
+ },
+ "bin": {
+ "rolldown": "bin/cli.mjs"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "optionalDependencies": {
+ "@rolldown/binding-android-arm64": "1.0.0-rc.15",
+ "@rolldown/binding-darwin-arm64": "1.0.0-rc.15",
+ "@rolldown/binding-darwin-x64": "1.0.0-rc.15",
+ "@rolldown/binding-freebsd-x64": "1.0.0-rc.15",
+ "@rolldown/binding-linux-arm-gnueabihf": "1.0.0-rc.15",
+ "@rolldown/binding-linux-arm64-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-arm64-musl": "1.0.0-rc.15",
+ "@rolldown/binding-linux-ppc64-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-s390x-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-x64-gnu": "1.0.0-rc.15",
+ "@rolldown/binding-linux-x64-musl": "1.0.0-rc.15",
+ "@rolldown/binding-openharmony-arm64": "1.0.0-rc.15",
+ "@rolldown/binding-wasm32-wasi": "1.0.0-rc.15",
+ "@rolldown/binding-win32-arm64-msvc": "1.0.0-rc.15",
+ "@rolldown/binding-win32-x64-msvc": "1.0.0-rc.15"
+ }
+ },
+ "node_modules/rolldown-plugin-dts": {
+ "version": "0.13.14",
+ "resolved": "https://registry.npmjs.org/rolldown-plugin-dts/-/rolldown-plugin-dts-0.13.14.tgz",
+ "integrity": "sha512-wjNhHZz9dlN6PTIXyizB6u/mAg1wEFMW9yw7imEVe3CxHSRnNHVyycIX0yDEOVJfDNISLPbkCIPEpFpizy5+PQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@babel/generator": "^7.28.0",
+ "@babel/parser": "^7.28.0",
+ "@babel/types": "^7.28.1",
+ "ast-kit": "^2.1.1",
+ "birpc": "^2.5.0",
+ "debug": "^4.4.1",
+ "dts-resolver": "^2.1.1",
+ "get-tsconfig": "^4.10.1"
+ },
+ "engines": {
+ "node": ">=20.18.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "@typescript/native-preview": ">=7.0.0-dev.20250601.1",
+ "rolldown": "^1.0.0-beta.9",
+ "typescript": "^5.0.0",
+ "vue-tsc": "^2.2.0 || ^3.0.0"
+ },
+ "peerDependenciesMeta": {
+ "@typescript/native-preview": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ },
+ "vue-tsc": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/rollup": {
+ "version": "4.60.1",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.60.1.tgz",
+ "integrity": "sha512-VmtB2rFU/GroZ4oL8+ZqXgSA38O6GR8KSIvWmEFv63pQ0G6KaBH9s07PO8XTXP4vI+3UJUEypOfjkGfmSBBR0w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/estree": "1.0.8"
+ },
+ "bin": {
+ "rollup": "dist/bin/rollup"
+ },
+ "engines": {
+ "node": ">=18.0.0",
+ "npm": ">=8.0.0"
+ },
+ "optionalDependencies": {
+ "@rollup/rollup-android-arm-eabi": "4.60.1",
+ "@rollup/rollup-android-arm64": "4.60.1",
+ "@rollup/rollup-darwin-arm64": "4.60.1",
+ "@rollup/rollup-darwin-x64": "4.60.1",
+ "@rollup/rollup-freebsd-arm64": "4.60.1",
+ "@rollup/rollup-freebsd-x64": "4.60.1",
+ "@rollup/rollup-linux-arm-gnueabihf": "4.60.1",
+ "@rollup/rollup-linux-arm-musleabihf": "4.60.1",
+ "@rollup/rollup-linux-arm64-gnu": "4.60.1",
+ "@rollup/rollup-linux-arm64-musl": "4.60.1",
+ "@rollup/rollup-linux-loong64-gnu": "4.60.1",
+ "@rollup/rollup-linux-loong64-musl": "4.60.1",
+ "@rollup/rollup-linux-ppc64-gnu": "4.60.1",
+ "@rollup/rollup-linux-ppc64-musl": "4.60.1",
+ "@rollup/rollup-linux-riscv64-gnu": "4.60.1",
+ "@rollup/rollup-linux-riscv64-musl": "4.60.1",
+ "@rollup/rollup-linux-s390x-gnu": "4.60.1",
+ "@rollup/rollup-linux-x64-gnu": "4.60.1",
+ "@rollup/rollup-linux-x64-musl": "4.60.1",
+ "@rollup/rollup-openbsd-x64": "4.60.1",
+ "@rollup/rollup-openharmony-arm64": "4.60.1",
+ "@rollup/rollup-win32-arm64-msvc": "4.60.1",
+ "@rollup/rollup-win32-ia32-msvc": "4.60.1",
+ "@rollup/rollup-win32-x64-gnu": "4.60.1",
+ "@rollup/rollup-win32-x64-msvc": "4.60.1",
+ "fsevents": "~2.3.2"
+ }
+ },
+ "node_modules/sade": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz",
+ "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "mri": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/semver": {
+ "version": "7.7.4",
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.4.tgz",
+ "integrity": "sha512-vFKC2IEtQnVhpT78h1Yp8wzwrf8CM+MzKMHGJZfBtzhZNycRFnXsHk6E5TxIkkMsgNS7mdX3AGB7x2QM2di4lA==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "semver": "bin/semver.js"
+ },
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "shebang-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/siginfo": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
+ "dev": true,
+ "license": "ISC"
+ },
+ "node_modules/signal-exit": {
+ "version": "4.1.0",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=14"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/skin-tone": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/skin-tone/-/skin-tone-2.0.0.tgz",
+ "integrity": "sha512-kUMbT1oBJCpgrnKoSr0o6wPtvRWT9W9UKvGLwfJYO2WuahZRHOpEyL1ckyMGgMWh0UdpmaoFqKKD29WTomNEGA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "unicode-emoji-modifier-base": "^1.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/slice-ansi": {
+ "version": "8.0.0",
+ "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-8.0.0.tgz",
+ "integrity": "sha512-stxByr12oeeOyY2BlviTNQlYV5xOj47GirPr4yA1hE9JCtxfQN0+tVbkxwCtYDQWhEKWFHsEK48ORg5jrouCAg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.3",
+ "is-fullwidth-code-point": "^5.1.0"
+ },
+ "engines": {
+ "node": ">=20"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/slice-ansi?sponsor=1"
+ }
+ },
+ "node_modules/slice-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/source-map-js": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
+ "dev": true,
+ "license": "BSD-3-Clause",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/split2": {
+ "version": "4.2.0",
+ "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
+ "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">= 10.x"
+ }
+ },
+ "node_modules/stackback": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/std-env": {
+ "version": "3.10.0",
+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz",
+ "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/string-argv": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/string-argv/-/string-argv-0.3.2.tgz",
+ "integrity": "sha512-aqD2Q0144Z+/RqG52NeHEkZauTAUWJO8c6yTftGJKO3Tja5tUgIfmIl6kExvhtxSDP7fXB6DvzkfMpCd/F3G+Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6.19"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs": {
+ "name": "string-width",
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^8.0.0",
+ "is-fullwidth-code-point": "^3.0.0",
+ "strip-ansi": "^6.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/is-fullwidth-code-point": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/string-width/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.2.0.tgz",
+ "integrity": "sha512-yDPMNjp4WyfYBkHnjIRLfca1i6KMyGCtsVgoKe/z1+6vukgaENdgGBZt+ZmKPc4gavvEZ5OgHfHdrazhgNyG7w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^6.2.2"
+ },
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
+ }
+ },
+ "node_modules/strip-ansi-cjs": {
+ "name": "strip-ansi",
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/strip-json-comments": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
+ "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/strip-literal": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz",
+ "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "js-tokens": "^9.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/strip-literal/node_modules/js-tokens": {
+ "version": "9.0.1",
+ "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
+ "integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/supports-color": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
+ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/supports-hyperlinks": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmjs.org/supports-hyperlinks/-/supports-hyperlinks-3.2.0.tgz",
+ "integrity": "sha512-zFObLMyZeEwzAoKCyu1B91U79K2t7ApXuQfo8OuxwXLDgcKxuwM+YvcbIhm6QWqz7mHUH1TVytR1PwVVjEuMig==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "has-flag": "^4.0.0",
+ "supports-color": "^7.0.0"
+ },
+ "engines": {
+ "node": ">=14.18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/supports-hyperlinks?sponsor=1"
+ }
+ },
+ "node_modules/test-exclude": {
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/test-exclude/-/test-exclude-7.0.2.tgz",
+ "integrity": "sha512-u9E6A+ZDYdp7a4WnarkXPZOx8Ilz46+kby6p1yZ8zsGTz9gYa6FIS7lj2oezzNKmtdyyJNNmmXDppga5GB7kSw==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "@istanbuljs/schema": "^0.1.2",
+ "glob": "^10.4.1",
+ "minimatch": "^10.2.2"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/test-exclude/node_modules/balanced-match": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-4.0.4.tgz",
+ "integrity": "sha512-BLrgEcRTwX2o6gGxGOCNyMvGSp35YofuYzw9h1IMTRmKqttAZZVU67bdb9Pr2vUHA8+j3i2tJfjO6C6+4myGTA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/test-exclude/node_modules/brace-expansion": {
+ "version": "5.0.5",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-5.0.5.tgz",
+ "integrity": "sha512-VZznLgtwhn+Mact9tfiwx64fA9erHH/MCXEUfB/0bX/6Fz6ny5EGTXYltMocqg4xFAQZtnO3DHWWXi8RiuN7cQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^4.0.2"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ }
+ },
+ "node_modules/test-exclude/node_modules/minimatch": {
+ "version": "10.2.5",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-10.2.5.tgz",
+ "integrity": "sha512-MULkVLfKGYDFYejP07QOurDLLQpcjk7Fw+7jXS2R2czRQzR56yHRveU5NDJEOviH+hETZKSkIk5c+T23GjFUMg==",
+ "dev": true,
+ "license": "BlueOak-1.0.0",
+ "dependencies": {
+ "brace-expansion": "^5.0.5"
+ },
+ "engines": {
+ "node": "18 || 20 || >=22"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/isaacs"
+ }
+ },
+ "node_modules/text-extensions": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/text-extensions/-/text-extensions-2.4.0.tgz",
+ "integrity": "sha512-te/NtwBwfiNRLf9Ijqx3T0nlqZiQ2XrrtBvu+cLL8ZRrGkO0NHTug8MYFKyoSrv/sHTaSKfilUkizV6XhxMJ3g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/thenify": {
+ "version": "3.3.1",
+ "resolved": "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz",
+ "integrity": "sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "any-promise": "^1.0.0"
+ }
+ },
+ "node_modules/thenify-all": {
+ "version": "1.6.0",
+ "resolved": "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz",
+ "integrity": "sha512-RNxQH/qI8/t3thXJDwcstUO4zeqo64+Uy/+sNVRBx4Xn2OX+OZ9oP+iJnNFqplFra2ZUVeKCSa2oVWi3T4uVmA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "thenify": ">= 3.1.0 < 4"
+ },
+ "engines": {
+ "node": ">=0.8"
+ }
+ },
+ "node_modules/through": {
+ "version": "2.3.8",
+ "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz",
+ "integrity": "sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinybench": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/tinyexec": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-1.1.1.tgz",
+ "integrity": "sha512-VKS/ZaQhhkKFMANmAOhhXVoIfBXblQxGX1myCQ2faQrfmobMftXeJPcZGp0gS07ocvGJWDLZGyOZDadDBqYIJg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/tinyglobby": {
+ "version": "0.2.16",
+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.16.tgz",
+ "integrity": "sha512-pn99VhoACYR8nFHhxqix+uvsbXineAasWm5ojXoN8xEwK5Kd3/TrhNn1wByuD52UxWRLy8pu+kRMniEi6Eq9Zg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.4"
+ },
+ "engines": {
+ "node": ">=12.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/SuperchupuDev"
+ }
+ },
+ "node_modules/tinypool": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
+ "integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": "^18.0.0 || >=20.0.0"
+ }
+ },
+ "node_modules/tinyrainbow": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tinyspy": {
+ "version": "4.0.4",
+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz",
+ "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=14.0.0"
+ }
+ },
+ "node_modules/tr46": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz",
+ "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ts-algebra": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/ts-algebra/-/ts-algebra-2.0.0.tgz",
+ "integrity": "sha512-FPAhNPFMrkwz76P7cdjdmiShwMynZYN6SgOujD1urY4oNm80Ou9oMdmbR45LotcKOXoy7wSmHkRFE6Mxbrhefw==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/ts-api-utils": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmjs.org/ts-api-utils/-/ts-api-utils-2.5.0.tgz",
+ "integrity": "sha512-OJ/ibxhPlqrMM0UiNHJ/0CKQkoKF243/AEmplt3qpRgkW8VG7IfOS41h7V8TjITqdByHzrjcS/2si+y4lIh8NA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18.12"
+ },
+ "peerDependencies": {
+ "typescript": ">=4.8.4"
+ }
+ },
+ "node_modules/tsdown": {
+ "version": "0.12.9",
+ "resolved": "https://registry.npmjs.org/tsdown/-/tsdown-0.12.9.tgz",
+ "integrity": "sha512-MfrXm9PIlT3saovtWKf/gCJJ/NQCdE0SiREkdNC+9Qy6UHhdeDPxnkFaBD7xttVUmgp0yUHtGirpoLB+OVLuLA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansis": "^4.1.0",
+ "cac": "^6.7.14",
+ "chokidar": "^4.0.3",
+ "debug": "^4.4.1",
+ "diff": "^8.0.2",
+ "empathic": "^2.0.0",
+ "hookable": "^5.5.3",
+ "rolldown": "^1.0.0-beta.19",
+ "rolldown-plugin-dts": "^0.13.12",
+ "semver": "^7.7.2",
+ "tinyexec": "^1.0.1",
+ "tinyglobby": "^0.2.14",
+ "unconfig": "^7.3.2"
+ },
+ "bin": {
+ "tsdown": "dist/run.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sxzz"
+ },
+ "peerDependencies": {
+ "@arethetypeswrong/core": "^0.18.1",
+ "publint": "^0.3.0",
+ "typescript": "^5.0.0",
+ "unplugin-lightningcss": "^0.4.0",
+ "unplugin-unused": "^0.5.0"
+ },
+ "peerDependenciesMeta": {
+ "@arethetypeswrong/core": {
+ "optional": true
+ },
+ "publint": {
+ "optional": true
+ },
+ "typescript": {
+ "optional": true
+ },
+ "unplugin-lightningcss": {
+ "optional": true
+ },
+ "unplugin-unused": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/tslib": {
+ "version": "2.8.1",
+ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.8.1.tgz",
+ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==",
+ "dev": true,
+ "license": "0BSD",
+ "optional": true
+ },
+ "node_modules/tsx": {
+ "version": "4.21.0",
+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz",
+ "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "~0.27.0",
+ "get-tsconfig": "^4.7.5"
+ },
+ "bin": {
+ "tsx": "dist/cli.mjs"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ }
+ },
+ "node_modules/type-check": {
+ "version": "0.4.0",
+ "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
+ "integrity": "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "prelude-ls": "^1.2.1"
+ },
+ "engines": {
+ "node": ">= 0.8.0"
+ }
+ },
+ "node_modules/typescript": {
+ "version": "5.9.3",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz",
+ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==",
+ "dev": true,
+ "license": "Apache-2.0",
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=14.17"
+ }
+ },
+ "node_modules/typescript-eslint": {
+ "version": "8.58.2",
+ "resolved": "https://registry.npmjs.org/typescript-eslint/-/typescript-eslint-8.58.2.tgz",
+ "integrity": "sha512-V8iSng9mRbdZjl54VJ9NKr6ZB+dW0J3TzRXRGcSbLIej9jV86ZRtlYeTKDR/QLxXykocJ5icNzbsl2+5TzIvcQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@typescript-eslint/eslint-plugin": "8.58.2",
+ "@typescript-eslint/parser": "8.58.2",
+ "@typescript-eslint/typescript-estree": "8.58.2",
+ "@typescript-eslint/utils": "8.58.2"
+ },
+ "engines": {
+ "node": "^18.18.0 || ^20.9.0 || >=21.1.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/typescript-eslint"
+ },
+ "peerDependencies": {
+ "eslint": "^8.57.0 || ^9.0.0 || ^10.0.0",
+ "typescript": ">=4.8.4 <6.1.0"
+ }
+ },
+ "node_modules/unconfig": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/unconfig/-/unconfig-7.5.0.tgz",
+ "integrity": "sha512-oi8Qy2JV4D3UQ0PsopR28CzdQ3S/5A1zwsUwp/rosSbfhJ5z7b90bIyTwi/F7hCLD4SGcZVjDzd4XoUQcEanvA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@quansync/fs": "^1.0.0",
+ "defu": "^6.1.4",
+ "jiti": "^2.6.1",
+ "quansync": "^1.0.0",
+ "unconfig-core": "7.5.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/unconfig-core": {
+ "version": "7.5.0",
+ "resolved": "https://registry.npmjs.org/unconfig-core/-/unconfig-core-7.5.0.tgz",
+ "integrity": "sha512-Su3FauozOGP44ZmKdHy2oE6LPjk51M/TRRjHv2HNCWiDvfvCoxC2lno6jevMA91MYAdCdwP05QnWdWpSbncX/w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@quansync/fs": "^1.0.0",
+ "quansync": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/antfu"
+ }
+ },
+ "node_modules/undici-types": {
+ "version": "6.21.0",
+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/unicode-emoji-modifier-base": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unicode-emoji-modifier-base/-/unicode-emoji-modifier-base-1.0.0.tgz",
+ "integrity": "sha512-yLSH4py7oFH3oG/9K+XWrz1pSi3dfUrWEnInbxMfArOfc1+33BlGPQtLsOYwvdMy11AwUBetYuaRxSPqgkq+8g==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/unicorn-magic": {
+ "version": "0.1.0",
+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
+ "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "dev": true,
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "node_modules/validate-npm-package-name": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/validate-npm-package-name/-/validate-npm-package-name-5.0.1.tgz",
+ "integrity": "sha512-OljLrQ9SQdOUqTaQxqL5dEfZWrXExyyWsozYlAWFawPVNuD83igl7uJD2RTkNMbniIYgt8l81eCJGIdQF7avLQ==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
+ }
+ },
+ "node_modules/vite": {
+ "version": "7.3.2",
+ "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.2.tgz",
+ "integrity": "sha512-Bby3NOsna2jsjfLVOHKes8sGwgl4TT0E6vvpYgnAYDIF/tie7MRaFthmKuHx1NSXjiTueXH3do80FMQgvEktRg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "esbuild": "^0.27.0",
+ "fdir": "^6.5.0",
+ "picomatch": "^4.0.3",
+ "postcss": "^8.5.6",
+ "rollup": "^4.43.0",
+ "tinyglobby": "^0.2.15"
+ },
+ "bin": {
+ "vite": "bin/vite.js"
+ },
+ "engines": {
+ "node": "^20.19.0 || >=22.12.0"
+ },
+ "funding": {
+ "url": "https://github.com/vitejs/vite?sponsor=1"
+ },
+ "optionalDependencies": {
+ "fsevents": "~2.3.3"
+ },
+ "peerDependencies": {
+ "@types/node": "^20.19.0 || >=22.12.0",
+ "jiti": ">=1.21.0",
+ "less": "^4.0.0",
+ "lightningcss": "^1.21.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
+ },
+ "jiti": {
+ "optional": true
+ },
+ "less": {
+ "optional": true
+ },
+ "lightningcss": {
+ "optional": true
+ },
+ "sass": {
+ "optional": true
+ },
+ "sass-embedded": {
+ "optional": true
+ },
+ "stylus": {
+ "optional": true
+ },
+ "sugarss": {
+ "optional": true
+ },
+ "terser": {
+ "optional": true
+ },
+ "tsx": {
+ "optional": true
+ },
+ "yaml": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vite-node": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
+ "integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cac": "^6.7.14",
+ "debug": "^4.4.1",
+ "es-module-lexer": "^1.7.0",
+ "pathe": "^2.0.3",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
+ },
+ "bin": {
+ "vite-node": "vite-node.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ }
+ },
+ "node_modules/vitest": {
+ "version": "3.2.4",
+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
+ "integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@types/chai": "^5.2.2",
+ "@vitest/expect": "3.2.4",
+ "@vitest/mocker": "3.2.4",
+ "@vitest/pretty-format": "^3.2.4",
+ "@vitest/runner": "3.2.4",
+ "@vitest/snapshot": "3.2.4",
+ "@vitest/spy": "3.2.4",
+ "@vitest/utils": "3.2.4",
+ "chai": "^5.2.0",
+ "debug": "^4.4.1",
+ "expect-type": "^1.2.1",
+ "magic-string": "^0.30.17",
+ "pathe": "^2.0.3",
+ "picomatch": "^4.0.2",
+ "std-env": "^3.9.0",
+ "tinybench": "^2.9.0",
+ "tinyexec": "^0.3.2",
+ "tinyglobby": "^0.2.14",
+ "tinypool": "^1.1.1",
+ "tinyrainbow": "^2.0.0",
+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
+ "vite-node": "3.2.4",
+ "why-is-node-running": "^2.3.0"
+ },
+ "bin": {
+ "vitest": "vitest.mjs"
+ },
+ "engines": {
+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
+ },
+ "funding": {
+ "url": "https://opencollective.com/vitest"
+ },
+ "peerDependencies": {
+ "@edge-runtime/vm": "*",
+ "@types/debug": "^4.1.12",
+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
+ "@vitest/browser": "3.2.4",
+ "@vitest/ui": "3.2.4",
+ "happy-dom": "*",
+ "jsdom": "*"
+ },
+ "peerDependenciesMeta": {
+ "@edge-runtime/vm": {
+ "optional": true
+ },
+ "@types/debug": {
+ "optional": true
+ },
+ "@types/node": {
+ "optional": true
+ },
+ "@vitest/browser": {
+ "optional": true
+ },
+ "@vitest/ui": {
+ "optional": true
+ },
+ "happy-dom": {
+ "optional": true
+ },
+ "jsdom": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/vitest/node_modules/tinyexec": {
+ "version": "0.3.2",
+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/web-streams-polyfill": {
+ "version": "4.0.0-beta.3",
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-4.0.0-beta.3.tgz",
+ "integrity": "sha512-QW95TCTaHmsYfHDybGMwO5IJIM93I/6vTRk+daHTWFPhwh+C8Cg7j7XyKrwrj8Ib6vYXe0ocYNrmzY4xAAN6ug==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/webidl-conversions": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz",
+ "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==",
+ "dev": true,
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/whatwg-url": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz",
+ "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "tr46": "~0.0.3",
+ "webidl-conversions": "^3.0.0"
+ }
+ },
+ "node_modules/which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "dev": true,
+ "license": "ISC",
+ "dependencies": {
+ "isexe": "^2.0.0"
+ },
+ "bin": {
+ "node-which": "bin/node-which"
+ },
+ "engines": {
+ "node": ">= 8"
+ }
+ },
+ "node_modules/why-is-node-running": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "siginfo": "^2.0.0",
+ "stackback": "0.0.2"
+ },
+ "bin": {
+ "why-is-node-running": "cli.js"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/word-wrap": {
+ "version": "1.2.5",
+ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.5.tgz",
+ "integrity": "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/wrap-ansi": {
+ "version": "9.0.2",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-9.0.2.tgz",
+ "integrity": "sha512-42AtmgqjV+X1VpdOfyTGOYRi0/zsoLqtXQckTmqTeybT+BDIbM/Guxo7x3pE2vtpr1ok6xRqM9OpBe+Jyoqyww==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^6.2.1",
+ "string-width": "^7.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs": {
+ "name": "wrap-ansi",
+ "version": "7.0.0",
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-styles": "^4.0.0",
+ "string-width": "^4.1.0",
+ "strip-ansi": "^6.0.0"
+ },
+ "engines": {
+ "node": ">=10"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^5.0.1"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/ansi-styles": {
+ "version": "6.2.3",
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz",
+ "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ },
+ "funding": {
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
+ }
+ },
+ "node_modules/wrap-ansi/node_modules/emoji-regex": {
+ "version": "10.6.0",
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.6.0.tgz",
+ "integrity": "sha512-toUI84YS5YmxW219erniWD0CIVOo46xGKColeNQRgOzDorgBi1v4D71/OFzgD9GO2UGKIv1C3Sp8DAn0+j5w7A==",
+ "dev": true,
+ "license": "MIT"
+ },
+ "node_modules/wrap-ansi/node_modules/string-width": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
+ "integrity": "sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "emoji-regex": "^10.3.0",
+ "get-east-asian-width": "^1.0.0",
+ "strip-ansi": "^7.1.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/y18n": {
+ "version": "5.0.8",
+ "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
+ "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=10"
+ }
+ },
+ "node_modules/yaml": {
+ "version": "2.8.3",
+ "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.3.tgz",
+ "integrity": "sha512-AvbaCLOO2Otw/lW5bmh9d/WEdcDFdQp2Z2ZUH3pX9U2ihyUY0nvLv7J6TrWowklRGPYbB/IuIMfYgxaCPg5Bpg==",
+ "dev": true,
+ "license": "ISC",
+ "bin": {
+ "yaml": "bin.mjs"
+ },
+ "engines": {
+ "node": ">= 14.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/eemeli"
+ }
+ },
+ "node_modules/yargs": {
+ "version": "17.7.2",
+ "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
+ "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cliui": "^8.0.1",
+ "escalade": "^3.1.1",
+ "get-caller-file": "^2.0.5",
+ "require-directory": "^2.1.1",
+ "string-width": "^4.2.3",
+ "y18n": "^5.0.5",
+ "yargs-parser": "^21.1.1"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yargs-parser": {
+ "version": "21.1.1",
+ "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
+ "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
+ "dev": true,
+ "license": "ISC",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/yocto-queue": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-1.2.2.tgz",
+ "integrity": "sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">=12.20"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
index 544bbfa..5ba4b46 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "@copilotkit/aimock",
- "version": "1.13.0",
+ "version": "1.14.0",
"description": "Mock infrastructure for AI application testing — LLM APIs, image generation, text-to-speech, transcription, video generation, MCP tools, A2A agents, AG-UI event streams, vector databases, search, rerank, and moderation. One package, one port, zero dependencies.",
"license": "MIT",
"keywords": [
diff --git a/skills/write-fixtures/SKILL.md b/skills/write-fixtures/SKILL.md
index 066643c..c61f722 100644
--- a/skills/write-fixtures/SKILL.md
+++ b/skills/write-fixtures/SKILL.md
@@ -51,12 +51,18 @@ Multi-part content (e.g., `[{type: "text", text: "hello"}]`) is automatically ex
### Tool Calls
```typescript
+// Preferred: object form (auto-stringified by the fixture loader)
+{
+ toolCalls: [{ name: "get_weather", arguments: { city: "SF" } }];
+}
+
+// Also accepted: JSON string form (backward compatible)
{
toolCalls: [{ name: "get_weather", arguments: '{"city":"SF"}' }];
}
```
-**`arguments` MUST be a JSON string**, not an object. This is the #1 mistake.
+**Both object and string forms are accepted** for `arguments`. The fixture loader auto-stringifies objects via `JSON.stringify()`. Object form is preferred for readability.
### Embedding
@@ -106,7 +112,7 @@ Use `match: { endpoint: "image" }` to prevent cross-matching with chat fixtures.
### Video
```typescript
-{ video: { url: "https://example.com/video.mp4", duration: 10 } }
+{ video: { id: "vid-1", status: "completed", url: "https://example.com/video.mp4" } }
```
Video uses async polling — `POST /v1/videos` creates, `GET /v1/videos/{id}` checks status.
@@ -148,7 +154,7 @@ The most common pattern. Fixture 1 triggers the tool call, fixture 2 handles the
```typescript
// Step 1: User asks about weather → LLM calls tool
mock.onMessage("weather", {
- toolCalls: [{ name: "get_weather", arguments: '{"city":"SF"}' }],
+ toolCalls: [{ name: "get_weather", arguments: { city: "SF" } }],
});
// Step 2: Tool result comes back → LLM responds with text
@@ -198,7 +204,7 @@ mock.addFixture({
// First call returns tool call, second returns text
mock.on(
{ userMessage: "status", sequenceIndex: 0 },
- { toolCalls: [{ name: "check_status", arguments: "{}" }] },
+ { toolCalls: [{ name: "check_status", arguments: {} }] },
);
mock.on({ userMessage: "status", sequenceIndex: 1 }, { content: "All systems operational." });
```
@@ -233,7 +239,7 @@ mock.addFixture({
return typeof sys === "string" && sys.includes("Flights found: false");
},
},
- response: { toolCalls: [{ name: "search_flights", arguments: "{}" }] },
+ response: { toolCalls: [{ name: "search_flights", arguments: {} }] },
});
```
@@ -307,6 +313,17 @@ mock.nextRequestError(429, { message: "Rate limited", type: "rate_limit_error" }
"match": { "userMessage": "hello" },
"response": { "content": "Hi!" }
},
+ {
+ "match": { "userMessage": "weather" },
+ "response": {
+ "toolCalls": [
+ {
+ "name": "get_weather",
+ "arguments": { "city": "SF", "units": "fahrenheit" }
+ }
+ ]
+ }
+ },
{
"match": { "inputText": "search query" },
"response": { "embedding": [0.1, 0.2, 0.3] }
@@ -319,6 +336,8 @@ mock.nextRequestError(429, { message: "Rate limited", type: "rate_limit_error" }
}
```
+**JSON auto-stringify**: In JSON fixture files, `arguments` and `content` can be objects — the loader auto-stringifies them with `JSON.stringify()`. The escaped-string form (`"{\"city\":\"SF\"}"`) still works but objects are preferred for readability.
+
JSON files cannot use `RegExp` or `predicate` — those are code-only features. `streamingProfile` is supported in JSON fixture files.
Load with `mock.loadFixtureFile("./fixtures/greetings.json")` or `mock.loadFixtureDir("./fixtures/")`.
@@ -360,11 +379,64 @@ All providers share the same fixture pool — write fixtures once, they work for
| `POST /v1/videos` | OpenAI | HTTP |
| `GET /v1/videos/{id}` | OpenAI | HTTP |
+## Response Template Overrides
+
+Fixture responses can include optional override fields to control auto-generated envelope values. These are merged into the provider-specific response format (OpenAI, Claude, Gemini, Responses API).
+
+| Field | Type | Default | Description |
+| ------------------- | ------ | ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `id` | string | auto-generated | Override response ID (e.g., `chatcmpl-custom`) |
+| `created` | number | `Date.now()/1000` | Override Unix timestamp |
+| `model` | string | echoes request | Override model name in response |
+| `usage` | object | zeroed | Override token counts: `{ prompt_tokens, completion_tokens, total_tokens }`. OpenAI Chat includes usage in response body; Responses API uses `response.usage`. When omitted, auto-computed from content length |
+| `finishReason` | string | `"stop"` / `"tool_calls"` | Override finish reason. Mappings: `stop` -> `end_turn` (Claude), `STOP` (Gemini); `tool_calls` -> `tool_use` (Claude), `FUNCTION_CALL` (Gemini); `length` -> `max_tokens` (Claude), `MAX_TOKENS` (Gemini); `content_filter` -> `SAFETY` (Gemini), `failed` (Responses API) |
+| `role` | string | `"assistant"` | Override message role |
+| `systemFingerprint` | string | (omitted) | Add `system_fingerprint` to response |
+
+### Example
+
+```typescript
+mock.onMessage("hello", {
+ content: "Hi!",
+ model: "gpt-4-turbo-2024-04-09",
+ usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 },
+ systemFingerprint: "fp_abc123",
+});
+```
+
+### In JSON fixtures
+
+```json
+{
+ "match": { "userMessage": "hello" },
+ "response": {
+ "content": "Hi!",
+ "model": "gpt-4-turbo-2024-04-09",
+ "usage": { "prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15 },
+ "systemFingerprint": "fp_abc123"
+ }
+}
+```
+
+These fields map correctly across all provider formats — for example, `finishReason: "stop"` becomes `finish_reason: "stop"` in OpenAI, `stop_reason: "end_turn"` in Claude, and `finishReason: "STOP"` in Gemini.
+
+## Provider Support Matrix
+
+| Feature | OpenAI Chat | OpenAI Responses | Claude | Gemini | Bedrock | Azure | Ollama | Cohere |
+| -------------------- | ----------- | ---------------- | ------ | ------ | ------- | ----- | ------ | ------ |
+| Text | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Tool Calls | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Content + Tool Calls | Yes | Yes | Yes | Yes | Yes | Yes | Yes | Yes |
+| Streaming | SSE | SSE | SSE | SSE | Binary | SSE | NDJSON | SSE |
+| Reasoning | Yes | Yes | Yes | Yes | Yes | Yes | -- | -- |
+| Web Searches | -- | Yes | -- | -- | -- | -- | -- | -- |
+| Response Overrides | Yes | Yes | Yes | Yes | -- | Yes | -- | -- |
+
## Critical Gotchas
1. **Order matters** — first match wins. Specific fixtures before general ones. Use `prependFixture()` to force priority.
-2. **`arguments` must be a JSON string** — `"arguments": "{\"key\":\"value\"}"` not `"arguments": {"key":"value"}`. The type system enforces this but JSON fixtures can get it wrong silently.
+2. **`arguments` accepts both objects and strings** — `"arguments": {"key":"value"}` (preferred, auto-stringified) or `"arguments": "{\"key\":\"value\"}"` (legacy). The same applies to `content` fields that contain JSON. The fixture loader detects `typeof === "object"` and calls `JSON.stringify()` automatically.
3. **Latency is per-chunk, not total** — `latency: 100` means 100ms between each SSE chunk, not 100ms total response time. Similarly, `truncateAfterChunks` and `disconnectAfterMs` are for simulating stream interruptions (added in v1.3.0).
@@ -611,7 +683,7 @@ const mock = await LLMock.create({ port: 0 }); // creates + starts in one call
| `onModerate(pattern, result)` | Match moderation requests by input |
| `onImage(pattern, response)` | Match image generation by prompt |
| `onSpeech(pattern, response)` | Match TTS by input text |
-| `onTranscription(match, response)` | Match audio transcription |
+| `onTranscription(response)` | Match audio transcription |
| `onVideo(pattern, response)` | Match video generation by prompt |
| `mount(path, handler)` | Mount a Mountable (VectorMock, etc.) |
| `url` / `baseUrl` | Server URL (throws if not started) |
diff --git a/src/__tests__/content-with-toolcalls.test.ts b/src/__tests__/content-with-toolcalls.test.ts
index 54dc897..b134d6b 100644
--- a/src/__tests__/content-with-toolcalls.test.ts
+++ b/src/__tests__/content-with-toolcalls.test.ts
@@ -27,14 +27,15 @@ describe("isContentWithToolCallsResponse", () => {
expect(isContentWithToolCallsResponse(r)).toBe(false);
});
- it("existing guards still work for combined response", () => {
+ it("existing guards are mutually exclusive with combined response", () => {
const r = {
content: "Hello",
toolCalls: [{ name: "get_weather", arguments: "{}" }],
};
- // Both existing guards would match — that's why we check combined first
- expect(isTextResponse(r)).toBe(true);
- expect(isToolCallResponse(r)).toBe(true);
+ // Guards are mutually exclusive — combined response only matches isContentWithToolCallsResponse
+ expect(isTextResponse(r)).toBe(false);
+ expect(isToolCallResponse(r)).toBe(false);
+ expect(isContentWithToolCallsResponse(r)).toBe(true);
});
});
@@ -426,6 +427,139 @@ describe("Gemini — content + toolCalls", () => {
});
});
+describe("Gemini — multi-tool-call CWTC", () => {
+ let mock: LLMock | null = null;
+
+ afterEach(async () => {
+ if (mock) {
+ await mock.stop();
+ mock = null;
+ }
+ });
+
+ it("Gemini non-streaming multi-tool-call CWTC", async () => {
+ mock = new LLMock({ port: 0 });
+ mock.addFixture({
+ match: { userMessage: "test gemini multi-tc" },
+ response: {
+ content: "Sure, let me check.",
+ toolCalls: [
+ { name: "get_weather", arguments: '{"city":"NYC"}' },
+ { name: "get_time", arguments: '{"tz":"EST"}' },
+ ],
+ },
+ });
+ await mock.start();
+
+ const res = await fetch(`${mock.url}/v1beta/models/gemini-2.0-flash:generateContent`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ body: JSON.stringify({
+ contents: [{ role: "user", parts: [{ text: "test gemini multi-tc" }] }],
+ }),
+ });
+
+ const body = await res.json();
+ const parts = body.candidates[0].content.parts;
+ const fcParts = parts.filter((p: { functionCall?: unknown }) => p.functionCall !== undefined);
+ expect(fcParts).toHaveLength(2);
+ expect(fcParts[0].functionCall.name).toBe("get_weather");
+ expect(fcParts[1].functionCall.name).toBe("get_time");
+ });
+});
+
+describe("Anthropic — multi-tool-call CWTC streaming", () => {
+ let mock: LLMock | null = null;
+
+ afterEach(async () => {
+ if (mock) {
+ await mock.stop();
+ mock = null;
+ }
+ });
+
+ it("Claude streaming multi-tool-call CWTC", async () => {
+ mock = new LLMock({ port: 0 });
+ mock.addFixture({
+ match: { userMessage: "test claude multi-tc" },
+ response: {
+ content: "Checking.",
+ toolCalls: [
+ { name: "get_weather", arguments: '{"city":"NYC"}' },
+ { name: "get_time", arguments: '{"tz":"EST"}' },
+ ],
+ },
+ });
+ await mock.start();
+
+ const res = await fetch(`${mock.url}/v1/messages`, {
+ method: "POST",
+ headers: {
+ "Content-Type": "application/json",
+ "x-api-key": "test-key",
+ "anthropic-version": "2023-06-01",
+ },
+ body: JSON.stringify({
+ model: "claude-sonnet-4-20250514",
+ max_tokens: 1024,
+ messages: [{ role: "user", content: "test claude multi-tc" }],
+ stream: true,
+ }),
+ });
+
+ const events = parseAnthropicSSEEvents(await res.text());
+ const toolBlockStarts = events.filter(
+ (e) =>
+ e.type === "content_block_start" &&
+ (e.content_block as { type: string })?.type === "tool_use",
+ );
+ expect(toolBlockStarts).toHaveLength(2);
+ });
+});
+
+describe("OpenAI — multi-tool-call CWTC streaming indices", () => {
+ let mock: LLMock | null = null;
+
+ afterEach(async () => {
+ if (mock) {
+ await mock.stop();
+ mock = null;
+ }
+ });
+
+ it("streams content then multiple tool calls with correct indices", async () => {
+ mock = new LLMock({ port: 0 });
+ mock.addFixture({
+ match: { userMessage: "test multi-tc indices" },
+ response: {
+ content: "Here.",
+ toolCalls: [
+ { name: "fn_a", arguments: '{"a":1}' },
+ { name: "fn_b", arguments: '{"b":2}' },
+ ],
+ },
+ });
+ await mock.start();
+
+ const res = await fetch(`${mock.url}/v1/chat/completions`, {
+ method: "POST",
+ headers: { "Content-Type": "application/json", Authorization: "Bearer test" },
+ body: JSON.stringify({
+ model: "gpt-4o",
+ messages: [{ role: "user", content: "test multi-tc indices" }],
+ stream: true,
+ }),
+ });
+
+ const chunks = parseSSEChunks(await res.text());
+ const toolChunks = chunks.filter((c) => c.choices?.[0]?.delta?.tool_calls);
+ const indices = toolChunks.map((c) => c.choices[0].delta.tool_calls![0].index);
+ // Should have both index 0 and index 1
+ expect(indices).toContain(0);
+ expect(indices).toContain(1);
+ });
+});
+
import {
collapseOpenAISSE,
collapseAnthropicSSE,
diff --git a/src/__tests__/fixture-loader.test.ts b/src/__tests__/fixture-loader.test.ts
index 35cfd6b..ee82303 100644
--- a/src/__tests__/fixture-loader.test.ts
+++ b/src/__tests__/fixture-loader.test.ts
@@ -2,7 +2,13 @@ import { describe, it, expect, vi, beforeEach, afterEach } from "vitest";
import { mkdirSync, mkdtempSync, rmSync, writeFileSync } from "node:fs";
import { tmpdir } from "node:os";
import { join } from "node:path";
-import { loadFixtureFile, loadFixturesFromDir } from "../fixture-loader.js";
+import { entryToFixture, loadFixtureFile, loadFixturesFromDir } from "../fixture-loader.js";
+import type {
+ FixtureFileEntry,
+ ToolCallResponse,
+ TextResponse,
+ ContentWithToolCallsResponse,
+} from "../types.js";
/* ------------------------------------------------------------------ *
* vi.mock for node:fs — defaults to the real implementation so that *
@@ -944,4 +950,507 @@ describe("validateFixtures", () => {
),
).toBe(true);
});
+
+ // --- ResponseOverrides validation ---
+
+ it("error: created as a string", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", created: "2024-01-01" as never } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "created"')),
+ ).toBe(true);
+ });
+
+ it("error: usage as a string", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", usage: "bad" as never } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "usage"')),
+ ).toBe(true);
+ });
+
+ it("error: usage with non-numeric field", () => {
+ const fixtures = [
+ makeFixture({
+ response: { content: "hi", usage: { prompt_tokens: "ten" as never } },
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some(
+ (r) => r.severity === "error" && r.message.includes('override "usage.prompt_tokens"'),
+ ),
+ ).toBe(true);
+ });
+
+ it("error: finishReason as a number", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", finishReason: 42 as never } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "finishReason"')),
+ ).toBe(true);
+ });
+
+ it("rejects non-string id", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", id: 123 as never } })];
+ const results = validateFixtures(fixtures);
+ expect(results.some((r) => r.severity === "error" && r.message.includes('override "id"'))).toBe(
+ true,
+ );
+ });
+
+ it("rejects non-string model", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", model: true as never } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "model"')),
+ ).toBe(true);
+ });
+
+ it("rejects non-string role", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", role: 42 as never } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "role"')),
+ ).toBe(true);
+ });
+
+ it("rejects non-string systemFingerprint", () => {
+ const fixtures = [
+ makeFixture({ response: { content: "hi", systemFingerprint: null as never } }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some(
+ (r) => r.severity === "error" && r.message.includes('override "systemFingerprint"'),
+ ),
+ ).toBe(true);
+ });
+
+ it("rejects negative created", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", created: -1 } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "created"')),
+ ).toBe(true);
+ });
+
+ it("rejects usage as array", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", usage: [1, 2, 3] as never } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "usage"')),
+ ).toBe(true);
+ });
+
+ it("rejects usage as null", () => {
+ const fixtures = [makeFixture({ response: { content: "hi", usage: null as never } })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes('override "usage"')),
+ ).toBe(true);
+ });
+
+ it("warns about unknown fields on response", () => {
+ // A response with only a typo field like "finishreason" (no content/toolCalls/error)
+ // is not recognized as any valid type
+ const fixtures = [makeFixture({ response: { finishreason: "stop" } as never })];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes("not a recognized type")),
+ ).toBe(true);
+ });
+
+ it("warns about unknown fields on ContentWithToolCallsResponse", () => {
+ // A CWTC with an extra typo field still validates the known parts
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "hi",
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ finishreason: "stop",
+ } as never,
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ // No error — the CWTC is valid; extra fields are silently ignored
+ const errors = results.filter((r) => r.severity === "error");
+ expect(errors).toHaveLength(0);
+ });
+
+ it("warns on empty content in ContentWithToolCallsResponse", () => {
+ // CWTC with empty content triggers the TextResponse empty-content error
+ // since isTextResponse also matches
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "",
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ },
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(results.some((r) => r.severity === "error" && r.message.includes("empty"))).toBe(true);
+ });
+
+ it("rejects empty toolCalls in ContentWithToolCallsResponse", () => {
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "hi",
+ toolCalls: [],
+ },
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(results.some((r) => r.message.includes("empty"))).toBe(true);
+ });
+
+ it("rejects missing tool name in ContentWithToolCallsResponse", () => {
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "hi",
+ toolCalls: [{ name: "", arguments: "{}" }],
+ },
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(results.some((r) => r.severity === "error" && r.message.includes("name is empty"))).toBe(
+ true,
+ );
+ });
+
+ it("rejects invalid JSON arguments in ContentWithToolCallsResponse", () => {
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "hi",
+ toolCalls: [{ name: "fn", arguments: "not json" }],
+ },
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some((r) => r.severity === "error" && r.message.includes("not valid JSON")),
+ ).toBe(true);
+ });
+
+ it("rejects non-string reasoning in ContentWithToolCallsResponse", () => {
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "hi",
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ reasoning: 123,
+ } as never,
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some(
+ (r) => r.severity === "error" && r.message.includes("reasoning must be a string"),
+ ),
+ ).toBe(true);
+ });
+
+ it("rejects non-array webSearches in ContentWithToolCallsResponse", () => {
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "hi",
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ webSearches: "not-array",
+ } as never,
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(
+ results.some(
+ (r) => r.severity === "error" && r.message.includes("webSearches must be an array"),
+ ),
+ ).toBe(true);
+ });
+
+ it("warns about unknown usage fields", () => {
+ // Usage with a typo field — all fields are validated as numbers, and promt_tokens
+ // is treated as a number field (just an unfamiliar name, still accepted if numeric)
+ const fixtures = [
+ makeFixture({
+ response: { content: "hi", usage: { promt_tokens: 10 } as never },
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ // No error — unknown numeric fields in usage are silently accepted
+ const usageErrors = results.filter(
+ (r) => r.severity === "error" && r.message.includes("promt_tokens"),
+ );
+ expect(usageErrors).toHaveLength(0);
+ });
+
+ it("rejects non-string id on ToolCallResponse", () => {
+ const fixtures = [
+ makeFixture({
+ response: {
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ id: 123,
+ } as never,
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ expect(results.some((r) => r.severity === "error" && r.message.includes('override "id"'))).toBe(
+ true,
+ );
+ });
+
+ it("warns about unknown fields on ToolCallResponse", () => {
+ // ToolCallResponse with extra typo field — silently ignored since toolCalls is valid
+ const fixtures = [
+ makeFixture({
+ response: {
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ finishreason: "tool_calls",
+ } as never,
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ // No error — the ToolCallResponse is valid; extra fields are silently ignored
+ const errors = results.filter((r) => r.severity === "error");
+ expect(errors).toHaveLength(0);
+ });
+
+ it("accepts valid overrides without errors", () => {
+ const fixtures = [
+ makeFixture({
+ response: {
+ content: "hi",
+ id: "chatcmpl-123",
+ created: 1700000000,
+ model: "gpt-4",
+ finishReason: "stop",
+ role: "assistant",
+ systemFingerprint: "fp_abc",
+ usage: { prompt_tokens: 10, completion_tokens: 20, total_tokens: 30 },
+ },
+ }),
+ ];
+ const results = validateFixtures(fixtures);
+ // No override-related errors
+ const overrideErrors = results.filter(
+ (r) => r.severity === "error" && r.message.includes("override"),
+ );
+ expect(overrideErrors).toHaveLength(0);
+ });
+});
+
+/* ------------------------------------------------------------------ *
+ * Auto-stringify: object arguments / content in fixture files *
+ * ------------------------------------------------------------------ */
+
+describe("auto-stringify JSON objects in fixture entries", () => {
+ it("stringifies object arguments in toolCalls", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: { city: "SF", temp: 72 } }],
+ },
+ };
+ const fixture = entryToFixture(entry);
+ const tc = (fixture.response as ToolCallResponse).toolCalls[0];
+ expect(tc.arguments).toBe('{"city":"SF","temp":72}');
+ });
+
+ it("leaves string arguments unchanged (backward compat)", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: '{"city":"SF"}' }],
+ },
+ };
+ const fixture = entryToFixture(entry);
+ const tc = (fixture.response as ToolCallResponse).toolCalls[0];
+ expect(tc.arguments).toBe('{"city":"SF"}');
+ });
+
+ it("stringifies object content (structured output)", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ content: { result: "success", score: 42 },
+ },
+ };
+ const fixture = entryToFixture(entry);
+ expect((fixture.response as TextResponse).content).toBe('{"result":"success","score":42}');
+ });
+
+ it("leaves string content unchanged", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: { content: "Hello, world!" },
+ };
+ const fixture = entryToFixture(entry);
+ expect((fixture.response as TextResponse).content).toBe("Hello, world!");
+ });
+
+ it("stringifies nested objects in arguments", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ toolCalls: [
+ {
+ name: "complex_call",
+ arguments: { outer: { inner: [1, 2, 3] }, flag: true },
+ },
+ ],
+ },
+ };
+ const fixture = entryToFixture(entry);
+ const tc = (fixture.response as ToolCallResponse).toolCalls[0];
+ expect(tc.arguments).toBe('{"outer":{"inner":[1,2,3]},"flag":true}');
+ });
+
+ it("handles content + toolCalls response with both object fields", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ content: { summary: "done" },
+ toolCalls: [{ name: "save", arguments: { id: 1 } }],
+ },
+ };
+ const fixture = entryToFixture(entry);
+ const resp = fixture.response as ContentWithToolCallsResponse;
+ expect(resp.content).toBe('{"summary":"done"}');
+ expect(resp.toolCalls[0].arguments).toBe('{"id":1}');
+ });
+
+ it("preserves ResponseOverrides fields through normalization", () => {
+ const entry = {
+ match: { userMessage: "test" },
+ response: {
+ content: { key: "value" },
+ id: "custom-id",
+ model: "custom-model",
+ created: 1234567890,
+ finishReason: "stop",
+ role: "assistant",
+ systemFingerprint: "fp-123",
+ usage: { prompt_tokens: 10 },
+ },
+ };
+ const fixture = entryToFixture(entry as unknown as FixtureFileEntry);
+ const r = fixture.response as Record;
+ expect(r.content).toBe('{"key":"value"}'); // stringified
+ expect(r.id).toBe("custom-id");
+ expect(r.model).toBe("custom-model");
+ expect(r.created).toBe(1234567890);
+ expect(r.finishReason).toBe("stop");
+ expect(r.role).toBe("assistant");
+ expect(r.systemFingerprint).toBe("fp-123");
+ expect(r.usage).toEqual({ prompt_tokens: 10 });
+ });
+
+ it("stringifies array content", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: { content: [1, 2, 3] as never },
+ };
+ const fixture = entryToFixture(entry);
+ expect((fixture.response as TextResponse).content).toBe("[1,2,3]");
+ });
+
+ it("passes null content through unchanged", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: { content: null as never },
+ };
+ const fixture = entryToFixture(entry);
+ expect((fixture.response as TextResponse).content).toBeNull();
+ });
+
+ it("stringifies array arguments in toolCalls", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ toolCalls: [{ name: "fn", arguments: [1, 2] as never }],
+ },
+ };
+ const fixture = entryToFixture(entry);
+ const tc = (fixture.response as ToolCallResponse).toolCalls[0];
+ expect(tc.arguments).toBe("[1,2]");
+ });
+
+ it("null arguments pass through unchanged", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ toolCalls: [{ name: "fn", arguments: null as never }],
+ },
+ };
+ const fixture = entryToFixture(entry);
+ const tc = (fixture.response as ToolCallResponse).toolCalls[0];
+ expect(tc.arguments).toBeNull();
+ });
+
+ it("mixed string/object arguments", () => {
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ toolCalls: [
+ { name: "fn1", arguments: '{"a":1}' },
+ { name: "fn2", arguments: { b: 2 } },
+ ],
+ },
+ };
+ const fixture = entryToFixture(entry);
+ const tcs = (fixture.response as ToolCallResponse).toolCalls;
+ expect(tcs[0].arguments).toBe('{"a":1}');
+ expect(tcs[1].arguments).toBe('{"b":2}');
+ });
+
+ it("does not mutate the original entry object", () => {
+ const args = { city: "SF" };
+ const entry: FixtureFileEntry = {
+ match: { userMessage: "test" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: args }],
+ },
+ };
+ entryToFixture(entry);
+ // Original object should be untouched
+ expect(typeof args).toBe("object");
+ expect(args.city).toBe("SF");
+ });
+
+ it("end-to-end: JSON round-trip through serialize + parse + entryToFixture", () => {
+ // Simulate the full JSON file round-trip: author writes JSON with object
+ // arguments, it gets serialized to disk, parsed back, and loaded.
+ const fixtureData = {
+ fixtures: [
+ {
+ match: { userMessage: "weather" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: { city: "SF", temp: 72 } }],
+ },
+ },
+ {
+ match: { userMessage: "structured" },
+ response: {
+ content: { answer: 42, nested: { key: "val" } },
+ },
+ },
+ ],
+ };
+ // Serialize -> parse (same as writing JSON to disk and reading it back)
+ const parsed = JSON.parse(JSON.stringify(fixtureData)) as { fixtures: FixtureFileEntry[] };
+ const fixtures = parsed.fixtures.map(entryToFixture);
+
+ expect(fixtures).toHaveLength(2);
+
+ const tc = (fixtures[0].response as ToolCallResponse).toolCalls[0];
+ expect(tc.arguments).toBe('{"city":"SF","temp":72}');
+
+ expect((fixtures[1].response as TextResponse).content).toBe(
+ '{"answer":42,"nested":{"key":"val"}}',
+ );
+ });
});
diff --git a/src/__tests__/llmock.test.ts b/src/__tests__/llmock.test.ts
index 1f14188..37a7132 100644
--- a/src/__tests__/llmock.test.ts
+++ b/src/__tests__/llmock.test.ts
@@ -223,6 +223,21 @@ describe("LLMock", () => {
expect(res.data).toContain("on response");
});
+ it("on() shorthand passes id and model overrides", async () => {
+ mock = new LLMock();
+ mock.on(
+ { userMessage: "override-test" },
+ { content: "overridden", id: "custom-id-123", model: "custom-model-456" },
+ );
+
+ await mock.start();
+ const res = await post(mock.url, chatBody("override-test", false));
+ expect(res.status).toBe(200);
+ const json = JSON.parse(res.data);
+ expect(json.id).toBe("custom-id-123");
+ expect(json.model).toBe("custom-model-456");
+ });
+
it("on() shorthand passes latency and chunkSize opts", async () => {
mock = new LLMock();
mock.on({ userMessage: "opts-test" }, { content: "response" }, { latency: 0, chunkSize: 5 });
@@ -586,6 +601,67 @@ describe("LLMock", () => {
});
});
+ describe("programmatic API auto-stringification", () => {
+ it("on() auto-stringifies object arguments in toolCalls", async () => {
+ mock = new LLMock();
+ mock.on(
+ { userMessage: "weather" },
+ {
+ toolCalls: [{ name: "get_weather", arguments: { city: "SF" } }],
+ },
+ );
+ await mock.start();
+
+ const res = await post(mock.url, {
+ model: "gpt-4",
+ messages: [{ role: "user", content: "weather" }],
+ stream: false,
+ });
+
+ expect(res.status).toBe(200);
+ const json = JSON.parse(res.data);
+ const args = json.choices[0].message.tool_calls[0].function.arguments;
+ expect(typeof args).toBe("string");
+ expect(JSON.parse(args)).toEqual({ city: "SF" });
+ });
+
+ it("onMessage() auto-stringifies object content", async () => {
+ mock = new LLMock();
+ mock.onMessage("structured", { content: { answer: 42, nested: { key: "val" } } });
+ await mock.start();
+
+ const res = await post(mock.url, chatBody("structured", false));
+
+ expect(res.status).toBe(200);
+ const json = JSON.parse(res.data);
+ const content = json.choices[0].message.content;
+ expect(typeof content).toBe("string");
+ expect(JSON.parse(content)).toEqual({ answer: 42, nested: { key: "val" } });
+ });
+
+ it("on() preserves string arguments without double-stringifying", async () => {
+ mock = new LLMock();
+ mock.on(
+ { userMessage: "already-string" },
+ {
+ toolCalls: [{ name: "fn", arguments: JSON.stringify({ key: "val" }) }],
+ },
+ );
+ await mock.start();
+
+ const res = await post(mock.url, {
+ model: "gpt-4",
+ messages: [{ role: "user", content: "already-string" }],
+ stream: false,
+ });
+
+ expect(res.status).toBe(200);
+ const json = JSON.parse(res.data);
+ const args = json.choices[0].message.tool_calls[0].function.arguments;
+ expect(JSON.parse(args)).toEqual({ key: "val" });
+ });
+ });
+
describe("onJsonOutput convenience", () => {
it("registers a fixture with responseFormat json_object and stringified content", () => {
mock = new LLMock();
diff --git a/src/__tests__/response-overrides.test.ts b/src/__tests__/response-overrides.test.ts
new file mode 100644
index 0000000..8e59aee
--- /dev/null
+++ b/src/__tests__/response-overrides.test.ts
@@ -0,0 +1,1377 @@
+import { describe, it, expect, afterEach } from "vitest";
+import http from "node:http";
+import { createServer, type ServerInstance } from "../server.js";
+import type {
+ Fixture,
+ SSEChunk,
+ TextResponse,
+ ToolCallResponse,
+ ContentWithToolCallsResponse,
+} from "../types.js";
+
+// ---------------------------------------------------------------------------
+// Helpers
+// ---------------------------------------------------------------------------
+
+function parseSSEResponse(body: string): SSEChunk[] {
+ return body
+ .split("\n\n")
+ .filter((line) => line.startsWith("data: ") && !line.includes("[DONE]"))
+ .map((line) => JSON.parse(line.slice(6)));
+}
+
+function parseClaudeSSE(body: string): object[] {
+ return body
+ .split("\n\n")
+ .filter((line) => line.includes("data: "))
+ .map((line) => {
+ const dataLine = line.split("\n").find((l) => l.startsWith("data: "));
+ return JSON.parse(dataLine!.slice(6));
+ });
+}
+
+function parseGeminiSSE(body: string): object[] {
+ return body
+ .split("\n\n")
+ .filter((line) => line.startsWith("data: "))
+ .map((line) => JSON.parse(line.slice(6)));
+}
+
+function parseResponsesSSE(body: string): object[] {
+ return body
+ .split("\n\n")
+ .filter((line) => line.includes("data: "))
+ .map((line) => {
+ const dataLine = line.split("\n").find((l) => l.startsWith("data: "));
+ return JSON.parse(dataLine!.slice(6));
+ });
+}
+
+async function httpPost(url: string, body: object): Promise<{ status: number; body: string }> {
+ return new Promise((resolve, reject) => {
+ const req = http.request(
+ url,
+ {
+ method: "POST",
+ headers: { "Content-Type": "application/json" },
+ },
+ (res) => {
+ const chunks: Buffer[] = [];
+ res.on("data", (c) => chunks.push(c));
+ res.on("end", () =>
+ resolve({ status: res.statusCode!, body: Buffer.concat(chunks).toString() }),
+ );
+ },
+ );
+ req.on("error", reject);
+ req.write(JSON.stringify(body));
+ req.end();
+ });
+}
+
+// ---------------------------------------------------------------------------
+// Tests
+// ---------------------------------------------------------------------------
+
+let instance: ServerInstance | null = null;
+
+afterEach(async () => {
+ if (instance) {
+ await new Promise((resolve) => instance!.server.close(() => resolve()));
+ instance = null;
+ }
+});
+
+describe("response overrides: OpenAI Chat Completions (non-streaming)", () => {
+ it("applies id override", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", id: "chatcmpl-test123" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.id).toBe("chatcmpl-test123");
+ });
+
+ it("applies created override", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", created: 1700000000 },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.created).toBe(1700000000);
+ });
+
+ it("applies model override", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", model: "gpt-4o-2024-08-06" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.model).toBe("gpt-4o-2024-08-06");
+ });
+
+ it("applies usage override", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.prompt_tokens).toBe(10);
+ expect(json.usage.completion_tokens).toBe(5);
+ expect(json.usage.total_tokens).toBe(15);
+ });
+
+ it("applies finishReason override", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "length" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.choices[0].finish_reason).toBe("length");
+ });
+
+ it("applies role override", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", role: "system" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.choices[0].message.role).toBe("system");
+ });
+
+ it("applies systemFingerprint override", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", systemFingerprint: "fp_abc123" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.system_fingerprint).toBe("fp_abc123");
+ });
+
+ it("partial usage merge — only prompt_tokens set", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", usage: { prompt_tokens: 42 } },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.prompt_tokens).toBe(42);
+ expect(json.usage.completion_tokens).toBe(0);
+ expect(json.usage.total_tokens).toBe(42);
+ });
+
+ it("default behavior unchanged when no overrides specified", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.id).toMatch(/^chatcmpl-/);
+ expect(json.model).toBe("gpt-4");
+ expect(json.choices[0].message.role).toBe("assistant");
+ expect(json.choices[0].finish_reason).toBe("stop");
+ expect(json.usage.prompt_tokens).toBe(0);
+ expect(json.system_fingerprint).toBeUndefined();
+ });
+});
+
+describe("response overrides: OpenAI Chat Completions (streaming)", () => {
+ it("overrides id/created/model on every chunk", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ id: "chatcmpl-stream-test",
+ created: 1700000000,
+ model: "gpt-4o-override",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: true,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const chunks = parseSSEResponse(res.body);
+ expect(chunks.length).toBeGreaterThan(0);
+ for (const chunk of chunks) {
+ expect(chunk.id).toBe("chatcmpl-stream-test");
+ expect(chunk.created).toBe(1700000000);
+ expect(chunk.model).toBe("gpt-4o-override");
+ }
+ });
+
+ it("overrides finishReason on final chunk only", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "length" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: true,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const chunks = parseSSEResponse(res.body);
+ const lastChunk = chunks[chunks.length - 1];
+ expect(lastChunk.choices[0].finish_reason).toBe("length");
+ });
+
+ it("overrides role on role chunk", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", role: "system" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: true,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const chunks = parseSSEResponse(res.body);
+ const roleChunk = chunks.find((c) => c.choices[0]?.delta?.role !== undefined);
+ expect(roleChunk?.choices[0].delta.role).toBe("system");
+ });
+
+ it("adds systemFingerprint to every chunk", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", systemFingerprint: "fp_stream" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: true,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const chunks = parseSSEResponse(res.body);
+ for (const chunk of chunks) {
+ expect((chunk as Record).system_fingerprint).toBe("fp_stream");
+ }
+ });
+});
+
+describe("response overrides: tool call", () => {
+ it("applies role override on tool-call-only response", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "weather" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: '{"city":"NYC"}' }],
+ role: "system",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "weather" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.choices[0].message.role).toBe("system");
+ });
+
+ it("applies finishReason on tool call response", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "weather" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: '{"city":"NYC"}' }],
+ finishReason: "stop",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "weather" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.choices[0].finish_reason).toBe("stop");
+ });
+});
+
+describe("response overrides: content+toolCalls", () => {
+ it("applies all overrides on combined response", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "search" },
+ response: {
+ content: "Let me search",
+ toolCalls: [{ name: "search", arguments: '{"q":"test"}' }],
+ id: "chatcmpl-combo",
+ model: "gpt-4o-combo",
+ usage: { prompt_tokens: 20, completion_tokens: 10, total_tokens: 30 },
+ systemFingerprint: "fp_combo",
+ role: "system",
+ finishReason: "stop",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "search" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.id).toBe("chatcmpl-combo");
+ expect(json.model).toBe("gpt-4o-combo");
+ expect(json.usage.prompt_tokens).toBe(20);
+ expect(json.system_fingerprint).toBe("fp_combo");
+ expect(json.choices[0].message.role).toBe("system");
+ expect(json.choices[0].finish_reason).toBe("stop");
+ });
+});
+
+describe("response overrides: Claude format", () => {
+ it("maps id to message id", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", id: "msg_test123" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.id).toBe("msg_test123");
+ });
+
+ it("maps finishReason 'stop' to stop_reason 'end_turn'", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "stop" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.stop_reason).toBe("end_turn");
+ });
+
+ it("maps usage input_tokens/output_tokens", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { input_tokens: 15, output_tokens: 8 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.input_tokens).toBe(15);
+ expect(json.usage.output_tokens).toBe(8);
+ });
+
+ it("maps overrides in streaming mode", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ id: "msg_stream_test",
+ model: "claude-override",
+ finishReason: "tool_calls",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: true,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const events = parseClaudeSSE(res.body);
+ const msgStart = events.find((e: Record) => e.type === "message_start") as
+ | Record
+ | undefined;
+ const msg = msgStart?.message as Record;
+ expect(msg.id).toBe("msg_stream_test");
+ expect(msg.model).toBe("claude-override");
+
+ const msgDelta = events.find((e: Record) => e.type === "message_delta") as
+ | Record
+ | undefined;
+ const delta = msgDelta?.delta as Record;
+ expect(delta.stop_reason).toBe("tool_use");
+ });
+});
+
+describe("response overrides: Gemini format", () => {
+ it("maps finishReason 'stop' to 'STOP'", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "stop" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.candidates[0].finishReason).toBe("STOP");
+ });
+
+ it("maps usage to usageMetadata", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { promptTokenCount: 10, candidatesTokenCount: 5, totalTokenCount: 15 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usageMetadata.promptTokenCount).toBe(10);
+ expect(json.usageMetadata.candidatesTokenCount).toBe(5);
+ expect(json.usageMetadata.totalTokenCount).toBe(15);
+ });
+
+ it("id/model/created are ignored in Gemini format", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ id: "should-be-ignored",
+ model: "should-be-ignored",
+ created: 1700000000,
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ });
+ const json = JSON.parse(res.body);
+ // Gemini format does not have id, model, or created at top level
+ expect(json.id).toBeUndefined();
+ expect(json.model).toBeUndefined();
+ expect(json.created).toBeUndefined();
+ });
+
+ it("auto-computes totalTokenCount in streaming mode when omitted", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { promptTokenCount: 10, candidatesTokenCount: 20 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(
+ `${instance.url}/v1beta/models/gemini-pro:streamGenerateContent?alt=sse`,
+ {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ },
+ );
+ const chunks = parseGeminiSSE(res.body) as Array>;
+ // Find the last chunk that has usageMetadata
+ const chunksWithUsage = chunks.filter((c) => c.usageMetadata !== undefined);
+ expect(chunksWithUsage.length).toBeGreaterThan(0);
+ const lastWithUsage = chunksWithUsage[chunksWithUsage.length - 1];
+ const usage = lastWithUsage.usageMetadata as Record;
+ expect(usage.totalTokenCount).toBe(30);
+ });
+
+ it("maps finishReason in streaming mode", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "tool_calls" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(
+ `${instance.url}/v1beta/models/gemini-pro:streamGenerateContent?alt=sse`,
+ {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ },
+ );
+ const chunks = parseGeminiSSE(res.body) as Array>;
+ const lastChunk = chunks[chunks.length - 1];
+ const candidates = lastChunk.candidates as Array>;
+ expect(candidates[0].finishReason).toBe("FUNCTION_CALL");
+ });
+});
+
+describe("response overrides: Responses API", () => {
+ it("applies id/created_at/model in envelope", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ id: "resp_test123",
+ created: 1700000000,
+ model: "gpt-4o-responses",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.id).toBe("resp_test123");
+ expect(json.created_at).toBe(1700000000);
+ expect(json.model).toBe("gpt-4o-responses");
+ });
+
+ it("maps finishReason 'stop' to status 'completed'", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "stop" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.status).toBe("completed");
+ });
+
+ it("maps finishReason 'length' to status 'incomplete'", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "length" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.status).toBe("incomplete");
+ });
+
+ it("maps usage in Responses API format", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { input_tokens: 12, output_tokens: 6, total_tokens: 18 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.input_tokens).toBe(12);
+ expect(json.usage.output_tokens).toBe(6);
+ expect(json.usage.total_tokens).toBe(18);
+ });
+
+ it("applies overrides in streaming mode", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ id: "resp_stream",
+ created: 1700000000,
+ model: "gpt-4o-stream-resp",
+ finishReason: "length",
+ usage: { input_tokens: 5, output_tokens: 3, total_tokens: 8 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: true,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const events = parseResponsesSSE(res.body) as Array>;
+
+ const created = events.find((e) => e.type === "response.created") as Record;
+ const createdResp = created.response as Record;
+ expect(createdResp.id).toBe("resp_stream");
+ expect(createdResp.created_at).toBe(1700000000);
+ expect(createdResp.model).toBe("gpt-4o-stream-resp");
+
+ const completed = events.find((e) => e.type === "response.completed") as Record<
+ string,
+ unknown
+ >;
+ const completedResp = completed.response as Record;
+ expect(completedResp.status).toBe("incomplete");
+ const usage = completedResp.usage as Record;
+ expect(usage.input_tokens).toBe(5);
+ expect(usage.output_tokens).toBe(3);
+ expect(usage.total_tokens).toBe(8);
+ });
+});
+
+describe("response overrides: cross-provider tool call coverage", () => {
+ it("Gemini tool call finishReason maps to FUNCTION_CALL", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "weather" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: '{"city":"NYC"}' }],
+ finishReason: "tool_calls",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-2.0-flash:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "weather" }] }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.candidates[0].finishReason).toBe("FUNCTION_CALL");
+ });
+
+ it("Claude tool call finishReason maps to tool_use", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "weather" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: '{"city":"NYC"}' }],
+ finishReason: "tool_calls",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "weather" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.stop_reason).toBe("tool_use");
+ });
+
+ it("Responses API tool call with id and finishReason overrides", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "weather" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: '{"city":"NYC"}' }],
+ id: "resp_custom_tc",
+ finishReason: "stop",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4o",
+ input: [{ role: "user", content: "weather" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.id).toBe("resp_custom_tc");
+ expect(json.status).toBe("completed");
+ });
+});
+
+describe("response overrides: finishReason cross-provider mappings", () => {
+ it("finishReason length maps to max_tokens on Claude", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "length" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.stop_reason).toBe("max_tokens");
+ });
+
+ it("finishReason length maps to MAX_TOKENS on Gemini", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "length" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.candidates[0].finishReason).toBe("MAX_TOKENS");
+ });
+
+ it("content_filter passthrough on OpenAI", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "content_filter" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.choices[0].finish_reason).toBe("content_filter");
+ });
+
+ it("unknown finishReason passthrough", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "custom_reason" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.choices[0].finish_reason).toBe("custom_reason");
+ });
+
+ it("content_filter maps to SAFETY on Gemini", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "content_filter" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.candidates[0].finishReason).toBe("SAFETY");
+ });
+
+ it("content_filter maps to failed on Responses API", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "content_filter" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.status).toBe("failed");
+ });
+
+ it("content_filter passthrough on Claude", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "content_filter" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.stop_reason).toBe("content_filter");
+ });
+});
+
+describe("response overrides: total_tokens auto-sum", () => {
+ it("total_tokens auto-sum with both prompt and completion tokens", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { prompt_tokens: 10, completion_tokens: 20 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.prompt_tokens).toBe(10);
+ expect(json.usage.completion_tokens).toBe(20);
+ // total_tokens is auto-computed from prompt_tokens + completion_tokens when omitted
+ expect(json.usage.total_tokens).toBe(30);
+ });
+
+ it("Responses API total_tokens auto-sum", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { input_tokens: 10, output_tokens: 20 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.input_tokens).toBe(10);
+ expect(json.usage.output_tokens).toBe(20);
+ expect(json.usage.total_tokens).toBe(30);
+ });
+
+ it("Gemini totalTokenCount auto-sum", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { promptTokenCount: 10, candidatesTokenCount: 20 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usageMetadata.promptTokenCount).toBe(10);
+ expect(json.usageMetadata.candidatesTokenCount).toBe(20);
+ expect(json.usageMetadata.totalTokenCount).toBe(30);
+ });
+});
+
+describe("response overrides: partial usage merge for non-OpenAI", () => {
+ it("partial usage merge for Claude", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { input_tokens: 42 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.input_tokens).toBe(42);
+ expect(json.usage.output_tokens).toBe(0);
+ });
+
+ it("partial usage merge for Gemini", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { promptTokenCount: 42 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "hello" }] }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usageMetadata.promptTokenCount).toBe(42);
+ expect(json.usageMetadata.candidatesTokenCount).toBe(0);
+ expect(json.usageMetadata.totalTokenCount).toBe(42);
+ });
+
+ it("partial usage merge for Responses API", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ usage: { input_tokens: 42 },
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "hello" }],
+ });
+ const json = JSON.parse(res.body);
+ expect(json.usage.input_tokens).toBe(42);
+ expect(json.usage.output_tokens).toBe(0);
+ expect(json.usage.total_tokens).toBe(42);
+ });
+});
+
+describe("response overrides: streaming CWTC overrides", () => {
+ it("streaming Claude CWTC overrides", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "search" },
+ response: {
+ content: "Let me search",
+ toolCalls: [{ name: "search", arguments: '{"q":"test"}' }],
+ id: "msg_cwtc_test",
+ model: "claude-override",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: true,
+ messages: [{ role: "user", content: "search" }],
+ });
+ const events = parseClaudeSSE(res.body);
+ const msgStart = events.find((e: Record) => e.type === "message_start") as
+ | Record
+ | undefined;
+ const msg = msgStart?.message as Record;
+ expect(msg.id).toBe("msg_cwtc_test");
+ expect(msg.model).toBe("claude-override");
+ });
+
+ it("streaming Gemini CWTC finishReason", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "search" },
+ response: {
+ content: "Let me search",
+ toolCalls: [{ name: "search", arguments: '{"q":"test"}' }],
+ finishReason: "tool_calls",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(
+ `${instance.url}/v1beta/models/gemini-pro:streamGenerateContent?alt=sse`,
+ {
+ contents: [{ role: "user", parts: [{ text: "search" }] }],
+ },
+ );
+ const chunks = parseGeminiSSE(res.body) as Array>;
+ const lastChunk = chunks[chunks.length - 1];
+ const candidates = lastChunk.candidates as Array>;
+ expect(candidates[0].finishReason).toBe("FUNCTION_CALL");
+ });
+
+ it("streaming Responses API CWTC overrides", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "search" },
+ response: {
+ content: "Let me search",
+ toolCalls: [{ name: "search", arguments: '{"q":"test"}' }],
+ id: "resp_cwtc_test",
+ model: "gpt-4o-cwtc",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: true,
+ input: [{ role: "user", content: "search" }],
+ });
+ const events = parseResponsesSSE(res.body) as Array>;
+ const completed = events.find((e) => e.type === "response.completed") as Record<
+ string,
+ unknown
+ >;
+ const completedResp = completed.response as Record;
+ expect(completedResp.id).toBe("resp_cwtc_test");
+ expect(completedResp.model).toBe("gpt-4o-cwtc");
+ });
+
+ it("finishReason length in Claude streaming", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "hello" },
+ response: { content: "Hi!", finishReason: "length" },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: true,
+ messages: [{ role: "user", content: "hello" }],
+ });
+ const events = parseClaudeSSE(res.body);
+ const msgDelta = events.find((e: Record) => e.type === "message_delta") as
+ | Record
+ | undefined;
+ const delta = msgDelta?.delta as Record;
+ expect(delta.stop_reason).toBe("max_tokens");
+ });
+});
+
+describe("response overrides: reasoning in CWTC", () => {
+ it("reasoning in CWTC streaming OpenAI", async () => {
+ // OpenAI CWTC streaming does not currently include reasoning_content chunks;
+ // reasoning is only supported for text-only streaming in OpenAI format.
+ // Verify that the content and tool call chunks still appear correctly.
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "think" },
+ response: {
+ content: "The answer is 42",
+ toolCalls: [{ name: "calc", arguments: '{"x":42}' }],
+ reasoning: "Let me think about this...",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: true,
+ messages: [{ role: "user", content: "think" }],
+ });
+ const chunks = parseSSEResponse(res.body);
+ const contentChunks = chunks.filter((c) => c.choices?.[0]?.delta?.content);
+ const toolChunks = chunks.filter((c) => c.choices?.[0]?.delta?.tool_calls);
+ expect(contentChunks.length).toBeGreaterThan(0);
+ expect(toolChunks.length).toBeGreaterThan(0);
+ });
+
+ it("reasoning in CWTC for Claude non-streaming", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "think" },
+ response: {
+ content: "The answer is 42",
+ toolCalls: [{ name: "calc", arguments: '{"x":42}' }],
+ reasoning: "Let me think about this...",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/messages`, {
+ model: "claude-3-opus-20240229",
+ max_tokens: 100,
+ stream: false,
+ messages: [{ role: "user", content: "think" }],
+ });
+ const json = JSON.parse(res.body);
+ const thinkingBlock = json.content.find((b: Record) => b.type === "thinking");
+ expect(thinkingBlock).toBeDefined();
+ expect(thinkingBlock.thinking).toBe("Let me think about this...");
+ });
+
+ it("reasoning in CWTC for Gemini non-streaming", async () => {
+ // Gemini CWTC does not currently include thought parts for reasoning;
+ // reasoning is only supported for text-only responses in Gemini format.
+ // Verify that the text and functionCall parts still appear correctly.
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "think" },
+ response: {
+ content: "The answer is 42",
+ toolCalls: [{ name: "calc", arguments: '{"x":42}' }],
+ reasoning: "Let me think about this...",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1beta/models/gemini-pro:generateContent`, {
+ contents: [{ role: "user", parts: [{ text: "think" }] }],
+ });
+ const json = JSON.parse(res.body);
+ const parts = json.candidates[0].content.parts;
+ const textPart = parts.find((p: Record) => p.text !== undefined && !p.thought);
+ const fcPart = parts.find((p: Record) => p.functionCall !== undefined);
+ expect(textPart).toBeDefined();
+ expect(textPart.text).toBe("The answer is 42");
+ expect(fcPart).toBeDefined();
+ });
+});
+
+describe("response overrides: webSearches in CWTC", () => {
+ it("webSearches in CWTC for Responses API", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "search" },
+ response: {
+ content: "Here are results",
+ toolCalls: [{ name: "lookup", arguments: '{"q":"test"}' }],
+ webSearches: ["search query 1"],
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/responses`, {
+ model: "gpt-4",
+ stream: false,
+ input: [{ role: "user", content: "search" }],
+ });
+ const json = JSON.parse(res.body);
+ const output = json.output as Array>;
+ const webSearchItems = output.filter((o) => o.type === "web_search_call");
+ expect(webSearchItems.length).toBeGreaterThan(0);
+ });
+});
+
+describe("response overrides: streaming tool calls with overrides", () => {
+ it("streaming tool call chunks with overrides per-chunk", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "weather" },
+ response: {
+ toolCalls: [{ name: "get_weather", arguments: '{"city":"NYC"}' }],
+ id: "chatcmpl-tc-override",
+ model: "gpt-4o-tc-override",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: true,
+ messages: [{ role: "user", content: "weather" }],
+ });
+ const chunks = parseSSEResponse(res.body);
+ expect(chunks.length).toBeGreaterThan(0);
+ for (const chunk of chunks) {
+ expect(chunk.id).toBe("chatcmpl-tc-override");
+ expect(chunk.model).toBe("gpt-4o-tc-override");
+ }
+ });
+
+ it("streaming content+toolCalls with overrides", async () => {
+ const fixtures: Fixture[] = [
+ {
+ match: { userMessage: "combo" },
+ response: {
+ content: "Let me check",
+ toolCalls: [{ name: "search", arguments: '{"q":"test"}' }],
+ id: "chatcmpl-combo-stream",
+ model: "gpt-4o-combo-stream",
+ },
+ },
+ ];
+ instance = await createServer(fixtures);
+ const res = await httpPost(`${instance.url}/v1/chat/completions`, {
+ model: "gpt-4",
+ stream: true,
+ messages: [{ role: "user", content: "combo" }],
+ });
+ const chunks = parseSSEResponse(res.body);
+ expect(chunks.length).toBeGreaterThan(0);
+ for (const chunk of chunks) {
+ expect(chunk.id).toBe("chatcmpl-combo-stream");
+ expect(chunk.model).toBe("gpt-4o-combo-stream");
+ }
+ });
+});
+
+describe("response overrides: extractOverrides unit tests", () => {
+ it("extractOverrides with empty usage", async () => {
+ const { extractOverrides } = await import("../helpers.js");
+ const result = extractOverrides({ content: "hi", usage: {} } as TextResponse);
+ expect(result.usage).toEqual({});
+ });
+
+ it("extractOverrides from ToolCallResponse", async () => {
+ const { extractOverrides } = await import("../helpers.js");
+ const result = extractOverrides({
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ id: "tc-1",
+ finishReason: "tool_calls",
+ } as ToolCallResponse);
+ expect(result.id).toBe("tc-1");
+ expect(result.finishReason).toBe("tool_calls");
+ });
+
+ it("extractOverrides from ContentWithToolCallsResponse", async () => {
+ const { extractOverrides } = await import("../helpers.js");
+ const result = extractOverrides({
+ content: "Hello",
+ toolCalls: [{ name: "fn", arguments: "{}" }],
+ id: "cwtc-1",
+ model: "gpt-4",
+ created: 1700000000,
+ finishReason: "tool_calls",
+ role: "assistant",
+ systemFingerprint: "fp_test",
+ usage: { prompt_tokens: 10 },
+ } as ContentWithToolCallsResponse);
+ expect(result.id).toBe("cwtc-1");
+ expect(result.model).toBe("gpt-4");
+ expect(result.created).toBe(1700000000);
+ expect(result.finishReason).toBe("tool_calls");
+ expect(result.role).toBe("assistant");
+ expect(result.systemFingerprint).toBe("fp_test");
+ expect(result.usage).toEqual({ prompt_tokens: 10 });
+ });
+});
+
+describe("response overrides: fixture file round-trip", () => {
+ it("preserves override fields from fixture file format", async () => {
+ // This tests that override fields on FixtureResponse are preserved through
+ // entryToFixture (fixture-loader) since it copies response as-is
+ const { entryToFixture } = await import("../fixture-loader.js");
+ const fixture = entryToFixture({
+ match: { userMessage: "hello" },
+ response: {
+ content: "Hi!",
+ id: "chatcmpl-file",
+ created: 1700000000,
+ model: "gpt-4o-file",
+ usage: { prompt_tokens: 10, completion_tokens: 5, total_tokens: 15 },
+ finishReason: "stop",
+ systemFingerprint: "fp_file",
+ },
+ });
+
+ const response = fixture.response as Record;
+ expect(response.id).toBe("chatcmpl-file");
+ expect(response.created).toBe(1700000000);
+ expect(response.model).toBe("gpt-4o-file");
+ expect(response.finishReason).toBe("stop");
+ expect(response.systemFingerprint).toBe("fp_file");
+ const usage = response.usage as Record;
+ expect(usage.prompt_tokens).toBe(10);
+ });
+});
diff --git a/src/fixture-loader.ts b/src/fixture-loader.ts
index 452ce14..40d2ddb 100644
--- a/src/fixture-loader.ts
+++ b/src/fixture-loader.ts
@@ -1,14 +1,53 @@
import { readFileSync, readdirSync, statSync } from "node:fs";
import { join } from "node:path";
-import type { Fixture, FixtureFile, FixtureFileEntry } from "./types.js";
+import type {
+ Fixture,
+ FixtureFile,
+ FixtureFileEntry,
+ FixtureFileResponse,
+ FixtureResponse,
+ ResponseOverrides,
+} from "./types.js";
import {
isTextResponse,
isToolCallResponse,
+ isContentWithToolCallsResponse,
isErrorResponse,
isEmbeddingResponse,
+ isImageResponse,
+ isAudioResponse,
+ isTranscriptionResponse,
+ isVideoResponse,
} from "./helpers.js";
import type { Logger } from "./logger.js";
+/**
+ * Auto-stringify object-valued `content` and `toolCalls[].arguments` fields.
+ * This lets fixture authors write plain JSON objects instead of escaped strings.
+ * All other fields (including ResponseOverrides) pass through unmodified.
+ */
+export function normalizeResponse(raw: FixtureFileResponse): FixtureResponse {
+ // Shallow-clone so we don't mutate the parsed JSON input.
+ const response = { ...raw } as Record;
+
+ // Auto-stringify object content (e.g. structured output)
+ if (typeof response.content === "object" && response.content !== null) {
+ response.content = JSON.stringify(response.content);
+ }
+
+ // Auto-stringify object arguments in toolCalls
+ if (Array.isArray(response.toolCalls)) {
+ response.toolCalls = (response.toolCalls as Array>).map((tc) => {
+ if (typeof tc.arguments === "object" && tc.arguments !== null) {
+ return { ...tc, arguments: JSON.stringify(tc.arguments) };
+ }
+ return tc;
+ });
+ }
+
+ return response as unknown as FixtureResponse;
+}
+
export function entryToFixture(entry: FixtureFileEntry): Fixture {
return {
match: {
@@ -21,7 +60,7 @@ export function entryToFixture(entry: FixtureFileEntry): Fixture {
endpoint: entry.match.endpoint,
...(entry.match.sequenceIndex !== undefined && { sequenceIndex: entry.match.sequenceIndex }),
},
- response: entry.response,
+ response: normalizeResponse(entry.response),
...(entry.latency !== undefined && { latency: entry.latency }),
...(entry.chunkSize !== undefined && { chunkSize: entry.chunkSize }),
...(entry.truncateAfterChunks !== undefined && {
@@ -120,6 +159,68 @@ export interface ValidationResult {
message: string;
}
+function validateReasoning(
+ response: { reasoning?: unknown },
+ fixtureIndex: number,
+ results: ValidationResult[],
+): void {
+ if (response.reasoning !== undefined) {
+ if (typeof response.reasoning !== "string") {
+ results.push({
+ severity: "error",
+ fixtureIndex,
+ message: "reasoning must be a string",
+ });
+ } else if (response.reasoning === "") {
+ results.push({
+ severity: "warning",
+ fixtureIndex,
+ message: "reasoning is empty string — no reasoning events will be emitted",
+ });
+ }
+ }
+}
+
+function validateWebSearches(
+ response: { webSearches?: unknown },
+ fixtureIndex: number,
+ results: ValidationResult[],
+): void {
+ if (response.webSearches !== undefined) {
+ if (!Array.isArray(response.webSearches)) {
+ results.push({
+ severity: "error",
+ fixtureIndex,
+ message: "webSearches must be an array of strings",
+ });
+ } else if (response.webSearches.length === 0) {
+ results.push({
+ severity: "warning",
+ fixtureIndex,
+ message: "webSearches is empty array — no web search events will be emitted",
+ });
+ } else {
+ for (let j = 0; j < response.webSearches.length; j++) {
+ if (typeof response.webSearches[j] !== "string") {
+ results.push({
+ severity: "error",
+ fixtureIndex,
+ message: `webSearches[${j}] is not a string`,
+ });
+ break;
+ }
+ if (response.webSearches[j] === "") {
+ results.push({
+ severity: "warning",
+ fixtureIndex,
+ message: `webSearches[${j}] is empty string`,
+ });
+ }
+ }
+ }
+ }
+}
+
export function validateFixtures(fixtures: Fixture[]): ValidationResult[] {
const results: ValidationResult[] = [];
@@ -132,17 +233,24 @@ export function validateFixtures(fixtures: Fixture[]): ValidationResult[] {
// --- Error checks ---
// Response type recognition
+ // Note: isContentWithToolCallsResponse must be checked before isTextResponse
+ // and isToolCallResponse since it is a structural superset of both.
if (
+ !isContentWithToolCallsResponse(response) &&
!isTextResponse(response) &&
!isToolCallResponse(response) &&
!isErrorResponse(response) &&
- !isEmbeddingResponse(response)
+ !isEmbeddingResponse(response) &&
+ !isImageResponse(response) &&
+ !isAudioResponse(response) &&
+ !isTranscriptionResponse(response) &&
+ !isVideoResponse(response)
) {
results.push({
severity: "error",
fixtureIndex: i,
message:
- "response is not a recognized type (must have content, toolCalls, error, or embedding)",
+ "response is not a recognized type (must have content, toolCalls, error, embedding, image, audio, transcription, or video)",
});
}
@@ -155,54 +263,47 @@ export function validateFixtures(fixtures: Fixture[]): ValidationResult[] {
message: "content is empty string",
});
}
- if (response.reasoning !== undefined) {
- if (typeof response.reasoning !== "string") {
+ validateReasoning(response, i, results);
+ validateWebSearches(response, i, results);
+ }
+
+ // ContentWithToolCalls response checks
+ if (isContentWithToolCallsResponse(response)) {
+ if (response.content === "") {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: "content is empty string",
+ });
+ }
+ if (response.toolCalls.length === 0) {
+ results.push({
+ severity: "warning",
+ fixtureIndex: i,
+ message: "toolCalls array is empty — fixture will never produce tool calls",
+ });
+ }
+ for (let j = 0; j < response.toolCalls.length; j++) {
+ const tc = response.toolCalls[j];
+ if (!tc.name) {
results.push({
severity: "error",
fixtureIndex: i,
- message: "reasoning must be a string",
- });
- } else if (response.reasoning === "") {
- results.push({
- severity: "warning",
- fixtureIndex: i,
- message: "reasoning is empty string — no reasoning events will be emitted",
+ message: `toolCalls[${j}].name is empty`,
});
}
- }
- if (response.webSearches !== undefined) {
- if (!Array.isArray(response.webSearches)) {
+ try {
+ JSON.parse(tc.arguments);
+ } catch {
results.push({
severity: "error",
fixtureIndex: i,
- message: "webSearches must be an array of strings",
- });
- } else if (response.webSearches.length === 0) {
- results.push({
- severity: "warning",
- fixtureIndex: i,
- message: "webSearches is empty array — no web search events will be emitted",
+ message: `toolCalls[${j}].arguments is not valid JSON: ${tc.arguments}`,
});
- } else {
- for (let j = 0; j < response.webSearches.length; j++) {
- if (typeof response.webSearches[j] !== "string") {
- results.push({
- severity: "error",
- fixtureIndex: i,
- message: `webSearches[${j}] is not a string`,
- });
- break;
- }
- if (response.webSearches[j] === "") {
- results.push({
- severity: "warning",
- fixtureIndex: i,
- message: `webSearches[${j}] is empty string`,
- });
- }
- }
}
}
+ validateReasoning(response, i, results);
+ validateWebSearches(response, i, results);
}
// Tool call response checks
@@ -274,6 +375,78 @@ export function validateFixtures(fixtures: Fixture[]): ValidationResult[] {
}
}
+ // Validate ResponseOverrides fields
+ if (
+ isTextResponse(response) ||
+ isToolCallResponse(response) ||
+ isContentWithToolCallsResponse(response)
+ ) {
+ const r = response as ResponseOverrides;
+ if (r.id !== undefined && typeof r.id !== "string") {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "id" must be a string, got ${typeof r.id}`,
+ });
+ }
+ if (r.created !== undefined && (typeof r.created !== "number" || r.created < 0)) {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "created" must be a non-negative number`,
+ });
+ }
+ if (r.model !== undefined && typeof r.model !== "string") {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "model" must be a string, got ${typeof r.model}`,
+ });
+ }
+ if (r.finishReason !== undefined && typeof r.finishReason !== "string") {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "finishReason" must be a string, got ${typeof r.finishReason}`,
+ });
+ }
+ if (r.role !== undefined && typeof r.role !== "string") {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "role" must be a string, got ${typeof r.role}`,
+ });
+ }
+ if (r.systemFingerprint !== undefined && typeof r.systemFingerprint !== "string") {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "systemFingerprint" must be a string, got ${typeof r.systemFingerprint}`,
+ });
+ }
+ if (r.usage !== undefined) {
+ if (typeof r.usage !== "object" || r.usage === null || Array.isArray(r.usage)) {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "usage" must be an object`,
+ });
+ } else {
+ // Check all known usage fields are numbers if present
+ for (const key of Object.keys(r.usage)) {
+ const val = (r.usage as Record)[key];
+ if (val !== undefined && typeof val !== "number") {
+ results.push({
+ severity: "error",
+ fixtureIndex: i,
+ message: `override "usage.${key}" must be a number, got ${typeof val}`,
+ });
+ }
+ }
+ }
+ }
+ }
+
// Numeric sanity checks
if (f.latency !== undefined && f.latency < 0) {
results.push({
diff --git a/src/gemini.ts b/src/gemini.ts
index 3c6529d..c879a14 100644
--- a/src/gemini.ts
+++ b/src/gemini.ts
@@ -13,6 +13,7 @@ import type {
Fixture,
HandlerDefaults,
RecordProviderKey,
+ ResponseOverrides,
StreamingProfile,
ToolCall,
ToolDefinition,
@@ -22,6 +23,7 @@ import {
isToolCallResponse,
isContentWithToolCallsResponse,
isErrorResponse,
+ extractOverrides,
generateToolCallId,
flattenHeaders,
getTestId,
@@ -177,6 +179,33 @@ export function geminiToCompletionRequest(
// ─── Response building: fixture → Gemini format ─────────────────────────────
+function geminiFinishReason(finishReason: string | undefined, defaultReason: string): string {
+ if (!finishReason) return defaultReason;
+ if (finishReason === "stop") return "STOP";
+ if (finishReason === "tool_calls") return "FUNCTION_CALL";
+ if (finishReason === "length") return "MAX_TOKENS";
+ if (finishReason === "content_filter") return "SAFETY";
+ // Pass through unrecognized values as-is
+ return finishReason;
+}
+
+function geminiUsageMetadata(overrides?: ResponseOverrides): {
+ promptTokenCount: number;
+ candidatesTokenCount: number;
+ totalTokenCount: number;
+} {
+ if (!overrides?.usage)
+ return { promptTokenCount: 0, candidatesTokenCount: 0, totalTokenCount: 0 };
+ const prompt = overrides.usage.promptTokenCount ?? 0;
+ const candidates = overrides.usage.candidatesTokenCount ?? 0;
+ const total = overrides.usage.totalTokenCount ?? prompt + candidates;
+ return {
+ promptTokenCount: prompt,
+ candidatesTokenCount: candidates,
+ totalTokenCount: total,
+ };
+}
+
interface GeminiResponseChunk {
candidates: {
content: { role: string; parts: GeminiPart[] };
@@ -194,8 +223,11 @@ function buildGeminiTextStreamChunks(
content: string,
chunkSize: number,
reasoning?: string,
+ overrides?: ResponseOverrides,
): GeminiResponseChunk[] {
const chunks: GeminiResponseChunk[] = [];
+ const effectiveFinish = geminiFinishReason(overrides?.finishReason, "STOP");
+ const usage = geminiUsageMetadata(overrides);
// Reasoning chunks (thought: true)
if (reasoning) {
@@ -212,7 +244,7 @@ function buildGeminiTextStreamChunks(
}
}
- // Content chunks (original logic unchanged)
+ // Content chunks
for (let i = 0; i < content.length; i += chunkSize) {
const slice = content.slice(i, i + chunkSize);
const isLast = i + chunkSize >= content.length;
@@ -221,37 +253,25 @@ function buildGeminiTextStreamChunks(
{
content: { role: "model", parts: [{ text: slice }] },
index: 0,
- ...(isLast ? { finishReason: "STOP" } : {}),
+ ...(isLast ? { finishReason: effectiveFinish } : {}),
},
],
- ...(isLast
- ? {
- usageMetadata: {
- promptTokenCount: 0,
- candidatesTokenCount: 0,
- totalTokenCount: 0,
- },
- }
- : {}),
+ ...(isLast ? { usageMetadata: usage } : {}),
};
chunks.push(chunk);
}
- // Handle empty content (original logic unchanged)
+ // Handle empty content
if (content.length === 0) {
chunks.push({
candidates: [
{
content: { role: "model", parts: [{ text: "" }] },
- finishReason: "STOP",
+ finishReason: effectiveFinish,
index: 0,
},
],
- usageMetadata: {
- promptTokenCount: 0,
- candidatesTokenCount: 0,
- totalTokenCount: 0,
- },
+ usageMetadata: usage,
});
}
@@ -272,6 +292,7 @@ function parseToolCallPart(tc: ToolCall, logger: Logger): GeminiPart {
function buildGeminiToolCallStreamChunks(
toolCalls: ToolCall[],
logger: Logger,
+ overrides?: ResponseOverrides,
): GeminiResponseChunk[] {
const parts: GeminiPart[] = toolCalls.map((tc) => parseToolCallPart(tc, logger));
@@ -281,22 +302,22 @@ function buildGeminiToolCallStreamChunks(
candidates: [
{
content: { role: "model", parts },
- finishReason: "FUNCTION_CALL",
+ finishReason: geminiFinishReason(overrides?.finishReason, "FUNCTION_CALL"),
index: 0,
},
],
- usageMetadata: {
- promptTokenCount: 0,
- candidatesTokenCount: 0,
- totalTokenCount: 0,
- },
+ usageMetadata: geminiUsageMetadata(overrides),
},
];
}
// Non-streaming response builders
-function buildGeminiTextResponse(content: string, reasoning?: string): GeminiResponseChunk {
+function buildGeminiTextResponse(
+ content: string,
+ reasoning?: string,
+ overrides?: ResponseOverrides,
+): GeminiResponseChunk {
const parts: GeminiPart[] = [];
if (reasoning) {
parts.push({ text: reasoning, thought: true });
@@ -307,34 +328,30 @@ function buildGeminiTextResponse(content: string, reasoning?: string): GeminiRes
candidates: [
{
content: { role: "model", parts },
- finishReason: "STOP",
+ finishReason: geminiFinishReason(overrides?.finishReason, "STOP"),
index: 0,
},
],
- usageMetadata: {
- promptTokenCount: 0,
- candidatesTokenCount: 0,
- totalTokenCount: 0,
- },
+ usageMetadata: geminiUsageMetadata(overrides),
};
}
-function buildGeminiToolCallResponse(toolCalls: ToolCall[], logger: Logger): GeminiResponseChunk {
+function buildGeminiToolCallResponse(
+ toolCalls: ToolCall[],
+ logger: Logger,
+ overrides?: ResponseOverrides,
+): GeminiResponseChunk {
const parts: GeminiPart[] = toolCalls.map((tc) => parseToolCallPart(tc, logger));
return {
candidates: [
{
content: { role: "model", parts },
- finishReason: "FUNCTION_CALL",
+ finishReason: geminiFinishReason(overrides?.finishReason, "FUNCTION_CALL"),
index: 0,
},
],
- usageMetadata: {
- promptTokenCount: 0,
- candidatesTokenCount: 0,
- totalTokenCount: 0,
- },
+ usageMetadata: geminiUsageMetadata(overrides),
};
}
@@ -343,9 +360,26 @@ function buildGeminiContentWithToolCallsStreamChunks(
toolCalls: ToolCall[],
chunkSize: number,
logger: Logger,
+ reasoning?: string,
+ overrides?: ResponseOverrides,
): GeminiResponseChunk[] {
const chunks: GeminiResponseChunk[] = [];
+ // Reasoning chunks (thought: true)
+ if (reasoning) {
+ for (let i = 0; i < reasoning.length; i += chunkSize) {
+ const slice = reasoning.slice(i, i + chunkSize);
+ chunks.push({
+ candidates: [
+ {
+ content: { role: "model", parts: [{ text: slice, thought: true }] },
+ index: 0,
+ },
+ ],
+ });
+ }
+ }
+
if (content.length === 0) {
chunks.push({
candidates: [
@@ -375,15 +409,11 @@ function buildGeminiContentWithToolCallsStreamChunks(
candidates: [
{
content: { role: "model", parts },
- finishReason: "FUNCTION_CALL",
+ finishReason: geminiFinishReason(overrides?.finishReason, "FUNCTION_CALL"),
index: 0,
},
],
- usageMetadata: {
- promptTokenCount: 0,
- candidatesTokenCount: 0,
- totalTokenCount: 0,
- },
+ usageMetadata: geminiUsageMetadata(overrides),
});
return chunks;
@@ -393,25 +423,25 @@ function buildGeminiContentWithToolCallsResponse(
content: string,
toolCalls: ToolCall[],
logger: Logger,
+ reasoning?: string,
+ overrides?: ResponseOverrides,
): GeminiResponseChunk {
- const parts: GeminiPart[] = [
- { text: content },
- ...toolCalls.map((tc) => parseToolCallPart(tc, logger)),
- ];
+ const parts: GeminiPart[] = [];
+ if (reasoning) {
+ parts.push({ text: reasoning, thought: true });
+ }
+ parts.push({ text: content });
+ parts.push(...toolCalls.map((tc) => parseToolCallPart(tc, logger)));
return {
candidates: [
{
content: { role: "model", parts },
- finishReason: "FUNCTION_CALL",
+ finishReason: geminiFinishReason(overrides?.finishReason, "FUNCTION_CALL"),
index: 0,
},
],
- usageMetadata: {
- promptTokenCount: 0,
- candidatesTokenCount: 0,
- totalTokenCount: 0,
- },
+ usageMetadata: geminiUsageMetadata(overrides),
};
}
@@ -617,6 +647,10 @@ export async function handleGemini(
// Content + tool calls response (must be checked before isTextResponse / isToolCallResponse)
if (isContentWithToolCallsResponse(response)) {
+ if (response.webSearches?.length) {
+ logger.warn("webSearches in fixture response are not supported for Gemini API — ignoring");
+ }
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path,
@@ -629,6 +663,8 @@ export async function handleGemini(
response.content,
response.toolCalls,
logger,
+ response.reasoning,
+ overrides,
);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
@@ -638,6 +674,8 @@ export async function handleGemini(
response.toolCalls,
chunkSize,
logger,
+ response.reasoning,
+ overrides,
);
const interruption = createInterruptionSignal(fixture);
const completed = await writeGeminiSSEStream(res, chunks, {
@@ -658,6 +696,10 @@ export async function handleGemini(
// Text response
if (isTextResponse(response)) {
+ if (response.webSearches?.length) {
+ logger.warn("webSearches in fixture response are not supported for Gemini API — ignoring");
+ }
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path,
@@ -666,11 +708,16 @@ export async function handleGemini(
response: { status: 200, fixture },
});
if (!streaming) {
- const body = buildGeminiTextResponse(response.content, response.reasoning);
+ const body = buildGeminiTextResponse(response.content, response.reasoning, overrides);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
} else {
- const chunks = buildGeminiTextStreamChunks(response.content, chunkSize, response.reasoning);
+ const chunks = buildGeminiTextStreamChunks(
+ response.content,
+ chunkSize,
+ response.reasoning,
+ overrides,
+ );
const interruption = createInterruptionSignal(fixture);
const completed = await writeGeminiSSEStream(res, chunks, {
latency,
@@ -690,6 +737,7 @@ export async function handleGemini(
// Tool call response
if (isToolCallResponse(response)) {
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path,
@@ -698,11 +746,11 @@ export async function handleGemini(
response: { status: 200, fixture },
});
if (!streaming) {
- const body = buildGeminiToolCallResponse(response.toolCalls, logger);
+ const body = buildGeminiToolCallResponse(response.toolCalls, logger, overrides);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
} else {
- const chunks = buildGeminiToolCallStreamChunks(response.toolCalls, logger);
+ const chunks = buildGeminiToolCallStreamChunks(response.toolCalls, logger, overrides);
const interruption = createInterruptionSignal(fixture);
const completed = await writeGeminiSSEStream(res, chunks, {
latency,
diff --git a/src/helpers.ts b/src/helpers.ts
index 325ac11..799902f 100644
--- a/src/helpers.ts
+++ b/src/helpers.ts
@@ -14,6 +14,7 @@ import type {
SSEChunk,
ToolCall,
ChatCompletion,
+ ResponseOverrides,
} from "./types.js";
const REDACTED_HEADERS = new Set(["authorization", "x-api-key", "api-key"]);
@@ -48,11 +49,15 @@ export function generateToolUseId(): string {
}
export function isTextResponse(r: FixtureResponse): r is TextResponse {
- return "content" in r && typeof (r as TextResponse).content === "string";
+ return "content" in r && typeof (r as TextResponse).content === "string" && !("toolCalls" in r);
}
export function isToolCallResponse(r: FixtureResponse): r is ToolCallResponse {
- return "toolCalls" in r && Array.isArray((r as ToolCallResponse).toolCalls);
+ return (
+ "toolCalls" in r &&
+ Array.isArray((r as ToolCallResponse).toolCalls) &&
+ !("content" in r && typeof (r as unknown as Record).content === "string")
+ );
}
export function isContentWithToolCallsResponse(
@@ -105,15 +110,33 @@ export function isVideoResponse(r: FixtureResponse): r is VideoResponse {
);
}
+export function extractOverrides(
+ response: TextResponse | ToolCallResponse | ContentWithToolCallsResponse,
+): ResponseOverrides {
+ const r = response;
+ return {
+ ...(r.id !== undefined && { id: r.id }),
+ ...(r.created !== undefined && { created: r.created }),
+ ...(r.model !== undefined && { model: r.model }),
+ ...(r.usage !== undefined && { usage: r.usage }),
+ ...(r.systemFingerprint !== undefined && { systemFingerprint: r.systemFingerprint }),
+ ...(r.finishReason !== undefined && { finishReason: r.finishReason }),
+ ...(r.role !== undefined && { role: r.role }),
+ };
+}
+
export function buildTextChunks(
content: string,
model: string,
chunkSize: number,
reasoning?: string,
+ overrides?: ResponseOverrides,
): SSEChunk[] {
- const id = generateId();
- const created = Math.floor(Date.now() / 1000);
+ const id = overrides?.id ?? generateId();
+ const created = overrides?.created ?? Math.floor(Date.now() / 1000);
+ const effectiveModel = overrides?.model ?? model;
const chunks: SSEChunk[] = [];
+ const fingerprint = overrides?.systemFingerprint;
// Reasoning chunks (emitted before content, OpenRouter format)
if (reasoning) {
@@ -123,8 +146,9 @@ export function buildTextChunks(
id,
object: "chat.completion.chunk",
created,
- model,
+ model: effectiveModel,
choices: [{ index: 0, delta: { reasoning_content: slice }, finish_reason: null }],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
}
}
@@ -134,8 +158,15 @@ export function buildTextChunks(
id,
object: "chat.completion.chunk",
created,
- model,
- choices: [{ index: 0, delta: { role: "assistant", content: "" }, finish_reason: null }],
+ model: effectiveModel,
+ choices: [
+ {
+ index: 0,
+ delta: { role: overrides?.role ?? "assistant", content: "" },
+ finish_reason: null,
+ },
+ ],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
// Content chunks
@@ -145,8 +176,9 @@ export function buildTextChunks(
id,
object: "chat.completion.chunk",
created,
- model,
+ model: effectiveModel,
choices: [{ index: 0, delta: { content: slice }, finish_reason: null }],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
}
@@ -155,8 +187,9 @@ export function buildTextChunks(
id,
object: "chat.completion.chunk",
created,
- model,
- choices: [{ index: 0, delta: {}, finish_reason: "stop" }],
+ model: effectiveModel,
+ choices: [{ index: 0, delta: {}, finish_reason: overrides?.finishReason ?? "stop" }],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
return chunks;
@@ -166,18 +199,28 @@ export function buildToolCallChunks(
toolCalls: ToolCall[],
model: string,
chunkSize: number,
+ overrides?: ResponseOverrides,
): SSEChunk[] {
- const id = generateId();
- const created = Math.floor(Date.now() / 1000);
+ const id = overrides?.id ?? generateId();
+ const created = overrides?.created ?? Math.floor(Date.now() / 1000);
+ const effectiveModel = overrides?.model ?? model;
const chunks: SSEChunk[] = [];
+ const fingerprint = overrides?.systemFingerprint;
// Role chunk
chunks.push({
id,
object: "chat.completion.chunk",
created,
- model,
- choices: [{ index: 0, delta: { role: "assistant", content: null }, finish_reason: null }],
+ model: effectiveModel,
+ choices: [
+ {
+ index: 0,
+ delta: { role: overrides?.role ?? "assistant", content: null },
+ finish_reason: null,
+ },
+ ],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
// Tool call chunks — one initial chunk per tool call, then argument chunks
@@ -190,7 +233,7 @@ export function buildToolCallChunks(
id,
object: "chat.completion.chunk",
created,
- model,
+ model: effectiveModel,
choices: [
{
index: 0,
@@ -207,6 +250,7 @@ export function buildToolCallChunks(
finish_reason: null,
},
],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
// Argument streaming chunks
@@ -217,7 +261,7 @@ export function buildToolCallChunks(
id,
object: "chat.completion.chunk",
created,
- model,
+ model: effectiveModel,
choices: [
{
index: 0,
@@ -227,6 +271,7 @@ export function buildToolCallChunks(
finish_reason: null,
},
],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
}
}
@@ -236,8 +281,9 @@ export function buildToolCallChunks(
id,
object: "chat.completion.chunk",
created,
- model,
- choices: [{ index: 0, delta: {}, finish_reason: "tool_calls" }],
+ model: effectiveModel,
+ choices: [{ index: 0, delta: {}, finish_reason: overrides?.finishReason ?? "tool_calls" }],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
return chunks;
@@ -249,39 +295,57 @@ export function buildTextCompletion(
content: string,
model: string,
reasoning?: string,
+ overrides?: ResponseOverrides,
): ChatCompletion {
+ const defaultUsage = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
return {
- id: generateId(),
+ id: overrides?.id ?? generateId(),
object: "chat.completion",
- created: Math.floor(Date.now() / 1000),
- model,
+ created: overrides?.created ?? Math.floor(Date.now() / 1000),
+ model: overrides?.model ?? model,
choices: [
{
index: 0,
message: {
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content,
refusal: null,
...(reasoning ? { reasoning_content: reasoning } : {}),
},
- finish_reason: "stop",
+ finish_reason: overrides?.finishReason ?? "stop",
},
],
- usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
+ usage: overrides?.usage
+ ? {
+ prompt_tokens: overrides.usage.prompt_tokens ?? defaultUsage.prompt_tokens,
+ completion_tokens: overrides.usage.completion_tokens ?? defaultUsage.completion_tokens,
+ total_tokens:
+ overrides.usage.total_tokens ??
+ (overrides.usage.prompt_tokens ?? 0) + (overrides.usage.completion_tokens ?? 0),
+ }
+ : defaultUsage,
+ ...(overrides?.systemFingerprint !== undefined && {
+ system_fingerprint: overrides.systemFingerprint,
+ }),
};
}
-export function buildToolCallCompletion(toolCalls: ToolCall[], model: string): ChatCompletion {
+export function buildToolCallCompletion(
+ toolCalls: ToolCall[],
+ model: string,
+ overrides?: ResponseOverrides,
+): ChatCompletion {
+ const defaultUsage = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
return {
- id: generateId(),
+ id: overrides?.id ?? generateId(),
object: "chat.completion",
- created: Math.floor(Date.now() / 1000),
- model,
+ created: overrides?.created ?? Math.floor(Date.now() / 1000),
+ model: overrides?.model ?? model,
choices: [
{
index: 0,
message: {
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content: null,
refusal: null,
tool_calls: toolCalls.map((tc) => ({
@@ -290,10 +354,21 @@ export function buildToolCallCompletion(toolCalls: ToolCall[], model: string): C
function: { name: tc.name, arguments: tc.arguments },
})),
},
- finish_reason: "tool_calls",
+ finish_reason: overrides?.finishReason ?? "tool_calls",
},
],
- usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
+ usage: overrides?.usage
+ ? {
+ prompt_tokens: overrides.usage.prompt_tokens ?? defaultUsage.prompt_tokens,
+ completion_tokens: overrides.usage.completion_tokens ?? defaultUsage.completion_tokens,
+ total_tokens:
+ overrides.usage.total_tokens ??
+ (overrides.usage.prompt_tokens ?? 0) + (overrides.usage.completion_tokens ?? 0),
+ }
+ : defaultUsage,
+ ...(overrides?.systemFingerprint !== undefined && {
+ system_fingerprint: overrides.systemFingerprint,
+ }),
};
}
@@ -302,18 +377,44 @@ export function buildContentWithToolCallsChunks(
toolCalls: ToolCall[],
model: string,
chunkSize: number,
+ reasoning?: string,
+ overrides?: ResponseOverrides,
): SSEChunk[] {
- const id = generateId();
- const created = Math.floor(Date.now() / 1000);
+ const id = overrides?.id ?? generateId();
+ const created = overrides?.created ?? Math.floor(Date.now() / 1000);
+ const effectiveModel = overrides?.model ?? model;
const chunks: SSEChunk[] = [];
+ const fingerprint = overrides?.systemFingerprint;
+
+ // Reasoning chunks (emitted before content, OpenRouter format)
+ if (reasoning) {
+ for (let i = 0; i < reasoning.length; i += chunkSize) {
+ const slice = reasoning.slice(i, i + chunkSize);
+ chunks.push({
+ id,
+ object: "chat.completion.chunk",
+ created,
+ model: effectiveModel,
+ choices: [{ index: 0, delta: { reasoning_content: slice }, finish_reason: null }],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
+ });
+ }
+ }
// Role chunk
chunks.push({
id,
object: "chat.completion.chunk",
created,
- model,
- choices: [{ index: 0, delta: { role: "assistant", content: "" }, finish_reason: null }],
+ model: effectiveModel,
+ choices: [
+ {
+ index: 0,
+ delta: { role: overrides?.role ?? "assistant", content: "" },
+ finish_reason: null,
+ },
+ ],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
// Content chunks
@@ -323,8 +424,9 @@ export function buildContentWithToolCallsChunks(
id,
object: "chat.completion.chunk",
created,
- model,
+ model: effectiveModel,
choices: [{ index: 0, delta: { content: slice }, finish_reason: null }],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
}
@@ -338,7 +440,7 @@ export function buildContentWithToolCallsChunks(
id,
object: "chat.completion.chunk",
created,
- model,
+ model: effectiveModel,
choices: [
{
index: 0,
@@ -355,6 +457,7 @@ export function buildContentWithToolCallsChunks(
finish_reason: null,
},
],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
// Argument streaming chunks
@@ -365,7 +468,7 @@ export function buildContentWithToolCallsChunks(
id,
object: "chat.completion.chunk",
created,
- model,
+ model: effectiveModel,
choices: [
{
index: 0,
@@ -375,6 +478,7 @@ export function buildContentWithToolCallsChunks(
finish_reason: null,
},
],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
}
}
@@ -384,8 +488,9 @@ export function buildContentWithToolCallsChunks(
id,
object: "chat.completion.chunk",
created,
- model,
- choices: [{ index: 0, delta: {}, finish_reason: "tool_calls" }],
+ model: effectiveModel,
+ choices: [{ index: 0, delta: {}, finish_reason: overrides?.finishReason ?? "tool_calls" }],
+ ...(fingerprint !== undefined && { system_fingerprint: fingerprint }),
});
return chunks;
@@ -395,29 +500,44 @@ export function buildContentWithToolCallsCompletion(
content: string,
toolCalls: ToolCall[],
model: string,
+ reasoning?: string,
+ overrides?: ResponseOverrides,
): ChatCompletion {
+ const defaultUsage = { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 };
return {
- id: generateId(),
+ id: overrides?.id ?? generateId(),
object: "chat.completion",
- created: Math.floor(Date.now() / 1000),
- model,
+ created: overrides?.created ?? Math.floor(Date.now() / 1000),
+ model: overrides?.model ?? model,
choices: [
{
index: 0,
message: {
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content,
refusal: null,
+ ...(reasoning ? { reasoning_content: reasoning } : {}),
tool_calls: toolCalls.map((tc) => ({
id: tc.id || generateToolCallId(),
type: "function" as const,
function: { name: tc.name, arguments: tc.arguments },
})),
},
- finish_reason: "tool_calls",
+ finish_reason: overrides?.finishReason ?? "tool_calls",
},
],
- usage: { prompt_tokens: 0, completion_tokens: 0, total_tokens: 0 },
+ usage: overrides?.usage
+ ? {
+ prompt_tokens: overrides.usage.prompt_tokens ?? defaultUsage.prompt_tokens,
+ completion_tokens: overrides.usage.completion_tokens ?? defaultUsage.completion_tokens,
+ total_tokens:
+ overrides.usage.total_tokens ??
+ (overrides.usage.prompt_tokens ?? 0) + (overrides.usage.completion_tokens ?? 0),
+ }
+ : defaultUsage,
+ ...(overrides?.systemFingerprint !== undefined && {
+ system_fingerprint: overrides.systemFingerprint,
+ }),
};
}
diff --git a/src/index.ts b/src/index.ts
index 4cb0cfb..e69602d 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -5,7 +5,12 @@ export { LLMock } from "./llmock.js";
export { createServer, type ServerInstance } from "./server.js";
// Fixture loading
-export { loadFixtureFile, loadFixturesFromDir, validateFixtures } from "./fixture-loader.js";
+export {
+ loadFixtureFile,
+ loadFixturesFromDir,
+ validateFixtures,
+ normalizeResponse,
+} from "./fixture-loader.js";
export type { ValidationResult } from "./fixture-loader.js";
// Logger
@@ -85,6 +90,15 @@ export {
generateToolUseId,
buildTextChunks,
buildToolCallChunks,
+ buildContentWithToolCallsChunks,
+ buildTextCompletion,
+ buildToolCallCompletion,
+ buildContentWithToolCallsCompletion,
+ extractOverrides,
+ isTextResponse,
+ isToolCallResponse,
+ isContentWithToolCallsResponse,
+ isErrorResponse,
isEmbeddingResponse,
isImageResponse,
isAudioResponse,
@@ -265,4 +279,11 @@ export type {
AudioResponse,
TranscriptionResponse,
VideoResponse,
+ ResponseOverrides,
+ ContentWithToolCallsResponse,
+ FixtureFileResponse,
+ FixtureFileToolCall,
+ FixtureFileTextResponse,
+ FixtureFileToolCallResponse,
+ FixtureFileContentWithToolCallsResponse,
} from "./types.js";
diff --git a/src/llmock.ts b/src/llmock.ts
index 973be71..a5c8dac 100644
--- a/src/llmock.ts
+++ b/src/llmock.ts
@@ -4,6 +4,7 @@ import type {
EmbeddingFixtureOpts,
Fixture,
FixtureFileEntry,
+ FixtureFileResponse,
FixtureMatch,
FixtureOpts,
FixtureResponse,
@@ -19,6 +20,7 @@ import {
loadFixtureFile,
loadFixturesFromDir,
entryToFixture,
+ normalizeResponse,
validateFixtures,
} from "./fixture-loader.js";
import { Journal } from "./journal.js";
@@ -95,21 +97,21 @@ export class LLMock {
// ---- Convenience ----
- on(match: FixtureMatch, response: FixtureResponse, opts?: FixtureOpts): this {
+ on(match: FixtureMatch, response: FixtureFileResponse, opts?: FixtureOpts): this {
return this.addFixture({
match,
- response,
+ response: normalizeResponse(response),
...opts,
});
}
- onMessage(pattern: string | RegExp, response: FixtureResponse, opts?: FixtureOpts): this {
+ onMessage(pattern: string | RegExp, response: FixtureFileResponse, opts?: FixtureOpts): this {
return this.on({ userMessage: pattern }, response, opts);
}
onEmbedding(
pattern: string | RegExp,
- response: FixtureResponse,
+ response: FixtureFileResponse,
opts?: EmbeddingFixtureOpts,
): this {
return this.on({ inputText: pattern }, response, opts);
@@ -120,11 +122,11 @@ export class LLMock {
return this.on({ userMessage: pattern, responseFormat: "json_object" }, { content }, opts);
}
- onToolCall(name: string, response: FixtureResponse, opts?: FixtureOpts): this {
+ onToolCall(name: string, response: FixtureFileResponse, opts?: FixtureOpts): this {
return this.on({ toolName: name }, response, opts);
}
- onToolResult(id: string, response: FixtureResponse, opts?: FixtureOpts): this {
+ onToolResult(id: string, response: FixtureFileResponse, opts?: FixtureOpts): this {
return this.on({ toolCallId: id }, response, opts);
}
diff --git a/src/messages.ts b/src/messages.ts
index c58d85a..0ed2e91 100644
--- a/src/messages.ts
+++ b/src/messages.ts
@@ -12,6 +12,7 @@ import type {
ChatMessage,
Fixture,
HandlerDefaults,
+ ResponseOverrides,
StreamingProfile,
ToolCall,
ToolDefinition,
@@ -19,6 +20,7 @@ import type {
import {
generateMessageId,
generateToolUseId,
+ extractOverrides,
isTextResponse,
isToolCallResponse,
isContentWithToolCallsResponse,
@@ -191,6 +193,25 @@ export function claudeToCompletionRequest(req: ClaudeRequest): ChatCompletionReq
// ─── Response building: fixture → Claude Messages API format ────────────────
+function claudeStopReason(finishReason: string | undefined, defaultReason: string): string {
+ if (!finishReason) return defaultReason;
+ if (finishReason === "stop") return "end_turn";
+ if (finishReason === "tool_calls") return "tool_use";
+ if (finishReason === "length") return "max_tokens";
+ return finishReason;
+}
+
+function claudeUsage(overrides?: ResponseOverrides): {
+ input_tokens: number;
+ output_tokens: number;
+} {
+ if (!overrides?.usage) return { input_tokens: 0, output_tokens: 0 };
+ return {
+ input_tokens: overrides.usage.input_tokens ?? 0,
+ output_tokens: overrides.usage.output_tokens ?? 0,
+ };
+}
+
interface ClaudeSSEEvent {
type: string;
[key: string]: unknown;
@@ -201,8 +222,10 @@ function buildClaudeTextStreamEvents(
model: string,
chunkSize: number,
reasoning?: string,
+ overrides?: ResponseOverrides,
): ClaudeSSEEvent[] {
- const msgId = generateMessageId();
+ const msgId = overrides?.id ?? generateMessageId();
+ const effectiveModel = overrides?.model ?? model;
const events: ClaudeSSEEvent[] = [];
// message_start
@@ -211,12 +234,12 @@ function buildClaudeTextStreamEvents(
message: {
id: msgId,
type: "message",
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content: [],
- model,
+ model: effectiveModel,
stop_reason: null,
stop_sequence: null,
- usage: { input_tokens: 0, output_tokens: 0 },
+ usage: claudeUsage(overrides),
},
});
@@ -273,8 +296,11 @@ function buildClaudeTextStreamEvents(
// message_delta
events.push({
type: "message_delta",
- delta: { stop_reason: "end_turn", stop_sequence: null },
- usage: { output_tokens: 0 },
+ delta: {
+ stop_reason: claudeStopReason(overrides?.finishReason, "end_turn"),
+ stop_sequence: null,
+ },
+ usage: { output_tokens: claudeUsage(overrides).output_tokens },
});
// message_stop
@@ -288,8 +314,10 @@ function buildClaudeToolCallStreamEvents(
model: string,
chunkSize: number,
logger: Logger,
+ overrides?: ResponseOverrides,
): ClaudeSSEEvent[] {
- const msgId = generateMessageId();
+ const msgId = overrides?.id ?? generateMessageId();
+ const effectiveModel = overrides?.model ?? model;
const events: ClaudeSSEEvent[] = [];
// message_start
@@ -298,12 +326,12 @@ function buildClaudeToolCallStreamEvents(
message: {
id: msgId,
type: "message",
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content: [],
- model,
+ model: effectiveModel,
stop_reason: null,
stop_sequence: null,
- usage: { input_tokens: 0, output_tokens: 0 },
+ usage: claudeUsage(overrides),
},
});
@@ -355,8 +383,11 @@ function buildClaudeToolCallStreamEvents(
// message_delta
events.push({
type: "message_delta",
- delta: { stop_reason: "tool_use", stop_sequence: null },
- usage: { output_tokens: 0 },
+ delta: {
+ stop_reason: claudeStopReason(overrides?.finishReason, "tool_use"),
+ stop_sequence: null,
+ },
+ usage: { output_tokens: claudeUsage(overrides).output_tokens },
});
// message_stop
@@ -367,7 +398,12 @@ function buildClaudeToolCallStreamEvents(
// Non-streaming response builders
-function buildClaudeTextResponse(content: string, model: string, reasoning?: string): object {
+function buildClaudeTextResponse(
+ content: string,
+ model: string,
+ reasoning?: string,
+ overrides?: ResponseOverrides,
+): object {
const contentBlocks: object[] = [];
if (reasoning) {
@@ -377,22 +413,27 @@ function buildClaudeTextResponse(content: string, model: string, reasoning?: str
contentBlocks.push({ type: "text", text: content });
return {
- id: generateMessageId(),
+ id: overrides?.id ?? generateMessageId(),
type: "message",
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content: contentBlocks,
- model,
- stop_reason: "end_turn",
+ model: overrides?.model ?? model,
+ stop_reason: claudeStopReason(overrides?.finishReason, "end_turn"),
stop_sequence: null,
- usage: { input_tokens: 0, output_tokens: 0 },
+ usage: claudeUsage(overrides),
};
}
-function buildClaudeToolCallResponse(toolCalls: ToolCall[], model: string, logger: Logger): object {
+function buildClaudeToolCallResponse(
+ toolCalls: ToolCall[],
+ model: string,
+ logger: Logger,
+ overrides?: ResponseOverrides,
+): object {
return {
- id: generateMessageId(),
+ id: overrides?.id ?? generateMessageId(),
type: "message",
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content: toolCalls.map((tc) => {
let argsObj: unknown;
try {
@@ -410,10 +451,10 @@ function buildClaudeToolCallResponse(toolCalls: ToolCall[], model: string, logge
input: argsObj,
};
}),
- model,
- stop_reason: "tool_use",
+ model: overrides?.model ?? model,
+ stop_reason: claudeStopReason(overrides?.finishReason, "tool_use"),
stop_sequence: null,
- usage: { input_tokens: 0, output_tokens: 0 },
+ usage: claudeUsage(overrides),
};
}
@@ -424,8 +465,10 @@ function buildClaudeContentWithToolCallsStreamEvents(
chunkSize: number,
logger: Logger,
reasoning?: string,
+ overrides?: ResponseOverrides,
): ClaudeSSEEvent[] {
- const msgId = generateMessageId();
+ const msgId = overrides?.id ?? generateMessageId();
+ const effectiveModel = overrides?.model ?? model;
const events: ClaudeSSEEvent[] = [];
// message_start
@@ -434,12 +477,12 @@ function buildClaudeContentWithToolCallsStreamEvents(
message: {
id: msgId,
type: "message",
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content: [],
- model,
+ model: effectiveModel,
stop_reason: null,
stop_sequence: null,
- usage: { input_tokens: 0, output_tokens: 0 },
+ usage: claudeUsage(overrides),
},
});
@@ -539,8 +582,11 @@ function buildClaudeContentWithToolCallsStreamEvents(
// message_delta
events.push({
type: "message_delta",
- delta: { stop_reason: "tool_use", stop_sequence: null },
- usage: { output_tokens: 0 },
+ delta: {
+ stop_reason: claudeStopReason(overrides?.finishReason, "tool_use"),
+ stop_sequence: null,
+ },
+ usage: { output_tokens: claudeUsage(overrides).output_tokens },
});
// message_stop
@@ -555,6 +601,7 @@ function buildClaudeContentWithToolCallsResponse(
model: string,
logger: Logger,
reasoning?: string,
+ overrides?: ResponseOverrides,
): object {
const contentBlocks: object[] = [];
@@ -583,14 +630,14 @@ function buildClaudeContentWithToolCallsResponse(
}
return {
- id: generateMessageId(),
+ id: overrides?.id ?? generateMessageId(),
type: "message",
- role: "assistant",
+ role: overrides?.role ?? "assistant",
content: contentBlocks,
- model,
- stop_reason: "tool_use",
+ model: overrides?.model ?? model,
+ stop_reason: claudeStopReason(overrides?.finishReason, "tool_use"),
stop_sequence: null,
- usage: { input_tokens: 0, output_tokens: 0 },
+ usage: claudeUsage(overrides),
};
}
@@ -791,6 +838,12 @@ export async function handleMessages(
// Content + tool calls response (must be checked before text/tool-only branches)
if (isContentWithToolCallsResponse(response)) {
+ if (response.webSearches?.length) {
+ logger.warn(
+ "webSearches in fixture response are not supported for Claude Messages API — ignoring",
+ );
+ }
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? "/v1/messages",
@@ -805,6 +858,7 @@ export async function handleMessages(
completionReq.model,
logger,
response.reasoning,
+ overrides,
);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
@@ -816,6 +870,7 @@ export async function handleMessages(
chunkSize,
logger,
response.reasoning,
+ overrides,
);
const interruption = createInterruptionSignal(fixture);
const completed = await writeClaudeSSEStream(res, events, {
@@ -841,6 +896,7 @@ export async function handleMessages(
"webSearches in fixture response are not supported for Claude Messages API — ignoring",
);
}
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? "/v1/messages",
@@ -853,6 +909,7 @@ export async function handleMessages(
response.content,
completionReq.model,
response.reasoning,
+ overrides,
);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
@@ -862,6 +919,7 @@ export async function handleMessages(
completionReq.model,
chunkSize,
response.reasoning,
+ overrides,
);
const interruption = createInterruptionSignal(fixture);
const completed = await writeClaudeSSEStream(res, events, {
@@ -882,6 +940,7 @@ export async function handleMessages(
// Tool call response
if (isToolCallResponse(response)) {
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? "/v1/messages",
@@ -890,7 +949,12 @@ export async function handleMessages(
response: { status: 200, fixture },
});
if (claudeReq.stream !== true) {
- const body = buildClaudeToolCallResponse(response.toolCalls, completionReq.model, logger);
+ const body = buildClaudeToolCallResponse(
+ response.toolCalls,
+ completionReq.model,
+ logger,
+ overrides,
+ );
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
} else {
@@ -899,6 +963,7 @@ export async function handleMessages(
completionReq.model,
chunkSize,
logger,
+ overrides,
);
const interruption = createInterruptionSignal(fixture);
const completed = await writeClaudeSSEStream(res, events, {
diff --git a/src/responses.ts b/src/responses.ts
index 7d6946e..72f6ec5 100644
--- a/src/responses.ts
+++ b/src/responses.ts
@@ -12,6 +12,7 @@ import type {
ChatMessage,
Fixture,
HandlerDefaults,
+ ResponseOverrides,
StreamingProfile,
ToolCall,
ToolDefinition,
@@ -19,6 +20,7 @@ import type {
import {
generateId,
generateToolCallId,
+ extractOverrides,
isTextResponse,
isToolCallResponse,
isContentWithToolCallsResponse,
@@ -148,6 +150,30 @@ export function responsesToCompletionRequest(req: ResponsesRequest): ChatComplet
// ─── Response building: fixture → Responses API format ──────────────────────
+function responsesStatus(finishReason: string | undefined, defaultStatus: string): string {
+ if (!finishReason) return defaultStatus;
+ if (finishReason === "stop") return "completed";
+ if (finishReason === "tool_calls") return "completed";
+ if (finishReason === "length") return "incomplete";
+ if (finishReason === "content_filter") return "failed";
+ return finishReason;
+}
+
+function responsesUsage(overrides?: ResponseOverrides): {
+ input_tokens: number;
+ output_tokens: number;
+ total_tokens: number;
+} {
+ if (!overrides?.usage) return { input_tokens: 0, output_tokens: 0, total_tokens: 0 };
+ return {
+ input_tokens: overrides.usage.input_tokens ?? 0,
+ output_tokens: overrides.usage.output_tokens ?? 0,
+ total_tokens:
+ overrides.usage.total_tokens ??
+ (overrides.usage.input_tokens ?? 0) + (overrides.usage.output_tokens ?? 0),
+ };
+}
+
function responseId(): string {
return generateId("resp");
}
@@ -169,12 +195,14 @@ export function buildTextStreamEvents(
chunkSize: number,
reasoning?: string,
webSearches?: string[],
+ overrides?: ResponseOverrides,
): ResponsesSSEEvent[] {
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(
model,
chunkSize,
reasoning,
webSearches,
+ overrides,
);
const { events: msgEvents, msgItem } = buildMessageOutputEvents(
@@ -190,10 +218,10 @@ export function buildTextStreamEvents(
id: respId,
object: "response",
created_at: created,
- model,
- status: "completed",
+ model: overrides?.model ?? model,
+ status: responsesStatus(overrides?.finishReason, "completed"),
output: [...prefixOutputItems, msgItem],
- usage: { input_tokens: 0, output_tokens: 0, total_tokens: 0 },
+ usage: responsesUsage(overrides),
},
});
@@ -204,9 +232,11 @@ export function buildToolCallStreamEvents(
toolCalls: ToolCall[],
model: string,
chunkSize: number,
+ overrides?: ResponseOverrides,
): ResponsesSSEEvent[] {
- const respId = responseId();
- const created = Math.floor(Date.now() / 1000);
+ const respId = overrides?.id ?? responseId();
+ const created = overrides?.created ?? Math.floor(Date.now() / 1000);
+ const effectiveModel = overrides?.model ?? model;
const events: ResponsesSSEEvent[] = [];
// response.created
@@ -216,7 +246,7 @@ export function buildToolCallStreamEvents(
id: respId,
object: "response",
created_at: created,
- model,
+ model: effectiveModel,
status: "in_progress",
output: [],
},
@@ -228,7 +258,7 @@ export function buildToolCallStreamEvents(
id: respId,
object: "response",
created_at: created,
- model,
+ model: effectiveModel,
status: "in_progress",
output: [],
},
@@ -300,14 +330,10 @@ export function buildToolCallStreamEvents(
id: respId,
object: "response",
created_at: created,
- model,
- status: "completed",
+ model: effectiveModel,
+ status: responsesStatus(overrides?.finishReason, "completed"),
output: outputItems,
- usage: {
- input_tokens: 0,
- output_tokens: 0,
- total_tokens: 0,
- },
+ usage: responsesUsage(overrides),
},
});
@@ -428,9 +454,11 @@ function buildResponsePreamble(
chunkSize: number,
reasoning?: string,
webSearches?: string[],
+ overrides?: ResponseOverrides,
): PreambleResult {
- const respId = responseId();
- const created = Math.floor(Date.now() / 1000);
+ const respId = overrides?.id ?? responseId();
+ const created = overrides?.created ?? Math.floor(Date.now() / 1000);
+ const effectiveModel = overrides?.model ?? model;
const events: ResponsesSSEEvent[] = [];
const prefixOutputItems: object[] = [];
let nextOutputIndex = 0;
@@ -441,7 +469,7 @@ function buildResponsePreamble(
id: respId,
object: "response",
created_at: created,
- model,
+ model: effectiveModel,
status: "in_progress",
output: [],
},
@@ -452,7 +480,7 @@ function buildResponsePreamble(
id: respId,
object: "response",
created_at: created,
- model,
+ model: effectiveModel,
status: "in_progress",
output: [],
},
@@ -581,15 +609,19 @@ function buildOutputPrefix(content: string, reasoning?: string, webSearches?: st
return output;
}
-function buildResponseEnvelope(model: string, output: object[]): object {
+function buildResponseEnvelope(
+ model: string,
+ output: object[],
+ overrides?: ResponseOverrides,
+): object {
return {
- id: responseId(),
+ id: overrides?.id ?? responseId(),
object: "response",
- created_at: Math.floor(Date.now() / 1000),
- model,
- status: "completed",
+ created_at: overrides?.created ?? Math.floor(Date.now() / 1000),
+ model: overrides?.model ?? model,
+ status: responsesStatus(overrides?.finishReason, "completed"),
output,
- usage: { input_tokens: 0, output_tokens: 0, total_tokens: 0 },
+ usage: responsesUsage(overrides),
};
}
@@ -598,11 +630,20 @@ function buildTextResponse(
model: string,
reasoning?: string,
webSearches?: string[],
+ overrides?: ResponseOverrides,
): object {
- return buildResponseEnvelope(model, buildOutputPrefix(content, reasoning, webSearches));
+ return buildResponseEnvelope(
+ model,
+ buildOutputPrefix(content, reasoning, webSearches),
+ overrides,
+ );
}
-function buildToolCallResponse(toolCalls: ToolCall[], model: string): object {
+function buildToolCallResponse(
+ toolCalls: ToolCall[],
+ model: string,
+ overrides?: ResponseOverrides,
+): object {
return buildResponseEnvelope(
model,
toolCalls.map((tc) => ({
@@ -613,6 +654,7 @@ function buildToolCallResponse(toolCalls: ToolCall[], model: string): object {
arguments: tc.arguments,
status: "completed",
})),
+ overrides,
);
}
@@ -623,12 +665,14 @@ export function buildContentWithToolCallsStreamEvents(
chunkSize: number,
reasoning?: string,
webSearches?: string[],
+ overrides?: ResponseOverrides,
): ResponsesSSEEvent[] {
const { respId, created, events, prefixOutputItems, nextOutputIndex } = buildResponsePreamble(
model,
chunkSize,
reasoning,
webSearches,
+ overrides,
);
const { events: msgEvents, msgItem } = buildMessageOutputEvents(
@@ -692,10 +736,10 @@ export function buildContentWithToolCallsStreamEvents(
id: respId,
object: "response",
created_at: created,
- model,
- status: "completed",
+ model: overrides?.model ?? model,
+ status: responsesStatus(overrides?.finishReason, "completed"),
output: [...prefixOutputItems, msgItem, ...fcOutputItems],
- usage: { input_tokens: 0, output_tokens: 0, total_tokens: 0 },
+ usage: responsesUsage(overrides),
},
});
@@ -708,6 +752,7 @@ function buildContentWithToolCallsResponse(
model: string,
reasoning?: string,
webSearches?: string[],
+ overrides?: ResponseOverrides,
): object {
const output = buildOutputPrefix(content, reasoning, webSearches);
for (const tc of toolCalls) {
@@ -720,7 +765,7 @@ function buildContentWithToolCallsResponse(
status: "completed",
});
}
- return buildResponseEnvelope(model, output);
+ return buildResponseEnvelope(model, output, overrides);
}
// ─── SSE writer for Responses API ───────────────────────────────────────────
@@ -909,6 +954,7 @@ export async function handleResponses(
// Combined content + tool calls response
if (isContentWithToolCallsResponse(response)) {
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? "/v1/responses",
@@ -923,6 +969,7 @@ export async function handleResponses(
completionReq.model,
response.reasoning,
response.webSearches,
+ overrides,
);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
@@ -934,6 +981,7 @@ export async function handleResponses(
chunkSize,
response.reasoning,
response.webSearches,
+ overrides,
);
const interruption = createInterruptionSignal(fixture);
const completed = await writeResponsesSSEStream(res, events, {
@@ -954,6 +1002,7 @@ export async function handleResponses(
// Text response
if (isTextResponse(response)) {
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? "/v1/responses",
@@ -967,6 +1016,7 @@ export async function handleResponses(
completionReq.model,
response.reasoning,
response.webSearches,
+ overrides,
);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
@@ -977,6 +1027,7 @@ export async function handleResponses(
chunkSize,
response.reasoning,
response.webSearches,
+ overrides,
);
const interruption = createInterruptionSignal(fixture);
const completed = await writeResponsesSSEStream(res, events, {
@@ -997,6 +1048,7 @@ export async function handleResponses(
// Tool call response
if (isToolCallResponse(response)) {
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? "/v1/responses",
@@ -1005,11 +1057,16 @@ export async function handleResponses(
response: { status: 200, fixture },
});
if (responsesReq.stream !== true) {
- const body = buildToolCallResponse(response.toolCalls, completionReq.model);
+ const body = buildToolCallResponse(response.toolCalls, completionReq.model, overrides);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(body));
} else {
- const events = buildToolCallStreamEvents(response.toolCalls, completionReq.model, chunkSize);
+ const events = buildToolCallStreamEvents(
+ response.toolCalls,
+ completionReq.model,
+ chunkSize,
+ overrides,
+ );
const interruption = createInterruptionSignal(fixture);
const completed = await writeResponsesSSEStream(res, events, {
latency,
diff --git a/src/server.ts b/src/server.ts
index 2337a2b..07083fe 100644
--- a/src/server.ts
+++ b/src/server.ts
@@ -20,6 +20,7 @@ import {
buildToolCallCompletion,
buildContentWithToolCallsChunks,
buildContentWithToolCallsCompletion,
+ extractOverrides,
isTextResponse,
isToolCallResponse,
isContentWithToolCallsResponse,
@@ -510,6 +511,12 @@ async function handleCompletions(
// Content + tool calls response
if (isContentWithToolCallsResponse(response)) {
+ if (response.webSearches?.length) {
+ defaults.logger.warn(
+ "webSearches in fixture response are not supported for Chat Completions API — ignoring",
+ );
+ }
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? COMPLETIONS_PATH,
@@ -522,6 +529,8 @@ async function handleCompletions(
response.content,
response.toolCalls,
body.model,
+ response.reasoning,
+ overrides,
);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(completion));
@@ -531,6 +540,8 @@ async function handleCompletions(
response.toolCalls,
body.model,
chunkSize,
+ response.reasoning,
+ overrides,
);
const interruption = createInterruptionSignal(fixture);
const completed = await writeSSEStream(res, chunks, {
@@ -551,6 +562,12 @@ async function handleCompletions(
// Text response
if (isTextResponse(response)) {
+ if (response.webSearches?.length) {
+ defaults.logger.warn(
+ "webSearches in fixture response are not supported for Chat Completions API — ignoring",
+ );
+ }
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? COMPLETIONS_PATH,
@@ -559,11 +576,22 @@ async function handleCompletions(
response: { status: 200, fixture },
});
if (body.stream !== true) {
- const completion = buildTextCompletion(response.content, body.model, response.reasoning);
+ const completion = buildTextCompletion(
+ response.content,
+ body.model,
+ response.reasoning,
+ overrides,
+ );
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(completion));
} else {
- const chunks = buildTextChunks(response.content, body.model, chunkSize, response.reasoning);
+ const chunks = buildTextChunks(
+ response.content,
+ body.model,
+ chunkSize,
+ response.reasoning,
+ overrides,
+ );
const interruption = createInterruptionSignal(fixture);
const completed = await writeSSEStream(res, chunks, {
latency,
@@ -583,6 +611,7 @@ async function handleCompletions(
// Tool call response
if (isToolCallResponse(response)) {
+ const overrides = extractOverrides(response);
const journalEntry = journal.add({
method: req.method ?? "POST",
path: req.url ?? COMPLETIONS_PATH,
@@ -591,11 +620,11 @@ async function handleCompletions(
response: { status: 200, fixture },
});
if (body.stream !== true) {
- const completion = buildToolCallCompletion(response.toolCalls, body.model);
+ const completion = buildToolCallCompletion(response.toolCalls, body.model, overrides);
res.writeHead(200, { "Content-Type": "application/json" });
res.end(JSON.stringify(completion));
} else {
- const chunks = buildToolCallChunks(response.toolCalls, body.model, chunkSize);
+ const chunks = buildToolCallChunks(response.toolCalls, body.model, chunkSize, overrides);
const interruption = createInterruptionSignal(fixture);
const completed = await writeSSEStream(res, chunks, {
latency,
diff --git a/src/stream-collapse.ts b/src/stream-collapse.ts
index c50e87c..31bad19 100644
--- a/src/stream-collapse.ts
+++ b/src/stream-collapse.ts
@@ -15,9 +15,6 @@ import type { Logger } from "./logger.js";
// Result type shared by all collapse functions
// ---------------------------------------------------------------------------
-// TODO: Consider making this a discriminated union ({ type: "text"; content: string }
-// | { type: "toolCalls"; toolCalls: ToolCall[] } | { type: "empty" }) to prevent
-// ambiguous results and simplify downstream consumers.
export interface CollapseResult {
content?: string;
reasoning?: string;
diff --git a/src/types.ts b/src/types.ts
index 4d8a3f4..488a0c9 100644
--- a/src/types.ts
+++ b/src/types.ts
@@ -77,12 +77,44 @@ export interface FixtureMatch {
// Fixture response types
-export interface TextResponse {
+/**
+ * Fields that override auto-generated envelope values in the built response.
+ * Scalar fields (finishReason, role) use OpenAI-canonical values — provider
+ * handlers translate automatically. For usage, provide field names native to
+ * your target provider (OpenAI Chat: prompt_tokens, completion_tokens;
+ * Responses API: input_tokens, output_tokens; Anthropic: input_tokens,
+ * output_tokens; Gemini: promptTokenCount, candidatesTokenCount).
+ *
+ * When total_tokens (or provider equivalent) is omitted, it is auto-computed
+ * from the component fields.
+ *
+ * Provider support: OpenAI Chat (all 7), Responses API (5: no role,
+ * systemFingerprint), Claude (5: no created, systemFingerprint),
+ * Gemini (2: only finishReason, usage).
+ */
+export interface ResponseOverrides {
+ id?: string;
+ created?: number;
+ model?: string;
+ usage?: {
+ prompt_tokens?: number;
+ completion_tokens?: number;
+ total_tokens?: number;
+ input_tokens?: number;
+ output_tokens?: number;
+ promptTokenCount?: number;
+ candidatesTokenCount?: number;
+ totalTokenCount?: number;
+ };
+ systemFingerprint?: string;
+ finishReason?: string;
+ role?: string;
+}
+
+export interface TextResponse extends ResponseOverrides {
content: string;
reasoning?: string;
webSearches?: string[];
- role?: string;
- finishReason?: string;
}
export interface ToolCall {
@@ -91,18 +123,15 @@ export interface ToolCall {
id?: string;
}
-export interface ToolCallResponse {
+export interface ToolCallResponse extends ResponseOverrides {
toolCalls: ToolCall[];
- finishReason?: string;
}
-export interface ContentWithToolCallsResponse {
+export interface ContentWithToolCallsResponse extends ResponseOverrides {
content: string;
toolCalls: ToolCall[];
reasoning?: string;
webSearches?: string[];
- role?: string;
- finishReason?: string;
}
export interface ErrorResponse {
@@ -192,6 +221,48 @@ export type FixtureOpts = Omit;
export type EmbeddingFixtureOpts = Pick;
// Fixture file format (JSON on disk)
+//
+// File-entry types are intentionally relaxed compared to their runtime
+// counterparts so that fixture authors can write JSON objects where the
+// API ultimately expects a JSON *string*. The fixture loader auto-
+// stringifies these before building the runtime Fixture.
+
+export interface FixtureFileToolCall {
+ name: string;
+ /** Accepts a JSON object or array for convenience — the loader will JSON.stringify it. */
+ arguments: string | Record | unknown[];
+ id?: string;
+}
+
+export interface FixtureFileToolCallResponse extends ResponseOverrides {
+ toolCalls: FixtureFileToolCall[];
+}
+
+export interface FixtureFileTextResponse extends ResponseOverrides {
+ /** Accepts a JSON object or array (structured output) — the loader will JSON.stringify it. */
+ content: string | Record | unknown[];
+ reasoning?: string;
+ webSearches?: string[];
+}
+
+export interface FixtureFileContentWithToolCallsResponse extends ResponseOverrides {
+ /** Accepts a JSON object or array (structured output) — the loader will JSON.stringify it. */
+ content: string | Record | unknown[];
+ toolCalls: FixtureFileToolCall[];
+ reasoning?: string;
+ webSearches?: string[];
+}
+
+export type FixtureFileResponse =
+ | FixtureFileTextResponse
+ | FixtureFileToolCallResponse
+ | FixtureFileContentWithToolCallsResponse
+ | ErrorResponse
+ | EmbeddingResponse
+ | ImageResponse
+ | AudioResponse
+ | TranscriptionResponse
+ | VideoResponse;
export interface FixtureFile {
fixtures: FixtureFileEntry[];
@@ -209,7 +280,7 @@ export interface FixtureFileEntry {
endpoint?: "chat" | "image" | "speech" | "transcription" | "video" | "embedding";
// predicate not supported in JSON files
};
- response: FixtureResponse;
+ response: FixtureFileResponse;
latency?: number;
chunkSize?: number;
truncateAfterChunks?: number;
@@ -245,6 +316,7 @@ export interface SSEChunk {
created: number;
model: string;
choices: SSEChoice[];
+ system_fingerprint?: string;
}
export interface SSEChoice {
@@ -276,6 +348,7 @@ export interface ChatCompletion {
model: string;
choices: ChatCompletionChoice[];
usage: { prompt_tokens: number; completion_tokens: number; total_tokens: number };
+ system_fingerprint?: string;
}
export interface ChatCompletionChoice {
@@ -285,7 +358,7 @@ export interface ChatCompletionChoice {
}
export interface ChatCompletionMessage {
- role: "assistant";
+ role: string;
content: string | null;
refusal: string | null;
reasoning_content?: string;