diff --git a/.changeset/mcp-stores-latest-sdk.md b/.changeset/mcp-stores-latest-sdk.md new file mode 100644 index 0000000..390ecfb --- /dev/null +++ b/.changeset/mcp-stores-latest-sdk.md @@ -0,0 +1,5 @@ +--- +"@mixedbread/mcp": major +--- + +Move to the Stores API on `@mixedbread/sdk` 0.78. Tools are renamed from `vector_store_*` to `store_*` and take `store_identifier(s)`; `store_list` paginates with `after`; `vector_store_file_search` is removed. The server no longer calls the deprecated `/v1/vector_stores` endpoints. diff --git a/packages/mcp/.gitignore b/packages/mcp/.gitignore new file mode 100644 index 0000000..28eb43b --- /dev/null +++ b/packages/mcp/.gitignore @@ -0,0 +1,39 @@ +# deps +/node_modules + +# generated content +.contentlayer +.content-collections +.source + +dist/ + +CLAUDE.md + +# env +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# test & build +/coverage +/.next/ +/out/ +/build +*.tsbuildinfo + +# misc +.DS_Store +*.pem +/.pnp +.pnp.js +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# others +.env*.local +.vercel +next-env.d.ts \ No newline at end of file diff --git a/packages/mcp/CHANGELOG.md b/packages/mcp/CHANGELOG.md new file mode 100644 index 0000000..88b5406 --- /dev/null +++ b/packages/mcp/CHANGELOG.md @@ -0,0 +1,142 @@ +# @mixedbread/mcp + +## 1.1.8 + +### Patch Changes + +- 247014f: Add the return_chunks parameter to the get vs file tool + +## 1.1.7 + +### Patch Changes + +- Update README with comprehensive documentation and fix import ordering + + - Added detailed overview section explaining MCP server capabilities + - Included complete tool descriptions for all 8 available tools + - Enhanced configuration examples for all platforms (macOS, Windows, Linux) + - Added security best practices and API key management guidelines + - Included comprehensive troubleshooting section with common issues + - Added development instructions for building from source + - Improved usage examples with natural language queries + - Added links to relevant documentation and resources + - Restructured content for better readability and user experience + - Fixed import ordering in tool files for consistency + +## 1.1.6 + +### Patch Changes + +- Update SDK dependency and homepage URL + + - Bump @mixedbread/sdk from 0.11.1 to 0.16.0 for latest features and bug fixes + +## 1.1.5 + +### Patch Changes + +- Fix schema parameter usage in implementation and tests + + - Updated tool implementations to use `vector_store_identifier` instead of `vector_store_id` + - Fixed all test assertions to match the new schema parameter names + - Ensures consistency between schema definitions and actual usage + +## 1.1.4 + +### Patch Changes + +- Update README for clarity and fix schema parameter names + + - Simplified README.md with clearer quick start instructions + - Renamed `vector_store_id` to `vector_store_identifier` in schemas for consistency + - Improved documentation structure and removed redundant development sections + - Added -y flag to npx command in Claude Desktop configuration example + +## 1.1.3 + +### Patch Changes + +- Fix MCP package structure for proper npx execution + + - Fixed bin field in package.json to use object notation mapping "mcp" command to dist/index.js + - Updated tsconfig.json to output files directly in dist/ instead of dist/src/ + - This ensures the package works correctly when executed via npx + +## 1.1.2 + +### Patch Changes + +- Fix npx execution by simplifying bin field to direct path + + Changed bin field from object format to string format (following the pattern used by official MCP servers like @modelcontextprotocol/server-filesystem). This ensures npx properly executes the package when running `npx @mixedbread/mcp`. + +## 1.1.1 + +### Patch Changes + +- Fix npx execution by adding "mcp" to bin field in package.json + + The MCP server can now be properly executed with `npx @mixedbread/mcp`. This fixes the Claude Desktop integration issue where the server failed to start. + +## 1.1.0 + +### Minor Changes + +- Fix executable configuration and update environment variable + + **Breaking Change**: Environment variable renamed from `MIXEDBREAD_API_KEY` to `MXBAI_API_KEY` + + - Update all references from MIXEDBREAD_API_KEY to MXBAI_API_KEY for consistency with other Mixedbread tools + - Update README documentation to reflect the new environment variable + + Users need to update their environment configuration: + + - Change `MIXEDBREAD_API_KEY` to `MXBAI_API_KEY` in their environment + - Update Claude Desktop configuration to use `MXBAI_API_KEY` + +## 1.0.4 + +### Patch Changes + +- Fix package executable configuration + + - Add bin field to package.json to make the package executable via npx + - Add shebang to index.ts for proper Node.js execution + - This fixes the "could not determine executable to run" error when using npx @mixedbread/mcp + +## 1.0.3 + +### Patch Changes + +- Rename package from @mixedbread/mcp-server to @mixedbread/mcp for better naming consistency + +## 1.0.2 + +### Patch Changes + +- Updated tests + +## 1.0.1 + +### Patch Changes + +- Fixed test warnings for graceful process exit in integration tests + - Resolved worker process exit warnings by properly cleaning up timeouts and spawned processes + - Added timeout cleanup with unref() to prevent open handles + - Fixed test teardown to prevent Jest warnings about leaking processes + +## 1.0.0 + +### Major Changes + +- Initial release of MCP server in monorepo + + - Migrated from standalone repository to openbread monorepo + - Added proper package.json configuration with scoped naming (@mixedbread/mcp-server) + - Configured TypeScript build system with ESNext modules and strict typing + - Integrated Biome linting and formatting with Node.js import protocol requirements + - Fixed all linting errors and type issues in test files + - Added missing npm scripts for CI/CD (lint, format, check-types, build) + - Updated repository metadata and publishing configuration + - All tests now pass with proper TypeScript strict mode + - Full CI/CD integration with independent versioning support diff --git a/packages/mcp/README.md b/packages/mcp/README.md new file mode 100644 index 0000000..163aa30 --- /dev/null +++ b/packages/mcp/README.md @@ -0,0 +1,238 @@ +# Mixedbread MCP Server + +[![npm version](https://badge.fury.io/js/@mixedbread%2Fmcp.svg)](https://www.npmjs.com/package/@mixedbread/mcp) +[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0) + +Connect your Mixedbread stores to any MCP-compatible client through the Model Context Protocol. Our MCP allows you to manage and search your store documents in natural language. Reduce your search time and improve your code output quality through rag in coding agents like claude code and cursor. + +## Overview + +The Mixedbread MCP Server allows you to: +- Create and manage stores for your documents +- Upload and process files with automated chunking and embedding +- Retrieve specific files and their contents +- Build AI-native search experiences directly in any MCP-Client + +## Available Tools + +### `store_create` +Create a new store to organize your documents. +- **Input**: Store name +- **Returns**: Store details + +### `store_list` +List all stores in your account. +- **Input**: Optional search query to filter stores. +- **Returns**: Array of stores with metadata + +### `store_retrieve` +Get detailed information about a specific store. +- **Input**: Store ID +- **Returns**: Store details including file count and settings + +### `store_delete` +Delete a store and all its contents. +- **Input**: Store ID +- **Returns**: Deletion confirmation + +### `store_upload` +Upload files to a store for processing and indexing. +- **Input**: Store ID, file paths +- **Returns**: Upload status and processed file information + +### `store_search` +Search for specific chunks within a store. +- **Input**: Store ID, search query, optional filters +- **Returns**: Relevant file chunks, scores, metadata + +### `store_file_retrieve` +Retrieve details about a specific file in a store. +- **Input**: Store ID, file ID +- **Returns**: File metadata and content access + +## Prerequisites + +- **Node.js**: Version 20 or higher +- **Mixedbread API Key**: Get yours at [platform.mixedbread.com](https://www.platform.mixedbread.com/platform?next=/api-keys) +- **MCP Client**: Claude Desktop or another MCP-compatible client +- **Optional**: `@modelcontextprotocol/server-filesystem` for local file uploads + +## Installation + +### NPM Global Install (Recommended) + +```bash +npm install -g @mixedbread/mcp +``` + +### Test Installation + +```bash +npx @mixedbread/mcp +``` + +You should see the MCP server start message if installed correctly. + +## Configuration + +### Claude Desktop Setup + +1. Open your Claude Desktop configuration file: + - **macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json` + - **Windows**: `%APPDATA%\Claude\claude_desktop_config.json` + - **Linux**: `~/.config/Claude/claude_desktop_config.json` + +2. Add the Mixedbread MCP server configuration: + +```json +{ + "mcpServers": { + "mixedbread": { + "command": "npx", + "args": ["-y", "@mixedbread/mcp"], + "env": { + "MXBAI_API_KEY": "mxb_your_api_key_here" + } + } + } +} +``` + +### With Filesystem Server (for file uploads) + +To upload local files, also configure the filesystem MCP server: + +```json +{ + "mcpServers": { + "mixedbread": { + "command": "npx", + "args": ["-y", "@mixedbread/mcp"], + "env": { + "MXBAI_API_KEY": "mxb_your_api_key_here" + } + }, + "filesystem": { + "command": "npx", + "args": [ + "-y", + "@modelcontextprotocol/server-filesystem", + "/path/to/your/documents" + ] + } + } +} +``` + +### Environment Variables + +- `MXBAI_API_KEY`: Your Mixedbread API key (required) + +## Usage Examples + +Once configured, you can interact with your stores using natural language in Claude Desktop: + +### Creating a Store +``` +"Create a new store called 'Product Documentation'" +``` + +### Uploading Documents +``` +"Upload all markdown files from the docs folder to my Product Documentation store" +``` + +### Searching Content +``` +"Search for information about authentication in the Product Documentation store" +``` + +### Managing Stores +``` +"List all my stores" +``` + +### Advanced Queries +``` +"Find all files in the Product Documentation store that mention API endpoints" +``` + +## Development + +### Building from Source + +```bash +# Clone the repository +git clone https://github.com/mixedbread-ai/openbread.git +cd openbread/packages/mcp + +# Install dependencies +npm install + +# Build the server +npm run build + +# Run in development mode +npm run dev +``` + +### Running Tests + +```bash +# Run all tests +npm test + +# Run with coverage +npm run test:coverage + +# Watch mode for development +npm run test:watch +``` + +## Security + +### API Key Management +- Store API keys securely in environment variables +- Never commit API keys to version control +- Use separate API keys for development and production +- Rotate keys regularly + +## Troubleshooting + +### Common Issues + +#### "API key not found" error +- Verify your API key starts with `mxb_` +- Check the key is correctly set in Claude Desktop config +- Ensure there are no extra spaces or quotes around the key + +#### "Cannot connect to Mixedbread API" +- Check your internet connection +- Verify the API endpoint is accessible +- Ensure your firewall allows outbound HTTPS connections + +#### "File upload failed" +- Confirm the filesystem MCP server is configured +- Check file paths are within allowed directories + +#### Tools not appearing in Claude +- Restart Claude Desktop after configuration changes +- Check the MCP server is running (test with `npx @mixedbread/mcp`) +- Review Claude Desktop logs for errors + +## Links & Resources + +- **Mixedbread Documentation**: [mixedbread.com/docs](https://www.mixedbread.com/docs) +- **MCP Documentation**: [mixedbread.com/mcp](https://www.mixedbread.com/mcp) +- **API Reference**: [mixedbread.com/api-reference](https://www.mixedbread.com/api-reference) +- **Model Context Protocol**: [modelcontextprotocol.io](https://modelcontextprotocol.io) +- **GitHub Issues**: [github.com/mixedbread-ai/openbread/issues](https://github.com/mixedbread-ai/openbread/issues) +- **Support**: support@mixedbread.com + +## License + +This project is licensed under the [Apache License 2.0](https://opensource.org/licenses/Apache-2.0). + +--- + +🍞 Baked with love by [Mixedbread](https://www.mixedbread.com/) \ No newline at end of file diff --git a/packages/mcp/jest.config.ts b/packages/mcp/jest.config.ts new file mode 100644 index 0000000..a4a1c79 --- /dev/null +++ b/packages/mcp/jest.config.ts @@ -0,0 +1,28 @@ +import type { JestConfigWithTsJest } from "ts-jest"; + +const config: JestConfigWithTsJest = { + preset: "ts-jest/presets/default-esm", + testEnvironment: "node", + extensionsToTreatAsEsm: [".ts"], + testMatch: ["/test/**/*.test.ts"], + testPathIgnorePatterns: ["/dist/", "/node_modules/"], + modulePathIgnorePatterns: ["/dist/"], + collectCoverageFrom: ["src/**/*.ts", "!src/**/*.d.ts", "!src/index.ts"], + moduleNameMapper: { + "^@/(.*)$": "/src/$1", + "^(\\.{1,2}/.*)\\.js$": "$1", + }, + transform: { + "^.+\\.ts$": [ + "ts-jest", + { + useESM: true, + }, + ], + }, + testTimeout: 10000, + setupFilesAfterEnv: ["/test/setup.ts"], + coverageReporters: ["text", "html"], +}; + +export default config; diff --git a/packages/mcp/package.json b/packages/mcp/package.json new file mode 100644 index 0000000..d0f9cba --- /dev/null +++ b/packages/mcp/package.json @@ -0,0 +1,68 @@ +{ + "name": "@mixedbread/mcp", + "version": "1.1.8", + "description": "MCP server for the Mixedbread Platform", + "type": "module", + "main": "dist/index.js", + "types": "dist/index.d.ts", + "bin": { + "mcp": "dist/index.js" + }, + "files": [ + "dist", + "README.md" + ], + "engines": { + "node": ">=20" + }, + "publishConfig": { + "access": "public" + }, + "scripts": { + "start": "tsx src/index.ts", + "build": "tsc", + "dev": "tsx src/index.ts", + "clean": "rm -rf dist", + "test": "jest", + "test:watch": "jest --watch", + "test:coverage": "jest --coverage", + "lint": "biome lint --write .", + "format": "biome format --write .", + "check-types": "tsc --noEmit" + }, + "repository": { + "type": "git", + "url": "github:mixedbread-ai/openbread", + "directory": "packages/mcp" + }, + "keywords": [ + "mixedbread", + "mcp", + "model-context-protocol", + "store", + "embeddings" + ], + "author": "Mixedbread ", + "license": "Apache-2.0", + "bugs": { + "url": "https://github.com/mixedbread-ai/openbread/issues" + }, + "homepage": "https://www.mixedbread.com/mcp", + "dependencies": { + "@mixedbread/sdk": "^0.78.0", + "@modelcontextprotocol/sdk": "^1.13.0", + "mime-types": "^3.0.1", + "zod": "^3.25.67", + "zod-to-json-schema": "^3.24.5" + }, + "devDependencies": { + "@jest/globals": "^30.0.2", + "@types/jest": "^29.5.14", + "@types/mime-types": "^3.0.1", + "@types/node": "^24.0.3", + "jest": "^29.5.0", + "ts-jest": "^29.1.0", + "tsx": "^4.20.3", + "typescript": "^5.8.3" + } +} diff --git a/packages/mcp/src/index.ts b/packages/mcp/src/index.ts new file mode 100644 index 0000000..6887762 --- /dev/null +++ b/packages/mcp/src/index.ts @@ -0,0 +1,152 @@ +#!/usr/bin/env node +import { Server } from "@modelcontextprotocol/sdk/server/index.js"; +import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"; +import { + CallToolRequestSchema, + ListToolsRequestSchema, +} from "@modelcontextprotocol/sdk/types.js"; +import { zodToJsonSchema } from "zod-to-json-schema"; +import { storeCreate } from "./tools/store-create.js"; +import { storeDelete } from "./tools/store-delete.js"; +import { storeFileRetrieve } from "./tools/store-file-retrieve.js"; +import { storeList } from "./tools/store-list.js"; +import { storeRetrieve } from "./tools/store-retrieve.js"; +import { storeSearch } from "./tools/store-search.js"; +import { storeUpload } from "./tools/store-upload.js"; +import { + StoreCreateSchema, + StoreDeleteSchema, + StoreFileRetrieveSchema, + StoreListSchema, + StoreRetrieveSchema, + StoreSearchSchema, + StoreUploadSchema, +} from "./types/index.js"; + +const server = new Server( + { + name: "mixedbread-mcp-server", + version: "1.0.0", + }, + { + capabilities: { + tools: {}, + }, + } +); + +// List available tools +server.setRequestHandler(ListToolsRequestSchema, async () => { + return { + tools: [ + { + name: "store_search", + description: + "Search for chunks within stores based on their relevance to the query", + inputSchema: zodToJsonSchema(StoreSearchSchema), + }, + { + name: "store_retrieve", + description: "Retrieve detailed information about a specific store", + inputSchema: zodToJsonSchema(StoreRetrieveSchema), + }, + { + name: "store_list", + description: "List all stores", + inputSchema: zodToJsonSchema(StoreListSchema), + }, + { + name: "store_create", + description: "Create a new store", + inputSchema: zodToJsonSchema(StoreCreateSchema), + }, + { + name: "store_delete", + description: "Delete a store", + inputSchema: zodToJsonSchema(StoreDeleteSchema), + }, + { + name: "store_upload", + description: "Upload a file to a store", + inputSchema: zodToJsonSchema(StoreUploadSchema), + }, + { + name: "store_file_retrieve", + description: + "Retrieve detailed information about a specific file in a store", + inputSchema: zodToJsonSchema(StoreFileRetrieveSchema), + }, + ], + }; +}); + +// Handle tool calls +server.setRequestHandler(CallToolRequestSchema, async (request) => { + try { + const { name, arguments: args } = request.params; + + switch (name) { + case "store_search": { + const validatedArgs = StoreSearchSchema.parse(args); + return await storeSearch(validatedArgs); + } + + case "store_retrieve": { + const validatedArgs = StoreRetrieveSchema.parse(args); + return await storeRetrieve(validatedArgs); + } + + case "store_list": { + const validatedArgs = StoreListSchema.parse(args); + return await storeList(validatedArgs); + } + + case "store_create": { + const validatedArgs = StoreCreateSchema.parse(args); + return await storeCreate(validatedArgs); + } + + case "store_delete": { + const validatedArgs = StoreDeleteSchema.parse(args); + return await storeDelete(validatedArgs); + } + + case "store_upload": { + const validatedArgs = StoreUploadSchema.parse(args); + return await storeUpload(validatedArgs); + } + + case "store_file_retrieve": { + const validatedArgs = StoreFileRetrieveSchema.parse(args); + return await storeFileRetrieve(validatedArgs); + } + + default: + throw new Error(`Unknown tool: ${name}`); + } + } catch (error) { + return { + content: [ + { + type: "text", + text: `Error: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +}); + +// Start the server +async function main() { + const transport = new StdioServerTransport(); + await server.connect(transport); + console.error("Mixedbread MCP server running on stdio"); +} + +main().catch((error) => { + console.error("Server error:", error); + process.exit(1); +}); diff --git a/packages/mcp/src/tools/store-create.ts b/packages/mcp/src/tools/store-create.ts new file mode 100644 index 0000000..384be43 --- /dev/null +++ b/packages/mcp/src/tools/store-create.ts @@ -0,0 +1,31 @@ +import type { StoreCreateInput } from "../types/index.js"; +import { getMixedbreadClient } from "../utils.js"; + +export async function storeCreate(args: StoreCreateInput) { + const client = getMixedbreadClient(); + + try { + const response = await client.stores.create(args); + + return { + content: [ + { + type: "text" as const, + text: JSON.stringify(response, null, 2), + }, + ], + }; + } catch (error) { + return { + content: [ + { + type: "text" as const, + text: `Error creating store: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +} diff --git a/packages/mcp/src/tools/store-delete.ts b/packages/mcp/src/tools/store-delete.ts new file mode 100644 index 0000000..c95b284 --- /dev/null +++ b/packages/mcp/src/tools/store-delete.ts @@ -0,0 +1,31 @@ +import type { StoreDeleteInput } from "../types/index.js"; +import { getMixedbreadClient } from "../utils.js"; + +export async function storeDelete(args: StoreDeleteInput) { + const client = getMixedbreadClient(); + + try { + const response = await client.stores.delete(args.store_identifier); + + return { + content: [ + { + type: "text" as const, + text: JSON.stringify(response, null, 2), + }, + ], + }; + } catch (error) { + return { + content: [ + { + type: "text" as const, + text: `Error deleting store: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +} diff --git a/packages/mcp/src/tools/store-file-retrieve.ts b/packages/mcp/src/tools/store-file-retrieve.ts new file mode 100644 index 0000000..dcd77a4 --- /dev/null +++ b/packages/mcp/src/tools/store-file-retrieve.ts @@ -0,0 +1,34 @@ +import type { StoreFileRetrieveInput } from "../types/index.js"; +import { getMixedbreadClient } from "../utils.js"; + +export async function storeFileRetrieve(args: StoreFileRetrieveInput) { + const client = getMixedbreadClient(); + + try { + const response = await client.stores.files.retrieve(args.file_id, { + store_identifier: args.store_identifier, + return_chunks: args.return_chunks ?? true, + }); + + return { + content: [ + { + type: "text" as const, + text: JSON.stringify(response, null, 2), + }, + ], + }; + } catch (error) { + return { + content: [ + { + type: "text" as const, + text: `Error retrieving file: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +} diff --git a/packages/mcp/src/tools/store-list.ts b/packages/mcp/src/tools/store-list.ts new file mode 100644 index 0000000..731f2bb --- /dev/null +++ b/packages/mcp/src/tools/store-list.ts @@ -0,0 +1,32 @@ +import type { StoreListInput } from "../types/index.js"; +import { getMixedbreadClient } from "../utils.js"; + +export async function storeList(args: StoreListInput) { + const client = getMixedbreadClient(); + + try { + const page = await client.stores.list(args); + const response = { data: page.data, pagination: page.pagination }; + + return { + content: [ + { + type: "text" as const, + text: JSON.stringify(response, null, 2), + }, + ], + }; + } catch (error) { + return { + content: [ + { + type: "text" as const, + text: `Error listing stores: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +} diff --git a/packages/mcp/src/tools/store-retrieve.ts b/packages/mcp/src/tools/store-retrieve.ts new file mode 100644 index 0000000..94c5d32 --- /dev/null +++ b/packages/mcp/src/tools/store-retrieve.ts @@ -0,0 +1,31 @@ +import type { StoreRetrieveInput } from "../types/index.js"; +import { getMixedbreadClient } from "../utils.js"; + +export async function storeRetrieve(args: StoreRetrieveInput) { + const client = getMixedbreadClient(); + + try { + const response = await client.stores.retrieve(args.store_identifier); + + return { + content: [ + { + type: "text" as const, + text: JSON.stringify(response, null, 2), + }, + ], + }; + } catch (error) { + return { + content: [ + { + type: "text" as const, + text: `Error retrieving store: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +} diff --git a/packages/mcp/src/tools/store-search.ts b/packages/mcp/src/tools/store-search.ts new file mode 100644 index 0000000..fa8992b --- /dev/null +++ b/packages/mcp/src/tools/store-search.ts @@ -0,0 +1,31 @@ +import type { StoreSearchInput } from "../types/index.js"; +import { getMixedbreadClient } from "../utils.js"; + +export async function storeSearch(args: StoreSearchInput) { + const mxbai = getMixedbreadClient(); + + try { + const response = await mxbai.stores.search(args); + + return { + content: [ + { + type: "text" as const, + text: JSON.stringify(response, null, 2), + }, + ], + }; + } catch (error) { + return { + content: [ + { + type: "text" as const, + text: `Error searching store: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +} diff --git a/packages/mcp/src/tools/store-upload.ts b/packages/mcp/src/tools/store-upload.ts new file mode 100644 index 0000000..8044ab0 --- /dev/null +++ b/packages/mcp/src/tools/store-upload.ts @@ -0,0 +1,67 @@ +import { readFile } from "node:fs/promises"; +import { basename } from "node:path"; +import { toFile } from "@mixedbread/sdk"; +import { lookup } from "mime-types"; +import type { StoreUploadInput } from "../types/index.js"; +import { getMixedbreadClient } from "../utils.js"; + +const SUPPORTED_MIME_TYPES = [ + "application/pdf", + "text/plain", + "text/markdown", + "image/png", + "image/jpeg", + "image/jpg", + "image/webp", + "application/vnd.ms-powerpoint", + "application/vnd.openxmlformats-officedocument.presentationml.presentation", + "application/vnd.openxmlformats-officedocument.presentationml.slideshow", + "application/vnd.ms-powerpoint.addin.macroEnabled.12", + "application/vnd.ms-powerpoint.presentation.macroEnabled.12", + "application/vnd.ms-powerpoint.template.macroEnabled.12", + "application/vnd.ms-powerpoint.slideshow.macroEnabled.12", + "application/vnd.oasis.opendocument.presentation", +] as const; + +export async function storeUpload(args: StoreUploadInput) { + const client = getMixedbreadClient(); + + try { + const fileBuffer = await readFile(args.file_path); + const filename = args.filename || basename(args.file_path); + const mimeType = args.mime_type || lookup(args.file_path); + + if (!mimeType) { + throw new Error( + `Could not determine MIME type for file: ${filename}. Supported types: ${SUPPORTED_MIME_TYPES.join(", ")}` + ); + } + + const file = await toFile(fileBuffer, filename, { type: mimeType }); + const response = await client.stores.files.upload({ + storeIdentifier: args.store_identifier, + file, + }); + + return { + content: [ + { + type: "text" as const, + text: JSON.stringify(response, null, 2), + }, + ], + }; + } catch (error) { + return { + content: [ + { + type: "text" as const, + text: `Error uploading file: ${ + error instanceof Error ? error.message : String(error) + }`, + }, + ], + isError: true, + }; + } +} diff --git a/packages/mcp/src/types/index.ts b/packages/mcp/src/types/index.ts new file mode 100644 index 0000000..54c135c --- /dev/null +++ b/packages/mcp/src/types/index.ts @@ -0,0 +1 @@ +export * from "./schemas.js"; diff --git a/packages/mcp/src/types/schemas.ts b/packages/mcp/src/types/schemas.ts new file mode 100644 index 0000000..9e5a725 --- /dev/null +++ b/packages/mcp/src/types/schemas.ts @@ -0,0 +1,111 @@ +import { z } from "zod"; + +// Store Search Schema +export const StoreSearchSchema = z.object({ + query: z.string().describe("The search query text"), + store_identifiers: z + .array(z.string().min(1)) + .min(1) + .describe("Array of store identifiers to search in"), + top_k: z + .number() + .int() + .positive() + .default(5) + .describe("Number of top results to return"), + filters: z + .any() + .optional() + .describe("Optional filters to apply to the search"), + file_ids: z + .array(z.string()) + .optional() + .describe("Optional file IDs to search within"), + search_options: z + .any() + .optional() + .describe("Additional search configuration options"), +}); + +// Store Retrieve Schema +export const StoreRetrieveSchema = z.object({ + store_identifier: z + .string() + .min(1) + .describe("The identifier of the store to retrieve"), +}); + +// Store List Schema +export const StoreListSchema = z.object({ + q: z.string().optional().describe("Search query to filter stores"), + limit: z + .number() + .int() + .positive() + .max(100) + .default(20) + .describe("Maximum number of stores to return"), + after: z + .string() + .optional() + .describe("Cursor from a previous page's pagination.last_cursor"), + include_total: z + .boolean() + .optional() + .describe("Whether to include total count"), +}); + +// Store Create Schema +export const StoreCreateSchema = z.object({ + name: z.string().min(1).describe("Name of the store"), + description: z.string().optional().describe("Optional description"), +}); + +// Store Delete Schema +export const StoreDeleteSchema = z.object({ + store_identifier: z + .string() + .min(1) + .describe("The identifier of the store to delete"), +}); + +// Store Upload Schema +export const StoreUploadSchema = z.object({ + store_identifier: z + .string() + .min(1) + .describe("The identifier of the store to upload to"), + file_path: z + .string() + .min(1) + .describe("Absolute path to the local file to upload"), + filename: z + .string() + .optional() + .describe("Optional custom filename (defaults to basename of file_path)"), + mime_type: z.string().optional().describe("Optional MIME type of the file"), +}); + +// Store File Retrieve Schema +export const StoreFileRetrieveSchema = z.object({ + file_id: z.string().min(1).describe("The ID of the file to retrieve"), + store_identifier: z + .string() + .min(1) + .describe("The identifier of the store containing the file"), + return_chunks: z + .boolean() + .optional() + .describe( + "Whether to return the chunks for the file. This is enabled by default." + ), +}); + +// Inferred types +export type StoreSearchInput = z.infer; +export type StoreRetrieveInput = z.infer; +export type StoreListInput = z.infer; +export type StoreCreateInput = z.infer; +export type StoreDeleteInput = z.infer; +export type StoreUploadInput = z.infer; +export type StoreFileRetrieveInput = z.infer; diff --git a/packages/mcp/src/utils.ts b/packages/mcp/src/utils.ts new file mode 100644 index 0000000..fd359e3 --- /dev/null +++ b/packages/mcp/src/utils.ts @@ -0,0 +1,28 @@ +import { Mixedbread } from "@mixedbread/sdk"; + +export function createMixedbreadClient(): Mixedbread { + const apiKey = process.env.MXBAI_API_KEY; + + if (!apiKey) { + throw new Error("MXBAI_API_KEY environment variable is required"); + } + + return new Mixedbread({ + apiKey: apiKey, + }); +} + +// Create a singleton instance +let mixedbreadClient: Mixedbread | null = null; + +export function getMixedbreadClient(): Mixedbread { + if (!mixedbreadClient) { + mixedbreadClient = createMixedbreadClient(); + } + return mixedbreadClient; +} + +// Export for testing purposes +export function resetMixedbreadClient(): void { + mixedbreadClient = null; +} diff --git a/packages/mcp/test/fixtures/mock-responses.ts b/packages/mcp/test/fixtures/mock-responses.ts new file mode 100644 index 0000000..fc9bda6 --- /dev/null +++ b/packages/mcp/test/fixtures/mock-responses.ts @@ -0,0 +1,70 @@ +export const mockStoreSearchResponse = { + chunks: [ + { + id: "chunk-1", + content: "This is a sample chunk", + score: 0.95, + metadata: { source: "test-file.txt" }, + }, + { + id: "chunk-2", + content: "Another sample chunk", + score: 0.87, + metadata: { source: "test-file.txt" }, + }, + ], + total: 2, +}; + +export const mockStoreRetrieveResponse = { + id: "vs-123", + name: "Test Store", + description: "A test store", + createdAt: "2024-01-01T00:00:00Z", + filesCount: 5, + chunksCount: 150, +}; + +export const mockStoreListResponse = { + data: [ + { + id: "vs-1", + name: "Store 1", + description: "First store", + createdAt: "2024-01-01T00:00:00Z", + }, + { + id: "vs-2", + name: "Store 2", + description: "Second store", + createdAt: "2024-01-02T00:00:00Z", + }, + ], + pagination: { has_more: false, total: 2 }, +}; + +export const mockStoreCreateResponse = { + id: "vs-new", + name: "New Store", + description: "Newly created store", + createdAt: "2024-01-01T00:00:00Z", + filesCount: 0, + chunksCount: 0, +}; + +export const mockStoreUploadResponse = { + id: "file-upload-123", + name: "uploaded-file.txt", + size: 1024, + mimeType: "text/plain", + uploadedAt: "2024-01-01T00:00:00Z", +}; + +export const mockStoreFileRetrieveResponse = { + id: "file-123", + name: "test-file.txt", + size: 2048, + mimeType: "text/plain", + uploadedAt: "2024-01-01T00:00:00Z", + chunksCount: 10, +}; diff --git a/packages/mcp/test/fixtures/test-files/sample.txt b/packages/mcp/test/fixtures/test-files/sample.txt new file mode 100644 index 0000000..41b7839 --- /dev/null +++ b/packages/mcp/test/fixtures/test-files/sample.txt @@ -0,0 +1,3 @@ +This is a sample text file for testing file uploads. +It contains multiple lines of text to simulate real-world usage. +Vector stores can process this content and create searchable chunks. \ No newline at end of file diff --git a/packages/mcp/test/helpers/mock-client.ts b/packages/mcp/test/helpers/mock-client.ts new file mode 100644 index 0000000..1288c81 --- /dev/null +++ b/packages/mcp/test/helpers/mock-client.ts @@ -0,0 +1,98 @@ +import { jest } from "@jest/globals"; + +interface MockMixedbreadClient { + stores: { + search: ReturnType; + retrieve: ReturnType; + list: ReturnType; + create: ReturnType; + delete: ReturnType; + uploadFile: ReturnType; + files: { + create: ReturnType; + retrieve: ReturnType; + list: ReturnType; + delete: ReturnType; + }; + }; + files: { + create: ReturnType; + retrieve: ReturnType; + list: ReturnType; + delete: ReturnType; + }; + embeddings: { + create: ReturnType; + }; +} + +/** + * Create a mock Mixedbread SDK client with common methods + */ +export function createMockMixedbreadClient(): MockMixedbreadClient { + return { + stores: { + search: jest.fn(), + retrieve: jest.fn(), + list: jest.fn(), + create: jest.fn(), + delete: jest.fn(), + uploadFile: jest.fn(), + files: { + create: jest.fn(), + retrieve: jest.fn(), + list: jest.fn(), + delete: jest.fn(), + }, + }, + files: { + create: jest.fn(), + retrieve: jest.fn(), + list: jest.fn(), + delete: jest.fn(), + }, + embeddings: { + create: jest.fn(), + }, + }; +} + +export const mockMixedbreadClient: MockMixedbreadClient = + createMockMixedbreadClient(); + +export const resetAllMocks = () => { + // Reset store mocks + const storeMocks = [ + mockMixedbreadClient.stores.search, + mockMixedbreadClient.stores.retrieve, + mockMixedbreadClient.stores.list, + mockMixedbreadClient.stores.create, + mockMixedbreadClient.stores.delete, + mockMixedbreadClient.stores.uploadFile, + ]; + + storeMocks.forEach((mock) => mock.mockReset()); + + // Reset nested file mocks + const storeFileMocks = [ + mockMixedbreadClient.stores.files.create, + mockMixedbreadClient.stores.files.retrieve, + mockMixedbreadClient.stores.files.list, + mockMixedbreadClient.stores.files.delete, + ]; + + storeFileMocks.forEach((mock) => mock.mockReset()); + + // Reset top-level file mocks + const fileMocks = [ + mockMixedbreadClient.files.create, + mockMixedbreadClient.files.retrieve, + mockMixedbreadClient.files.list, + mockMixedbreadClient.files.delete, + ]; + + fileMocks.forEach((mock) => mock.mockReset()); + + // Reset embeddings mocks + mockMixedbreadClient.embeddings.create.mockReset(); +}; diff --git a/packages/mcp/test/helpers/test-utils.ts b/packages/mcp/test/helpers/test-utils.ts new file mode 100644 index 0000000..5f38341 --- /dev/null +++ b/packages/mcp/test/helpers/test-utils.ts @@ -0,0 +1,46 @@ +interface MCPRequest { + jsonrpc: "2.0"; + id: number; + method: string; + params: Record; +} + +export const createMCPRequest = ( + method: string, + params: Record, + id = 1 +): MCPRequest => ({ + jsonrpc: "2.0" as const, + id, + method, + params, +}); + +export const createMCPToolCall = ( + name: string, + args: Record, + id = 1 +) => createMCPRequest("tools/call", { name, arguments: args }, id); + +export const createMCPListToolsRequest = (id = 1): MCPRequest => + createMCPRequest("tools/list", {}, id); + +interface MCPResponse { + content: Array<{ type: string; text: string }>; + isError?: boolean; +} + +export const expectMCPResponse = (response: MCPResponse) => { + expect(response).toHaveProperty("content"); + expect(Array.isArray(response.content)).toBe(true); + expect(response.content.length).toBeGreaterThan(0); + expect(response.content[0]).toHaveProperty("type", "text"); + expect(response.content[0]).toHaveProperty("text"); +}; + +export const expectMCPError = (response: MCPResponse) => { + expect(response).toHaveProperty("content"); + expect(response).toHaveProperty("isError", true); + expect(response.content[0]).toHaveProperty("type", "text"); + expect(response.content[0]).toHaveProperty("text"); +}; diff --git a/packages/mcp/test/integration/mcp-protocol.test.ts b/packages/mcp/test/integration/mcp-protocol.test.ts new file mode 100644 index 0000000..be05e98 --- /dev/null +++ b/packages/mcp/test/integration/mcp-protocol.test.ts @@ -0,0 +1,78 @@ +import { + createMCPListToolsRequest, + createMCPToolCall, +} from "../helpers/test-utils.js"; + +jest.mock("../../src/utils.js", () => ({ + getMixedbreadClient: jest.fn(() => ({ + stores: { + search: jest.fn().mockResolvedValue({ chunks: [], total: 0 }), + list: jest.fn().mockResolvedValue({ data: [], pagination: {} }), + }, + })), +})); + +describe("MCP Protocol Compliance", () => { + describe("Tool Registration", () => { + it("should register all expected tools", () => { + const expectedTools = [ + "store_search", + "store_retrieve", + "store_list", + "store_create", + "store_delete", + "store_upload", + "store_file_retrieve", + ]; + + expect(expectedTools).toHaveLength(7); + expect(expectedTools).toContain("store_search"); + expect(expectedTools).toContain("store_list"); + }); + }); + + describe("Request/Response Format", () => { + it("should handle valid MCP requests", () => { + const request = createMCPToolCall("store_search", { + query: "test", + store_identifiers: ["store1"], + top_k: 5, + }); + + expect(request.jsonrpc).toBe("2.0"); + expect(request.method).toBe("tools/call"); + expect(request.params.name).toBe("store_search"); + expect(request.params.arguments).toEqual({ + query: "test", + store_identifiers: ["store1"], + top_k: 5, + }); + }); + + it("should format list tools request correctly", () => { + const request = createMCPListToolsRequest(); + + expect(request.jsonrpc).toBe("2.0"); + expect(request.method).toBe("tools/list"); + expect(request.params).toEqual({}); + }); + }); + + describe("Error Handling", () => { + it("should return proper error format for invalid tool calls", () => { + const errorResponse = { + content: [ + { + type: "text" as const, + text: "Error: Unknown tool: invalid_tool", + }, + ], + isError: true, + }; + + expect(errorResponse.isError).toBe(true); + expect(errorResponse.content[0].type).toBe("text"); + expect(errorResponse.content[0].text).toContain("Error"); + }); + }); +}); diff --git a/packages/mcp/test/integration/server.test.ts b/packages/mcp/test/integration/server.test.ts new file mode 100644 index 0000000..ce3b8fe --- /dev/null +++ b/packages/mcp/test/integration/server.test.ts @@ -0,0 +1,113 @@ +import { spawn } from "node:child_process"; +import { + createMCPListToolsRequest, + createMCPToolCall, +} from "../helpers/test-utils.js"; + +describe("Server Integration", () => { + const timeout = 10000; + + const createServerTest = ( + apiKey: string, + requestFn: () => object, + assertionFn: (response: Record) => boolean, + expectationFn: (response: Record) => void + ) => { + return (done: jest.DoneCallback) => { + const server = spawn("npm", ["start"], { + stdio: ["pipe", "pipe", "pipe"], + env: { ...process.env, MXBAI_API_KEY: apiKey }, + }); + + let buffer = ""; + let timeoutId: NodeJS.Timeout; + + const cleanup = () => { + if (timeoutId) { + clearTimeout(timeoutId); + } + if (!server.killed) { + server.kill("SIGKILL"); + } + server.removeAllListeners(); + }; + + const handleData = (data: Buffer) => { + buffer += data.toString(); + const lines = buffer.split("\n"); + buffer = lines.pop() || ""; + + for (const line of lines) { + if (!line.trim()) continue; + try { + const response = JSON.parse(line) as Record; + if (assertionFn(response)) { + expectationFn(response); + cleanup(); + done(); + return; + } + } catch { + // Not JSON, ignore + } + } + }; + + const handleReady = (data: Buffer) => { + if (data.toString().includes("Mixedbread MCP server running")) { + server.stdin?.write(`${JSON.stringify(requestFn())}\n`); + } + }; + + server.stdout?.on("data", handleData); + server.stderr?.on("data", handleReady); + server.on("error", (error) => { + cleanup(); + done(error); + }); + server.on("close", () => { + server.removeAllListeners(); + }); + + timeoutId = setTimeout(() => { + cleanup(); + done(new Error("Test timeout")); + }, timeout); + timeoutId.unref(); + }; + }; + + it( + "should start server and respond to list tools request", + createServerTest( + "test-key", + () => createMCPListToolsRequest(), + (response) => response.id === 1 && !!response.result, + (response) => { + const result = response.result as Record; + const tools = result.tools as unknown[]; + expect(tools).toHaveLength(7); + expect(tools[0]).toHaveProperty("name"); + expect(tools[0]).toHaveProperty("description"); + expect(tools[0]).toHaveProperty("inputSchema"); + } + ), + timeout + ); + + it( + "should handle tool call with error when API key is invalid", + createServerTest( + "invalid-key", + () => createMCPToolCall("store_list", { limit: 10 }, 2), + (response) => response.id === 2 && !!response.result, + (response) => { + const result = response.result as Record; + const content = result.content as Record[]; + expect(result.isError).toBe(true); + expect(content[0].text).toContain("Error"); + } + ), + timeout + ); +}); diff --git a/packages/mcp/test/setup.ts b/packages/mcp/test/setup.ts new file mode 100644 index 0000000..366774f --- /dev/null +++ b/packages/mcp/test/setup.ts @@ -0,0 +1,32 @@ +import { afterAll, afterEach, beforeEach, jest } from "@jest/globals"; + +// Set up test environment variables +process.env.MXBAI_API_KEY = "mxb_test-api-key"; +process.env.NODE_ENV = "test"; + +// Mock console methods globally to reduce noise in tests +const originalConsoleWarn = console.warn; +const originalConsoleError = console.error; +const originalConsoleLog = console.log; +const originalProcessExit = process.exit; + +beforeEach(() => { + // Reset console mocks for each test + console.warn = jest.fn(); + console.error = jest.fn(); + console.log = jest.fn(); + process.exit = jest.fn() as never; +}); + +afterEach(() => { + // Clean up after each test + jest.clearAllMocks(); +}); + +afterAll(() => { + // Restore original methods + console.warn = originalConsoleWarn; + console.error = originalConsoleError; + console.log = originalConsoleLog; + process.exit = originalProcessExit; +}); diff --git a/packages/mcp/test/unit/schemas.test.ts b/packages/mcp/test/unit/schemas.test.ts new file mode 100644 index 0000000..541739b --- /dev/null +++ b/packages/mcp/test/unit/schemas.test.ts @@ -0,0 +1,213 @@ +import { + StoreCreateSchema, + StoreDeleteSchema, + StoreFileRetrieveSchema, + StoreListSchema, + StoreRetrieveSchema, + StoreSearchSchema, + StoreUploadSchema, +} from "../../src/types/schemas.js"; + +describe("Schema Validation", () => { + describe("StoreSearchSchema", () => { + const validInput = { + query: "test query", + store_identifiers: ["store1", "store2"], + top_k: 5, + }; + + it("should validate correct input", () => { + const result = StoreSearchSchema.parse(validInput); + expect(result.query).toBe("test query"); + expect(result.store_identifiers).toEqual(["store1", "store2"]); + expect(result.top_k).toBe(5); + }); + + it("should apply default top_k value", () => { + const input = { + query: "test query", + store_identifiers: ["store1"], + }; + const result = StoreSearchSchema.parse(input); + expect(result.top_k).toBe(5); + }); + + it("should reject empty store_identifiers", () => { + const input = { + query: "test query", + store_identifiers: [], + }; + expect(() => StoreSearchSchema.parse(input)).toThrow(); + }); + + it("should reject missing required fields", () => { + expect(() => StoreSearchSchema.parse({})).toThrow(); + }); + }); + + describe("StoreRetrieveSchema", () => { + it("should validate correct input", () => { + const input = { store_identifier: "vs-123" }; + const result = StoreRetrieveSchema.parse(input); + expect(result.store_identifier).toBe("vs-123"); + }); + + it("should reject empty store_identifier", () => { + const input = { store_identifier: "" }; + expect(() => StoreRetrieveSchema.parse(input)).toThrow(); + }); + }); + + describe("StoreListSchema", () => { + it("should validate with all optional fields", () => { + const input = { + q: "search term", + limit: 50, + after: "next_page_after", + include_total: true, + }; + const result = StoreListSchema.parse(input); + expect(result.q).toBe("search term"); + expect(result.limit).toBe(50); + expect(result.after).toBe("next_page_after"); + expect(result.include_total).toBe(true); + }); + + it("should apply default limit value", () => { + const result = StoreListSchema.parse({}); + expect(result.limit).toBe(20); + }); + + it("should reject limit over 100", () => { + const input = { limit: 150 }; + expect(() => StoreListSchema.parse(input)).toThrow(); + }); + + it("should accept minimal input", () => { + const result = StoreListSchema.parse({}); + expect(result.limit).toBe(20); + expect(result.q).toBeUndefined(); + expect(result.after).toBeUndefined(); + expect(result.include_total).toBeUndefined(); + }); + + it("should validate search query", () => { + const input = { q: "embeddings" }; + const result = StoreListSchema.parse(input); + expect(result.q).toBe("embeddings"); + }); + + it("should validate after pagination", () => { + const input = { after: "eyJpZCI6MTIzfQ==" }; + const result = StoreListSchema.parse(input); + expect(result.after).toBe("eyJpZCI6MTIzfQ=="); + }); + + it("should validate include_total flag", () => { + const input = { include_total: false }; + const result = StoreListSchema.parse(input); + expect(result.include_total).toBe(false); + }); + }); + + describe("StoreCreateSchema", () => { + it("should validate correct input", () => { + const input = { + name: "Test Store", + description: "A test store", + }; + const result = StoreCreateSchema.parse(input); + expect(result.name).toBe("Test Store"); + expect(result.description).toBe("A test store"); + }); + + it("should validate without description", () => { + const input = { name: "Test Store" }; + const result = StoreCreateSchema.parse(input); + expect(result.name).toBe("Test Store"); + expect(result.description).toBeUndefined(); + }); + + it("should reject empty name", () => { + const input = { name: "" }; + expect(() => StoreCreateSchema.parse(input)).toThrow(); + }); + }); + + describe("StoreDeleteSchema", () => { + it("should validate correct input", () => { + const input = { store_identifier: "vs-123" }; + const result = StoreDeleteSchema.parse(input); + expect(result.store_identifier).toBe("vs-123"); + }); + + it("should reject empty store_identifier", () => { + const input = { store_identifier: "" }; + expect(() => StoreDeleteSchema.parse(input)).toThrow(); + }); + }); + + describe("StoreUploadSchema", () => { + it("should validate correct input", () => { + const input = { + store_identifier: "vs-123", + file_path: "/path/to/file.txt", + filename: "custom-name.txt", + mime_type: "text/plain", + }; + const result = StoreUploadSchema.parse(input); + expect(result.store_identifier).toBe("vs-123"); + expect(result.file_path).toBe("/path/to/file.txt"); + expect(result.filename).toBe("custom-name.txt"); + expect(result.mime_type).toBe("text/plain"); + }); + + it("should validate without optional fields", () => { + const input = { + store_identifier: "vs-123", + file_path: "/path/to/file.txt", + }; + const result = StoreUploadSchema.parse(input); + expect(result.store_identifier).toBe("vs-123"); + expect(result.file_path).toBe("/path/to/file.txt"); + expect(result.filename).toBeUndefined(); + expect(result.mime_type).toBeUndefined(); + }); + + it("should reject empty file_path", () => { + const input = { + store_identifier: "vs-123", + file_path: "", + }; + expect(() => StoreUploadSchema.parse(input)).toThrow(); + }); + }); + + describe("StoreFileRetrieveSchema", () => { + it("should validate correct input", () => { + const input = { + file_id: "file-123", + store_identifier: "vs-123", + }; + const result = StoreFileRetrieveSchema.parse(input); + expect(result.file_id).toBe("file-123"); + expect(result.store_identifier).toBe("vs-123"); + }); + + it("should reject empty file_id", () => { + const input = { + file_id: "", + store_identifier: "vs-123", + }; + expect(() => StoreFileRetrieveSchema.parse(input)).toThrow(); + }); + + it("should reject empty store_identifier", () => { + const input = { + file_id: "file-123", + store_identifier: "", + }; + expect(() => StoreFileRetrieveSchema.parse(input)).toThrow(); + }); + }); +}); diff --git a/packages/mcp/test/unit/tools/store-create.test.ts b/packages/mcp/test/unit/tools/store-create.test.ts new file mode 100644 index 0000000..38d1fc4 --- /dev/null +++ b/packages/mcp/test/unit/tools/store-create.test.ts @@ -0,0 +1,44 @@ +import { storeCreate } from "../../../src/tools/store-create.js"; +import { mockStoreCreateResponse } from "../../fixtures/mock-responses.js"; +import { expectMCPError, expectMCPResponse } from "../../helpers/test-utils.js"; + +const mockCreate = jest.fn(); +const mockClient = { + stores: { + create: mockCreate, + }, +}; + +jest.mock("../../../src/utils.js", () => ({ + getMixedbreadClient: jest.fn(() => mockClient), +})); + +describe("storeCreate", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should create store successfully", async () => { + mockCreate.mockResolvedValue(mockStoreCreateResponse); + + const args = { name: "New Store", description: "Test store" }; + const result = await storeCreate(args); + + expect(mockCreate).toHaveBeenCalledWith(args); + expectMCPResponse(result); + expect(result.content[0].text).toContain("vs-new"); + expect(result.content[0].text).toContain("New Store"); + }); + + it("should handle create errors gracefully", async () => { + const error = new Error("API Error: Name already exists"); + mockCreate.mockRejectedValue(error); + + const args = { name: "Duplicate Store" }; + const result = await storeCreate(args); + + expectMCPError(result); + expect(result.content[0].text).toContain("Error creating store"); + expect(result.content[0].text).toContain("Name already exists"); + }); +}); diff --git a/packages/mcp/test/unit/tools/store-list.test.ts b/packages/mcp/test/unit/tools/store-list.test.ts new file mode 100644 index 0000000..b8f8cd7 --- /dev/null +++ b/packages/mcp/test/unit/tools/store-list.test.ts @@ -0,0 +1,101 @@ +import { storeList } from "../../../src/tools/store-list.js"; +import { mockStoreListResponse } from "../../fixtures/mock-responses.js"; +import { expectMCPError, expectMCPResponse } from "../../helpers/test-utils.js"; + +const mockList = jest.fn(); +const mockClient = { + stores: { + list: mockList, + }, +}; + +jest.mock("../../../src/utils.js", () => ({ + getMixedbreadClient: jest.fn(() => mockClient), +})); + +describe("storeList", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should list stores successfully", async () => { + mockList.mockResolvedValue(mockStoreListResponse); + + const args = { limit: 20 }; + const result = await storeList(args); + + expect(mockList).toHaveBeenCalledWith(args); + expectMCPResponse(result); + expect(result.content[0].text).toContain("vs-1"); + expect(result.content[0].text).toContain("Store 1"); + }); + + it("should list stores with search query", async () => { + mockList.mockResolvedValue(mockStoreListResponse); + + const args = { q: "embeddings", limit: 10 }; + const result = await storeList(args); + + expect(mockList).toHaveBeenCalledWith(args); + expectMCPResponse(result); + expect(result.content[0].text).toContain("vs-1"); + }); + + it("should list stores with after cursor", async () => { + mockList.mockResolvedValue(mockStoreListResponse); + + const args = { after: "next_page_cursor", limit: 20 }; + const result = await storeList(args); + + expect(mockList).toHaveBeenCalledWith(args); + expectMCPResponse(result); + expect(result.content[0].text).toContain("vs-1"); + }); + + it("should list stores with include_total flag", async () => { + mockList.mockResolvedValue(mockStoreListResponse); + + const args = { include_total: true, limit: 20 }; + const result = await storeList(args); + + expect(mockList).toHaveBeenCalledWith(args); + expectMCPResponse(result); + expect(result.content[0].text).toContain("vs-1"); + }); + + it("should list stores with all optional parameters", async () => { + mockList.mockResolvedValue(mockStoreListResponse); + + const args = { + q: "search term", + limit: 50, + after: "page_cursor", + include_total: true, + }; + const result = await storeList(args); + + expect(mockList).toHaveBeenCalledWith(args); + expectMCPResponse(result); + expect(result.content[0].text).toContain("vs-1"); + }); + + it("should use default limit when not provided", async () => { + mockList.mockResolvedValue(mockStoreListResponse); + + const result = await storeList({ limit: 20, include_total: true }); + + expect(mockList).toHaveBeenCalledWith({ limit: 20, include_total: true }); + expectMCPResponse(result); + }); + + it("should handle list errors gracefully", async () => { + const error = new Error("API Error: Unauthorized"); + mockList.mockRejectedValue(error); + + const result = await storeList({ limit: 20 }); + + expectMCPError(result); + expect(result.content[0].text).toContain("Error listing stores"); + expect(result.content[0].text).toContain("Unauthorized"); + }); +}); diff --git a/packages/mcp/test/unit/tools/store-search.test.ts b/packages/mcp/test/unit/tools/store-search.test.ts new file mode 100644 index 0000000..2d9f155 --- /dev/null +++ b/packages/mcp/test/unit/tools/store-search.test.ts @@ -0,0 +1,88 @@ +import { storeSearch } from "../../../src/tools/store-search.js"; +import { mockStoreSearchResponse } from "../../fixtures/mock-responses.js"; +import { expectMCPError, expectMCPResponse } from "../../helpers/test-utils.js"; + +const mockSearch = jest.fn(); +const mockClient = { + stores: { + search: mockSearch, + }, +}; + +jest.mock("../../../src/utils.js", () => ({ + getMixedbreadClient: jest.fn(() => mockClient), +})); + +describe("storeSearch", () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it("should return search results successfully", async () => { + mockSearch.mockResolvedValue(mockStoreSearchResponse); + + const args = { + query: "test query", + store_identifiers: ["store1", "store2"], + top_k: 5, + }; + + const result = await storeSearch(args); + + expect(mockSearch).toHaveBeenCalledWith(args); + expectMCPResponse(result); + expect(result.content[0].text).toContain("chunk-1"); + expect(result.content[0].text).toContain("sample chunk"); + }); + + it("should handle search with optional parameters", async () => { + mockSearch.mockResolvedValue(mockStoreSearchResponse); + + const args = { + query: "test query", + store_identifiers: ["store1"], + top_k: 10, + filters: { type: "document" }, + file_ids: ["file1", "file2"], + search_options: { rerank: true }, + }; + + const result = await storeSearch(args); + + expect(mockSearch).toHaveBeenCalledWith(args); + expectMCPResponse(result); + }); + + it("should handle API errors gracefully", async () => { + const error = new Error("API Error: Invalid store ID"); + mockSearch.mockRejectedValue(error); + + const args = { + query: "test query", + store_identifiers: ["invalid-store"], + top_k: 5, + }; + + const result = await storeSearch(args); + + expect(mockSearch).toHaveBeenCalledWith(args); + expectMCPError(result); + expect(result.content[0].text).toContain("Error searching store"); + expect(result.content[0].text).toContain("API Error: Invalid store ID"); + }); + + it("should handle non-Error exceptions", async () => { + mockSearch.mockRejectedValue("String error"); + + const args = { + query: "test query", + store_identifiers: ["store1"], + top_k: 5, + }; + + const result = await storeSearch(args); + + expectMCPError(result); + expect(result.content[0].text).toContain("String error"); + }); +}); diff --git a/packages/mcp/test/unit/utils.test.ts b/packages/mcp/test/unit/utils.test.ts new file mode 100644 index 0000000..15212b3 --- /dev/null +++ b/packages/mcp/test/unit/utils.test.ts @@ -0,0 +1,75 @@ +import { + createMixedbreadClient, + getMixedbreadClient, + resetMixedbreadClient, +} from "../../src/utils.js"; + +describe("Utils", () => { + const originalEnv = process.env; + + beforeEach(() => { + jest.resetModules(); + process.env = { ...originalEnv }; + // Reset singleton + resetMixedbreadClient(); + }); + + afterAll(() => { + process.env = originalEnv; + }); + + describe("createMixedbreadClient", () => { + it("should create client with valid API key", () => { + process.env.MXBAI_API_KEY = "test-api-key"; + + const client = createMixedbreadClient(); + + expect(client).toBeDefined(); + expect(client.constructor.name).toBe("Mixedbread"); + }); + + it("should throw error when API key is missing", () => { + delete process.env.MXBAI_API_KEY; + + expect(() => createMixedbreadClient()).toThrow( + "MXBAI_API_KEY environment variable is required" + ); + }); + + it("should throw error when API key is empty", () => { + process.env.MXBAI_API_KEY = ""; + + expect(() => createMixedbreadClient()).toThrow( + "MXBAI_API_KEY environment variable is required" + ); + }); + }); + + describe("getMixedbreadClient", () => { + it("should return singleton instance", () => { + process.env.MXBAI_API_KEY = "test-api-key"; + + const client1 = getMixedbreadClient(); + const client2 = getMixedbreadClient(); + + expect(client1).toBe(client2); + }); + + it("should create client on first call", () => { + process.env.MXBAI_API_KEY = "test-api-key"; + + const client = getMixedbreadClient(); + + expect(client).toBeDefined(); + expect(client.constructor.name).toBe("Mixedbread"); + }); + + it("should throw error when API key is missing", () => { + delete process.env.MXBAI_API_KEY; + + expect(() => getMixedbreadClient()).toThrow( + "MXBAI_API_KEY environment variable is required" + ); + }); + }); +}); diff --git a/packages/mcp/tsconfig.json b/packages/mcp/tsconfig.json new file mode 100644 index 0000000..c025fb4 --- /dev/null +++ b/packages/mcp/tsconfig.json @@ -0,0 +1,23 @@ +{ + "compilerOptions": { + "target": "ES2022", + "module": "NodeNext", + "moduleResolution": "NodeNext", + "outDir": "./dist", + "rootDir": "./src", + "strict": true, + "esModuleInterop": true, + "skipLibCheck": true, + "forceConsistentCasingInFileNames": true, + "declaration": true, + "declarationMap": true, + "sourceMap": true, + "resolveJsonModule": true, + "allowSyntheticDefaultImports": true, + "allowImportingTsExtensions": false, + "noEmit": false, + "types": ["node", "jest"] + }, + "include": ["src/**/*"], + "exclude": ["node_modules", "dist"] +} diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5c18bd1..1162c1f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -100,6 +100,49 @@ importers: specifier: 5.9.3 version: 5.9.3 + packages/mcp: + dependencies: + '@mixedbread/sdk': + specifier: ^0.78.0 + version: 0.78.0 + '@modelcontextprotocol/sdk': + specifier: ^1.13.0 + version: 1.31.0(zod@3.25.76) + mime-types: + specifier: ^3.0.1 + version: 3.0.2 + zod: + specifier: ^3.25.67 + version: 3.25.76 + zod-to-json-schema: + specifier: ^3.24.5 + version: 3.25.2(zod@3.25.76) + devDependencies: + '@jest/globals': + specifier: ^30.0.2 + version: 30.2.0 + '@types/jest': + specifier: ^29.5.14 + version: 29.5.14 + '@types/mime-types': + specifier: ^3.0.1 + version: 3.0.1 + '@types/node': + specifier: ^24.0.3 + version: 24.19.0 + jest: + specifier: ^29.5.0 + version: 29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + ts-jest: + specifier: ^29.1.0 + version: 29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)))(typescript@5.9.3) + tsx: + specifier: ^4.20.3 + version: 4.23.15 + typescript: + specifier: ^5.8.3 + version: 5.9.3 + packages/search: dependencies: '@mixedbread/sdk': @@ -494,6 +537,168 @@ packages: '@emnapi/wasi-threads@1.1.0': resolution: {integrity: sha512-WI0DdZ8xFSbgMjR1sFsKABJ/C5OnRrjT06JXbZKexJGrDuPTzZdDYfFlsgcCXCyf+suG5QU2e/y1Wo2V/OapLQ==} + '@esbuild/aix-ppc64@0.28.2': + resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [aix] + + '@esbuild/android-arm64@0.28.2': + resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==} + engines: {node: '>=18'} + cpu: [arm64] + os: [android] + + '@esbuild/android-arm@0.28.2': + resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==} + engines: {node: '>=18'} + cpu: [arm] + os: [android] + + '@esbuild/android-x64@0.28.2': + resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==} + engines: {node: '>=18'} + cpu: [x64] + os: [android] + + '@esbuild/darwin-arm64@0.28.2': + resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [darwin] + + '@esbuild/darwin-x64@0.28.2': + resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==} + engines: {node: '>=18'} + cpu: [x64] + os: [darwin] + + '@esbuild/freebsd-arm64@0.28.2': + resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [freebsd] + + '@esbuild/freebsd-x64@0.28.2': + resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==} + engines: {node: '>=18'} + cpu: [x64] + os: [freebsd] + + '@esbuild/linux-arm64@0.28.2': + resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==} + engines: {node: '>=18'} + cpu: [arm64] + os: [linux] + + '@esbuild/linux-arm@0.28.2': + resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==} + engines: {node: '>=18'} + cpu: [arm] + os: [linux] + + '@esbuild/linux-ia32@0.28.2': + resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==} + engines: {node: '>=18'} + cpu: [ia32] + os: [linux] + + '@esbuild/linux-loong64@0.28.2': + resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==} + engines: {node: '>=18'} + cpu: [loong64] + os: [linux] + + '@esbuild/linux-mips64el@0.28.2': + resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==} + engines: {node: '>=18'} + cpu: [mips64el] + os: [linux] + + '@esbuild/linux-ppc64@0.28.2': + resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==} + engines: {node: '>=18'} + cpu: [ppc64] + os: [linux] + + '@esbuild/linux-riscv64@0.28.2': + resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==} + engines: {node: '>=18'} + cpu: [riscv64] + os: [linux] + + '@esbuild/linux-s390x@0.28.2': + resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==} + engines: {node: '>=18'} + cpu: [s390x] + os: [linux] + + '@esbuild/linux-x64@0.28.2': + resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==} + engines: {node: '>=18'} + cpu: [x64] + os: [linux] + + '@esbuild/netbsd-arm64@0.28.2': + resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==} + engines: {node: '>=18'} + cpu: [arm64] + os: [netbsd] + + '@esbuild/netbsd-x64@0.28.2': + resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==} + engines: {node: '>=18'} + cpu: [x64] + os: [netbsd] + + '@esbuild/openbsd-arm64@0.28.2': + resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openbsd] + + '@esbuild/openbsd-x64@0.28.2': + resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==} + engines: {node: '>=18'} + cpu: [x64] + os: [openbsd] + + '@esbuild/openharmony-arm64@0.28.2': + resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==} + engines: {node: '>=18'} + cpu: [arm64] + os: [openharmony] + + '@esbuild/sunos-x64@0.28.2': + resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==} + engines: {node: '>=18'} + cpu: [x64] + os: [sunos] + + '@esbuild/win32-arm64@0.28.2': + resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==} + engines: {node: '>=18'} + cpu: [arm64] + os: [win32] + + '@esbuild/win32-ia32@0.28.2': + resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==} + engines: {node: '>=18'} + cpu: [ia32] + os: [win32] + + '@esbuild/win32-x64@0.28.2': + resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==} + engines: {node: '>=18'} + cpu: [x64] + os: [win32] + + '@hono/node-server@2.1.3': + resolution: {integrity: sha512-TA//nWMqPhbfdfneACk6t5a9eqbS9lABEPyKn0/xZTah3H3U2XaVg85rJFl0/Fyit0I552YDHgXGVSf3GwqbUw==} + engines: {node: '>=20'} + peerDependencies: + hono: ^4 + '@img/sharp-darwin-arm64@0.34.3': resolution: {integrity: sha512-ryFMfvxxpQRsgZJqBd4wsttYQbCxsJksrv9Lw/v798JcQ8+w84mBWuXwl+TT0WJ/WrYOLaYpwQXi3sA9nTIaIg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -645,10 +850,23 @@ packages: resolution: {integrity: sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==} engines: {node: '>=8'} + '@jest/console@29.7.0': + resolution: {integrity: sha512-5Ni4CU7XHQi32IJ398EEP4RrB8eV09sXP2ROqD4bksHrnTree52PsxvX8tpL8LvTZ3pFzXyPbNQReSN41CAhOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/console@30.2.0': resolution: {integrity: sha512-+O1ifRjkvYIkBqASKWgLxrpEhQAAE7hY77ALLUufSk5717KfOShg6IbqLmdsLMPdUiFvA2kTs0R7YZy+l0IzZQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/core@29.7.0': + resolution: {integrity: sha512-n7aeXWKMnGtDA48y8TLWJPJmLmmZ642Ceo78cYWEpiD7FzDgmNDV/GCVRorPABdXLJZ/9wzzgZAlHjXjxDHGsg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + '@jest/core@30.2.0': resolution: {integrity: sha512-03W6IhuhjqTlpzh/ojut/pDB2LPRygyWX8ExpgHtQA8H/3K7+1vKmcINx5UzeOX1se6YEsBsOHQ1CRzf3fOwTQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -662,18 +880,34 @@ packages: resolution: {integrity: sha512-n5H8QLDJ47QqbCNn5SuFjCRDrOLEZ0h8vAHCK5RL9Ls7Xa8AQLa/YxAc9UjFqoEDM48muwtBGjtMY5cr0PLDCw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/environment@29.7.0': + resolution: {integrity: sha512-aQIfHDq33ExsN4jP1NWGXhxgQ/wixs60gDiKO+XVMd8Mn0NWPWgc34ZQDTb2jKaUWQ7MuwoitXAsN2XVXNMpAw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/environment@30.2.0': resolution: {integrity: sha512-/QPTL7OBJQ5ac09UDRa3EQes4gt1FTEG/8jZ/4v5IVzx+Cv7dLxlVIvfvSVRiiX2drWyXeBjkMSR8hvOWSog5g==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/expect-utils@29.7.0': + resolution: {integrity: sha512-GlsNBWiFQFCVi9QVSx7f5AgMeLxe9YCCs5PuP2O2LdjDAA8Jh9eX7lA1Jq/xdXw3Wb3hyvlFNfZIfcRetSzYcA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect-utils@30.2.0': resolution: {integrity: sha512-1JnRfhqpD8HGpOmQp180Fo9Zt69zNtC+9lR+kT7NVL05tNXIi+QC8Csz7lfidMoVLPD3FnOtcmp0CEFnxExGEA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/expect@29.7.0': + resolution: {integrity: sha512-8uMeAMycttpva3P1lBHB8VciS9V0XAr3GymPpipdyQXbBcuhkLQOSe8E/p92RyAdToS6ZD1tFkX+CkhoECE0dQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/expect@30.2.0': resolution: {integrity: sha512-V9yxQK5erfzx99Sf+7LbhBwNWEZ9eZay8qQ9+JSC0TrMR1pMDHLMY+BnVPacWU6Jamrh252/IKo4F1Xn/zfiqA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/fake-timers@29.7.0': + resolution: {integrity: sha512-q4DH1Ha4TTFPdxLsqDXK1d3+ioSL7yL5oCMJZgDYm6i+6CygW5E5xVr/D1HdsGxjt1ZWSfUAs9OxSB/BNelWrQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/fake-timers@30.2.0': resolution: {integrity: sha512-HI3tRLjRxAbBy0VO8dqqm7Hb2mIa8d5bg/NJkyQcOk7V118ObQML8RC5luTF/Zsg4474a+gDvhce7eTnP4GhYw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -682,6 +916,10 @@ packages: resolution: {integrity: sha512-eMbZE2hUnx1WV0pmURZY9XoXPkUYjpc55mb0CrhtdWLtzMQPFvu/rZkTLZFTsdaVQa+Tr4eWAteqcUzoawq/uA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/globals@29.7.0': + resolution: {integrity: sha512-mpiz3dutLbkW2MNFubUGUEVLkTGiqW6yLVTA+JbP6fI6J5iL9Y0Nlg8k95pcF8ctKwCS7WVxteBs29hhfAotzQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/globals@30.2.0': resolution: {integrity: sha512-b63wmnKPaK+6ZZfpYhz9K61oybvbI1aMcIs80++JI1O1rR1vaxHUCNqo3ITu6NU0d4V34yZFoHMn/uoKr/Rwfw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -690,6 +928,15 @@ packages: resolution: {integrity: sha512-gWp7NfQW27LaBQz3TITS8L7ZCQ0TLvtmI//4OwlQRx4rnWxcPNIYjxZpDcN4+UlGxgm3jS5QPz8IPTCkb59wZA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/reporters@29.7.0': + resolution: {integrity: sha512-DApq0KJbJOEzAFYjHADNNxAE3KbhxQB1y5Kplb5Waqw6zVbuWatSnMjE5gs8FUgEPmNsnZA3NCWl9NG0ia04Pg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + '@jest/reporters@30.2.0': resolution: {integrity: sha512-DRyW6baWPqKMa9CzeiBjHwjd8XeAyco2Vt8XbcLFjiwCOEKOvy82GJ8QQnJE9ofsxCMPjH4MfH8fCWIHHDKpAQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -699,6 +946,10 @@ packages: node-notifier: optional: true + '@jest/schemas@29.6.3': + resolution: {integrity: sha512-mo5j5X+jIZmJQveBKeS/clAueipV7KgiX1vMgCxam1RNYiqE1w62n0/tJJnHtjW8ZHcQco5gY85jA3mi0L+nSA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/schemas@30.0.5': resolution: {integrity: sha512-DmdYgtezMkh3cpU8/1uyXakv3tJRcmcXxBOcO0tbaozPwpmh4YMsnWrQm9ZmZMfa5ocbxzbFk6O4bDPEc/iAnA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -707,22 +958,42 @@ packages: resolution: {integrity: sha512-0aVxM3RH6DaiLcjj/b0KrIBZhSX1373Xci4l3cW5xiUWPctZ59zQ7jj4rqcJQ/Z8JuN/4wX3FpJSa3RssVvCug==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/source-map@29.6.3': + resolution: {integrity: sha512-MHjT95QuipcPrpLM+8JMSzFx6eHp5Bm+4XeFDJlwsvVBjmKNiIAvasGK2fxz2WbGRlnvqehFbh07MMa7n3YJnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/source-map@30.0.1': resolution: {integrity: sha512-MIRWMUUR3sdbP36oyNyhbThLHyJ2eEDClPCiHVbrYAe5g3CHRArIVpBw7cdSB5fr+ofSfIb2Tnsw8iEHL0PYQg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/test-result@29.7.0': + resolution: {integrity: sha512-Fdx+tv6x1zlkJPcWXmMDAG2HBnaR9XPSd5aDWQVsfrZmLVT3lU1cwyxLgRmXR9yrq4NBoEm9BMsfgFzTQAbJYA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-result@30.2.0': resolution: {integrity: sha512-RF+Z+0CCHkARz5HT9mcQCBulb1wgCP3FBvl9VFokMX27acKphwyQsNuWH3c+ojd1LeWBLoTYoxF0zm6S/66mjg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/test-sequencer@29.7.0': + resolution: {integrity: sha512-GQwJ5WZVrKnOJuiYiAF52UNUJXgTZx1NHjFSEB0qEMmSZKAkdMoIzw/Cj6x6NF4AvV23AUqDpFzQkN/eYCYTxw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/test-sequencer@30.2.0': resolution: {integrity: sha512-wXKgU/lk8fKXMu/l5Hog1R61bL4q5GCdT6OJvdAFz1P+QrpoFuLU68eoKuVc4RbrTtNnTL5FByhWdLgOPSph+Q==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/transform@29.7.0': + resolution: {integrity: sha512-ok/BTPFzFKVMwO5eOHRrvnBVHdRy9IrsrW1GpMaQ9MCnilNLXQKmAX8s1YXDFaai9xJpac2ySzV0YeRRECr2Vw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/transform@30.2.0': resolution: {integrity: sha512-XsauDV82o5qXbhalKxD7p4TZYYdwcaEXC77PPD2HixEFF+6YGppjrAAQurTl2ECWcEomHBMMNS9AH3kcCFx8jA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + '@jest/types@29.6.3': + resolution: {integrity: sha512-u3UPsIilWKOM3F9CXtrG8LEJmNxwoCQC/XVj4IKYXvvpx7QIi/Kg1LI5uDmDpKlac62NUtX7eLjRh+jVZcLOzw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + '@jest/types@30.2.0': resolution: {integrity: sha512-H9xg1/sfVvyfU7o3zMfBEjQ1gcsdeTMgqHoYdN79tuLqfTtuu7WckRA1R5whDwOzxaZAeMKTYWqP+WCAi0CHsg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -763,6 +1034,20 @@ packages: resolution: {integrity: sha512-OxVkpVoJpdCGSo1v1Nu6tDiSv7M17LXT9A0LOT97WnkiGaHTranfeTioUI1XuQYfqXiAftPWC6eznswW9AB0DA==} hasBin: true + '@mixedbread/sdk@0.78.0': + resolution: {integrity: sha512-gd5F8jaMt+mwRPzPBkLuXwP8jbR5dQQul5uuJomHrxGaO6Msff92Zu4rMXjZRyI8JYhQIDbzGqy9uSxjSz1YWA==} + hasBin: true + + '@modelcontextprotocol/sdk@1.31.0': + resolution: {integrity: sha512-UvTMgnNlnIBO/22ob2RcVGDlcvOslQs8T59+FTGdA0L27a39fdGF/EDETNtDVK4DZGpwomlsYpRdA8UXcVL/pw==} + engines: {node: '>=18'} + peerDependencies: + '@cfworker/json-schema': ^4.1.1 + zod: ^3.25 || ^4.0 + peerDependenciesMeta: + '@cfworker/json-schema': + optional: true + '@napi-rs/wasm-runtime@0.2.12': resolution: {integrity: sha512-ZVWUcfwY4E/yPitQJl481FjFo3K22D6qF0DuFH6Y/nbnE11GY5uguDxZMGXPQ8WQ0128MXQD7TnfHyK4oWoIJQ==} @@ -1097,12 +1382,18 @@ packages: '@shikijs/vscode-textmate@10.0.2': resolution: {integrity: sha512-83yeghZ2xxin3Nj8z1NMd/NCuca+gsYXswywDy5bHvwlWL8tpTQmzGeUuHd9FC3E/SBEMvzJRwWEOz5gGes9Qg==} + '@sinclair/typebox@0.27.12': + resolution: {integrity: sha512-hhyNJ+nbR6ZR7pToHvllEFun9TL0sbL+tk/ON75lo+Xas054uez98qRbsuNt7MBCyZKK4+8Yli/OAGZhmfBZ/g==} + '@sinclair/typebox@0.34.48': resolution: {integrity: sha512-kKJTNuK3AQOrgjjotVxMrCn1sUJwM76wMszfq1kdU4uYVJjvEWuFQ6HgvLt4Xz3fSmZlTOxJ/Ie13KnIcWQXFA==} '@sinonjs/commons@3.0.1': resolution: {integrity: sha512-K3mCHKQ9sVh8o1C9cxkwxaOmXoAMlDxC1mYyHrjqOWEcBjYr76t96zL2zlj5dUGZ3HSw240X1qgH3Mjf1yJWpQ==} + '@sinonjs/fake-timers@10.3.0': + resolution: {integrity: sha512-V4BG07kuYSUkTCSBHG8G8TNhM+F19jXFWnQtzj+we8DrkpSBCee9Z3Ms8yiGer/dlmhe35/Xdgyo3/0rQKg7YA==} + '@sinonjs/fake-timers@13.0.5': resolution: {integrity: sha512-36/hTbH2uaWuGVERyC6da9YwGWnzUZXuPro/F2LfsdOsLnCojz/iSH8MxUt/FD2S5XBSVPhmArFUXcpCQ2Hkiw==} @@ -1233,6 +1524,9 @@ packages: '@types/estree@1.0.8': resolution: {integrity: sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==} + '@types/graceful-fs@4.1.9': + resolution: {integrity: sha512-olP3sd1qOEe5dXTSaFvQG+02VdRXcdytWLAZsAq1PecU8uqQAhkrnbli7DagjtXKW/Bl7YJbUsa8MPcuc8LHEQ==} + '@types/hast@3.0.4': resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==} @@ -1245,6 +1539,9 @@ packages: '@types/istanbul-reports@3.0.4': resolution: {integrity: sha512-pk2B1NWalF9toCRu6gjBzR69syFjP4Od8WRAX+0mmf9lAjCRicLOWc+ZrxZHx/0XRjotgkF9t6iaMJ+aXcOdZQ==} + '@types/jest@29.5.14': + resolution: {integrity: sha512-ZN+4sdnLUbo8EVvVc2ao0GFW6oVrQRPn4K2lglySj7APvSrgzxHiNNK99us4WDMi57xxA2yggblIAMNhXOotLQ==} + '@types/jest@30.0.0': resolution: {integrity: sha512-XTYugzhuwqWjws0CVz8QpM36+T+Dz5mTEBKhNs/esGLnCIlGdRy+Dq78NRjd7ls7r8BC8ZRMOrKlkO1hU0JOwA==} @@ -1273,6 +1570,9 @@ packages: '@types/node@20.19.11': resolution: {integrity: sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==} + '@types/node@24.19.0': + resolution: {integrity: sha512-zY+5tKxXdhGh1PYI0ac+7juvEu4OI6vWtVVoj5i2m42jxAY1U+zHGt6QCyOFwykdP62sM3MJ9stoYYUw5aCWew==} + '@types/node@25.2.3': resolution: {integrity: sha512-m0jEgYlYz+mDJZ2+F4v8D1AyQb+QzsNqRuI7xg1VQX/KlKS0qT9r1Mo16yo5F/MtifXFgaofIFsdFMox2SxIbQ==} @@ -1398,6 +1698,10 @@ packages: cpu: [x64] os: [win32] + accepts@2.0.0: + resolution: {integrity: sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==} + engines: {node: '>= 0.6'} + acorn-walk@8.3.4: resolution: {integrity: sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==} engines: {node: '>=0.4.0'} @@ -1411,6 +1715,17 @@ packages: resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} engines: {node: '>=8'} + ajv-formats@3.0.1: + resolution: {integrity: sha512-8iUql50EUR+uUcdRQ3HDqa6EVyo3docL8g5WJ3FNcWmu62IbkGUue/pEyLBW8VGKKucTPgqeks4fIU1DA4yowQ==} + peerDependencies: + ajv: ^8.0.0 + peerDependenciesMeta: + ajv: + optional: true + + ajv@8.20.0: + resolution: {integrity: sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==} + ansi-colors@4.1.3: resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} engines: {node: '>=6'} @@ -1457,16 +1772,30 @@ packages: resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} engines: {node: '>=8'} + babel-jest@29.7.0: + resolution: {integrity: sha512-BrvGY3xZSwEcCzKvKsCi2GgHqDqsYkOP4/by5xCgIwGXQxIEh+8ew3gmrE1y7XRR6LHZIj6yLYnUi/mm2KXKBg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.8.0 + babel-jest@30.2.0: resolution: {integrity: sha512-0YiBEOxWqKkSQWL9nNGGEgndoeL0ZpWrbLMNL5u/Kaxrli3Eaxlt3ZtIDktEvXt4L/R9r3ODr2zKwGM/2BjxVw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} peerDependencies: '@babel/core': ^7.11.0 || ^8.0.0-0 + babel-plugin-istanbul@6.1.1: + resolution: {integrity: sha512-Y1IQok9821cC9onCx5otgFfRm7Lm+I+wwxOx738M/WLPZ9Q42m4IG5W0FNX8WLL2gYMZo3JkuXIH2DOpWM+qwA==} + engines: {node: '>=8'} + babel-plugin-istanbul@7.0.1: resolution: {integrity: sha512-D8Z6Qm8jCvVXtIRkBnqNHX0zJ37rQcFJ9u8WOS6tkYOsRdHBzypCstaxWiu5ZIlqQtviRYbgnRLSoCEvjqcqbA==} engines: {node: '>=12'} + babel-plugin-jest-hoist@29.6.3: + resolution: {integrity: sha512-ESAc/RJvGTFEzRwOTT4+lNDk/GNHMkKbNzsvT0qKRfDyyYTskxB5rnU2njIDYVxXCBHHEI1c0YwHob3WaYujOg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + babel-plugin-jest-hoist@30.2.0: resolution: {integrity: sha512-ftzhzSGMUnOzcCXd6WHdBGMyuwy15Wnn0iyyWGKgBDLxf9/s5ABuraCSpBX2uG0jUg4rqJnxsLc5+oYBqoxVaA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -1476,6 +1805,12 @@ packages: peerDependencies: '@babel/core': ^7.0.0 || ^8.0.0-0 + babel-preset-jest@29.6.3: + resolution: {integrity: sha512-0B3bhxR6snWXJZtR/RliHTDPRgn1sNHOR0yVtq/IiQFyuOVjFS+wuio/R4gSNkyYmKmJB4wGZv2NZanmKmTnNA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@babel/core': ^7.0.0 + babel-preset-jest@30.2.0: resolution: {integrity: sha512-US4Z3NOieAQumwFnYdUWKvUKh8+YSnS/gB3t6YBiz0bskpu7Pine8pPCheNxlPEW4wnUkma2a94YuW2q3guvCQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -1500,6 +1835,10 @@ packages: resolution: {integrity: sha512-pbnl5XzGBdrFU/wT4jqmJVPn2B6UHPBOhzMQkY/SPUPB6QtUXtmBHBIwCbXJol93mOpGMnQyP/+BB19q04xj7g==} engines: {node: '>=4'} + body-parser@2.3.0: + resolution: {integrity: sha512-2cGmJupaNgg+QUwVLAucDuWuoMZ6EX9iHDRswZ5lsNYEmwPaRknMPCLZz07yTzVq/83p4o/wzbDZbBrTvGGTIw==} + engines: {node: '>=18'} + brace-expansion@1.1.12: resolution: {integrity: sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==} @@ -1529,6 +1868,18 @@ packages: buffer-from@1.1.2: resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} + bytes@3.1.2: + resolution: {integrity: sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==} + engines: {node: '>= 0.8'} + + call-bind-apply-helpers@1.0.2: + resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} + engines: {node: '>= 0.4'} + + call-bound@1.0.4: + resolution: {integrity: sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==} + engines: {node: '>= 0.4'} + callsites@3.1.0: resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} engines: {node: '>=6'} @@ -1589,6 +1940,9 @@ packages: resolution: {integrity: sha512-77PSwercCZU2Fc4sX94eF8k8Pxte6JAwL4/ICZLFjJLqegs7kCuAsqqj/70NQF6TvDpgFjkubQB2FW2ZZddvQg==} engines: {node: '>=8'} + cjs-module-lexer@1.4.3: + resolution: {integrity: sha512-9z8TZaGM1pfswYeXrUpzPrkx8UnWYdhJclsiYMm6x/w5+nN+8Tf/LnAgfLGQCm59qAOxU8WwHEq2vNwF6i4j+Q==} + cjs-module-lexer@2.2.0: resolution: {integrity: sha512-4bHTS2YuzUvtoLjdy+98ykbNB5jS0+07EvFNXerqZQJ89F7DI6ET7OQo/HJuW6K0aVsKA9hj9/RVb2kQVOrPDQ==} @@ -1649,9 +2003,38 @@ packages: concat-map@0.0.1: resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} + content-disposition@1.1.0: + resolution: {integrity: sha512-5jRCH9Z/+DRP7rkvY83B+yGIGX96OYdJmzngqnw2SBSxqCFPd0w2km3s5iawpGX8krnwSGmF0FW5Nhr0Hfai3g==} + engines: {node: '>=18'} + + content-type@1.0.5: + resolution: {integrity: sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==} + engines: {node: '>= 0.6'} + + content-type@2.1.0: + resolution: {integrity: sha512-mj7UPXE0jaqaOsukNZRUEfEi2AcL7C/vwmwcHV0O97eO1E1pxBZuyjlZrx5seTaNBg1U6+o35wpa35Qfcc+7ag==} + engines: {node: '>=18'} + convert-source-map@2.0.0: resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==} + cookie-signature@1.2.2: + resolution: {integrity: sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==} + engines: {node: '>=6.6.0'} + + cookie@0.7.2: + resolution: {integrity: sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==} + engines: {node: '>= 0.6'} + + cors@2.8.6: + resolution: {integrity: sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==} + engines: {node: '>= 0.10'} + + create-jest@29.7.0: + resolution: {integrity: sha512-Adz2bdH0Vq3F53KEMJOoftQFutWCukm6J24wbPWRO4k1kMY7gS7ds/uoJkNuV8wDCtWWnuwGcJwpWcih+zEW1Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + create-require@1.1.1: resolution: {integrity: sha512-dcKFX3jn0MpIaXjisoRvexIJVEKzaq7z2rZKxf+MSr9TkdmHmsU4m2lcLojrj/FHl8mk5VxMmYA+ftRkP/3oKQ==} @@ -1686,6 +2069,10 @@ packages: resolution: {integrity: sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A==} engines: {node: '>=0.10.0'} + depd@2.0.0: + resolution: {integrity: sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==} + engines: {node: '>= 0.8'} + dequal@2.0.3: resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==} engines: {node: '>=6'} @@ -1708,6 +2095,10 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} + diff-sequences@29.6.3: + resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + diff@4.0.4: resolution: {integrity: sha512-X07nttJQkwkfKfvTPG/KSnE2OMdcUCao6+eXF3wmnIQRn2aPAHH3VxDbDOdegkd6JbPsXqShpvEOHfAT+nCNwQ==} engines: {node: '>=0.3.1'} @@ -1716,9 +2107,16 @@ packages: resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} engines: {node: '>=8'} + dunder-proto@1.0.1: + resolution: {integrity: sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==} + engines: {node: '>= 0.4'} + eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + ee-first@1.1.1: + resolution: {integrity: sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==} + electron-to-chromium@1.5.286: resolution: {integrity: sha512-9tfDXhJ4RKFNerfjdCcZfufu49vg620741MNs26a9+bhLThdB+plgMeou98CAaHu/WATj2iHOOHTp1hWtABj2A==} @@ -1732,6 +2130,10 @@ packages: emoji-regex@9.2.2: resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} + encodeurl@2.0.0: + resolution: {integrity: sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==} + engines: {node: '>= 0.8'} + enhanced-resolve@5.18.3: resolution: {integrity: sha512-d4lC8xfavMeBjzGr2vECC3fsGXziXZQyJxD868h2M/mBI3PwAuODxAkLkq5HYuvrPYcUtiLzsTo8U3PgX3Ocww==} engines: {node: '>=10.13.0'} @@ -1747,10 +2149,30 @@ packages: error-ex@1.3.4: resolution: {integrity: sha512-sqQamAnR14VgCr1A618A3sGrygcpK+HEbenA/HiEAkkUwcZIIB/tgWqHFxWgOyDh4nB4JCRimh79dR5Ywc9MDQ==} + es-define-property@1.0.1: + resolution: {integrity: sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==} + engines: {node: '>= 0.4'} + + es-errors@1.3.0: + resolution: {integrity: sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==} + engines: {node: '>= 0.4'} + + es-object-atoms@1.1.2: + resolution: {integrity: sha512-HWcBoN6NileqtSydK2FqHbS/LoDd2pqrnQHLyJzBj4kOp/ky2MWMN694xOfkK8/SnUsW2DH7EfyVlydKCsm1Zw==} + engines: {node: '>= 0.4'} + + esbuild@0.28.2: + resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==} + engines: {node: '>=18'} + hasBin: true + escalade@3.2.0: resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==} engines: {node: '>=6'} + escape-html@1.0.3: + resolution: {integrity: sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==} + escape-string-regexp@2.0.0: resolution: {integrity: sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==} engines: {node: '>=8'} @@ -1767,6 +2189,18 @@ packages: estree-util-is-identifier-name@3.0.0: resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==} + etag@1.8.1: + resolution: {integrity: sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==} + engines: {node: '>= 0.6'} + + eventsource-parser@3.1.1: + resolution: {integrity: sha512-EKN1vKAMcZ8MlYMpaNuxN6R9yakzH6uajHcHVTqWJzvu5pWw9DyhbP35HH8MVBQ+dZjAfDxk+A8NiR9KWaXiyQ==} + engines: {node: '>=18.0.0'} + + eventsource@3.0.7: + resolution: {integrity: sha512-CRT1WTyuQoD771GW56XEZFQ/ZoSfWid1alKGDYMmkt2yl8UXrVR4pspqWNEcqKvVIzg6PAltWjxcSSPrboA4iA==} + engines: {node: '>=18.0.0'} + execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -1775,16 +2209,37 @@ packages: resolution: {integrity: sha512-+I6B/IkJc1o/2tiURyz/ivu/O0nKNEArIUB5O7zBrlDVJr22SCLH3xTeEry428LvFhRzIA1g8izguxJ/gbNcVQ==} engines: {node: '>= 0.8.0'} + exit@0.1.2: + resolution: {integrity: sha512-Zk/eNKV2zbjpKzrsQ+n1G6poVbErQxJ0LBOJXaKZ1EViLzH+hrLu9cdXI4zw9dBQJslwBEpbQ2P1oS7nDxs6jQ==} + engines: {node: '>= 0.8.0'} + + expect@29.7.0: + resolution: {integrity: sha512-2Zks0hf1VLFYI1kbh0I5jP3KHHyCHpkfyHBzsSXRFgl/Bg9mWYfMW8oD+PdMPlEwy5HNsR9JutYy6pMeOh61nw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + expect@30.2.0: resolution: {integrity: sha512-u/feCi0GPsI+988gU2FLcsHyAHTU0MX1Wg68NhAnN7z/+C5wqG+CY8J53N9ioe8RXgaoz0nBR/TYMf3AycUuPw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + express-rate-limit@8.7.0: + resolution: {integrity: sha512-hOwV7WOxXfjRpAM1DSJWZDXx3GhplwD8IfwuwvogD8i1Qnkgosw/H45s4ZnFAUHDAhPjlY9hLBvJhKmGMyY26g==} + engines: {node: '>= 16'} + peerDependencies: + express: '>= 4.11' + + express@5.2.1: + resolution: {integrity: sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==} + engines: {node: '>= 18'} + extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} + fast-deep-equal@3.1.3: + resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} + fast-glob@3.3.3: resolution: {integrity: sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg==} engines: {node: '>=8.6.0'} @@ -1792,6 +2247,9 @@ packages: fast-json-stable-stringify@2.1.0: resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} + fast-uri@3.1.8: + resolution: {integrity: sha512-GZMtZUTNRpOVIECoXwLNZS5xUGE+mVNbTB8h/7Rwh2TFWcBQiPzTgyZi05BF9UMZKkLJv8XBRJTlU7zg8+ZfMg==} + fastq@1.20.1: resolution: {integrity: sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==} @@ -1802,6 +2260,10 @@ packages: resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} engines: {node: '>=8'} + finalhandler@2.1.1: + resolution: {integrity: sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==} + engines: {node: '>= 18.0.0'} + find-up@4.1.0: resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} engines: {node: '>=8'} @@ -1810,6 +2272,10 @@ packages: resolution: {integrity: sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==} engines: {node: '>=14'} + forwarded@0.2.0: + resolution: {integrity: sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==} + engines: {node: '>= 0.6'} + framer-motion@12.23.12: resolution: {integrity: sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==} peerDependencies: @@ -1824,6 +2290,10 @@ packages: react-dom: optional: true + fresh@2.0.0: + resolution: {integrity: sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==} + engines: {node: '>= 0.8'} + fs-extra@7.0.1: resolution: {integrity: sha512-YJDaCJZEnBmcbw13fvdAM9AwNOJwOzrE4pqMqBq5nFiEqXUqHwlK4B+3pUw6JNvfSPtX05xFHtYy/1ni01eGCw==} engines: {node: '>=6 <7 || >=8'} @@ -1840,6 +2310,9 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] + function-bind@1.1.2: + resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + gensync@1.0.0-beta.2: resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} engines: {node: '>=6.9.0'} @@ -1848,6 +2321,10 @@ packages: resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} engines: {node: 6.* || 8.* || >= 10.*} + get-intrinsic@1.3.0: + resolution: {integrity: sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==} + engines: {node: '>= 0.4'} + get-nonce@1.0.1: resolution: {integrity: sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q==} engines: {node: '>=6'} @@ -1856,6 +2333,10 @@ packages: resolution: {integrity: sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==} engines: {node: '>=8.0.0'} + get-proto@1.0.1: + resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} + engines: {node: '>= 0.4'} + get-stdin@8.0.0: resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} engines: {node: '>=10'} @@ -1885,6 +2366,10 @@ packages: resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} engines: {node: '>=10'} + gopd@1.2.0: + resolution: {integrity: sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==} + engines: {node: '>= 0.4'} + graceful-fs@4.2.11: resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==} @@ -1897,6 +2382,14 @@ packages: resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} engines: {node: '>=8'} + has-symbols@1.1.0: + resolution: {integrity: sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==} + engines: {node: '>= 0.4'} + + hasown@2.0.4: + resolution: {integrity: sha512-T2UbfbBEF32wiepXIsMlTW9+dDYC6wMh/t/vYA4tuOMKqWz/n3vr1NFSxQiyP+zk2mXsoMA/i/7qV6LKut1t1A==} + engines: {node: '>= 0.4'} + hast-util-from-dom@5.0.1: resolution: {integrity: sha512-N+LqofjR2zuzTjCPzyDUdSshy4Ma6li7p/c3pA78uTwzFgENbgbUrm2ugwsOdcjI1muO+o6Dgzp9p8WHtn/39Q==} @@ -1930,6 +2423,10 @@ packages: hastscript@9.0.1: resolution: {integrity: sha512-g7df9rMFX/SPi34tyGCyUBREQoKkapwdY/T04Qn9TDWfHhAYt4/I0gMVirzK5wEzeUqIjEB+LXC/ypb7Aqno5w==} + hono@4.13.12: + resolution: {integrity: sha512-6E2QDAc9Ick9Sq77ZrGS/dk2WUYni91aufTw6LJKpV7w8kW5/GxVUc650FOADOmlwg3K+f7Pun6XlV+pYmW6gw==} + engines: {node: '>=16.9.0'} + html-escaper@2.0.2: resolution: {integrity: sha512-H2iMtd0I4Mt5eYiapRdIDjp+XzelXQ0tFE4JS7YFwFevXXMmOp9myNrUvCg0D6ws8iqkRPBfKHgbwig1SmlLfg==} @@ -1939,6 +2436,10 @@ packages: html-void-elements@3.0.0: resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==} + http-errors@2.0.1: + resolution: {integrity: sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==} + engines: {node: '>= 0.8'} + human-id@4.1.1: resolution: {integrity: sha512-3gKm/gCSUipeLsRYZbbdA1BD83lBoWUkZ7G9VFrhWPAU76KwYo5KR8V28bpoPm/ygy0x5/GCbpRQdY7VLYCoIg==} hasBin: true @@ -1951,6 +2452,10 @@ packages: resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} engines: {node: '>=0.10.0'} + iconv-lite@0.7.3: + resolution: {integrity: sha512-IKXpvIzjnC9XTAUbVBcMfGS0EPaIXtW6v+zr+RRp+hqULEpo0owZax6wyRwPOJbWbzjYspQwusTsfVr0ifh4uQ==} + engines: {node: '>=0.10.0'} + ignore@5.3.2: resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==} engines: {node: '>= 4'} @@ -1978,6 +2483,14 @@ packages: inline-style-parser@0.2.4: resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==} + ip-address@10.7.2: + resolution: {integrity: sha512-7H/2gFSIitxc0hG3nOI1glS8QLo/EHBFFLk8vEUjXY/xu0AdL8jZ9U1IzO2PUm0d2D/ofQcAifb0g6OBkt8U7w==} + engines: {node: '>= 12'} + + ipaddr.js@1.9.1: + resolution: {integrity: sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==} + engines: {node: '>= 0.10'} + is-alphabetical@2.0.1: resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==} @@ -1990,6 +2503,10 @@ packages: is-arrayish@0.3.2: resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==} + is-core-module@2.17.0: + resolution: {integrity: sha512-J/vG0zBCbIKOQFfufSwyXdMrsohyJIUNkrnmo6WZGzoM7tr/lsbfW5b2BvisL6zsyMzK9UxV9L6c7AoFbyXHOA==} + engines: {node: '>= 0.4'} + is-decimal@2.0.1: resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==} @@ -2020,6 +2537,9 @@ packages: resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==} engines: {node: '>=12'} + is-promise@4.0.0: + resolution: {integrity: sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==} + is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} @@ -2039,6 +2559,10 @@ packages: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} + istanbul-lib-instrument@5.2.1: + resolution: {integrity: sha512-pzqtp31nLv/XFOzXGuvhCb8qhjmTVo5vjVk19XE4CRlSWz0KoeJ3bw9XsA7nOp9YBf4qHjwBxkDzKcME/J29Yg==} + engines: {node: '>=8'} + istanbul-lib-instrument@6.0.3: resolution: {integrity: sha512-Vtgk7L/R2JHyyGW07spoFlB8/lpjiOLTjMdms6AFMraYt3BaJauod/NGrfnVG/y4Ix1JEuMRPDPEj2ua+zz1/Q==} engines: {node: '>=10'} @@ -2047,6 +2571,10 @@ packages: resolution: {integrity: sha512-GCfE1mtsHGOELCU8e/Z7YWzpmybrx/+dSTfLrvY8qRmaY6zXTKWn6WQIjaAFw069icm6GVMNkgu0NzI4iPZUNw==} engines: {node: '>=10'} + istanbul-lib-source-maps@4.0.1: + resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} + engines: {node: '>=10'} + istanbul-lib-source-maps@5.0.6: resolution: {integrity: sha512-yg2d+Em4KizZC5niWhQaIomgf5WlL4vOOjZ5xGCmF8SnPE/mDWWXgvRExdcpCgh9lLRRa1/fSYp2ymmbJ1pI+A==} engines: {node: '>=10'} @@ -2062,14 +2590,32 @@ packages: resolution: {integrity: sha512-ykkVRwrYvFm1nb2AJfKKYPr0emF6IiXDYUaFx4Zn9ZuIH7MrzEZ3sD5RlqGXNRpHtvUHJyOnCEFxOlNDtGo7wg==} engines: {node: 20 || >=22} + jest-changed-files@29.7.0: + resolution: {integrity: sha512-fEArFiwf1BpQ+4bXSprcDc3/x4HSzL4al2tozwVpDFpsxALjLYdyiIK4e5Vz66GQJIbXJ82+35PtysofptNX2w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-changed-files@30.2.0: resolution: {integrity: sha512-L8lR1ChrRnSdfeOvTrwZMlnWV8G/LLjQ0nG9MBclwWZidA2N5FviRki0Bvh20WRMOX31/JYvzdqTJrk5oBdydQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-circus@29.7.0: + resolution: {integrity: sha512-3E1nCMgipcTkCocFwM90XXQab9bS+GMsjdpmPrlelaxwD93Ad8iVEjX/vvHPdLPnFf+L40u+5+iutRdA1N9myw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-circus@30.2.0: resolution: {integrity: sha512-Fh0096NC3ZkFx05EP2OXCxJAREVxj1BcW/i6EWqqymcgYKWjyyDpral3fMxVcHXg6oZM7iULer9wGRFvfpl+Tg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-cli@29.7.0: + resolution: {integrity: sha512-OVVobw2IubN/GSYsxETi+gOe7Ka59EFMR/twOU3Jb2GnKKeMGJB5SGUUrEz3SFVmJASUdZUzy83sLNNQ2gZslg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + jest-cli@30.2.0: resolution: {integrity: sha512-Os9ukIvADX/A9sLt6Zse3+nmHtHaE6hqOsjQtNiugFTbKRHYIYtZXNGNK9NChseXy7djFPjndX1tL0sCTlfpAA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2080,6 +2626,18 @@ packages: node-notifier: optional: true + jest-config@29.7.0: + resolution: {integrity: sha512-uXbpfeQ7R6TZBqI3/TxCU4q4ttk3u0PJeC+E0zbfSoSjq6bJ7buBPxzQPL0ifrkY4DNu4JUdk0ImlBUYi840eQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + jest-config@30.2.0: resolution: {integrity: sha512-g4WkyzFQVWHtu6uqGmQR4CQxz/CH3yDSlhzXMWzNjDx843gYjReZnMRanjRCq5XZFuQrGDxgUaiYWE8BRfVckA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2095,38 +2653,78 @@ packages: ts-node: optional: true + jest-diff@29.7.0: + resolution: {integrity: sha512-LMIgiIrhigmPrs03JHpxUh2yISK3vLFPkAodPeo0+BuF7wA2FoQbkEg1u8gBYBThncu7e1oEDUfIXVuTqLRUjw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-diff@30.2.0: resolution: {integrity: sha512-dQHFo3Pt4/NLlG5z4PxZ/3yZTZ1C7s9hveiOj+GCN+uT109NC2QgsoVZsVOAvbJ3RgKkvyLGXZV9+piDpWbm6A==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-docblock@29.7.0: + resolution: {integrity: sha512-q617Auw3A612guyaFgsbFeYpNP5t2aoUNLwBUbc/0kD1R4t9ixDbyFTHd1nok4epoVFpr7PmeWHrhvuV3XaJ4g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-docblock@30.2.0: resolution: {integrity: sha512-tR/FFgZKS1CXluOQzZvNH3+0z9jXr3ldGSD8bhyuxvlVUwbeLOGynkunvlTMxchC5urrKndYiwCFC0DLVjpOCA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-each@29.7.0: + resolution: {integrity: sha512-gns+Er14+ZrEoC5fhOfYCY1LOHHr0TI+rQUHZS8Ttw2l7gl+80eHc/gFf2Ktkw0+SIACDTeWvpFcv3B04VembQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-each@30.2.0: resolution: {integrity: sha512-lpWlJlM7bCUf1mfmuqTA8+j2lNURW9eNafOy99knBM01i5CQeY5UH1vZjgT9071nDJac1M4XsbyI44oNOdhlDQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-environment-node@29.7.0: + resolution: {integrity: sha512-DOSwCRqXirTOyheM+4d5YZOrWcdu0LNZ87ewUoywbcb2XR4wKgqiG8vNeYwhjFMbEkfju7wx2GYH0P2gevGvFw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-environment-node@30.2.0: resolution: {integrity: sha512-ElU8v92QJ9UrYsKrxDIKCxu6PfNj4Hdcktcn0JX12zqNdqWHB0N+hwOnnBBXvjLd2vApZtuLUGs1QSY+MsXoNA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-get-type@29.6.3: + resolution: {integrity: sha512-zrteXnqYxfQh7l5FHyL38jL39di8H8rHoecLH3JNxH3BwOrBsNeabdap5e0I23lD4HHI8W5VFBZqG4Eaq5LNcw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + + jest-haste-map@29.7.0: + resolution: {integrity: sha512-fP8u2pyfqx0K1rGn1R9pyE0/KTn+G7PxktWidOBTqFPLYX0b9ksaMFkhK5vrS3DVun09pckLdlx90QthlW7AmA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-haste-map@30.2.0: resolution: {integrity: sha512-sQA/jCb9kNt+neM0anSj6eZhLZUIhQgwDt7cPGjumgLM4rXsfb9kpnlacmvZz3Q5tb80nS+oG/if+NBKrHC+Xw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-leak-detector@29.7.0: + resolution: {integrity: sha512-kYA8IJcSYtST2BY9I+SMC32nDpBT3J2NvWJx8+JCuCdl/CR1I4EKUJROiP8XtCcxqgTTBGJNdbB1A8XRKbTetw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-leak-detector@30.2.0: resolution: {integrity: sha512-M6jKAjyzjHG0SrQgwhgZGy9hFazcudwCNovY/9HPIicmNSBuockPSedAP9vlPK6ONFJ1zfyH/M2/YYJxOz5cdQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-matcher-utils@29.7.0: + resolution: {integrity: sha512-sBkD+Xi9DtcChsI3L3u0+N0opgPYnCRPtGcQYrgXmR+hmt/fYfWAL0xRXYU8eWOdfuLgBe0YCW3AFtnRLagq/g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-matcher-utils@30.2.0: resolution: {integrity: sha512-dQ94Nq4dbzmUWkQ0ANAWS9tBRfqCrn0bV9AMYdOi/MHW726xn7eQmMeRTpX2ViC00bpNaWXq+7o4lIQ3AX13Hg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-message-util@29.7.0: + resolution: {integrity: sha512-GBEV4GRADeP+qtB2+6u61stea8mGcOT4mCtrYISZwfu9/ISHFJ/5zOMXYbpBE9RsS5+Gb63DW4FgmnKJ79Kf6w==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-message-util@30.2.0: resolution: {integrity: sha512-y4DKFLZ2y6DxTWD4cDe07RglV88ZiNEdlRfGtqahfbIjfsw1nMCPx49Uev4IA/hWn3sDKyAnSPwoYSsAEdcimw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-mock@29.7.0: + resolution: {integrity: sha512-ITOMZn+UkYS4ZFh83xYAOzWStloNzJFO2s8DWrE4lhtGD+AorgnbkiKERe4wQVBydIGPx059g6riW5Btp6Llnw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-mock@30.2.0: resolution: {integrity: sha512-JNNNl2rj4b5ICpmAcq+WbLH83XswjPbjH4T7yvGzfAGCPh1rw+xVNbtk+FnRslvt9lkCcdn9i1oAoKUuFsOxRw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2140,46 +2738,96 @@ packages: jest-resolve: optional: true + jest-regex-util@29.6.3: + resolution: {integrity: sha512-KJJBsRCyyLNWCNBOvZyRDnAIfUiRJ8v+hOBQYGn8gDyF3UegwiP4gwRR3/SDa42g1YbVycTidUF3rKjyLFDWbg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-regex-util@30.0.1: resolution: {integrity: sha512-jHEQgBXAgc+Gh4g0p3bCevgRCVRkB4VB70zhoAE48gxeSr1hfUOsM/C2WoJgVL7Eyg//hudYENbm3Ne+/dRVVA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-resolve-dependencies@29.7.0: + resolution: {integrity: sha512-un0zD/6qxJ+S0et7WxeI3H5XSe9lTBBR7bOHCHXkKR6luG5mwDDlIzVQ0V5cZCuoTgEdcdwzTghYkTWfubi+nA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve-dependencies@30.2.0: resolution: {integrity: sha512-xTOIGug/0RmIe3mmCqCT95yO0vj6JURrn1TKWlNbhiAefJRWINNPgwVkrVgt/YaerPzY3iItufd80v3lOrFJ2w==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-resolve@29.7.0: + resolution: {integrity: sha512-IOVhZSrg+UvVAshDSDtHyFCCBUl/Q3AAJv8iZ6ZjnZ74xzvwuzLXid9IIIPgTnY62SJjfuupMKZsZQRsCvxEgA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-resolve@30.2.0: resolution: {integrity: sha512-TCrHSxPlx3tBY3hWNtRQKbtgLhsXa1WmbJEqBlTBrGafd5fiQFByy2GNCEoGR+Tns8d15GaL9cxEzKOO3GEb2A==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-runner@29.7.0: + resolution: {integrity: sha512-fsc4N6cPCAahybGBfTRcq5wFR6fpLznMg47sY5aDpsoejOcVYFb07AHuSnR0liMcPTgBsA3ZJL6kFOjPdoNipQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runner@30.2.0: resolution: {integrity: sha512-PqvZ2B2XEyPEbclp+gV6KO/F1FIFSbIwewRgmROCMBo/aZ6J1w8Qypoj2pEOcg3G2HzLlaP6VUtvwCI8dM3oqQ==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-runtime@29.7.0: + resolution: {integrity: sha512-gUnLjgwdGqW7B4LvOIkbKs9WGbn+QLqRQQ9juC6HndeDiezIwhDP+mhMwHWCEcfQ5RUXa6OPnFF8BJh5xegwwQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-runtime@30.2.0: resolution: {integrity: sha512-p1+GVX/PJqTucvsmERPMgCPvQJpFt4hFbM+VN3n8TMo47decMUcJbt+rgzwrEme0MQUA/R+1de2axftTHkKckg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-snapshot@29.7.0: + resolution: {integrity: sha512-Rm0BMWtxBcioHr1/OX5YCP8Uov4riHvKPknOGs804Zg9JGZgmIBkbtlxJC/7Z4msKYVbIJtfU+tKb8xlYNfdkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-snapshot@30.2.0: resolution: {integrity: sha512-5WEtTy2jXPFypadKNpbNkZ72puZCa6UjSr/7djeecHWOu7iYhSXSnHScT8wBz3Rn8Ena5d5RYRcsyKIeqG1IyA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-util@29.7.0: + resolution: {integrity: sha512-z6EbKajIpqGKU56y5KBUgy1dt1ihhQJgWzUlZHArA/+X2ad7Cb5iF+AK1EWVL/Bo7Rz9uurpqw6SiBCefUbCGA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-util@30.2.0: resolution: {integrity: sha512-QKNsM0o3Xe6ISQU869e+DhG+4CK/48aHYdJZGlFQVTjnbvgpcKyxpzk29fGiO7i/J8VENZ+d2iGnSsvmuHywlA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-validate@29.7.0: + resolution: {integrity: sha512-ZB7wHqaRGVw/9hST/OuFUReG7M8vKeq0/J2egIGLdvjHCmYqGARhzXmtgi+gVeZ5uXFF219aOc3Ls2yLg27tkw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-validate@30.2.0: resolution: {integrity: sha512-FBGWi7dP2hpdi8nBoWxSsLvBFewKAg0+uSQwBaof4Y4DPgBabXgpSYC5/lR7VmnIlSpASmCi/ntRWPbv7089Pw==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-watcher@29.7.0: + resolution: {integrity: sha512-49Fg7WXkU3Vl2h6LbLtMQ/HyB6rXSIX7SqvBLQmssRBGN9I0PNvPmAmCWSOY6SOvrjhI/F7/bGAv9RtnsPA03g==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-watcher@30.2.0: resolution: {integrity: sha512-PYxa28dxJ9g777pGm/7PrbnMeA0Jr7osHP9bS7eJy9DuAjMgdGtxgf0uKMyoIsTWAkIbUW5hSDdJ3urmgXBqxg==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest-worker@29.7.0: + resolution: {integrity: sha512-eIz2msL/EzL9UFTFFx7jBTkeZfku0yUAyZZZmJ93H2TYEiroIx2PQjEXcwYtYl8zXCxb+PAmA2hLIt/6ZEkPHw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + jest-worker@30.2.0: resolution: {integrity: sha512-0Q4Uk8WF7BUwqXHuAjc23vmopWJw5WH7w2tqBoUOZpOjW/ZnR44GXXd1r82RvnmI2GZge3ivrYXk/BE2+VtW2g==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + jest@29.7.0: + resolution: {integrity: sha512-NIy3oAFp9shda19hy4HK0HRTWKtPJmGdnvywu01nOqNC2vZg+Z+fvJDxpMQA88eb2I9EcafcdjYgsDthnYTvGw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + hasBin: true + peerDependencies: + node-notifier: ^8.0.1 || ^9.0.0 || ^10.0.0 + peerDependenciesMeta: + node-notifier: + optional: true + jest@30.2.0: resolution: {integrity: sha512-F26gjC0yWN8uAA5m5Ss8ZQf5nDHWGlN/xWZIh8S5SRbsEKBovwZhxGd6LJlbZYxBgCYOtreSUyb8hpXyGC5O4A==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} @@ -2194,13 +2842,12 @@ packages: resolution: {integrity: sha512-twQoecYPiVA5K/h6SxtORw/Bs3ar+mLUtoPSc7iMXzQzK8d7eJ/R09wmTwAjiamETn1cXYPGfNnu7DMoHgu12w==} hasBin: true + jose@6.2.12: + resolution: {integrity: sha512-9NiFmJEex0sy2Dk58j2UGBSHgUs2ypF9eZSu4L6vjOX3Dp96Sw1F3uL+H+D1sx02jZZdzUT0HgvCy59CuvXcWw==} + js-tokens@4.0.0: resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - js-yaml@3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - js-yaml@3.14.2: resolution: {integrity: sha512-PMSmkqxr106Xa156c2M265Z+FTrPl+oxd/rgOQy2tijQeK5TxQ43psO1ZCwhVOSdnn+RzkzlRz/eY4BgJBYVpg==} hasBin: true @@ -2213,6 +2860,12 @@ packages: json-parse-even-better-errors@2.3.1: resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} + json-schema-traverse@1.0.0: + resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} + + json-schema-typed@8.0.2: + resolution: {integrity: sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==} + json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -2225,6 +2878,10 @@ packages: resolution: {integrity: sha512-XCHRdUw4lf3SKBaJe4EvgqIuWwkPSo9XoeO8GjQW94Bp7TWv9hNhzZjZ+OH9yf1UmLygb7DIT5GSFQiyt16zYg==} hasBin: true + kleur@3.0.3: + resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==} + engines: {node: '>=6'} + leven@3.1.0: resolution: {integrity: sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A==} engines: {node: '>=6'} @@ -2340,6 +2997,10 @@ packages: markdown-table@3.0.4: resolution: {integrity: sha512-wiYz4+JrLyb/DqW2hkFJxP7Vd7JuTDm77fvbM8VfEQdmSMqcImWeeRbHwZjBjIFki/VaMK2BhFi7oUUZeM5bqw==} + math-intrinsics@1.1.0: + resolution: {integrity: sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==} + engines: {node: '>= 0.4'} + mdast-util-find-and-replace@3.0.2: resolution: {integrity: sha512-Tmd1Vg/m3Xz43afeNxDIhWRtFZgM2VLyaf4vSTYwudTyeuTneoL3qtWMA5jeLyz/O1vDJmmV4QuScFCA2tBPwg==} @@ -2388,6 +3049,14 @@ packages: mdast-util-to-string@4.0.0: resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==} + media-typer@1.1.1: + resolution: {integrity: sha512-yz3xRaG20c6/BOzvYoDaGtPmGscs7YivItZEEqe6GbwNfHuxu9YNmvnEkMzKldAGY4/80pRcQRZSEnhquk9XuQ==} + engines: {node: '>= 0.8'} + + merge-descriptors@2.0.0: + resolution: {integrity: sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==} + engines: {node: '>=18'} + merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} @@ -2569,6 +3238,10 @@ packages: natural-compare@1.4.0: resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} + negotiator@1.1.0: + resolution: {integrity: sha512-NMPBRMJgiQHjbd8phG3Vebdx4kZ1H121rbl5IkMqeOsahptB9BKo/d7oJ3zTXqTgagn2bWlNSXkh0QUGM31RYg==} + engines: {node: '>=18'} + neo-async@2.6.2: resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} @@ -2613,6 +3286,18 @@ packages: resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} engines: {node: '>=8'} + object-assign@4.1.1: + resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} + engines: {node: '>=0.10.0'} + + object-inspect@1.13.4: + resolution: {integrity: sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==} + engines: {node: '>= 0.4'} + + on-finished@2.4.1: + resolution: {integrity: sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==} + engines: {node: '>= 0.8'} + once@1.4.0: resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} @@ -2681,6 +3366,10 @@ packages: parse5@7.3.0: resolution: {integrity: sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==} + parseurl@1.3.3: + resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} + engines: {node: '>= 0.8'} + path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} @@ -2693,6 +3382,9 @@ packages: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} + path-parse@1.0.7: + resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} + path-scurry@1.11.1: resolution: {integrity: sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==} engines: {node: '>=16 || 14 >=14.18'} @@ -2701,6 +3393,9 @@ packages: resolution: {integrity: sha512-oWyT4gICAu+kaA7QWk/jvCHWarMKNs6pXOGWKDTr7cw4IGcUbW+PeTfbaQiLGheFRpjo6O9J0PmyMfQPjH71oA==} engines: {node: 20 || >=22} + path-to-regexp@8.4.2: + resolution: {integrity: sha512-qRcuIdP69NPm4qbACK+aDogI5CBDMi1jKe0ry5rSQJz8JVLsC7jV8XpiJjGRLLol3N+R5ihGYcrPLTno6pAdBA==} + path-type@4.0.0: resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} engines: {node: '>=8'} @@ -2724,6 +3419,10 @@ packages: resolution: {integrity: sha512-TfySrs/5nm8fQJDcBDuUng3VOUKsd7S+zqvbOTiGXHfxX4wK31ard+hoNuvkicM/2YFzlpDgABOevKSsB4G/FA==} engines: {node: '>= 6'} + pkce-challenge@5.0.1: + resolution: {integrity: sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==} + engines: {node: '>=16.20.0'} + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -2741,22 +3440,49 @@ packages: engines: {node: '>=10.13.0'} hasBin: true + pretty-format@29.7.0: + resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + pretty-format@30.2.0: resolution: {integrity: sha512-9uBdv/B4EefsuAL+pWqueZyZS2Ba+LxfFeQ9DN14HU4bN8bhaxKdkpjpB6fs9+pSjIBu+FXQHImEg8j/Lw0+vA==} engines: {node: ^18.14.0 || ^20.0.0 || ^22.0.0 || >=24.0.0} + prompts@2.4.2: + resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==} + engines: {node: '>= 6'} + property-information@7.1.0: resolution: {integrity: sha512-TwEZ+X+yCJmYfL7TPUOcvBZ4QfoT5YenQiJuX//0th53DE6w0xxLEtfK3iyryQFddXuvkIk51EEgrJQ0WJkOmQ==} + proxy-addr@2.0.8: + resolution: {integrity: sha512-5nnx0yGyVUcY6t9RnWcARWtwT9F1D8O9rt08htPvnd49W1IgZtmLkhu9WfMzQj1cFxjHIO6connUNVW5k7AVyQ==} + engines: {node: '>= 0.10'} + + pure-rand@6.1.0: + resolution: {integrity: sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA==} + pure-rand@7.0.1: resolution: {integrity: sha512-oTUZM/NAZS8p7ANR3SHh30kXB+zK2r2BPcEn/awJIbOvq82WoMN4p62AWWp3Hhw50G0xMsw1mhIBLqHw64EcNQ==} + qs@6.16.0: + resolution: {integrity: sha512-h6fhOIaRrID2CbEY2fqs+7t+UXZo+MLAnU5gRIq85uFtdiUPCdsApMlHhXogKVM4HM2DVbIjGNTTYH2OcmP1vA==} + engines: {node: '>=0.6'} + quansync@0.2.11: resolution: {integrity: sha512-AifT7QEbW9Nri4tAwR5M/uzpBuqfZf+zwaEM/QkzEjj7NBuFD2rBuy0K3dE+8wltbezDV7JMA0WfnCPYRSYbXA==} queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} + range-parser@1.3.0: + resolution: {integrity: sha512-hek2mFQpPuI4E1BBKrSto+BU3e3x4xuarsbiwr3+lf7p44juvFMV0XFWQAP3xUyqXA4RrXLIoaSUGbSt056ZMw==} + engines: {node: '>= 0.6'} + + raw-body@3.0.2: + resolution: {integrity: sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==} + engines: {node: '>= 0.10'} + react-dom@19.1.1: resolution: {integrity: sha512-Dlq/5LAZgF0Gaz6yiqZCf6VCcZs1ghAJyrsu84Q/GT0gV+mCxbfmKNoGRKBYMJ8IEdGPqu49YWXD02GCknEDkw==} peerDependencies: @@ -2857,6 +3583,10 @@ packages: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} + require-from-string@2.0.2: + resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} + engines: {node: '>=0.10.0'} + resolve-cwd@3.0.0: resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} engines: {node: '>=8'} @@ -2865,10 +3595,23 @@ packages: resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} engines: {node: '>=8'} + resolve.exports@2.0.3: + resolution: {integrity: sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==} + engines: {node: '>=10'} + + resolve@1.22.12: + resolution: {integrity: sha512-TyeJ1zif53BPfHootBGwPRYT1RUt6oGWsaQr8UyZW/eAm9bKoijtvruSDEmZHm92CwS9nj7/fWttqPCgzep8CA==} + engines: {node: '>= 0.4'} + hasBin: true + reusify@1.1.0: resolution: {integrity: sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw==} engines: {iojs: '>=1.0.0', node: '>=0.10.0'} + router@2.2.0: + resolution: {integrity: sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==} + engines: {node: '>= 18'} + run-parallel@1.2.0: resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} @@ -2895,6 +3638,17 @@ packages: engines: {node: '>=10'} hasBin: true + send@1.2.1: + resolution: {integrity: sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==} + engines: {node: '>= 18'} + + serve-static@2.2.1: + resolution: {integrity: sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==} + engines: {node: '>= 18'} + + setprototypeof@1.2.0: + resolution: {integrity: sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==} + sharp@0.34.3: resolution: {integrity: sha512-eX2IQ6nFohW4DbvHIOLRB3MHFpYqaqvXd3Tp5e/T/dSH83fxaNJQRvDMhASmkNTsNTVF2/OOopzRCt7xokgPfg==} engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0} @@ -2910,6 +3664,22 @@ packages: shiki@3.12.1: resolution: {integrity: sha512-eMlxVaXyuNQAQCaMtDKQjKv0eVm+kA6fsZtv9UqKgspP+7lWCVi7SoN+cJq1dawvIDQY7TI3SixamztotM6R6Q==} + side-channel-list@1.0.1: + resolution: {integrity: sha512-mjn/0bi/oUURjc5Xl7IaWi/OJJJumuoJFQJfDDyO46+hBWsfaVM65TBHq2eoZBhzl9EchxOijpkbRC8SVBQU0w==} + engines: {node: '>= 0.4'} + + side-channel-map@1.0.1: + resolution: {integrity: sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==} + engines: {node: '>= 0.4'} + + side-channel-weakmap@1.0.2: + resolution: {integrity: sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==} + engines: {node: '>= 0.4'} + + side-channel@1.1.1: + resolution: {integrity: sha512-6x6dK6zJdpTzF4sQeNYxwtvBzf6Eg4GtlesS94HOvTudUeyK2WXAaIfmDgsyslYrRBeFIlsi54AYsFGUuhmvrQ==} + engines: {node: '>= 0.4'} + signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} @@ -2951,6 +3721,10 @@ packages: resolution: {integrity: sha512-XlkWvfIm6RmsWtNJx+uqtKLS8eqFbxUg0ZzLXqY0caEy9l7hruX8IpiDnjsLavoBgqCCR71TqWO8MaXYheJ3RQ==} engines: {node: '>=10'} + statuses@2.0.2: + resolution: {integrity: sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==} + engines: {node: '>= 0.8'} + string-length@4.0.2: resolution: {integrity: sha512-+l6rNN5fYHNhZZy41RXsYptCjA2Igmq4EG7kZAYFQI1E1VTXarr6ZPXBg6eq7Y6eK4FEhY6AJlyuFIb/v/S0VQ==} engines: {node: '>=10'} @@ -3027,6 +3801,10 @@ packages: resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} engines: {node: '>=10'} + supports-preserve-symlinks-flag@1.0.0: + resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} + engines: {node: '>= 0.4'} + synckit@0.11.12: resolution: {integrity: sha512-Bh7QjT8/SuKUIfObSXNHNSK6WHo6J1tHCqJsuaFDP7gP0fkzSfTxI8y85JrppZ0h8l0maIgc2tfuZQ6/t3GtnQ==} engines: {node: ^14.18.0 || >=16.0.0} @@ -3061,6 +3839,10 @@ packages: resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} engines: {node: '>=8.0'} + toidentifier@1.0.1: + resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} + engines: {node: '>=0.6'} + trim-lines@3.0.1: resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==} @@ -3119,6 +3901,11 @@ packages: tslib@2.8.1: resolution: {integrity: sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==} + tsx@4.23.15: + resolution: {integrity: sha512-Yiex1Ovn8z2xPpOWckIiysV1SSyRMY9BkLF++q0yKiDxCqRhosKfMg3janKkiLBwZ5c/YryloKwGZcrEmtwxKw==} + engines: {node: '>=18.0.0'} + hasBin: true + turbo-darwin-64@2.5.6: resolution: {integrity: sha512-3C1xEdo4aFwMJAPvtlPqz1Sw/+cddWIOmsalHFMrsqqydcptwBfu26WW2cDm3u93bUzMbBJ8k3zNKFqxJ9ei2A==} cpu: [x64] @@ -3168,6 +3955,10 @@ packages: resolution: {integrity: sha512-TeTSQ6H5YHvpqVwBRcnLDCBnDOHWYu7IvGbHT6N8AOymcr9PJGjc1GTtiWZTYg0NCgYwvnYWEkVChQAr9bjfwA==} engines: {node: '>=16'} + type-is@2.1.0: + resolution: {integrity: sha512-faYHw0anBbc/kWF3zFTEnxSFOAGUX9GFbOBthvDdLsIlEoWOFOtS0zgCiQYwIskL9iGXZL3kAXD8OoZ4GmMATA==} + engines: {node: '>= 18'} + typescript@5.8.2: resolution: {integrity: sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==} engines: {node: '>=14.17'} @@ -3194,6 +3985,9 @@ packages: undici-types@7.16.0: resolution: {integrity: sha512-Zz+aZWSj8LE6zoxD+xrjh4VfkIG8Ya6LvYkZqtUQGJPZjYl53ypCaUwWqo7eI0x66KBGeRo+mlBEkMSeSZ38Nw==} + undici-types@7.24.6: + resolution: {integrity: sha512-WRNW+sJgj5OBN4/0JpHFqtqzhpbnV0GuB+OozA9gCL7a993SmU+1JBZCzLNxYsbMfIeDL+lTsphD5jN5N+n0zg==} + unified@11.0.5: resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==} @@ -3222,6 +4016,10 @@ packages: resolution: {integrity: sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg==} engines: {node: '>= 4.0.0'} + unpipe@1.0.0: + resolution: {integrity: sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==} + engines: {node: '>= 0.8'} + unrs-resolver@1.11.1: resolution: {integrity: sha512-bSjt9pjaEBnNiGgc9rUiHGKv5l4/TGzDmYw3RhnkJGtLhbnnA/5qJj7x3dNDCRx/PJxu774LlH8lCOlB4hEfKg==} @@ -3265,6 +4063,10 @@ packages: resolution: {integrity: sha512-kiGUalWN+rgBJ/1OHZsBtU4rXZOfj/7rKQxULKlIzwzQSvMJUUNgPwJEEh7gU6xEVxC0ahoOBvN2YI8GH6FNgA==} engines: {node: '>=10.12.0'} + vary@1.1.2: + resolution: {integrity: sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==} + engines: {node: '>= 0.8'} + vfile-location@5.0.3: resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==} @@ -3299,6 +4101,10 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} + write-file-atomic@4.0.2: + resolution: {integrity: sha512-7KxauUdBmSdWnmpaGFg+ppNjKF8uNLry8LyzjauQDOVONfFLNKrKvQOxZ/VuTIcS/gge/YNahf5RIIQWTSarlg==} + engines: {node: ^12.13.0 || ^14.15.0 || >=16.0.0} + write-file-atomic@5.0.1: resolution: {integrity: sha512-+QU2zd6OTD8XWIJCbffaiQeH9U73qIqafo1x6V1snCWYGJf6cVE0cDR4D8xRzcEnfI21IFrUPzPGtcPf8AC+Rw==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -3339,6 +4145,11 @@ packages: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} + zod-to-json-schema@3.25.2: + resolution: {integrity: sha512-O/PgfnpT1xKSDeQYSCfRI5Gy3hPf91mKVDuYLUHZJMiDFptvP41MSnWofm8dnCm0256ZNfZIM7DSzuSMAFnjHA==} + peerDependencies: + zod: ^3.25.28 || ^4 + zod@3.25.76: resolution: {integrity: sha512-gzUt/qt81nXsFGKIFcC3YnfEAx5NkunCfnDlvuBSSFS02bcXu4Lmea0AFIUwbLWxWPx3d9p8S5QoaujKcNQxcQ==} @@ -3592,7 +4403,7 @@ snapshots: outdent: 0.5.0 prettier: 2.8.8 resolve-from: 5.0.0 - semver: 7.7.2 + semver: 7.7.4 '@changesets/assemble-release-plan@6.0.9': dependencies: @@ -3601,7 +4412,7 @@ snapshots: '@changesets/should-skip-package': 0.1.2 '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 - semver: 7.7.2 + semver: 7.7.4 '@changesets/changelog-git@0.2.1': dependencies: @@ -3659,7 +4470,7 @@ snapshots: '@changesets/types': 6.1.0 '@manypkg/get-packages': 1.1.3 picocolors: 1.1.1 - semver: 7.7.2 + semver: 7.7.4 '@changesets/get-release-plan@4.0.13': dependencies: @@ -3687,7 +4498,7 @@ snapshots: '@changesets/parse@0.4.1': dependencies: '@changesets/types': 6.1.0 - js-yaml: 3.14.1 + js-yaml: 3.14.2 '@changesets/pre@2.0.2': dependencies: @@ -3761,6 +4572,88 @@ snapshots: tslib: 2.8.1 optional: true + '@esbuild/aix-ppc64@0.28.2': + optional: true + + '@esbuild/android-arm64@0.28.2': + optional: true + + '@esbuild/android-arm@0.28.2': + optional: true + + '@esbuild/android-x64@0.28.2': + optional: true + + '@esbuild/darwin-arm64@0.28.2': + optional: true + + '@esbuild/darwin-x64@0.28.2': + optional: true + + '@esbuild/freebsd-arm64@0.28.2': + optional: true + + '@esbuild/freebsd-x64@0.28.2': + optional: true + + '@esbuild/linux-arm64@0.28.2': + optional: true + + '@esbuild/linux-arm@0.28.2': + optional: true + + '@esbuild/linux-ia32@0.28.2': + optional: true + + '@esbuild/linux-loong64@0.28.2': + optional: true + + '@esbuild/linux-mips64el@0.28.2': + optional: true + + '@esbuild/linux-ppc64@0.28.2': + optional: true + + '@esbuild/linux-riscv64@0.28.2': + optional: true + + '@esbuild/linux-s390x@0.28.2': + optional: true + + '@esbuild/linux-x64@0.28.2': + optional: true + + '@esbuild/netbsd-arm64@0.28.2': + optional: true + + '@esbuild/netbsd-x64@0.28.2': + optional: true + + '@esbuild/openbsd-arm64@0.28.2': + optional: true + + '@esbuild/openbsd-x64@0.28.2': + optional: true + + '@esbuild/openharmony-arm64@0.28.2': + optional: true + + '@esbuild/sunos-x64@0.28.2': + optional: true + + '@esbuild/win32-arm64@0.28.2': + optional: true + + '@esbuild/win32-ia32@0.28.2': + optional: true + + '@esbuild/win32-x64@0.28.2': + optional: true + + '@hono/node-server@2.1.3(hono@4.13.12)': + dependencies: + hono: 4.13.12 + '@img/sharp-darwin-arm64@0.34.3': optionalDependencies: '@img/sharp-libvips-darwin-arm64': 1.2.0 @@ -3879,6 +4772,15 @@ snapshots: '@istanbuljs/schema@0.1.3': {} + '@jest/console@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + chalk: 4.1.2 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + '@jest/console@30.2.0': dependencies: '@jest/types': 30.2.0 @@ -3888,6 +4790,41 @@ snapshots: jest-util: 30.2.0 slash: 3.0.0 + '@jest/core@29.7.0(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3))': + dependencies: + '@jest/console': 29.7.0 + '@jest/reporters': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + ci-info: 3.9.0 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-changed-files: 29.7.0 + jest-config: 29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-resolve-dependencies: 29.7.0 + jest-runner: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + jest-watcher: 29.7.0 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-ansi: 6.0.1 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + - ts-node + '@jest/core@30.2.0(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3))': dependencies: '@jest/console': 30.2.0 @@ -3926,6 +4863,13 @@ snapshots: '@jest/diff-sequences@30.0.1': {} + '@jest/environment@29.7.0': + dependencies: + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + jest-mock: 29.7.0 + '@jest/environment@30.2.0': dependencies: '@jest/fake-timers': 30.2.0 @@ -3933,10 +4877,21 @@ snapshots: '@types/node': 25.2.3 jest-mock: 30.2.0 + '@jest/expect-utils@29.7.0': + dependencies: + jest-get-type: 29.6.3 + '@jest/expect-utils@30.2.0': dependencies: '@jest/get-type': 30.1.0 + '@jest/expect@29.7.0': + dependencies: + expect: 29.7.0 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + '@jest/expect@30.2.0': dependencies: expect: 30.2.0 @@ -3944,6 +4899,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/fake-timers@29.7.0': + dependencies: + '@jest/types': 29.6.3 + '@sinonjs/fake-timers': 10.3.0 + '@types/node': 24.19.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + '@jest/fake-timers@30.2.0': dependencies: '@jest/types': 30.2.0 @@ -3955,6 +4919,15 @@ snapshots: '@jest/get-type@30.1.0': {} + '@jest/globals@29.7.0': + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/types': 29.6.3 + jest-mock: 29.7.0 + transitivePeerDependencies: + - supports-color + '@jest/globals@30.2.0': dependencies: '@jest/environment': 30.2.0 @@ -3969,6 +4942,35 @@ snapshots: '@types/node': 25.2.3 jest-regex-util: 30.0.1 + '@jest/reporters@29.7.0': + dependencies: + '@bcoe/v8-coverage': 0.2.3 + '@jest/console': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + '@types/node': 24.19.0 + chalk: 4.1.2 + collect-v8-coverage: 1.0.3 + exit: 0.1.2 + glob: 7.2.3 + graceful-fs: 4.2.11 + istanbul-lib-coverage: 3.2.2 + istanbul-lib-instrument: 6.0.3 + istanbul-lib-report: 3.0.1 + istanbul-lib-source-maps: 4.0.1 + istanbul-reports: 3.2.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + jest-worker: 29.7.0 + slash: 3.0.0 + string-length: 4.0.2 + strip-ansi: 6.0.1 + v8-to-istanbul: 9.3.0 + transitivePeerDependencies: + - supports-color + '@jest/reporters@30.2.0': dependencies: '@bcoe/v8-coverage': 0.2.3 @@ -3997,6 +4999,10 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/schemas@29.6.3': + dependencies: + '@sinclair/typebox': 0.27.12 + '@jest/schemas@30.0.5': dependencies: '@sinclair/typebox': 0.34.48 @@ -4008,12 +5014,25 @@ snapshots: graceful-fs: 4.2.11 natural-compare: 1.4.0 + '@jest/source-map@29.6.3': + dependencies: + '@jridgewell/trace-mapping': 0.3.31 + callsites: 3.1.0 + graceful-fs: 4.2.11 + '@jest/source-map@30.0.1': dependencies: '@jridgewell/trace-mapping': 0.3.31 callsites: 3.1.0 graceful-fs: 4.2.11 + '@jest/test-result@29.7.0': + dependencies: + '@jest/console': 29.7.0 + '@jest/types': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + collect-v8-coverage: 1.0.3 + '@jest/test-result@30.2.0': dependencies: '@jest/console': 30.2.0 @@ -4021,6 +5040,13 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 collect-v8-coverage: 1.0.3 + '@jest/test-sequencer@29.7.0': + dependencies: + '@jest/test-result': 29.7.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + slash: 3.0.0 + '@jest/test-sequencer@30.2.0': dependencies: '@jest/test-result': 30.2.0 @@ -4028,6 +5054,26 @@ snapshots: jest-haste-map: 30.2.0 slash: 3.0.0 + '@jest/transform@29.7.0': + dependencies: + '@babel/core': 7.29.0 + '@jest/types': 29.6.3 + '@jridgewell/trace-mapping': 0.3.31 + babel-plugin-istanbul: 6.1.1 + chalk: 4.1.2 + convert-source-map: 2.0.0 + fast-json-stable-stringify: 2.1.0 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + micromatch: 4.0.8 + pirates: 4.0.7 + slash: 3.0.0 + write-file-atomic: 4.0.2 + transitivePeerDependencies: + - supports-color + '@jest/transform@30.2.0': dependencies: '@babel/core': 7.29.0 @@ -4048,6 +5094,15 @@ snapshots: transitivePeerDependencies: - supports-color + '@jest/types@29.6.3': + dependencies: + '@jest/schemas': 29.6.3 + '@types/istanbul-lib-coverage': 2.0.6 + '@types/istanbul-reports': 3.0.4 + '@types/node': 24.19.0 + '@types/yargs': 17.0.35 + chalk: 4.1.2 + '@jest/types@30.2.0': dependencies: '@jest/pattern': 30.0.1 @@ -4107,6 +5162,30 @@ snapshots: '@mixedbread/sdk@0.77.0': {} + '@mixedbread/sdk@0.78.0': {} + + '@modelcontextprotocol/sdk@1.31.0(zod@3.25.76)': + dependencies: + '@hono/node-server': 2.1.3(hono@4.13.12) + ajv: 8.20.0 + ajv-formats: 3.0.1(ajv@8.20.0) + content-type: 1.0.5 + cors: 2.8.6 + cross-spawn: 7.0.6 + eventsource: 3.0.7 + eventsource-parser: 3.1.1 + express: 5.2.1 + express-rate-limit: 8.7.0(express@5.2.1) + hono: 4.13.12 + jose: 6.2.12 + json-schema-typed: 8.0.2 + pkce-challenge: 5.0.1 + raw-body: 3.0.2 + zod: 3.25.76 + zod-to-json-schema: 3.25.2(zod@3.25.76) + transitivePeerDependencies: + - supports-color + '@napi-rs/wasm-runtime@0.2.12': dependencies: '@emnapi/core': 1.8.1 @@ -4412,12 +5491,18 @@ snapshots: '@shikijs/vscode-textmate@10.0.2': {} + '@sinclair/typebox@0.27.12': {} + '@sinclair/typebox@0.34.48': {} '@sinonjs/commons@3.0.1': dependencies: type-detect: 4.0.8 + '@sinonjs/fake-timers@10.3.0': + dependencies: + '@sinonjs/commons': 3.0.1 + '@sinonjs/fake-timers@13.0.5': dependencies: '@sinonjs/commons': 3.0.1 @@ -4542,6 +5627,10 @@ snapshots: '@types/estree@1.0.8': {} + '@types/graceful-fs@4.1.9': + dependencies: + '@types/node': 24.19.0 + '@types/hast@3.0.4': dependencies: '@types/unist': 3.0.3 @@ -4556,6 +5645,11 @@ snapshots: dependencies: '@types/istanbul-lib-report': 3.0.3 + '@types/jest@29.5.14': + dependencies: + expect: 29.7.0 + pretty-format: 29.7.0 + '@types/jest@30.0.0': dependencies: expect: 30.2.0 @@ -4585,6 +5679,10 @@ snapshots: dependencies: undici-types: 6.21.0 + '@types/node@24.19.0': + dependencies: + undici-types: 7.24.6 + '@types/node@25.2.3': dependencies: undici-types: 7.16.0 @@ -4670,6 +5768,11 @@ snapshots: '@unrs/resolver-binding-win32-x64-msvc@1.11.1': optional: true + accepts@2.0.0: + dependencies: + mime-types: 3.0.2 + negotiator: 1.1.0 + acorn-walk@8.3.4: dependencies: acorn: 8.15.0 @@ -4681,6 +5784,17 @@ snapshots: clean-stack: 2.2.0 indent-string: 4.0.0 + ajv-formats@3.0.1(ajv@8.20.0): + optionalDependencies: + ajv: 8.20.0 + + ajv@8.20.0: + dependencies: + fast-deep-equal: 3.1.3 + fast-uri: 3.1.8 + json-schema-traverse: 1.0.0 + require-from-string: 2.0.2 + ansi-colors@4.1.3: {} ansi-escapes@4.3.2: @@ -4716,12 +5830,25 @@ snapshots: array-union@2.1.0: {} - babel-jest@30.2.0(@babel/core@7.29.0): + babel-jest@29.7.0(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 - '@jest/transform': 30.2.0 + '@jest/transform': 29.7.0 '@types/babel__core': 7.20.5 - babel-plugin-istanbul: 7.0.1 + babel-plugin-istanbul: 6.1.1 + babel-preset-jest: 29.6.3(@babel/core@7.29.0) + chalk: 4.1.2 + graceful-fs: 4.2.11 + slash: 3.0.0 + transitivePeerDependencies: + - supports-color + + babel-jest@30.2.0(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + '@jest/transform': 30.2.0 + '@types/babel__core': 7.20.5 + babel-plugin-istanbul: 7.0.1 babel-preset-jest: 30.2.0(@babel/core@7.29.0) chalk: 4.1.2 graceful-fs: 4.2.11 @@ -4729,6 +5856,16 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-istanbul@6.1.1: + dependencies: + '@babel/helper-plugin-utils': 7.28.6 + '@istanbuljs/load-nyc-config': 1.1.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-instrument: 5.2.1 + test-exclude: 6.0.0 + transitivePeerDependencies: + - supports-color + babel-plugin-istanbul@7.0.1: dependencies: '@babel/helper-plugin-utils': 7.28.6 @@ -4739,6 +5876,13 @@ snapshots: transitivePeerDependencies: - supports-color + babel-plugin-jest-hoist@29.6.3: + dependencies: + '@babel/template': 7.28.6 + '@babel/types': 7.29.0 + '@types/babel__core': 7.20.5 + '@types/babel__traverse': 7.28.0 + babel-plugin-jest-hoist@30.2.0: dependencies: '@types/babel__core': 7.20.5 @@ -4762,6 +5906,12 @@ snapshots: '@babel/plugin-syntax-private-property-in-object': 7.14.5(@babel/core@7.29.0) '@babel/plugin-syntax-top-level-await': 7.14.5(@babel/core@7.29.0) + babel-preset-jest@29.6.3(@babel/core@7.29.0): + dependencies: + '@babel/core': 7.29.0 + babel-plugin-jest-hoist: 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + babel-preset-jest@30.2.0(@babel/core@7.29.0): dependencies: '@babel/core': 7.29.0 @@ -4782,6 +5932,20 @@ snapshots: dependencies: is-windows: 1.0.2 + body-parser@2.3.0: + dependencies: + bytes: 3.1.2 + content-type: 2.1.0 + debug: 4.4.3 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + on-finished: 2.4.1 + qs: 6.16.0 + raw-body: 3.0.2 + type-is: 2.1.0 + transitivePeerDependencies: + - supports-color + brace-expansion@1.1.12: dependencies: balanced-match: 1.0.2 @@ -4817,6 +5981,18 @@ snapshots: buffer-from@1.1.2: {} + bytes@3.1.2: {} + + call-bind-apply-helpers@1.0.2: + dependencies: + es-errors: 1.3.0 + function-bind: 1.1.2 + + call-bound@1.0.4: + dependencies: + call-bind-apply-helpers: 1.0.2 + get-intrinsic: 1.3.0 + callsites@3.1.0: {} camelcase@5.3.1: {} @@ -4854,6 +6030,8 @@ snapshots: ci-info@4.4.0: {} + cjs-module-lexer@1.4.3: {} + cjs-module-lexer@2.2.0: {} class-variance-authority@0.7.1: @@ -4908,8 +6086,38 @@ snapshots: concat-map@0.0.1: {} + content-disposition@1.1.0: {} + + content-type@1.0.5: {} + + content-type@2.1.0: {} + convert-source-map@2.0.0: {} + cookie-signature@1.2.2: {} + + cookie@0.7.2: {} + + cors@2.8.6: + dependencies: + object-assign: 4.1.1 + vary: 1.1.2 + + create-jest@29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)): + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + exit: 0.1.2 + graceful-fs: 4.2.11 + jest-config: 29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + jest-util: 29.7.0 + prompts: 2.4.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + create-require@1.1.1: {} cross-spawn@7.0.6: @@ -4932,6 +6140,8 @@ snapshots: deepmerge@4.3.1: {} + depd@2.0.0: {} + dequal@2.0.3: {} detect-indent@6.1.0: {} @@ -4946,14 +6156,24 @@ snapshots: dependencies: dequal: 2.0.3 + diff-sequences@29.6.3: {} + diff@4.0.4: {} dir-glob@3.0.1: dependencies: path-type: 4.0.0 + dunder-proto@1.0.1: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-errors: 1.3.0 + gopd: 1.2.0 + eastasianwidth@0.2.0: {} + ee-first@1.1.1: {} + electron-to-chromium@1.5.286: {} emittery@0.13.1: {} @@ -4962,6 +6182,8 @@ snapshots: emoji-regex@9.2.2: {} + encodeurl@2.0.0: {} + enhanced-resolve@5.18.3: dependencies: graceful-fs: 4.2.11 @@ -4978,8 +6200,47 @@ snapshots: dependencies: is-arrayish: 0.2.1 + es-define-property@1.0.1: {} + + es-errors@1.3.0: {} + + es-object-atoms@1.1.2: + dependencies: + es-errors: 1.3.0 + + esbuild@0.28.2: + optionalDependencies: + '@esbuild/aix-ppc64': 0.28.2 + '@esbuild/android-arm': 0.28.2 + '@esbuild/android-arm64': 0.28.2 + '@esbuild/android-x64': 0.28.2 + '@esbuild/darwin-arm64': 0.28.2 + '@esbuild/darwin-x64': 0.28.2 + '@esbuild/freebsd-arm64': 0.28.2 + '@esbuild/freebsd-x64': 0.28.2 + '@esbuild/linux-arm': 0.28.2 + '@esbuild/linux-arm64': 0.28.2 + '@esbuild/linux-ia32': 0.28.2 + '@esbuild/linux-loong64': 0.28.2 + '@esbuild/linux-mips64el': 0.28.2 + '@esbuild/linux-ppc64': 0.28.2 + '@esbuild/linux-riscv64': 0.28.2 + '@esbuild/linux-s390x': 0.28.2 + '@esbuild/linux-x64': 0.28.2 + '@esbuild/netbsd-arm64': 0.28.2 + '@esbuild/netbsd-x64': 0.28.2 + '@esbuild/openbsd-arm64': 0.28.2 + '@esbuild/openbsd-x64': 0.28.2 + '@esbuild/openharmony-arm64': 0.28.2 + '@esbuild/sunos-x64': 0.28.2 + '@esbuild/win32-arm64': 0.28.2 + '@esbuild/win32-ia32': 0.28.2 + '@esbuild/win32-x64': 0.28.2 + escalade@3.2.0: {} + escape-html@1.0.3: {} + escape-string-regexp@2.0.0: {} escape-string-regexp@5.0.0: {} @@ -4988,6 +6249,14 @@ snapshots: estree-util-is-identifier-name@3.0.0: {} + etag@1.8.1: {} + + eventsource-parser@3.1.1: {} + + eventsource@3.0.7: + dependencies: + eventsource-parser: 3.1.1 + execa@5.1.1: dependencies: cross-spawn: 7.0.6 @@ -5002,6 +6271,16 @@ snapshots: exit-x@0.2.2: {} + exit@0.1.2: {} + + expect@29.7.0: + dependencies: + '@jest/expect-utils': 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + expect@30.2.0: dependencies: '@jest/expect-utils': 30.2.0 @@ -5011,10 +6290,53 @@ snapshots: jest-mock: 30.2.0 jest-util: 30.2.0 + express-rate-limit@8.7.0(express@5.2.1): + dependencies: + debug: 4.4.3 + express: 5.2.1 + ip-address: 10.7.2 + transitivePeerDependencies: + - supports-color + + express@5.2.1: + dependencies: + accepts: 2.0.0 + body-parser: 2.3.0 + content-disposition: 1.1.0 + content-type: 1.0.5 + cookie: 0.7.2 + cookie-signature: 1.2.2 + debug: 4.4.3 + depd: 2.0.0 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + finalhandler: 2.1.1 + fresh: 2.0.0 + http-errors: 2.0.1 + merge-descriptors: 2.0.0 + mime-types: 3.0.2 + on-finished: 2.4.1 + once: 1.4.0 + parseurl: 1.3.3 + proxy-addr: 2.0.8 + qs: 6.16.0 + range-parser: 1.3.0 + router: 2.2.0 + send: 1.2.1 + serve-static: 2.2.1 + statuses: 2.0.2 + type-is: 2.1.0 + vary: 1.1.2 + transitivePeerDependencies: + - supports-color + extend@3.0.2: {} extendable-error@0.1.7: {} + fast-deep-equal@3.1.3: {} + fast-glob@3.3.3: dependencies: '@nodelib/fs.stat': 2.0.5 @@ -5025,6 +6347,8 @@ snapshots: fast-json-stable-stringify@2.1.0: {} + fast-uri@3.1.8: {} + fastq@1.20.1: dependencies: reusify: 1.1.0 @@ -5037,6 +6361,17 @@ snapshots: dependencies: to-regex-range: 5.0.1 + finalhandler@2.1.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + on-finished: 2.4.1 + parseurl: 1.3.3 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + find-up@4.1.0: dependencies: locate-path: 5.0.0 @@ -5047,6 +6382,8 @@ snapshots: cross-spawn: 7.0.6 signal-exit: 4.1.0 + forwarded@0.2.0: {} + framer-motion@12.23.12(react-dom@19.1.1(react@19.1.1))(react@19.1.1): dependencies: motion-dom: 12.23.12 @@ -5056,6 +6393,8 @@ snapshots: react: 19.1.1 react-dom: 19.1.1(react@19.1.1) + fresh@2.0.0: {} + fs-extra@7.0.1: dependencies: graceful-fs: 4.2.11 @@ -5073,14 +6412,34 @@ snapshots: fsevents@2.3.3: optional: true + function-bind@1.1.2: {} + gensync@1.0.0-beta.2: {} get-caller-file@2.0.5: {} + get-intrinsic@1.3.0: + dependencies: + call-bind-apply-helpers: 1.0.2 + es-define-property: 1.0.1 + es-errors: 1.3.0 + es-object-atoms: 1.1.2 + function-bind: 1.1.2 + get-proto: 1.0.1 + gopd: 1.2.0 + has-symbols: 1.1.0 + hasown: 2.0.4 + math-intrinsics: 1.1.0 + get-nonce@1.0.1: {} get-package-type@0.1.0: {} + get-proto@1.0.1: + dependencies: + dunder-proto: 1.0.1 + es-object-atoms: 1.1.2 + get-stdin@8.0.0: {} get-stream@6.0.1: {} @@ -5122,6 +6481,8 @@ snapshots: merge2: 1.4.1 slash: 3.0.0 + gopd@1.2.0: {} + graceful-fs@4.2.11: {} handlebars@4.7.8: @@ -5135,6 +6496,12 @@ snapshots: has-flag@4.0.0: {} + has-symbols@1.1.0: {} + + hasown@2.0.4: + dependencies: + function-bind: 1.1.2 + hast-util-from-dom@5.0.1: dependencies: '@types/hast': 3.0.4 @@ -5229,12 +6596,22 @@ snapshots: property-information: 7.1.0 space-separated-tokens: 2.0.2 + hono@4.13.12: {} + html-escaper@2.0.2: {} html-url-attributes@3.0.1: {} html-void-elements@3.0.0: {} + http-errors@2.0.1: + dependencies: + depd: 2.0.0 + inherits: 2.0.4 + setprototypeof: 1.2.0 + statuses: 2.0.2 + toidentifier: 1.0.1 + human-id@4.1.1: {} human-signals@2.1.0: {} @@ -5243,6 +6620,10 @@ snapshots: dependencies: safer-buffer: 2.1.2 + iconv-lite@0.7.3: + dependencies: + safer-buffer: 2.1.2 + ignore@5.3.2: {} import-local@3.2.0: @@ -5263,6 +6644,10 @@ snapshots: inline-style-parser@0.2.4: {} + ip-address@10.7.2: {} + + ipaddr.js@1.9.1: {} + is-alphabetical@2.0.1: {} is-alphanumerical@2.0.1: @@ -5275,6 +6660,10 @@ snapshots: is-arrayish@0.3.2: optional: true + is-core-module@2.17.0: + dependencies: + hasown: 2.0.4 + is-decimal@2.0.1: {} is-extglob@2.1.1: {} @@ -5293,6 +6682,8 @@ snapshots: is-plain-obj@4.1.0: {} + is-promise@4.0.0: {} + is-stream@2.0.1: {} is-subdir@1.2.0: @@ -5305,6 +6696,16 @@ snapshots: istanbul-lib-coverage@3.2.2: {} + istanbul-lib-instrument@5.2.1: + dependencies: + '@babel/core': 7.29.0 + '@babel/parser': 7.29.0 + '@istanbuljs/schema': 0.1.3 + istanbul-lib-coverage: 3.2.2 + semver: 6.3.1 + transitivePeerDependencies: + - supports-color + istanbul-lib-instrument@6.0.3: dependencies: '@babel/core': 7.29.0 @@ -5321,6 +6722,14 @@ snapshots: make-dir: 4.0.0 supports-color: 7.2.0 + istanbul-lib-source-maps@4.0.1: + dependencies: + debug: 4.4.3 + istanbul-lib-coverage: 3.2.2 + source-map: 0.6.1 + transitivePeerDependencies: + - supports-color + istanbul-lib-source-maps@5.0.6: dependencies: '@jridgewell/trace-mapping': 0.3.31 @@ -5344,12 +6753,44 @@ snapshots: dependencies: '@isaacs/cliui': 9.0.0 + jest-changed-files@29.7.0: + dependencies: + execa: 5.1.1 + jest-util: 29.7.0 + p-limit: 3.1.0 + jest-changed-files@30.2.0: dependencies: execa: 5.1.1 jest-util: 30.2.0 p-limit: 3.1.0 + jest-circus@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/expect': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + chalk: 4.1.2 + co: 4.6.0 + dedent: 1.7.1 + is-generator-fn: 2.1.0 + jest-each: 29.7.0 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-runtime: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + p-limit: 3.1.0 + pretty-format: 29.7.0 + pure-rand: 6.1.0 + slash: 3.0.0 + stack-utils: 2.0.6 + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-circus@30.2.0: dependencies: '@jest/environment': 30.2.0 @@ -5376,6 +6817,25 @@ snapshots: - babel-plugin-macros - supports-color + jest-cli@29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + chalk: 4.1.2 + create-jest: 29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + exit: 0.1.2 + import-local: 3.2.0 + jest-config: 29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + jest-util: 29.7.0 + jest-validate: 29.7.0 + yargs: 17.7.2 + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest-cli@30.2.0(@types/node@25.2.3)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)): dependencies: '@jest/core': 30.2.0(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)) @@ -5395,6 +6855,37 @@ snapshots: - supports-color - ts-node + jest-config@29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)): + dependencies: + '@babel/core': 7.29.0 + '@jest/test-sequencer': 29.7.0 + '@jest/types': 29.6.3 + babel-jest: 29.7.0(@babel/core@7.29.0) + chalk: 4.1.2 + ci-info: 3.9.0 + deepmerge: 4.3.1 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-circus: 29.7.0 + jest-environment-node: 29.7.0 + jest-get-type: 29.6.3 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-runner: 29.7.0 + jest-util: 29.7.0 + jest-validate: 29.7.0 + micromatch: 4.0.8 + parse-json: 5.2.0 + pretty-format: 29.7.0 + slash: 3.0.0 + strip-json-comments: 3.1.1 + optionalDependencies: + '@types/node': 24.19.0 + ts-node: 10.9.2(@types/node@24.19.0)(typescript@5.9.3) + transitivePeerDependencies: + - babel-plugin-macros + - supports-color + jest-config@30.2.0(@types/node@25.2.3)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)): dependencies: '@babel/core': 7.29.0 @@ -5428,6 +6919,13 @@ snapshots: - babel-plugin-macros - supports-color + jest-diff@29.7.0: + dependencies: + chalk: 4.1.2 + diff-sequences: 29.6.3 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + jest-diff@30.2.0: dependencies: '@jest/diff-sequences': 30.0.1 @@ -5435,10 +6933,22 @@ snapshots: chalk: 4.1.2 pretty-format: 30.2.0 + jest-docblock@29.7.0: + dependencies: + detect-newline: 3.1.0 + jest-docblock@30.2.0: dependencies: detect-newline: 3.1.0 + jest-each@29.7.0: + dependencies: + '@jest/types': 29.6.3 + chalk: 4.1.2 + jest-get-type: 29.6.3 + jest-util: 29.7.0 + pretty-format: 29.7.0 + jest-each@30.2.0: dependencies: '@jest/get-type': 30.1.0 @@ -5447,6 +6957,15 @@ snapshots: jest-util: 30.2.0 pretty-format: 30.2.0 + jest-environment-node@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + jest-mock: 29.7.0 + jest-util: 29.7.0 + jest-environment-node@30.2.0: dependencies: '@jest/environment': 30.2.0 @@ -5457,6 +6976,24 @@ snapshots: jest-util: 30.2.0 jest-validate: 30.2.0 + jest-get-type@29.6.3: {} + + jest-haste-map@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/graceful-fs': 4.1.9 + '@types/node': 24.19.0 + anymatch: 3.1.3 + fb-watchman: 2.0.2 + graceful-fs: 4.2.11 + jest-regex-util: 29.6.3 + jest-util: 29.7.0 + jest-worker: 29.7.0 + micromatch: 4.0.8 + walker: 1.0.8 + optionalDependencies: + fsevents: 2.3.3 + jest-haste-map@30.2.0: dependencies: '@jest/types': 30.2.0 @@ -5472,11 +7009,23 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + jest-leak-detector@29.7.0: + dependencies: + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + jest-leak-detector@30.2.0: dependencies: '@jest/get-type': 30.1.0 pretty-format: 30.2.0 + jest-matcher-utils@29.7.0: + dependencies: + chalk: 4.1.2 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + pretty-format: 29.7.0 + jest-matcher-utils@30.2.0: dependencies: '@jest/get-type': 30.1.0 @@ -5484,6 +7033,18 @@ snapshots: jest-diff: 30.2.0 pretty-format: 30.2.0 + jest-message-util@29.7.0: + dependencies: + '@babel/code-frame': 7.29.0 + '@jest/types': 29.6.3 + '@types/stack-utils': 2.0.3 + chalk: 4.1.2 + graceful-fs: 4.2.11 + micromatch: 4.0.8 + pretty-format: 29.7.0 + slash: 3.0.0 + stack-utils: 2.0.6 + jest-message-util@30.2.0: dependencies: '@babel/code-frame': 7.29.0 @@ -5496,18 +7057,37 @@ snapshots: slash: 3.0.0 stack-utils: 2.0.6 + jest-mock@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + jest-util: 29.7.0 + jest-mock@30.2.0: dependencies: '@jest/types': 30.2.0 '@types/node': 25.2.3 jest-util: 30.2.0 + jest-pnp-resolver@1.2.3(jest-resolve@29.7.0): + optionalDependencies: + jest-resolve: 29.7.0 + jest-pnp-resolver@1.2.3(jest-resolve@30.2.0): optionalDependencies: jest-resolve: 30.2.0 + jest-regex-util@29.6.3: {} + jest-regex-util@30.0.1: {} + jest-resolve-dependencies@29.7.0: + dependencies: + jest-regex-util: 29.6.3 + jest-snapshot: 29.7.0 + transitivePeerDependencies: + - supports-color + jest-resolve-dependencies@30.2.0: dependencies: jest-regex-util: 30.0.1 @@ -5515,6 +7095,18 @@ snapshots: transitivePeerDependencies: - supports-color + jest-resolve@29.7.0: + dependencies: + chalk: 4.1.2 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-pnp-resolver: 1.2.3(jest-resolve@29.7.0) + jest-util: 29.7.0 + jest-validate: 29.7.0 + resolve: 1.22.12 + resolve.exports: 2.0.3 + slash: 3.0.0 + jest-resolve@30.2.0: dependencies: chalk: 4.1.2 @@ -5526,6 +7118,32 @@ snapshots: slash: 3.0.0 unrs-resolver: 1.11.1 + jest-runner@29.7.0: + dependencies: + '@jest/console': 29.7.0 + '@jest/environment': 29.7.0 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + chalk: 4.1.2 + emittery: 0.13.1 + graceful-fs: 4.2.11 + jest-docblock: 29.7.0 + jest-environment-node: 29.7.0 + jest-haste-map: 29.7.0 + jest-leak-detector: 29.7.0 + jest-message-util: 29.7.0 + jest-resolve: 29.7.0 + jest-runtime: 29.7.0 + jest-util: 29.7.0 + jest-watcher: 29.7.0 + jest-worker: 29.7.0 + p-limit: 3.1.0 + source-map-support: 0.5.13 + transitivePeerDependencies: + - supports-color + jest-runner@30.2.0: dependencies: '@jest/console': 30.2.0 @@ -5553,6 +7171,33 @@ snapshots: transitivePeerDependencies: - supports-color + jest-runtime@29.7.0: + dependencies: + '@jest/environment': 29.7.0 + '@jest/fake-timers': 29.7.0 + '@jest/globals': 29.7.0 + '@jest/source-map': 29.6.3 + '@jest/test-result': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + chalk: 4.1.2 + cjs-module-lexer: 1.4.3 + collect-v8-coverage: 1.0.3 + glob: 7.2.3 + graceful-fs: 4.2.11 + jest-haste-map: 29.7.0 + jest-message-util: 29.7.0 + jest-mock: 29.7.0 + jest-regex-util: 29.6.3 + jest-resolve: 29.7.0 + jest-snapshot: 29.7.0 + jest-util: 29.7.0 + slash: 3.0.0 + strip-bom: 4.0.0 + transitivePeerDependencies: + - supports-color + jest-runtime@30.2.0: dependencies: '@jest/environment': 30.2.0 @@ -5580,6 +7225,31 @@ snapshots: transitivePeerDependencies: - supports-color + jest-snapshot@29.7.0: + dependencies: + '@babel/core': 7.29.0 + '@babel/generator': 7.29.1 + '@babel/plugin-syntax-jsx': 7.28.6(@babel/core@7.29.0) + '@babel/plugin-syntax-typescript': 7.28.6(@babel/core@7.29.0) + '@babel/types': 7.29.0 + '@jest/expect-utils': 29.7.0 + '@jest/transform': 29.7.0 + '@jest/types': 29.6.3 + babel-preset-current-node-syntax: 1.2.0(@babel/core@7.29.0) + chalk: 4.1.2 + expect: 29.7.0 + graceful-fs: 4.2.11 + jest-diff: 29.7.0 + jest-get-type: 29.6.3 + jest-matcher-utils: 29.7.0 + jest-message-util: 29.7.0 + jest-util: 29.7.0 + natural-compare: 1.4.0 + pretty-format: 29.7.0 + semver: 7.7.4 + transitivePeerDependencies: + - supports-color + jest-snapshot@30.2.0: dependencies: '@babel/core': 7.29.0 @@ -5606,6 +7276,15 @@ snapshots: transitivePeerDependencies: - supports-color + jest-util@29.7.0: + dependencies: + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + chalk: 4.1.2 + ci-info: 3.9.0 + graceful-fs: 4.2.11 + picomatch: 2.3.1 + jest-util@30.2.0: dependencies: '@jest/types': 30.2.0 @@ -5615,6 +7294,15 @@ snapshots: graceful-fs: 4.2.11 picomatch: 4.0.3 + jest-validate@29.7.0: + dependencies: + '@jest/types': 29.6.3 + camelcase: 6.3.0 + chalk: 4.1.2 + jest-get-type: 29.6.3 + leven: 3.1.0 + pretty-format: 29.7.0 + jest-validate@30.2.0: dependencies: '@jest/get-type': 30.1.0 @@ -5624,6 +7312,17 @@ snapshots: leven: 3.1.0 pretty-format: 30.2.0 + jest-watcher@29.7.0: + dependencies: + '@jest/test-result': 29.7.0 + '@jest/types': 29.6.3 + '@types/node': 24.19.0 + ansi-escapes: 4.3.2 + chalk: 4.1.2 + emittery: 0.13.1 + jest-util: 29.7.0 + string-length: 4.0.2 + jest-watcher@30.2.0: dependencies: '@jest/test-result': 30.2.0 @@ -5635,6 +7334,13 @@ snapshots: jest-util: 30.2.0 string-length: 4.0.2 + jest-worker@29.7.0: + dependencies: + '@types/node': 24.19.0 + jest-util: 29.7.0 + merge-stream: 2.0.0 + supports-color: 8.1.1 + jest-worker@30.2.0: dependencies: '@types/node': 25.2.3 @@ -5643,6 +7349,18 @@ snapshots: merge-stream: 2.0.0 supports-color: 8.1.1 + jest@29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)): + dependencies: + '@jest/core': 29.7.0(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + '@jest/types': 29.6.3 + import-local: 3.2.0 + jest-cli: 29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + transitivePeerDependencies: + - '@types/node' + - babel-plugin-macros + - supports-color + - ts-node + jest@30.2.0(@types/node@25.2.3)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)): dependencies: '@jest/core': 30.2.0(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)) @@ -5658,12 +7376,9 @@ snapshots: jiti@2.5.1: {} - js-tokens@4.0.0: {} + jose@6.2.12: {} - js-yaml@3.14.1: - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 + js-tokens@4.0.0: {} js-yaml@3.14.2: dependencies: @@ -5674,6 +7389,10 @@ snapshots: json-parse-even-better-errors@2.3.1: {} + json-schema-traverse@1.0.0: {} + + json-schema-typed@8.0.2: {} + json5@2.2.3: {} jsonfile@4.0.0: @@ -5684,6 +7403,8 @@ snapshots: dependencies: commander: 8.3.0 + kleur@3.0.3: {} + leven@3.1.0: {} lightningcss-darwin-arm64@1.30.1: @@ -5771,6 +7492,8 @@ snapshots: markdown-table@3.0.4: {} + math-intrinsics@1.1.0: {} + mdast-util-find-and-replace@3.0.2: dependencies: '@types/mdast': 4.0.4 @@ -5936,6 +7659,10 @@ snapshots: dependencies: '@types/mdast': 4.0.4 + media-typer@1.1.1: {} + + merge-descriptors@2.0.0: {} + merge-stream@2.0.0: {} merge2@1.4.1: {} @@ -6202,6 +7929,10 @@ snapshots: natural-compare@1.4.0: {} + negotiator@1.1.0: + dependencies: + content-type: 2.1.0 + neo-async@2.6.2: {} next-themes@0.4.6(react-dom@19.1.1(react@19.1.1))(react@19.1.1): @@ -6242,6 +7973,14 @@ snapshots: dependencies: path-key: 3.1.1 + object-assign@4.1.1: {} + + object-inspect@1.13.4: {} + + on-finished@2.4.1: + dependencies: + ee-first: 1.1.1 + once@1.4.0: dependencies: wrappy: 1.0.2 @@ -6319,12 +8058,16 @@ snapshots: dependencies: entities: 6.0.1 + parseurl@1.3.3: {} + path-exists@4.0.0: {} path-is-absolute@1.0.1: {} path-key@3.1.1: {} + path-parse@1.0.7: {} + path-scurry@1.11.1: dependencies: lru-cache: 10.4.3 @@ -6335,6 +8078,8 @@ snapshots: lru-cache: 11.2.6 minipass: 7.1.2 + path-to-regexp@8.4.2: {} + path-type@4.0.0: {} picocolors@1.1.1: {} @@ -6347,6 +8092,8 @@ snapshots: pirates@4.0.7: {} + pkce-challenge@5.0.1: {} + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -6365,20 +8112,52 @@ snapshots: prettier@2.8.8: {} + pretty-format@29.7.0: + dependencies: + '@jest/schemas': 29.6.3 + ansi-styles: 5.2.0 + react-is: 18.3.1 + pretty-format@30.2.0: dependencies: '@jest/schemas': 30.0.5 ansi-styles: 5.2.0 react-is: 18.3.1 + prompts@2.4.2: + dependencies: + kleur: 3.0.3 + sisteransi: 1.0.5 + property-information@7.1.0: {} + proxy-addr@2.0.8: + dependencies: + forwarded: 0.2.0 + ipaddr.js: 1.9.1 + + pure-rand@6.1.0: {} + pure-rand@7.0.1: {} + qs@6.16.0: + dependencies: + es-define-property: 1.0.1 + side-channel: 1.1.1 + quansync@0.2.11: {} queue-microtask@1.2.3: {} + range-parser@1.3.0: {} + + raw-body@3.0.2: + dependencies: + bytes: 3.1.2 + http-errors: 2.0.1 + iconv-lite: 0.7.3 + unpipe: 1.0.0 + react-dom@19.1.1(react@19.1.1): dependencies: react: 19.1.1 @@ -6451,7 +8230,7 @@ snapshots: read-yaml-file@1.1.0: dependencies: graceful-fs: 4.2.11 - js-yaml: 3.14.1 + js-yaml: 3.14.2 pify: 4.0.1 strip-bom: 3.0.0 @@ -6526,14 +8305,35 @@ snapshots: require-directory@2.1.1: {} + require-from-string@2.0.2: {} + resolve-cwd@3.0.0: dependencies: resolve-from: 5.0.0 resolve-from@5.0.0: {} + resolve.exports@2.0.3: {} + + resolve@1.22.12: + dependencies: + es-errors: 1.3.0 + is-core-module: 2.17.0 + path-parse: 1.0.7 + supports-preserve-symlinks-flag: 1.0.0 + reusify@1.1.0: {} + router@2.2.0: + dependencies: + debug: 4.4.3 + depd: 2.0.0 + is-promise: 4.0.0 + parseurl: 1.3.3 + path-to-regexp: 8.4.2 + transitivePeerDependencies: + - supports-color + run-parallel@1.2.0: dependencies: queue-microtask: 1.2.3 @@ -6550,6 +8350,33 @@ snapshots: semver@7.7.4: {} + send@1.2.1: + dependencies: + debug: 4.4.3 + encodeurl: 2.0.0 + escape-html: 1.0.3 + etag: 1.8.1 + fresh: 2.0.0 + http-errors: 2.0.1 + mime-types: 3.0.2 + ms: 2.1.3 + on-finished: 2.4.1 + range-parser: 1.3.0 + statuses: 2.0.2 + transitivePeerDependencies: + - supports-color + + serve-static@2.2.1: + dependencies: + encodeurl: 2.0.0 + escape-html: 1.0.3 + parseurl: 1.3.3 + send: 1.2.1 + transitivePeerDependencies: + - supports-color + + setprototypeof@1.2.0: {} + sharp@0.34.3: dependencies: color: 4.2.3 @@ -6597,6 +8424,34 @@ snapshots: '@shikijs/vscode-textmate': 10.0.2 '@types/hast': 3.0.4 + side-channel-list@1.0.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + + side-channel-map@1.0.1: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + + side-channel-weakmap@1.0.2: + dependencies: + call-bound: 1.0.4 + es-errors: 1.3.0 + get-intrinsic: 1.3.0 + object-inspect: 1.13.4 + side-channel-map: 1.0.1 + + side-channel@1.1.1: + dependencies: + es-errors: 1.3.0 + object-inspect: 1.13.4 + side-channel-list: 1.0.1 + side-channel-map: 1.0.1 + side-channel-weakmap: 1.0.2 + signal-exit@3.0.7: {} signal-exit@4.1.0: {} @@ -6632,6 +8487,8 @@ snapshots: dependencies: escape-string-regexp: 2.0.0 + statuses@2.0.2: {} + string-length@4.0.2: dependencies: char-regex: 1.0.2 @@ -6701,6 +8558,8 @@ snapshots: dependencies: has-flag: 4.0.0 + supports-preserve-symlinks-flag@1.0.0: {} + synckit@0.11.12: dependencies: '@pkgr/core': 0.2.9 @@ -6734,10 +8593,32 @@ snapshots: dependencies: is-number: 7.0.0 + toidentifier@1.0.1: {} + trim-lines@3.0.1: {} trough@2.2.0: {} + ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)))(typescript@5.9.3): + dependencies: + bs-logger: 0.2.6 + fast-json-stable-stringify: 2.1.0 + handlebars: 4.7.8 + jest: 29.7.0(@types/node@24.19.0)(ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3)) + json5: 2.2.3 + lodash.memoize: 4.1.2 + make-error: 1.3.6 + semver: 7.7.4 + type-fest: 4.41.0 + typescript: 5.9.3 + yargs-parser: 21.1.1 + optionalDependencies: + '@babel/core': 7.29.0 + '@jest/transform': 30.2.0 + '@jest/types': 30.2.0 + babel-jest: 30.2.0(@babel/core@7.29.0) + jest-util: 30.2.0 + ts-jest@29.4.6(@babel/core@7.29.0)(@jest/transform@30.2.0)(@jest/types@30.2.0)(babel-jest@30.2.0(@babel/core@7.29.0))(jest-util@30.2.0)(jest@30.2.0(@types/node@25.2.3)(ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3)))(typescript@5.9.3): dependencies: bs-logger: 0.2.6 @@ -6758,6 +8639,25 @@ snapshots: babel-jest: 30.2.0(@babel/core@7.29.0) jest-util: 30.2.0 + ts-node@10.9.2(@types/node@24.19.0)(typescript@5.9.3): + dependencies: + '@cspotcode/source-map-support': 0.8.1 + '@tsconfig/node10': 1.0.12 + '@tsconfig/node12': 1.0.11 + '@tsconfig/node14': 1.0.3 + '@tsconfig/node16': 1.0.4 + '@types/node': 24.19.0 + acorn: 8.15.0 + acorn-walk: 8.3.4 + arg: 4.1.3 + create-require: 1.1.1 + diff: 4.0.4 + make-error: 1.3.6 + typescript: 5.9.3 + v8-compile-cache-lib: 3.0.1 + yn: 3.1.1 + optional: true + ts-node@10.9.2(@types/node@25.2.3)(typescript@5.9.3): dependencies: '@cspotcode/source-map-support': 0.8.1 @@ -6794,6 +8694,12 @@ snapshots: tslib@2.8.1: {} + tsx@4.23.15: + dependencies: + esbuild: 0.28.2 + optionalDependencies: + fsevents: 2.3.3 + turbo-darwin-64@2.5.6: optional: true @@ -6829,6 +8735,12 @@ snapshots: type-fest@4.41.0: {} + type-is@2.1.0: + dependencies: + content-type: 2.1.0 + media-typer: 1.1.1 + mime-types: 3.0.2 + typescript@5.8.2: {} typescript@5.8.3: {} @@ -6842,6 +8754,8 @@ snapshots: undici-types@7.16.0: {} + undici-types@7.24.6: {} + unified@11.0.5: dependencies: '@types/unist': 3.0.3 @@ -6887,6 +8801,8 @@ snapshots: universalify@0.1.2: {} + unpipe@1.0.0: {} + unrs-resolver@1.11.1: dependencies: napi-postinstall: 0.3.4 @@ -6944,6 +8860,8 @@ snapshots: '@types/istanbul-lib-coverage': 2.0.6 convert-source-map: 2.0.0 + vary@1.1.2: {} + vfile-location@5.0.3: dependencies: '@types/unist': 3.0.3 @@ -6985,6 +8903,11 @@ snapshots: wrappy@1.0.2: {} + write-file-atomic@4.0.2: + dependencies: + imurmurhash: 0.1.4 + signal-exit: 3.0.7 + write-file-atomic@5.0.1: dependencies: imurmurhash: 0.1.4 @@ -7016,6 +8939,10 @@ snapshots: yocto-queue@1.2.2: {} + zod-to-json-schema@3.25.2(zod@3.25.76): + dependencies: + zod: 3.25.76 + zod@3.25.76: {} zod@4.3.6: {}