@happyvertical/smrt-core 0.46.0 → 0.47.0

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 (72) hide show
  1. package/AGENTS.md +38 -0
  2. package/dist/decorators/compatibility.d.ts +46 -0
  3. package/dist/decorators/compatibility.d.ts.map +1 -1
  4. package/dist/decorators/compatibility.js +48 -5
  5. package/dist/decorators/compatibility.js.map +1 -1
  6. package/dist/decorators/index.d.ts +119 -1
  7. package/dist/decorators/index.d.ts.map +1 -1
  8. package/dist/decorators/index.js +52 -8
  9. package/dist/decorators/index.js.map +1 -1
  10. package/dist/generators/custom-action.d.ts +379 -2
  11. package/dist/generators/custom-action.d.ts.map +1 -1
  12. package/dist/generators/custom-action.js +694 -17
  13. package/dist/generators/custom-action.js.map +1 -1
  14. package/dist/generators/index.d.ts +1 -1
  15. package/dist/generators/index.d.ts.map +1 -1
  16. package/dist/generators/index.js +2 -2
  17. package/dist/generators/preflight-route.d.ts +12 -10
  18. package/dist/generators/preflight-route.d.ts.map +1 -1
  19. package/dist/generators/preflight-route.js +46 -14
  20. package/dist/generators/preflight-route.js.map +1 -1
  21. package/dist/generators/rest.d.ts +44 -0
  22. package/dist/generators/rest.d.ts.map +1 -1
  23. package/dist/generators/rest.js +84 -9
  24. package/dist/generators/rest.js.map +1 -1
  25. package/dist/generators.js +2 -2
  26. package/dist/index.d.ts +2 -2
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +4 -4
  29. package/dist/knowledge.d.ts.map +1 -1
  30. package/dist/knowledge.js +59 -15
  31. package/dist/knowledge.js.map +1 -1
  32. package/dist/manifest/static-manifest.d.ts.map +1 -1
  33. package/dist/manifest/static-manifest.js +125 -53
  34. package/dist/manifest/static-manifest.js.map +1 -1
  35. package/dist/manifest/store.js +1 -1
  36. package/dist/manifest/store.js.map +1 -1
  37. package/dist/manifest.json +184 -53
  38. package/dist/postgres-permissions.d.ts +6 -1
  39. package/dist/postgres-permissions.d.ts.map +1 -1
  40. package/dist/postgres-permissions.js +78 -7
  41. package/dist/postgres-permissions.js.map +1 -1
  42. package/dist/registry/index.d.ts +1 -1
  43. package/dist/registry/index.d.ts.map +1 -1
  44. package/dist/registry/shared-state.d.ts +19 -0
  45. package/dist/registry/shared-state.d.ts.map +1 -1
  46. package/dist/registry/shared-state.js +16 -1
  47. package/dist/registry/shared-state.js.map +1 -1
  48. package/dist/registry.d.ts +136 -1
  49. package/dist/registry.d.ts.map +1 -1
  50. package/dist/registry.js +231 -1
  51. package/dist/registry.js.map +1 -1
  52. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  53. package/dist/scanner/manifest-generator.js +18 -16
  54. package/dist/scanner/manifest-generator.js.map +1 -1
  55. package/dist/scanner/types.d.ts +59 -6
  56. package/dist/scanner/types.d.ts.map +1 -1
  57. package/dist/scanner/types.js.map +1 -1
  58. package/dist/smrt-knowledge.json +33 -32
  59. package/dist/vite-plugin/api-client-entries.d.ts.map +1 -1
  60. package/dist/vite-plugin/api-client-entries.js +10 -8
  61. package/dist/vite-plugin/api-client-entries.js.map +1 -1
  62. package/dist/vite-plugin/index.d.ts.map +1 -1
  63. package/dist/vite-plugin/index.js +1 -1
  64. package/dist/vite-plugin/index.js.map +1 -1
  65. package/dist/vite-plugin/sveltekit-generator.d.ts +28 -2
  66. package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
  67. package/dist/vite-plugin/sveltekit-generator.js +121 -51
  68. package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
  69. package/dist/vite-plugin/web-collections.d.ts.map +1 -1
  70. package/dist/vite-plugin/web-collections.js +1 -1
  71. package/dist/vite-plugin/web-collections.js.map +1 -1
  72. package/package.json +10 -5
package/AGENTS.md CHANGED
@@ -53,6 +53,44 @@ and repository rules.
53
53
  constructor, explicit package, and isolated one-object manifest. Never infer
54
54
  ownership from paths, simple names, or table names; packages can share names.
55
55
  Consumer regression gate: `packages/bundle-gate/src/__tests__/registry-identity.spec.ts`.
56
+ - API custom-action eligibility has ONE resolver, `resolveApiMethodExposure()`
57
+ in `generators/custom-action.ts`: both SvelteKit route emitters,
58
+ `resolveApiActionSet`, and `knowledge.ts` read it, and a new consumer must too
59
+ — a local mirror is how a method gets reported unavailable while its route
60
+ file is still written. A public method routes by default only when every
61
+ parameter is JSON-shaped; `@method({ expose })` overrides in both directions,
62
+ `expose: true` bypasses the heuristic ALONE, and an explicit `api.include` or
63
+ `api.routes` entry keeps its pre-#2686 route. Fail closed on scanner
64
+ uncertainty: read `parameters[].typeUnresolved`, never the `'any'` it
65
+ substitutes. Accepting `Date` as wire-able and hydrating it
66
+ (`toCustomActionDate`) are one decision — changing either breaks the other.
67
+ The runtime `APIGenerator` transport stays declaration-gated: `rest.ts`
68
+ dispatch and `preflight-route.ts` prediction both read
69
+ `declaresRuntimeRestRoute()`, which must accept every `ApiCustomRouteConfig`
70
+ option so a sweep moving one onto its method cannot delete the endpoint. Its
71
+ twin `declaresRuntimeRestRouteShape()` deliberately ignores `expose: false`:
72
+ the dispatcher must still SEE a withheld declaration to answer 404, because
73
+ `POST /<collection>/<segment>` resolves to `create` when nothing claims the
74
+ segment. Split unions and type arguments with `splitTopLevel()` — a naive
75
+ `split('|')` truncates `Record<string, Asset | null>` into fragments that
76
+ match no rule and are then accepted, widening the gate. `extractTypeName`
77
+ returns `null` for a generic with an unresolvable ARGUMENT or a union with an
78
+ unresolvable BRANCH so those reach that fail-closed path instead of arriving
79
+ as a bare `'Array'`. Runtime transports read
80
+ `ObjectRegistry.resolveRuntimeMethod()`, which tries the item class's manifest
81
+ entry, then the COLLECTION class's (where a collection-hosted action's
82
+ parameters live), then the live `@method()` store — keyed by CONSTRUCTOR,
83
+ never by simple name (`Account` exists in two packages), and recording
84
+ `isStatic` because an unscanned runtime has no manifest to recover the
85
+ receiver from. `isRestActionRoutable` ANDs "declared" with that receiver, so
86
+ it never predicts `allow` for an action dispatch refuses. A declared action
87
+ with no receiver is refused (501 collection-scoped, 404 item-scoped), never
88
+ allowed to fall through into `create`. All eight consumers read the resolver,
89
+ including `packages/smrt-workbench/src/discovery.ts`; it imports the
90
+ `./generators/custom-action` LEAF subpath, not `./generators`, because that
91
+ barrel value-re-exports `MCPGenerator` and so drags `@happyvertical/ai` and
92
+ `@happyvertical/sql` into a build-time helper (2 modules vs 109). Keep
93
+ `custom-action.ts` free of value imports outside `tools/tool-generator`.
56
94
 
