@happyvertical/smrt-core 0.43.3 → 0.43.5

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.
Files changed (34) hide show
  1. package/agents/generators.md +18 -0
  2. package/dist/__typechecks__/custom-action-metadata.d.ts +2 -0
  3. package/dist/__typechecks__/custom-action-metadata.d.ts.map +1 -0
  4. package/dist/generators/custom-action.d.ts +11 -2
  5. package/dist/generators/custom-action.d.ts.map +1 -1
  6. package/dist/generators/custom-action.js +18 -1
  7. package/dist/generators/custom-action.js.map +1 -1
  8. package/dist/generators/index.d.ts +1 -1
  9. package/dist/generators/index.d.ts.map +1 -1
  10. package/dist/generators/rest.d.ts.map +1 -1
  11. package/dist/generators/rest.js +3 -2
  12. package/dist/generators/rest.js.map +1 -1
  13. package/dist/generators/tool-schema.d.ts +8 -2
  14. package/dist/generators/tool-schema.d.ts.map +1 -1
  15. package/dist/generators/tool-schema.js +46 -8
  16. package/dist/generators/tool-schema.js.map +1 -1
  17. package/dist/manifest/static-manifest.js +1 -1
  18. package/dist/manifest/static-manifest.js.map +1 -1
  19. package/dist/manifest/store.js +1 -1
  20. package/dist/manifest.json +1 -1
  21. package/dist/prebuild/index.d.ts.map +1 -1
  22. package/dist/prebuild/index.js +17 -0
  23. package/dist/prebuild/index.js.map +1 -1
  24. package/dist/registry/types.d.ts +13 -0
  25. package/dist/registry/types.d.ts.map +1 -1
  26. package/dist/smrt-knowledge.json +5 -5
  27. package/dist/vite-plugin/index.d.ts.map +1 -1
  28. package/dist/vite-plugin/index.js +23 -1
  29. package/dist/vite-plugin/index.js.map +1 -1
  30. package/dist/vite-plugin/web-collections.d.ts +49 -1
  31. package/dist/vite-plugin/web-collections.d.ts.map +1 -1
  32. package/dist/vite-plugin/web-collections.js +185 -19
  33. package/dist/vite-plugin/web-collections.js.map +1 -1
  34. package/package.json +4 -4
@@ -13,6 +13,14 @@ invariants, and the traps that apply before editing anything live in
13
13
  | MCP Server | `src/generators/mcp.ts` | Model Context Protocol tools |
