@vritti/api-sdk 0.4.7 → 0.4.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/auth.cjs +70 -4
- package/dist/auth.cjs.map +1 -1
- package/dist/auth.d.cts +16 -1
- package/dist/auth.d.ts +16 -1
- package/dist/auth.js +70 -4
- package/dist/auth.js.map +1 -1
- package/dist/bad-request.exception-D-KmhiXQ.d.cts +18 -0
- package/dist/bad-request.exception-Db94kZxY.d.ts +18 -0
- package/dist/data-table.cjs +3 -4
- package/dist/data-table.cjs.map +1 -1
- package/dist/data-table.js +3 -4
- package/dist/data-table.js.map +1 -1
- package/dist/database.cjs +11 -2
- package/dist/database.cjs.map +1 -1
- package/dist/database.d.cts +1 -0
- package/dist/database.d.ts +1 -0
- package/dist/database.js +26 -17
- package/dist/database.js.map +1 -1
- package/dist/decimal.d.cts +1 -0
- package/dist/decimal.d.ts +1 -0
- package/dist/exceptions.d.cts +4 -17
- package/dist/exceptions.d.ts +4 -17
- package/dist/index.d.cts +16 -2
- package/dist/index.d.ts +16 -2
- package/dist/mcp.cjs +814 -0
- package/dist/mcp.cjs.map +1 -0
- package/dist/mcp.d.cts +135 -0
- package/dist/mcp.d.ts +135 -0
- package/dist/mcp.js +771 -0
- package/dist/mcp.js.map +1 -0
- package/dist/root.cjs +1 -0
- package/dist/root.cjs.map +1 -1
- package/dist/root.js +1 -0
- package/dist/root.js.map +1 -1
- package/dist/zod.cjs +25 -0
- package/dist/zod.cjs.map +1 -0
- package/dist/zod.d.cts +1 -0
- package/dist/zod.d.ts +1 -0
- package/dist/zod.js +3 -0
- package/dist/zod.js.map +1 -0
- package/package.json +24 -2
package/dist/mcp.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/mcp/coverage.ts","../src/mcp/mcp.module.ts","../src/mcp/mcp.options.ts","../src/exceptions/bad-gateway.exception.ts","../src/exceptions/base-field.exception.ts","../src/exceptions/bad-request.exception.ts","../src/exceptions/conflict.exception.ts","../src/exceptions/forbidden.exception.ts","../src/exceptions/gone.exception.ts","../src/exceptions/internal-server-error.exception.ts","../src/exceptions/method-not-allowed.exception.ts","../src/exceptions/not-acceptable.exception.ts","../src/exceptions/not-found.exception.ts","../src/exceptions/not-implemented.exception.ts","../src/exceptions/payload-too-large.exception.ts","../src/exceptions/request-timeout.exception.ts","../src/exceptions/service-unavailable.exception.ts","../src/exceptions/too-many-requests.exception.ts","../src/exceptions/unauthorized.exception.ts","../src/exceptions/unprocessable-entity.exception.ts","../src/exceptions/unsupported-media-type.exception.ts","../src/exceptions/validation.exception.ts","../src/mcp/mcp-principal.ts","../src/mcp/mcp-request.handler.ts","../src/mcp/mcp-server.factory.ts","../src/mcp/tool-registry.ts","../src/mcp/tool-definition.ts","../src/mcp/tool-result.ts","../src/mcp/mcp-transport.factory.ts","../src/mcp/mcp-schema-registry.ts","../src/mcp/validate-dto.ts"],"sourcesContent":["import type { Type } from '@nestjs/common';\nimport { METHOD_METADATA, MODULE_METADATA } from '@nestjs/common/constants';\n\n// The operation ids Swagger derives for every route-decorated method of the given modules' controllers\n// (`${ControllerName}_${method}`). A server's coverage test compares this with what its tools cover and exclude.\nexport function collectOperationIds(modules: Type[]): string[] {\n const ids: string[] = [];\n for (const module of modules) {\n const controllers: Type[] = Reflect.getMetadata(MODULE_METADATA.CONTROLLERS, module) ?? [];\n for (const controller of controllers) {\n const prototype = controller.prototype as Record<string, unknown>;\n for (const method of Object.getOwnPropertyNames(prototype)) {\n if (method === 'constructor') continue;\n const handler = prototype[method];\n if (typeof handler !== 'function') continue;\n if (Reflect.getMetadata(METHOD_METADATA, handler) === undefined) continue;\n ids.push(`${controller.name}_${method}`);\n }\n }\n }\n return ids;\n}\n","import { type DynamicModule, Module } from '@nestjs/common';\nimport { DiscoveryModule } from '@nestjs/core';\nimport { MCP_SERVER_OPTIONS, type McpModuleOptions, type McpServerOptions } from './mcp.options';\nimport { MCP_PRINCIPAL_FACTORY, principalFromOAuth } from './mcp-principal';\nimport { McpRequestHandler } from './mcp-request.handler';\nimport { McpSchemaRegistry } from './mcp-schema-registry';\nimport { McpServerFactory } from './mcp-server.factory';\nimport { McpTransportFactory } from './mcp-transport.factory';\nimport { ToolRegistry } from './tool-registry';\n\n// The MCP plumbing a server shares: transport, protocol server, request handler, schema registry and tool registry.\n// The server keeps what is its own — the controller carrying the route and its @Require(), the @McpTools() providers,\n// and whatever resource tables or workflows those tools compose.\n@Module({})\nexport class McpModule {\n static forRoot(options: McpModuleOptions): DynamicModule {\n const serverOptions: McpServerOptions = {\n name: options.name,\n version: options.version,\n instructions: options.instructions,\n };\n return {\n module: McpModule,\n imports: [DiscoveryModule],\n providers: [\n { provide: MCP_SERVER_OPTIONS, useValue: serverOptions },\n { provide: MCP_PRINCIPAL_FACTORY, useValue: options.principal ?? principalFromOAuth },\n McpTransportFactory,\n McpServerFactory,\n McpRequestHandler,\n McpSchemaRegistry,\n ToolRegistry,\n ],\n exports: [McpRequestHandler, McpSchemaRegistry, ToolRegistry],\n };\n }\n}\n","import type { McpPrincipalFactory } from './mcp-principal';\n\nexport const MCP_SERVER_OPTIONS = Symbol('MCP_SERVER_OPTIONS');\n\nexport interface McpServerOptions {\n name: string;\n version: string;\n instructions?: string;\n}\n\nexport interface McpModuleOptions extends McpServerOptions {\n // How a request becomes a principal; defaults to the OAuth bearer the auth guard resolved\n principal?: McpPrincipalFactory;\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class BadGatewayException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Bad Gateway', HttpStatus.BAD_GATEWAY);\n }\n}\n","import { HttpException, HttpStatus } from '@nestjs/common';\nimport type { FieldError } from '../types/error-response.types';\n\n// Re-export FieldError for backwards compatibility\nexport type { FieldError } from '../types/error-response.types';\n\nexport interface ProblemOptions {\n type?: string;\n label?: string;\n detail?: string;\n errors?: FieldError[];\n}\n\nexport abstract class HttpProblemException extends HttpException {\n constructor(detailOrOptions: string | ProblemOptions, httpStatus: HttpStatus) {\n const options = typeof detailOrOptions === 'string' ? { detail: detailOrOptions } : detailOrOptions;\n\n super(\n {\n type: options.type ?? 'about:blank',\n label: options.label,\n detail: options.detail,\n errors: options.errors ?? [],\n },\n httpStatus,\n );\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class BadRequestException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Bad Request', HttpStatus.BAD_REQUEST);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ConflictException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Conflict', HttpStatus.CONFLICT);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ForbiddenException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Forbidden', HttpStatus.FORBIDDEN);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class GoneException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Gone', HttpStatus.GONE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class InternalServerErrorException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Internal Server Error', HttpStatus.INTERNAL_SERVER_ERROR);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class MethodNotAllowedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Method Not Allowed', HttpStatus.METHOD_NOT_ALLOWED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotAcceptableException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Acceptable', HttpStatus.NOT_ACCEPTABLE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotFoundException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Found', HttpStatus.NOT_FOUND);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class NotImplementedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Not Implemented', HttpStatus.NOT_IMPLEMENTED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class PayloadTooLargeException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Payload Too Large', HttpStatus.PAYLOAD_TOO_LARGE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class RequestTimeoutException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Request Timeout', HttpStatus.REQUEST_TIMEOUT);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ServiceUnavailableException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Service Unavailable', HttpStatus.SERVICE_UNAVAILABLE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class TooManyRequestsException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Too Many Requests', HttpStatus.TOO_MANY_REQUESTS);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnauthorizedException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unauthorized', HttpStatus.UNAUTHORIZED);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnprocessableEntityException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unprocessable Entity', HttpStatus.UNPROCESSABLE_ENTITY);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class UnsupportedMediaTypeException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Unsupported Media Type', HttpStatus.UNSUPPORTED_MEDIA_TYPE);\n }\n}\n","import { HttpStatus } from '@nestjs/common';\nimport { HttpProblemException, type ProblemOptions } from './base-field.exception';\n\nexport class ValidationException extends HttpProblemException {\n constructor(detailOrOptions?: string | ProblemOptions) {\n super(detailOrOptions ?? 'Validation Failed', HttpStatus.UNPROCESSABLE_ENTITY);\n }\n}\n","import type { FastifyRequest } from 'fastify';\nimport { UnauthorizedException } from '../exceptions';\nimport '../types/fastify-augmentation';\n\n// Who a tool call acts as, whatever authenticated the request. Scopes are the server's own vocabulary; the registry\n// only compares them with each tool's requiredScope.\nexport class McpPrincipal {\n constructor(\n readonly userId: string,\n readonly scopes: readonly string[],\n readonly clientId?: string,\n readonly grantId?: string,\n readonly organizationId?: string,\n ) {}\n\n hasScope(scope: string): boolean {\n return this.scopes.includes(scope);\n }\n}\n\nexport type McpPrincipalFactory = (request: FastifyRequest) => McpPrincipal;\n\nexport const MCP_PRINCIPAL_FACTORY = Symbol('MCP_PRINCIPAL_FACTORY');\n\n// The default: an OAuth bearer the auth guard resolved. Fails loudly when the guard did not run — a missing principal\n// must never mean \"no restrictions\". Servers that authenticate MCP calls another way supply their own factory.\nexport function principalFromOAuth(request: FastifyRequest): McpPrincipal {\n const auth = request.auth;\n if (!auth || auth.kind !== 'oauth' || !auth.userId || !auth.grantId) {\n throw new UnauthorizedException('MCP request is not authenticated.');\n }\n return new McpPrincipal(auth.userId, auth.scopes ?? [], auth.clientId, auth.grantId, auth.organizationId);\n}\n","import { Inject, Injectable } from '@nestjs/common';\nimport type { FastifyReply, FastifyRequest } from 'fastify';\nimport { MCP_PRINCIPAL_FACTORY, type McpPrincipalFactory } from './mcp-principal';\nimport { McpServerFactory } from './mcp-server.factory';\nimport { McpTransportFactory } from './mcp-transport.factory';\n\n// Runs one JSON-RPC exchange. The reply is hijacked so the MCP transport writes the raw response itself, and the\n// already-parsed body is handed over because Fastify has consumed the request stream by the time a handler runs.\n@Injectable()\nexport class McpRequestHandler {\n constructor(\n private readonly serverFactory: McpServerFactory,\n private readonly transportFactory: McpTransportFactory,\n @Inject(MCP_PRINCIPAL_FACTORY) private readonly principalFactory: McpPrincipalFactory,\n ) {}\n\n async handle(request: FastifyRequest, reply: FastifyReply, body: unknown): Promise<void> {\n const principal = this.principalFactory(request);\n reply.hijack();\n\n const transport = this.transportFactory.create();\n const server = this.serverFactory.create(principal);\n reply.raw.on('close', () => {\n void transport.close();\n void server.close();\n });\n\n await server.connect(transport);\n await transport.handleRequest(request.raw, reply.raw, body);\n }\n\n // The JSON-RPC answer for verbs a stateless server does not serve (GET streams, DELETE session teardown)\n methodNotAllowed(reply: FastifyReply): void {\n reply\n .status(405)\n .header('Allow', 'POST')\n .send({ jsonrpc: '2.0', error: { code: -32000, message: 'Method not allowed.' }, id: null });\n }\n}\n","import { Server } from '@modelcontextprotocol/sdk/server/index.js';\nimport { CallToolRequestSchema, ListToolsRequestSchema } from '@modelcontextprotocol/sdk/types.js';\nimport { Inject, Injectable } from '@nestjs/common';\nimport { MCP_SERVER_OPTIONS, type McpServerOptions } from './mcp.options';\nimport type { McpPrincipal } from './mcp-principal';\nimport { ToolRegistry } from './tool-registry';\n\n// Builds the protocol server for one request, binding the two tool handlers to the caller's principal\n@Injectable()\nexport class McpServerFactory {\n constructor(\n @Inject(MCP_SERVER_OPTIONS) private readonly options: McpServerOptions,\n private readonly toolRegistry: ToolRegistry,\n ) {}\n\n create(principal: McpPrincipal): Server {\n const server = new Server(\n { name: this.options.name, version: this.options.version },\n { capabilities: { tools: {} }, instructions: this.options.instructions },\n );\n server.setRequestHandler(ListToolsRequestSchema, async () => ({ tools: this.toolRegistry.listTools() }));\n server.setRequestHandler(CallToolRequestSchema, async (request) =>\n this.toolRegistry.execute(request.params.name, request.params.arguments, principal),\n );\n return server;\n }\n}\n","import type { CallToolResult, Tool } from '@modelcontextprotocol/sdk/types.js';\nimport { Injectable, Logger, type OnApplicationBootstrap, type Type } from '@nestjs/common';\nimport { DiscoveryService, Reflector } from '@nestjs/core';\nimport { z } from 'zod';\nimport type { McpPrincipal } from './mcp-principal';\nimport { MCP_TOOL_PROVIDER_KEY, type McpToolProvider, type ToolDefinition } from './tool-definition';\nimport { problemFromError, toolError, toolOk } from './tool-result';\n\nconst TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,64}$/;\n\n// Owns every tool the server exposes: collects @McpTools() providers at bootstrap, builds the tools/list catalog once,\n// then runs each call through the same scope check, argument validation, error mapping and audit line so individual\n// tools only implement their handler.\n@Injectable()\nexport class ToolRegistry implements OnApplicationBootstrap {\n private readonly logger = new Logger(ToolRegistry.name);\n private readonly definitions = new Map<string, ToolDefinition>();\n private catalog: Tool[] = [];\n\n constructor(\n private readonly discovery: DiscoveryService,\n private readonly reflector: Reflector,\n ) {}\n\n // After every module has initialised, so providers from any module are instantiated and discoverable\n onApplicationBootstrap(): void {\n for (const provider of this.findProviders()) {\n for (const definition of provider.tools()) this.register(definition);\n }\n this.catalog = [...this.definitions.values()].map((definition) => this.toCatalogEntry(definition));\n this.logger.log(`Registered ${this.catalog.length} MCP tools`);\n }\n\n listTools(): Tool[] {\n return this.catalog;\n }\n\n // Every REST operation the tools stand in for — a coverage test compares this with the live route set\n coveredOperationIds(): string[] {\n return [...this.definitions.values()].flatMap((definition) => [...definition.covers]);\n }\n\n async execute(name: string, rawArgs: unknown, principal: McpPrincipal): Promise<CallToolResult> {\n const started = Date.now();\n const definition = this.definitions.get(name);\n if (!definition) {\n return toolError({ status: 404, label: 'Unknown Tool', detail: `No tool named \"${name}\".`, errors: [] });\n }\n\n let status = 200;\n let result: CallToolResult;\n if (!principal.hasScope(definition.requiredScope)) {\n status = 403;\n result = toolError({\n status,\n label: 'Insufficient Scope',\n detail: `Tool \"${name}\" requires the ${definition.requiredScope} scope. Reconnect the client and grant it.`,\n errors: [],\n });\n } else {\n try {\n const args = definition.inputSchema.parse(rawArgs ?? {});\n result = toolOk(await definition.handler(principal, args));\n } catch (error) {\n const problem = problemFromError(error);\n status = problem.status;\n result = toolError(problem);\n }\n }\n\n this.logger.log(\n `mcp tool=${name} user=${principal.userId} grant=${principal.grantId ?? '-'} client=${principal.clientId ?? '-'} scope=${definition.requiredScope} ok=${status < 400} status=${status} ms=${Date.now() - started}`,\n );\n return result;\n }\n\n private findProviders(): McpToolProvider[] {\n return this.discovery\n .getProviders()\n .filter((wrapper) => typeof wrapper.metatype === 'function' && wrapper.instance)\n .filter(\n (wrapper) => this.reflector.get<boolean>(MCP_TOOL_PROVIDER_KEY, wrapper.metatype as Type<unknown>) === true,\n )\n .map((wrapper) => wrapper.instance as McpToolProvider);\n }\n\n private register(definition: ToolDefinition): void {\n if (!TOOL_NAME_PATTERN.test(definition.name)) {\n throw new Error(`MCP tool name \"${definition.name}\" is invalid (letters, digits, _ and -, max 64 chars).`);\n }\n if (this.definitions.has(definition.name)) {\n throw new Error(`MCP tool \"${definition.name}\" is registered twice.`);\n }\n this.definitions.set(definition.name, definition);\n }\n\n private toCatalogEntry(definition: ToolDefinition): Tool {\n return {\n name: definition.name,\n title: definition.title,\n description: definition.description,\n inputSchema: this.toInputSchema(definition),\n annotations: {\n title: definition.title,\n readOnlyHint: definition.annotations.readOnlyHint,\n destructiveHint: definition.annotations.destructiveHint,\n idempotentHint: definition.annotations.idempotentHint,\n openWorldHint: false,\n },\n };\n }\n\n // MCP wants a bare JSON Schema object at the root; zod adds a $schema marker the catalog does not need\n private toInputSchema(definition: ToolDefinition): Tool['inputSchema'] {\n const schema = z.toJSONSchema(definition.inputSchema, { io: 'input' }) as Record<string, unknown>;\n delete schema.$schema;\n if (schema.type !== 'object') {\n throw new Error(`MCP tool \"${definition.name}\" must declare an object input schema.`);\n }\n return schema as Tool['inputSchema'];\n }\n}\n","import { SetMetadata } from '@nestjs/common';\nimport type { ZodType } from 'zod';\nimport type { McpPrincipal } from './mcp-principal';\n\nexport interface McpToolAnnotations {\n readOnlyHint: boolean;\n destructiveHint: boolean;\n idempotentHint: boolean;\n}\n\nexport interface ToolDefinition<Args = unknown> {\n name: string;\n title: string;\n description: string;\n inputSchema: ZodType<Args>;\n annotations: McpToolAnnotations;\n requiredScope: string;\n covers: readonly string[];\n handler: (principal: McpPrincipal, args: Args) => Promise<unknown>;\n}\n\nexport interface McpToolProvider {\n tools(): ToolDefinition[];\n}\n\nexport const MCP_TOOL_PROVIDER_KEY = 'mcp:tool-provider';\n\n// Marks an injectable class whose tools() the registry collects at bootstrap. Register the class as an ordinary\n// provider in any module — discovery finds it wherever it lives, so a server's tools stay in the server's own module.\nexport const McpTools = (): ClassDecorator => SetMetadata(MCP_TOOL_PROVIDER_KEY, true);\n\n// Keeps the parsed argument type flowing into the handler while the registry stores every definition in one list\nexport function defineTool<Args>(definition: ToolDefinition<Args>): ToolDefinition {\n return definition as unknown as ToolDefinition;\n}\n","import type { CallToolResult } from '@modelcontextprotocol/sdk/types.js';\nimport { Logger } from '@nestjs/common';\nimport { ZodError } from 'zod';\n\nexport interface ToolFieldError {\n field?: string;\n message: string;\n}\n\nexport interface ToolProblem {\n status: number;\n label?: string;\n detail: string;\n errors: ToolFieldError[];\n}\n\ninterface HttpExceptionLike {\n getStatus(): number;\n getResponse(): unknown;\n}\n\nconst PG_UNIQUE_VIOLATION = '23505';\nconst logger = new Logger('McpTool');\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\n// Duck-typed like the exception filter: pnpm may load more than one @nestjs/common, so instanceof is not reliable\nfunction isHttpExceptionLike(value: unknown): value is HttpExceptionLike {\n return isRecord(value) && typeof value.getStatus === 'function' && typeof value.getResponse === 'function';\n}\n\n// Walks the cause chain for a Postgres unique violation the way the exception filter does\nfunction findPgUniqueViolation(error: unknown, depth = 0): { detail?: string } | undefined {\n if (!isRecord(error) || depth > 5) return undefined;\n if (error.code === PG_UNIQUE_VIOLATION)\n return { detail: typeof error.detail === 'string' ? error.detail : undefined };\n return findPgUniqueViolation(error.cause, depth + 1);\n}\n\nfunction normalizeFieldErrors(value: unknown): ToolFieldError[] {\n if (!Array.isArray(value)) return [];\n return value.filter(isRecord).map((entry) => ({\n field: typeof entry.field === 'string' ? entry.field : undefined,\n message: typeof entry.message === 'string' ? entry.message : 'Invalid value',\n }));\n}\n\nexport function toolOk(payload: unknown): CallToolResult {\n const structuredContent = isRecord(payload) ? payload : { result: payload };\n return { content: [{ type: 'text', text: JSON.stringify(payload) }], structuredContent };\n}\n\nexport function toolError(problem: ToolProblem): CallToolResult {\n return {\n isError: true,\n content: [{ type: 'text', text: JSON.stringify(problem) }],\n structuredContent: { ...problem },\n };\n}\n\n// Turns whatever a handler threw into the problem shape the REST API speaks, so field errors reach the model verbatim\nexport function problemFromError(error: unknown): ToolProblem {\n if (error instanceof ZodError) {\n return {\n status: 400,\n label: 'Invalid Arguments',\n detail: 'The tool arguments did not match the schema.',\n errors: error.issues.map((issue) => ({ field: issue.path.join('.'), message: issue.message })),\n };\n }\n\n if (isHttpExceptionLike(error)) {\n const status = error.getStatus();\n const body = error.getResponse();\n if (isRecord(body)) {\n const detail =\n typeof body.detail === 'string'\n ? body.detail\n : typeof body.message === 'string'\n ? body.message\n : 'Request failed.';\n return {\n status,\n label: typeof body.label === 'string' ? body.label : undefined,\n detail,\n errors: normalizeFieldErrors(body.errors),\n };\n }\n return { status, detail: typeof body === 'string' ? body : 'Request failed.', errors: [] };\n }\n\n const duplicate = findPgUniqueViolation(error);\n if (duplicate) {\n return {\n status: 409,\n label: 'Duplicate Entry',\n detail: duplicate.detail ?? 'A record with these values already exists.',\n errors: [],\n };\n }\n\n logger.error(`Unhandled tool error: ${error instanceof Error ? error.stack : String(error)}`);\n return { status: 500, detail: 'An unexpected error occurred.', errors: [] };\n}\n","import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';\nimport { Injectable } from '@nestjs/common';\n\n// One transport per request. Stateless: no session id is issued, so any node can serve any call and nothing is kept\n// between calls. JSON responses rather than an SSE stream, since a tools-only server never pushes notifications.\n@Injectable()\nexport class McpTransportFactory {\n create(): StreamableHTTPServerTransport {\n return new StreamableHTTPServerTransport({ sessionIdGenerator: undefined, enableJsonResponse: true });\n }\n}\n","import { Injectable } from '@nestjs/common';\nimport type { OpenAPIObject } from '@nestjs/swagger';\n\ntype JsonSchema = Record<string, unknown>;\n\nconst COMPONENT_REF = '#/components/schemas/';\n\n// Serves the request DTO schemas the REST API already documents (descriptions, examples, enums) to tools that\n// describe resources. The server hands over its live Swagger document at boot, so schemas cannot drift from the DTOs.\n@Injectable()\nexport class McpSchemaRegistry {\n private schemas: Record<string, JsonSchema> = {};\n\n setDocument(document: OpenAPIObject): void {\n this.schemas = (document.components?.schemas ?? {}) as Record<string, JsonSchema>;\n }\n\n // The schema for a DTO class, with its component references inlined as local $defs\n schemaFor(dto: { name: string }): JsonSchema {\n const root = this.schemas[dto.name];\n if (!root) return { type: 'object', description: `The schema for ${dto.name} is unavailable.` };\n const defs: Record<string, JsonSchema> = {};\n const rewritten = this.rewrite(root, defs);\n return Object.keys(defs).length > 0 ? { ...rewritten, $defs: defs } : rewritten;\n }\n\n private rewrite(node: unknown, defs: Record<string, JsonSchema>): JsonSchema {\n if (Array.isArray(node)) return node.map((item) => this.rewrite(item, defs)) as unknown as JsonSchema;\n if (typeof node !== 'object' || node === null) return node as JsonSchema;\n\n const record = node as JsonSchema;\n if (typeof record.$ref === 'string' && record.$ref.startsWith(COMPONENT_REF)) {\n const name = record.$ref.slice(COMPONENT_REF.length);\n if (!(name in defs)) {\n // Placeholder first, so a self-referencing schema terminates\n defs[name] = {};\n defs[name] = this.rewrite(this.schemas[name] ?? {}, defs);\n }\n return { $ref: `#/$defs/${name}` };\n }\n\n const out: JsonSchema = {};\n for (const [key, value] of Object.entries(record)) out[key] = this.rewrite(value, defs);\n return out;\n }\n}\n","import { type ClassConstructor, plainToInstance } from 'class-transformer';\nimport { type ValidationError, validate } from 'class-validator';\nimport { BadRequestException } from '../exceptions';\n\ninterface FieldError {\n field: string;\n message: string;\n}\n\nexport class McpValidationError extends BadRequestException {\n constructor(errors: FieldError[]) {\n super({ label: 'Validation Failed', detail: 'Please check your input and try again.', errors });\n }\n}\n\n// Nested paths (\"entries.0.amount\") where the global pipe only reports the top-level property — an agent needs the path\nfunction flattenValidationErrors(errors: ValidationError[], parent = ''): FieldError[] {\n return errors.flatMap((error) => {\n const field = parent ? `${parent}.${error.property}` : error.property;\n const own = Object.values(error.constraints ?? {}).map((message) => ({ field, message }));\n const nested = error.children?.length ? flattenValidationErrors(error.children, field) : [];\n return [...own, ...nested];\n });\n}\n\n// Validates tool input against the same class-validator DTO the REST endpoint uses, with the global pipe's options\nexport async function validateDto<T extends object>(cls: ClassConstructor<T>, input: unknown): Promise<T> {\n const instance = plainToInstance(cls, input ?? {}, { enableImplicitConversion: true });\n const errors = await validate(instance, { whitelist: true, forbidNonWhitelisted: true });\n if (errors.length > 0) throw new McpValidationError(flattenValidationErrors(errors));\n return instance;\n}\n"],"mappings":"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","names":["METHOD_METADATA","MODULE_METADATA","collectOperationIds","modules","ids","module","controllers","Reflect","getMetadata","MODULE_METADATA","CONTROLLERS","controller","prototype","method","Object","getOwnPropertyNames","handler","METHOD_METADATA","undefined","push","name","Module","DiscoveryModule","MCP_SERVER_OPTIONS","Symbol","HttpStatus","HttpException","HttpProblemException","HttpException","detailOrOptions","httpStatus","options","detail","type","label","errors","HttpStatus","BadRequestException","HttpProblemException","detailOrOptions","HttpStatus","BAD_REQUEST","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","HttpStatus","UnauthorizedException","HttpProblemException","detailOrOptions","HttpStatus","UNAUTHORIZED","HttpStatus","HttpStatus","HttpStatus","McpPrincipal","userId","scopes","clientId","grantId","organizationId","hasScope","scope","includes","MCP_PRINCIPAL_FACTORY","Symbol","principalFromOAuth","request","auth","kind","UnauthorizedException","Inject","Injectable","Server","CallToolRequestSchema","ListToolsRequestSchema","Inject","Injectable","Injectable","Logger","DiscoveryService","Reflector","z","SetMetadata","MCP_TOOL_PROVIDER_KEY","McpTools","SetMetadata","defineTool","definition","Logger","ZodError","PG_UNIQUE_VIOLATION","logger","Logger","isRecord","value","Array","isArray","isHttpExceptionLike","getStatus","getResponse","findPgUniqueViolation","error","depth","undefined","code","detail","cause","normalizeFieldErrors","filter","map","entry","field","message","toolOk","payload","structuredContent","result","content","type","text","JSON","stringify","toolError","problem","isError","problemFromError","ZodError","status","label","errors","issues","issue","path","join","body","duplicate","Error","stack","String","TOOL_NAME_PATTERN","ToolRegistry","logger","Logger","name","definitions","Map","catalog","discovery","reflector","onApplicationBootstrap","provider","findProviders","definition","tools","register","values","map","toCatalogEntry","log","length","listTools","coveredOperationIds","flatMap","covers","execute","rawArgs","principal","started","Date","now","get","toolError","status","label","detail","errors","result","hasScope","requiredScope","args","inputSchema","parse","toolOk","handler","error","problem","problemFromError","userId","grantId","clientId","getProviders","filter","wrapper","metatype","instance","MCP_TOOL_PROVIDER_KEY","test","Error","has","set","title","description","toInputSchema","annotations","readOnlyHint","destructiveHint","idempotentHint","openWorldHint","schema","z","toJSONSchema","io","$schema","type","McpServerFactory","options","toolRegistry","create","principal","server","Server","name","version","capabilities","tools","instructions","setRequestHandler","ListToolsRequestSchema","listTools","CallToolRequestSchema","request","execute","params","arguments","StreamableHTTPServerTransport","Injectable","McpTransportFactory","create","StreamableHTTPServerTransport","sessionIdGenerator","undefined","enableJsonResponse","McpRequestHandler","serverFactory","transportFactory","principalFactory","handle","request","reply","body","principal","hijack","transport","create","server","raw","on","close","connect","handleRequest","methodNotAllowed","status","header","send","jsonrpc","error","code","message","id","Injectable","COMPONENT_REF","McpSchemaRegistry","schemas","setDocument","document","components","schemaFor","dto","root","name","type","description","defs","rewritten","rewrite","Object","keys","length","$defs","node","Array","isArray","map","item","record","$ref","startsWith","slice","out","key","value","entries","McpModule","forRoot","options","serverOptions","name","version","instructions","module","imports","DiscoveryModule","providers","provide","MCP_SERVER_OPTIONS","useValue","MCP_PRINCIPAL_FACTORY","principal","principalFromOAuth","McpTransportFactory","McpServerFactory","McpRequestHandler","McpSchemaRegistry","ToolRegistry","exports","plainToInstance","validate","McpValidationError","BadRequestException","errors","label","detail","flattenValidationErrors","parent","flatMap","error","field","property","own","Object","values","constraints","map","message","nested","children","length","validateDto","cls","input","instance","plainToInstance","enableImplicitConversion","validate","whitelist","forbidNonWhitelisted"]}
|
package/dist/root.cjs
CHANGED
package/dist/root.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/root/index.ts","../src/root/root.module.ts","../src/root/controllers/app.controller.ts","../src/auth/decorators/require.decorator.ts","../src/root/docs/app.docs.ts","../src/root/services/app.service.ts","../src/root/controllers/csrf.controller.ts","../src/root/docs/csrf.docs.ts"],"sourcesContent":["export { RootModule } from './root.module';\n","import { Module } from '@nestjs/common';\nimport { AppController } from './controllers/app.controller';\nimport { CsrfController } from './controllers/csrf.controller';\nimport { AppService } from './services/app.service';\n\n@Module({\n controllers: [AppController, CsrfController],\n providers: [AppService],\n})\nexport class RootModule {}\n","import { Controller, Get } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiHealthCheck } from '../docs/app.docs';\nimport { AppService } from '../services/app.service';\n\n@ApiTags('Health')\n@Controller()\nexport class AppController {\n constructor(private readonly appService: AppService) {}\n\n // Returns a welcome message indicating the API is running\n @Get()\n @Require(AuthType.Public)\n @ApiHealthCheck()\n getHello(): string {\n return this.appService.getHello();\n }\n}\n","import { SetMetadata } from '@nestjs/common';\n\nexport const REQUIRE_AUTH_KEY = 'requireAuth';\n\nexport enum AuthType {\n Session = 'session',\n App = 'app',\n Cloud = 'cloud',\n Public = 'public',\n}\n\nexport interface AuthRequirement {\n type: AuthType;\n subtypes: string[];\n}\n\n// Declares how a route authenticates, and which subtypes of that caller may reach it.\n//\n// One decorator for every caller kind, so the branch the guard takes is stated at the call\n// site rather than inferred from which of three decorators happens to be present:\n//\n// @Require(AuthType.Session, SessionTypeValues.WEB) session types WEB\n// @Require(AuthType.App, AppTypeValues.GRAPHQL) app credentials of type GRAPHQL\n// @Require(AuthType.Cloud) signed control-plane calls\n// @Require(AuthType.Public) no authentication\n//\n// Subtypes are compared as strings — the enums belong to the consuming server's schema and\n// this only ever compares. Passing none means \"any subtype\", so the caller is still\n// authenticated but unrestricted.\nexport const Require = (type: AuthType, ...subtypes: string[]) =>\n SetMetadata<string, AuthRequirement>(REQUIRE_AUTH_KEY, { type, subtypes });\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiHealthCheck() {\n return applyDecorators(\n ApiOperation({ summary: 'Health check endpoint' }),\n ApiResponse({\n status: 200,\n description: 'Returns a welcome message indicating the API is running',\n type: String,\n }),\n );\n}\n","import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class AppService {\n // Returns the API welcome message\n getHello(): string {\n return `Hello World!`;\n }\n}\n","import { Controller, Get, HttpCode, HttpStatus, Res } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport type { FastifyReply } from 'fastify';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiGetCsrfToken } from '../docs/csrf.docs';\n\n// Type augmentation for @fastify/csrf-protection — added by the consuming server at runtime\ntype FastifyReplyWithCsrf = FastifyReply & { generateCsrf(): string };\n\n@ApiTags('CSRF')\n@Controller('csrf')\nexport class CsrfController {\n // Generates a CSRF token via Fastify's csrf-protection plugin\n @Get('token')\n @Require(AuthType.Public)\n @HttpCode(HttpStatus.OK)\n @ApiGetCsrfToken()\n getToken(@Res({ passthrough: true }) reply: FastifyReply): { csrfToken: string } {\n const csrfToken = (reply as FastifyReplyWithCsrf).generateCsrf();\n return { csrfToken };\n }\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiGetCsrfToken() {\n return applyDecorators(\n ApiOperation({\n summary: 'Get CSRF token',\n description:\n 'Generates and returns a CSRF token that must be included in all state-changing requests (POST, PUT, PATCH, DELETE). The token should be sent in the X-CSRF-Token header.',\n }),\n ApiResponse({\n status: 200,\n description: 'CSRF token generated successfully',\n schema: {\n type: 'object',\n properties: {\n csrfToken: {\n type: 'string',\n description: 'The CSRF token to use in subsequent requests',\n example: 'abc123xyz789',\n },\n },\n required: ['csrfToken'],\n },\n }),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;ACAA,IAAAA,iBAAuB;;;ACAvB,IAAAC,iBAAgC;AAChC,IAAAC,kBAAwB;;;ACDxB,oBAA4B;AAErB,IAAMC,mBAAmB;AAEzB,IAAKC,WAAAA,0BAAAA,WAAAA
|
|
1
|
+
{"version":3,"sources":["../src/root/index.ts","../src/root/root.module.ts","../src/root/controllers/app.controller.ts","../src/auth/decorators/require.decorator.ts","../src/root/docs/app.docs.ts","../src/root/services/app.service.ts","../src/root/controllers/csrf.controller.ts","../src/root/docs/csrf.docs.ts"],"sourcesContent":["export { RootModule } from './root.module';\n","import { Module } from '@nestjs/common';\nimport { AppController } from './controllers/app.controller';\nimport { CsrfController } from './controllers/csrf.controller';\nimport { AppService } from './services/app.service';\n\n@Module({\n controllers: [AppController, CsrfController],\n providers: [AppService],\n})\nexport class RootModule {}\n","import { Controller, Get } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiHealthCheck } from '../docs/app.docs';\nimport { AppService } from '../services/app.service';\n\n@ApiTags('Health')\n@Controller()\nexport class AppController {\n constructor(private readonly appService: AppService) {}\n\n // Returns a welcome message indicating the API is running\n @Get()\n @Require(AuthType.Public)\n @ApiHealthCheck()\n getHello(): string {\n return this.appService.getHello();\n }\n}\n","import { SetMetadata } from '@nestjs/common';\n\nexport const REQUIRE_AUTH_KEY = 'requireAuth';\n\nexport enum AuthType {\n Session = 'session',\n App = 'app',\n Cloud = 'cloud',\n OAuth = 'oauth',\n Public = 'public',\n}\n\nexport interface AuthRequirement {\n type: AuthType;\n subtypes: string[];\n}\n\n// Declares how a route authenticates, and which subtypes of that caller may reach it.\n//\n// One decorator for every caller kind, so the branch the guard takes is stated at the call\n// site rather than inferred from which of three decorators happens to be present:\n//\n// @Require(AuthType.Session, SessionTypeValues.WEB) session types WEB\n// @Require(AuthType.App, AppTypeValues.GRAPHQL) app credentials of type GRAPHQL\n// @Require(AuthType.Cloud) signed control-plane calls\n// @Require(AuthType.OAuth, 'admin:read') OAuth 2.1 bearer tokens carrying scope admin:read\n// @Require(AuthType.Public) no authentication\n//\n// Subtypes are compared as strings — the enums belong to the consuming server's schema and\n// this only ever compares. Passing none means \"any subtype\", so the caller is still\n// authenticated but unrestricted.\nexport const Require = (type: AuthType, ...subtypes: string[]) =>\n SetMetadata<string, AuthRequirement>(REQUIRE_AUTH_KEY, { type, subtypes });\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiHealthCheck() {\n return applyDecorators(\n ApiOperation({ summary: 'Health check endpoint' }),\n ApiResponse({\n status: 200,\n description: 'Returns a welcome message indicating the API is running',\n type: String,\n }),\n );\n}\n","import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class AppService {\n // Returns the API welcome message\n getHello(): string {\n return `Hello World!`;\n }\n}\n","import { Controller, Get, HttpCode, HttpStatus, Res } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport type { FastifyReply } from 'fastify';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiGetCsrfToken } from '../docs/csrf.docs';\n\n// Type augmentation for @fastify/csrf-protection — added by the consuming server at runtime\ntype FastifyReplyWithCsrf = FastifyReply & { generateCsrf(): string };\n\n@ApiTags('CSRF')\n@Controller('csrf')\nexport class CsrfController {\n // Generates a CSRF token via Fastify's csrf-protection plugin\n @Get('token')\n @Require(AuthType.Public)\n @HttpCode(HttpStatus.OK)\n @ApiGetCsrfToken()\n getToken(@Res({ passthrough: true }) reply: FastifyReply): { csrfToken: string } {\n const csrfToken = (reply as FastifyReplyWithCsrf).generateCsrf();\n return { csrfToken };\n }\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiGetCsrfToken() {\n return applyDecorators(\n ApiOperation({\n summary: 'Get CSRF token',\n description:\n 'Generates and returns a CSRF token that must be included in all state-changing requests (POST, PUT, PATCH, DELETE). The token should be sent in the X-CSRF-Token header.',\n }),\n ApiResponse({\n status: 200,\n description: 'CSRF token generated successfully',\n schema: {\n type: 'object',\n properties: {\n csrfToken: {\n type: 'string',\n description: 'The CSRF token to use in subsequent requests',\n example: 'abc123xyz789',\n },\n },\n required: ['csrfToken'],\n },\n }),\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;ACAA,IAAAA,iBAAuB;;;ACAvB,IAAAC,iBAAgC;AAChC,IAAAC,kBAAwB;;;ACDxB,oBAA4B;AAErB,IAAMC,mBAAmB;AAEzB,IAAKC,WAAAA,0BAAAA,WAAAA;;;;;;SAAAA;;AA2BL,IAAMC,UAAU,wBAACC,SAAmBC,iBACzCC,2BAAqCL,kBAAkB;EAAEG;EAAMC;AAAS,CAAA,GADnD;;;AC/BvB,IAAAE,iBAAgC;AAChC,qBAA0C;AAEnC,SAASC,iBAAAA;AACd,aAAOC,oCACLC,6BAAa;IAAEC,SAAS;EAAwB,CAAA,OAChDC,4BAAY;IACVC,QAAQ;IACRC,aAAa;IACbC,MAAMC;EACR,CAAA,CAAA;AAEJ;AATgBR;;;ACHhB,IAAAS,iBAA2B;;;;;;;;;;;;;;;AAGpB,IAAMC,aAAN,MAAMA;SAAAA;;;;EAEXC,WAAmB;AACjB,WAAO;EACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;AHAO,IAAMC,gBAAN,MAAMA;SAAAA;;;;EACX,YAA6BC,YAAwB;SAAxBA,aAAAA;EAAyB;;EAMtDC,WAAmB;AACjB,WAAO,KAAKD,WAAWC,SAAQ;EACjC;AACF;;;mBALoBC,MAAAA;;;;;;;;;;;;;;;;AIbpB,IAAAC,iBAA2D;AAC3D,IAAAC,kBAAwB;;;ACDxB,IAAAC,iBAAgC;AAChC,IAAAC,kBAA0C;AAEnC,SAASC,kBAAAA;AACd,aAAOC,oCACLC,8BAAa;IACXC,SAAS;IACTC,aACE;EACJ,CAAA,OACAC,6BAAY;IACVC,QAAQ;IACRF,aAAa;IACbG,QAAQ;MACNC,MAAM;MACNC,YAAY;QACVC,WAAW;UACTF,MAAM;UACNJ,aAAa;UACbO,SAAS;QACX;MACF;MACAC,UAAU;QAAC;;IACb;EACF,CAAA,CAAA;AAEJ;AAvBgBZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADQT,IAAMa,iBAAN,MAAMA;SAAAA;;;;EAMXC,SAAqCC,OAA4C;AAC/E,UAAMC,YAAaD,MAA+BE,aAAY;AAC9D,WAAO;MAAED;IAAU;EACrB;AACF;;;mBAPoBE,MAAAA;yDACGC,EAAAA;;;IAELC,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;ALRxB,IAAMC,aAAN,MAAMA;SAAAA;;;AAAY;;;IAHvBC,aAAa;MAACC;MAAeC;;IAC7BC,WAAW;MAACC;;;;","names":["import_common","import_common","import_swagger","REQUIRE_AUTH_KEY","AuthType","Require","type","subtypes","SetMetadata","import_common","ApiHealthCheck","applyDecorators","ApiOperation","summary","ApiResponse","status","description","type","String","import_common","AppService","getHello","AppController","appService","getHello","Public","import_common","import_swagger","import_common","import_swagger","ApiGetCsrfToken","applyDecorators","ApiOperation","summary","description","ApiResponse","status","schema","type","properties","csrfToken","example","required","CsrfController","getToken","reply","csrfToken","generateCsrf","Public","OK","passthrough","RootModule","controllers","AppController","CsrfController","providers","AppService"]}
|
package/dist/root.js
CHANGED
package/dist/root.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/root/root.module.ts","../src/root/controllers/app.controller.ts","../src/auth/decorators/require.decorator.ts","../src/root/docs/app.docs.ts","../src/root/services/app.service.ts","../src/root/controllers/csrf.controller.ts","../src/root/docs/csrf.docs.ts"],"sourcesContent":["import { Module } from '@nestjs/common';\nimport { AppController } from './controllers/app.controller';\nimport { CsrfController } from './controllers/csrf.controller';\nimport { AppService } from './services/app.service';\n\n@Module({\n controllers: [AppController, CsrfController],\n providers: [AppService],\n})\nexport class RootModule {}\n","import { Controller, Get } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiHealthCheck } from '../docs/app.docs';\nimport { AppService } from '../services/app.service';\n\n@ApiTags('Health')\n@Controller()\nexport class AppController {\n constructor(private readonly appService: AppService) {}\n\n // Returns a welcome message indicating the API is running\n @Get()\n @Require(AuthType.Public)\n @ApiHealthCheck()\n getHello(): string {\n return this.appService.getHello();\n }\n}\n","import { SetMetadata } from '@nestjs/common';\n\nexport const REQUIRE_AUTH_KEY = 'requireAuth';\n\nexport enum AuthType {\n Session = 'session',\n App = 'app',\n Cloud = 'cloud',\n Public = 'public',\n}\n\nexport interface AuthRequirement {\n type: AuthType;\n subtypes: string[];\n}\n\n// Declares how a route authenticates, and which subtypes of that caller may reach it.\n//\n// One decorator for every caller kind, so the branch the guard takes is stated at the call\n// site rather than inferred from which of three decorators happens to be present:\n//\n// @Require(AuthType.Session, SessionTypeValues.WEB) session types WEB\n// @Require(AuthType.App, AppTypeValues.GRAPHQL) app credentials of type GRAPHQL\n// @Require(AuthType.Cloud) signed control-plane calls\n// @Require(AuthType.Public) no authentication\n//\n// Subtypes are compared as strings — the enums belong to the consuming server's schema and\n// this only ever compares. Passing none means \"any subtype\", so the caller is still\n// authenticated but unrestricted.\nexport const Require = (type: AuthType, ...subtypes: string[]) =>\n SetMetadata<string, AuthRequirement>(REQUIRE_AUTH_KEY, { type, subtypes });\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiHealthCheck() {\n return applyDecorators(\n ApiOperation({ summary: 'Health check endpoint' }),\n ApiResponse({\n status: 200,\n description: 'Returns a welcome message indicating the API is running',\n type: String,\n }),\n );\n}\n","import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class AppService {\n // Returns the API welcome message\n getHello(): string {\n return `Hello World!`;\n }\n}\n","import { Controller, Get, HttpCode, HttpStatus, Res } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport type { FastifyReply } from 'fastify';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiGetCsrfToken } from '../docs/csrf.docs';\n\n// Type augmentation for @fastify/csrf-protection — added by the consuming server at runtime\ntype FastifyReplyWithCsrf = FastifyReply & { generateCsrf(): string };\n\n@ApiTags('CSRF')\n@Controller('csrf')\nexport class CsrfController {\n // Generates a CSRF token via Fastify's csrf-protection plugin\n @Get('token')\n @Require(AuthType.Public)\n @HttpCode(HttpStatus.OK)\n @ApiGetCsrfToken()\n getToken(@Res({ passthrough: true }) reply: FastifyReply): { csrfToken: string } {\n const csrfToken = (reply as FastifyReplyWithCsrf).generateCsrf();\n return { csrfToken };\n }\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiGetCsrfToken() {\n return applyDecorators(\n ApiOperation({\n summary: 'Get CSRF token',\n description:\n 'Generates and returns a CSRF token that must be included in all state-changing requests (POST, PUT, PATCH, DELETE). The token should be sent in the X-CSRF-Token header.',\n }),\n ApiResponse({\n status: 200,\n description: 'CSRF token generated successfully',\n schema: {\n type: 'object',\n properties: {\n csrfToken: {\n type: 'string',\n description: 'The CSRF token to use in subsequent requests',\n example: 'abc123xyz789',\n },\n },\n required: ['csrfToken'],\n },\n }),\n );\n}\n"],"mappings":";;;;AAAA,SAASA,cAAc;;;ACAvB,SAASC,YAAYC,WAAW;AAChC,SAASC,eAAe;;;ACDxB,SAASC,mBAAmB;AAErB,IAAMC,mBAAmB;AAEzB,IAAKC,WAAAA,0BAAAA,WAAAA
|
|
1
|
+
{"version":3,"sources":["../src/root/root.module.ts","../src/root/controllers/app.controller.ts","../src/auth/decorators/require.decorator.ts","../src/root/docs/app.docs.ts","../src/root/services/app.service.ts","../src/root/controllers/csrf.controller.ts","../src/root/docs/csrf.docs.ts"],"sourcesContent":["import { Module } from '@nestjs/common';\nimport { AppController } from './controllers/app.controller';\nimport { CsrfController } from './controllers/csrf.controller';\nimport { AppService } from './services/app.service';\n\n@Module({\n controllers: [AppController, CsrfController],\n providers: [AppService],\n})\nexport class RootModule {}\n","import { Controller, Get } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiHealthCheck } from '../docs/app.docs';\nimport { AppService } from '../services/app.service';\n\n@ApiTags('Health')\n@Controller()\nexport class AppController {\n constructor(private readonly appService: AppService) {}\n\n // Returns a welcome message indicating the API is running\n @Get()\n @Require(AuthType.Public)\n @ApiHealthCheck()\n getHello(): string {\n return this.appService.getHello();\n }\n}\n","import { SetMetadata } from '@nestjs/common';\n\nexport const REQUIRE_AUTH_KEY = 'requireAuth';\n\nexport enum AuthType {\n Session = 'session',\n App = 'app',\n Cloud = 'cloud',\n OAuth = 'oauth',\n Public = 'public',\n}\n\nexport interface AuthRequirement {\n type: AuthType;\n subtypes: string[];\n}\n\n// Declares how a route authenticates, and which subtypes of that caller may reach it.\n//\n// One decorator for every caller kind, so the branch the guard takes is stated at the call\n// site rather than inferred from which of three decorators happens to be present:\n//\n// @Require(AuthType.Session, SessionTypeValues.WEB) session types WEB\n// @Require(AuthType.App, AppTypeValues.GRAPHQL) app credentials of type GRAPHQL\n// @Require(AuthType.Cloud) signed control-plane calls\n// @Require(AuthType.OAuth, 'admin:read') OAuth 2.1 bearer tokens carrying scope admin:read\n// @Require(AuthType.Public) no authentication\n//\n// Subtypes are compared as strings — the enums belong to the consuming server's schema and\n// this only ever compares. Passing none means \"any subtype\", so the caller is still\n// authenticated but unrestricted.\nexport const Require = (type: AuthType, ...subtypes: string[]) =>\n SetMetadata<string, AuthRequirement>(REQUIRE_AUTH_KEY, { type, subtypes });\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiHealthCheck() {\n return applyDecorators(\n ApiOperation({ summary: 'Health check endpoint' }),\n ApiResponse({\n status: 200,\n description: 'Returns a welcome message indicating the API is running',\n type: String,\n }),\n );\n}\n","import { Injectable } from '@nestjs/common';\n\n@Injectable()\nexport class AppService {\n // Returns the API welcome message\n getHello(): string {\n return `Hello World!`;\n }\n}\n","import { Controller, Get, HttpCode, HttpStatus, Res } from '@nestjs/common';\nimport { ApiTags } from '@nestjs/swagger';\nimport type { FastifyReply } from 'fastify';\nimport { AuthType, Require } from '../../auth/decorators/require.decorator';\nimport { ApiGetCsrfToken } from '../docs/csrf.docs';\n\n// Type augmentation for @fastify/csrf-protection — added by the consuming server at runtime\ntype FastifyReplyWithCsrf = FastifyReply & { generateCsrf(): string };\n\n@ApiTags('CSRF')\n@Controller('csrf')\nexport class CsrfController {\n // Generates a CSRF token via Fastify's csrf-protection plugin\n @Get('token')\n @Require(AuthType.Public)\n @HttpCode(HttpStatus.OK)\n @ApiGetCsrfToken()\n getToken(@Res({ passthrough: true }) reply: FastifyReply): { csrfToken: string } {\n const csrfToken = (reply as FastifyReplyWithCsrf).generateCsrf();\n return { csrfToken };\n }\n}\n","import { applyDecorators } from '@nestjs/common';\nimport { ApiOperation, ApiResponse } from '@nestjs/swagger';\n\nexport function ApiGetCsrfToken() {\n return applyDecorators(\n ApiOperation({\n summary: 'Get CSRF token',\n description:\n 'Generates and returns a CSRF token that must be included in all state-changing requests (POST, PUT, PATCH, DELETE). The token should be sent in the X-CSRF-Token header.',\n }),\n ApiResponse({\n status: 200,\n description: 'CSRF token generated successfully',\n schema: {\n type: 'object',\n properties: {\n csrfToken: {\n type: 'string',\n description: 'The CSRF token to use in subsequent requests',\n example: 'abc123xyz789',\n },\n },\n required: ['csrfToken'],\n },\n }),\n );\n}\n"],"mappings":";;;;AAAA,SAASA,cAAc;;;ACAvB,SAASC,YAAYC,WAAW;AAChC,SAASC,eAAe;;;ACDxB,SAASC,mBAAmB;AAErB,IAAMC,mBAAmB;AAEzB,IAAKC,WAAAA,0BAAAA,WAAAA;;;;;;SAAAA;;AA2BL,IAAMC,UAAU,wBAACC,SAAmBC,aACzCC,YAAqCL,kBAAkB;EAAEG;EAAMC;AAAS,CAAA,GADnD;;;AC/BvB,SAASE,uBAAuB;AAChC,SAASC,cAAcC,mBAAmB;AAEnC,SAASC,iBAAAA;AACd,SAAOC,gBACLC,aAAa;IAAEC,SAAS;EAAwB,CAAA,GAChDC,YAAY;IACVC,QAAQ;IACRC,aAAa;IACbC,MAAMC;EACR,CAAA,CAAA;AAEJ;AATgBR;;;ACHhB,SAASS,kBAAkB;;;;;;;;;;;;;;;AAGpB,IAAMC,aAAN,MAAMA;SAAAA;;;;EAEXC,WAAmB;AACjB,WAAO;EACT;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;AHAO,IAAMC,gBAAN,MAAMA;SAAAA;;;;EACX,YAA6BC,YAAwB;SAAxBA,aAAAA;EAAyB;;EAMtDC,WAAmB;AACjB,WAAO,KAAKD,WAAWC,SAAQ;EACjC;AACF;;;mBALoBC,MAAAA;;;;;;;;;;;;;;;;AIbpB,SAASC,cAAAA,aAAYC,OAAAA,MAAKC,UAAUC,YAAYC,WAAW;AAC3D,SAASC,WAAAA,gBAAe;;;ACDxB,SAASC,mBAAAA,wBAAuB;AAChC,SAASC,gBAAAA,eAAcC,eAAAA,oBAAmB;AAEnC,SAASC,kBAAAA;AACd,SAAOC,iBACLC,cAAa;IACXC,SAAS;IACTC,aACE;EACJ,CAAA,GACAC,aAAY;IACVC,QAAQ;IACRF,aAAa;IACbG,QAAQ;MACNC,MAAM;MACNC,YAAY;QACVC,WAAW;UACTF,MAAM;UACNJ,aAAa;UACbO,SAAS;QACX;MACF;MACAC,UAAU;QAAC;;IACb;EACF,CAAA,CAAA;AAEJ;AAvBgBZ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ADQT,IAAMa,iBAAN,MAAMA;SAAAA;;;;EAMXC,SAAqCC,OAA4C;AAC/E,UAAMC,YAAaD,MAA+BE,aAAY;AAC9D,WAAO;MAAED;IAAU;EACrB;AACF;;;mBAPoBE,MAAAA;sBACGC,EAAAA;;;IAELC,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;ALRxB,IAAMC,aAAN,MAAMA;SAAAA;;;AAAY;;;IAHvBC,aAAa;MAACC;MAAeC;;IAC7BC,WAAW;MAACC;;;;","names":["Module","Controller","Get","ApiTags","SetMetadata","REQUIRE_AUTH_KEY","AuthType","Require","type","subtypes","SetMetadata","applyDecorators","ApiOperation","ApiResponse","ApiHealthCheck","applyDecorators","ApiOperation","summary","ApiResponse","status","description","type","String","Injectable","AppService","getHello","AppController","appService","getHello","Public","Controller","Get","HttpCode","HttpStatus","Res","ApiTags","applyDecorators","ApiOperation","ApiResponse","ApiGetCsrfToken","applyDecorators","ApiOperation","summary","description","ApiResponse","status","schema","type","properties","csrfToken","example","required","CsrfController","getToken","reply","csrfToken","generateCsrf","Public","OK","passthrough","RootModule","controllers","AppController","CsrfController","providers","AppService"]}
|
package/dist/zod.cjs
ADDED
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __copyProps = (to, from, except, desc) => {
|
|
7
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
8
|
+
for (let key of __getOwnPropNames(from))
|
|
9
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
10
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
11
|
+
}
|
|
12
|
+
return to;
|
|
13
|
+
};
|
|
14
|
+
var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default"));
|
|
15
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
16
|
+
|
|
17
|
+
// src/zod.ts
|
|
18
|
+
var zod_exports = {};
|
|
19
|
+
module.exports = __toCommonJS(zod_exports);
|
|
20
|
+
__reExport(zod_exports, require("zod"), module.exports);
|
|
21
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
22
|
+
0 && (module.exports = {
|
|
23
|
+
...require("zod")
|
|
24
|
+
});
|
|
25
|
+
//# sourceMappingURL=zod.cjs.map
|
package/dist/zod.cjs.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/zod.ts"],"sourcesContent":["// Re-export zod as a subpath so servers author MCP tool schemas against the SAME zod instance the tool pipeline\n// validates and serialises with — a second copy would make every ZodType a foreign object to the registry.\nexport * from 'zod';\n"],"mappings":";;;;;;;;;;;;;;;;;AAAA;;AAEA,wBAAc,gBAFd;","names":[]}
|
package/dist/zod.d.cts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'zod';
|
package/dist/zod.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from 'zod';
|
package/dist/zod.js
ADDED
package/dist/zod.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/zod.ts"],"sourcesContent":["// Re-export zod as a subpath so servers author MCP tool schemas against the SAME zod instance the tool pipeline\n// validates and serialises with — a second copy would make every ZodType a foreign object to the registry.\nexport * from 'zod';\n"],"mappings":";AAEA,cAAc;","names":[]}
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vritti/api-sdk",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "0.4.
|
|
4
|
+
"version": "0.4.9",
|
|
5
5
|
"main": "./dist/index.cjs",
|
|
6
6
|
"module": "./dist/index.js",
|
|
7
7
|
"types": "./dist/index.d.ts",
|
|
@@ -76,6 +76,16 @@
|
|
|
76
76
|
"default": "./dist/xlsx.cjs"
|
|
77
77
|
}
|
|
78
78
|
},
|
|
79
|
+
"./zod": {
|
|
80
|
+
"import": {
|
|
81
|
+
"types": "./dist/zod.d.ts",
|
|
82
|
+
"default": "./dist/zod.js"
|
|
83
|
+
},
|
|
84
|
+
"require": {
|
|
85
|
+
"types": "./dist/zod.d.cts",
|
|
86
|
+
"default": "./dist/zod.cjs"
|
|
87
|
+
}
|
|
88
|
+
},
|
|
79
89
|
"./lodash": {
|
|
80
90
|
"import": {
|
|
81
91
|
"types": "./dist/lodash.d.ts",
|
|
@@ -305,6 +315,16 @@
|
|
|
305
315
|
"types": "./dist/utils.d.cts",
|
|
306
316
|
"default": "./dist/utils.cjs"
|
|
307
317
|
}
|
|
318
|
+
},
|
|
319
|
+
"./mcp": {
|
|
320
|
+
"import": {
|
|
321
|
+
"types": "./dist/mcp.d.ts",
|
|
322
|
+
"default": "./dist/mcp.js"
|
|
323
|
+
},
|
|
324
|
+
"require": {
|
|
325
|
+
"types": "./dist/mcp.d.cts",
|
|
326
|
+
"default": "./dist/mcp.cjs"
|
|
327
|
+
}
|
|
308
328
|
}
|
|
309
329
|
},
|
|
310
330
|
"files": [
|
|
@@ -322,6 +342,7 @@
|
|
|
322
342
|
},
|
|
323
343
|
"dependencies": {
|
|
324
344
|
"@getbrevo/brevo": "^4.0.1",
|
|
345
|
+
"@modelcontextprotocol/sdk": "1.30.0",
|
|
325
346
|
"@nats-io/transport-node": "^3.4.0",
|
|
326
347
|
"decimal.js": "^10.6.0",
|
|
327
348
|
"dinero.js": "2.0.2",
|
|
@@ -333,7 +354,8 @@
|
|
|
333
354
|
"pluralize-esm": "^9.0.5",
|
|
334
355
|
"winston": "^3.19.0",
|
|
335
356
|
"winston-daily-rotate-file": "^5.0.0",
|
|
336
|
-
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz"
|
|
357
|
+
"xlsx": "https://cdn.sheetjs.com/xlsx-0.20.3/xlsx-0.20.3.tgz",
|
|
358
|
+
"zod": "4.5.4"
|
|
337
359
|
},
|
|
338
360
|
"peerDependencies": {
|
|
339
361
|
"@aws-sdk/client-s3": "^3.997.0",
|