57
95
  ## Gotchas
58
96
 
@@ -8,7 +8,53 @@ export interface CompatiblePropertyDecorator<This = unknown, Value = unknown> {
8
8
  (target: object, propertyKey: string | symbol): void;
9
9
  (value: undefined, context: ClassFieldDecoratorContext<This, Value>): void;
10
10
  }
11
+ /**
12
+ * A method decorator that works under BOTH decorator implementations, the same
13
+ * way {@link CompatiblePropertyDecorator} does for class fields.
14
+ *
15
+ * Legacy (TypeScript `experimentalDecorators`, and the Oxc legacy mode this
16
+ * repo builds with) calls `(target, propertyKey, descriptor)`, where `target`
17
+ * is the prototype for an instance method and the constructor for a static
18
+ * one. TC39 standard decorators call `(value, context)`. Returning `void` from
19
+ * either leaves the method untouched, which is all a metadata-only decorator
20
+ * needs (#2686).
21
+ */
22
+ /**
23
+ * The constraint `ClassMethodDecoratorContext<This, Value>` imposes on its
24
+ * `Value`, restated so this module's own generics can satisfy it. Any narrower
25
+ * spelling (`...args: never`, `unknown[]`) is rejected by the lib type, and a
26
+ * method decorator has to accept every method signature anyway.
27
+ */
28
+ type AnyMethodOf<This> = (this: This, ...args: any) => any;
29
+ type AnyMethod = (this: any, ...args: any) => any;
30
+ export type CompatibleMethodDecoratorContext<This, Value extends AnyMethodOf<This>> = string | symbol | ClassMethodDecoratorContext<This, Value>;
31
+ export interface CompatibleMethodDecorator<This = unknown, Value extends AnyMethodOf<This> = AnyMethod> {
32
+ (target: object, propertyKey: string | symbol, descriptor?: PropertyDescriptor): void;
33
+ (value: Value, context: ClassMethodDecoratorContext<This, Value>): void;
34
+ }
11
35
  export declare function resolveDecoratorClassName(target: unknown): string | undefined;
12
36
  export declare function applyPendingDecoratorRegistrations(target: Function, decoratorContext?: ClassDecoratorContext): void;
37
+ /**
38
+ * Register a method decorator's metadata under the decorated class's name,
39
+ * under whichever decorator implementation is running.
40
+ *
41
+ * The class-field twin below is the model, but the two cannot share one
42
+ * function: their legacy signatures differ (a method decorator receives a
43
+ * property descriptor as a third argument), and a static method's legacy
44
+ * `target` is the CONSTRUCTOR while an instance method's is the prototype —
45
+ * `getDecoratorConstructor` already handles both, which is why the receiver
46
+ * resolution is shared even though the entry point is not.
47
+ *
48
+ * Registration is keyed by the CONSTRUCTOR, not by its name: two packages may
49
+ * legitimately declare a class with the same simple name (`Account` exists in
50
+ * both `smrt-ledgers` and `smrt-messages`), and the kernel forbids inferring
51
+ * ownership from simple names. A name-keyed store would let one package's
52
+ * `@method({ expose: false })` withhold the other's identically-named action.
53
+ *
54
+ * Metadata-only: nothing is wrapped and nothing is returned, so the decorated
55
+ * method keeps its identity and remains directly callable (#2686).
56
+ */
57
+ export declare function registerCompatibleMethodDecorator<This, Value extends AnyMethodOf<This>>(targetOrValue: LegacyPropertyDecoratorTarget | Value | undefined, propertyKeyOrContext: CompatibleMethodDecoratorContext<This, Value>, registerMethodDecorator: (ctor: Function, methodName: string, isStatic: boolean) => void): void;
13
58
  export declare function registerCompatibleFieldDecorator<This, Value>(targetOrValue: LegacyPropertyDecoratorTarget | undefined, propertyKeyOrContext: CompatiblePropertyDecoratorContext<This, Value>, registerFieldDecorator: (className: string, propertyKey: string) => void): void;
59
+ export {};
14
60
  //# sourceMappingURL=compatibility.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"compatibility.d.ts","sourceRoot":"","sources":["../../src/decorators/compatibility.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,WAAW,CAAC,EAAE,QAAQ,GAAG;QACvB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,kCAAkC,CAAC,IAAI,EAAE,KAAK,IACtD,MAAM,GACN,MAAM,GACN,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAE5C,MAAM,WAAW,2BAA2B,CAAC,IAAI,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO;IAC1E,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACrD,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;CAC5E;AA2FD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU7E;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,QAAQ,EAChB,gBAAgB,CAAC,EAAE,qBAAqB,GACvC,IAAI,CAsBN;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,KAAK,EAC1D,aAAa,EAAE,6BAA6B,GAAG,SAAS,EACxD,oBAAoB,EAAE,kCAAkC,CAAC,IAAI,EAAE,KAAK,CAAC,EACrE,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,GACvE,IAAI,CAiCN"}