14
14
  | Web collections | `src/vite-plugin/web-collections.ts` (selectors) + `generateWebModule` | `@happyvertical/smrt-virt-web` — one typed collection definition per API-exposed REST collection (#1761), consumed by `@happyvertical/smrt-web` |
15
15
 
16
+ The same web virtual module exports `webMcpToolDefinitions` (#2518), a
17
+ canonical per-tool array selected independently of list materialization. Every
18
+ non-empty canonical API action set contributes tools, so get-only and
19
+ custom-action-only models are discoverable; custom actions declared on a
20
+ `SmrtCollection` merge into the owning row collection. Each definition carries
21
+ complete route and invalidation metadata. `collectionDefinitions` and its
22
+ embedded descriptor copy remain unchanged for existing cache-backed consumers.
23
+
16
24
  Generated API clients share `selectApiClientEntries()` across the runtime Vite
17
25
  module, its ambient declaration, and physical prebuild declarations. When a
18
26
  collection class and its populated model share an endpoint, the model owns the
@@ -25,6 +33,9 @@ fallback so duplicate class names across packages cannot reintroduce ordering.
25
33
 
26
34
  The web module also emits a build-time **`manifestHash`** constant (#1764): `computeWebManifestHash(manifest)` is a deterministic, replica-stable digest of the emitted web-collection SHAPE (name/className/endpoint/idField/actions/fields/relationships), canonicalized (recursive key sort) before `sha256 → base64url`, truncated to 16 chars — so the same schema always hashes the same, and a field add/remove/type-change/edge-change changes it. A change means old persisted client rows may mis-hydrate, so smrt-web keys its durable persistence namespace on it and its `updateAvailable` contract signal compares against it. Four co-managed emission sites must not drift: the runtime value (`generateWebModule`), the `@happyvertical/smrt-virt-web` ambient d.ts (`vite-plugin/index.ts`), the physical `@smrt/web` d.ts (`prebuild/index.ts`), and the hand-written type mirror in `@happyvertical/smrt-web` (`packages/smrt-web/src/index.ts` — dependency-free, so textual sync only).
27
35
 
36
+ `webMcpToolDefinitions` is deliberately outside that digest: tool-only route,
37
+ identifier, or annotation changes cannot alter persisted row hydration.
38
+
28
39
  Per-field web emission (#2046): `buildWebFieldDefinitions` carries `description` (from `@field({ description })`) and sanitized `ui` hints (from `@field({ ui: { basic, group, order, locked } })`, read off the manifest `_meta.ui` bag through per-key type guards) into each emitted field definition, and `buildWebToolDescriptors` threads the same `description` into browser MCP tool schemas. `sensitive`/`transient` fields are excluded from emission entirely, so their descriptions never ship. Both keys are conditional, so hint-less schemas emit byte-identical definitions (and hashes) as before; adding a description/ui hint changes the manifest hash — deliberate over-invalidation, harmless per the #1764 contract.
29
40
 
30
41
  ## Generated MCP server output language
@@ -81,4 +92,11 @@ returns `isError: true` and `_meta['io.happyvertical/smrt']`. Opaque successful
81
92
  objects (including `{ code, message }`) remain untouched; thrown exceptions are
82
93
  not reclassified as domain failures.
83
94
 
95
+ Custom route metadata also classifies browser-tool effects. Set `effect` to
96
+ `read`, `write`, or `destructive`, with truthful `idempotent` and `openWorld`
97
+ flags. CRUD classification is fixed: list/get are read, create/update are write,
98
+ and delete is destructive. An undeclared custom action deliberately defaults to
99
+ destructive, non-idempotent, and open-world so a browser capability policy never
100
+ fails open.
101
+
84
102
  Generated reads (`list`/`get`) on the REST and SvelteKit generators support conditional GET (helpers in `src/generators/conditional-get.ts`). ETag v2 (#1765): the validator is the table's change-feed version (`getTableVersion`) keyed by the request representation, so a **concrete** `If-None-Match` short-circuits into a 304 with an empty body **before** the collection query runs — an unchanged table revalidates with zero table scan. A wildcard `If-None-Match: *` is deferred until the payload builds (existence confirmed), so a missing item still returns 404, not a false 304. Tenant-scoped reads fold the active tenant into the representation (`resolveTenantEtagDiscriminator`) so one tenant's cached validator never satisfies another's read of the same URL. Routes whose GET renders via a **custom serializer** (which can load related tables the base-table version can't observe) keep the v1 body-hash ETag (`#1757`, query-first but correct); the default `toPublicJSON` path — all REST reads and non-serializer SvelteKit reads — uses v2. v2 is weakly consistent by design (the cost of not reading the data): a revalidation in the sub-statement window between a committed write and its feed append can return a stale 304 that self-heals on the next revalidation. The other v2 window — a deploy that changes the response shape WITHOUT a table write — is closed by the **#1764 ETag salt**: `computeTableVersionEtag(version, representation, manifestHash?)` folds the build's web-collection shape digest into the digest, so a shape-only redeploy busts every read validator (`undefined` reproduces the pre-#1764 unsalted value byte-for-byte for direct helper callers). The generated SvelteKit route bakes the digest in as a `MANIFEST_HASH` constant (via `generateConditionalGetRouteHelper`'s `manifestHash` option, sourced from `computeWebManifestHash(manifest)`) — automatic for the SvelteKit transport. The runtime `APIGenerator` auto-populates the same salt from the runtime registry with `computeRuntimeWebManifestHash()` when `APIConfig.manifestHash` is omitted; explicit `APIConfig.manifestHash` still wins for custom setups. The digest scope is get-OR-list (`selectWebEtagSaltEntries`), so **get-only** routes are salted too. Strong consistency still requires the v1 body-hash path. Cache-Control policy (unchanged from #1757): `private, no-cache` by default; public models may opt into shared caching via `@smrt({ api: { public: true | 'read', cache: { sMaxage } } })` → `public, max-age=0, s-maxage=<n>`; non-public models never emit shared-cache headers. Tenant-scoped models (any mode) never emit them either — bodies vary with session-cookie tenant context that URL-keyed shared caches cannot see; `sMaxage` is neutralized to `private, no-cache` with a one-time warning.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=custom-action-metadata.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"custom-action-metadata.d.ts","sourceRoot":"","sources":["../../src/__typechecks__/custom-action-metadata.ts"],"names":[],"mappings":""}
@@ -1,5 +1,7 @@
1
+ import { ToolEffect } from '../registry/types.js';
1
2
  import { MethodDefinition } from '../scanner/types.js';
2
3
  export type CustomActionScope = 'item' | 'collection';
4
+ export type { ToolEffect } from '../registry/types.js';
3
5
  export interface CustomActionMetadata {
4
6
  scope: CustomActionScope;
5
7
  /** An item-targeted action requires its target identifier. */
@@ -8,7 +10,15 @@ export interface CustomActionMetadata {
8
10
  parameters?: MethodDefinition['parameters'];
9
11
  /** Collection actions on a model class invoke its static method. */
10
12
  isStatic: boolean;
13
+ /** Browser/agent-visible effect. Omitted declarations fail closed. */
14
+ effect?: ToolEffect;
15
+ /** Whether repeating the action with the same arguments is safe. */
16
+ idempotent?: boolean;
17
+ /** Whether the opaque action may interact outside the SMRT application. */
18
+ openWorld?: boolean;
11
19
  }
20
+ /** Fully resolved metadata returned by {@link resolveCustomActionMetadata}. */
21
+ export type ResolvedCustomActionMetadata = CustomActionMetadata & Required<Pick<CustomActionMetadata, 'effect' | 'idempotent' | 'openWorld'>>;
12
22
  /**
13
23
  * Return the transport field for a method parameter. Flat tool and CLI
14
24
  * transports reserve `id` for receiver parsing even when a collection action
@@ -33,7 +43,7 @@ type ToolArgs = Record<string, unknown>;
33
43
  * and WebMCP. A missing manifest method retains the historical item-shaped
34
44
  * schema; runtime callers may still provide their legacy collection fallback.
35
45
  */
36
- export declare function resolveCustomActionMetadata(options: ResolveCustomActionMetadataOptions): CustomActionMetadata;
46
+ export declare function resolveCustomActionMetadata(options: ResolveCustomActionMetadataOptions): ResolvedCustomActionMetadata;
37
47
  /** Build the custom-action portion of an MCP/WebMCP JSON Schema. */
38
48
  export declare function buildCustomActionInputSchema(metadata: CustomActionMetadata): JsonSchema;
39
49
  /**
@@ -64,5 +74,4 @@ export declare const SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY = "io.happyvertical/s
64
74
  * REST callers receive non-2xx semantics even when an adapter omits it.
65
75
  */
66
76
  export declare function normalizeCustomActionFailure(value: unknown): CustomActionFailure | undefined;
67
- export {};
68
77
  //# sourceMappingURL=custom-action.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"custom-action.d.ts","sourceRoot":"","sources":["../../src/generators/custom-action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,YAAY,CAAC;AAEtD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,iBAAiB,CAAC;IACzB,8DAA8D;IAC9D,UAAU,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,EAAE,OAAO,CAAC;CACnB;AAED;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,IAAI,CAAC,oBAAoB,EAAE,YAAY,CAAC,EACnD,aAAa,EAAE,MAAM,GACpB,MAAM,CAER;AAED,MAAM,WAAW,kCAAkC;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;KAC7C,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC1C,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,GAC1C,oBAAoB,CAqBtB;AAED,oEAAoE;AACpE,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,oBAAoB,GAC7B,UAAU,CAuDZ;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,EAAE,QAAQ,GACb,OAAO,EAAE,CAwBX;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,gFAAgF;AAChF,eAAO,MAAM,qCAAqC,0BAA0B,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,mBAAmB,GAAG,SAAS,CA6BjC"}
1
+ {"version":3,"file":"custom-action.d.ts","sourceRoot":"","sources":["../../src/generators/custom-action.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAG5D,MAAM,MAAM,iBAAiB,GAAG,MAAM,GAAG,YAAY,CAAC;AACtD,YAAY,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,iBAAiB,CAAC;IACzB,8DAA8D;IAC9D,UAAU,EAAE,OAAO,CAAC;IACpB,gEAAgE;IAChE,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;IAC5C,oEAAoE;IACpE,QAAQ,EAAE,OAAO,CAAC;IAClB,sEAAsE;IACtE,MAAM,CAAC,EAAE,UAAU,CAAC;IACpB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,+EAA+E;AAC/E,MAAM,MAAM,4BAA4B,GAAG,oBAAoB,GAC7D,QAAQ,CAAC,IAAI,CAAC,oBAAoB,EAAE,QAAQ,GAAG,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC;AAE9E;;;;;GAKG;AACH,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,IAAI,CAAC,oBAAoB,EAAE,YAAY,CAAC,EACnD,aAAa,EAAE,MAAM,GACpB,MAAM,CAER;AAED,MAAM,WAAW,kCAAkC;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE;QACP,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,UAAU,CAAC,EAAE,gBAAgB,CAAC,YAAY,CAAC,CAAC;KAC7C,CAAC;IACF,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,gFAAgF;IAChF,YAAY,CAAC,EAAE,iBAAiB,CAAC;CAClC;AAED,KAAK,UAAU,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC1C,KAAK,QAAQ,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAExC;;;;GAIG;AACH,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,kCAAkC,GAC1C,4BAA4B,CA6B9B;AAED,oEAAoE;AACpE,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,oBAAoB,GAC7B,UAAU,CAuDZ;AAED;;;;GAIG;AACH,wBAAgB,+BAA+B,CAC7C,QAAQ,EAAE,oBAAoB,EAC9B,IAAI,EAAE,QAAQ,GACb,OAAO,EAAE,CAwBX;AAED;;;;GAIG;AACH,MAAM,WAAW,mBAAmB;IAClC,EAAE,EAAE,KAAK,CAAC;IACV,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,gFAAgF;AAChF,eAAO,MAAM,qCAAqC,0BAA0B,CAAC;AAE7E;;;;GAIG;AACH,wBAAgB,4BAA4B,CAC1C,KAAK,EAAE,OAAO,GACb,mBAAmB,GAAG,SAAS,CA6BjC"}
@@ -18,11 +18,16 @@ function resolveCustomActionMetadata(options) {
18
18
  const defaultScope = options.defaultScope ?? (options.method?.isStatic ? "collection" : "item");
19
19
  const requestedScope = readConfiguredScope(options.apiConfig, options.actionName);
20
20
  const scope = requestedScope === defaultScope ? requestedScope : defaultScope;
21
+ const configured = readConfiguredToolMetadata(options.apiConfig, options.actionName);
22
+ const effect = configured.effect ?? "destructive";
21
23
  return {
22
24
  scope,
23
25
  idRequired: scope === "item",
24
26
  ...options.method?.parameters ? { parameters: options.method.parameters } : {},
25
- isStatic: options.method?.isStatic === true
27
+ isStatic: options.method?.isStatic === true,
28
+ effect,
29
+ idempotent: configured.idempotent ?? effect === "read",
30
+ openWorld: configured.openWorld ?? true
26
31
  };
27
32
  }
28
33
  /** Build the custom-action portion of an MCP/WebMCP JSON Schema. */
@@ -101,6 +106,18 @@ function readConfiguredScope(apiConfig, actionName) {
101
106
  const route = apiConfig.routes[actionName];
102
107
  return isRecord(route) && (route.scope === "item" || route.scope === "collection") ? route.scope : void 0;
103
108
  }
109
+ function readConfiguredToolMetadata(apiConfig, actionName) {
110
+ if (!isRecord(apiConfig) || !isRecord(apiConfig.routes)) return {};
111
+ const route = apiConfig.routes[actionName];
112
+ if (!isRecord(route)) return {};
113
+ const effect = route.effect === "read" || route.effect === "write" || route.effect === "destructive" ? route.effect : void 0;
114
+ if (effect === "read" && (route.method === "PUT" || route.method === "PATCH" || route.method === "DELETE")) throw new Error(`Custom action ${actionName} cannot declare a read effect for a ${route.method} route`);
115
+ return {
116
+ ...effect ? { effect } : {},
117
+ ...typeof route.idempotent === "boolean" ? { idempotent: route.idempotent } : {},
118
+ ...typeof route.openWorld === "boolean" ? { openWorld: route.openWorld } : {}
119
+ };
120
+ }
104
121
  function redactValue(value, seen = /* @__PURE__ */ new WeakSet()) {
105
122
  if (typeof value === "string") return redactText(value);
106
123
  if (value === null || typeof value !== "object") return value;
@@ -1 +1 @@
1
- {"version":3,"file":"custom-action.js","names":[],"sources":["../../src/generators/custom-action.ts"],"sourcesContent":["/**\n * Canonical custom-action metadata and transport-safe result helpers.\n *\n * Custom actions are intentionally distinct from generated CRUD. Their target\n * is derived from method metadata: instance methods target an item and static\n * methods target the collection. API route configuration may shape an HTTP\n * route, but it cannot change a method's receiver.\n */\n\nimport type { MethodDefinition } from '../scanner/types.js';\nimport { convertTypeToJsonSchema } from '../tools/tool-generator.js';\n\nexport type CustomActionScope = 'item' | 'collection';\n\nexport interface CustomActionMetadata {\n scope: CustomActionScope;\n /** An item-targeted action requires its target identifier. */\n idRequired: boolean;\n /** Present only when scanner/manifest metadata is available. */\n parameters?: MethodDefinition['parameters'];\n /** Collection actions on a model class invoke its static method. */\n isStatic: boolean;\n}\n\n/**\n * Return the transport field for a method parameter. Flat tool and CLI\n * transports reserve `id` for receiver parsing even when a collection action\n * rejects it, so every action parameter named `id` is exposed as `actionId`.\n * REST already has separate path/body namespaces.\n */\nexport function customActionParameterInputName(\n _metadata: Pick<CustomActionMetadata, 'idRequired'>,\n parameterName: string,\n): string {\n return parameterName === 'id' ? 'actionId' : parameterName;\n}\n\nexport interface ResolveCustomActionMetadataOptions {\n actionName: string;\n method?: {\n isStatic?: boolean;\n parameters?: MethodDefinition['parameters'];\n };\n apiConfig?: unknown;\n /** Collection-class actions have a collection receiver even when non-static. */\n defaultScope?: CustomActionScope;\n}\n\ntype JsonSchema = Record<string, unknown>;\ntype ToolArgs = Record<string, unknown>;\n\n/**\n * Resolve the target contract shared by MCP, generated REST, CLI discovery,\n * and WebMCP. A missing manifest method retains the historical item-shaped\n * schema; runtime callers may still provide their legacy collection fallback.\n */\nexport function resolveCustomActionMetadata(\n options: ResolveCustomActionMetadataOptions,\n): CustomActionMetadata {\n const defaultScope =\n options.defaultScope ?? (options.method?.isStatic ? 'collection' : 'item');\n const requestedScope = readConfiguredScope(\n options.apiConfig,\n options.actionName,\n );\n // A route-only scope override cannot manufacture a receiver. A normal\n // instance method is always item-targeted; a static model method and a\n // recognized collection-class method are always collection-targeted. Keep\n // a matching explicit value for diagnostics/config round-tripping only.\n const scope = requestedScope === defaultScope ? requestedScope : defaultScope;\n\n return {\n scope,\n idRequired: scope === 'item',\n ...(options.method?.parameters\n ? { parameters: options.method.parameters }\n : {}),\n isStatic: options.method?.isStatic === true,\n };\n}\n\n/** Build the custom-action portion of an MCP/WebMCP JSON Schema. */\nexport function buildCustomActionInputSchema(\n metadata: CustomActionMetadata,\n): JsonSchema {\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n if (metadata.idRequired) {\n properties.id = {\n type: 'string',\n description: 'ID of the object to execute action on',\n };\n required.push('id');\n }\n\n // Absent metadata is the legacy options-bag contract. Do not infer direct\n // positional arguments from runtime function arity: it is lossy after\n // transpilation and would make discovery non-deterministic.\n if (!metadata.parameters) {\n properties.options = {\n type: 'object',\n description: 'Additional options for the custom action',\n additionalProperties: true,\n };\n } else if (\n metadata.parameters.length === 1 &&\n metadata.parameters[0]?.name === 'options'\n ) {\n const parameter = metadata.parameters[0];\n properties.options = {\n ...convertTypeToJsonSchema(parameter.type),\n description: 'Options for the custom action',\n ...(parameter.default !== undefined\n ? { default: parameter.default }\n : {}),\n };\n if (!parameter.optional) required.push('options');\n } else {\n for (const parameter of metadata.parameters) {\n const inputName = customActionParameterInputName(\n metadata,\n parameter.name,\n );\n properties[inputName] = {\n ...convertTypeToJsonSchema(parameter.type),\n ...(parameter.default !== undefined\n ? { default: parameter.default }\n : {}),\n };\n if (!parameter.optional) required.push(inputName);\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\n/**\n * Translate a transport object into the method's call arguments. Legacy\n * actions retain their single options-bag invocation; scanner metadata enables\n * an exact positional projection without changing legacy action behavior.\n */\nexport function buildCustomActionInvocationArgs(\n metadata: CustomActionMetadata,\n args: ToolArgs,\n): unknown[] {\n const { id: _id, options, ...directArgs } = args;\n\n if (!metadata.parameters) {\n return [\n isRecord(options) && Object.keys(options).length > 0\n ? options\n : directArgs,\n ];\n }\n if (metadata.parameters.length === 0) return [];\n if (\n metadata.parameters.length === 1 &&\n metadata.parameters[0]?.name === 'options'\n ) {\n // Preserve `undefined` (and an explicit `null`) so JavaScript default\n // parameter initializers and intentional null handling retain their native\n // semantics. Legacy options bags still receive an empty object below.\n return [options];\n }\n return metadata.parameters.map(\n (parameter) =>\n args[customActionParameterInputName(metadata, parameter.name)],\n );\n}\n\n/**\n * Domain-neutral returned-failure convention for custom actions. The explicit\n * `ok: false` marker prevents successful opaque values such as `{ code,\n * message }` from being reclassified as failures by a transport.\n */\nexport interface CustomActionFailure {\n ok: false;\n code: string;\n message: string;\n status: number;\n details?: unknown;\n retryable?: boolean;\n correlationId?: string;\n}\n\n/** Stable MCP `_meta` member shared with the app discovery contract (#2181). */\nexport const SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY = 'io.happyvertical/smrt';\n\n/**\n * Detect, validate, and redact an explicitly returned custom-action failure.\n * Unknown return values remain opaque successes. `status` defaults to 400 so\n * REST callers receive non-2xx semantics even when an adapter omits it.\n */\nexport function normalizeCustomActionFailure(\n value: unknown,\n): CustomActionFailure | undefined {\n if (!isRecord(value) || value.ok !== false) return undefined;\n if (typeof value.code !== 'string' || typeof value.message !== 'string') {\n return undefined;\n }\n\n const status =\n typeof value.status === 'number' &&\n Number.isInteger(value.status) &&\n value.status >= 400 &&\n value.status <= 599\n ? value.status\n : 400;\n\n return {\n ok: false,\n code: value.code,\n message: redactText(value.message),\n status,\n ...(Object.hasOwn(value, 'details')\n ? { details: redactValue(value.details) }\n : {}),\n ...(typeof value.retryable === 'boolean'\n ? { retryable: value.retryable }\n : {}),\n ...(typeof value.correlationId === 'string'\n ? { correlationId: value.correlationId }\n : {}),\n };\n}\n\nfunction readConfiguredScope(\n apiConfig: unknown,\n actionName: string,\n): CustomActionScope | undefined {\n if (!isRecord(apiConfig) || !isRecord(apiConfig.routes)) return undefined;\n const route = apiConfig.routes[actionName];\n return isRecord(route) &&\n (route.scope === 'item' || route.scope === 'collection')\n ? route.scope\n : undefined;\n}\n\nfunction redactValue(value: unknown, seen = new WeakSet<object>()): unknown {\n if (typeof value === 'string') return redactText(value);\n if (value === null || typeof value !== 'object') return value;\n if (seen.has(value)) return '[REDACTED]';\n seen.add(value);\n if (Array.isArray(value))\n return value.map((entry) => redactValue(entry, seen));\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return '[REDACTED]';\n const result: Record<string, unknown> = {};\n for (const [key, nested] of Object.entries(value)) {\n result[key] = isSensitiveKey(key)\n ? '[REDACTED]'\n : redactValue(nested, seen);\n }\n return result;\n}\n\nfunction redactText(value: string): string {\n return value\n .replace(/\\bBearer\\s+[^\\s,;]+/giu, 'Bearer [REDACTED]')\n .replace(\n /\\b(token|secret|password|api[_-]?key)=([^\\s&]+)/giu,\n '$1=[REDACTED]',\n );\n}\n\nfunction isSensitiveKey(key: string): boolean {\n return /(?:token|secret|password|authorization|cookie|credential|api[_-]?key)/iu.test(\n key,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"custom-action.js","names":[],"sources":["../../src/generators/custom-action.ts"],"sourcesContent":["/**\n * Canonical custom-action metadata and transport-safe result helpers.\n *\n * Custom actions are intentionally distinct from generated CRUD. Their target\n * is derived from method metadata: instance methods target an item and static\n * methods target the collection. API route configuration may shape an HTTP\n * route, but it cannot change a method's receiver.\n */\n\nimport type { ToolEffect } from '../registry/types.js';\nimport type { MethodDefinition } from '../scanner/types.js';\nimport { convertTypeToJsonSchema } from '../tools/tool-generator.js';\n\nexport type CustomActionScope = 'item' | 'collection';\nexport type { ToolEffect } from '../registry/types.js';\n\nexport interface CustomActionMetadata {\n scope: CustomActionScope;\n /** An item-targeted action requires its target identifier. */\n idRequired: boolean;\n /** Present only when scanner/manifest metadata is available. */\n parameters?: MethodDefinition['parameters'];\n /** Collection actions on a model class invoke its static method. */\n isStatic: boolean;\n /** Browser/agent-visible effect. Omitted declarations fail closed. */\n effect?: ToolEffect;\n /** Whether repeating the action with the same arguments is safe. */\n idempotent?: boolean;\n /** Whether the opaque action may interact outside the SMRT application. */\n openWorld?: boolean;\n}\n\n/** Fully resolved metadata returned by {@link resolveCustomActionMetadata}. */\nexport type ResolvedCustomActionMetadata = CustomActionMetadata &\n Required<Pick<CustomActionMetadata, 'effect' | 'idempotent' | 'openWorld'>>;\n\n/**\n * Return the transport field for a method parameter. Flat tool and CLI\n * transports reserve `id` for receiver parsing even when a collection action\n * rejects it, so every action parameter named `id` is exposed as `actionId`.\n * REST already has separate path/body namespaces.\n */\nexport function customActionParameterInputName(\n _metadata: Pick<CustomActionMetadata, 'idRequired'>,\n parameterName: string,\n): string {\n return parameterName === 'id' ? 'actionId' : parameterName;\n}\n\nexport interface ResolveCustomActionMetadataOptions {\n actionName: string;\n method?: {\n isStatic?: boolean;\n parameters?: MethodDefinition['parameters'];\n };\n apiConfig?: unknown;\n /** Collection-class actions have a collection receiver even when non-static. */\n defaultScope?: CustomActionScope;\n}\n\ntype JsonSchema = Record<string, unknown>;\ntype ToolArgs = Record<string, unknown>;\n\n/**\n * Resolve the target contract shared by MCP, generated REST, CLI discovery,\n * and WebMCP. A missing manifest method retains the historical item-shaped\n * schema; runtime callers may still provide their legacy collection fallback.\n */\nexport function resolveCustomActionMetadata(\n options: ResolveCustomActionMetadataOptions,\n): ResolvedCustomActionMetadata {\n const defaultScope =\n options.defaultScope ?? (options.method?.isStatic ? 'collection' : 'item');\n const requestedScope = readConfiguredScope(\n options.apiConfig,\n options.actionName,\n );\n // A route-only scope override cannot manufacture a receiver. A normal\n // instance method is always item-targeted; a static model method and a\n // recognized collection-class method are always collection-targeted. Keep\n // a matching explicit value for diagnostics/config round-tripping only.\n const scope = requestedScope === defaultScope ? requestedScope : defaultScope;\n const configured = readConfiguredToolMetadata(\n options.apiConfig,\n options.actionName,\n );\n const effect = configured.effect ?? 'destructive';\n\n return {\n scope,\n idRequired: scope === 'item',\n ...(options.method?.parameters\n ? { parameters: options.method.parameters }\n : {}),\n isStatic: options.method?.isStatic === true,\n effect,\n idempotent: configured.idempotent ?? effect === 'read',\n openWorld: configured.openWorld ?? true,\n };\n}\n\n/** Build the custom-action portion of an MCP/WebMCP JSON Schema. */\nexport function buildCustomActionInputSchema(\n metadata: CustomActionMetadata,\n): JsonSchema {\n const properties: Record<string, JsonSchema> = {};\n const required: string[] = [];\n\n if (metadata.idRequired) {\n properties.id = {\n type: 'string',\n description: 'ID of the object to execute action on',\n };\n required.push('id');\n }\n\n // Absent metadata is the legacy options-bag contract. Do not infer direct\n // positional arguments from runtime function arity: it is lossy after\n // transpilation and would make discovery non-deterministic.\n if (!metadata.parameters) {\n properties.options = {\n type: 'object',\n description: 'Additional options for the custom action',\n additionalProperties: true,\n };\n } else if (\n metadata.parameters.length === 1 &&\n metadata.parameters[0]?.name === 'options'\n ) {\n const parameter = metadata.parameters[0];\n properties.options = {\n ...convertTypeToJsonSchema(parameter.type),\n description: 'Options for the custom action',\n ...(parameter.default !== undefined\n ? { default: parameter.default }\n : {}),\n };\n if (!parameter.optional) required.push('options');\n } else {\n for (const parameter of metadata.parameters) {\n const inputName = customActionParameterInputName(\n metadata,\n parameter.name,\n );\n properties[inputName] = {\n ...convertTypeToJsonSchema(parameter.type),\n ...(parameter.default !== undefined\n ? { default: parameter.default }\n : {}),\n };\n if (!parameter.optional) required.push(inputName);\n }\n }\n\n return {\n type: 'object',\n properties,\n ...(required.length > 0 ? { required } : {}),\n };\n}\n\n/**\n * Translate a transport object into the method's call arguments. Legacy\n * actions retain their single options-bag invocation; scanner metadata enables\n * an exact positional projection without changing legacy action behavior.\n */\nexport function buildCustomActionInvocationArgs(\n metadata: CustomActionMetadata,\n args: ToolArgs,\n): unknown[] {\n const { id: _id, options, ...directArgs } = args;\n\n if (!metadata.parameters) {\n return [\n isRecord(options) && Object.keys(options).length > 0\n ? options\n : directArgs,\n ];\n }\n if (metadata.parameters.length === 0) return [];\n if (\n metadata.parameters.length === 1 &&\n metadata.parameters[0]?.name === 'options'\n ) {\n // Preserve `undefined` (and an explicit `null`) so JavaScript default\n // parameter initializers and intentional null handling retain their native\n // semantics. Legacy options bags still receive an empty object below.\n return [options];\n }\n return metadata.parameters.map(\n (parameter) =>\n args[customActionParameterInputName(metadata, parameter.name)],\n );\n}\n\n/**\n * Domain-neutral returned-failure convention for custom actions. The explicit\n * `ok: false` marker prevents successful opaque values such as `{ code,\n * message }` from being reclassified as failures by a transport.\n */\nexport interface CustomActionFailure {\n ok: false;\n code: string;\n message: string;\n status: number;\n details?: unknown;\n retryable?: boolean;\n correlationId?: string;\n}\n\n/** Stable MCP `_meta` member shared with the app discovery contract (#2181). */\nexport const SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY = 'io.happyvertical/smrt';\n\n/**\n * Detect, validate, and redact an explicitly returned custom-action failure.\n * Unknown return values remain opaque successes. `status` defaults to 400 so\n * REST callers receive non-2xx semantics even when an adapter omits it.\n */\nexport function normalizeCustomActionFailure(\n value: unknown,\n): CustomActionFailure | undefined {\n if (!isRecord(value) || value.ok !== false) return undefined;\n if (typeof value.code !== 'string' || typeof value.message !== 'string') {\n return undefined;\n }\n\n const status =\n typeof value.status === 'number' &&\n Number.isInteger(value.status) &&\n value.status >= 400 &&\n value.status <= 599\n ? value.status\n : 400;\n\n return {\n ok: false,\n code: value.code,\n message: redactText(value.message),\n status,\n ...(Object.hasOwn(value, 'details')\n ? { details: redactValue(value.details) }\n : {}),\n ...(typeof value.retryable === 'boolean'\n ? { retryable: value.retryable }\n : {}),\n ...(typeof value.correlationId === 'string'\n ? { correlationId: value.correlationId }\n : {}),\n };\n}\n\nfunction readConfiguredScope(\n apiConfig: unknown,\n actionName: string,\n): CustomActionScope | undefined {\n if (!isRecord(apiConfig) || !isRecord(apiConfig.routes)) return undefined;\n const route = apiConfig.routes[actionName];\n return isRecord(route) &&\n (route.scope === 'item' || route.scope === 'collection')\n ? route.scope\n : undefined;\n}\n\nfunction readConfiguredToolMetadata(\n apiConfig: unknown,\n actionName: string,\n): {\n effect?: ToolEffect;\n idempotent?: boolean;\n openWorld?: boolean;\n} {\n if (!isRecord(apiConfig) || !isRecord(apiConfig.routes)) return {};\n const route = apiConfig.routes[actionName];\n if (!isRecord(route)) return {};\n const effect =\n route.effect === 'read' ||\n route.effect === 'write' ||\n route.effect === 'destructive'\n ? route.effect\n : undefined;\n if (\n effect === 'read' &&\n (route.method === 'PUT' ||\n route.method === 'PATCH' ||\n route.method === 'DELETE')\n ) {\n throw new Error(\n `Custom action ${actionName} cannot declare a read effect for a ${route.method} route`,\n );\n }\n return {\n ...(effect ? { effect } : {}),\n ...(typeof route.idempotent === 'boolean'\n ? { idempotent: route.idempotent }\n : {}),\n ...(typeof route.openWorld === 'boolean'\n ? { openWorld: route.openWorld }\n : {}),\n };\n}\n\nfunction redactValue(value: unknown, seen = new WeakSet<object>()): unknown {\n if (typeof value === 'string') return redactText(value);\n if (value === null || typeof value !== 'object') return value;\n if (seen.has(value)) return '[REDACTED]';\n seen.add(value);\n if (Array.isArray(value))\n return value.map((entry) => redactValue(entry, seen));\n const prototype = Object.getPrototypeOf(value);\n if (prototype !== Object.prototype && prototype !== null) return '[REDACTED]';\n const result: Record<string, unknown> = {};\n for (const [key, nested] of Object.entries(value)) {\n result[key] = isSensitiveKey(key)\n ? '[REDACTED]'\n : redactValue(nested, seen);\n }\n return result;\n}\n\nfunction redactText(value: string): string {\n return value\n .replace(/\\bBearer\\s+[^\\s,;]+/giu, 'Bearer [REDACTED]')\n .replace(\n /\\b(token|secret|password|api[_-]?key)=([^\\s&]+)/giu,\n '$1=[REDACTED]',\n );\n}\n\nfunction isSensitiveKey(key: string): boolean {\n return /(?:token|secret|password|authorization|cookie|credential|api[_-]?key)/iu.test(\n key,\n );\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@
4
4
  export type { CLIConfig, CLIContext } from './cli';
5
5
  export { CLIGenerator, getCLIHandler, setupCLI } from './cli';
6
6
  export { canonicalReadRepresentation, computeBodyEtag, computeTableVersionEtag, conditionalJsonResponse, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, PRIVATE_READ_CACHE_CONTROL, type ReadCacheControlOptions, resolveReadCacheControl, resolveTenantEtagDiscriminator, versionConditionalResponse, warnIfSharedCacheNeutralized, } from './conditional-get';
7
- export { buildCustomActionInputSchema, buildCustomActionInvocationArgs, type CustomActionFailure, type CustomActionMetadata, type CustomActionScope, customActionParameterInputName, normalizeCustomActionFailure, type ResolveCustomActionMetadataOptions, resolveCustomActionMetadata, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, } from './custom-action';
7
+ export { buildCustomActionInputSchema, buildCustomActionInvocationArgs, type CustomActionFailure, type CustomActionMetadata, type CustomActionScope, customActionParameterInputName, normalizeCustomActionFailure, type ResolveCustomActionMetadataOptions, type ResolvedCustomActionMetadata, resolveCustomActionMetadata, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, type ToolEffect, } from './custom-action';
8
8
  export { buildChangeEventStream, type ChangeEventStreamOptions, changeEventSubscribersAtCapacity, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, eventStreamCapacityExceededResponse, normalizeEventsMaxSubscribers, signalVisibleToTenant, tryReserveChangeEventSubscriberSlot, } from './events-route';
9
9
  export type { MCPConfig, MCPContext, MCPRequest, MCPResponse, MCPTool, MCPToolListCacheHint, MCPToolListCacheOptions, } from './mcp';
10
10
  export { MCP_STABLE_CATALOG_TTL_MS, MCPGenerator, resolveMCPToolListCacheHint, sortMCPTools, } from './mcp';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG9D,OAAO,EACL,2BAA2B,EAC3B,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,uBAAuB,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,8BAA8B,EAC9B,4BAA4B,EAC5B,KAAK,kCAAkC,EACvC,2BAA2B,EAC3B,qCAAqC,GACtC,MAAM,iBAAiB,CAAC;AAKzB,OAAO,EACL,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,gCAAgC,EAChC,2BAA2B,EAC3B,8BAA8B,EAC9B,kCAAkC,EAClC,mCAAmC,EACnC,6BAA6B,EAC7B,qBAAqB,EACrB,mCAAmC,GACpC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,SAAS,EACT,UAAU,EACV,UAAU,EACV,WAAW,EACX,OAAO,EACP,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,2BAA2B,EAC3B,YAAY,GACb,MAAM,OAAO,CAAC;AACf,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAEtE,OAAO,EACL,YAAY,EACZ,6BAA6B,EAC7B,gBAAgB,EAChB,eAAe,GAChB,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,uBAAuB,EACvB,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/generators/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAG9D,OAAO,EACL,2BAA2B,EAC3B,eAAe,EACf,uBAAuB,EACvB,uBAAuB,EACvB,2BAA2B,EAC3B,oBAAoB,EACpB,0BAA0B,EAC1B,KAAK,uBAAuB,EAC5B,uBAAuB,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,4BAA4B,GAC7B,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,4BAA4B,EAC5B,+BAA+B,EAC/B,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,8BAA8B,EAC9B,4BAA4B,EAC5B,KAAK,kCAAkC,EACvC,KAAK,4BAA4B,EACjC,2BAA2B,EAC3B,qCAAqC,EACrC,KAAK,UAAU,GAChB,MAAM,iBAAiB,CAAC;AAKzB,OAAO,EACL,sBAAsB,EACtB,KAAK,wBAAwB,EAC7B,gCAAgC,EAChC,2BAA2B,EAC3B,8BAA8B,EAC9B,kCAAkC,EAClC,mCAAmC,EACnC,6BAA6B,EAC7B,qBAAqB,EACrB,mCAAmC,GACpC,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACV,SAAS,EACT,UAAU,EACV,UAAU,EACV,WAAW,EACX,OAAO,EACP,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,OAAO,CAAC;AAEf,OAAO,EACL,yBAAyB,EACzB,YAAY,EACZ,2BAA2B,EAC3B,YAAY,GACb,MAAM,OAAO,CAAC;AACf,YAAY,EAAE,SAAS,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAEtE,OAAO,EACL,YAAY,EACZ,6BAA6B,EAC7B,gBAAgB,EAChB,eAAe,GAChB,MAAM,QAAQ,CAAC;AAChB,YAAY,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE/C,OAAO,EACL,mBAAmB,EACnB,cAAc,GACf,MAAM,WAAW,CAAC;AAEnB,OAAO,EACL,iBAAiB,EACjB,yBAAyB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,iBAAiB,GACvB,MAAM,eAAe,CAAC;AAEvB,OAAO,EACL,uBAAuB,EACvB,KAAK,gBAAgB,GACtB,MAAM,oBAAoB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"rest.d.ts","sourceRoot":"","sources":["../../src/generators/rest.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"rest.d.ts","sourceRoot":"","sources":["../../src/generators/rest.ts"],"names":[],"mappings":"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"}
@@ -414,7 +414,7 @@ var APIGenerator = class {
414
414
  if (metadata.scope !== "collection") continue;
415
415
  const invoke = isCollectionHosted ? (args) => collectionMethod.apply(collection, args) : (args) => staticMethod.apply(itemConstructor, args);
416
416
  let options;
417
- if (routeMethod === "GET") {
417
+ if (routeMethod === "GET") if (metadata.parameters === void 0 || metadata.parameters.length === 1 && metadata.parameters[0]?.name === "options") {
418
418
  const optionsMarker = url.searchParams.get("__smrt_options");
419
419
  if (optionsMarker === "undefined") options = void 0;
420
420
  else if (optionsMarker === "null") options = null;
@@ -423,7 +423,8 @@ var APIGenerator = class {
423
423
  const entries = [...url.searchParams.entries()].filter(([key]) => key !== "__smrt_options");
424
424
  options = entries.length > 0 ? Object.fromEntries(entries) : void 0;
425
425
  }
426
- } else {
426
+ } else options = Object.fromEntries(url.searchParams.entries());
427
+ else {
427
428
  let rawBody = "";
428
429
  try {
429
430
  rawBody = await req.text();