@happyvertical/smrt-core 0.44.1 → 0.45.1
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/agents/change-feed.md +3 -2
- package/dist/browser.js +2 -1
- package/dist/change-feed.d.ts +60 -1
- package/dist/change-feed.d.ts.map +1 -1
- package/dist/change-feed.js +464 -27
- package/dist/change-feed.js.map +1 -1
- package/dist/change-signals.d.ts.map +1 -1
- package/dist/change-signals.js +13 -11
- package/dist/change-signals.js.map +1 -1
- package/dist/generators/cli.d.ts.map +1 -1
- package/dist/generators/cli.js +10 -18
- package/dist/generators/cli.js.map +1 -1
- package/dist/generators/custom-action.d.ts +216 -0
- package/dist/generators/custom-action.d.ts.map +1 -1
- package/dist/generators/custom-action.js +256 -1
- package/dist/generators/custom-action.js.map +1 -1
- package/dist/generators/index.d.ts +1 -1
- package/dist/generators/index.d.ts.map +1 -1
- package/dist/generators/index.js +2 -2
- package/dist/generators/mcp.d.ts.map +1 -1
- package/dist/generators/mcp.js +14 -39
- package/dist/generators/mcp.js.map +1 -1
- package/dist/generators/rest.d.ts.map +1 -1
- package/dist/generators/rest.js +2 -0
- package/dist/generators/rest.js.map +1 -1
- package/dist/generators/tool-schema.d.ts.map +1 -1
- package/dist/generators/tool-schema.js +2 -8
- package/dist/generators/tool-schema.js.map +1 -1
- package/dist/generators.js +2 -2
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -3
- package/dist/knowledge.d.ts.map +1 -1
- package/dist/knowledge.js +283 -35
- package/dist/knowledge.js.map +1 -1
- package/dist/manifest/static-manifest.js +1 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest.json +1 -1
- package/dist/registry/framework-base-classes.d.ts +10 -0
- package/dist/registry/framework-base-classes.d.ts.map +1 -0
- package/dist/registry/framework-base-classes.js +92 -0
- package/dist/registry/framework-base-classes.js.map +1 -0
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +2 -0
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/types.d.ts +27 -6
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +2 -1
- package/dist/registry.js.map +1 -1
- package/dist/scanner/manifest-generator.d.ts +46 -16
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +198 -45
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/smrt-knowledge.json +5 -5
- package/dist/system/bootstrap.d.ts.map +1 -1
- package/dist/system/bootstrap.js +2 -1
- package/dist/system/bootstrap.js.map +1 -1
- package/dist/system/schema.d.ts +75 -2
- package/dist/system/schema.d.ts.map +1 -1
- package/dist/system/schema.js +326 -4
- package/dist/system/schema.js.map +1 -1
- package/dist/vite-plugin/index.d.ts +10 -0
- package/dist/vite-plugin/index.d.ts.map +1 -1
- package/dist/vite-plugin/index.js +52 -23
- package/dist/vite-plugin/index.js.map +1 -1
- package/dist/vite-plugin/resources-route.d.ts +18 -0
- package/dist/vite-plugin/resources-route.d.ts.map +1 -0
- package/dist/vite-plugin/resources-route.js +154 -0
- package/dist/vite-plugin/resources-route.js.map +1 -0
- package/dist/vite-plugin/sveltekit-generator.d.ts +43 -7
- package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
- package/dist/vite-plugin/sveltekit-generator.js +90 -17
- package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
- package/dist/vite-plugin/sync-apply-route.d.ts.map +1 -1
- package/dist/vite-plugin/sync-apply-route.js +2 -0
- package/dist/vite-plugin/sync-apply-route.js.map +1 -1
- package/dist/vite-plugin/web-collections.d.ts.map +1 -1
- package/dist/vite-plugin/web-collections.js +28 -5
- package/dist/vite-plugin/web-collections.js.map +1 -1
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tool-schema.js","names":[],"sources":["../../src/generators/tool-schema.ts"],"sourcesContent":["import {\n buildCustomActionInputSchema,\n type CustomActionMetadata,\n type ToolEffect,\n} from './custom-action.js';\n\n/**\n * Transport-agnostic tool-descriptor builder (#1812, tracer).\n *\n * The single source of truth for turning a model's fields + exposed actions into\n * MCP-shaped tool descriptors (`{ name, description, inputSchema }`). This is the\n * shape both the Model Context Protocol AND Chrome's WebMCP\n * (`document.modelContext.registerTool`) consume — see\n * https://developer.chrome.com/docs/ai/webmcp.\n *\n * It is deliberately pure and free of `ObjectRegistry` / manifest coupling: it\n * takes a normalized {@link ToolFieldMeta}[] so BOTH callers can share it —\n * - `MCPGenerator` (`src/generators/mcp.ts`) for the Node stdio server, and\n * - the web-collections emitter (`src/vite-plugin/web-collections.ts`) for the\n * browser client-data runtime's WebMCP descriptors.\n *\n * Keeping one implementation removes the field-mapping drift risk the\n * \"three emission sites must agree\" contract in web-collections.ts already warns\n * about. The `fieldTypeToJsonSchema` / per-action skeletons below are ported\n * verbatim from mcp.ts's `fieldToMCPSchema` + `generateObjectTools`, so wiring\n * mcp.ts to call this helper is a mechanical, behavior-preserving refactor.\n */\n\n/**\n * A JSON Schema fragment. Values vary by field kind, so this is only ever\n * serialized into tool descriptors, never read back structurally.\n */\nexport type ToolJsonSchema = Record<string, unknown>;\n\n/** The only JSON Schema dialect emitted by generated MCP and WebMCP tools. */\nexport const JSON_SCHEMA_2020_12 =\n 'https://json-schema.org/draft/2020-12/schema';\n\n/**\n * Bounds for generated schemas. Field metadata is authored input, so it must\n * not turn a tools/list response into an unbounded composition or validation\n * workload. These limits are deliberately far above normal SMRT objects while\n * still keeping schemas comfortably inside MCP transport budgets.\n */\nexport const MCP_SCHEMA_LIMITS = {\n maxDepth: 16,\n maxNodes: 2_048,\n maxSerializedBytes: 65_536,\n} as const;\n\n/**\n * Apply the draft-2020-12 dialect and reject schemas that violate MCP's\n * bounded-composition contract. Generated schemas only ever reference local\n * `$defs`; external refs are neither emitted nor followed.\n */\nexport function finalizeMcpJsonSchema(schema: ToolJsonSchema): ToolJsonSchema {\n const finalized = {\n ...schema,\n $schema: JSON_SCHEMA_2020_12,\n };\n assertMcpJsonSchemaSafety(finalized);\n return finalized;\n}\n\n/**\n * Validate the resource envelope of an emitted schema without resolving refs.\n * This is intentionally structural rather than a general JSON-Schema\n * evaluator: the server already owns every schema it emits, and this guard\n * exists to keep authored metadata from introducing hostile shape growth.\n */\nexport function assertMcpJsonSchemaSafety(schema: ToolJsonSchema): void {\n let nodes = 0;\n const ancestors = new WeakSet<object>();\n\n const visit = (value: unknown, depth: number, key?: string): void => {\n nodes += 1;\n if (nodes > MCP_SCHEMA_LIMITS.maxNodes) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxNodes} nodes`,\n );\n }\n if (depth > MCP_SCHEMA_LIMITS.maxDepth) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxDepth} levels of depth`,\n );\n }\n if (key === '$ref') {\n if (\n typeof value !== 'string' ||\n !value.startsWith('#/$defs/') ||\n value.includes('://')\n ) {\n throw new Error(\n 'MCP JSON Schema may only use local #/$defs/ references',\n );\n }\n return;\n }\n if (value === null || typeof value !== 'object') return;\n if (ancestors.has(value)) {\n throw new Error('MCP JSON Schema must not contain cyclic values');\n }\n\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (const entry of value) visit(entry, depth + 1);\n } else {\n for (const [childKey, child] of Object.entries(value)) {\n visit(child, depth + 1, childKey);\n }\n }\n ancestors.delete(value);\n };\n\n visit(schema, 0);\n\n let serialized: string;\n try {\n serialized = JSON.stringify(schema);\n } catch {\n throw new Error('MCP JSON Schema must be JSON-serializable');\n }\n if (\n new TextEncoder().encode(serialized).byteLength >\n MCP_SCHEMA_LIMITS.maxSerializedBytes\n ) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxSerializedBytes} serialized bytes`,\n );\n }\n}\n\n/**\n * Normalized field metadata — the intersection of what the runtime registry\n * (`FieldDefinition._meta`) and the build-time manifest (`WebFieldDefinition`)\n * can each supply. Callers flatten their own field source into this shape.\n */\nexport interface ToolFieldMeta {\n name: string;\n /** Field kind: text | integer | decimal | boolean | datetime | json | foreignKey | … */\n type: string;\n required?: boolean;\n description?: string;\n default?: unknown;\n maxLength?: number;\n minLength?: number;\n min?: number;\n max?: number;\n /** Field values may explicitly be null in the runtime/manifest contract. */\n nullable?: boolean;\n /** For `foreignKey`: the related class name, for the generated description. */\n related?: string;\n}\n\n/** Storage contract for the synthetic primary identifier. */\nexport type ToolIdType = 'uuid' | 'text';\n\n/** The CRUD verbs with dedicated input-schema skeletons; anything else is custom. */\nconst CRUD_ACTIONS = new Set(['list', 'get', 'create', 'update', 'delete']);\n\nexport interface ToolRouteDescriptor {\n /** HTTP method emitted for the route. */\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n /** Whether the route targets one item or the whole collection. */\n scope: 'item' | 'collection';\n /** Route segments below the collection endpoint. Dynamic segments use `[x]`. */\n path: string[];\n /** Transport names rewritten by the tool schema (e.g. `actionId` → `id`). */\n parameterAliases?: Record<string, string>;\n /** The generated method accepts one `options` bag as its sole argument. */\n optionsBag?: boolean;\n}\n\n/** A single generated tool descriptor — the WebMCP / MCP tool shape. */\nexport interface ToolDescriptor {\n /** The action this tool performs (`list` | `get` | … | a custom method name). */\n action: string;\n /** Tool id, `${toolPrefix}_${action}` (e.g. `product_list`). */\n name: string;\n description: string;\n inputSchema: ToolJsonSchema;\n /** True when the declared effect is `read` → WebMCP `annotations.readOnlyHint`. */\n readOnly: boolean;\n /** Capability effect used by browser-tool exposure policy. */\n effect: ToolEffect;\n /** Whether repeating this tool with the same arguments is safe. */\n idempotent: boolean;\n /** Whether the tool may interact outside the SMRT application. */\n openWorld: boolean;\n /** Generated custom-route transport metadata, when the action has a route. */\n route?: ToolRouteDescriptor;\n}\n\n/**\n * Map one normalized field to its JSON-Schema fragment. Ported from\n * `MCPGenerator.fieldToMCPSchema` (mcp.ts) — keep the two in lockstep until\n * mcp.ts is switched to call this.\n */\nexport function fieldTypeToJsonSchema(field: ToolFieldMeta): ToolJsonSchema {\n const schema: ToolJsonSchema = {\n description: field.description || `${field.type} field`,\n };\n\n switch (field.type) {\n case 'text':\n schema.type = 'string';\n if (field.maxLength !== undefined) schema.maxLength = field.maxLength;\n if (field.minLength !== undefined) schema.minLength = field.minLength;\n break;\n case 'integer':\n schema.type = 'integer';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'decimal':\n schema.type = 'number';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'boolean':\n schema.type = 'boolean';\n break;\n case 'datetime':\n schema.type = 'string';\n schema.format = 'date-time';\n break;\n case 'json':\n schema.type = 'object';\n break;\n case 'foreignKey':\n case 'crossPackageRef':\n schema.type = 'string';\n // The generic relation hint is a fallback only — an authored\n // `@field({ description })` wins (#2046 threads descriptions into web\n // tool descriptors; clobbering them here would strip the help text).\n if (!field.description) {\n schema.description = `ID of related ${field.related || 'object'}`;\n }\n break;\n default:\n schema.type = 'string';\n }\n\n if (field.default !== undefined) {\n schema.default = field.default;\n }\n\n if (field.nullable && typeof schema.type === 'string') {\n schema.type = [schema.type, 'null'];\n }\n\n return schema;\n}\n\nfunction buildFieldProperties(fields: ToolFieldMeta[]): {\n properties: Record<string, ToolJsonSchema>;\n defs: Record<string, ToolJsonSchema>;\n} {\n const properties: Record<string, ToolJsonSchema> = {};\n const defs: Record<string, ToolJsonSchema> = {};\n\n fields.forEach((field, index) => {\n // Numeric keys avoid JSON Pointer escaping and keep output deterministic\n // even for an authored field name containing `/` or `~`.\n const defKey = `field_${index}`;\n defs[defKey] = fieldTypeToJsonSchema(field);\n properties[field.name] = { $ref: `#/$defs/${defKey}` };\n });\n\n return { properties, defs };\n}\n\n/**\n * Build the `inputSchema` for one action. CRUD verbs get the fixed skeletons\n * ported from mcp.ts's `generateObjectTools`; any other action is treated as a\n * custom method taking `{ id, options }`.\n */\nexport function buildToolInputSchema(\n action: string,\n fields: ToolFieldMeta[],\n customAction?: CustomActionMetadata,\n idType: ToolIdType = 'uuid',\n): ToolJsonSchema {\n const identifierSchema = (description: string): ToolJsonSchema => ({\n type: 'string',\n ...(idType === 'uuid' ? { format: 'uuid' } : {}),\n description,\n });\n\n switch (action) {\n case 'list':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n limit: {\n type: 'integer',\n description: 'Maximum number of items to return',\n default: 50,\n minimum: 1,\n maximum: 1000,\n },\n offset: {\n type: 'integer',\n description: 'Number of items to skip',\n default: 0,\n minimum: 0,\n },\n orderBy: {\n type: 'string',\n description: 'Field to order by (e.g., \"created_at DESC\")',\n },\n where: {\n type: 'object',\n description: 'Filter conditions as key-value pairs',\n additionalProperties: true,\n },\n },\n });\n\n case 'get':\n // Either `id` OR `slug` identifies the object (collection.get resolves\n // both). The schema must require one of them just as the handler does,\n // while still allowing slug-only lookups.\n return finalizeMcpJsonSchema({\n type: 'object',\n anyOf: [{ required: ['id'] }, { required: ['slug'] }],\n properties: {\n id: identifierSchema('Unique identifier of the object'),\n slug: {\n type: 'string',\n description: 'URL-friendly identifier of the object',\n },\n },\n });\n\n case 'create': {\n const { properties, defs } = buildFieldProperties(fields);\n const required: string[] = [];\n for (const field of fields) {\n if (field.required) required.push(field.name);\n }\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'update': {\n const { properties: fieldProperties, defs } =\n buildFieldProperties(fields);\n const properties: Record<string, ToolJsonSchema> = {\n id: identifierSchema('ID of the object to update'),\n ...fieldProperties,\n };\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n required: ['id'],\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'delete':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n id: identifierSchema('ID of the object to delete'),\n },\n required: ['id'],\n });\n\n default:\n return finalizeMcpJsonSchema(\n buildCustomActionInputSchema(\n customAction ?? {\n scope: 'item',\n idRequired: true,\n isStatic: false,\n effect: 'destructive',\n idempotent: false,\n openWorld: true,\n },\n ),\n );\n }\n}\n\n/**\n * Human-readable description for a tool, matching mcp.ts's phrasing so the Node\n * MCP and WebMCP surfaces read identically.\n */\nfunction describeAction(action: string, className: string): string {\n switch (action) {\n case 'list':\n return `List ${className} objects with optional filtering`;\n case 'get':\n return `Get a specific ${className} by ID or slug`;\n case 'create':\n return `Create a new ${className}`;\n case 'update':\n return `Update an existing ${className}`;\n case 'delete':\n return `Delete a ${className} by ID`;\n default:\n return `Execute ${action} action on ${className}`;\n }\n}\n\n/**\n * Build the full descriptor set for a model. `toolPrefix` defaults to the\n * lowercased class name so tool ids match the existing Node MCP surface exactly\n * (`product_list`, `invoice_record_payment`), giving one stable tool vocabulary\n * across MCP and WebMCP.\n */\nexport function buildToolDescriptors(opts: {\n className: string;\n fields: ToolFieldMeta[];\n actions: string[];\n customActions?: Record<string, CustomActionMetadata>;\n toolPrefix?: string;\n idType?: ToolIdType;\n}): ToolDescriptor[] {\n const { className, fields, actions } = opts;\n const prefix = (opts.toolPrefix ?? className).toLowerCase();\n\n return actions.map((action) => {\n const customAction = opts.customActions?.[action];\n const semantics = toolSemantics(action, customAction);\n return {\n action,\n // Custom method names can contain underscores; the runtime splits on the\n // FIRST underscore only (mcp.ts #1378), so a lowercased join is safe here.\n name: `${prefix}_${action}`.toLowerCase(),\n description: describeAction(action, className),\n inputSchema: buildToolInputSchema(\n action,\n fields,\n customAction,\n opts.idType,\n ),\n readOnly: semantics.effect === 'read',\n ...semantics,\n };\n });\n}\n\nfunction toolSemantics(\n action: string,\n customAction?: CustomActionMetadata,\n): Pick<ToolDescriptor, 'effect' | 'idempotent' | 'openWorld'> {\n switch (action) {\n case 'list':\n case 'get':\n return { effect: 'read', idempotent: true, openWorld: false };\n case 'create':\n return { effect: 'write', idempotent: false, openWorld: false };\n case 'update':\n return { effect: 'write', idempotent: true, openWorld: false };\n case 'delete':\n return { effect: 'destructive', idempotent: true, openWorld: false };\n default:\n return {\n effect: customAction?.effect ?? 'destructive',\n idempotent: customAction?.idempotent ?? false,\n openWorld: customAction?.openWorld ?? true,\n };\n }\n}\n\n/** True when `action` is one of the fixed CRUD verbs (vs. a custom method). */\nexport function isCrudAction(action: string): boolean {\n return CRUD_ACTIONS.has(action);\n}\n"],"mappings":";;;AAmCA,IAAa,sBACX;;;;;;;AAQF,IAAa,oBAAoB;CAC/B,UAAU;CACV,UAAU;CACV,oBAAoB;AACtB;;;;;;AAOA,SAAgB,sBAAsB,QAAwC;CAC5E,MAAM,YAAY;EAChB,GAAG;EACH,SAAS;CACX;CACA,0BAA0B,SAAS;CACnC,OAAO;AACT;;;;;;;AAQA,SAAgB,0BAA0B,QAA8B;CACtE,IAAI,QAAQ;CACZ,MAAM,4BAAY,IAAI,QAAgB;CAEtC,MAAM,SAAS,OAAgB,OAAe,QAAuB;EACnE,SAAS;EACT,IAAI,QAAQ,kBAAkB,UAC5B,MAAM,IAAI,MACR,2BAA2B,kBAAkB,SAAS,OACxD;EAEF,IAAI,QAAQ,kBAAkB,UAC5B,MAAM,IAAI,MACR,2BAA2B,kBAAkB,SAAS,iBACxD;EAEF,IAAI,QAAQ,QAAQ;GAClB,IACE,OAAO,UAAU,YACjB,CAAC,MAAM,WAAW,UAAU,KAC5B,MAAM,SAAS,KAAK,GAEpB,MAAM,IAAI,MACR,wDACF;GAEF;EACF;EACA,IAAI,UAAU,QAAQ,OAAO,UAAU,UAAU;EACjD,IAAI,UAAU,IAAI,KAAK,GACrB,MAAM,IAAI,MAAM,gDAAgD;EAGlE,UAAU,IAAI,KAAK;EACnB,IAAI,MAAM,QAAQ,KAAK,GACrB,KAAK,MAAM,SAAS,OAAO,MAAM,OAAO,QAAQ,CAAC;OAEjD,KAAK,MAAM,CAAC,UAAU,UAAU,OAAO,QAAQ,KAAK,GAClD,MAAM,OAAO,QAAQ,GAAG,QAAQ;EAGpC,UAAU,OAAO,KAAK;CACxB;CAEA,MAAM,QAAQ,CAAC;CAEf,IAAI;CACJ,IAAI;EACF,aAAa,KAAK,UAAU,MAAM;CACpC,QAAQ;EACN,MAAM,IAAI,MAAM,2CAA2C;CAC7D;CACA,IACE,IAAI,YAAY,CAAC,CAAC,OAAO,UAAU,CAAC,CAAC,aACrC,kBAAkB,oBAElB,MAAM,IAAI,MACR,2BAA2B,kBAAkB,mBAAmB,kBAClE;AAEJ;;AA4BA,IAAM,+BAAe,IAAI,IAAI;CAAC;CAAQ;CAAO;CAAU;CAAU;AAAQ,CAAC;;;;;;AAwC1E,SAAgB,sBAAsB,OAAsC;CAC1E,MAAM,SAAyB,EAC7B,aAAa,MAAM,eAAe,GAAG,MAAM,KAAK,QAClD;CAEA,QAAQ,MAAM,MAAd;EACE,KAAK;GACH,OAAO,OAAO;GACd,IAAI,MAAM,cAAc,KAAA,GAAW,OAAO,YAAY,MAAM;GAC5D,IAAI,MAAM,cAAc,KAAA,GAAW,OAAO,YAAY,MAAM;GAC5D;EACF,KAAK;GACH,OAAO,OAAO;GACd,IAAI,MAAM,QAAQ,KAAA,GAAW,OAAO,UAAU,MAAM;GACpD,IAAI,MAAM,QAAQ,KAAA,GAAW,OAAO,UAAU,MAAM;GACpD;EACF,KAAK;GACH,OAAO,OAAO;GACd,IAAI,MAAM,QAAQ,KAAA,GAAW,OAAO,UAAU,MAAM;GACpD,IAAI,MAAM,QAAQ,KAAA,GAAW,OAAO,UAAU,MAAM;GACpD;EACF,KAAK;GACH,OAAO,OAAO;GACd;EACF,KAAK;GACH,OAAO,OAAO;GACd,OAAO,SAAS;GAChB;EACF,KAAK;GACH,OAAO,OAAO;GACd;EACF,KAAK;EACL,KAAK;GACH,OAAO,OAAO;GAId,IAAI,CAAC,MAAM,aACT,OAAO,cAAc,iBAAiB,MAAM,WAAW;GAEzD;EACF,SACE,OAAO,OAAO;CAClB;CAEA,IAAI,MAAM,YAAY,KAAA,GACpB,OAAO,UAAU,MAAM;CAGzB,IAAI,MAAM,YAAY,OAAO,OAAO,SAAS,UAC3C,OAAO,OAAO,CAAC,OAAO,MAAM,MAAM;CAGpC,OAAO;AACT;AAEA,SAAS,qBAAqB,QAG5B;CACA,MAAM,aAA6C,CAAC;CACpD,MAAM,OAAuC,CAAC;CAE9C,OAAO,SAAS,OAAO,UAAU;EAG/B,MAAM,SAAS,SAAS;EACxB,KAAK,UAAU,sBAAsB,KAAK;EAC1C,WAAW,MAAM,QAAQ,EAAE,MAAM,WAAW,SAAS;CACvD,CAAC;CAED,OAAO;EAAE;EAAY;CAAK;AAC5B;;;;;;AAOA,SAAgB,qBACd,QACA,QACA,cACA,SAAqB,QACL;CAChB,MAAM,oBAAoB,iBAAyC;EACjE,MAAM;EACN,GAAI,WAAW,SAAS,EAAE,QAAQ,OAAO,IAAI,CAAC;EAC9C;CACF;CAEA,QAAQ,QAAR;EACE,KAAK,QACH,OAAO,sBAAsB;GAC3B,MAAM;GACN,YAAY;IACV,OAAO;KACL,MAAM;KACN,aAAa;KACb,SAAS;KACT,SAAS;KACT,SAAS;IACX;IACA,QAAQ;KACN,MAAM;KACN,aAAa;KACb,SAAS;KACT,SAAS;IACX;IACA,SAAS;KACP,MAAM;KACN,aAAa;IACf;IACA,OAAO;KACL,MAAM;KACN,aAAa;KACb,sBAAsB;IACxB;GACF;EACF,CAAC;EAEH,KAAK,OAIH,OAAO,sBAAsB;GAC3B,MAAM;GACN,OAAO,CAAC,EAAE,UAAU,CAAC,IAAI,EAAE,GAAG,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;GACpD,YAAY;IACV,IAAI,iBAAiB,iCAAiC;IACtD,MAAM;KACJ,MAAM;KACN,aAAa;IACf;GACF;EACF,CAAC;EAEH,KAAK,UAAU;GACb,MAAM,EAAE,YAAY,SAAS,qBAAqB,MAAM;GACxD,MAAM,WAAqB,CAAC;GAC5B,KAAK,MAAM,SAAS,QAClB,IAAI,MAAM,UAAU,SAAS,KAAK,MAAM,IAAI;GAE9C,OAAO,sBAAsB;IAC3B,MAAM;IACN;IACA,GAAI,SAAS,SAAS,IAAI,EAAE,SAAS,IAAI,CAAC;IAC1C,GAAI,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;GACxD,CAAC;EACH;EAEA,KAAK,UAAU;GACb,MAAM,EAAE,YAAY,iBAAiB,SACnC,qBAAqB,MAAM;GAK7B,OAAO,sBAAsB;IAC3B,MAAM;IACN,YAAA;KALA,IAAI,iBAAiB,4BAA4B;KACjD,GAAG;IAIH;IACA,UAAU,CAAC,IAAI;IACf,GAAI,OAAO,KAAK,IAAI,CAAC,CAAC,SAAS,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;GACxD,CAAC;EACH;EAEA,KAAK,UACH,OAAO,sBAAsB;GAC3B,MAAM;GACN,YAAY,EACV,IAAI,iBAAiB,4BAA4B,EACnD;GACA,UAAU,CAAC,IAAI;EACjB,CAAC;EAEH,SACE,OAAO,sBACL,6BACE,gBAAgB;GACd,OAAO;GACP,YAAY;GACZ,UAAU;GACV,QAAQ;GACR,YAAY;GACZ,WAAW;EACb,CACF,CACF;CACJ;AACF;;;;;AAMA,SAAS,eAAe,QAAgB,WAA2B;CACjE,QAAQ,QAAR;EACE,KAAK,QACH,OAAO,QAAQ,UAAU;EAC3B,KAAK,OACH,OAAO,kBAAkB,UAAU;EACrC,KAAK,UACH,OAAO,gBAAgB;EACzB,KAAK,UACH,OAAO,sBAAsB;EAC/B,KAAK,UACH,OAAO,YAAY,UAAU;EAC/B,SACE,OAAO,WAAW,OAAO,aAAa;CAC1C;AACF;;;;;;;AAQA,SAAgB,qBAAqB,MAOhB;CACnB,MAAM,EAAE,WAAW,QAAQ,YAAY;CACvC,MAAM,UAAU,KAAK,cAAc,UAAA,CAAW,YAAY;CAE1D,OAAO,QAAQ,KAAK,WAAW;EAC7B,MAAM,eAAe,KAAK,gBAAgB;EAC1C,MAAM,YAAY,cAAc,QAAQ,YAAY;EACpD,OAAO;GACL;GAGA,MAAM,GAAG,OAAO,GAAG,SAAS,YAAY;GACxC,aAAa,eAAe,QAAQ,SAAS;GAC7C,aAAa,qBACX,QACA,QACA,cACA,KAAK,MACP;GACA,UAAU,UAAU,WAAW;GAC/B,GAAG;EACL;CACF,CAAC;AACH;AAEA,SAAS,cACP,QACA,cAC6D;CAC7D,QAAQ,QAAR;EACE,KAAK;EACL,KAAK,OACH,OAAO;GAAE,QAAQ;GAAQ,YAAY;GAAM,WAAW;EAAM;EAC9D,KAAK,UACH,OAAO;GAAE,QAAQ;GAAS,YAAY;GAAO,WAAW;EAAM;EAChE,KAAK,UACH,OAAO;GAAE,QAAQ;GAAS,YAAY;GAAM,WAAW;EAAM;EAC/D,KAAK,UACH,OAAO;GAAE,QAAQ;GAAe,YAAY;GAAM,WAAW;EAAM;EACrE,SACE,OAAO;GACL,QAAQ,cAAc,UAAU;GAChC,YAAY,cAAc,cAAc;GACxC,WAAW,cAAc,aAAa;EACxC;CACJ;AACF;;AAGA,SAAgB,aAAa,QAAyB;CACpD,OAAO,aAAa,IAAI,MAAM;AAChC"}
|
|
1
|
+
{"version":3,"file":"tool-schema.js","names":[],"sources":["../../src/generators/tool-schema.ts"],"sourcesContent":["import {\n buildCustomActionInputSchema,\n CRUD_OPERATIONS,\n type CustomActionMetadata,\n type ToolEffect,\n} from './custom-action.js';\n\n/**\n * Transport-agnostic tool-descriptor builder (#1812, tracer).\n *\n * The single source of truth for turning a model's fields + exposed actions into\n * MCP-shaped tool descriptors (`{ name, description, inputSchema }`). This is the\n * shape both the Model Context Protocol AND Chrome's WebMCP\n * (`document.modelContext.registerTool`) consume — see\n * https://developer.chrome.com/docs/ai/webmcp.\n *\n * It is deliberately pure and free of `ObjectRegistry` / manifest coupling: it\n * takes a normalized {@link ToolFieldMeta}[] so BOTH callers can share it —\n * - `MCPGenerator` (`src/generators/mcp.ts`) for the Node stdio server, and\n * - the web-collections emitter (`src/vite-plugin/web-collections.ts`) for the\n * browser client-data runtime's WebMCP descriptors.\n *\n * Keeping one implementation removes the field-mapping drift risk the\n * \"three emission sites must agree\" contract in web-collections.ts already warns\n * about. The `fieldTypeToJsonSchema` / per-action skeletons below are ported\n * verbatim from mcp.ts's `fieldToMCPSchema` + `generateObjectTools`, so wiring\n * mcp.ts to call this helper is a mechanical, behavior-preserving refactor.\n */\n\n/**\n * A JSON Schema fragment. Values vary by field kind, so this is only ever\n * serialized into tool descriptors, never read back structurally.\n */\nexport type ToolJsonSchema = Record<string, unknown>;\n\n/** The only JSON Schema dialect emitted by generated MCP and WebMCP tools. */\nexport const JSON_SCHEMA_2020_12 =\n 'https://json-schema.org/draft/2020-12/schema';\n\n/**\n * Bounds for generated schemas. Field metadata is authored input, so it must\n * not turn a tools/list response into an unbounded composition or validation\n * workload. These limits are deliberately far above normal SMRT objects while\n * still keeping schemas comfortably inside MCP transport budgets.\n */\nexport const MCP_SCHEMA_LIMITS = {\n maxDepth: 16,\n maxNodes: 2_048,\n maxSerializedBytes: 65_536,\n} as const;\n\n/**\n * Apply the draft-2020-12 dialect and reject schemas that violate MCP's\n * bounded-composition contract. Generated schemas only ever reference local\n * `$defs`; external refs are neither emitted nor followed.\n */\nexport function finalizeMcpJsonSchema(schema: ToolJsonSchema): ToolJsonSchema {\n const finalized = {\n ...schema,\n $schema: JSON_SCHEMA_2020_12,\n };\n assertMcpJsonSchemaSafety(finalized);\n return finalized;\n}\n\n/**\n * Validate the resource envelope of an emitted schema without resolving refs.\n * This is intentionally structural rather than a general JSON-Schema\n * evaluator: the server already owns every schema it emits, and this guard\n * exists to keep authored metadata from introducing hostile shape growth.\n */\nexport function assertMcpJsonSchemaSafety(schema: ToolJsonSchema): void {\n let nodes = 0;\n const ancestors = new WeakSet<object>();\n\n const visit = (value: unknown, depth: number, key?: string): void => {\n nodes += 1;\n if (nodes > MCP_SCHEMA_LIMITS.maxNodes) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxNodes} nodes`,\n );\n }\n if (depth > MCP_SCHEMA_LIMITS.maxDepth) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxDepth} levels of depth`,\n );\n }\n if (key === '$ref') {\n if (\n typeof value !== 'string' ||\n !value.startsWith('#/$defs/') ||\n value.includes('://')\n ) {\n throw new Error(\n 'MCP JSON Schema may only use local #/$defs/ references',\n );\n }\n return;\n }\n if (value === null || typeof value !== 'object') return;\n if (ancestors.has(value)) {\n throw new Error('MCP JSON Schema must not contain cyclic values');\n }\n\n ancestors.add(value);\n if (Array.isArray(value)) {\n for (const entry of value) visit(entry, depth + 1);\n } else {\n for (const [childKey, child] of Object.entries(value)) {\n visit(child, depth + 1, childKey);\n }\n }\n ancestors.delete(value);\n };\n\n visit(schema, 0);\n\n let serialized: string;\n try {\n serialized = JSON.stringify(schema);\n } catch {\n throw new Error('MCP JSON Schema must be JSON-serializable');\n }\n if (\n new TextEncoder().encode(serialized).byteLength >\n MCP_SCHEMA_LIMITS.maxSerializedBytes\n ) {\n throw new Error(\n `MCP JSON Schema exceeds ${MCP_SCHEMA_LIMITS.maxSerializedBytes} serialized bytes`,\n );\n }\n}\n\n/**\n * Normalized field metadata — the intersection of what the runtime registry\n * (`FieldDefinition._meta`) and the build-time manifest (`WebFieldDefinition`)\n * can each supply. Callers flatten their own field source into this shape.\n */\nexport interface ToolFieldMeta {\n name: string;\n /** Field kind: text | integer | decimal | boolean | datetime | json | foreignKey | … */\n type: string;\n required?: boolean;\n description?: string;\n default?: unknown;\n maxLength?: number;\n minLength?: number;\n min?: number;\n max?: number;\n /** Field values may explicitly be null in the runtime/manifest contract. */\n nullable?: boolean;\n /** For `foreignKey`: the related class name, for the generated description. */\n related?: string;\n}\n\n/** Storage contract for the synthetic primary identifier. */\nexport type ToolIdType = 'uuid' | 'text';\n\n/** The CRUD verbs with dedicated input-schema skeletons; anything else is custom. */\nconst CRUD_ACTIONS = new Set<string>(CRUD_OPERATIONS);\n\nexport interface ToolRouteDescriptor {\n /** HTTP method emitted for the route. */\n method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n /** Whether the route targets one item or the whole collection. */\n scope: 'item' | 'collection';\n /** Route segments below the collection endpoint. Dynamic segments use `[x]`. */\n path: string[];\n /** Transport names rewritten by the tool schema (e.g. `actionId` → `id`). */\n parameterAliases?: Record<string, string>;\n /** The generated method accepts one `options` bag as its sole argument. */\n optionsBag?: boolean;\n}\n\n/** A single generated tool descriptor — the WebMCP / MCP tool shape. */\nexport interface ToolDescriptor {\n /** The action this tool performs (`list` | `get` | … | a custom method name). */\n action: string;\n /** Tool id, `${toolPrefix}_${action}` (e.g. `product_list`). */\n name: string;\n description: string;\n inputSchema: ToolJsonSchema;\n /** True when the declared effect is `read` → WebMCP `annotations.readOnlyHint`. */\n readOnly: boolean;\n /** Capability effect used by browser-tool exposure policy. */\n effect: ToolEffect;\n /** Whether repeating this tool with the same arguments is safe. */\n idempotent: boolean;\n /** Whether the tool may interact outside the SMRT application. */\n openWorld: boolean;\n /** Generated custom-route transport metadata, when the action has a route. */\n route?: ToolRouteDescriptor;\n}\n\n/**\n * Map one normalized field to its JSON-Schema fragment. Ported from\n * `MCPGenerator.fieldToMCPSchema` (mcp.ts) — keep the two in lockstep until\n * mcp.ts is switched to call this.\n */\nexport function fieldTypeToJsonSchema(field: ToolFieldMeta): ToolJsonSchema {\n const schema: ToolJsonSchema = {\n description: field.description || `${field.type} field`,\n };\n\n switch (field.type) {\n case 'text':\n schema.type = 'string';\n if (field.maxLength !== undefined) schema.maxLength = field.maxLength;\n if (field.minLength !== undefined) schema.minLength = field.minLength;\n break;\n case 'integer':\n schema.type = 'integer';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'decimal':\n schema.type = 'number';\n if (field.min !== undefined) schema.minimum = field.min;\n if (field.max !== undefined) schema.maximum = field.max;\n break;\n case 'boolean':\n schema.type = 'boolean';\n break;\n case 'datetime':\n schema.type = 'string';\n schema.format = 'date-time';\n break;\n case 'json':\n schema.type = 'object';\n break;\n case 'foreignKey':\n case 'crossPackageRef':\n schema.type = 'string';\n // The generic relation hint is a fallback only — an authored\n // `@field({ description })` wins (#2046 threads descriptions into web\n // tool descriptors; clobbering them here would strip the help text).\n if (!field.description) {\n schema.description = `ID of related ${field.related || 'object'}`;\n }\n break;\n default:\n schema.type = 'string';\n }\n\n if (field.default !== undefined) {\n schema.default = field.default;\n }\n\n if (field.nullable && typeof schema.type === 'string') {\n schema.type = [schema.type, 'null'];\n }\n\n return schema;\n}\n\nfunction buildFieldProperties(fields: ToolFieldMeta[]): {\n properties: Record<string, ToolJsonSchema>;\n defs: Record<string, ToolJsonSchema>;\n} {\n const properties: Record<string, ToolJsonSchema> = {};\n const defs: Record<string, ToolJsonSchema> = {};\n\n fields.forEach((field, index) => {\n // Numeric keys avoid JSON Pointer escaping and keep output deterministic\n // even for an authored field name containing `/` or `~`.\n const defKey = `field_${index}`;\n defs[defKey] = fieldTypeToJsonSchema(field);\n properties[field.name] = { $ref: `#/$defs/${defKey}` };\n });\n\n return { properties, defs };\n}\n\n/**\n * Build the `inputSchema` for one action. CRUD verbs get the fixed skeletons\n * ported from mcp.ts's `generateObjectTools`; any other action is treated as a\n * custom method taking `{ id, options }`.\n */\nexport function buildToolInputSchema(\n action: string,\n fields: ToolFieldMeta[],\n customAction?: CustomActionMetadata,\n idType: ToolIdType = 'uuid',\n): ToolJsonSchema {\n const identifierSchema = (description: string): ToolJsonSchema => ({\n type: 'string',\n ...(idType === 'uuid' ? { format: 'uuid' } : {}),\n description,\n });\n\n switch (action) {\n case 'list':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n limit: {\n type: 'integer',\n description: 'Maximum number of items to return',\n default: 50,\n minimum: 1,\n maximum: 1000,\n },\n offset: {\n type: 'integer',\n description: 'Number of items to skip',\n default: 0,\n minimum: 0,\n },\n orderBy: {\n type: 'string',\n description: 'Field to order by (e.g., \"created_at DESC\")',\n },\n where: {\n type: 'object',\n description: 'Filter conditions as key-value pairs',\n additionalProperties: true,\n },\n },\n });\n\n case 'get':\n // Either `id` OR `slug` identifies the object (collection.get resolves\n // both). The schema must require one of them just as the handler does,\n // while still allowing slug-only lookups.\n return finalizeMcpJsonSchema({\n type: 'object',\n anyOf: [{ required: ['id'] }, { required: ['slug'] }],\n properties: {\n id: identifierSchema('Unique identifier of the object'),\n slug: {\n type: 'string',\n description: 'URL-friendly identifier of the object',\n },\n },\n });\n\n case 'create': {\n const { properties, defs } = buildFieldProperties(fields);\n const required: string[] = [];\n for (const field of fields) {\n if (field.required) required.push(field.name);\n }\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'update': {\n const { properties: fieldProperties, defs } =\n buildFieldProperties(fields);\n const properties: Record<string, ToolJsonSchema> = {\n id: identifierSchema('ID of the object to update'),\n ...fieldProperties,\n };\n return finalizeMcpJsonSchema({\n type: 'object',\n properties,\n required: ['id'],\n ...(Object.keys(defs).length > 0 ? { $defs: defs } : {}),\n });\n }\n\n case 'delete':\n return finalizeMcpJsonSchema({\n type: 'object',\n properties: {\n id: identifierSchema('ID of the object to delete'),\n },\n required: ['id'],\n });\n\n default:\n return finalizeMcpJsonSchema(\n buildCustomActionInputSchema(\n customAction ?? {\n scope: 'item',\n idRequired: true,\n isStatic: false,\n effect: 'destructive',\n idempotent: false,\n openWorld: true,\n },\n ),\n );\n }\n}\n\n/**\n * Human-readable description for a tool, matching mcp.ts's phrasing so the Node\n * MCP and WebMCP surfaces read identically.\n */\nfunction describeAction(action: string, className: string): string {\n switch (action) {\n case 'list':\n return `List ${className} objects with optional filtering`;\n case 'get':\n return `Get a specific ${className} by ID or slug`;\n case 'create':\n return `Create a new ${className}`;\n case 'update':\n return `Update an existing ${className}`;\n case 'delete':\n return `Delete a ${className} by ID`;\n default:\n return `Execute ${action} action on ${className}`;\n }\n}\n\n/**\n * Build the full descriptor set for a model. `toolPrefix` defaults to the\n * lowercased class name so tool ids match the existing Node MCP surface exactly\n * (`product_list`, `invoice_record_payment`), giving one stable tool vocabulary\n * across MCP and WebMCP.\n */\nexport function buildToolDescriptors(opts: {\n className: string;\n fields: ToolFieldMeta[];\n actions: string[];\n customActions?: Record<string, CustomActionMetadata>;\n toolPrefix?: string;\n idType?: ToolIdType;\n}): ToolDescriptor[] {\n const { className, fields, actions } = opts;\n const prefix = (opts.toolPrefix ?? className).toLowerCase();\n\n return actions.map((action) => {\n const customAction = opts.customActions?.[action];\n const semantics = toolSemantics(action, customAction);\n return {\n action,\n // Custom method names can contain underscores; the runtime splits on the\n // FIRST underscore only (mcp.ts #1378), so a lowercased join is safe here.\n name: `${prefix}_${action}`.toLowerCase(),\n description: describeAction(action, className),\n inputSchema: buildToolInputSchema(\n action,\n fields,\n customAction,\n opts.idType,\n ),\n readOnly: semantics.effect === 'read',\n ...semantics,\n };\n });\n}\n\nfunction toolSemantics(\n action: string,\n customAction?: CustomActionMetadata,\n): Pick<ToolDescriptor, 'effect' | 'idempotent' | 'openWorld'> {\n switch (action) {\n case 'list':\n case 'get':\n return { effect: 'read', idempotent: true, openWorld: false };\n case 'create':\n return { effect: 'write', idempotent: false, openWorld: false };\n case 'update':\n return { effect: 'write', idempotent: true, openWorld: false };\n case 'delete':\n return { effect: 'destructive', idempotent: true, openWorld: false };\n default:\n return {\n effect: customAction?.effect ?? 'destructive',\n idempotent: customAction?.idempotent ?? false,\n openWorld: customAction?.openWorld ?? true,\n };\n }\n}\n\n/** True when `action` is one of the fixed CRUD verbs (vs. a custom method). */\nexport function isCrudAction(action: string): boolean {\n return CRUD_ACTIONS.has(action);\n}\n"],"mappings":"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"}
|
package/dist/generators.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, buildCustomActionInputSchema, buildCustomActionInvocationArgs, customActionParameterInputName, normalizeCustomActionFailure, resolveCustomActionMetadata } from "./generators/custom-action.js";
|
|
1
|
+
import { CRUD_OPERATIONS, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, buildCustomActionInputSchema, buildCustomActionInvocationArgs, customActionParameterInputName, isCrudOperation, isCrudToolAction, normalizeCustomActionFailure, resolveCustomActionMetadata } from "./generators/custom-action.js";
|
|
2
2
|
import { runWithTenantGate, setTenantEntryPointRunner } from "./generators/tenant-gate.js";
|
|
3
3
|
import { CLIGenerator, getCLIHandler, setupCLI } from "./generators/cli.js";
|
|
4
4
|
import { PRIVATE_READ_CACHE_CONTROL, canonicalReadRepresentation, computeBodyEtag, computeTableVersionEtag, conditionalJsonResponse, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, resolveReadCacheControl, resolveTenantEtagDiscriminator, versionConditionalResponse, warnIfSharedCacheNeutralized } from "./generators/conditional-get.js";
|
|
@@ -9,4 +9,4 @@ import { normalizeTypedHttpError } from "./generators/typed-http-error.js";
|
|
|
9
9
|
import { APIGenerator, computeRuntimeWebManifestHash, createRestServer, startRestServer } from "./generators/rest.js";
|
|
10
10
|
import { generateOpenAPISpec, setupSwaggerUI } from "./generators/swagger.js";
|
|
11
11
|
import "./generators/index.js";
|
|
12
|
-
export { APIGenerator, CLIGenerator, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, PRIVATE_READ_CACHE_CONTROL, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, canonicalReadRepresentation, changeEventSubscribersAtCapacity, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, createRestServer, customActionParameterInputName, eventStreamCapacityExceededResponse, generateOpenAPISpec, getCLIHandler, handlePlaybookPreflightRoute, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, isApiActionEnabledForObject, isRestActionRoutable, isRestRoutePublic, normalizeCustomActionFailure, normalizeEventsMaxSubscribers, normalizeTypedHttpError, resolveCustomActionMetadata, resolveMCPToolListCacheHint, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runWithTenantGate, setTenantEntryPointRunner, setupCLI, setupSwaggerUI, signalVisibleToTenant, sortMCPTools, startRestServer, tryReserveChangeEventSubscriberSlot, versionConditionalResponse, warnIfSharedCacheNeutralized };
|
|
12
|
+
export { APIGenerator, CLIGenerator, CRUD_OPERATIONS, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, PRIVATE_READ_CACHE_CONTROL, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, canonicalReadRepresentation, changeEventSubscribersAtCapacity, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, createRestServer, customActionParameterInputName, eventStreamCapacityExceededResponse, generateOpenAPISpec, getCLIHandler, handlePlaybookPreflightRoute, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, isApiActionEnabledForObject, isCrudOperation, isCrudToolAction, isRestActionRoutable, isRestRoutePublic, normalizeCustomActionFailure, normalizeEventsMaxSubscribers, normalizeTypedHttpError, resolveCustomActionMetadata, resolveMCPToolListCacheHint, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runWithTenantGate, setTenantEntryPointRunner, setupCLI, setupSwaggerUI, signalVisibleToTenant, sortMCPTools, startRestServer, tryReserveChangeEventSubscriberSlot, versionConditionalResponse, warnIfSharedCacheNeutralized };
|
package/dist/index.d.ts
CHANGED
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*/
|
|
18
18
|
export * from './adapters/index';
|
|
19
19
|
export { buildCascadePlan, type CascadePlan, type CascadePolymorphicReference, type CascadeReference, type CascadeRegistryView, type CascadeResult, cascadeReferencesTo, normalizeOnDelete, type OnDeleteAction, runCascadeDelete, } from './cascade';
|
|
20
|
-
export { type AppendChangeInput, appendChange, bumpChangeFeed, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, type ChangeFeedEntry, type ChangeFeedPage, type ChangeFeedRetention, type ChangeOperation, DEFAULT_CHANGES_LIMIT, ensureChangeFeedTable, type GetChangesOptions, getChangesSince, getTableVersion, getTenantScopedChangesSince, MAX_CHANGES_LIMIT, pruneChangeFeed, registerChangeFeedWriter, resetChangeFeedWarnings, unregisterChangeFeedWriter, } from './change-feed';
|
|
20
|
+
export { type AppendChangeInput, appendChange, bumpChangeFeed, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, type ChangeFeedEntry, type ChangeFeedPage, type ChangeFeedRetention, type ChangeOperation, DEFAULT_CHANGES_LIMIT, drainChangeFeed, ensureChangeFeedTable, type GetChangesOptions, getChangesSince, getTableVersion, getTenantScopedChangesSince, MAX_CHANGES_LIMIT, pruneChangeFeed, registerChangeFeedWriter, resetChangeFeedWarnings, unregisterChangeFeedWriter, } from './change-feed';
|
|
21
21
|
export { CHANGE_SIGNAL_CHANNEL, type ChangeSignal, type ChangeSignalListener, resetChangeSignals, stopChangeSignalListeners, subscribeToChangeSignals, } from './change-signals';
|
|
22
22
|
export { applyOneToManyChildAccessors, childAccessorName, } from './child-accessors';
|
|
23
23
|
export * from './class';
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -13,7 +13,7 @@ import { isEmbeddedDatabase, isPostgresDatabase, usesEmbeddedRevisionFallback, w
|
|
|
13
13
|
import { GlobalInterceptors, createInterceptorContext, resolveGetStringFilter } from "./interceptors.js";
|
|
14
14
|
import { detectEngine, generateDDLForEngine } from "./schema/ddl/index.js";
|
|
15
15
|
import { SYSTEM_TABLE_NAMES, getSystemTableShapes } from "./schema/system-table-shapes.js";
|
|
16
|
-
import { CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, DEFAULT_CHANGES_LIMIT, MAX_CHANGES_LIMIT, appendChange, bumpChangeFeed, ensureChangeFeedTable, getChangesSince, getTableVersion, getTenantScopedChangesSince, pruneChangeFeed, registerChangeFeedWriter, resetChangeFeedWarnings, unregisterChangeFeedWriter } from "./change-feed.js";
|
|
16
|
+
import { CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, DEFAULT_CHANGES_LIMIT, MAX_CHANGES_LIMIT, appendChange, bumpChangeFeed, drainChangeFeed, ensureChangeFeedTable, getChangesSince, getTableVersion, getTenantScopedChangesSince, pruneChangeFeed, registerChangeFeedWriter, resetChangeFeedWarnings, unregisterChangeFeedWriter } from "./change-feed.js";
|
|
17
17
|
import { applyOneToManyChildAccessors, childAccessorName } from "./child-accessors.js";
|
|
18
18
|
import { config } from "./config.js";
|
|
19
19
|
import { importOptionalDependency, registerOptionalDependency } from "./lazy-external.js";
|
|
@@ -32,7 +32,7 @@ import { applyPendingDecoratorRegistrations, registerCompatibleFieldDecorator }
|
|
|
32
32
|
import { createQualifiedName, getClassName, getPackageFromQualifiedName, isFromPackage, isQualifiedName, isType, parseQualifiedName, qualifiedNamesEqual } from "./utils/qualified-names.js";
|
|
33
33
|
import { clone, getAdapterInfo, isValid, parse, safeParse, safeStringify, stringify } from "./utils/json.js";
|
|
34
34
|
import { convertTypeToJsonSchema, generateToolFromMethod, generateToolManifest, shouldIncludeMethod } from "./tools/tool-generator.js";
|
|
35
|
-
import { SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, buildCustomActionInputSchema, buildCustomActionInvocationArgs, customActionParameterInputName, normalizeCustomActionFailure, resolveCustomActionMetadata } from "./generators/custom-action.js";
|
|
35
|
+
import { CRUD_OPERATIONS, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, buildCustomActionInputSchema, buildCustomActionInvocationArgs, customActionParameterInputName, isCrudOperation, isCrudToolAction, normalizeCustomActionFailure, resolveCustomActionMetadata } from "./generators/custom-action.js";
|
|
36
36
|
import { ManifestGenerator } from "./scanner/manifest-generator.js";
|
|
37
37
|
import { ManifestManager } from "./manifest/manager.js";
|
|
38
38
|
import { discoverManifestEntry, findManifestEntryByQualifiedName, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync } from "./manifest/manifest-loader.js";
|
|
@@ -42,6 +42,7 @@ import { resetVerifiedTables } from "./table-cache.js";
|
|
|
42
42
|
import { executeToolCall, executeToolCalls, formatToolResults, validateToolCall } from "./tools/tool-executor.js";
|
|
43
43
|
import { SmrtObject } from "./object.js";
|
|
44
44
|
import { SMRT_COLLECTION_BASE_NAMES, isSmrtCollectionExtendsName } from "./registry/collection-resolution.js";
|
|
45
|
+
import { isFrameworkBaseClass } from "./registry/framework-base-classes.js";
|
|
45
46
|
import { ObjectRegistry, smrt } from "./registry.js";
|
|
46
47
|
import { DEFAULT_FACET_LIMIT, MAX_FACET_FIELDS, MAX_FACET_LIMIT, MAX_STI_READ_SCOPE_TYPES, SmrtCollection } from "./collection.js";
|
|
47
48
|
import { executeCollectionReadPlan } from "./collection-read-plan.js";
|
|
@@ -87,4 +88,4 @@ import "./system/index.js";
|
|
|
87
88
|
import { getTestDatabase } from "./testing/database.js";
|
|
88
89
|
import "./tools/index.js";
|
|
89
90
|
import { smrtPlugin } from "./vite-plugin/index.js";
|
|
90
|
-
export { AGENT_SURFACE_HASH_PREFIX, AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CLIGenerator, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_FACET_LIMIT, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DEFAULT_RETENTION_POLICY, DataQueryValidationError, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, ErrorUtils, FilesystemError, GlobalInterceptors, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, MAX_FACET_FIELDS, MAX_FACET_LIMIT, MAX_LIST_LIMIT, MAX_STI_READ_SCOPE_TYPES, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, POSTGRES_REVISION_GUARD_EXPRESSION, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SYSTEM_TABLE_NAMES, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildCascadePlan, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, bumpChangeFeed, canonicalReadRepresentation, canonicalizeDataQuery, cascadeReferencesTo, changeEventSubscribersAtCapacity, checkLiveSchemaParity, childAccessorName, classifyDatabaseError, classifyDialectMessage, clearRetentionTasks, clone, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createDataQueryFingerprint, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, detectEngine, discoverManifestEntry, ensureBootstrapSystemTableCompatibility, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, ensureSystemTables, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeToolCall, executeToolCalls, field, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getCLIHandler, getCacheGeneration, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getRetentionTasks, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, handlePlaybookPreflightRoute, hasActionableChanges, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isApiActionEnabledForObject, isDatabaseInterface, isDeterministicDatabaseError, isEmbeddedDatabase, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isPostgresDatabase, isQualifiedName, isRestActionRoutable, isRestRoutePublic, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema, normalizeEventsMaxSubscribers, normalizeOnDelete, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planForeignKeyCreation, planPostgresSystemTimestampMigrations, postgresRevisionCandidates, postgresRevisionCondition, processSyncApplyBatch, pruneAiUsage, pruneChangeFeed, pruneExpiredContexts, qualifiedNamesEqual, readAgentModuleDocs, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, registerRetentionTask, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDispatchTenantId, resolveDispatchTenantScope, resolveGetStringFilter, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runCascadeDelete, runRetentionSweep, runWithTenantGate, safeParse, safeStringify, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupCLI, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, sortMCPTools, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, unregisterRetentionTask, usesEmbeddedRevisionFallback, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized, withEmbeddedWriteQueue, withEmbeddedWriteTransaction };
|
|
91
|
+
export { AGENT_SURFACE_HASH_PREFIX, AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CLIGenerator, CRUD_OPERATIONS, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_FACET_LIMIT, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DEFAULT_RETENTION_POLICY, DataQueryValidationError, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, ErrorUtils, FilesystemError, GlobalInterceptors, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, MAX_FACET_FIELDS, MAX_FACET_LIMIT, MAX_LIST_LIMIT, MAX_STI_READ_SCOPE_TYPES, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, POSTGRES_REVISION_GUARD_EXPRESSION, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SYSTEM_TABLE_NAMES, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildCascadePlan, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, bumpChangeFeed, canonicalReadRepresentation, canonicalizeDataQuery, cascadeReferencesTo, changeEventSubscribersAtCapacity, checkLiveSchemaParity, childAccessorName, classifyDatabaseError, classifyDialectMessage, clearRetentionTasks, clone, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createDataQueryFingerprint, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, detectEngine, discoverManifestEntry, drainChangeFeed, ensureBootstrapSystemTableCompatibility, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, ensureSystemTables, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeToolCall, executeToolCalls, field, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getCLIHandler, getCacheGeneration, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getRetentionTasks, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, handlePlaybookPreflightRoute, hasActionableChanges, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isApiActionEnabledForObject, isCrudOperation, isCrudToolAction, isDatabaseInterface, isDeterministicDatabaseError, isEmbeddedDatabase, isFrameworkBaseClass, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isPostgresDatabase, isQualifiedName, isRestActionRoutable, isRestRoutePublic, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema, normalizeEventsMaxSubscribers, normalizeOnDelete, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planForeignKeyCreation, planPostgresSystemTimestampMigrations, postgresRevisionCandidates, postgresRevisionCondition, processSyncApplyBatch, pruneAiUsage, pruneChangeFeed, pruneExpiredContexts, qualifiedNamesEqual, readAgentModuleDocs, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, registerRetentionTask, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDispatchTenantId, resolveDispatchTenantScope, resolveGetStringFilter, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runCascadeDelete, runRetentionSweep, runWithTenantGate, safeParse, safeStringify, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupCLI, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, sortMCPTools, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, unregisterRetentionTask, usesEmbeddedRevisionFallback, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized, withEmbeddedWriteQueue, withEmbeddedWriteTransaction };
|
package/dist/knowledge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EAGrB,uBAAuB,EAEvB,wBAAwB,EAIzB,MAAM,2BAA2B,CAAC;
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EAGrB,uBAAuB,EAEvB,wBAAwB,EAIzB,MAAM,2BAA2B,CAAC;AASnC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAG5B;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,2BAA2B,CAAC;CAC5C;AAmDD,yFAAyF;AACzF,eAAO,MAAM,sBAAsB,eAAe,CAAC;AAEnD;;;GAGG;AACH,eAAO,MAAM,yBAAyB,kBAAkB,CAAC;AAEzD;;;;;;;;;;GAUG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,EAAE,CAgBV;AAED,yEAAyE;AACzE,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,wBAAwB,EAAE,CAM5B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,2BAA2B,GACnC,uBAAuB,CAkFzB"}
|
package/dist/knowledge.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { toSnakeCase } from "./utils/naming.js";
|
|
2
|
+
import { CRUD_OPERATIONS, isCrudOperation, isCrudToolAction, isFrameworkLifecycleMethod, resolveCustomActionMetadata } from "./generators/custom-action.js";
|
|
3
|
+
import { isFrameworkBaseClass } from "./registry/framework-base-classes.js";
|
|
2
4
|
import { createHash } from "node:crypto";
|
|
3
5
|
import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
|
|
4
6
|
import { basename, join, relative, resolve, sep } from "node:path";
|
|
@@ -31,13 +33,15 @@ var RELATIONSHIP_FIELD_TYPES = /* @__PURE__ */ new Set([
|
|
|
31
33
|
"oneToMany",
|
|
32
34
|
"manyToMany"
|
|
33
35
|
]);
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
36
|
+
/**
|
|
37
|
+
* The generated CRUD verbs, derived from the generators' own list so both
|
|
38
|
+
* halves of this projection — which operations are ENUMERATED
|
|
39
|
+
* (`resolveCrudOperations`) and which method names are RESERVED
|
|
40
|
+
* (`reservesCrudName`) — move together. Reading one from `CRUD_OPERATIONS` and
|
|
41
|
+
* the other from a local copy would let a new verb be suppressed as a custom
|
|
42
|
+
* method while never being added as CRUD, dropping the surface entirely.
|
|
43
|
+
*/
|
|
44
|
+
var STANDARD_OPERATIONS = CRUD_OPERATIONS;
|
|
41
45
|
/**
|
|
42
46
|
* Markdown inline links whose target is a `.md` file — `[label](agents/x.md)`,
|
|
43
47
|
* tolerating an `#anchor` and a `"title"`. This is how a package registers a
|
|
@@ -104,7 +108,7 @@ function buildDomainKnowledgeManifest(options) {
|
|
|
104
108
|
...record(packageJson.peerDependencies)
|
|
105
109
|
};
|
|
106
110
|
const manifestObjects = Object.values(options.manifest.objects).filter((object) => object.decoratorConfig?.knowledge !== false);
|
|
107
|
-
const objects = manifestObjects.map((object) => buildKnowledgeObject(object));
|
|
111
|
+
const objects = manifestObjects.map((object) => buildKnowledgeObject(object, options.manifest));
|
|
108
112
|
const surfaces = objects.flatMap((object) => object.surfaces);
|
|
109
113
|
const manifestJson = stableJson(normalizeManifestForHash(options.manifest));
|
|
110
114
|
const agentSurface = normalizeAgentSurface(options.agentSurface);
|
|
@@ -161,7 +165,7 @@ function agentSurfaceSourcePaths(surface) {
|
|
|
161
165
|
for (const diagnostic of surface.diagnostics) paths.add(diagnostic.sourceFile);
|
|
162
166
|
return [...paths].sort();
|
|
163
167
|
}
|
|
164
|
-
function buildKnowledgeObject(object) {
|
|
168
|
+
function buildKnowledgeObject(object, manifest) {
|
|
165
169
|
const knowledge = typeof object.decoratorConfig?.knowledge === "object" ? object.decoratorConfig.knowledge : {};
|
|
166
170
|
const fields = Object.entries(object.fields).filter(([, field]) => !isSensitiveField(field)).map(([name, field]) => {
|
|
167
171
|
const defaultValue = fieldValue(field, "default");
|
|
@@ -202,7 +206,7 @@ function buildKnowledgeObject(object) {
|
|
|
202
206
|
tenant,
|
|
203
207
|
tableStrategy: object.decoratorConfig?.tableStrategy,
|
|
204
208
|
conflictColumns: conflictColumns && conflictColumns.length > 0 ? conflictColumns : void 0,
|
|
205
|
-
surfaces: objectSurfaces(object),
|
|
209
|
+
surfaces: objectSurfaces(object, manifest),
|
|
206
210
|
relationshipFeatures: relationshipFeatures(object, fields),
|
|
207
211
|
tags: knowledge.tags ?? [],
|
|
208
212
|
summary: knowledge.summary,
|
|
@@ -280,33 +284,189 @@ function methodSignatures(object) {
|
|
|
280
284
|
}));
|
|
281
285
|
return signatures.length > 0 ? signatures : void 0;
|
|
282
286
|
}
|
|
283
|
-
function objectSurfaces(object) {
|
|
287
|
+
function objectSurfaces(object, manifest) {
|
|
284
288
|
return [
|
|
285
|
-
...configuredSurfaces("api", object),
|
|
286
|
-
...configuredSurfaces("cli", object),
|
|
287
|
-
...configuredSurfaces("mcp", object),
|
|
289
|
+
...configuredSurfaces("api", object, manifest),
|
|
290
|
+
...configuredSurfaces("cli", object, manifest),
|
|
291
|
+
...configuredSurfaces("mcp", object, manifest),
|
|
288
292
|
...aiSurfaces(object)
|
|
289
293
|
];
|
|
290
294
|
}
|
|
291
|
-
function configuredSurfaces(kind, object) {
|
|
295
|
+
function configuredSurfaces(kind, object, manifest) {
|
|
292
296
|
const config = object.decoratorConfig?.[kind];
|
|
293
|
-
|
|
294
|
-
return configuredOperations(config).map((operation) =>
|
|
295
|
-
kind,
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
297
|
+
const collectionClass = isSurfaceCollectionClass(manifest, object);
|
|
298
|
+
return configuredOperations(kind, object, config, manifest).map((operation) => {
|
|
299
|
+
const route = kind === "api" && !STANDARD_OPERATIONS.includes(operation) ? apiCustomRoute(object, operation, collectionClass) : void 0;
|
|
300
|
+
return {
|
|
301
|
+
kind,
|
|
302
|
+
name: surfaceName(kind, object, operation),
|
|
303
|
+
operation,
|
|
304
|
+
objectName: object.qualifiedName ?? object.className,
|
|
305
|
+
path: kind === "api" ? apiPath(object, operation, route) : void 0,
|
|
306
|
+
method: kind === "api" ? apiMethod(operation, route) : void 0
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
/**
|
|
311
|
+
* `MCPGenerator.buildCustomActionTool()` registers a custom-action tool as
|
|
312
|
+
* `` `${lowerName}_${methodName}`.toLowerCase() `` — lowercasing the WHOLE
|
|
313
|
+
* joined string, not just the object-name prefix. A CRUD verb is already
|
|
314
|
+
* lowercase so this is a no-op there, but a camelCase custom method name
|
|
315
|
+
* (`findByDimensions`) would otherwise report a surface `name` the real tool
|
|
316
|
+
* is never registered under. `CLIGenerator.listCommands()` does not
|
|
317
|
+
* lowercase the method half of its command string, so `cli` keeps the
|
|
318
|
+
* operation as-authored.
|
|
319
|
+
*
|
|
320
|
+
* Note the shapes differ from the transports' own: a `cli` surface `name`
|
|
321
|
+
* here is `object_operation`, while the command a user types is
|
|
322
|
+
* `object:operation`. `operation` is the field to correlate on.
|
|
323
|
+
*/
|
|
324
|
+
function surfaceName(kind, object, operation) {
|
|
325
|
+
if (kind === "api") return `${object.collection}.${operation}`;
|
|
326
|
+
const name = `${object.className.toLowerCase()}_${operation}`;
|
|
327
|
+
return kind === "mcp" ? name.toLowerCase() : name;
|
|
328
|
+
}
|
|
329
|
+
/**
|
|
330
|
+
* A hand-written `SmrtCollection` subclass (`class WidgetCollection extends
|
|
331
|
+
* SmrtCollection<Widget>`) is discovered structurally by the scanner and
|
|
332
|
+
* lands in the manifest even without its own `@smrt()` decorator, so it never
|
|
333
|
+
* registers with `ObjectRegistry`. `MCPGenerator`/`CLIGenerator` iterate
|
|
334
|
+
* `ObjectRegistry`, not the manifest, so such a class never gets its own
|
|
335
|
+
* MCP tools or CLI commands — only its collection-scoped custom actions get
|
|
336
|
+
* REST routes. Reporting full CRUD for it here would over-report a surface
|
|
337
|
+
* that does not exist, trading the #2619 under-report for a new false
|
|
338
|
+
* positive.
|
|
339
|
+
*
|
|
340
|
+
* A deeper subclass (`SpecialCollection extends WidgetCollection`) carries no
|
|
341
|
+
* `extendsTypeArg` of its own, so this walks the extends chain through the
|
|
342
|
+
* manifest — mirroring `isCollectionManifestClass` in
|
|
343
|
+
* `vite-plugin/web-collections.ts` (kept as a separate, lean implementation
|
|
344
|
+
* here rather than imported: that module pulls in the full SvelteKit route
|
|
345
|
+
* generator transitively, which would balloon the standalone `./knowledge`
|
|
346
|
+
* build entry for a ~15-line check).
|
|
347
|
+
*/
|
|
348
|
+
function isSurfaceCollectionClass(manifest, object, seen = /* @__PURE__ */ new Set()) {
|
|
349
|
+
if (object.extends === "SmrtCollection" || object.extendsTypeArg) return true;
|
|
350
|
+
const parentName = object.extendsQualified || object.extends;
|
|
351
|
+
if (!parentName || seen.has(parentName)) return false;
|
|
352
|
+
seen.add(parentName);
|
|
353
|
+
const parent = findManifestObjectByName(manifest, parentName, object);
|
|
354
|
+
return parent ? isSurfaceCollectionClass(manifest, parent, seen) : false;
|
|
355
|
+
}
|
|
356
|
+
function findManifestObjectByName(manifest, name, owner) {
|
|
357
|
+
const entries = Object.entries(manifest.objects);
|
|
358
|
+
if (name.includes(":")) {
|
|
359
|
+
const exact = entries.find(([key, candidate]) => (candidate.qualifiedName ?? key) === name);
|
|
360
|
+
if (exact) return exact[1];
|
|
361
|
+
}
|
|
362
|
+
const ownerKey = entries.find(([, candidate]) => candidate === owner)?.[0];
|
|
363
|
+
const ownerPackage = manifestObjectPackage(owner, ownerKey);
|
|
364
|
+
if (ownerPackage) {
|
|
365
|
+
const packageLocal = entries.find(([key, candidate]) => manifestObjectPackage(candidate, key) === ownerPackage && candidate.className === name);
|
|
366
|
+
if (packageLocal) return packageLocal[1];
|
|
367
|
+
}
|
|
368
|
+
return entries.find(([, candidate]) => candidate.className === name)?.[1];
|
|
302
369
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
370
|
+
/**
|
|
371
|
+
* An object's owning package. `packageName` is optional on
|
|
372
|
+
* `SmartObjectDefinition` (older manifests and hand-built fixtures omit it),
|
|
373
|
+
* so fall back to the package half of the qualified name — and, when that is
|
|
374
|
+
* absent too, of the manifest key, which is qualified for every entry the
|
|
375
|
+
* scanner writes. Mirrors `manifestObjectPackage` in
|
|
376
|
+
* `vite-plugin/web-collections.ts`, key fallback included: without it an
|
|
377
|
+
* entry carrying only a qualified key resolves no package at all, the
|
|
378
|
+
* same-package preference is skipped, and a duplicate simple name can pick
|
|
379
|
+
* the wrong parent.
|
|
380
|
+
*/
|
|
381
|
+
function manifestObjectPackage(object, manifestKey) {
|
|
382
|
+
if (object.packageName) return object.packageName;
|
|
383
|
+
const qualifiedName = object.qualifiedName ?? manifestKey;
|
|
384
|
+
const separator = qualifiedName?.lastIndexOf(":") ?? -1;
|
|
385
|
+
return separator > 0 ? qualifiedName?.slice(0, separator) : void 0;
|
|
386
|
+
}
|
|
387
|
+
/**
|
|
388
|
+
* Operations exposed for one object's `api`/`cli`/`mcp` surface, derived from
|
|
389
|
+
* the same defaults `APIGenerator`/`CLIGenerator`/`MCPGenerator` apply rather
|
|
390
|
+
* than from the presence of a config key (#2619): an omitted config is full
|
|
391
|
+
* CRUD, not a closed surface — an `include` list, when present, is the
|
|
392
|
+
* COMPLETE allowlist for custom methods too; without one, every public
|
|
393
|
+
* method not explicitly excluded is exposed by default. Only `config ===
|
|
394
|
+
* false` closes the surface entirely.
|
|
395
|
+
*
|
|
396
|
+
* Custom (non-CRUD, public) method gating is NOT identical across the three
|
|
397
|
+
* kinds. `CLIGenerator.listCommands()`/`assertCommandExposed()` additionally
|
|
398
|
+
* refuse a framework lifecycle method (`save`, `initialize`, ...) even when a
|
|
399
|
+
* class declares its own override — it is the mechanism behind generated
|
|
400
|
+
* CRUD, not a distinct action (#2638) — and `resolveCustomMethodNames()`
|
|
401
|
+
* below mirrors that same `isFrameworkLifecycleMethod()` check for
|
|
402
|
+
* `kind === 'cli'` only (#2657). `api`/`mcp` remain ungated on this: neither
|
|
403
|
+
* generator changed in #2650, the mcp.ts wiring is separate #2638 scope still
|
|
404
|
+
* pending, and the api-surface fix is a PR #2651 recommendation, not yet
|
|
405
|
+
* implemented.
|
|
406
|
+
*
|
|
407
|
+
* This `cli` projection models `CLIGenerator` (`generators/cli.ts`), not the
|
|
408
|
+
* shipped local CLI transport (`@happyvertical/smrt-cli`'s
|
|
409
|
+
* `cli-generator.ts`, the `smrt <object>:<action>` binary): that generator
|
|
410
|
+
* does not gate on `isFrameworkLifecycleMethod()` today, so a locally
|
|
411
|
+
* overridden lifecycle method the artifact now reports as absent can still
|
|
412
|
+
* be invoked there. Retargeting this projection at the shipped binary is a
|
|
413
|
+
* contract change tracked on #2664, not part of this fix.
|
|
414
|
+
*/
|
|
415
|
+
function configuredOperations(kind, object, config, manifest) {
|
|
416
|
+
if (config === false) return [];
|
|
417
|
+
if (isFrameworkBaseClass(object.className, object.packageName)) return [];
|
|
418
|
+
const collectionClass = isSurfaceCollectionClass(manifest, object);
|
|
419
|
+
const crud = collectionClass ? [] : resolveCrudOperations(config);
|
|
420
|
+
const custom = resolveCustomMethodNames(Object.entries(object.methods), config, kind);
|
|
421
|
+
const eligible = kind === "api" ? custom.filter((operation) => apiCustomRoute(object, operation, collectionClass) !== void 0) : custom;
|
|
422
|
+
return [...crud, ...eligible];
|
|
423
|
+
}
|
|
424
|
+
function resolveCrudOperations(config) {
|
|
425
|
+
const { include, exclude } = includeExcludeConfig(config);
|
|
426
|
+
const base = include ? STANDARD_OPERATIONS.filter((operation) => include.includes(operation)) : [...STANDARD_OPERATIONS];
|
|
427
|
+
if (!exclude || exclude.length === 0) return base;
|
|
428
|
+
const excluded = new Set(exclude);
|
|
429
|
+
return base.filter((operation) => !excluded.has(operation));
|
|
430
|
+
}
|
|
431
|
+
function resolveCustomMethodNames(methods, config, kind) {
|
|
432
|
+
const { include, exclude } = includeExcludeConfig(config);
|
|
433
|
+
const excluded = new Set(exclude ?? []);
|
|
434
|
+
const names = [];
|
|
435
|
+
for (const [name, method] of methods) {
|
|
436
|
+
if (reservesCrudName(kind, name)) continue;
|
|
437
|
+
if (kind === "cli" && isFrameworkLifecycleMethod(name)) continue;
|
|
438
|
+
if (!method.isPublic) continue;
|
|
439
|
+
if (excluded.has(name)) continue;
|
|
440
|
+
if (include !== void 0 && !include.includes(name)) continue;
|
|
441
|
+
names.push(name);
|
|
442
|
+
}
|
|
443
|
+
return names;
|
|
444
|
+
}
|
|
445
|
+
/**
|
|
446
|
+
* Whether `kind` reserves `name` for its generated CRUD operation, so the
|
|
447
|
+
* method behind it is not reported as a distinct surface.
|
|
448
|
+
*
|
|
449
|
+
* MCP folds case: its tool ids are lowercased whole
|
|
450
|
+
* (`` `${object}_${method}`.toLowerCase() ``), so a method named `List` lands on
|
|
451
|
+
* the `${object}_list` identifier the CRUD tool already owns and
|
|
452
|
+
* `MCPGenerator` emits no separate tool for it (#2646). REST and the CLI keep
|
|
453
|
+
* the declared casing in their route/command names, so only an exact match is
|
|
454
|
+
* reserved there.
|
|
455
|
+
*
|
|
456
|
+
* Reads the emitters' own predicates rather than re-testing the verb list, and
|
|
457
|
+
* `STANDARD_OPERATIONS` derives from `CRUD_OPERATIONS`, so a change to the
|
|
458
|
+
* shared list reaches both halves of this projection together.
|
|
459
|
+
*/
|
|
460
|
+
function reservesCrudName(kind, name) {
|
|
461
|
+
return kind === "mcp" ? isCrudToolAction(name) : isCrudOperation(name);
|
|
462
|
+
}
|
|
463
|
+
function includeExcludeConfig(config) {
|
|
464
|
+
if (typeof config !== "object" || config === null || Array.isArray(config)) return {};
|
|
465
|
+
const record = config;
|
|
466
|
+
return {
|
|
467
|
+
include: Array.isArray(record.include) ? record.include : void 0,
|
|
468
|
+
exclude: Array.isArray(record.exclude) ? record.exclude : void 0
|
|
469
|
+
};
|
|
310
470
|
}
|
|
311
471
|
function aiSurfaces(object) {
|
|
312
472
|
return (object.tools ?? []).map((tool) => ({
|
|
@@ -317,14 +477,102 @@ function aiSurfaces(object) {
|
|
|
317
477
|
objectName: object.qualifiedName ?? object.className
|
|
318
478
|
}));
|
|
319
479
|
}
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
480
|
+
/**
|
|
481
|
+
* Resolve a custom (non-CRUD) action's REST route the way the generator does,
|
|
482
|
+
* or `undefined` when no route is emitted for it at all.
|
|
483
|
+
*
|
|
484
|
+
* A custom action's path is NOT `/collection/action`: `generateRoutesForObject`
|
|
485
|
+
* nests an item-scoped action under `[id]`, and an instance method defaults to
|
|
486
|
+
* item scope. Reporting the collection-shaped path for every public instance
|
|
487
|
+
* method would advertise endpoints that do not exist — the exact failure this
|
|
488
|
+
* projection exists to avoid. Scope comes from the shared
|
|
489
|
+
* `resolveCustomActionMetadata`, the same resolver the REST, CLI, MCP, and
|
|
490
|
+
* WebMCP paths use, so a `routes` override cannot drift between them.
|
|
491
|
+
*
|
|
492
|
+
* `kebabRoutes` is a Vite-plugin option rather than manifest data, so an
|
|
493
|
+
* explicit `routes[action].path` is honored but the generator's optional
|
|
494
|
+
* kebab-casing of a derived segment is not visible here.
|
|
495
|
+
*/
|
|
496
|
+
function apiCustomRoute(object, operation, collectionClass) {
|
|
497
|
+
const method = object.methods[operation];
|
|
498
|
+
const apiConfig = object.decoratorConfig?.api;
|
|
499
|
+
const scope = resolveActionScope(operation, method, apiConfig, collectionClass || method?.isStatic ? "collection" : "item");
|
|
500
|
+
if (collectionClass) {
|
|
501
|
+
if (scope !== "collection") return void 0;
|
|
502
|
+
} else if (scope === "collection" && !method?.isStatic) return;
|
|
503
|
+
const route = customRouteConfig(apiConfig, operation);
|
|
504
|
+
const overridden = typeof route?.path === "string" ? route.path.split("/").map((segment) => segment.trim()).filter(Boolean) : [];
|
|
505
|
+
return {
|
|
506
|
+
scope,
|
|
507
|
+
segments: overridden.length > 0 ? overridden : [operation],
|
|
508
|
+
method: normalizeApiMethod(route?.method)
|
|
509
|
+
};
|
|
510
|
+
}
|
|
511
|
+
/**
|
|
512
|
+
* The shared resolver validates as it resolves — a `routes` entry declaring
|
|
513
|
+
* `effect: 'read'` on a PUT/PATCH/DELETE route throws by design. This
|
|
514
|
+
* projection reads untrusted scanned config and must not fail the whole
|
|
515
|
+
* knowledge build for one malformed action (same defensive stance as
|
|
516
|
+
* {@link includeExcludeConfig}), so fall back to the receiver the method
|
|
517
|
+
* itself dictates — which a route-only override cannot change anyway.
|
|
518
|
+
*/
|
|
519
|
+
function resolveActionScope(operation, method, apiConfig, defaultScope) {
|
|
520
|
+
try {
|
|
521
|
+
return resolveCustomActionMetadata({
|
|
522
|
+
actionName: operation,
|
|
523
|
+
method,
|
|
524
|
+
apiConfig,
|
|
525
|
+
defaultScope
|
|
526
|
+
}).scope;
|
|
527
|
+
} catch {
|
|
528
|
+
return defaultScope;
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
function customRouteConfig(apiConfig, operation) {
|
|
532
|
+
if (typeof apiConfig !== "object" || apiConfig === null) return void 0;
|
|
533
|
+
const routes = apiConfig.routes;
|
|
534
|
+
if (typeof routes !== "object" || routes === null) return void 0;
|
|
535
|
+
const route = routes[operation];
|
|
536
|
+
return typeof route === "object" && route !== null ? route : void 0;
|
|
537
|
+
}
|
|
538
|
+
/** Mirrors `normalizeApiHttpMethod` in `vite-plugin/sveltekit-generator.ts`. */
|
|
539
|
+
function normalizeApiMethod(method) {
|
|
540
|
+
const normalized = typeof method === "string" ? method.toUpperCase() : void 0;
|
|
541
|
+
switch (normalized) {
|
|
542
|
+
case "GET":
|
|
543
|
+
case "POST":
|
|
544
|
+
case "PUT":
|
|
545
|
+
case "PATCH":
|
|
546
|
+
case "DELETE": return normalized;
|
|
547
|
+
default: return "POST";
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
/**
|
|
551
|
+
* The collection segment of a generated REST route.
|
|
552
|
+
*
|
|
553
|
+
* `generateRoutesForObject` builds its route directory from
|
|
554
|
+
* `objectDef.collection` verbatim, and the runtime dispatcher in
|
|
555
|
+
* `generators/rest.ts` matches the URL segment against `info.collection`
|
|
556
|
+
* verbatim, so this reports that and nothing else (#2630).
|
|
557
|
+
*
|
|
558
|
+
* In particular it does NOT read `api.path`, which configures a different
|
|
559
|
+
* surface: `@happyvertical/smrt-agents`' own agent-facing route map derives
|
|
560
|
+
* `api.path ?? tableName.replace(/_/g, '-')`. Honoring it here produced a
|
|
561
|
+
* hybrid — `api.path` over `collection` — that matched neither transport and
|
|
562
|
+
* named endpoints that 404 on both.
|
|
563
|
+
*/
|
|
564
|
+
function apiCollectionSegment(object) {
|
|
565
|
+
return object.collection;
|
|
566
|
+
}
|
|
567
|
+
function apiPath(object, operation, route) {
|
|
568
|
+
const configuredPath = apiCollectionSegment(object);
|
|
569
|
+
if (route) return `${route.scope === "collection" ? `/${configuredPath}` : `/${configuredPath}/[id]`}/${route.segments.join("/")}`;
|
|
323
570
|
if (operation === "list" || operation === "create") return `/${configuredPath}`;
|
|
324
571
|
if (STANDARD_OPERATIONS.includes(operation)) return `/${configuredPath}/[id]`;
|
|
325
572
|
return `/${configuredPath}/${operation}`;
|
|
326
573
|
}
|
|
327
|
-
function apiMethod(operation) {
|
|
574
|
+
function apiMethod(operation, route) {
|
|
575
|
+
if (route) return route.method;
|
|
328
576
|
switch (operation) {
|
|
329
577
|
case "list":
|
|
330
578
|
case "get": return "GET";
|