1
+ {"version":3,"file":"compatibility.d.ts","sourceRoot":"","sources":["../../src/decorators/compatibility.ts"],"names":[],"mappings":"AAcA,MAAM,MAAM,6BAA6B,GAAG;IAC1C,WAAW,CAAC,EAAE,QAAQ,GAAG;QACvB,IAAI,CAAC,EAAE,MAAM,CAAC;KACf,CAAC;CACH,CAAC;AAEF,MAAM,MAAM,kCAAkC,CAAC,IAAI,EAAE,KAAK,IACtD,MAAM,GACN,MAAM,GACN,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAE5C,MAAM,WAAW,2BAA2B,CAAC,IAAI,GAAG,OAAO,EAAE,KAAK,GAAG,OAAO;IAC1E,CAAC,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACrD,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,0BAA0B,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;CAC5E;AAED;;;;;;;;;;GAUG;AACH;;;;;GAKG;AAEH,KAAK,WAAW,CAAC,IAAI,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;AAG3D,KAAK,SAAS,GAAG,CAAC,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,EAAE,GAAG,KAAK,GAAG,CAAC;AAElD,MAAM,MAAM,gCAAgC,CAC1C,IAAI,EACJ,KAAK,SAAS,WAAW,CAAC,IAAI,CAAC,IAC7B,MAAM,GAAG,MAAM,GAAG,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AAE/D,MAAM,WAAW,yBAAyB,CACxC,IAAI,GAAG,OAAO,EACd,KAAK,SAAS,WAAW,CAAC,IAAI,CAAC,GAAG,SAAS;IAE3C,CACE,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,GAAG,MAAM,EAC5B,UAAU,CAAC,EAAE,kBAAkB,GAC9B,IAAI,CAAC;IACR,CAAC,KAAK,EAAE,KAAK,EAAE,OAAO,EAAE,2BAA2B,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,IAAI,CAAC;CACzE;AA4FD,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU7E;AAED,wBAAgB,kCAAkC,CAChD,MAAM,EAAE,QAAQ,EAChB,gBAAgB,CAAC,EAAE,qBAAqB,GACvC,IAAI,CAsBN;AAED;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,iCAAiC,CAC/C,IAAI,EACJ,KAAK,SAAS,WAAW,CAAC,IAAI,CAAC,EAE/B,aAAa,EAAE,6BAA6B,GAAG,KAAK,GAAG,SAAS,EAChE,oBAAoB,EAAE,gCAAgC,CAAC,IAAI,EAAE,KAAK,CAAC,EACnE,uBAAuB,EAAE,CACvB,IAAI,EAAE,QAAQ,EACd,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,OAAO,KACd,IAAI,GACR,IAAI,CA8CN;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,KAAK,EAC1D,aAAa,EAAE,6BAA6B,GAAG,SAAS,EACxD,oBAAoB,EAAE,kCAAkC,CAAC,IAAI,EAAE,KAAK,CAAC,EACrE,sBAAsB,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,KAAK,IAAI,GACvE,IAAI,CAqCN"}
@@ -46,10 +46,51 @@ function applyPendingDecoratorRegistrations(target, decoratorContext) {
46
46
  if (!pendingDecorators || pendingDecorators.length === 0) return;
47
47
  for (const { register } of pendingDecorators) {
48
48
  if (!markStandardDecoratorRegistration(target, register)) continue;
49
- register(target.name);
49
+ register(target);
50
50
  }
51
51
  Reflect.deleteProperty(metadata, PENDING_FIELD_DECORATORS_KEY);
52
52
  }
