From cd8eb5060fdfd6042ba05234d33f8167950120ae Mon Sep 17 00:00:00 2001 From: Ben Rabinovich Date: Thu, 8 Jan 2026 14:31:31 +0200 Subject: [PATCH 1/4] feat: custom endpoints --- examples/custom-endpoints-demo.ts | 557 +++++++++++++++++ src/http/FastifyTransport.ts | 15 + src/http/customEndpoints.ts | 322 ++++++++++ src/http/endpointRegistration.ts | 202 ++++++ src/index.ts | 16 + .../PermissionAwareFastifyTransport.ts | 39 ++ src/server/createMcpServer.ts | 7 + tests/customEndpoints.integration.test.ts | 530 ++++++++++++++++ tests/customEndpoints.test.ts | 573 ++++++++++++++++++ 9 files changed, 2261 insertions(+) create mode 100644 examples/custom-endpoints-demo.ts create mode 100644 src/http/customEndpoints.ts create mode 100644 src/http/endpointRegistration.ts create mode 100644 tests/customEndpoints.integration.test.ts create mode 100644 tests/customEndpoints.test.ts diff --git a/examples/custom-endpoints-demo.ts b/examples/custom-endpoints-demo.ts new file mode 100644 index 0000000..ece2275 --- /dev/null +++ b/examples/custom-endpoints-demo.ts @@ -0,0 +1,557 @@ +#!/usr/bin/env tsx + +/** + * Example server demonstrating custom endpoint functionality. + * + * This example shows: + * - Basic GET/POST/PUT/DELETE endpoints with Zod validation + * - Query parameter validation and coercion + * - Path parameter validation + * - Request body validation + * - Response validation + * - Client ID extraction + * - Permission-aware endpoints + * + * Run this example with: + * npx tsx examples/custom-endpoints-demo.ts + * + * Then test the endpoints with curl: + * curl "http://localhost:3000/api/users?limit=5" + * curl -X POST http://localhost:3000/api/users -H 'Content-Type: application/json' -d '{"name":"Alice","email":"alice@example.com"}' + */ + +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import { z } from "zod"; +import { + createMcpServer, + createPermissionBasedMcpServer, + defineEndpoint, + definePermissionAwareEndpoint, +} from "../src/index.js"; + +// ============================================================================ +// Example 1: Standard Server with Custom Endpoints +// ============================================================================ + +async function runStandardServerExample() { + console.log("\nšŸš€ Starting Standard MCP Server with Custom Endpoints\n"); + + const server = await createMcpServer({ + createServer: () => + new McpServer({ + name: "custom-endpoints-demo", + version: "1.0.0", + }), + catalog: { + // Example toolset - not the focus of this demo + "greeting-tools": { + name: "Greeting Tools", + description: "Simple greeting tools", + tools: [ + { + name: "greet", + description: "Greet a user", + inputSchema: { + type: "object", + properties: { + name: { type: "string" }, + }, + required: ["name"], + }, + handler: async (args: any) => ({ + content: [ + { + type: "text", + text: `Hello, ${args.name}!`, + }, + ], + }), + }, + ], + }, + }, + startup: { + mode: "STATIC", + toolsets: ["greeting-tools"], + }, + http: { + port: 3000, + customEndpoints: [ + // ==================================================================== + // GET endpoint with query parameter validation + // ==================================================================== + defineEndpoint({ + method: "GET", + path: "/api/users", + description: "Get a list of users with pagination", + querySchema: z.object({ + // Coerce string to number (query params are always strings) + limit: z.coerce.number().int().positive().max(100).default(10), + offset: z.coerce.number().int().nonnegative().default(0), + // Optional filter + role: z.enum(["admin", "user", "guest"]).optional(), + // Search query + search: z.string().optional(), + }), + responseSchema: z.object({ + users: z.array( + z.object({ + id: z.string(), + name: z.string(), + email: z.string().email(), + role: z.string(), + }) + ), + pagination: z.object({ + limit: z.number(), + offset: z.number(), + total: z.number(), + }), + }), + handler: async (req) => { + console.log( + `šŸ“„ GET /api/users - Client: ${req.clientId}, Query:`, + req.query + ); + + // Mock database + const allUsers = [ + { + id: "1", + name: "Alice Johnson", + email: "alice@example.com", + role: "admin", + }, + { + id: "2", + name: "Bob Smith", + email: "bob@example.com", + role: "user", + }, + { + id: "3", + name: "Charlie Brown", + email: "charlie@example.com", + role: "user", + }, + { + id: "4", + name: "Diana Prince", + email: "diana@example.com", + role: "guest", + }, + ]; + + // Filter by role + let filtered = req.query.role + ? allUsers.filter((u) => u.role === req.query.role) + : allUsers; + + // Filter by search + if (req.query.search) { + const searchLower = req.query.search.toLowerCase(); + filtered = filtered.filter( + (u) => + u.name.toLowerCase().includes(searchLower) || + u.email.toLowerCase().includes(searchLower) + ); + } + + // Paginate + const users = filtered.slice( + req.query.offset, + req.query.offset + req.query.limit + ); + + return { + users, + pagination: { + limit: req.query.limit, + offset: req.query.offset, + total: filtered.length, + }, + }; + }, + }), + + // ==================================================================== + // POST endpoint with body validation + // ==================================================================== + defineEndpoint({ + method: "POST", + path: "/api/users", + description: "Create a new user", + bodySchema: z.object({ + name: z.string().min(1, "Name is required").max(100), + email: z.string().email("Invalid email address"), + role: z.enum(["admin", "user", "guest"]).default("user"), + age: z.number().int().positive().optional(), + }), + responseSchema: z.object({ + id: z.string(), + name: z.string(), + email: z.string(), + role: z.string(), + createdAt: z.string().datetime(), + }), + handler: async (req) => { + console.log( + `šŸ“„ POST /api/users - Client: ${req.clientId}, Body:`, + req.body + ); + + // Simulate database insert + const newUser = { + id: `user-${Date.now()}`, + name: req.body.name, + email: req.body.email, + role: req.body.role, + createdAt: new Date().toISOString(), + }; + + return newUser; + }, + }), + + // ==================================================================== + // GET endpoint with path parameters + // ==================================================================== + defineEndpoint({ + method: "GET", + path: "/api/users/:userId", + description: "Get a user by ID", + paramsSchema: z.object({ + userId: z.string().min(1, "User ID is required"), + }), + responseSchema: z.object({ + id: z.string(), + name: z.string(), + email: z.string(), + role: z.string(), + }), + handler: async (req) => { + console.log( + `šŸ“„ GET /api/users/:userId - Client: ${req.clientId}, UserId: ${req.params.userId}` + ); + + // Simulate database lookup + return { + id: req.params.userId, + name: "Example User", + email: "user@example.com", + role: "user", + }; + }, + }), + + // ==================================================================== + // PUT endpoint for updates + // ==================================================================== + defineEndpoint({ + method: "PUT", + path: "/api/users/:userId", + description: "Update a user", + paramsSchema: z.object({ + userId: z.string(), + }), + bodySchema: z.object({ + name: z.string().min(1).optional(), + email: z.string().email().optional(), + role: z.enum(["admin", "user", "guest"]).optional(), + }), + responseSchema: z.object({ + id: z.string(), + name: z.string(), + email: z.string(), + role: z.string(), + updatedAt: z.string().datetime(), + }), + handler: async (req) => { + console.log( + `šŸ“„ PUT /api/users/:userId - Client: ${req.clientId}, UserId: ${req.params.userId}, Body:`, + req.body + ); + + return { + id: req.params.userId, + name: req.body.name || "Example User", + email: req.body.email || "user@example.com", + role: req.body.role || "user", + updatedAt: new Date().toISOString(), + }; + }, + }), + + // ==================================================================== + // DELETE endpoint + // ==================================================================== + defineEndpoint({ + method: "DELETE", + path: "/api/users/:userId", + description: "Delete a user", + paramsSchema: z.object({ + userId: z.string(), + }), + responseSchema: z.object({ + success: z.boolean(), + deletedId: z.string(), + deletedAt: z.string().datetime(), + }), + handler: async (req) => { + console.log( + `šŸ“„ DELETE /api/users/:userId - Client: ${req.clientId}, UserId: ${req.params.userId}` + ); + + return { + success: true, + deletedId: req.params.userId, + deletedAt: new Date().toISOString(), + }; + }, + }), + + // ==================================================================== + // Status endpoint showing client ID access + // ==================================================================== + defineEndpoint({ + method: "GET", + path: "/api/status", + description: "Get server status and client info", + responseSchema: z.object({ + status: z.string(), + clientId: z.string(), + timestamp: z.number(), + version: z.string(), + }), + handler: async (req) => { + console.log(`šŸ“„ GET /api/status - Client: ${req.clientId}`); + + return { + status: "ok", + clientId: req.clientId, + timestamp: Date.now(), + version: "1.0.0", + }; + }, + }), + ], + }, + }); + + await server.start(); + + console.log("āœ… Server started on http://localhost:3000\n"); + console.log("šŸ“ Available Custom Endpoints:"); + console.log(" GET /api/users - List users with pagination"); + console.log(" POST /api/users - Create a new user"); + console.log(" GET /api/users/:userId - Get a specific user"); + console.log(" PUT /api/users/:userId - Update a user"); + console.log(" DELETE /api/users/:userId - Delete a user"); + console.log(" GET /api/status - Server status\n"); + + console.log("šŸ“ Built-in MCP Endpoints:"); + console.log(" GET /healthz - Health check"); + console.log(" GET /tools - Available toolsets"); + console.log(" POST /mcp - MCP JSON-RPC endpoint\n"); + + console.log("šŸ’” Example curl commands:"); + console.log( + '\n # List users\n curl "http://localhost:3000/api/users"' + ); + console.log( + '\n # List users with pagination and filtering\n curl "http://localhost:3000/api/users?limit=2&offset=0&role=user"' + ); + console.log( + '\n # Search users\n curl "http://localhost:3000/api/users?search=alice"' + ); + console.log( + "\n # Create a user\n curl -X POST http://localhost:3000/api/users \\\n -H 'Content-Type: application/json' \\\n -d '{\"name\":\"Alice\",\"email\":\"alice@example.com\",\"role\":\"admin\"}'" + ); + console.log( + '\n # Get a user\n curl "http://localhost:3000/api/users/123"' + ); + console.log( + "\n # Update a user\n curl -X PUT http://localhost:3000/api/users/123 \\\n -H 'Content-Type: application/json' \\\n -d '{\"name\":\"Alice Updated\"}'" + ); + console.log( + '\n # Delete a user\n curl -X DELETE "http://localhost:3000/api/users/123"' + ); + console.log( + '\n # Check status\n curl "http://localhost:3000/api/status"' + ); + console.log( + '\n # Check status with custom client ID\n curl "http://localhost:3000/api/status" -H "mcp-client-id: my-client"' + ); + console.log( + '\n # Test validation error\n curl -X POST http://localhost:3000/api/users \\\n -H \'Content-Type: application/json\' \\\n -d \'{"name":"","email":"invalid-email"}\'' + ); + + console.log("\n\nāŒ› Server running. Press Ctrl+C to stop.\n"); + + // Keep the process running + await new Promise(() => {}); +} + +// ============================================================================ +// Example 2: Permission-Based Server with Custom Endpoints +// ============================================================================ + +async function runPermissionBasedServerExample() { + console.log( + "\nšŸš€ Starting Permission-Based MCP Server with Custom Endpoints\n" + ); + + const server = await createPermissionBasedMcpServer({ + createServer: () => + new McpServer({ + name: "permission-demo", + version: "1.0.0", + }), + catalog: { + "admin-tools": { + name: "Admin Tools", + description: "Administrative tools", + tools: [ + { + name: "admin-action", + description: "Perform admin action", + inputSchema: { type: "object", properties: {} }, + handler: async () => ({ + content: [{ type: "text", text: "Admin action completed" }], + }), + }, + ], + }, + "user-tools": { + name: "User Tools", + description: "User tools", + tools: [ + { + name: "user-action", + description: "Perform user action", + inputSchema: { type: "object", properties: {} }, + handler: async () => ({ + content: [{ type: "text", text: "User action completed" }], + }), + }, + ], + }, + }, + permissions: { + source: "config", + staticMap: { + "admin-client": ["admin-tools", "user-tools"], + "user-client": ["user-tools"], + "guest-client": [], + }, + defaultPermissions: [], + }, + http: { + port: 3001, + customEndpoints: [ + // Permission-aware endpoint + definePermissionAwareEndpoint({ + method: "GET", + path: "/api/me", + description: "Get current client permissions", + responseSchema: z.object({ + clientId: z.string(), + allowedToolsets: z.array(z.string()), + failedToolsets: z.array(z.string()), + isAdmin: z.boolean(), + }), + handler: async (req) => { + console.log( + `šŸ“„ GET /api/me - Client: ${req.clientId}, Toolsets: [${req.allowedToolsets.join(", ")}]` + ); + + return { + clientId: req.clientId, + allowedToolsets: req.allowedToolsets, + failedToolsets: req.failedToolsets, + isAdmin: req.allowedToolsets.includes("admin-tools"), + }; + }, + }), + + // Admin-only endpoint + definePermissionAwareEndpoint({ + method: "POST", + path: "/api/admin/users/:userId/ban", + description: "Ban a user (admin only)", + paramsSchema: z.object({ + userId: z.string(), + }), + bodySchema: z.object({ + reason: z.string().min(1), + }), + responseSchema: z.object({ + success: z.boolean(), + userId: z.string(), + reason: z.string(), + }), + handler: async (req) => { + console.log( + `šŸ“„ POST /api/admin/users/:userId/ban - Client: ${req.clientId}` + ); + + // Check permissions + if (!req.allowedToolsets.includes("admin-tools")) { + throw new Error("Access denied: admin-tools required"); + } + + return { + success: true, + userId: req.params.userId, + reason: req.body.reason, + }; + }, + }), + ], + }, + }); + + await server.start(); + + console.log("āœ… Permission server started on http://localhost:3001\n"); + console.log("šŸ“ Available Custom Endpoints:"); + console.log(" GET /api/me - Get permissions"); + console.log(" POST /api/admin/users/:userId/ban - Ban user (admin only)\n"); + + console.log("šŸ’” Example curl commands:"); + console.log( + '\n # Get admin permissions\n curl "http://localhost:3001/api/me" -H "mcp-client-id: admin-client"' + ); + console.log( + '\n # Get user permissions\n curl "http://localhost:3001/api/me" -H "mcp-client-id: user-client"' + ); + console.log( + '\n # Ban user as admin (succeeds)\n curl -X POST "http://localhost:3001/api/admin/users/123/ban" \\\n -H "mcp-client-id: admin-client" \\\n -H "Content-Type: application/json" \\\n -d \'{"reason":"Spam"}\'' + ); + console.log( + '\n # Ban user as regular user (fails)\n curl -X POST "http://localhost:3001/api/admin/users/123/ban" \\\n -H "mcp-client-id: user-client" \\\n -H "Content-Type: application/json" \\\n -d \'{"reason":"Spam"}\'' + ); + + console.log("\n\nāŒ› Server running. Press Ctrl+C to stop.\n"); + + await new Promise(() => {}); +} + +// ============================================================================ +// Main +// ============================================================================ + +const args = process.argv.slice(2); +const mode = args[0] || "standard"; + +if (mode === "permission") { + runPermissionBasedServerExample().catch((error) => { + console.error("āŒ Error:", error); + process.exit(1); + }); +} else { + runStandardServerExample().catch((error) => { + console.error("āŒ Error:", error); + process.exit(1); + }); +} diff --git a/src/http/FastifyTransport.ts b/src/http/FastifyTransport.ts index 8706019..cd58b56 100644 --- a/src/http/FastifyTransport.ts +++ b/src/http/FastifyTransport.ts @@ -11,6 +11,8 @@ import { ClientResourceCache } from "../session/ClientResourceCache.js"; import { StreamableHTTPServerTransport } from "@modelcontextprotocol/sdk/server/streamableHttp.js"; import { isInitializeRequest } from "@modelcontextprotocol/sdk/types.js"; import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import type { CustomEndpointDefinition } from "./customEndpoints.js"; +import { registerCustomEndpoints } from "./endpointRegistration.js"; export interface FastifyTransportOptions { host?: string; @@ -20,6 +22,11 @@ export interface FastifyTransportOptions { logger?: boolean; // Optional DI: provide a Fastify instance (e.g., for tests). If provided, start() will not listen. app?: FastifyInstance; + /** + * Optional custom HTTP endpoints to register alongside MCP protocol endpoints. + * Allows adding REST-like endpoints with Zod validation and type inference. + */ + customEndpoints?: CustomEndpointDefinition[]; } export class FastifyTransport { @@ -30,6 +37,7 @@ export class FastifyTransport { cors: boolean; logger: boolean; app?: FastifyInstance; + customEndpoints?: CustomEndpointDefinition[]; }; private readonly defaultManager: DynamicToolManager; private readonly createBundle: () => { @@ -66,6 +74,7 @@ export class FastifyTransport { cors: options.cors ?? true, logger: options.logger ?? false, app: options.app, + customEndpoints: options.customEndpoints, }; this.configSchema = configSchema; } @@ -253,6 +262,12 @@ export class FastifyTransport { } ); + // Register custom endpoints if provided + // IMPORTANT: Only register if customEndpoints is provided AND has items + if (this.options.customEndpoints && this.options.customEndpoints.length > 0) { + registerCustomEndpoints(app, base, this.options.customEndpoints); + } + // Only listen if we created the app if (!this.options.app) { await app.listen({ host: this.options.host, port: this.options.port }); diff --git a/src/http/customEndpoints.ts b/src/http/customEndpoints.ts new file mode 100644 index 0000000..0c1d260 --- /dev/null +++ b/src/http/customEndpoints.ts @@ -0,0 +1,322 @@ +import { z } from "zod"; + +/** + * Supported HTTP methods for custom endpoints + */ +export type HttpMethod = "GET" | "POST" | "PUT" | "DELETE" | "PATCH"; + +/** + * Request context passed to custom endpoint handlers. + * Contains validated and typed request data without exposing Fastify types. + */ +export interface CustomEndpointRequest< + TBody = unknown, + TQuery = unknown, + TParams = unknown +> { + /** + * Validated request body (typed from bodySchema) + */ + body: TBody; + + /** + * Validated query parameters (typed from querySchema) + */ + query: TQuery; + + /** + * Validated path parameters (typed from paramsSchema) + */ + params: TParams; + + /** + * Raw request headers + */ + headers: Record; + + /** + * Client ID (from mcp-client-id header or auto-generated for anonymous clients) + */ + clientId: string; +} + +/** + * Permission-aware request context for custom endpoints in permission-based servers. + * Extends CustomEndpointRequest with permission information. + */ +export interface PermissionAwareEndpointRequest< + TBody = unknown, + TQuery = unknown, + TParams = unknown +> extends CustomEndpointRequest { + /** + * Toolsets this client is allowed to access (resolved from permissions) + */ + allowedToolsets: string[]; + + /** + * Toolsets that failed to enable for this client + */ + failedToolsets: string[]; +} + +/** + * Handler function type with automatic type inference from Zod schemas. + * Receives validated and typed request data, returns typed response. + */ +export type CustomEndpointHandler< + TBody extends z.ZodTypeAny, + TQuery extends z.ZodTypeAny, + TParams extends z.ZodTypeAny, + TResponse extends z.ZodTypeAny +> = ( + request: CustomEndpointRequest< + TBody extends z.ZodTypeAny ? z.infer : never, + TQuery extends z.ZodTypeAny ? z.infer : never, + TParams extends z.ZodTypeAny ? z.infer : never + > +) => Promise> | z.infer; + +/** + * Permission-aware handler function type for permission-based servers. + * Receives permission context in addition to validated request data. + */ +export type PermissionAwareEndpointHandler< + TBody extends z.ZodTypeAny, + TQuery extends z.ZodTypeAny, + TParams extends z.ZodTypeAny, + TResponse extends z.ZodTypeAny +> = ( + request: PermissionAwareEndpointRequest< + TBody extends z.ZodTypeAny ? z.infer : never, + TQuery extends z.ZodTypeAny ? z.infer : never, + TParams extends z.ZodTypeAny ? z.infer : never + > +) => Promise> | z.infer; + +/** + * Custom HTTP endpoint definition with Zod schema-based validation and type inference. + * Allows defining REST-like endpoints alongside MCP protocol endpoints. + * + * @template TBody - Zod schema for request body validation + * @template TQuery - Zod schema for query parameter validation + * @template TParams - Zod schema for path parameter validation + * @template TResponse - Zod schema for response validation + * + * @example + * ```typescript + * const getUserEndpoint = defineEndpoint({ + * method: "GET", + * path: "/users/:userId", + * paramsSchema: z.object({ + * userId: z.string().uuid(), + * }), + * responseSchema: z.object({ + * id: z.string(), + * name: z.string(), + * }), + * handler: async (req) => { + * // req.params is typed: { userId: string } + * const { userId } = req.params; + * return { id: userId, name: "Alice" }; + * }, + * }); + * ``` + */ +export interface CustomEndpointDefinition< + TBody extends z.ZodTypeAny = z.ZodTypeAny, + TQuery extends z.ZodTypeAny = z.ZodTypeAny, + TParams extends z.ZodTypeAny = z.ZodTypeAny, + TResponse extends z.ZodTypeAny = z.ZodTypeAny +> { + /** + * HTTP method for this endpoint + */ + method: HttpMethod; + + /** + * URL path (relative to basePath). Supports path parameters using :param syntax. + * + * @example + * - "/users" - Simple path + * - "/users/:id" - Path with single parameter + * - "/items/:category/:id" - Path with multiple parameters + */ + path: string; + + /** + * Optional Zod schema for request body validation (typically used with POST, PUT, PATCH). + * Enables automatic type inference for handler body parameter. + */ + bodySchema?: TBody; + + /** + * Optional Zod schema for query parameter validation. + * Enables automatic type inference for handler query parameter. + * + * @example + * ```typescript + * querySchema: z.object({ + * limit: z.coerce.number().int().positive().default(10), + * offset: z.coerce.number().int().nonnegative().default(0), + * }) + * ``` + */ + querySchema?: TQuery; + + /** + * Optional Zod schema for path parameter validation. + * Enables automatic type inference for handler params parameter. + */ + paramsSchema?: TParams; + + /** + * Optional Zod schema for response validation. + * Enables automatic type inference for handler return type. + * If validation fails, returns 500 error to prevent information leakage. + */ + responseSchema?: TResponse; + + /** + * Request handler function with inferred types from schemas. + * Receives validated and typed request data, returns typed response. + */ + handler: CustomEndpointHandler; + + /** + * Optional description for documentation purposes + */ + description?: string; +} + +/** + * Standard error response structure for custom endpoints + */ +export interface EndpointErrorResponse { + error: { + /** + * Error code indicating the type of error + * - VALIDATION_ERROR: Request validation failed (400) + * - INTERNAL_ERROR: Handler threw an error (500) + * - RESPONSE_VALIDATION_ERROR: Response validation failed (500) + */ + code: "VALIDATION_ERROR" | "INTERNAL_ERROR" | "RESPONSE_VALIDATION_ERROR"; + + /** + * Human-readable error message + */ + message: string; + + /** + * Optional additional error details (e.g., Zod validation errors) + */ + details?: unknown; + }; +} + +/** + * Helper function to create type-safe custom endpoints with automatic type inference. + * Provides better IntelliSense and type checking for endpoint definitions. + * + * @template TBody - Zod schema for request body + * @template TQuery - Zod schema for query parameters + * @template TParams - Zod schema for path parameters + * @template TResponse - Zod schema for response + * + * @param definition - Endpoint definition with schemas and handler + * @returns The same endpoint definition with full type inference + * + * @example + * ```typescript + * import { z } from "zod"; + * import { defineEndpoint } from "toolception"; + * + * const getUsersEndpoint = defineEndpoint({ + * method: "GET", + * path: "/users", + * querySchema: z.object({ + * limit: z.coerce.number().int().positive().default(10), + * role: z.enum(["admin", "user"]).optional(), + * }), + * responseSchema: z.object({ + * users: z.array(z.object({ + * id: z.string(), + * name: z.string(), + * })), + * total: z.number(), + * }), + * handler: async (req) => { + * // req.query is fully typed: { limit: number, role?: "admin" | "user" } + * const { limit, role } = req.query; + * + * return { + * users: [{ id: "1", name: "Alice" }], + * total: 1, + * }; + * }, + * }); + * ``` + */ +export function defineEndpoint< + TBody extends z.ZodTypeAny = z.ZodNever, + TQuery extends z.ZodTypeAny = z.ZodNever, + TParams extends z.ZodTypeAny = z.ZodNever, + TResponse extends z.ZodTypeAny = z.ZodAny +>( + definition: CustomEndpointDefinition +): CustomEndpointDefinition { + return definition; +} + +/** + * Helper function to create permission-aware custom endpoints for permission-based servers. + * Similar to defineEndpoint but with access to permission context in the handler. + * + * @template TBody - Zod schema for request body + * @template TQuery - Zod schema for query parameters + * @template TParams - Zod schema for path parameters + * @template TResponse - Zod schema for response + * + * @param definition - Endpoint definition with permission-aware handler + * @returns Endpoint definition compatible with permission-based servers + * + * @example + * ```typescript + * import { definePermissionAwareEndpoint } from "toolception"; + * + * const statsEndpoint = definePermissionAwareEndpoint({ + * method: "GET", + * path: "/my-permissions", + * responseSchema: z.object({ + * toolsets: z.array(z.string()), + * count: z.number(), + * }), + * handler: async (req) => { + * // req.allowedToolsets and req.failedToolsets are available + * return { + * toolsets: req.allowedToolsets, + * count: req.allowedToolsets.length, + * }; + * }, + * }); + * ``` + */ +export function definePermissionAwareEndpoint< + TBody extends z.ZodTypeAny = z.ZodNever, + TQuery extends z.ZodTypeAny = z.ZodNever, + TParams extends z.ZodTypeAny = z.ZodNever, + TResponse extends z.ZodTypeAny = z.ZodAny +>(definition: { + method: HttpMethod; + path: string; + bodySchema?: TBody; + querySchema?: TQuery; + paramsSchema?: TParams; + responseSchema?: TResponse; + handler: PermissionAwareEndpointHandler; + description?: string; +}): CustomEndpointDefinition { + // Internal conversion: permission-aware handler is compatible with standard handler + // The permission fields will be injected by the registration logic + return definition as any; +} diff --git a/src/http/endpointRegistration.ts b/src/http/endpointRegistration.ts new file mode 100644 index 0000000..a790035 --- /dev/null +++ b/src/http/endpointRegistration.ts @@ -0,0 +1,202 @@ +import type { FastifyInstance, FastifyRequest, FastifyReply } from "fastify"; +import { z } from "zod"; +import { randomUUID } from "node:crypto"; +import type { + CustomEndpointDefinition, + CustomEndpointRequest, + EndpointErrorResponse, +} from "./customEndpoints.js"; + +/** + * Options for registering custom endpoints + */ +export interface RegisterCustomEndpointsOptions { + /** + * Optional function to extract additional context for each request. + * Used by permission-aware transport to inject permission data. + */ + contextExtractor?: ( + req: FastifyRequest + ) => Promise> | Record; +} + +/** + * Registers custom endpoints on a Fastify instance. + * Handles Zod validation, error responses, and type-safe request mapping. + * + * @param app - Fastify instance to register endpoints on + * @param basePath - Base path for all endpoints (e.g., "/" or "/api") + * @param endpoints - Array of custom endpoint definitions + * @param options - Optional configuration for endpoint registration + * + * @example + * ```typescript + * registerCustomEndpoints(app, "/api", [ + * defineEndpoint({ + * method: "GET", + * path: "/users", + * querySchema: z.object({ limit: z.coerce.number() }), + * handler: async (req) => ({ users: [] }), + * }), + * ]); + * ``` + */ +export function registerCustomEndpoints( + app: FastifyInstance, + basePath: string, + endpoints: CustomEndpointDefinition[], + options?: RegisterCustomEndpointsOptions +): void { + // Built-in MCP paths that should not be overridden + const reservedPaths = ["/mcp", "/healthz", "/tools", "/.well-known/mcp-config"]; + + for (const endpoint of endpoints) { + const fullPath = `${basePath}${endpoint.path}`; + + // Check for path conflicts with built-in endpoints + const isReserved = reservedPaths.some((reserved) => + fullPath.startsWith(`${basePath}${reserved}`) + ); + + if (isReserved) { + console.warn( + `Custom endpoint ${endpoint.method} ${endpoint.path} conflicts with built-in MCP endpoint. Skipping registration.` + ); + continue; + } + + // Convert method to lowercase for Fastify + const method = endpoint.method.toLowerCase() as + | "get" + | "post" + | "put" + | "delete" + | "patch"; + + // Register the endpoint with Fastify + app[method](fullPath, async (req: FastifyRequest, reply: FastifyReply) => { + try { + // Extract client ID from header or generate anonymous ID + const clientIdHeader = (req.headers["mcp-client-id"] as string)?.trim(); + const clientId = + clientIdHeader && clientIdHeader.length > 0 + ? clientIdHeader + : `anon-${randomUUID()}`; + + // Validate request body if schema provided + let body: any = undefined; + if (endpoint.bodySchema) { + const bodyResult = endpoint.bodySchema.safeParse(req.body); + if (!bodyResult.success) { + return createValidationError(reply, "body", bodyResult.error); + } + body = bodyResult.data; + } + + // Validate query parameters if schema provided + let query: any = {}; + if (endpoint.querySchema) { + const queryResult = endpoint.querySchema.safeParse(req.query); + if (!queryResult.success) { + return createValidationError(reply, "query", queryResult.error); + } + query = queryResult.data; + } + + // Validate path parameters if schema provided + let params: any = {}; + if (endpoint.paramsSchema) { + const paramsResult = endpoint.paramsSchema.safeParse(req.params); + if (!paramsResult.success) { + return createValidationError(reply, "params", paramsResult.error); + } + params = paramsResult.data; + } + + // Build request object with validated data + const customRequest: CustomEndpointRequest = { + body, + query, + params, + headers: req.headers as Record, + clientId, + }; + + // Merge additional context if provided (e.g., permissions from contextExtractor) + if (options?.contextExtractor) { + const additionalContext = await options.contextExtractor(req); + Object.assign(customRequest, additionalContext); + } + + // Call the user-defined handler with validated and typed data + const result = await endpoint.handler(customRequest as any); + + // Validate response if schema provided + if (endpoint.responseSchema) { + const responseResult = endpoint.responseSchema.safeParse(result); + if (!responseResult.success) { + // Log the validation error for debugging + console.error( + `Response validation failed for ${endpoint.method} ${endpoint.path}:`, + responseResult.error + ); + + // Return generic error to prevent information leakage + reply.code(500); + return { + error: { + code: "RESPONSE_VALIDATION_ERROR", + message: "Internal server error: invalid response format", + }, + } as EndpointErrorResponse; + } + // Return validated response data + return responseResult.data; + } + + // No response validation - return result as-is + return result; + } catch (error) { + // Handle any errors thrown by the handler + console.error( + `Error in custom endpoint ${endpoint.method} ${endpoint.path}:`, + error + ); + + reply.code(500); + return { + error: { + code: "INTERNAL_ERROR", + message: + error instanceof Error ? error.message : "Internal server error", + }, + } as EndpointErrorResponse; + } + }); + } +} + +/** + * Creates a standardized validation error response. + * Returns 400 status code with detailed Zod validation errors. + * + * @param reply - Fastify reply object + * @param field - The field that failed validation (body, query, or params) + * @param error - Zod validation error + * @returns Formatted error response + * @private + */ +function createValidationError( + reply: FastifyReply, + field: string, + error: z.ZodError +): EndpointErrorResponse { + reply.code(400); + return { + error: { + code: "VALIDATION_ERROR", + message: `Validation failed for ${field}`, + details: error.errors, + }, + }; +} diff --git a/src/index.ts b/src/index.ts index 6746bf2..f8b7a1a 100644 --- a/src/index.ts +++ b/src/index.ts @@ -18,3 +18,19 @@ export type { PermissionConfig, CreatePermissionBasedMcpServerOptions, } from "./types/index.js"; + +// Custom endpoint support +export type { + CustomEndpointDefinition, + CustomEndpointRequest, + PermissionAwareEndpointRequest, + CustomEndpointHandler, + PermissionAwareEndpointHandler, + HttpMethod, + EndpointErrorResponse, +} from "./http/customEndpoints.js"; + +export { + defineEndpoint, + definePermissionAwareEndpoint, +} from "./http/customEndpoints.js"; diff --git a/src/permissions/PermissionAwareFastifyTransport.ts b/src/permissions/PermissionAwareFastifyTransport.ts index 05b1324..f0f6f5a 100644 --- a/src/permissions/PermissionAwareFastifyTransport.ts +++ b/src/permissions/PermissionAwareFastifyTransport.ts @@ -15,6 +15,8 @@ import type { ClientRequestContext, PermissionAwareBundle, } from "./createPermissionAwareBundle.js"; +import type { CustomEndpointDefinition } from "../http/customEndpoints.js"; +import { registerCustomEndpoints } from "../http/endpointRegistration.js"; export interface PermissionAwareFastifyTransportOptions { host?: string; @@ -23,6 +25,12 @@ export interface PermissionAwareFastifyTransportOptions { cors?: boolean; logger?: boolean; app?: FastifyInstance; + /** + * Optional custom HTTP endpoints to register alongside MCP protocol endpoints. + * Allows adding REST-like endpoints with Zod validation and type inference. + * Handlers receive permission context (allowedToolsets, failedToolsets). + */ + customEndpoints?: CustomEndpointDefinition[]; } /** @@ -41,6 +49,7 @@ export class PermissionAwareFastifyTransport { cors: boolean; logger: boolean; app?: FastifyInstance; + customEndpoints?: CustomEndpointDefinition[]; }; private readonly defaultManager: DynamicToolManager; private readonly createPermissionAwareBundle: ( @@ -87,6 +96,7 @@ export class PermissionAwareFastifyTransport { cors: options.cors ?? true, logger: options.logger ?? false, app: options.app, + customEndpoints: options.customEndpoints, }; this.configSchema = configSchema; } @@ -111,6 +121,35 @@ export class PermissionAwareFastifyTransport { this.#registerMcpGetEndpoint(app, base); this.#registerMcpDeleteEndpoint(app, base); + // Register custom endpoints if provided with permission context + // IMPORTANT: Only register if customEndpoints is provided AND has items + if (this.options.customEndpoints && this.options.customEndpoints.length > 0) { + registerCustomEndpoints(app, base, this.options.customEndpoints, { + contextExtractor: async (req) => { + // Extract client context from request + const context = this.#extractClientContext(req); + + // Resolve permissions for this client + try { + const bundle = await this.createPermissionAwareBundle(context); + return { + allowedToolsets: bundle.allowedToolsets, + failedToolsets: bundle.failedToolsets, + }; + } catch (error) { + // If permission resolution fails, return empty permissions + console.warn( + `Permission resolution failed for custom endpoint: ${error}` + ); + return { + allowedToolsets: [], + failedToolsets: [], + }; + } + }, + }); + } + // Only listen if we created the app if (!this.options.app) { await app.listen({ host: this.options.host, port: this.options.port }); diff --git a/src/server/createMcpServer.ts b/src/server/createMcpServer.ts index 34390d1..2e586fe 100644 --- a/src/server/createMcpServer.ts +++ b/src/server/createMcpServer.ts @@ -48,6 +48,7 @@ export async function createMcpServer(options: CreateMcpServerOptions) { /** * Sends a tools list changed notification to the client. * Logs warnings on failure instead of throwing. + * Suppresses "Not connected" errors as they're expected when no clients are connected. * @param target - The MCP server instance */ const notifyToolsChanged = async (target: unknown) => { @@ -62,6 +63,12 @@ export async function createMcpServer(options: CreateMcpServerOptions) { await target.notifyToolsListChanged(); } } catch (err) { + // Suppress "Not connected" errors - expected when no clients are connected + const errorMessage = err instanceof Error ? err.message : String(err); + if (errorMessage === "Not connected") { + return; // Silently ignore - no clients to notify + } + // Log other errors as they indicate actual problems console.warn("Failed to send tools list changed notification:", err); } }; diff --git a/tests/customEndpoints.integration.test.ts b/tests/customEndpoints.integration.test.ts new file mode 100644 index 0000000..e648350 --- /dev/null +++ b/tests/customEndpoints.integration.test.ts @@ -0,0 +1,530 @@ +import { describe, it, expect, beforeAll, afterAll } from "vitest"; +import { z } from "zod"; +import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js"; +import Fastify, { type FastifyInstance } from "fastify"; +import { createMcpServer, defineEndpoint } from "../src/index.js"; +import { createPermissionBasedMcpServer, definePermissionAwareEndpoint } from "../src/index.js"; + +describe("Custom Endpoints Integration", () => { + describe("Standard MCP Server with Custom Endpoints", () => { + let server: Awaited>; + let testApp: FastifyInstance; + + beforeAll(async () => { + // Create test Fastify instance to avoid port conflicts + testApp = Fastify({ logger: false }); + + server = await createMcpServer({ + createServer: () => + new McpServer({ name: "test-server", version: "1.0.0" }), + catalog: { + "test-toolset": { + name: "Test Toolset", + description: "A test toolset", + tools: [ + { + name: "ping", + description: "Test tool", + inputSchema: { type: "object", properties: {} }, + handler: async () => ({ + content: [{ type: "text", text: "pong" }], + }), + }, + ], + }, + }, + startup: { + mode: "STATIC", + toolsets: ["test-toolset"], + }, + http: { + app: testApp, // Inject Fastify instance for testing + customEndpoints: [ + // GET endpoint with query validation + defineEndpoint({ + method: "GET", + path: "/api/users", + querySchema: z.object({ + limit: z.coerce.number().int().positive().default(10), + offset: z.coerce.number().int().nonnegative().default(0), + }), + responseSchema: z.object({ + users: z.array( + z.object({ + id: z.string(), + name: z.string(), + }) + ), + pagination: z.object({ + limit: z.number(), + offset: z.number(), + }), + }), + handler: async (req) => ({ + users: [ + { id: "1", name: "Alice" }, + { id: "2", name: "Bob" }, + ].slice(req.query.offset, req.query.offset + req.query.limit), + pagination: { + limit: req.query.limit, + offset: req.query.offset, + }, + }), + }), + + // POST endpoint with body validation + defineEndpoint({ + method: "POST", + path: "/api/users", + bodySchema: z.object({ + name: z.string().min(1).max(100), + email: z.string().email(), + age: z.number().int().positive().optional(), + }), + responseSchema: z.object({ + id: z.string(), + name: z.string(), + email: z.string(), + createdAt: z.string(), + }), + handler: async (req) => ({ + id: "new-user-id", + name: req.body.name, + email: req.body.email, + createdAt: new Date().toISOString(), + }), + }), + + // GET endpoint with path parameters + defineEndpoint({ + method: "GET", + path: "/api/users/:userId", + paramsSchema: z.object({ + userId: z.string(), + }), + responseSchema: z.object({ + id: z.string(), + name: z.string(), + }), + handler: async (req) => ({ + id: req.params.userId, + name: `User ${req.params.userId}`, + }), + }), + + // DELETE endpoint + defineEndpoint({ + method: "DELETE", + path: "/api/users/:userId", + paramsSchema: z.object({ + userId: z.string(), + }), + responseSchema: z.object({ + success: z.boolean(), + deletedId: z.string(), + }), + handler: async (req) => ({ + success: true, + deletedId: req.params.userId, + }), + }), + + // Status endpoint accessing client ID + defineEndpoint({ + method: "GET", + path: "/api/status", + responseSchema: z.object({ + status: z.string(), + clientId: z.string(), + timestamp: z.number(), + }), + handler: async (req) => ({ + status: "ok", + clientId: req.clientId, + timestamp: Date.now(), + }), + }), + ], + }, + }); + + await server.start(); + }); + + afterAll(async () => { + await server.close(); + }); + + it("handles GET request with query parameters", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/api/users?limit=5&offset=0", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.users).toHaveLength(2); + expect(body.pagination).toEqual({ limit: 5, offset: 0 }); + }); + + it("handles POST request with body validation", async () => { + const response = await testApp.inject({ + method: "POST", + url: "/api/users", + payload: { + name: "Charlie", + email: "charlie@example.com", + age: 30, + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.id).toBe("new-user-id"); + expect(body.name).toBe("Charlie"); + expect(body.email).toBe("charlie@example.com"); + expect(body.createdAt).toBeDefined(); + }); + + it("handles GET request with path parameters", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/api/users/user-123", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.id).toBe("user-123"); + expect(body.name).toBe("User user-123"); + }); + + it("handles DELETE request", async () => { + const response = await testApp.inject({ + method: "DELETE", + url: "/api/users/user-456", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.success).toBe(true); + expect(body.deletedId).toBe("user-456"); + }); + + it("extracts client ID from header", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/api/status", + headers: { + "mcp-client-id": "test-client-xyz", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.clientId).toBe("test-client-xyz"); + expect(body.status).toBe("ok"); + }); + + it("generates anonymous client ID when header missing", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/api/status", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.clientId).toMatch(/^anon-/); + }); + + it("validates request body and returns error", async () => { + const response = await testApp.inject({ + method: "POST", + url: "/api/users", + payload: { + name: "", + email: "invalid-email", + }, + }); + + expect(response.statusCode).toBe(400); + const body = JSON.parse(response.body); + expect(body.error.code).toBe("VALIDATION_ERROR"); + expect(body.error.details).toBeDefined(); + }); + + it("built-in MCP endpoints still work", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/healthz", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.ok).toBe(true); + }); + }); + + describe("Permission-Based MCP Server with Custom Endpoints", () => { + let server: Awaited>; + let testApp: FastifyInstance; + + beforeAll(async () => { + testApp = Fastify({ logger: false }); + + server = await createPermissionBasedMcpServer({ + createServer: () => + new McpServer({ + name: "permission-test-server", + version: "1.0.0", + }), + catalog: { + "admin-toolset": { + name: "Admin Toolset", + description: "Admin tools", + tools: [ + { + name: "admin-ping", + description: "Admin test tool", + inputSchema: { type: "object", properties: {} }, + handler: async () => ({ + content: [{ type: "text", text: "admin-pong" }], + }), + }, + ], + }, + "user-toolset": { + name: "User Toolset", + description: "User tools", + tools: [ + { + name: "user-ping", + description: "User test tool", + inputSchema: { type: "object", properties: {} }, + handler: async () => ({ + content: [{ type: "text", text: "user-pong" }], + }), + }, + ], + }, + }, + permissions: { + source: "config", + staticMap: { + "admin-client": ["admin-toolset", "user-toolset"], + "user-client": ["user-toolset"], + "guest-client": [], + }, + defaultPermissions: [], + }, + http: { + app: testApp, + customEndpoints: [ + // Permission-aware endpoint + definePermissionAwareEndpoint({ + method: "GET", + path: "/api/permissions", + responseSchema: z.object({ + clientId: z.string(), + allowedToolsets: z.array(z.string()), + failedToolsets: z.array(z.string()), + isAdmin: z.boolean(), + }), + handler: async (req) => ({ + clientId: req.clientId, + allowedToolsets: req.allowedToolsets, + failedToolsets: req.failedToolsets, + isAdmin: req.allowedToolsets.includes("admin-toolset"), + }), + }), + + // Admin-only endpoint + definePermissionAwareEndpoint({ + method: "POST", + path: "/api/admin/action", + bodySchema: z.object({ + action: z.string(), + }), + responseSchema: z.object({ + success: z.boolean(), + message: z.string(), + }), + handler: async (req) => { + if (!req.allowedToolsets.includes("admin-toolset")) { + throw new Error( + "Insufficient permissions: admin-toolset required" + ); + } + + return { + success: true, + message: `Action '${req.body.action}' executed successfully`, + }; + }, + }), + + // Endpoint that checks any toolset access + definePermissionAwareEndpoint({ + method: "GET", + path: "/api/tools/count", + responseSchema: z.object({ + count: z.number(), + hasAccess: z.boolean(), + }), + handler: async (req) => ({ + count: req.allowedToolsets.length, + hasAccess: req.allowedToolsets.length > 0, + }), + }), + ], + }, + }); + + await server.start(); + }); + + afterAll(async () => { + await server.close(); + }); + + it("provides permission context for admin client", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/api/permissions", + headers: { + "mcp-client-id": "admin-client", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.clientId).toBe("admin-client"); + expect(body.allowedToolsets).toEqual( + expect.arrayContaining(["admin-toolset", "user-toolset"]) + ); + expect(body.isAdmin).toBe(true); + }); + + it("provides permission context for user client", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/api/permissions", + headers: { + "mcp-client-id": "user-client", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.clientId).toBe("user-client"); + expect(body.allowedToolsets).toEqual(["user-toolset"]); + expect(body.isAdmin).toBe(false); + }); + + it("provides empty permissions for guest client", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/api/permissions", + headers: { + "mcp-client-id": "guest-client", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.clientId).toBe("guest-client"); + expect(body.allowedToolsets).toEqual([]); + expect(body.isAdmin).toBe(false); + }); + + it("allows admin action for admin client", async () => { + const response = await testApp.inject({ + method: "POST", + url: "/api/admin/action", + headers: { + "mcp-client-id": "admin-client", + }, + payload: { + action: "delete-user", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.success).toBe(true); + expect(body.message).toContain("delete-user"); + }); + + it("blocks admin action for user client", async () => { + const response = await testApp.inject({ + method: "POST", + url: "/api/admin/action", + headers: { + "mcp-client-id": "user-client", + }, + payload: { + action: "delete-user", + }, + }); + + expect(response.statusCode).toBe(500); + const body = JSON.parse(response.body); + expect(body.error.code).toBe("INTERNAL_ERROR"); + expect(body.error.message).toContain("Insufficient permissions"); + }); + + it("counts toolsets correctly for different clients", async () => { + // Admin client + const adminResponse = await testApp.inject({ + method: "GET", + url: "/api/tools/count", + headers: { + "mcp-client-id": "admin-client", + }, + }); + + expect(adminResponse.statusCode).toBe(200); + let body = JSON.parse(adminResponse.body); + expect(body.count).toBe(2); + expect(body.hasAccess).toBe(true); + + // User client + const userResponse = await testApp.inject({ + method: "GET", + url: "/api/tools/count", + headers: { + "mcp-client-id": "user-client", + }, + }); + + expect(userResponse.statusCode).toBe(200); + body = JSON.parse(userResponse.body); + expect(body.count).toBe(1); + expect(body.hasAccess).toBe(true); + + // Guest client + const guestResponse = await testApp.inject({ + method: "GET", + url: "/api/tools/count", + headers: { + "mcp-client-id": "guest-client", + }, + }); + + expect(guestResponse.statusCode).toBe(200); + body = JSON.parse(guestResponse.body); + expect(body.count).toBe(0); + expect(body.hasAccess).toBe(false); + }); + + it("built-in MCP endpoints still work with permissions", async () => { + const response = await testApp.inject({ + method: "GET", + url: "/healthz", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.ok).toBe(true); + }); + }); +}); diff --git a/tests/customEndpoints.test.ts b/tests/customEndpoints.test.ts new file mode 100644 index 0000000..06388e6 --- /dev/null +++ b/tests/customEndpoints.test.ts @@ -0,0 +1,573 @@ +import { describe, it, expect, vi, beforeEach, afterEach } from "vitest"; +import { z } from "zod"; +import Fastify, { type FastifyInstance } from "fastify"; +import { registerCustomEndpoints } from "../src/http/endpointRegistration.js"; +import { defineEndpoint, definePermissionAwareEndpoint } from "../src/http/customEndpoints.js"; + +describe("Custom Endpoints", () => { + let app: FastifyInstance; + + beforeEach(async () => { + app = Fastify({ logger: false }); + }); + + afterEach(async () => { + await app.close(); + }); + + describe("defineEndpoint helper", () => { + it("returns endpoint definition with correct structure", () => { + const endpoint = defineEndpoint({ + method: "GET", + path: "/test", + querySchema: z.object({ id: z.string() }), + responseSchema: z.object({ success: z.boolean() }), + handler: async (req) => ({ success: true }), + }); + + expect(endpoint).toHaveProperty("method", "GET"); + expect(endpoint).toHaveProperty("path", "/test"); + expect(endpoint).toHaveProperty("querySchema"); + expect(endpoint).toHaveProperty("responseSchema"); + expect(endpoint).toHaveProperty("handler"); + }); + }); + + describe("definePermissionAwareEndpoint helper", () => { + it("returns endpoint definition compatible with permission-based servers", () => { + const endpoint = definePermissionAwareEndpoint({ + method: "POST", + path: "/admin", + bodySchema: z.object({ action: z.string() }), + responseSchema: z.object({ success: z.boolean() }), + handler: async (req) => { + // Should have access to allowedToolsets + return { success: req.allowedToolsets.length > 0 }; + }, + }); + + expect(endpoint).toHaveProperty("method", "POST"); + expect(endpoint).toHaveProperty("path", "/admin"); + expect(endpoint).toHaveProperty("bodySchema"); + expect(endpoint).toHaveProperty("handler"); + }); + }); + + describe("registerCustomEndpoints", () => { + describe("GET endpoint with query params", () => { + it("validates and parses query parameters", async () => { + const handler = vi.fn(async (req) => ({ + received: req.query, + })); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/users", + querySchema: z.object({ + limit: z.coerce.number().int().positive(), + offset: z.coerce.number().int().nonnegative().default(0), + }), + handler, + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/users?limit=10&offset=5", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.received).toEqual({ limit: 10, offset: 5 }); + expect(handler).toHaveBeenCalledOnce(); + }); + + it("returns validation error for invalid query params", async () => { + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/users", + querySchema: z.object({ + limit: z.coerce.number().int().positive(), + }), + handler: async () => ({ success: true }), + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/users?limit=-5", + }); + + expect(response.statusCode).toBe(400); + const body = JSON.parse(response.body); + expect(body.error.code).toBe("VALIDATION_ERROR"); + expect(body.error.message).toContain("query"); + expect(body.error.details).toBeDefined(); + }); + + it("applies default values from schema", async () => { + const handler = vi.fn(async (req) => ({ received: req.query })); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/users", + querySchema: z.object({ + limit: z.coerce.number().default(10), + }), + handler, + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/users", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.received.limit).toBe(10); + }); + }); + + describe("POST endpoint with body validation", () => { + it("validates and parses request body", async () => { + const handler = vi.fn(async (req) => ({ + created: req.body, + })); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "POST", + path: "/users", + bodySchema: z.object({ + name: z.string().min(1), + email: z.string().email(), + }), + handler, + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "POST", + url: "/users", + payload: { + name: "Alice", + email: "alice@example.com", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.created).toEqual({ + name: "Alice", + email: "alice@example.com", + }); + expect(handler).toHaveBeenCalledOnce(); + }); + + it("returns validation error for invalid body", async () => { + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "POST", + path: "/users", + bodySchema: z.object({ + name: z.string().min(1), + email: z.string().email(), + }), + handler: async () => ({ success: true }), + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "POST", + url: "/users", + payload: { + name: "", + email: "invalid-email", + }, + }); + + expect(response.statusCode).toBe(400); + const body = JSON.parse(response.body); + expect(body.error.code).toBe("VALIDATION_ERROR"); + expect(body.error.message).toContain("body"); + expect(body.error.details).toHaveLength(2); + }); + }); + + describe("Path parameters", () => { + it("validates and parses path parameters", async () => { + const handler = vi.fn(async (req) => ({ + userId: req.params.userId, + })); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/users/:userId", + paramsSchema: z.object({ + userId: z.string().uuid(), + }), + handler, + }), + ]); + + await app.ready(); + + const validUuid = "123e4567-e89b-12d3-a456-426614174000"; + const response = await app.inject({ + method: "GET", + url: `/users/${validUuid}`, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.userId).toBe(validUuid); + expect(handler).toHaveBeenCalledOnce(); + }); + + it("returns validation error for invalid path params", async () => { + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/users/:userId", + paramsSchema: z.object({ + userId: z.string().uuid(), + }), + handler: async () => ({ success: true }), + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/users/invalid-uuid", + }); + + expect(response.statusCode).toBe(400); + const body = JSON.parse(response.body); + expect(body.error.code).toBe("VALIDATION_ERROR"); + expect(body.error.message).toContain("params"); + }); + }); + + describe("Response validation", () => { + it("validates response against schema", async () => { + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/status", + responseSchema: z.object({ + status: z.string(), + code: z.number(), + }), + handler: async () => ({ + status: "ok", + code: 200, + }), + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/status", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body).toEqual({ status: "ok", code: 200 }); + }); + + it("returns 500 if response validation fails", async () => { + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/status", + responseSchema: z.object({ + status: z.string(), + code: z.number(), + }), + handler: async () => ({ + status: "ok", + // Missing required 'code' field + } as any), + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/status", + }); + + expect(response.statusCode).toBe(500); + const body = JSON.parse(response.body); + expect(body.error.code).toBe("RESPONSE_VALIDATION_ERROR"); + expect(body.error.message).toContain("invalid response format"); + + consoleErrorSpy.mockRestore(); + }); + }); + + describe("Client ID handling", () => { + it("extracts client ID from header", async () => { + const handler = vi.fn(async (req) => ({ + clientId: req.clientId, + })); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/me", + handler, + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/me", + headers: { + "mcp-client-id": "test-client-123", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.clientId).toBe("test-client-123"); + }); + + it("generates anonymous client ID when header missing", async () => { + const handler = vi.fn(async (req) => ({ + clientId: req.clientId, + })); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/me", + handler, + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/me", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.clientId).toMatch(/^anon-/); + }); + }); + + describe("Error handling", () => { + it("handles handler errors gracefully", async () => { + const consoleErrorSpy = vi.spyOn(console, "error").mockImplementation(() => {}); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/error", + handler: async () => { + throw new Error("Something went wrong"); + }, + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/error", + }); + + expect(response.statusCode).toBe(500); + const body = JSON.parse(response.body); + expect(body.error.code).toBe("INTERNAL_ERROR"); + expect(body.error.message).toBe("Something went wrong"); + + consoleErrorSpy.mockRestore(); + }); + }); + + describe("Context extractor", () => { + it("merges additional context into request", async () => { + const handler = vi.fn(async (req: any) => ({ + hasPermissions: "allowedToolsets" in req, + toolsets: req.allowedToolsets, + })); + + registerCustomEndpoints( + app, + "", + [ + defineEndpoint({ + method: "GET", + path: "/admin", + handler, + }), + ], + { + contextExtractor: async () => ({ + allowedToolsets: ["admin", "user"], + failedToolsets: [], + }), + } + ); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/admin", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.hasPermissions).toBe(true); + expect(body.toolsets).toEqual(["admin", "user"]); + }); + }); + + describe("Base path handling", () => { + it("registers endpoints with base path", async () => { + registerCustomEndpoints(app, "/api", [ + defineEndpoint({ + method: "GET", + path: "/status", + handler: async () => ({ ok: true }), + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/api/status", + }); + + expect(response.statusCode).toBe(200); + }); + }); + + describe("Reserved path conflicts", () => { + it("skips registration and warns for conflicting paths", async () => { + const consoleWarnSpy = vi.spyOn(console, "warn").mockImplementation(() => {}); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/mcp", + handler: async () => ({ ok: true }), + }), + defineEndpoint({ + method: "GET", + path: "/healthz", + handler: async () => ({ ok: true }), + }), + defineEndpoint({ + method: "GET", + path: "/tools", + handler: async () => ({ ok: true }), + }), + ]); + + await app.ready(); + + expect(consoleWarnSpy).toHaveBeenCalledTimes(3); + expect(consoleWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("/mcp") + ); + expect(consoleWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("/healthz") + ); + expect(consoleWarnSpy).toHaveBeenCalledWith( + expect.stringContaining("/tools") + ); + + consoleWarnSpy.mockRestore(); + }); + }); + + describe("All HTTP methods", () => { + it.each(["GET", "POST", "PUT", "DELETE", "PATCH"] as const)( + "supports %s method", + async (method) => { + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method, + path: "/test", + handler: async () => ({ method }), + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method, + url: "/test", + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.method).toBe(method); + } + ); + }); + + describe("Headers access", () => { + it("provides access to request headers", async () => { + const handler = vi.fn(async (req) => ({ + hasCustomHeader: "x-custom-header" in req.headers, + customValue: req.headers["x-custom-header"], + })); + + registerCustomEndpoints(app, "", [ + defineEndpoint({ + method: "GET", + path: "/headers", + handler, + }), + ]); + + await app.ready(); + + const response = await app.inject({ + method: "GET", + url: "/headers", + headers: { + "x-custom-header": "custom-value", + }, + }); + + expect(response.statusCode).toBe(200); + const body = JSON.parse(response.body); + expect(body.hasCustomHeader).toBe(true); + expect(body.customValue).toBe("custom-value"); + }); + }); + }); +}); From 4a36ee91cceb7b699134b63042b57367dadd6495 Mon Sep 17 00:00:00 2001 From: Ben Rabinovich Date: Thu, 8 Jan 2026 14:34:38 +0200 Subject: [PATCH 2/4] chore: audit fix --- package-lock.json | 191 +++++++++++++++++++--------------------------- 1 file changed, 80 insertions(+), 111 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4e8eae4..38da872 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "toolception", - "version": "0.3.0", + "version": "0.4.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "toolception", - "version": "0.3.0", + "version": "0.4.0", "license": "Apache-2.0", "dependencies": { "@fastify/cors": "^10.0.1", @@ -565,28 +565,6 @@ "fast-uri": "^3.0.0" } }, - "node_modules/@fastify/ajv-compiler/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/@fastify/ajv-compiler/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/@fastify/cors": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/@fastify/cors/-/cors-10.1.0.tgz", @@ -677,6 +655,18 @@ "ipaddr.js": "^2.1.0" } }, + "node_modules/@hono/node-server": { + "version": "1.19.7", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/@hono/node-server/-/node-server-1.19.7.tgz", + "integrity": "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==", + "license": "MIT", + "engines": { + "node": ">=18.14.1" + }, + "peerDependencies": { + "hono": "^4" + } + }, "node_modules/@isaacs/balanced-match": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/@isaacs/balanced-match/-/balanced-match-4.0.1.tgz", @@ -900,20 +890,15 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@microsoft/tsdoc-config/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/@modelcontextprotocol/sdk": { - "version": "1.17.3", - "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.17.3.tgz", - "integrity": "sha512-JPwUKWSsbzx+DLFznf/QZ32Qa+ptfbUlHhRLrBQBAFu9iI1iYvizM4p+zhhRDceSsPutXp4z+R/HPVphlIiclg==", + "version": "1.25.2", + "resolved": "https://registry.npmjs.org/@modelcontextprotocol/sdk/-/sdk-1.25.2.tgz", + "integrity": "sha512-LZFeo4F9M5qOhC/Uc1aQSrBHxMrvxett+9KLHt7OhcExtoiRN9DKgbZffMP/nxjutWDQpfMDfP3nkHI4X9ijww==", "license": "MIT", "dependencies": { - "ajv": "^6.12.6", + "@hono/node-server": "^1.19.7", + "ajv": "^8.17.1", + "ajv-formats": "^3.0.1", "content-type": "^1.0.5", "cors": "^2.8.5", "cross-spawn": "^7.0.5", @@ -921,13 +906,27 @@ "eventsource-parser": "^3.0.0", "express": "^5.0.1", "express-rate-limit": "^7.5.0", + "jose": "^6.1.1", + "json-schema-typed": "^8.0.2", "pkce-challenge": "^5.0.0", "raw-body": "^3.0.0", - "zod": "^3.23.8", - "zod-to-json-schema": "^3.24.1" + "zod": "^3.25 || ^4.0", + "zod-to-json-schema": "^3.25.0" }, "engines": { "node": ">=18" + }, + "peerDependencies": { + "@cfworker/json-schema": "^4.1.1", + "zod": "^3.25 || ^4.0" + }, + "peerDependenciesMeta": { + "@cfworker/json-schema": { + "optional": true + }, + "zod": { + "optional": false + } } }, "node_modules/@pkgjs/parseargs": { @@ -1308,13 +1307,6 @@ } } }, - "node_modules/@rushstack/node-core-library/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true, - "license": "MIT" - }, "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1740,15 +1732,15 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "8.17.1", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -1772,28 +1764,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/alien-signals": { "version": "0.4.14", "resolved": "https://registry.npmjs.org/alien-signals/-/alien-signals-0.4.14.tgz", @@ -2413,12 +2383,6 @@ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", "license": "MIT" }, - "node_modules/fast-json-stable-stringify": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", - "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "license": "MIT" - }, "node_modules/fast-json-stringify": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.0.1.tgz", @@ -2443,28 +2407,6 @@ "rfdc": "^1.2.0" } }, - "node_modules/fast-json-stringify/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "license": "MIT", - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/fast-json-stringify/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "license": "MIT" - }, "node_modules/fast-querystring": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/fast-querystring/-/fast-querystring-1.1.2.tgz", @@ -2804,6 +2746,16 @@ "he": "bin/he" } }, + "node_modules/hono": { + "version": "4.11.3", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/hono/-/hono-4.11.3.tgz", + "integrity": "sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=16.9.0" + } + }, "node_modules/html-escaper": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/html-escaper/-/html-escaper-2.0.2.tgz", @@ -2987,6 +2939,15 @@ "dev": true, "license": "MIT" }, + "node_modules/jose": { + "version": "6.1.3", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/jose/-/jose-6.1.3.tgz", + "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", + "license": "MIT", + "funding": { + "url": "https://github.com/sponsors/panva" + } + }, "node_modules/js-tokens": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz", @@ -3014,11 +2975,17 @@ } }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "version": "1.0.0", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, + "node_modules/json-schema-typed": { + "version": "8.0.2", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", + "license": "BSD-2-Clause" + }, "node_modules/jsonfile": { "version": "6.2.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.2.0.tgz", @@ -3609,15 +3576,16 @@ "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", "integrity": "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==", + "dev": true, "license": "MIT", "engines": { "node": ">=6" } }, "node_modules/qs": { - "version": "6.14.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.0.tgz", - "integrity": "sha512-YWWTjgABSKcvs/nWBi9PycY/JiPJqOD4JA6o9Sej2AtvSGarXxKC3OQSk4pAarbdQlKAh5D4FCQkJNkW+GAn3w==", + "version": "6.14.1", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/qs/-/qs-6.14.1.tgz", + "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "license": "BSD-3-Clause", "dependencies": { "side-channel": "^1.1.0" @@ -4472,6 +4440,7 @@ "version": "4.4.1", "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", + "dev": true, "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" @@ -4844,12 +4813,12 @@ } }, "node_modules/zod-to-json-schema": { - "version": "3.24.6", - "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.24.6.tgz", - "integrity": "sha512-h/z3PKvcTcTetyjl1fkj79MHNEjm+HpD6NXheWjzOekY7kV+lwDYnHw+ivHkijnCSMz1yJaWBD9vu/Fcmk+vEg==", + "version": "3.25.1", + "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", "license": "ISC", "peerDependencies": { - "zod": "^3.24.1" + "zod": "^3.25 || ^4" } } } From 2d1919dba8bd25fec0ed3553289f64d71f6c5c6b Mon Sep 17 00:00:00 2001 From: Ben Rabinovich Date: Thu, 8 Jan 2026 14:40:00 +0200 Subject: [PATCH 3/4] chore: npmrc --- .npmrc | 1 + package-lock.json | 1161 +++++++++++++++++++++++++-------------------- 2 files changed, 648 insertions(+), 514 deletions(-) create mode 100644 .npmrc diff --git a/.npmrc b/.npmrc new file mode 100644 index 0000000..214c29d --- /dev/null +++ b/.npmrc @@ -0,0 +1 @@ +registry=https://registry.npmjs.org/ diff --git a/package-lock.json b/package-lock.json index 38da872..08f10b9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -53,9 +53,9 @@ } }, "node_modules/@babel/helper-validator-identifier": { - "version": "7.27.1", - "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.27.1.tgz", - "integrity": "sha512-D2hP9eA+Sqx1kBZgzxZh0y1trbuU+JoDkiEwqhQ36nodYqJwyEIhPSdMNd7lOm/4io72luTPWH20Yda0xOuUow==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.28.5.tgz", + "integrity": "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q==", "dev": true, "license": "MIT", "engines": { @@ -63,13 +63,13 @@ } }, "node_modules/@babel/parser": { - "version": "7.28.3", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.3.tgz", - "integrity": "sha512-7+Ey1mAgYqFAx2h0RuoxcQT5+MlG3GTV0TQrgr7/ZliKsm/MNDxVVutlWaziMq7wJNAz8MTqz55XLpWvva6StA==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.28.5.tgz", + "integrity": "sha512-KKBU1VGYR7ORr3At5HAtUQ+TV3SzRCXmA/8OdDZiLDBIZxVyzXuztPjfLd3BV1PRAQGCMWWSHYhL0F8d5uHBDQ==", "dev": true, "license": "MIT", "dependencies": { - "@babel/types": "^7.28.2" + "@babel/types": "^7.28.5" }, "bin": { "parser": "bin/babel-parser.js" @@ -79,14 +79,14 @@ } }, "node_modules/@babel/types": { - "version": "7.28.2", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.2.tgz", - "integrity": "sha512-ruv7Ae4J5dUYULmeXw1gmb7rYRz57OWCPM57pHojnLq/3Z1CK2lNSLTCVjxVk1F/TZHwOZZrOWi0ur95BbLxNQ==", + "version": "7.28.5", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.28.5.tgz", + "integrity": "sha512-qQ5m48eI/MFLQ5PxQj4PFaprjyCTLI37ElWMmNs0K8Lk3dVeOdNpB3ks8jc7yM5CDmVC73eMVk/trk3fgmrUpA==", "dev": true, "license": "MIT", "dependencies": { "@babel/helper-string-parser": "^7.27.1", - "@babel/helper-validator-identifier": "^7.27.1" + "@babel/helper-validator-identifier": "^7.28.5" }, "engines": { "node": ">=6.9.0" @@ -103,9 +103,9 @@ } }, "node_modules/@esbuild/aix-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.9.tgz", - "integrity": "sha512-OaGtL73Jck6pBKjNIe24BnFE6agGl+6KxDtTfHhy1HmhthfKouEcOhqpSL64K4/0WCtbKFLOdzD/44cJ4k9opA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.2.tgz", + "integrity": "sha512-GZMB+a0mOMZs4MpDbj8RJp4cw+w1WV5NYD6xzgvzUJ5Ek2jerwfO2eADyI6ExDSUED+1X8aMbegahsJi+8mgpw==", "cpu": [ "ppc64" ], @@ -120,9 +120,9 @@ } }, "node_modules/@esbuild/android-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.9.tgz", - "integrity": "sha512-5WNI1DaMtxQ7t7B6xa572XMXpHAaI/9Hnhk8lcxF4zVN4xstUgTlvuGDorBguKEnZO70qwEcLpfifMLoxiPqHQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.2.tgz", + "integrity": "sha512-DVNI8jlPa7Ujbr1yjU2PfUSRtAUZPG9I1RwW4F4xFB1Imiu2on0ADiI/c3td+KmDtVKNbi+nffGDQMfcIMkwIA==", "cpu": [ "arm" ], @@ -137,9 +137,9 @@ } }, "node_modules/@esbuild/android-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.9.tgz", - "integrity": "sha512-IDrddSmpSv51ftWslJMvl3Q2ZT98fUSL2/rlUXuVqRXHCs5EUF1/f+jbjF5+NG9UffUDMCiTyh8iec7u8RlTLg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.2.tgz", + "integrity": "sha512-pvz8ZZ7ot/RBphf8fv60ljmaoydPU12VuXHImtAs0XhLLw+EXBi2BLe3OYSBslR4rryHvweW5gmkKFwTiFy6KA==", "cpu": [ "arm64" ], @@ -154,9 +154,9 @@ } }, "node_modules/@esbuild/android-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.9.tgz", - "integrity": "sha512-I853iMZ1hWZdNllhVZKm34f4wErd4lMyeV7BLzEExGEIZYsOzqDWDf+y082izYUE8gtJnYHdeDpN/6tUdwvfiw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.2.tgz", + "integrity": "sha512-z8Ank4Byh4TJJOh4wpz8g2vDy75zFL0TlZlkUkEwYXuPSgX8yzep596n6mT7905kA9uHZsf/o2OJZubl2l3M7A==", "cpu": [ "x64" ], @@ -171,9 +171,9 @@ } }, "node_modules/@esbuild/darwin-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.9.tgz", - "integrity": "sha512-XIpIDMAjOELi/9PB30vEbVMs3GV1v2zkkPnuyRRURbhqjyzIINwj+nbQATh4H9GxUgH1kFsEyQMxwiLFKUS6Rg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.2.tgz", + "integrity": "sha512-davCD2Zc80nzDVRwXTcQP/28fiJbcOwvdolL0sOiOsbwBa72kegmVU0Wrh1MYrbuCL98Omp5dVhQFWRKR2ZAlg==", "cpu": [ "arm64" ], @@ -188,9 +188,9 @@ } }, "node_modules/@esbuild/darwin-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.9.tgz", - "integrity": "sha512-jhHfBzjYTA1IQu8VyrjCX4ApJDnH+ez+IYVEoJHeqJm9VhG9Dh2BYaJritkYK3vMaXrf7Ogr/0MQ8/MeIefsPQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.2.tgz", + "integrity": "sha512-ZxtijOmlQCBWGwbVmwOF/UCzuGIbUkqB1faQRf5akQmxRJ1ujusWsb3CVfk/9iZKr2L5SMU5wPBi1UWbvL+VQA==", "cpu": [ "x64" ], @@ -205,9 +205,9 @@ } }, "node_modules/@esbuild/freebsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.9.tgz", - "integrity": "sha512-z93DmbnY6fX9+KdD4Ue/H6sYs+bhFQJNCPZsi4XWJoYblUqT06MQUdBCpcSfuiN72AbqeBFu5LVQTjfXDE2A6Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.2.tgz", + "integrity": "sha512-lS/9CN+rgqQ9czogxlMcBMGd+l8Q3Nj1MFQwBZJyoEKI50XGxwuzznYdwcav6lpOGv5BqaZXqvBSiB/kJ5op+g==", "cpu": [ "arm64" ], @@ -222,9 +222,9 @@ } }, "node_modules/@esbuild/freebsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.9.tgz", - "integrity": "sha512-mrKX6H/vOyo5v71YfXWJxLVxgy1kyt1MQaD8wZJgJfG4gq4DpQGpgTB74e5yBeQdyMTbgxp0YtNj7NuHN0PoZg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.2.tgz", + "integrity": "sha512-tAfqtNYb4YgPnJlEFu4c212HYjQWSO/w/h/lQaBK7RbwGIkBOuNKQI9tqWzx7Wtp7bTPaGC6MJvWI608P3wXYA==", "cpu": [ "x64" ], @@ -239,9 +239,9 @@ } }, "node_modules/@esbuild/linux-arm": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.9.tgz", - "integrity": "sha512-HBU2Xv78SMgaydBmdor38lg8YDnFKSARg1Q6AT0/y2ezUAKiZvc211RDFHlEZRFNRVhcMamiToo7bDx3VEOYQw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.2.tgz", + "integrity": "sha512-vWfq4GaIMP9AIe4yj1ZUW18RDhx6EPQKjwe7n8BbIecFtCQG4CfHGaHuh7fdfq+y3LIA2vGS/o9ZBGVxIDi9hw==", "cpu": [ "arm" ], @@ -256,9 +256,9 @@ } }, "node_modules/@esbuild/linux-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.9.tgz", - "integrity": "sha512-BlB7bIcLT3G26urh5Dmse7fiLmLXnRlopw4s8DalgZ8ef79Jj4aUcYbk90g8iCa2467HX8SAIidbL7gsqXHdRw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.2.tgz", + "integrity": "sha512-hYxN8pr66NsCCiRFkHUAsxylNOcAQaxSSkHMMjcpx0si13t1LHFphxJZUiGwojB1a/Hd5OiPIqDdXONia6bhTw==", "cpu": [ "arm64" ], @@ -273,9 +273,9 @@ } }, "node_modules/@esbuild/linux-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.9.tgz", - "integrity": "sha512-e7S3MOJPZGp2QW6AK6+Ly81rC7oOSerQ+P8L0ta4FhVi+/j/v2yZzx5CqqDaWjtPFfYz21Vi1S0auHrap3Ma3A==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.2.tgz", + "integrity": "sha512-MJt5BRRSScPDwG2hLelYhAAKh9imjHK5+NE/tvnRLbIqUWa+0E9N4WNMjmp/kXXPHZGqPLxggwVhz7QP8CTR8w==", "cpu": [ "ia32" ], @@ -290,9 +290,9 @@ } }, "node_modules/@esbuild/linux-loong64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.9.tgz", - "integrity": "sha512-Sbe10Bnn0oUAB2AalYztvGcK+o6YFFA/9829PhOCUS9vkJElXGdphz0A3DbMdP8gmKkqPmPcMJmJOrI3VYB1JQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.2.tgz", + "integrity": "sha512-lugyF1atnAT463aO6KPshVCJK5NgRnU4yb3FUumyVz+cGvZbontBgzeGFO1nF+dPueHD367a2ZXe1NtUkAjOtg==", "cpu": [ "loong64" ], @@ -307,9 +307,9 @@ } }, "node_modules/@esbuild/linux-mips64el": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.9.tgz", - "integrity": "sha512-YcM5br0mVyZw2jcQeLIkhWtKPeVfAerES5PvOzaDxVtIyZ2NUBZKNLjC5z3/fUlDgT6w89VsxP2qzNipOaaDyA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.2.tgz", + "integrity": "sha512-nlP2I6ArEBewvJ2gjrrkESEZkB5mIoaTswuqNFRv/WYd+ATtUpe9Y09RnJvgvdag7he0OWgEZWhviS1OTOKixw==", "cpu": [ "mips64el" ], @@ -324,9 +324,9 @@ } }, "node_modules/@esbuild/linux-ppc64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.9.tgz", - "integrity": "sha512-++0HQvasdo20JytyDpFvQtNrEsAgNG2CY1CLMwGXfFTKGBGQT3bOeLSYE2l1fYdvML5KUuwn9Z8L1EWe2tzs1w==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.2.tgz", + "integrity": "sha512-C92gnpey7tUQONqg1n6dKVbx3vphKtTHJaNG2Ok9lGwbZil6DrfyecMsp9CrmXGQJmZ7iiVXvvZH6Ml5hL6XdQ==", "cpu": [ "ppc64" ], @@ -341,9 +341,9 @@ } }, "node_modules/@esbuild/linux-riscv64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.9.tgz", - "integrity": "sha512-uNIBa279Y3fkjV+2cUjx36xkx7eSjb8IvnL01eXUKXez/CBHNRw5ekCGMPM0BcmqBxBcdgUWuUXmVWwm4CH9kg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.2.tgz", + "integrity": "sha512-B5BOmojNtUyN8AXlK0QJyvjEZkWwy/FKvakkTDCziX95AowLZKR6aCDhG7LeF7uMCXEJqwa8Bejz5LTPYm8AvA==", "cpu": [ "riscv64" ], @@ -358,9 +358,9 @@ } }, "node_modules/@esbuild/linux-s390x": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.9.tgz", - "integrity": "sha512-Mfiphvp3MjC/lctb+7D287Xw1DGzqJPb/J2aHHcHxflUo+8tmN/6d4k6I2yFR7BVo5/g7x2Monq4+Yew0EHRIA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.2.tgz", + "integrity": "sha512-p4bm9+wsPwup5Z8f4EpfN63qNagQ47Ua2znaqGH6bqLlmJ4bx97Y9JdqxgGZ6Y8xVTixUnEkoKSHcpRlDnNr5w==", "cpu": [ "s390x" ], @@ -375,9 +375,9 @@ } }, "node_modules/@esbuild/linux-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.9.tgz", - "integrity": "sha512-iSwByxzRe48YVkmpbgoxVzn76BXjlYFXC7NvLYq+b+kDjyyk30J0JY47DIn8z1MO3K0oSl9fZoRmZPQI4Hklzg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.2.tgz", + "integrity": "sha512-uwp2Tip5aPmH+NRUwTcfLb+W32WXjpFejTIOWZFw/v7/KnpCDKG66u4DLcurQpiYTiYwQ9B7KOeMJvLCu/OvbA==", "cpu": [ "x64" ], @@ -392,9 +392,9 @@ } }, "node_modules/@esbuild/netbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.9.tgz", - "integrity": "sha512-9jNJl6FqaUG+COdQMjSCGW4QiMHH88xWbvZ+kRVblZsWrkXlABuGdFJ1E9L7HK+T0Yqd4akKNa/lO0+jDxQD4Q==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.2.tgz", + "integrity": "sha512-Kj6DiBlwXrPsCRDeRvGAUb/LNrBASrfqAIok+xB0LxK8CHqxZ037viF13ugfsIpePH93mX7xfJp97cyDuTZ3cw==", "cpu": [ "arm64" ], @@ -409,9 +409,9 @@ } }, "node_modules/@esbuild/netbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.9.tgz", - "integrity": "sha512-RLLdkflmqRG8KanPGOU7Rpg829ZHu8nFy5Pqdi9U01VYtG9Y0zOG6Vr2z4/S+/3zIyOxiK6cCeYNWOFR9QP87g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.2.tgz", + "integrity": "sha512-HwGDZ0VLVBY3Y+Nw0JexZy9o/nUAWq9MlV7cahpaXKW6TOzfVno3y3/M8Ga8u8Yr7GldLOov27xiCnqRZf0tCA==", "cpu": [ "x64" ], @@ -426,9 +426,9 @@ } }, "node_modules/@esbuild/openbsd-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.9.tgz", - "integrity": "sha512-YaFBlPGeDasft5IIM+CQAhJAqS3St3nJzDEgsgFixcfZeyGPCd6eJBWzke5piZuZ7CtL656eOSYKk4Ls2C0FRQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.2.tgz", + "integrity": "sha512-DNIHH2BPQ5551A7oSHD0CKbwIA/Ox7+78/AWkbS5QoRzaqlev2uFayfSxq68EkonB+IKjiuxBFoV8ESJy8bOHA==", "cpu": [ "arm64" ], @@ -443,9 +443,9 @@ } }, "node_modules/@esbuild/openbsd-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.9.tgz", - "integrity": "sha512-1MkgTCuvMGWuqVtAvkpkXFmtL8XhWy+j4jaSO2wxfJtilVCi0ZE37b8uOdMItIHz4I6z1bWWtEX4CJwcKYLcuA==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.2.tgz", + "integrity": "sha512-/it7w9Nb7+0KFIzjalNJVR5bOzA9Vay+yIPLVHfIQYG/j+j9VTH84aNB8ExGKPU4AzfaEvN9/V4HV+F+vo8OEg==", "cpu": [ "x64" ], @@ -460,9 +460,9 @@ } }, "node_modules/@esbuild/openharmony-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.25.9.tgz", - "integrity": "sha512-4Xd0xNiMVXKh6Fa7HEJQbrpP3m3DDn43jKxMjxLLRjWnRsfxjORYJlXPO4JNcXtOyfajXorRKY9NkOpTHptErg==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.2.tgz", + "integrity": "sha512-LRBbCmiU51IXfeXk59csuX/aSaToeG7w48nMwA6049Y4J4+VbWALAuXcs+qcD04rHDuSCSRKdmY63sruDS5qag==", "cpu": [ "arm64" ], @@ -477,9 +477,9 @@ } }, "node_modules/@esbuild/sunos-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.9.tgz", - "integrity": "sha512-WjH4s6hzo00nNezhp3wFIAfmGZ8U7KtrJNlFMRKxiI9mxEK1scOMAaa9i4crUtu+tBr+0IN6JCuAcSBJZfnphw==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.2.tgz", + "integrity": "sha512-kMtx1yqJHTmqaqHPAzKCAkDaKsffmXkPHThSfRwZGyuqyIeBvf08KSsYXl+abf5HDAPMJIPnbBfXvP2ZC2TfHg==", "cpu": [ "x64" ], @@ -494,9 +494,9 @@ } }, "node_modules/@esbuild/win32-arm64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.9.tgz", - "integrity": "sha512-mGFrVJHmZiRqmP8xFOc6b84/7xa5y5YvR1x8djzXpJBSv/UsNK6aqec+6JDjConTgvvQefdGhFDAs2DLAds6gQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.2.tgz", + "integrity": "sha512-Yaf78O/B3Kkh+nKABUF++bvJv5Ijoy9AN1ww904rOXZFLWVc5OLOfL56W+C8F9xn5JQZa3UX6m+IktJnIb1Jjg==", "cpu": [ "arm64" ], @@ -511,9 +511,9 @@ } }, "node_modules/@esbuild/win32-ia32": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.9.tgz", - "integrity": "sha512-b33gLVU2k11nVx1OhX3C8QQP6UHQK4ZtN56oFWvVXvz2VkDoe6fbG8TOgHFxEvqeqohmRnIHe5A1+HADk4OQww==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.2.tgz", + "integrity": "sha512-Iuws0kxo4yusk7sw70Xa2E2imZU5HoixzxfGCdxwBdhiDgt9vX9VUCBhqcwY7/uh//78A1hMkkROMJq9l27oLQ==", "cpu": [ "ia32" ], @@ -528,9 +528,9 @@ } }, "node_modules/@esbuild/win32-x64": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.9.tgz", - "integrity": "sha512-PPOl1mi6lpLNQxnGoyAfschAodRFYXJ+9fs6WHXz7CSWKbOqiMZsubC+BQsVKuul+3vKLuwTHsS2c2y9EoKwxQ==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.2.tgz", + "integrity": "sha512-sRdU18mcKf7F+YgheI/zGf5alZatMUTKj/jNS6l744f9u3WFu4v7twcUI9vu4mknF4Y9aDlblIie0IM+5xxaqQ==", "cpu": [ "x64" ], @@ -545,9 +545,9 @@ } }, "node_modules/@fastify/ajv-compiler": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-4.0.2.tgz", - "integrity": "sha512-Rkiu/8wIjpsf46Rr+Fitd3HRP+VsxUFDDeag0hs9L0ksfnwx2g7SPQQTFL0E8Qv+rfXzQOxBJnjUB9ITUDjfWQ==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/@fastify/ajv-compiler/-/ajv-compiler-4.0.5.tgz", + "integrity": "sha512-KoWKW+MhvfTRWL4qrhUwAAZoaChluo0m0vbiJlGMt2GXvL4LVPQEjt8kSpHI3IBq5Rez8fg+XeH3cneztq+C7A==", "funding": [ { "type": "github", @@ -621,9 +621,19 @@ } }, "node_modules/@fastify/forwarded": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.0.0.tgz", - "integrity": "sha512-kJExsp4JCms7ipzg7SJ3y8DwmePaELHxKYtg+tZow+k0znUTf3cb+npgyqm8+ATZOdmfgfydIebPDWM172wfyA==", + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/@fastify/forwarded/-/forwarded-3.0.1.tgz", + "integrity": "sha512-JqDochHFqXs3C3Ml3gOY58zM7OqO9ENqPo0UqAjAjH8L01fRZqwX9iLeX34//kiJubF7r2ZQHtBRU36vONbLlw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT" }, "node_modules/@fastify/merge-json-schemas": { @@ -646,9 +656,19 @@ } }, "node_modules/@fastify/proxy-addr": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.0.0.tgz", - "integrity": "sha512-37qVVA1qZ5sgH7KpHkkC4z9SK6StIsIcOmpjvMPXNb3vx2GQxhZocogVYbr2PbbeLCQxYIPDok307xEvRZOzGA==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/@fastify/proxy-addr/-/proxy-addr-5.1.0.tgz", + "integrity": "sha512-INS+6gh91cLUjB+PVHfu1UqcB76Sqtpyp7bnL+FYojhjygvOPA9ctiD/JDKsyD9Xgu4hUhCSJBPig/w7duNajw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT", "dependencies": { "@fastify/forwarded": "^3.0.0", @@ -657,7 +677,7 @@ }, "node_modules/@hono/node-server": { "version": "1.19.7", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/@hono/node-server/-/node-server-1.19.7.tgz", + "resolved": "https://registry.npmjs.org/@hono/node-server/-/node-server-1.19.7.tgz", "integrity": "sha512-vUcD0uauS7EU2caukW8z5lJKtoGMokxNbJtBiwHgpqxEXokaHCBkQUmCHhjFB1VUTWdqj25QoMkMKzgjq+uhrw==", "license": "MIT", "engines": { @@ -747,9 +767,9 @@ "license": "MIT" }, "node_modules/@jridgewell/trace-mapping": { - "version": "0.3.30", - "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.30.tgz", - "integrity": "sha512-GQ7Nw5G2lTu/BtHTKfXhKHok2WGetd4XYcVKGx00SjAk8GMwgJM3zr6zORiPGuOE+/vkc90KtTosSSvaCjKb2Q==", + "version": "0.3.31", + "resolved": "https://registry.npmjs.org/@jridgewell/trace-mapping/-/trace-mapping-0.3.31.tgz", + "integrity": "sha512-zzNR+SdQSDJzc8joaeP8QQoCQr8NuYx2dIIytl1QeBEZHJ9uW6hebsrYgbz8hJwUQao3TWCMtmfV8Nu1twOLAw==", "dev": true, "license": "MIT", "dependencies": { @@ -758,19 +778,20 @@ } }, "node_modules/@microsoft/api-extractor": { - "version": "7.52.10", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.52.10.tgz", - "integrity": "sha512-LhKytJM5ZJkbHQVfW/3o747rZUNs/MGg6j/wt/9qwwqEOfvUDTYXXxIBuMgrRXhJ528p41iyz4zjBVHZU74Odg==", + "version": "7.55.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor/-/api-extractor-7.55.2.tgz", + "integrity": "sha512-1jlWO4qmgqYoVUcyh+oXYRztZde/pAi7cSVzBz/rc+S7CoVzDasy8QE13dx6sLG4VRo8SfkkLbFORR6tBw4uGQ==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/api-extractor-model": "7.30.7", - "@microsoft/tsdoc": "~0.15.1", - "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.14.0", - "@rushstack/rig-package": "0.5.3", - "@rushstack/terminal": "0.15.4", - "@rushstack/ts-command-line": "5.0.2", + "@microsoft/api-extractor-model": "7.32.2", + "@microsoft/tsdoc": "~0.16.0", + "@microsoft/tsdoc-config": "~0.18.0", + "@rushstack/node-core-library": "5.19.1", + "@rushstack/rig-package": "0.6.0", + "@rushstack/terminal": "0.19.5", + "@rushstack/ts-command-line": "5.1.5", + "diff": "~8.0.2", "lodash": "~4.17.15", "minimatch": "10.0.3", "resolve": "~1.22.1", @@ -783,15 +804,15 @@ } }, "node_modules/@microsoft/api-extractor-model": { - "version": "7.30.7", - "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.30.7.tgz", - "integrity": "sha512-TBbmSI2/BHpfR9YhQA7nH0nqVmGgJ0xH0Ex4D99/qBDAUpnhA2oikGmdXanbw9AWWY/ExBYIpkmY8dBHdla3YQ==", + "version": "7.32.2", + "resolved": "https://registry.npmjs.org/@microsoft/api-extractor-model/-/api-extractor-model-7.32.2.tgz", + "integrity": "sha512-Ussc25rAalc+4JJs9HNQE7TuO9y6jpYQX9nWD1DhqUzYPBr3Lr7O9intf+ZY8kD5HnIqeIRJX7ccCT0QyBy2Ww==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/tsdoc": "~0.15.1", - "@microsoft/tsdoc-config": "~0.17.1", - "@rushstack/node-core-library": "5.14.0" + "@microsoft/tsdoc": "~0.16.0", + "@microsoft/tsdoc-config": "~0.18.0", + "@rushstack/node-core-library": "5.19.1" } }, "node_modules/@microsoft/api-extractor/node_modules/lru-cache": { @@ -854,20 +875,20 @@ } }, "node_modules/@microsoft/tsdoc": { - "version": "0.15.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.15.1.tgz", - "integrity": "sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==", + "version": "0.16.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc/-/tsdoc-0.16.0.tgz", + "integrity": "sha512-xgAyonlVVS+q7Vc7qLW0UrJU7rSFcETRWsqdXZtjzRU8dF+6CkozTK4V4y1LwOX7j8r/vHphjDeMeGI4tNGeGA==", "dev": true, "license": "MIT" }, "node_modules/@microsoft/tsdoc-config": { - "version": "0.17.1", - "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.17.1.tgz", - "integrity": "sha512-UtjIFe0C6oYgTnad4q1QP4qXwLhe6tIpNTRStJ2RZEPIkqQPREAwE5spzVxsdn9UaEMUqhh0AqSx3X4nWAKXWw==", + "version": "0.18.0", + "resolved": "https://registry.npmjs.org/@microsoft/tsdoc-config/-/tsdoc-config-0.18.0.tgz", + "integrity": "sha512-8N/vClYyfOH+l4fLkkr9+myAoR6M7akc8ntBJ4DJdWH2b09uVfr71+LTMpNyG19fNqWDg8KEDZhx5wxuqHyGjw==", "dev": true, "license": "MIT", "dependencies": { - "@microsoft/tsdoc": "0.15.1", + "@microsoft/tsdoc": "0.16.0", "ajv": "~8.12.0", "jju": "~1.4.0", "resolve": "~1.22.2" @@ -929,6 +950,12 @@ } } }, + "node_modules/@pinojs/redact": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/@pinojs/redact/-/redact-0.4.0.tgz", + "integrity": "sha512-k2ENnmBugE/rzQfEcdWHcCY+/FM3VLzH9cYEsbdsoqrvzAKRhUZeRNhAZvB8OitQJ1TBed3yqWtdjzS6wJKBwg==", + "license": "MIT" + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", @@ -941,9 +968,9 @@ } }, "node_modules/@rollup/pluginutils": { - "version": "5.2.0", - "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.2.0.tgz", - "integrity": "sha512-qWJ2ZTbmumwiLFomfzTyt5Kng4hwPi9rwCYN4SHb6eaRU1KNO4ccxINHr/VhH4GgPlt1XfSTLX2LBTme8ne4Zw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/@rollup/pluginutils/-/pluginutils-5.3.0.tgz", + "integrity": "sha512-5EdhGZtnu3V88ces7s53hhfK5KSASnJZv8Lulpc04cWO3REESroJXg73DFsOmgbU2BhwV0E20bu2IDZb3VKW4Q==", "dev": true, "license": "MIT", "dependencies": { @@ -971,9 +998,9 @@ "license": "MIT" }, "node_modules/@rollup/rollup-android-arm-eabi": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.46.2.tgz", - "integrity": "sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.55.1.tgz", + "integrity": "sha512-9R0DM/ykwfGIlNu6+2U09ga0WXeZ9MRC2Ter8jnz8415VbuIykVuc6bhdrbORFZANDmTDvq26mJrEVTl8TdnDg==", "cpu": [ "arm" ], @@ -985,9 +1012,9 @@ ] }, "node_modules/@rollup/rollup-android-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.46.2.tgz", - "integrity": "sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.55.1.tgz", + "integrity": "sha512-eFZCb1YUqhTysgW3sj/55du5cG57S7UTNtdMjCW7LwVcj3dTTcowCsC8p7uBdzKsZYa8J7IDE8lhMI+HX1vQvg==", "cpu": [ "arm64" ], @@ -999,9 +1026,9 @@ ] }, "node_modules/@rollup/rollup-darwin-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.46.2.tgz", - "integrity": "sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.55.1.tgz", + "integrity": "sha512-p3grE2PHcQm2e8PSGZdzIhCKbMCw/xi9XvMPErPhwO17vxtvCN5FEA2mSLgmKlCjHGMQTP6phuQTYWUnKewwGg==", "cpu": [ "arm64" ], @@ -1013,9 +1040,9 @@ ] }, "node_modules/@rollup/rollup-darwin-x64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.46.2.tgz", - "integrity": "sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.55.1.tgz", + "integrity": "sha512-rDUjG25C9qoTm+e02Esi+aqTKSBYwVTaoS1wxcN47/Luqef57Vgp96xNANwt5npq9GDxsH7kXxNkJVEsWEOEaQ==", "cpu": [ "x64" ], @@ -1027,9 +1054,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-arm64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.46.2.tgz", - "integrity": "sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.55.1.tgz", + "integrity": "sha512-+JiU7Jbp5cdxekIgdte0jfcu5oqw4GCKr6i3PJTlXTCU5H5Fvtkpbs4XJHRmWNXF+hKmn4v7ogI5OQPaupJgOg==", "cpu": [ "arm64" ], @@ -1041,9 +1068,9 @@ ] }, "node_modules/@rollup/rollup-freebsd-x64": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.46.2.tgz", - "integrity": "sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.55.1.tgz", + "integrity": "sha512-V5xC1tOVWtLLmr3YUk2f6EJK4qksksOYiz/TCsFHu/R+woubcLWdC9nZQmwjOAbmExBIVKsm1/wKmEy4z4u4Bw==", "cpu": [ "x64" ], @@ -1055,9 +1082,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-gnueabihf": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.46.2.tgz", - "integrity": "sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.55.1.tgz", + "integrity": "sha512-Rn3n+FUk2J5VWx+ywrG/HGPTD9jXNbicRtTM11e/uorplArnXZYsVifnPPqNNP5BsO3roI4n8332ukpY/zN7rQ==", "cpu": [ "arm" ], @@ -1069,9 +1096,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm-musleabihf": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.46.2.tgz", - "integrity": "sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.55.1.tgz", + "integrity": "sha512-grPNWydeKtc1aEdrJDWk4opD7nFtQbMmV7769hiAaYyUKCT1faPRm2av8CX1YJsZ4TLAZcg9gTR1KvEzoLjXkg==", "cpu": [ "arm" ], @@ -1083,9 +1110,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.46.2.tgz", - "integrity": "sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.55.1.tgz", + "integrity": "sha512-a59mwd1k6x8tXKcUxSyISiquLwB5pX+fJW9TkWU46lCqD/GRDe9uDN31jrMmVP3feI3mhAdvcCClhV8V5MhJFQ==", "cpu": [ "arm64" ], @@ -1097,9 +1124,9 @@ ] }, "node_modules/@rollup/rollup-linux-arm64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.46.2.tgz", - "integrity": "sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.55.1.tgz", + "integrity": "sha512-puS1MEgWX5GsHSoiAsF0TYrpomdvkaXm0CofIMG5uVkP6IBV+ZO9xhC5YEN49nsgYo1DuuMquF9+7EDBVYu4uA==", "cpu": [ "arm64" ], @@ -1110,10 +1137,24 @@ "linux" ] }, - "node_modules/@rollup/rollup-linux-loongarch64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.46.2.tgz", - "integrity": "sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==", + "node_modules/@rollup/rollup-linux-loong64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-gnu/-/rollup-linux-loong64-gnu-4.55.1.tgz", + "integrity": "sha512-r3Wv40in+lTsULSb6nnoudVbARdOwb2u5fpeoOAZjFLznp6tDU8kd+GTHmJoqZ9lt6/Sys33KdIHUaQihFcu7g==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-loong64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loong64-musl/-/rollup-linux-loong64-musl-4.55.1.tgz", + "integrity": "sha512-MR8c0+UxAlB22Fq4R+aQSPBayvYa3+9DrwG/i1TKQXFYEaoW3B5b/rkSRIypcZDdWjWnpcvxbNaAJDcSbJU3Lw==", "cpu": [ "loong64" ], @@ -1125,9 +1166,23 @@ ] }, "node_modules/@rollup/rollup-linux-ppc64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.46.2.tgz", - "integrity": "sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-gnu/-/rollup-linux-ppc64-gnu-4.55.1.tgz", + "integrity": "sha512-3KhoECe1BRlSYpMTeVrD4sh2Pw2xgt4jzNSZIIPLFEsnQn9gAnZagW9+VqDqAHgm1Xc77LzJOo2LdigS5qZ+gw==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@rollup/rollup-linux-ppc64-musl": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-ppc64-musl/-/rollup-linux-ppc64-musl-4.55.1.tgz", + "integrity": "sha512-ziR1OuZx0vdYZZ30vueNZTg73alF59DicYrPViG0NEgDVN8/Jl87zkAPu4u6VjZST2llgEUjaiNl9JM6HH1Vdw==", "cpu": [ "ppc64" ], @@ -1139,9 +1194,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.46.2.tgz", - "integrity": "sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.55.1.tgz", + "integrity": "sha512-uW0Y12ih2XJRERZ4jAfKamTyIHVMPQnTZcQjme2HMVDAHY4amf5u414OqNYC+x+LzRdRcnIG1YodLrrtA8xsxw==", "cpu": [ "riscv64" ], @@ -1153,9 +1208,9 @@ ] }, "node_modules/@rollup/rollup-linux-riscv64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.46.2.tgz", - "integrity": "sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.55.1.tgz", + "integrity": "sha512-u9yZ0jUkOED1BFrqu3BwMQoixvGHGZ+JhJNkNKY/hyoEgOwlqKb62qu+7UjbPSHYjiVy8kKJHvXKv5coH4wDeg==", "cpu": [ "riscv64" ], @@ -1167,9 +1222,9 @@ ] }, "node_modules/@rollup/rollup-linux-s390x-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.46.2.tgz", - "integrity": "sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.55.1.tgz", + "integrity": "sha512-/0PenBCmqM4ZUd0190j7J0UsQ/1nsi735iPRakO8iPciE7BQ495Y6msPzaOmvx0/pn+eJVVlZrNrSh4WSYLxNg==", "cpu": [ "s390x" ], @@ -1181,9 +1236,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-gnu": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.46.2.tgz", - "integrity": "sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.55.1.tgz", + "integrity": "sha512-a8G4wiQxQG2BAvo+gU6XrReRRqj+pLS2NGXKm8io19goR+K8lw269eTrPkSdDTALwMmJp4th2Uh0D8J9bEV1vg==", "cpu": [ "x64" ], @@ -1195,9 +1250,9 @@ ] }, "node_modules/@rollup/rollup-linux-x64-musl": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.46.2.tgz", - "integrity": "sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.55.1.tgz", + "integrity": "sha512-bD+zjpFrMpP/hqkfEcnjXWHMw5BIghGisOKPj+2NaNDuVT+8Ds4mPf3XcPHuat1tz89WRL+1wbcxKY3WSbiT7w==", "cpu": [ "x64" ], @@ -1208,10 +1263,38 @@ "linux" ] }, + "node_modules/@rollup/rollup-openbsd-x64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openbsd-x64/-/rollup-openbsd-x64-4.55.1.tgz", + "integrity": "sha512-eLXw0dOiqE4QmvikfQ6yjgkg/xDM+MdU9YJuP4ySTibXU0oAvnEWXt7UDJmD4UkYialMfOGFPJnIHSe/kdzPxg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ] + }, + "node_modules/@rollup/rollup-openharmony-arm64": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-openharmony-arm64/-/rollup-openharmony-arm64-4.55.1.tgz", + "integrity": "sha512-xzm44KgEP11te3S2HCSyYf5zIzWmx3n8HDCc7EE59+lTcswEWNpvMLfd9uJvVX8LCg9QWG67Xt75AuHn4vgsXw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ] + }, "node_modules/@rollup/rollup-win32-arm64-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.46.2.tgz", - "integrity": "sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.55.1.tgz", + "integrity": "sha512-yR6Bl3tMC/gBok5cz/Qi0xYnVbIxGx5Fcf/ca0eB6/6JwOY+SRUcJfI0OpeTpPls7f194as62thCt/2BjxYN8g==", "cpu": [ "arm64" ], @@ -1223,9 +1306,9 @@ ] }, "node_modules/@rollup/rollup-win32-ia32-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.46.2.tgz", - "integrity": "sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.55.1.tgz", + "integrity": "sha512-3fZBidchE0eY0oFZBnekYCfg+5wAB0mbpCBuofh5mZuzIU/4jIVkbESmd2dOsFNS78b53CYv3OAtwqkZZmU5nA==", "cpu": [ "ia32" ], @@ -1236,10 +1319,24 @@ "win32" ] }, + "node_modules/@rollup/rollup-win32-x64-gnu": { + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-gnu/-/rollup-win32-x64-gnu-4.55.1.tgz", + "integrity": "sha512-xGGY5pXj69IxKb4yv/POoocPy/qmEGhimy/FoTpTSVju3FYXUQQMFCaZZXJVidsmGxRioZAwpThl/4zX41gRKg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@rollup/rollup-win32-x64-msvc": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.46.2.tgz", - "integrity": "sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.55.1.tgz", + "integrity": "sha512-SPEpaL6DX4rmcXtnhdrQYgzQ5W2uW3SCJch88lB2zImhJRhIIK44fkUrgIV/Q8yUNfw5oyZ5vkeQsZLhCb06lw==", "cpu": [ "x64" ], @@ -1251,9 +1348,9 @@ ] }, "node_modules/@rushstack/node-core-library": { - "version": "5.14.0", - "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.14.0.tgz", - "integrity": "sha512-eRong84/rwQUlATGFW3TMTYVyqL1vfW9Lf10PH+mVGfIb9HzU3h5AASNIw+axnBLjnD0n3rT5uQBwu9fvzATrg==", + "version": "5.19.1", + "resolved": "https://registry.npmjs.org/@rushstack/node-core-library/-/node-core-library-5.19.1.tgz", + "integrity": "sha512-ESpb2Tajlatgbmzzukg6zyAhH+sICqJR2CNXNhXcEbz6UGCQfrKCtkxOpJTftWc8RGouroHG0Nud1SJAszvpmA==", "dev": true, "license": "MIT", "dependencies": { @@ -1292,21 +1389,6 @@ "url": "https://github.com/sponsors/epoberezkin" } }, - "node_modules/@rushstack/node-core-library/node_modules/ajv-draft-04": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", - "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", - "dev": true, - "license": "MIT", - "peerDependencies": { - "ajv": "^8.5.0" - }, - "peerDependenciesMeta": { - "ajv": { - "optional": true - } - } - }, "node_modules/@rushstack/node-core-library/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -1336,10 +1418,25 @@ "node": ">=10" } }, + "node_modules/@rushstack/problem-matcher": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@rushstack/problem-matcher/-/problem-matcher-0.1.1.tgz", + "integrity": "sha512-Fm5XtS7+G8HLcJHCWpES5VmeMyjAKaWeyZU5qPzZC+22mPlJzAsOxymHiWIfuirtPckX3aptWws+K2d0BzniJA==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "@types/node": "*" + }, + "peerDependenciesMeta": { + "@types/node": { + "optional": true + } + } + }, "node_modules/@rushstack/rig-package": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.5.3.tgz", - "integrity": "sha512-olzSSjYrvCNxUFZowevC3uz8gvKr3WTpHQ7BkpjtRpA3wK+T0ybep/SRUMfr195gBzJm5gaXw0ZMgjIyHqJUow==", + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/@rushstack/rig-package/-/rig-package-0.6.0.tgz", + "integrity": "sha512-ZQmfzsLE2+Y91GF15c65L/slMRVhF6Hycq04D4TwtdGaUAbIXXg9c5pKA5KFU7M4QMaihoobp9JJYpYcaY3zOw==", "dev": true, "license": "MIT", "dependencies": { @@ -1348,13 +1445,14 @@ } }, "node_modules/@rushstack/terminal": { - "version": "0.15.4", - "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.15.4.tgz", - "integrity": "sha512-OQSThV0itlwVNHV6thoXiAYZlQh4Fgvie2CzxFABsbO2MWQsI4zOh3LRNigYSTrmS+ba2j0B3EObakPzf/x6Zg==", + "version": "0.19.5", + "resolved": "https://registry.npmjs.org/@rushstack/terminal/-/terminal-0.19.5.tgz", + "integrity": "sha512-6k5tpdB88G0K7QrH/3yfKO84HK9ggftfUZ51p7fePyCE7+RLLHkWZbID9OFWbXuna+eeCFE7AkKnRMHMxNbz7Q==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/node-core-library": "5.14.0", + "@rushstack/node-core-library": "5.19.1", + "@rushstack/problem-matcher": "0.1.1", "supports-color": "~8.1.1" }, "peerDependencies": { @@ -1383,13 +1481,13 @@ } }, "node_modules/@rushstack/ts-command-line": { - "version": "5.0.2", - "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.0.2.tgz", - "integrity": "sha512-+AkJDbu1GFMPIU8Sb7TLVXDv/Q7Mkvx+wAjEl8XiXVVq+p1FmWW6M3LYpJMmoHNckSofeMecgWg5lfMwNAAsEQ==", + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/@rushstack/ts-command-line/-/ts-command-line-5.1.5.tgz", + "integrity": "sha512-YmrFTFUdHXblYSa+Xc9OO9FsL/XFcckZy0ycQ6q7VSBsVs5P0uD9vcges5Q9vctGlVdu27w+Ct6IuJ458V0cTQ==", "dev": true, "license": "MIT", "dependencies": { - "@rushstack/terminal": "0.15.4", + "@rushstack/terminal": "0.19.5", "@types/argparse": "1.0.38", "argparse": "~1.0.9", "string-argv": "~0.3.1" @@ -1403,13 +1501,14 @@ "license": "MIT" }, "node_modules/@types/chai": { - "version": "5.2.2", - "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz", - "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==", + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.3.tgz", + "integrity": "sha512-Mw558oeA9fFbv65/y4mHtXDs9bPnFMZAL/jxdPFUpOHHIXX91mcgEHbS5Lahr+pwZFR8A7GQleRWeI6cGFC2UA==", "dev": true, "license": "MIT", "dependencies": { - "@types/deep-eql": "*" + "@types/deep-eql": "*", + "assertion-error": "^2.0.1" } }, "node_modules/@types/connect": { @@ -1437,9 +1536,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.11", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.11.tgz", - "integrity": "sha512-uug3FEEGv0r+jrecvUUpbY8lLisvIjg6AAic6a2bSP5OEOLeJsDSnvhCDov7ipFFMXS3orMpzlmi0ZcuGkBbow==", + "version": "20.19.27", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.27.tgz", + "integrity": "sha512-N2clP5pJhB2YnZJ3PIHFk5RkygRX5WO/5f0WC08tp0wd+sv0rsJk3MqWn3CbNmT2J505a5336jaQj4ph1AdMug==", "dev": true, "license": "MIT", "dependencies": { @@ -1596,44 +1695,44 @@ } }, "node_modules/@volar/language-core": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.23.tgz", - "integrity": "sha512-hEEd5ET/oSmBC6pi1j6NaNYRWoAiDhINbT8rmwtINugR39loROSlufGdYMF9TaKGfz+ViGs1Idi3mAhnuPcoGQ==", + "version": "2.4.27", + "resolved": "https://registry.npmjs.org/@volar/language-core/-/language-core-2.4.27.tgz", + "integrity": "sha512-DjmjBWZ4tJKxfNC1F6HyYERNHPYS7L7OPFyCrestykNdUZMFYzI9WTyvwPcaNaHlrEUwESHYsfEw3isInncZxQ==", "dev": true, "license": "MIT", "dependencies": { - "@volar/source-map": "2.4.23" + "@volar/source-map": "2.4.27" } }, "node_modules/@volar/source-map": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.23.tgz", - "integrity": "sha512-Z1Uc8IB57Lm6k7q6KIDu/p+JWtf3xsXJqAX/5r18hYOTpJyBn0KXUR8oTJ4WFYOcDzWC9n3IflGgHowx6U6z9Q==", + "version": "2.4.27", + "resolved": "https://registry.npmjs.org/@volar/source-map/-/source-map-2.4.27.tgz", + "integrity": "sha512-ynlcBReMgOZj2i6po+qVswtDUeeBRCTgDurjMGShbm8WYZgJ0PA4RmtebBJ0BCYol1qPv3GQF6jK7C9qoVc7lg==", "dev": true, "license": "MIT" }, "node_modules/@volar/typescript": { - "version": "2.4.23", - "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.23.tgz", - "integrity": "sha512-lAB5zJghWxVPqfcStmAP1ZqQacMpe90UrP5RJ3arDyrhy4aCUQqmxPPLB2PWDKugvylmO41ljK7vZ+t6INMTag==", + "version": "2.4.27", + "resolved": "https://registry.npmjs.org/@volar/typescript/-/typescript-2.4.27.tgz", + "integrity": "sha512-eWaYCcl/uAPInSK2Lze6IqVWaBu/itVqR5InXcHXFyles4zO++Mglt3oxdgj75BDcv1Knr9Y93nowS8U3wqhxg==", "dev": true, "license": "MIT", "dependencies": { - "@volar/language-core": "2.4.23", + "@volar/language-core": "2.4.27", "path-browserify": "^1.0.1", "vscode-uri": "^3.0.8" } }, "node_modules/@vue/compiler-core": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.18.tgz", - "integrity": "sha512-3slwjQrrV1TO8MoXgy3aynDQ7lslj5UqDxuHnrzHtpON5CBinhWjJETciPngpin/T3OuW3tXUf86tEurusnztw==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-core/-/compiler-core-3.5.26.tgz", + "integrity": "sha512-vXyI5GMfuoBCnv5ucIT7jhHKl55Y477yxP6fc4eUswjP8FG3FFVFd41eNDArR+Uk3QKn2Z85NavjaxLxOC19/w==", "dev": true, "license": "MIT", "dependencies": { - "@babel/parser": "^7.28.0", - "@vue/shared": "3.5.18", - "entities": "^4.5.0", + "@babel/parser": "^7.28.5", + "@vue/shared": "3.5.26", + "entities": "^7.0.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.1" } @@ -1646,14 +1745,14 @@ "license": "MIT" }, "node_modules/@vue/compiler-dom": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.18.tgz", - "integrity": "sha512-RMbU6NTU70++B1JyVJbNbeFkK+A+Q7y9XKE2EM4NLGm2WFR8x9MbAtWxPPLdm0wUkuZv9trpwfSlL6tjdIa1+A==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.26.tgz", + "integrity": "sha512-y1Tcd3eXs834QjswshSilCBnKGeQjQXB6PqFn/1nxcQw4pmG42G8lwz+FZPAZAby6gZeHSt/8LMPfZ4Rb+Bd/A==", "dev": true, "license": "MIT", "dependencies": { - "@vue/compiler-core": "3.5.18", - "@vue/shared": "3.5.18" + "@vue/compiler-core": "3.5.26", + "@vue/shared": "3.5.26" } }, "node_modules/@vue/compiler-vue2": { @@ -1693,9 +1792,9 @@ } }, "node_modules/@vue/shared": { - "version": "3.5.18", - "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.18.tgz", - "integrity": "sha512-cZy8Dq+uuIXbxCZpuLd2GJdeSO/lIzIspC2WtkqIpje5QyFbvLaI5wZtdUjLHjGZrlVX6GilejatWwVYYRc8tA==", + "version": "3.5.26", + "resolved": "https://registry.npmjs.org/@vue/shared/-/shared-3.5.26.tgz", + "integrity": "sha512-7Z6/y3uFI5PRoKeorTOSXKcDj0MSasfNNltcslbFrPpcw6aXRUALq4IfJlaTRspiWIUOEZbrpM+iQGmCOiWe4A==", "dev": true, "license": "MIT" }, @@ -1733,7 +1832,7 @@ }, "node_modules/ajv": { "version": "8.17.1", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/ajv/-/ajv-8.17.1.tgz", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", "license": "MIT", "dependencies": { @@ -1747,6 +1846,21 @@ "url": "https://github.com/sponsors/epoberezkin" } }, + "node_modules/ajv-draft-04": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/ajv-draft-04/-/ajv-draft-04-1.0.0.tgz", + "integrity": "sha512-mv00Te6nmYbRp5DCwclxtt7yV/joXJPGS7nM+97GdxvuttCOfgI3K4U25zboyeX0O+myI8ERluxQe5wljMmVIw==", + "dev": true, + "license": "MIT", + "peerDependencies": { + "ajv": "^8.5.0" + }, + "peerDependenciesMeta": { + "ajv": { + "optional": true + } + } + }, "node_modules/ajv-formats": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-3.0.1.tgz", @@ -1772,9 +1886,9 @@ "license": "MIT" }, "node_modules/ansi-regex": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", - "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "version": "6.2.2", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", + "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", "dev": true, "license": "MIT", "engines": { @@ -1785,9 +1899,9 @@ } }, "node_modules/ansi-styles": { - "version": "6.2.1", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", - "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "version": "6.2.3", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", + "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", "dev": true, "license": "MIT", "engines": { @@ -1818,13 +1932,13 @@ } }, "node_modules/ast-v8-to-istanbul": { - "version": "0.3.4", - "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.4.tgz", - "integrity": "sha512-cxrAnZNLBnQwBPByK4CeDaw5sWZtMilJE/Q3iDA0aamgaIVNDF9T6K2/8DfYDZEejZ2jNnDrG9m8MY72HFd0KA==", + "version": "0.3.10", + "resolved": "https://registry.npmjs.org/ast-v8-to-istanbul/-/ast-v8-to-istanbul-0.3.10.tgz", + "integrity": "sha512-p4K7vMz2ZSk3wN8l5o3y2bJAoZXT3VuJI5OLTATY/01CYWumWvwkUw0SqDBnNq6IiTO3qDa1eSQDibAV8g7XOQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/trace-mapping": "^0.3.29", + "@jridgewell/trace-mapping": "^0.3.31", "estree-walker": "^3.0.3", "js-tokens": "^9.0.1" } @@ -1856,9 +1970,9 @@ "license": "MIT" }, "node_modules/body-parser": { - "version": "2.2.1", - "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.1.tgz", - "integrity": "sha512-nfDwkulwiZYQIGwxdy0RUmowMhKcFVcYXUU7m4QlKYim1rUtg83xm2yjZ40QjDuc291AJjjeSc9b++AWHSgSHw==", + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz", + "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==", "license": "MIT", "dependencies": { "bytes": "^3.1.2", @@ -1867,7 +1981,7 @@ "http-errors": "^2.0.0", "iconv-lite": "^0.7.0", "on-finished": "^2.4.1", - "qs": "^6.14.0", + "qs": "^6.14.1", "raw-body": "^3.0.1", "type-is": "^2.0.1" }, @@ -1938,9 +2052,9 @@ } }, "node_modules/chai": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.1.tgz", - "integrity": "sha512-5nFxhUrX0PqtyogoYOA8IPswy5sZFTOsBFl/9bNsmDLgsxYTzSZQJDPppDnZPTQbzSEm0hqGjWPzRemQCYbD6A==", + "version": "5.3.3", + "resolved": "https://registry.npmjs.org/chai/-/chai-5.3.3.tgz", + "integrity": "sha512-4zNhdJD/iOjSH0A05ea+Ke6MU5mmpQcbQsSOkgdaUMJ9zTlDTD/GYlwohmIE2u0gaxHYiVHEn1Fw9mZ/ktJWgw==", "dev": true, "license": "MIT", "dependencies": { @@ -1955,9 +2069,9 @@ } }, "node_modules/check-error": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz", - "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==", + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.3.tgz", + "integrity": "sha512-PAJdDJusoxnwm1VwW07VWwUN1sl7smmC3OKggvndJFadxxDRyFJBX/ggnu/KE4kQAB7a3Dp8f/YXC1FlUprWmA==", "dev": true, "license": "MIT", "engines": { @@ -1999,15 +2113,16 @@ "license": "MIT" }, "node_modules/content-disposition": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.0.tgz", - "integrity": "sha512-Au9nRL8VNUut/XSzbQA38+M78dzP4D+eqg3gfJHMIHHYa3bg067xj1KxMUWj+VULbiZMowKngFFbKczUrNJ1mg==", + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz", + "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==", "license": "MIT", - "dependencies": { - "safe-buffer": "5.2.1" - }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/content-type": { @@ -2116,6 +2231,16 @@ "node": ">=6" } }, + "node_modules/diff": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-8.0.2.tgz", + "integrity": "sha512-sSuxWU5j5SR9QQji/o2qMvqRNYRDOcBTgsJ/DeCf4iSN4gW+gNMXM7wFIP+fdXZxoNiAnHUTGjCr+TSWXdRDKg==", + "dev": true, + "license": "BSD-3-Clause", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dunder-proto": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz", @@ -2160,9 +2285,9 @@ } }, "node_modules/entities": { - "version": "4.5.0", - "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz", - "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.0.tgz", + "integrity": "sha512-FDWG5cmEYf2Z00IkYRhbFrwIwvdFKH07uV8dvNy0omp/Qb1xcyCWp2UDtcwJF4QZZvk0sLudP6/hAu42TaqVhQ==", "dev": true, "license": "BSD-2-Clause", "engines": { @@ -2210,9 +2335,9 @@ } }, "node_modules/esbuild": { - "version": "0.25.9", - "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.9.tgz", - "integrity": "sha512-CRbODhYyQx3qp7ZEwzxOk4JBqmD/seJrzPa/cGjY1VtIn5E09Oi9/dB4JwctnfZ8Q8iT7rioVv5k/FNT/uf54g==", + "version": "0.27.2", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.2.tgz", + "integrity": "sha512-HyNQImnsOC7X9PMNaCIeAm4ISCQXs5a5YasTXVliKv4uuBo1dKrG0A+uQS8M5eXjVMnLg3WgXaKvprHlFJQffw==", "dev": true, "hasInstallScript": true, "license": "MIT", @@ -2223,32 +2348,32 @@ "node": ">=18" }, "optionalDependencies": { - "@esbuild/aix-ppc64": "0.25.9", - "@esbuild/android-arm": "0.25.9", - "@esbuild/android-arm64": "0.25.9", - "@esbuild/android-x64": "0.25.9", - "@esbuild/darwin-arm64": "0.25.9", - "@esbuild/darwin-x64": "0.25.9", - "@esbuild/freebsd-arm64": "0.25.9", - "@esbuild/freebsd-x64": "0.25.9", - "@esbuild/linux-arm": "0.25.9", - "@esbuild/linux-arm64": "0.25.9", - "@esbuild/linux-ia32": "0.25.9", - "@esbuild/linux-loong64": "0.25.9", - "@esbuild/linux-mips64el": "0.25.9", - "@esbuild/linux-ppc64": "0.25.9", - "@esbuild/linux-riscv64": "0.25.9", - "@esbuild/linux-s390x": "0.25.9", - "@esbuild/linux-x64": "0.25.9", - "@esbuild/netbsd-arm64": "0.25.9", - "@esbuild/netbsd-x64": "0.25.9", - "@esbuild/openbsd-arm64": "0.25.9", - "@esbuild/openbsd-x64": "0.25.9", - "@esbuild/openharmony-arm64": "0.25.9", - "@esbuild/sunos-x64": "0.25.9", - "@esbuild/win32-arm64": "0.25.9", - "@esbuild/win32-ia32": "0.25.9", - "@esbuild/win32-x64": "0.25.9" + "@esbuild/aix-ppc64": "0.27.2", + "@esbuild/android-arm": "0.27.2", + "@esbuild/android-arm64": "0.27.2", + "@esbuild/android-x64": "0.27.2", + "@esbuild/darwin-arm64": "0.27.2", + "@esbuild/darwin-x64": "0.27.2", + "@esbuild/freebsd-arm64": "0.27.2", + "@esbuild/freebsd-x64": "0.27.2", + "@esbuild/linux-arm": "0.27.2", + "@esbuild/linux-arm64": "0.27.2", + "@esbuild/linux-ia32": "0.27.2", + "@esbuild/linux-loong64": "0.27.2", + "@esbuild/linux-mips64el": "0.27.2", + "@esbuild/linux-ppc64": "0.27.2", + "@esbuild/linux-riscv64": "0.27.2", + "@esbuild/linux-s390x": "0.27.2", + "@esbuild/linux-x64": "0.27.2", + "@esbuild/netbsd-arm64": "0.27.2", + "@esbuild/netbsd-x64": "0.27.2", + "@esbuild/openbsd-arm64": "0.27.2", + "@esbuild/openbsd-x64": "0.27.2", + "@esbuild/openharmony-arm64": "0.27.2", + "@esbuild/sunos-x64": "0.27.2", + "@esbuild/win32-arm64": "0.27.2", + "@esbuild/win32-ia32": "0.27.2", + "@esbuild/win32-x64": "0.27.2" } }, "node_modules/escape-html": { @@ -2289,18 +2414,18 @@ } }, "node_modules/eventsource-parser": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.3.tgz", - "integrity": "sha512-nVpZkTMM9rF6AQ9gPJpFsNAMt48wIzB5TQgiTLdHiuO8XEDhUgZEhqKlZWXbIzo9VmJ/HvysHqEaVeD5v9TPvA==", + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/eventsource-parser/-/eventsource-parser-3.0.6.tgz", + "integrity": "sha512-Vo1ab+QXPzZ4tCa8SwIHJFaSzy4R6SHf7BY79rFBDf0idraZWAkYrDjDj8uWaSm3S2TK+hJ7/t1CEmZ7jXw+pg==", "license": "MIT", "engines": { - "node": ">=20.0.0" + "node": ">=18.0.0" } }, "node_modules/expect-type": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz", - "integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.3.0.tgz", + "integrity": "sha512-knvyeauYhqjOYvQ66MznSMs83wmHrCycNEN6Ao+2AeYEfxUIkuiVxdEa1qlGEPK+We3n0THiDciYSsCcgW/DoA==", "dev": true, "license": "Apache-2.0", "engines": { @@ -2308,18 +2433,19 @@ } }, "node_modules/express": { - "version": "5.1.0", - "resolved": "https://registry.npmjs.org/express/-/express-5.1.0.tgz", - "integrity": "sha512-DT9ck5YIRU+8GYzzU5kT3eHGA5iL+1Zd0EutOmTE9Dtk+Tvuzd23VBU+ec7HPNSTxXYO55gPV/hq4pSBJDjFpA==", + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz", + "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==", "license": "MIT", "dependencies": { "accepts": "^2.0.0", - "body-parser": "^2.2.0", + "body-parser": "^2.2.1", "content-disposition": "^1.0.0", "content-type": "^1.0.5", "cookie": "^0.7.1", "cookie-signature": "^1.2.1", "debug": "^4.4.0", + "depd": "^2.0.0", "encodeurl": "^2.0.0", "escape-html": "^1.0.3", "etag": "^1.8.1", @@ -2365,9 +2491,9 @@ } }, "node_modules/exsolve": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.7.tgz", - "integrity": "sha512-VO5fQUzZtI6C+vx4w/4BWJpg3s/5l+6pRQEHzFRM8WFi4XffSP1Z+4qi7GbjWbvRQEbdIco5mIMq+zX4rPuLrw==", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/exsolve/-/exsolve-1.0.8.tgz", + "integrity": "sha512-LmDxfWXwcTArk8fUEnOfSZpHOJ6zOMUJKOtFLFqJLoKJetuQG874Uc7/Kki7zFLzYybmZhp1M7+98pfMqeX8yA==", "dev": true, "license": "MIT" }, @@ -2384,9 +2510,9 @@ "license": "MIT" }, "node_modules/fast-json-stringify": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.0.1.tgz", - "integrity": "sha512-s7SJE83QKBZwg54dIbD5rCtzOBVD43V1ReWXXYqBgwCwHLYAAT0RQc/FmrQglXqWPpz6omtryJQOau5jI4Nrvg==", + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-6.1.1.tgz", + "integrity": "sha512-DbgptncYEXZqDUOEl4krff4mUiVrTZZVI7BBrQR/T3BqMj/eM1flTC1Uk2uUoLcWCxjT95xKulV/Lc6hhOZsBQ==", "funding": [ { "type": "github", @@ -2403,7 +2529,7 @@ "ajv": "^8.12.0", "ajv-formats": "^3.0.1", "fast-uri": "^3.0.0", - "json-schema-ref-resolver": "^2.0.0", + "json-schema-ref-resolver": "^3.0.0", "rfdc": "^1.2.0" } }, @@ -2416,19 +2542,10 @@ "fast-decode-uri-component": "^1.0.1" } }, - "node_modules/fast-redact": { - "version": "3.5.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.5.0.tgz", - "integrity": "sha512-dwsoQlS7h9hMeYUq1W++23NDcBLV4KqONnITDV9DjfS3q1SgDGVrBdvvTLUotWtPSD7asWDV9/CmsZPy8Hf70A==", - "license": "MIT", - "engines": { - "node": ">=6" - } - }, "node_modules/fast-uri": { - "version": "3.0.6", - "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.6.tgz", - "integrity": "sha512-Atfo14OibSv5wAp4VWNsFYE1AchQRTv9cBGWET4pZWHzYshFSS9NQI6I57rdKn9croWVMbYFbLhJ+yJvmZIIHw==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.1.0.tgz", + "integrity": "sha512-iPeeDKJSWf4IEOasVVrknXpaBV0IApz/gp7S2bb7Z4Lljbl2MGJRqInZiUrQwV16cpzw/D3S5j5Julj/gT52AA==", "funding": [ { "type": "github", @@ -2442,9 +2559,9 @@ "license": "BSD-3-Clause" }, "node_modules/fastify": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.5.0.tgz", - "integrity": "sha512-ZWSWlzj3K/DcULCnCjEiC2zn2FBPdlZsSA/pnPa/dbUfLvxkD/Nqmb0XXMXLrWkeM4uQPUvjdJpwtXmTfriXqw==", + "version": "5.6.2", + "resolved": "https://registry.npmjs.org/fastify/-/fastify-5.6.2.tgz", + "integrity": "sha512-dPugdGnsvYkBlENLhCgX8yhyGCsCPrpA8lFWbTNU428l+YOnLgYHR69hzV8HWPC79n536EqzqQtvhtdaCE0dKg==", "funding": [ { "type": "github", @@ -2466,7 +2583,7 @@ "fast-json-stringify": "^6.0.0", "find-my-way": "^9.0.0", "light-my-request": "^6.0.0", - "pino": "^9.0.0", + "pino": "^10.1.0", "process-warning": "^5.0.0", "rfdc": "^1.3.1", "secure-json-parse": "^4.0.0", @@ -2475,15 +2592,25 @@ } }, "node_modules/fastify-plugin": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.0.1.tgz", - "integrity": "sha512-HCxs+YnRaWzCl+cWRYFnHmeRFyR5GVnJTAaCJQiYzQSDwK9MgJdyAsuL3nh0EWRCYMgQ5MeziymvmAhUHYHDUQ==", + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/fastify-plugin/-/fastify-plugin-5.1.0.tgz", + "integrity": "sha512-FAIDA8eovSt5qcDgcBvDuX/v0Cjz0ohGhENZ/wpc3y+oZCY2afZ9Baqql3g/lC+OHRnciQol4ww7tuthOb9idw==", + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/fastify" + }, + { + "type": "opencollective", + "url": "https://opencollective.com/fastify" + } + ], "license": "MIT" }, "node_modules/fastq": { - "version": "1.19.1", - "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", - "integrity": "sha512-GwLTyxkCXjXbxqIhTsMI2Nui8huMPtnxg7krajPJAjnEG/iiOS7i+zCtWGZR9G0NBKbXKh6X9m9UIsYX/N6vvQ==", + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.20.1.tgz", + "integrity": "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw==", "license": "ISC", "dependencies": { "reusify": "^1.0.4" @@ -2508,9 +2635,9 @@ } }, "node_modules/finalhandler": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.0.tgz", - "integrity": "sha512-/t88Ty3d5JWQbWYgaOGCCYfXRwV1+be02WqYYlL6h0lEiUAMPM8o8qKGO01YIkOHzka2up08wvgYD0mDiI+q3Q==", + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz", + "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==", "license": "MIT", "dependencies": { "debug": "^4.4.0", @@ -2521,13 +2648,17 @@ "statuses": "^2.0.1" }, "engines": { - "node": ">= 0.8" + "node": ">= 18.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/find-my-way": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.3.0.tgz", - "integrity": "sha512-eRoFWQw+Yv2tuYlK2pjFS2jGXSxSppAs3hSQjfxVKxM5amECzIgYYc1FEI8ZmhSh/Ig+FrKEz43NLRKJjYCZVg==", + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/find-my-way/-/find-my-way-9.4.0.tgz", + "integrity": "sha512-5Ye4vHsypZRYtS01ob/iwHzGRUDELlsoCftI/OZFhcLs1M0tkGPcXldE80TAZC5yYuJMBPJQQ43UHlqbJWiX2w==", "license": "MIT", "dependencies": { "fast-deep-equal": "^3.1.3", @@ -2574,9 +2705,9 @@ } }, "node_modules/fs-extra": { - "version": "11.3.1", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.1.tgz", - "integrity": "sha512-eXvGGwZ5CL17ZSwHWd3bbgk7UUpF6IFHtP57NYYakPvHOs8GDgDe5KJI36jIJzDkJ6eJjuzRA8eBQb6SkKue0g==", + "version": "11.3.3", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.3.3.tgz", + "integrity": "sha512-VWSRii4t0AFm6ixFFmLLx1t7wS1gh+ckoa84aOeapGum0h+EZd1EhEumSB+ZdDLnEPuucsVB9oB7cxJHap6Afg==", "dev": true, "license": "MIT", "dependencies": { @@ -2650,9 +2781,9 @@ } }, "node_modules/get-tsconfig": { - "version": "4.10.1", - "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz", - "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==", + "version": "4.13.0", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.13.0.tgz", + "integrity": "sha512-1VKTZJCwBrvbd+Wn3AOgQP/2Av+TfTCOlE4AcRJE72W1ksZXbAx8PPBR9RzgTeSPzlPMHrbANMH3LbltH73wxQ==", "dev": true, "license": "MIT", "dependencies": { @@ -2748,7 +2879,7 @@ }, "node_modules/hono": { "version": "4.11.3", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/hono/-/hono-4.11.3.tgz", + "resolved": "https://registry.npmjs.org/hono/-/hono-4.11.3.tgz", "integrity": "sha512-PmQi306+M/ct/m5s66Hrg+adPnkD5jiO6IjA7WhWw0gSBSo1EcRegwuI1deZ+wd5pzCGynCcn2DprnE4/yEV4w==", "license": "MIT", "peer": true, @@ -2784,9 +2915,9 @@ } }, "node_modules/iconv-lite": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.0.tgz", - "integrity": "sha512-cf6L2Ds3h57VVmkZe+Pn+5APsT7FpqJtEhhieDCvrE2MK5Qk9MyffgQyuxQTm6BChfeZNtcOLHp9IcWRVcIcBQ==", + "version": "0.7.1", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.1.tgz", + "integrity": "sha512-2Tth85cXwGFHfvRgZWszZSvdo+0Xsqmw8k8ZwxScfcBneNUraK+dxRxRm24nszx80Y0TVio8kKLt5sLE7ZCLlw==", "license": "MIT", "dependencies": { "safer-buffer": ">= 2.1.2 < 3.0.0" @@ -2816,9 +2947,9 @@ "license": "ISC" }, "node_modules/ipaddr.js": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", - "integrity": "sha512-Ag3wB2o37wslZS19hZqorUnrnzSkpOVy+IiiDEiTqNubEYpYuHWIf6K4psgN2ZWKExS4xhVCrRVfb/wfW8fWJA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.3.0.tgz", + "integrity": "sha512-Zv/pA+ciVFbCSBBjGfaKUya/CcGmUHzTydLMaTwrUUEM2DIEO3iZvueGxmacvmN50fGpGVKeTXpb2LcYQxeVdg==", "license": "MIT", "engines": { "node": ">= 10" @@ -2903,9 +3034,9 @@ } }, "node_modules/istanbul-reports": { - "version": "3.1.7", - "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.1.7.tgz", - "integrity": "sha512-BewmUXImeuRk2YY0PVbxgKAysvhRPUQE0h5QRM++nVWyubKGV0l8qQ5op8+B2DOmwSe63Jivj0BjkPQVf8fP5g==", + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.2.0.tgz", + "integrity": "sha512-HGYWWS/ehqTV3xN10i23tkPkpH46MLCIMFNCaaKNavAXTF1RkqxawEPtnjnGZ6XKSInBKkiOA5BKS+aZiY3AvA==", "dev": true, "license": "BSD-3-Clause", "dependencies": { @@ -2941,7 +3072,7 @@ }, "node_modules/jose": { "version": "6.1.3", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/jose/-/jose-6.1.3.tgz", + "resolved": "https://registry.npmjs.org/jose/-/jose-6.1.3.tgz", "integrity": "sha512-0TpaTfihd4QMNwrz/ob2Bp7X04yuxJkjRGi4aKmOqwhov54i6u79oCv7T+C7lo70MKH6BesI3vscD1yb/yzKXQ==", "license": "MIT", "funding": { @@ -2956,9 +3087,9 @@ "license": "MIT" }, "node_modules/json-schema-ref-resolver": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-2.0.1.tgz", - "integrity": "sha512-HG0SIB9X4J8bwbxCbnd5FfPEbcXAJYTi1pBJeP/QPON+w8ovSME8iRG+ElHNxZNX2Qh6eYn1GdzJFS4cDFfx0Q==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/json-schema-ref-resolver/-/json-schema-ref-resolver-3.0.0.tgz", + "integrity": "sha512-hOrZIVL5jyYFjzk7+y7n5JDzGlU8rfWDuYyHwGa2WA8/pcmMHezp2xsVwxrebD/Q9t8Nc5DboieySDpCp4WG4A==", "funding": [ { "type": "github", @@ -2976,13 +3107,13 @@ }, "node_modules/json-schema-traverse": { "version": "1.0.0", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", "license": "MIT" }, "node_modules/json-schema-typed": { "version": "8.0.2", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/json-schema-typed/-/json-schema-typed-8.0.2.tgz", + "resolved": "https://registry.npmjs.org/json-schema-typed/-/json-schema-typed-8.0.2.tgz", "integrity": "sha512-fQhoXdcvc3V28x7C7BMs4P5+kNlgUURe2jmUT1T//oBRMDrqy1QPelJimwZGo7Hg9VPV3EQV5Bnq4hbFy2vetA==", "license": "BSD-2-Clause" }, @@ -3028,12 +3159,16 @@ } }, "node_modules/light-my-request/node_modules/cookie": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz", - "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==", + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.1.1.tgz", + "integrity": "sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==", "license": "MIT", "engines": { "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/light-my-request/node_modules/process-warning": { @@ -3053,15 +3188,15 @@ "license": "MIT" }, "node_modules/local-pkg": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.1.tgz", - "integrity": "sha512-WunYko2W1NcdfAFpuLUoucsgULmgDBRkdxHxWQ7mK0cQqwPiy8E1enjuRBrhLtZkB5iScJ1XIPdhVEFK8aOLSg==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/local-pkg/-/local-pkg-1.1.2.tgz", + "integrity": "sha512-arhlxbFRmoQHl33a0Zkle/YWlmNwoyt6QNZEIJcqNbdrsix5Lvc4HyyI3EnwxTYlZYc32EbYrQ8SzEZ7dqgg9A==", "dev": true, "license": "MIT", "dependencies": { "mlly": "^1.7.4", - "pkg-types": "^2.0.1", - "quansync": "^0.2.8" + "pkg-types": "^2.3.0", + "quansync": "^0.2.11" }, "engines": { "node": ">=14" @@ -3078,9 +3213,9 @@ "license": "MIT" }, "node_modules/loupe": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz", - "integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==", + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.1.tgz", + "integrity": "sha512-CdzqowRJCeLU72bHvWqwRBBlLcMEtIvGrlvef74kMnV2AolS9Y8xUv1I0U/MNAWMhBlKIoyuEgoJ0t/bbwHbLQ==", "dev": true, "license": "MIT" }, @@ -3092,13 +3227,13 @@ "license": "ISC" }, "node_modules/magic-string": { - "version": "0.30.17", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz", - "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==", + "version": "0.30.21", + "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.21.tgz", + "integrity": "sha512-vd2F4YUyEXKGcLHoq+TEyCjxueSeHnFxyyjNp80yg0XV4vUhnDer/lvvlqM/arB5bXQN5K2/3oinyCRyx8T2CQ==", "dev": true, "license": "MIT", "dependencies": { - "@jridgewell/sourcemap-codec": "^1.5.0" + "@jridgewell/sourcemap-codec": "^1.5.5" } }, "node_modules/magicast": { @@ -3169,15 +3304,19 @@ } }, "node_modules/mime-types": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.1.tgz", - "integrity": "sha512-xRc4oEhT6eaBpU1XF7AjpOFD+xQmXNB5OVKwp4tqCuBpHLS/ZbBDrc07mYTDqVMg6PfxUjjNp85O6Cd2Z/5HWA==", + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz", + "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==", "license": "MIT", "dependencies": { "mime-db": "^1.54.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/minimatch": { @@ -3207,16 +3346,16 @@ } }, "node_modules/mlly": { - "version": "1.7.4", - "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.7.4.tgz", - "integrity": "sha512-qmdSIPC4bDJXgZTCR7XosJiNKySV7O215tsPtDN9iEO/7q/76b/ijtgRu/+epFXSJhijtTCCGp3DWS549P3xKw==", + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/mlly/-/mlly-1.8.0.tgz", + "integrity": "sha512-l8D9ODSRWLe2KHJSifWGwBqpTZXIXTeo8mlKjY+E2HAakaTeNpqAyBZ8GSqLzHgw4XmHmC8whvpjJNMbFZN7/g==", "dev": true, "license": "MIT", "dependencies": { - "acorn": "^8.14.0", - "pathe": "^2.0.1", - "pkg-types": "^1.3.0", - "ufo": "^1.5.4" + "acorn": "^8.15.0", + "pathe": "^2.0.3", + "pkg-types": "^1.3.1", + "ufo": "^1.6.1" } }, "node_modules/mlly/node_modules/confbox": { @@ -3402,12 +3541,13 @@ } }, "node_modules/path-to-regexp": { - "version": "8.2.0", - "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.2.0.tgz", - "integrity": "sha512-TdrF7fW9Rphjq4RjrW0Kp2AW0Ahwu9sRGTkS6bvDi0SCwZlEZYmcfDbEsTz8RVk0EHIS/Vd1bv3JhG+1xZuAyQ==", + "version": "8.3.0", + "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz", + "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==", "license": "MIT", - "engines": { - "node": ">=16" + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/pathe": { @@ -3448,13 +3588,13 @@ } }, "node_modules/pino": { - "version": "9.9.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-9.9.0.tgz", - "integrity": "sha512-zxsRIQG9HzG+jEljmvmZupOMDUQ0Jpj0yAgE28jQvvrdYTlEaiGwelJpdndMl/MBuRr70heIj83QyqJUWaU8mQ==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-10.1.0.tgz", + "integrity": "sha512-0zZC2ygfdqvqK8zJIr1e+wT1T/L+LF6qvqvbzEQ6tiMAoTqEVK9a1K3YRu8HEUvGEvNqZyPJTtb2sNIoTkB83w==", "license": "MIT", "dependencies": { + "@pinojs/redact": "^0.4.0", "atomic-sleep": "^1.0.0", - "fast-redact": "^3.1.1", "on-exit-leak-free": "^2.1.0", "pino-abstract-transport": "^2.0.0", "pino-std-serializers": "^7.0.0", @@ -3485,18 +3625,18 @@ "license": "MIT" }, "node_modules/pkce-challenge": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.0.tgz", - "integrity": "sha512-ueGLflrrnvwB3xuo/uGob5pd5FN7l0MsLf0Z87o/UQmRtwjvfylfc9MurIxRAWywCYTgrvpXBcqjV4OfCYGCIQ==", + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/pkce-challenge/-/pkce-challenge-5.0.1.tgz", + "integrity": "sha512-wQ0b/W4Fr01qtpHlqSqspcj3EhBvimsdh0KlHhH8HRZnMsEa0ea2fTULOXOS9ccQr3om+GcGRk4e+isrZWV8qQ==", "license": "MIT", "engines": { "node": ">=16.20.0" } }, "node_modules/pkg-types": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.2.0.tgz", - "integrity": "sha512-2SM/GZGAEkPp3KWORxQZns4M+WSeXbC2HEvmOIJe3Cmiv6ieAJvdVhDldtHqM5J1Y7MrR1XhkBT/rMlhh9FdqQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pkg-types/-/pkg-types-2.3.0.tgz", + "integrity": "sha512-SIqCzDRg0s9npO5XQ3tNZioRY1uK06lA41ynBC1YmFTmnY6FjUjVt6s4LoADmwoig1qqD0oK8h1p/8mlMx8Oig==", "dev": true, "license": "MIT", "dependencies": { @@ -3584,7 +3724,7 @@ }, "node_modules/qs": { "version": "6.14.1", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/qs/-/qs-6.14.1.tgz", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.14.1.tgz", "integrity": "sha512-4EK3+xJl8Ts67nLYNwqw/dsFVnCf+qR7RgXSK9jEEm9unao3njwMDdmsdvoKBKHzxd7tCYz5e5M+SnMjdtXGQQ==", "license": "BSD-3-Clause", "dependencies": { @@ -3663,13 +3803,13 @@ } }, "node_modules/resolve": { - "version": "1.22.10", - "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.10.tgz", - "integrity": "sha512-NPRy+/ncIMeDlTAsuqwKIiferiawhefFJtkNSW0qZJEqMEb+qBt/77B/jGeeek+F0uOeN05CDa6HXbbIgtVX4w==", + "version": "1.22.11", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.11.tgz", + "integrity": "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ==", "dev": true, "license": "MIT", "dependencies": { - "is-core-module": "^2.16.0", + "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, @@ -3719,9 +3859,9 @@ "license": "MIT" }, "node_modules/rollup": { - "version": "4.46.2", - "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.46.2.tgz", - "integrity": "sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==", + "version": "4.55.1", + "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.55.1.tgz", + "integrity": "sha512-wDv/Ht1BNHB4upNbK74s9usvl7hObDnvVzknxqY/E/O3X6rW1U1rV1aENEfJ54eFZDTNo7zv1f5N4edCluH7+A==", "dev": true, "license": "MIT", "dependencies": { @@ -3735,26 +3875,31 @@ "npm": ">=8.0.0" }, "optionalDependencies": { - "@rollup/rollup-android-arm-eabi": "4.46.2", - "@rollup/rollup-android-arm64": "4.46.2", - "@rollup/rollup-darwin-arm64": "4.46.2", - "@rollup/rollup-darwin-x64": "4.46.2", - "@rollup/rollup-freebsd-arm64": "4.46.2", - "@rollup/rollup-freebsd-x64": "4.46.2", - "@rollup/rollup-linux-arm-gnueabihf": "4.46.2", - "@rollup/rollup-linux-arm-musleabihf": "4.46.2", - "@rollup/rollup-linux-arm64-gnu": "4.46.2", - "@rollup/rollup-linux-arm64-musl": "4.46.2", - "@rollup/rollup-linux-loongarch64-gnu": "4.46.2", - "@rollup/rollup-linux-ppc64-gnu": "4.46.2", - "@rollup/rollup-linux-riscv64-gnu": "4.46.2", - "@rollup/rollup-linux-riscv64-musl": "4.46.2", - "@rollup/rollup-linux-s390x-gnu": "4.46.2", - "@rollup/rollup-linux-x64-gnu": "4.46.2", - "@rollup/rollup-linux-x64-musl": "4.46.2", - "@rollup/rollup-win32-arm64-msvc": "4.46.2", - "@rollup/rollup-win32-ia32-msvc": "4.46.2", - "@rollup/rollup-win32-x64-msvc": "4.46.2", + "@rollup/rollup-android-arm-eabi": "4.55.1", + "@rollup/rollup-android-arm64": "4.55.1", + "@rollup/rollup-darwin-arm64": "4.55.1", + "@rollup/rollup-darwin-x64": "4.55.1", + "@rollup/rollup-freebsd-arm64": "4.55.1", + "@rollup/rollup-freebsd-x64": "4.55.1", + "@rollup/rollup-linux-arm-gnueabihf": "4.55.1", + "@rollup/rollup-linux-arm-musleabihf": "4.55.1", + "@rollup/rollup-linux-arm64-gnu": "4.55.1", + "@rollup/rollup-linux-arm64-musl": "4.55.1", + "@rollup/rollup-linux-loong64-gnu": "4.55.1", + "@rollup/rollup-linux-loong64-musl": "4.55.1", + "@rollup/rollup-linux-ppc64-gnu": "4.55.1", + "@rollup/rollup-linux-ppc64-musl": "4.55.1", + "@rollup/rollup-linux-riscv64-gnu": "4.55.1", + "@rollup/rollup-linux-riscv64-musl": "4.55.1", + "@rollup/rollup-linux-s390x-gnu": "4.55.1", + "@rollup/rollup-linux-x64-gnu": "4.55.1", + "@rollup/rollup-linux-x64-musl": "4.55.1", + "@rollup/rollup-openbsd-x64": "4.55.1", + "@rollup/rollup-openharmony-arm64": "4.55.1", + "@rollup/rollup-win32-arm64-msvc": "4.55.1", + "@rollup/rollup-win32-ia32-msvc": "4.55.1", + "@rollup/rollup-win32-x64-gnu": "4.55.1", + "@rollup/rollup-win32-x64-msvc": "4.55.1", "fsevents": "~2.3.2" } }, @@ -3774,26 +3919,6 @@ "node": ">= 18" } }, - "node_modules/safe-buffer": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", - "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", - "funding": [ - { - "type": "github", - "url": "https://github.com/sponsors/feross" - }, - { - "type": "patreon", - "url": "https://www.patreon.com/feross" - }, - { - "type": "consulting", - "url": "https://feross.org/support" - } - ], - "license": "MIT" - }, "node_modules/safe-regex2": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/safe-regex2/-/safe-regex2-5.0.0.tgz", @@ -3829,9 +3954,9 @@ "license": "MIT" }, "node_modules/secure-json-parse": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.0.0.tgz", - "integrity": "sha512-dxtLJO6sc35jWidmLxo7ij+Eg48PM/kleBsxpC8QJE0qJICe+KawkDQmvCMZUr9u7WKVHgMW6vy3fQ7zMiFZMA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/secure-json-parse/-/secure-json-parse-4.1.0.tgz", + "integrity": "sha512-l4KnYfEyqYJxDwlNVyRfO2E4NTHfMKAWdUuA8J0yve2Dz/E/PdBepY03RvyJpssIpRFwJoCD55wA+mEDs6ByWA==", "funding": [ { "type": "github", @@ -3845,9 +3970,9 @@ "license": "BSD-3-Clause" }, "node_modules/semver": { - "version": "7.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.2.tgz", - "integrity": "sha512-RF0Fw+rO5AMf9MAyaRXI4AV0Ulj5lMHqVxxdSgiVbixSCXoEmmX/jk0CuJw4+3SqroYO9VoUh+HcuJivvtJemA==", + "version": "7.7.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.3.tgz", + "integrity": "sha512-SdsKMrI9TdgjdweUSR9MweHA4EJ8YxHn8DFaDisvhVlUOe4BF1tLD7GAj0lIqWVl+dPb/rExr0Btby5loQm20Q==", "license": "ISC", "bin": { "semver": "bin/semver.js" @@ -3857,31 +3982,35 @@ } }, "node_modules/send": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/send/-/send-1.2.0.tgz", - "integrity": "sha512-uaW0WwXKpL9blXE2o0bRhoL2EGXIrZxQ2ZQ4mgcfoBxdFmQold+qWsD2jLrfZ0trjKL6vOw0j//eAwcALFjKSw==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz", + "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==", "license": "MIT", "dependencies": { - "debug": "^4.3.5", + "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.0", - "mime-types": "^3.0.1", + "http-errors": "^2.0.1", + "mime-types": "^3.0.2", "ms": "^2.1.3", "on-finished": "^2.4.1", "range-parser": "^1.2.1", - "statuses": "^2.0.1" + "statuses": "^2.0.2" }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/serve-static": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.0.tgz", - "integrity": "sha512-61g9pCh0Vnh7IutZjtLGGpTA355+OPn2TyDv/6ivP2h/AdAVX9azsoxmg2/M6nZeQZNYBEwIcsne1mJd9oQItQ==", + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz", + "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==", "license": "MIT", "dependencies": { "encodeurl": "^2.0.0", @@ -3891,12 +4020,16 @@ }, "engines": { "node": ">= 18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/express" } }, "node_modules/set-cookie-parser": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz", - "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==", + "version": "2.7.2", + "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.2.tgz", + "integrity": "sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==", "license": "MIT" }, "node_modules/setprototypeof": { @@ -4080,9 +4213,9 @@ } }, "node_modules/std-env": { - "version": "3.9.0", - "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz", - "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==", + "version": "3.10.0", + "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.10.0.tgz", + "integrity": "sha512-5GS12FdOZNliM5mAOxFRg7Ir0pWz8MdpYm6AY6VPkGpbA7ZzmbzNcBJQ0GPvvyWgcY7QAhCgf9Uy89I03faLkg==", "dev": true, "license": "MIT" }, @@ -4161,9 +4294,9 @@ } }, "node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", + "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", "dev": true, "license": "MIT", "dependencies": { @@ -4214,9 +4347,9 @@ } }, "node_modules/strip-literal": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz", - "integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.1.0.tgz", + "integrity": "sha512-8r3mkIM/2+PpjHoOtiAW8Rg3jJLHaV7xPwG+YRGrv6FP0wwk/toTpATxWYOW0BKdWwl82VT2tFYi5DlROa0Mxg==", "dev": true, "license": "MIT", "dependencies": { @@ -4328,9 +4461,9 @@ } }, "node_modules/tinyspy": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz", - "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.4.tgz", + "integrity": "sha512-azl+t0z7pw/z958Gy9svOTuzqIk6xq+NSheJzn5MMWtWTFywIacg2wUlzKFGtt3cthx0r2SxMK0yzJOR0IES7Q==", "dev": true, "license": "MIT", "engines": { @@ -4356,13 +4489,13 @@ } }, "node_modules/tsx": { - "version": "4.20.4", - "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.20.4.tgz", - "integrity": "sha512-yyxBKfORQ7LuRt/BQKBXrpcq59ZvSW0XxwfjAt3w2/8PmdxaFzijtMhTawprSHhpzeM5BgU2hXHG3lklIERZXg==", + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "~0.25.0", + "esbuild": "~0.27.0", "get-tsconfig": "^4.7.5" }, "bin": { @@ -4390,9 +4523,9 @@ } }, "node_modules/typescript": { - "version": "5.9.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.2.tgz", - "integrity": "sha512-CWBzXQrc/qOkhidw1OzBTQuYRbfyxDXJMVJ1XNwUHGROVmuaeiEm3OslpZ1RV96d7SKKjZKrSJu3+t/xlw3R9A==", + "version": "5.9.3", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.9.3.tgz", + "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", "bin": { @@ -4404,9 +4537,9 @@ } }, "node_modules/ufo": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.1.tgz", - "integrity": "sha512-9a4/uxlTWJ4+a5i0ooc1rU7C7YOw3wT+UGqdeNNHWnOF9qcMBgLRS+4IYUqbczewFx4mLEig6gawh7X6mFlEkA==", + "version": "1.6.2", + "resolved": "https://registry.npmjs.org/ufo/-/ufo-1.6.2.tgz", + "integrity": "sha512-heMioaxBcG9+Znsda5Q8sQbWnLJSl98AFDXTO80wELWEzX3hordXsTdxrIfMQoO9IY1MEnoGoPjpoKpMj+Yx0Q==", "dev": true, "license": "MIT" }, @@ -4456,13 +4589,13 @@ } }, "node_modules/vite": { - "version": "7.2.4", - "resolved": "https://registry.npmjs.org/vite/-/vite-7.2.4.tgz", - "integrity": "sha512-NL8jTlbo0Tn4dUEXEsUg8KeyG/Lkmc4Fnzb8JXN/Ykm9G4HNImjtABMJgkQoVjOBN/j2WAwDTRytdqJbZsah7w==", + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/vite/-/vite-7.3.1.tgz", + "integrity": "sha512-w+N7Hifpc3gRjZ63vYBXA56dvvRlNWRczTdmCBBa+CotUzAPf5b7YMdMR/8CQoeYE5LX3W4wj6RYTgonm1b9DA==", "dev": true, "license": "MIT", "dependencies": { - "esbuild": "^0.25.0", + "esbuild": "^0.27.0", "fdir": "^6.5.0", "picomatch": "^4.0.3", "postcss": "^8.5.6", @@ -4814,7 +4947,7 @@ }, "node_modules/zod-to-json-schema": { "version": "3.25.1", - "resolved": "https://placer.jfrog.io/artifactory/api/npm/virtual-npm/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", + "resolved": "https://registry.npmjs.org/zod-to-json-schema/-/zod-to-json-schema-3.25.1.tgz", "integrity": "sha512-pM/SU9d3YAggzi6MtR4h7ruuQlqKtad8e9S0fmxcMi+ueAK5Korys/aWcV9LIIHTVbj01NdzxcnXSN+O74ZIVA==", "license": "ISC", "peerDependencies": { From 79db734a7c0933ead69a1a60a860b7bc2ac98263 Mon Sep 17 00:00:00 2001 From: Ben Rabinovich Date: Thu, 8 Jan 2026 15:18:01 +0200 Subject: [PATCH 4/4] chore: update version --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 08f10b9..af7c7f5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "toolception", - "version": "0.4.0", + "version": "0.5.0", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "toolception", - "version": "0.4.0", + "version": "0.5.0", "license": "Apache-2.0", "dependencies": { "@fastify/cors": "^10.0.1", diff --git a/package.json b/package.json index 6746c7f..9ca92d4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "toolception", - "version": "0.4.0", + "version": "0.5.0", "private": false, "type": "module", "main": "dist/index.js",