53
+ /**
54
+ * Register a method decorator's metadata under the decorated class's name,
55
+ * under whichever decorator implementation is running.
56
+ *
57
+ * The class-field twin below is the model, but the two cannot share one
58
+ * function: their legacy signatures differ (a method decorator receives a
59
+ * property descriptor as a third argument), and a static method's legacy
60
+ * `target` is the CONSTRUCTOR while an instance method's is the prototype —
61
+ * `getDecoratorConstructor` already handles both, which is why the receiver
62
+ * resolution is shared even though the entry point is not.
63
+ *
64
+ * Registration is keyed by the CONSTRUCTOR, not by its name: two packages may
65
+ * legitimately declare a class with the same simple name (`Account` exists in
66
+ * both `smrt-ledgers` and `smrt-messages`), and the kernel forbids inferring
67
+ * ownership from simple names. A name-keyed store would let one package's
68
+ * `@method({ expose: false })` withhold the other's identically-named action.
69
+ *
70
+ * Metadata-only: nothing is wrapped and nothing is returned, so the decorated
71
+ * method keeps its identity and remains directly callable (#2686).
72
+ */
73
+ function registerCompatibleMethodDecorator(targetOrValue, propertyKeyOrContext, registerMethodDecorator) {
74
+ if (typeof propertyKeyOrContext === "string" || typeof propertyKeyOrContext === "symbol") {
75
+ const ctor = getDecoratorConstructor(targetOrValue);
76
+ if (ctor) registerMethodDecorator(ctor, String(propertyKeyOrContext), typeof targetOrValue === "function");
77
+ return;
78
+ }
79
+ const context = propertyKeyOrContext;
80
+ const methodName = String(context.name);
81
+ const isStatic = context.static === true;
82
+ const register = (ctor) => registerMethodDecorator(ctor, methodName, isStatic);
83
+ const metadata = getDecoratorMetadata(context);
84
+ if (metadata) {
85
+ queuePendingFieldDecorator(metadata, register);
86
+ return;
87
+ }
88
+ context.addInitializer?.(function registerSmrtMethodDecorator() {
89
+ if (!markStandardDecoratorRegistration(this, register)) return;
90
+ const ctor = getDecoratorConstructor(this);
91
+ if (ctor) register(ctor);
92
+ });
93
+ }
53
94
  function registerCompatibleFieldDecorator(targetOrValue, propertyKeyOrContext, registerFieldDecorator) {
54
95
  if (typeof propertyKeyOrContext === "string" || typeof propertyKeyOrContext === "symbol") {
55
96
  const className = resolveDecoratorClassName(targetOrValue);
@@ -58,7 +99,9 @@ function registerCompatibleFieldDecorator(targetOrValue, propertyKeyOrContext, r
58
99
  }
59
100
  const context = propertyKeyOrContext;
60
101
  const propertyKey = String(context.name);
61
- const register = (className) => registerFieldDecorator(className, propertyKey);
102
+ const register = (ctor) => {
103
+ if (ctor.name) registerFieldDecorator(ctor.name, propertyKey);
104
+ };
62
105
  const metadata = getDecoratorMetadata(context);
63
106
  if (metadata) {
64
107
  queuePendingFieldDecorator(metadata, register);
@@ -66,11 +109,11 @@ function registerCompatibleFieldDecorator(targetOrValue, propertyKeyOrContext, r
66
109
  }
67
110
  context.addInitializer?.(function registerSmrtDecorator() {
68
111
  if (!markStandardDecoratorRegistration(this, register)) return;
69
- const className = resolveDecoratorClassName(this);
70
- if (className) register(className);
112
+ const ctor = getDecoratorConstructor(this);
113
+ if (ctor) register(ctor);
71
114
  });
72
115
  }
73
116
  //#endregion
74
- export { applyPendingDecoratorRegistrations, registerCompatibleFieldDecorator, resolveDecoratorClassName };
117
+ export { applyPendingDecoratorRegistrations, registerCompatibleFieldDecorator, registerCompatibleMethodDecorator, resolveDecoratorClassName };
75
118
 
76
119
  //# sourceMappingURL=compatibility.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"compatibility.js","names":[],"sources":["../../src/decorators/compatibility.ts"],"sourcesContent":["type DecoratorMetadataStore = Record<PropertyKey, unknown>;\n\nconst PENDING_FIELD_DECORATORS_KEY = Symbol.for(\n '@happyvertical/smrt-core/pending-field-decorators',\n);\nconst standardDecoratorRegistrations = new WeakMap<\n Function,\n WeakSet<(className: string) => void>\n>();\n\ntype PendingDecoratorRegistration = {\n register: (className: string) => void;\n};\n\nexport type LegacyPropertyDecoratorTarget = {\n constructor?: Function & {\n name?: string;\n };\n};\n\nexport type CompatiblePropertyDecoratorContext<This, Value> =\n | string\n | symbol\n | ClassFieldDecoratorContext<This, Value>;\n\nexport interface CompatiblePropertyDecorator<This = unknown, Value = unknown> {\n (target: object, propertyKey: string | symbol): void;\n (value: undefined, context: ClassFieldDecoratorContext<This, Value>): void;\n}\n\nfunction getDecoratorConstructor(target: unknown): Function | undefined {\n if (typeof target === 'function') {\n return target;\n }\n\n if (target && typeof target === 'object') {\n return (target as LegacyPropertyDecoratorTarget).constructor;\n }\n\n return undefined;\n}\n\nfunction markStandardDecoratorRegistration(\n target: unknown,\n register: (className: string) => void,\n): boolean {\n const ctor = getDecoratorConstructor(target);\n if (!ctor) {\n return false;\n }\n\n const registeredCallbacks =\n standardDecoratorRegistrations.get(ctor) ?? new WeakSet();\n if (registeredCallbacks.has(register)) {\n return false;\n }\n\n registeredCallbacks.add(register);\n standardDecoratorRegistrations.set(ctor, registeredCallbacks);\n return true;\n}\n\nfunction getDecoratorMetadata(\n contextOrMetadata:\n | ClassFieldDecoratorContext<unknown, unknown>\n | ClassDecoratorContext\n | DecoratorMetadataStore\n | undefined,\n): DecoratorMetadataStore | undefined {\n if (!contextOrMetadata || typeof contextOrMetadata !== 'object') {\n return undefined;\n }\n\n if ('metadata' in contextOrMetadata) {\n const { metadata } = contextOrMetadata as {\n metadata?: DecoratorMetadataStore;\n };\n return metadata && typeof metadata === 'object' ? metadata : undefined;\n }\n\n return contextOrMetadata;\n}\n\nfunction getClassDecoratorMetadata(\n target: Function,\n decoratorContext?: ClassDecoratorContext,\n): DecoratorMetadataStore | undefined {\n const metadataFromContext = getDecoratorMetadata(decoratorContext);\n if (metadataFromContext) {\n return metadataFromContext;\n }\n\n const metadataSymbol = (Symbol as typeof Symbol & { metadata?: symbol })\n .metadata;\n if (!metadataSymbol) {\n return undefined;\n }\n\n const metadata = (target as unknown as Record<PropertyKey, unknown>)[\n metadataSymbol\n ];\n return metadata && typeof metadata === 'object'\n ? (metadata as DecoratorMetadataStore)\n : undefined;\n}\n\nfunction queuePendingFieldDecorator(\n metadata: DecoratorMetadataStore,\n register: (className: string) => void,\n): void {\n const pendingDecorators =\n (metadata[PENDING_FIELD_DECORATORS_KEY] as\n | PendingDecoratorRegistration[]\n | undefined) ?? [];\n\n pendingDecorators.push({ register });\n metadata[PENDING_FIELD_DECORATORS_KEY] = pendingDecorators;\n}\n\nexport function resolveDecoratorClassName(target: unknown): string | undefined {\n if (typeof target === 'function') {\n return target.name;\n }\n\n if (target && typeof target === 'object') {\n return (target as LegacyPropertyDecoratorTarget).constructor?.name;\n }\n\n return undefined;\n}\n\nexport function applyPendingDecoratorRegistrations(\n target: Function,\n decoratorContext?: ClassDecoratorContext,\n): void {\n const metadata = getClassDecoratorMetadata(target, decoratorContext);\n if (!metadata) {\n return;\n }\n\n const pendingDecorators = metadata[PENDING_FIELD_DECORATORS_KEY] as\n | PendingDecoratorRegistration[]\n | undefined;\n if (!pendingDecorators || pendingDecorators.length === 0) {\n return;\n }\n\n for (const { register } of pendingDecorators) {\n if (!markStandardDecoratorRegistration(target, register)) {\n continue;\n }\n\n register(target.name);\n }\n\n Reflect.deleteProperty(metadata, PENDING_FIELD_DECORATORS_KEY);\n}\n\nexport function registerCompatibleFieldDecorator<This, Value>(\n targetOrValue: LegacyPropertyDecoratorTarget | undefined,\n propertyKeyOrContext: CompatiblePropertyDecoratorContext<This, Value>,\n registerFieldDecorator: (className: string, propertyKey: string) => void,\n): void {\n if (\n typeof propertyKeyOrContext === 'string' ||\n typeof propertyKeyOrContext === 'symbol'\n ) {\n const className = resolveDecoratorClassName(targetOrValue);\n if (className) {\n registerFieldDecorator(className, String(propertyKeyOrContext));\n }\n return;\n }\n\n const context = propertyKeyOrContext;\n const propertyKey = String(context.name);\n const register = (className: string) =>\n registerFieldDecorator(className, propertyKey);\n const metadata = getDecoratorMetadata(context);\n\n if (metadata) {\n queuePendingFieldDecorator(metadata, register);\n return;\n }\n\n context.addInitializer?.(function registerSmrtDecorator() {\n if (!markStandardDecoratorRegistration(this, register)) {\n return;\n }\n\n const className = resolveDecoratorClassName(this);\n if (className) {\n register(className);\n }\n });\n}\n"],"mappings":";AAEA,IAAM,+BAA+B,OAAO,IAC1C,mDACF;AACA,IAAM,iDAAiC,IAAI,QAGzC;AAsBF,SAAS,wBAAwB,QAAuC;CACtE,IAAI,OAAO,WAAW,YACpB,OAAO;CAGT,IAAI,UAAU,OAAO,WAAW,UAC9B,OAAQ,OAAyC;AAIrD;AAEA,SAAS,kCACP,QACA,UACS;CACT,MAAM,OAAO,wBAAwB,MAAM;CAC3C,IAAI,CAAC,MACH,OAAO;CAGT,MAAM,sBACJ,+BAA+B,IAAI,IAAI,qBAAK,IAAI,QAAQ;CAC1D,IAAI,oBAAoB,IAAI,QAAQ,GAClC,OAAO;CAGT,oBAAoB,IAAI,QAAQ;CAChC,+BAA+B,IAAI,MAAM,mBAAmB;CAC5D,OAAO;AACT;AAEA,SAAS,qBACP,mBAKoC;CACpC,IAAI,CAAC,qBAAqB,OAAO,sBAAsB,UACrD;CAGF,IAAI,cAAc,mBAAmB;EACnC,MAAM,EAAE,aAAa;EAGrB,OAAO,YAAY,OAAO,aAAa,WAAW,WAAW,KAAA;CAC/D;CAEA,OAAO;AACT;AAEA,SAAS,0BACP,QACA,kBACoC;CACpC,MAAM,sBAAsB,qBAAqB,gBAAgB;CACjE,IAAI,qBACF,OAAO;CAGT,MAAM,iBAAkB,OACrB;CACH,IAAI,CAAC,gBACH;CAGF,MAAM,WAAY,OAChB;CAEF,OAAO,YAAY,OAAO,aAAa,WAClC,WACD,KAAA;AACN;AAEA,SAAS,2BACP,UACA,UACM;CACN,MAAM,oBACH,SAAS,iCAEQ,CAAC;CAErB,kBAAkB,KAAK,EAAE,SAAS,CAAC;CACnC,SAAS,gCAAgC;AAC3C;AAEA,SAAgB,0BAA0B,QAAqC;CAC7E,IAAI,OAAO,WAAW,YACpB,OAAO,OAAO;CAGhB,IAAI,UAAU,OAAO,WAAW,UAC9B,OAAQ,OAAyC,aAAa;AAIlE;AAEA,SAAgB,mCACd,QACA,kBACM;CACN,MAAM,WAAW,0BAA0B,QAAQ,gBAAgB;CACnE,IAAI,CAAC,UACH;CAGF,MAAM,oBAAoB,SAAS;CAGnC,IAAI,CAAC,qBAAqB,kBAAkB,WAAW,GACrD;CAGF,KAAK,MAAM,EAAE,cAAc,mBAAmB;EAC5C,IAAI,CAAC,kCAAkC,QAAQ,QAAQ,GACrD;EAGF,SAAS,OAAO,IAAI;CACtB;CAEA,QAAQ,eAAe,UAAU,4BAA4B;AAC/D;AAEA,SAAgB,iCACd,eACA,sBACA,wBACM;CACN,IACE,OAAO,yBAAyB,YAChC,OAAO,yBAAyB,UAChC;EACA,MAAM,YAAY,0BAA0B,aAAa;EACzD,IAAI,WACF,uBAAuB,WAAW,OAAO,oBAAoB,CAAC;EAEhE;CACF;CAEA,MAAM,UAAU;CAChB,MAAM,cAAc,OAAO,QAAQ,IAAI;CACvC,MAAM,YAAY,cAChB,uBAAuB,WAAW,WAAW;CAC/C,MAAM,WAAW,qBAAqB,OAAO;CAE7C,IAAI,UAAU;EACZ,2BAA2B,UAAU,QAAQ;EAC7C;CACF;CAEA,QAAQ,iBAAiB,SAAS,wBAAwB;EACxD,IAAI,CAAC,kCAAkC,MAAM,QAAQ,GACnD;EAGF,MAAM,YAAY,0BAA0B,IAAI;EAChD,IAAI,WACF,SAAS,SAAS;CAEtB,CAAC;AACH"}
1
+ {"version":3,"file":"compatibility.js","names":[],"sources":["../../src/decorators/compatibility.ts"],"sourcesContent":["type DecoratorMetadataStore = Record<PropertyKey, unknown>;\n\nconst PENDING_FIELD_DECORATORS_KEY = Symbol.for(\n '@happyvertical/smrt-core/pending-field-decorators',\n);\nconst standardDecoratorRegistrations = new WeakMap<\n Function,\n WeakSet<(ctor: Function) => void>\n>();\n\ntype PendingDecoratorRegistration = {\n register: (ctor: Function) => void;\n};\n\nexport type LegacyPropertyDecoratorTarget = {\n constructor?: Function & {\n name?: string;\n };\n};\n\nexport type CompatiblePropertyDecoratorContext<This, Value> =\n | string\n | symbol\n | ClassFieldDecoratorContext<This, Value>;\n\nexport interface CompatiblePropertyDecorator<This = unknown, Value = unknown> {\n (target: object, propertyKey: string | symbol): void;\n (value: undefined, context: ClassFieldDecoratorContext<This, Value>): void;\n}\n\n/**\n * A method decorator that works under BOTH decorator implementations, the same\n * way {@link CompatiblePropertyDecorator} does for class fields.\n *\n * Legacy (TypeScript `experimentalDecorators`, and the Oxc legacy mode this\n * repo builds with) calls `(target, propertyKey, descriptor)`, where `target`\n * is the prototype for an instance method and the constructor for a static\n * one. TC39 standard decorators call `(value, context)`. Returning `void` from\n * either leaves the method untouched, which is all a metadata-only decorator\n * needs (#2686).\n */\n/**\n * The constraint `ClassMethodDecoratorContext<This, Value>` imposes on its\n * `Value`, restated so this module's own generics can satisfy it. Any narrower\n * spelling (`...args: never`, `unknown[]`) is rejected by the lib type, and a\n * method decorator has to accept every method signature anyway.\n */\n// biome-ignore lint/suspicious/noExplicitAny: mirrors the lib's own `ClassMethodDecoratorContext` constraint; a narrower type does not satisfy it. Same rationale as `SmrtObjectConstructor` in registry/types.ts. S4 #1579.\ntype AnyMethodOf<This> = (this: This, ...args: any) => any;\n\n// biome-ignore lint/suspicious/noExplicitAny: see AnyMethodOf above. S4 #1579.\ntype AnyMethod = (this: any, ...args: any) => any;\n\nexport type CompatibleMethodDecoratorContext<\n This,\n Value extends AnyMethodOf<This>,\n> = string | symbol | ClassMethodDecoratorContext<This, Value>;\n\nexport interface CompatibleMethodDecorator<\n This = unknown,\n Value extends AnyMethodOf<This> = AnyMethod,\n> {\n (\n target: object,\n propertyKey: string | symbol,\n descriptor?: PropertyDescriptor,\n ): void;\n (value: Value, context: ClassMethodDecoratorContext<This, Value>): void;\n}\n\nfunction getDecoratorConstructor(target: unknown): Function | undefined {\n if (typeof target === 'function') {\n return target;\n }\n\n if (target && typeof target === 'object') {\n return (target as LegacyPropertyDecoratorTarget).constructor;\n }\n\n return undefined;\n}\n\nfunction markStandardDecoratorRegistration(\n target: unknown,\n register: (ctor: Function) => void,\n): boolean {\n const ctor = getDecoratorConstructor(target);\n if (!ctor) {\n return false;\n }\n\n const registeredCallbacks =\n standardDecoratorRegistrations.get(ctor) ?? new WeakSet();\n if (registeredCallbacks.has(register)) {\n return false;\n }\n\n registeredCallbacks.add(register);\n standardDecoratorRegistrations.set(ctor, registeredCallbacks);\n return true;\n}\n\nfunction getDecoratorMetadata(\n contextOrMetadata:\n | ClassFieldDecoratorContext<unknown, unknown>\n | ClassMethodDecoratorContext<unknown, AnyMethod>\n | ClassDecoratorContext\n | DecoratorMetadataStore\n | undefined,\n): DecoratorMetadataStore | undefined {\n if (!contextOrMetadata || typeof contextOrMetadata !== 'object') {\n return undefined;\n }\n\n if ('metadata' in contextOrMetadata) {\n const { metadata } = contextOrMetadata as {\n metadata?: DecoratorMetadataStore;\n };\n return metadata && typeof metadata === 'object' ? metadata : undefined;\n }\n\n return contextOrMetadata;\n}\n\nfunction getClassDecoratorMetadata(\n target: Function,\n decoratorContext?: ClassDecoratorContext,\n): DecoratorMetadataStore | undefined {\n const metadataFromContext = getDecoratorMetadata(decoratorContext);\n if (metadataFromContext) {\n return metadataFromContext;\n }\n\n const metadataSymbol = (Symbol as typeof Symbol & { metadata?: symbol })\n .metadata;\n if (!metadataSymbol) {\n return undefined;\n }\n\n const metadata = (target as unknown as Record<PropertyKey, unknown>)[\n metadataSymbol\n ];\n return metadata && typeof metadata === 'object'\n ? (metadata as DecoratorMetadataStore)\n : undefined;\n}\n\nfunction queuePendingFieldDecorator(\n metadata: DecoratorMetadataStore,\n register: (ctor: Function) => void,\n): void {\n const pendingDecorators =\n (metadata[PENDING_FIELD_DECORATORS_KEY] as\n | PendingDecoratorRegistration[]\n | undefined) ?? [];\n\n pendingDecorators.push({ register });\n metadata[PENDING_FIELD_DECORATORS_KEY] = pendingDecorators;\n}\n\nexport function resolveDecoratorClassName(target: unknown): string | undefined {\n if (typeof target === 'function') {\n return target.name;\n }\n\n if (target && typeof target === 'object') {\n return (target as LegacyPropertyDecoratorTarget).constructor?.name;\n }\n\n return undefined;\n}\n\nexport function applyPendingDecoratorRegistrations(\n target: Function,\n decoratorContext?: ClassDecoratorContext,\n): void {\n const metadata = getClassDecoratorMetadata(target, decoratorContext);\n if (!metadata) {\n return;\n }\n\n const pendingDecorators = metadata[PENDING_FIELD_DECORATORS_KEY] as\n | PendingDecoratorRegistration[]\n | undefined;\n if (!pendingDecorators || pendingDecorators.length === 0) {\n return;\n }\n\n for (const { register } of pendingDecorators) {\n if (!markStandardDecoratorRegistration(target, register)) {\n continue;\n }\n\n register(target);\n }\n\n Reflect.deleteProperty(metadata, PENDING_FIELD_DECORATORS_KEY);\n}\n\n/**\n * Register a method decorator's metadata under the decorated class's name,\n * under whichever decorator implementation is running.\n *\n * The class-field twin below is the model, but the two cannot share one\n * function: their legacy signatures differ (a method decorator receives a\n * property descriptor as a third argument), and a static method's legacy\n * `target` is the CONSTRUCTOR while an instance method's is the prototype —\n * `getDecoratorConstructor` already handles both, which is why the receiver\n * resolution is shared even though the entry point is not.\n *\n * Registration is keyed by the CONSTRUCTOR, not by its name: two packages may\n * legitimately declare a class with the same simple name (`Account` exists in\n * both `smrt-ledgers` and `smrt-messages`), and the kernel forbids inferring\n * ownership from simple names. A name-keyed store would let one package's\n * `@method({ expose: false })` withhold the other's identically-named action.\n *\n * Metadata-only: nothing is wrapped and nothing is returned, so the decorated\n * method keeps its identity and remains directly callable (#2686).\n */\nexport function registerCompatibleMethodDecorator<\n This,\n Value extends AnyMethodOf<This>,\n>(\n targetOrValue: LegacyPropertyDecoratorTarget | Value | undefined,\n propertyKeyOrContext: CompatibleMethodDecoratorContext<This, Value>,\n registerMethodDecorator: (\n ctor: Function,\n methodName: string,\n isStatic: boolean,\n ) => void,\n): void {\n if (\n typeof propertyKeyOrContext === 'string' ||\n typeof propertyKeyOrContext === 'symbol'\n ) {\n // Legacy decorators hand a STATIC method its constructor and an instance\n // method its prototype. That distinction IS the method's receiver, and\n // nothing downstream can recover it in an unscanned runtime, so capture it\n // here (#2686).\n const ctor = getDecoratorConstructor(targetOrValue);\n if (ctor) {\n registerMethodDecorator(\n ctor,\n String(propertyKeyOrContext),\n typeof targetOrValue === 'function',\n );\n }\n return;\n }\n\n const context = propertyKeyOrContext;\n const methodName = String(context.name);\n // Standard decorators state the receiver outright.\n const isStatic = context.static === true;\n const register = (ctor: Function) =>\n registerMethodDecorator(ctor, methodName, isStatic);\n const metadata = getDecoratorMetadata(context);\n\n if (metadata) {\n queuePendingFieldDecorator(metadata, register);\n return;\n }\n\n context.addInitializer?.(function registerSmrtMethodDecorator(this: unknown) {\n // A static method's initializer runs with the constructor as `this`; an\n // instance method's runs with the instance. `getDecoratorConstructor`\n // reads the constructor in the latter case, so both land on the same class.\n if (!markStandardDecoratorRegistration(this, register)) {\n return;\n }\n\n const ctor = getDecoratorConstructor(this);\n if (ctor) {\n register(ctor);\n }\n });\n}\n\nexport function registerCompatibleFieldDecorator<This, Value>(\n targetOrValue: LegacyPropertyDecoratorTarget | undefined,\n propertyKeyOrContext: CompatiblePropertyDecoratorContext<This, Value>,\n registerFieldDecorator: (className: string, propertyKey: string) => void,\n): void {\n if (\n typeof propertyKeyOrContext === 'string' ||\n typeof propertyKeyOrContext === 'symbol'\n ) {\n const className = resolveDecoratorClassName(targetOrValue);\n if (className) {\n registerFieldDecorator(className, String(propertyKeyOrContext));\n }\n return;\n }\n\n const context = propertyKeyOrContext;\n const propertyKey = String(context.name);\n // The shared queue passes the CONSTRUCTOR (the method arm needs an identity a\n // simple name cannot provide); field registration keeps its name-keyed store,\n // so it derives the name here.\n const register = (ctor: Function) => {\n if (ctor.name) registerFieldDecorator(ctor.name, propertyKey);\n };\n const metadata = getDecoratorMetadata(context);\n\n if (metadata) {\n queuePendingFieldDecorator(metadata, register);\n return;\n }\n\n context.addInitializer?.(function registerSmrtDecorator() {\n if (!markStandardDecoratorRegistration(this, register)) {\n return;\n }\n\n const ctor = getDecoratorConstructor(this);\n if (ctor) {\n register(ctor);\n }\n });\n}\n"],"mappings":"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"}
@@ -1,6 +1,8 @@
1
+ import { CustomActionScope, ToolEffect } from '../generators/custom-action.js';
2
+ import { ApiHttpMethod } from '../registry/types.js';
1
3
  import { FieldUIHints } from '../scanner/types.js';
2
4
  import { SQLDataType } from '../schema/types.js';
3
- import { CompatiblePropertyDecorator } from './compatibility.js';
5
+ import { CompatibleMethodDecorator, CompatiblePropertyDecorator } from './compatibility.js';
4
6
  export type { FieldUIHints } from '../scanner/types.js';
5
7
  /**
6
8
  * Meta type wrapper for STI (Single Table Inheritance) meta fields
@@ -513,4 +515,120 @@ export declare function manyToMany(relatedClass: string | Function, options?: Om
513
515
  * @see {@link field} for regular (non-STI) field declarations
514
516
  */
515
517
  export declare function meta(options?: FieldOptions): CompatiblePropertyDecorator;
518
+ /**
519
+ * Options for {@link method}.
520
+ *
521
+ * Every option is optional, and an omitted one falls back to the class-level
522
+ * `api.routes[methodName]` entry (or `ai.descriptions[methodName]` for
523
+ * `description`) when one exists. The merge is FIELD BY FIELD, so adding
524
+ * `@method({ description })` to a class that already declares a route verb and
525
+ * path does not reset them (#2686).
526
+ */
527
+ export interface MethodOptions {
528
+ /**
529
+ * Override the default routing decision.
530
+ *
531
+ * Public methods are routed by default when they are WIRE-ABLE: every
532
+ * parameter can be built from a JSON request body or query string. Set
533
+ * `false` to withhold a method the heuristic accepted, `true` to expose one
534
+ * it rejected.
535
+ *
536
+ * `true` bypasses the heuristic and NOTHING else. It cannot manufacture a
537
+ * receiver, undo `api: false`, cross an `include`/`exclude` boundary, reach a
538
+ * non-public method, claim a CRUD verb, or hydrate a value the transport
539
+ * cannot build — a model-instance parameter still arrives as whatever JSON
540
+ * the caller sent.
541
+ */
542
+ expose?: boolean;
543
+ /**
544
+ * Why the method is withheld. Recorded in the knowledge artifact so
545
+ * `smrt doctor` and agents read an explanation instead of silence.
546
+ */
547
+ reason?: string;
548
+ /**
549
+ * HTTP verb for the generated route. Defaults to `POST`.
550
+ *
551
+ * Named `httpMethod`, not `method`: RFC 9110 calls this the request
552
+ * "method", so the protocol word is exactly the one that collides with the
553
+ * decorator's own name, and `@method({ method: 'POST' })` stutters.
554
+ * `httpMethod` is also already this framework's name for it — `ApiHttpMethod`
555
+ * is carried across the whole discovery/invoke path.
556
+ *
557
+ * Migrates from `api.routes[methodName].method`.
558
+ */
559
+ httpMethod?: ApiHttpMethod;
560
+ /**
561
+ * Route path segment(s), used verbatim and split on `/`.
562
+ * Defaults to the method name. Migrates from `api.routes[methodName].path`.
563
+ */
564
+ path?: string;
565
+ /**
566
+ * Declared receiver scope. Migrates from `api.routes[methodName].scope`.
567
+ *
568
+ * A DECLARATION checked against the method's executable receiver, not a
569
+ * relocation: an instance method is item-scoped and a static (or
570
+ * collection-class) method is collection-scoped, and no config can change
571
+ * that. A contradicting value is reported at build time and ignored.
572
+ */
573
+ scope?: CustomActionScope;
574
+ /**
575
+ * Agent-visible effect classification. Omitted actions are treated as
576
+ * `destructive`, so missing metadata can never widen browser capability
577
+ * exposure. Migrates from `api.routes[methodName].effect`.
578
+ */
579
+ effect?: ToolEffect;
580
+ /** Whether repeating the action with the same arguments is safe. */
581
+ idempotent?: boolean;
582
+ /** Whether the action may interact outside the SMRT application. */
583
+ openWorld?: boolean;
584
+ /**
585
+ * Description used by AI/tool surfaces, overriding the method's JSDoc.
586
+ * Migrates from `ai.descriptions[methodName]`.
587
+ */
588
+ description?: string;
589
+ }
590
+ /**
591
+ * Refines how a method is exposed on generated surfaces.
592
+ *
593
+ * The method counterpart of {@link field}, and symmetric with it: a manifest
594
+ * records exactly two collections per object, `fields` and `methods`. Neither
595
+ * decorator DECLARES its member — a property is a field because it is a
596
+ * property, and a method is a candidate action because it is public — both
597
+ * REFINE what the framework already inferred. `@field()` refines an inferred
598
+ * column type and constraints; `@method()` refines inferred exposure, its
599
+ * route shape, and its tool semantics.
600
+ *
601
+ * The name is `@method()` rather than `@action()` because of the negative
602
+ * case: withholding a method has to read correctly, and
603
+ * `@action({ expose: false })` contradicts itself — declaring something an
604
+ * action in order to say it is not one. "Action" keeps its established meaning
605
+ * in the generators (a non-CRUD method exposed on a surface); this decorator
606
+ * is how a method BECOMES one.
607
+ *
608
+ * Metadata only: the decorated method is not wrapped and keeps its identity,
609
+ * so it stays directly callable.
610
+ *
611
+ * @example Shape the generated route
612
+ * ```typescript
613
+ * @method({ httpMethod: 'POST', path: 'reviews', effect: 'write' })
614
+ * async runReview(options?: RunContentReviewOptions) { … }
615
+ * ```
616
+ *
617
+ * @example Withhold a method the heuristic would have routed
618
+ * ```typescript
619
+ * @method({ expose: false, reason: 'callback registration, not a wire operation' })
620
+ * static registerValidator(validator: ValidatorFunction) { … }
621
+ * ```
622
+ *
623
+ * @example Force a route the heuristic rejected
624
+ * ```typescript
625
+ * // `expose: true` bypasses the heuristic only — this method must still
626
+ * // accept whatever JSON the caller sends for `asset`.
627
+ * @method({ expose: true })
628
+ * async addAsset(asset: Asset) { … }
629
+ * ```
630
+ *
631
+ * @see {@link field} for the property-side refinement decorator
632
+ */
633
+ export declare function method(options?: MethodOptions): CompatibleMethodDecorator;
516
634
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/decorators/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,UAAU,EACX,MAAM,gCAAgC,CAAC;AACxC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EACL,KAAK,yBAAyB,EAE9B,KAAK,2BAA2B,EAKjC,MAAM,oBAAoB,CAAC;AAE5B,YAAY,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,MAAM,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC;AAExB;;GAEG;AACH,MAAM,MAAM,kBAAkB,GAC1B,MAAM,GACN,SAAS,GACT,SAAS,GACT,SAAS,GACT,UAAU,GACV,MAAM,CAAC;AAEX,MAAM,MAAM,SAAS,GACjB,kBAAkB,GAClB,MAAM,GACN,YAAY,GACZ,iBAAiB,GACjB,WAAW,GACX,YAAY,CAAC;AAEjB,MAAM,WAAW,YAAY;IAC3B,8DAA8D;IAC9D,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,8EAA8E;IAC9E,OAAO,CAAC,EAAE,WAAW,CAAC;IACtB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,kCAAkC;IAClC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kCAAkC;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,yDAAyD;IACzD,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;;;;;;OAWG;IACH,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB;;;;;;OAMG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,wBAAwB;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;;;;;OAQG;IACH,EAAE,CAAC,EAAE,YAAY,CAAC;IAClB;;;;;OAKG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAiB,SAAQ,YAAY;IACpD,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC3B;AAED;;GAEG;AACH,MAAM,WAAW,mBAAoB,SAAQ,YAAY;IACvD,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,oBAAoB;IACpB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED;;GAEG;AACH,MAAM,WAAW,wBAAyB,SAAQ,YAAY;IAC5D,yBAAyB;IACzB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,6BAA6B;IAC7B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qCAAqC;IACrC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,IAAI,CAAC,EAAE,YAAY,GAAG,iBAAiB,GAAG,WAAW,GAAG,YAAY,CAAC;IACrE;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,QAAQ,CAAC,EAAE,SAAS,GAAG,UAAU,GAAG,UAAU,GAAG,WAAW,CAAC;IAC7D;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EACP,OAAO,GACP;QACE;;;;;;;WAOG;QACH,OAAO,EAAE,KAAK,CAAC,UAAU,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;KAC3D,CAAC;CACP;AAED;;GAEG;AACH,MAAM,WAAW,sBACf,SAAQ,IAAI,CAAC,wBAAwB,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1D;;;;;OAKG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;;;;;;;;OASG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAyFD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AACH,wBAAgB,KAAK,CACnB,OAAO,GAAE,YAAY,GAAG,mBAAmB,GAAG,gBAAqB,GAa7D,2BAA2B,CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,GAAG,QAAQ,EAC/B,OAAO,GAAE,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAM,GAsBjD,2BAA2B,CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE,sBAA2B,GAiB9B,2BAA2B,CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqEG;AACH,wBAAgB,SAAS,CACvB,YAAY,EAAE,MAAM,GAAG,QAAQ,EAC/B,OAAO,GAAE,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAM,GAuBjD,2BAA2B,CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,wBAAgB,UAAU,CACxB,YAAY,EAAE,MAAM,GAAG,QAAQ,EAC/B,OAAO,GAAE,IAAI,CAAC,wBAAwB,EAAE,SAAS,CAAM,GAuBjD,2BAA2B,CAClC;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,wBAAgB,IAAI,CAAC,OAAO,GAAE,YAAiB,GAevC,2BAA2B,CAClC;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,aAAa;IAC5B;;;;;;;;;;;;;OAaG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;IAEjB;;;OAGG;IACH,MAAM,CAAC,EAAE,MAAM,CAAC;IAEhB;;;;;;;;;;OAUG;IACH,UAAU,CAAC,EAAE,aAAa,CAAC;IAE3B;;;OAGG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IAEd;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAE1B;;;;OAIG;IACH,MAAM,CAAC,EAAE,UAAU,CAAC;IAEpB,oEAAoE;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IAErB,oEAAoE;IACpE,SAAS,CAAC,EAAE,OAAO,CAAC;IAEpB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,wBAAgB,MAAM,CAAC,OAAO,GAAE,aAAkB,GAqB1C,yBAAyB,CAChC"}
@@ -1,13 +1,7 @@
1
- import { registerCompatibleFieldDecorator } from "./compatibility.js";
1
+ import { registerCompatibleFieldDecorator, registerCompatibleMethodDecorator } from "./compatibility.js";
2
2
  import { ObjectRegistry } from "../registry.js";
3
3
  //#region src/decorators/index.ts
4
4
  /**
5
- * Field decorators for SMRT objects
6
- *
7
- * Modern decorator-based API for defining SMRT object properties.
8
- * Properties are typed as primitives with decorator metadata.
9
- */
10
- /**
11
5
  * Resolve a relationship decorator's target argument to a class name.
12
6
  *
13
7
  * Accepted target forms:
@@ -407,7 +401,57 @@ function meta(options = {}) {
407
401
  });
408
402
  });
409
403
  }
404
+ /**
405
+ * Refines how a method is exposed on generated surfaces.
406
+ *
407
+ * The method counterpart of {@link field}, and symmetric with it: a manifest
408
+ * records exactly two collections per object, `fields` and `methods`. Neither
409
+ * decorator DECLARES its member — a property is a field because it is a
410
+ * property, and a method is a candidate action because it is public — both
411
+ * REFINE what the framework already inferred. `@field()` refines an inferred
412
+ * column type and constraints; `@method()` refines inferred exposure, its
413
+ * route shape, and its tool semantics.
414
+ *
415
+ * The name is `@method()` rather than `@action()` because of the negative
416
+ * case: withholding a method has to read correctly, and
417
+ * `@action({ expose: false })` contradicts itself — declaring something an
418
+ * action in order to say it is not one. "Action" keeps its established meaning
419
+ * in the generators (a non-CRUD method exposed on a surface); this decorator
420
+ * is how a method BECOMES one.
421
+ *
422
+ * Metadata only: the decorated method is not wrapped and keeps its identity,
423
+ * so it stays directly callable.
424
+ *
425
+ * @example Shape the generated route
426
+ * ```typescript
427
+ * @method({ httpMethod: 'POST', path: 'reviews', effect: 'write' })
428
+ * async runReview(options?: RunContentReviewOptions) { … }
429
+ * ```
430
+ *
431
+ * @example Withhold a method the heuristic would have routed
432
+ * ```typescript
433
+ * @method({ expose: false, reason: 'callback registration, not a wire operation' })
434
+ * static registerValidator(validator: ValidatorFunction) { … }
435
+ * ```
436
+ *
437
+ * @example Force a route the heuristic rejected
438
+ * ```typescript
439
+ * // `expose: true` bypasses the heuristic only — this method must still
440
+ * // accept whatever JSON the caller sends for `asset`.
441
+ * @method({ expose: true })
442
+ * async addAsset(asset: Asset) { … }
443
+ * ```
444
+ *
445
+ * @see {@link field} for the property-side refinement decorator
446
+ */
447
+ function method(options = {}) {
448
+ return ((targetOrValue, propertyKeyOrContext) => {
449
+ registerCompatibleMethodDecorator(targetOrValue, propertyKeyOrContext, (ctor, methodName, isStatic) => {
450
+ ObjectRegistry.registerMethodDecorator(ctor, methodName, options, isStatic);
451
+ });
452
+ });
453
+ }
410
454
  //#endregion
411
- export { crossPackageRef, field, foreignKey, manyToMany, meta, oneToMany };
455
+ export { crossPackageRef, field, foreignKey, manyToMany, meta, method, oneToMany };
412
456
 
413
457
  //# sourceMappingURL=index.js.map