@happyvertical/smrt-core 0.55.24 → 0.56.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 (66) hide show
  1. package/agents/collection-reads.md +6 -3
  2. package/agents/generators.md +16 -0
  3. package/agents/object-runtime.md +3 -0
  4. package/agents/recipes.md +7 -4
  5. package/dist/browser.d.ts +1 -0
  6. package/dist/browser.d.ts.map +1 -1
  7. package/dist/browser.js +2 -1
  8. package/dist/collection.d.ts +4 -0
  9. package/dist/collection.d.ts.map +1 -1
  10. package/dist/collection.js +19 -9
  11. package/dist/collection.js.map +1 -1
  12. package/dist/consumer-plugin/hosted-sti-collections.d.ts.map +1 -1
  13. package/dist/consumer-plugin/hosted-sti-collections.js +4 -2
  14. package/dist/consumer-plugin/hosted-sti-collections.js.map +1 -1
  15. package/dist/decorators/index.d.ts +2 -0
  16. package/dist/decorators/index.d.ts.map +1 -1
  17. package/dist/decorators/index.js.map +1 -1
  18. package/dist/generators/mcp.d.ts.map +1 -1
  19. package/dist/generators/mcp.js +4 -2
  20. package/dist/generators/mcp.js.map +1 -1
  21. package/dist/generators/preflight-route.d.ts.map +1 -1
  22. package/dist/generators/preflight-route.js +3 -1
  23. package/dist/generators/preflight-route.js.map +1 -1
  24. package/dist/generators/rest.d.ts.map +1 -1
  25. package/dist/generators/rest.js +5 -0
  26. package/dist/generators/rest.js.map +1 -1
  27. package/dist/generators/swagger.d.ts.map +1 -1
  28. package/dist/generators/swagger.js +3 -1
  29. package/dist/generators/swagger.js.map +1 -1
  30. package/dist/index.d.ts +1 -0
  31. package/dist/index.d.ts.map +1 -1
  32. package/dist/index.js +2 -1
  33. package/dist/manifest/static-manifest.d.ts.map +1 -1
  34. package/dist/manifest/static-manifest.js +9 -1
  35. package/dist/manifest/static-manifest.js.map +1 -1
  36. package/dist/manifest/store.js +1 -1
  37. package/dist/manifest/store.js.map +1 -1
  38. package/dist/manifest.json +9 -1
  39. package/dist/object.d.ts +2 -0
  40. package/dist/object.d.ts.map +1 -1
  41. package/dist/object.js +51 -0
  42. package/dist/object.js.map +1 -1
  43. package/dist/operation-permission.d.ts +10 -0
  44. package/dist/operation-permission.d.ts.map +1 -0
  45. package/dist/operation-permission.js +36 -0
  46. package/dist/operation-permission.js.map +1 -0
  47. package/dist/registry/class-registration.d.ts.map +1 -1
  48. package/dist/registry/class-registration.js +12 -0
  49. package/dist/registry/class-registration.js.map +1 -1
  50. package/dist/registry/types.d.ts +5 -3
  51. package/dist/registry/types.d.ts.map +1 -1
  52. package/dist/scanner/manifest-generator.d.ts.map +1 -1
  53. package/dist/scanner/manifest-generator.js +47 -0
  54. package/dist/scanner/manifest-generator.js.map +1 -1
  55. package/dist/scanner/types.d.ts +5 -0
  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 +16 -11
  59. package/dist/vite-plugin/api-client-entries.d.ts.map +1 -1
  60. package/dist/vite-plugin/api-client-entries.js +1 -0
  61. package/dist/vite-plugin/api-client-entries.js.map +1 -1
  62. package/dist/vite-plugin/sveltekit-generator.d.ts +0 -4
  63. package/dist/vite-plugin/sveltekit-generator.d.ts.map +1 -1
  64. package/dist/vite-plugin/sveltekit-generator.js +36 -24
  65. package/dist/vite-plugin/sveltekit-generator.js.map +1 -1
  66. package/package.json +4 -4
@@ -0,0 +1,10 @@
1
+ /** Server-authored custom-action permission aliases shared by every transport. */
2
+ export interface OperationPermissionAlias {
3
+ /** Existing CRUD permission in the same collection; never a permission bypass. */
4
+ action: 'read' | 'create' | 'update' | 'delete';
5
+ /** Additional SQL policy actions this permission needs for the custom method. */
6
+ databaseActions?: ('SELECT' | 'INSERT' | 'UPDATE' | 'DELETE')[];
7
+ }
8
+ /** Resolve one explicit action alias; malformed declarations fail closed. */
9
+ export declare function resolveOperationPermissionAlias(config: unknown, action: string): OperationPermissionAlias | undefined;
10
+ //# sourceMappingURL=operation-permission.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-permission.d.ts","sourceRoot":"","sources":["../src/operation-permission.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,WAAW,wBAAwB;IACvC,kFAAkF;IAClF,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAChD,iFAAiF;IACjF,eAAe,CAAC,EAAE,CAAC,QAAQ,GAAG,QAAQ,GAAG,QAAQ,GAAG,QAAQ,CAAC,EAAE,CAAC;CACjE;AAED,6EAA6E;AAC7E,wBAAgB,+BAA+B,CAC7C,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,MAAM,GACb,wBAAwB,GAAG,SAAS,CA+BtC"}
@@ -0,0 +1,36 @@
1
+ //#region src/operation-permission.ts
2
+ /** Resolve one explicit action alias; malformed declarations fail closed. */
3
+ function resolveOperationPermissionAlias(config, action) {
4
+ if (!config || typeof config !== "object") return void 0;
5
+ const aliases = config.operationPermissions;
6
+ if (aliases === void 0) return void 0;
7
+ if (!aliases || typeof aliases !== "object" || Array.isArray(aliases)) throw new Error("operationPermissions must be an action map");
8
+ if (!Object.hasOwn(aliases, action)) return void 0;
9
+ if ([
10
+ "list",
11
+ "get",
12
+ "read",
13
+ "create",
14
+ "update",
15
+ "delete"
16
+ ].includes(action)) throw new Error("CRUD permissions cannot be aliased");
17
+ const alias = aliases[action];
18
+ if (!alias || typeof alias !== "object" || Array.isArray(alias)) throw new Error("Invalid operation permission alias");
19
+ const value = alias;
20
+ if (![
21
+ "read",
22
+ "create",
23
+ "update",
24
+ "delete"
25
+ ].includes(value.action) || Object.keys(alias).some((key) => key !== "action" && key !== "databaseActions") || value.databaseActions !== void 0 && (!Array.isArray(value.databaseActions) || value.databaseActions.some((entry) => ![
26
+ "SELECT",
27
+ "INSERT",
28
+ "UPDATE",
29
+ "DELETE"
30
+ ].includes(entry)))) throw new Error("Invalid operation permission alias");
31
+ return value;
32
+ }
33
+ //#endregion
34
+ export { resolveOperationPermissionAlias };
35
+
36
+ //# sourceMappingURL=operation-permission.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation-permission.js","names":[],"sources":["../src/operation-permission.ts"],"sourcesContent":["/** Server-authored custom-action permission aliases shared by every transport. */\nexport interface OperationPermissionAlias {\n /** Existing CRUD permission in the same collection; never a permission bypass. */\n action: 'read' | 'create' | 'update' | 'delete';\n /** Additional SQL policy actions this permission needs for the custom method. */\n databaseActions?: ('SELECT' | 'INSERT' | 'UPDATE' | 'DELETE')[];\n}\n\n/** Resolve one explicit action alias; malformed declarations fail closed. */\nexport function resolveOperationPermissionAlias(\n config: unknown,\n action: string,\n): OperationPermissionAlias | undefined {\n if (!config || typeof config !== 'object') return undefined;\n const aliases = (config as { operationPermissions?: unknown })\n .operationPermissions;\n if (aliases === undefined) return undefined;\n if (!aliases || typeof aliases !== 'object' || Array.isArray(aliases)) {\n throw new Error('operationPermissions must be an action map');\n }\n if (!Object.hasOwn(aliases, action)) return undefined;\n if (['list', 'get', 'read', 'create', 'update', 'delete'].includes(action)) {\n throw new Error('CRUD permissions cannot be aliased');\n }\n const alias = (aliases as Record<string, unknown>)[action];\n if (!alias || typeof alias !== 'object' || Array.isArray(alias)) {\n throw new Error('Invalid operation permission alias');\n }\n const value = alias as OperationPermissionAlias;\n if (\n !['read', 'create', 'update', 'delete'].includes(value.action) ||\n Object.keys(alias).some(\n (key) => key !== 'action' && key !== 'databaseActions',\n ) ||\n (value.databaseActions !== undefined &&\n (!Array.isArray(value.databaseActions) ||\n value.databaseActions.some(\n (entry) => !['SELECT', 'INSERT', 'UPDATE', 'DELETE'].includes(entry),\n )))\n ) {\n throw new Error('Invalid operation permission alias');\n }\n return value;\n}\n"],"mappings":";;AASA,SAAgB,gCACd,QACA,QACsC;CACtC,IAAI,CAAC,UAAU,OAAO,WAAW,UAAU,OAAO,KAAA;CAClD,MAAM,UAAW,OACd;CACH,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;CAClC,IAAI,CAAC,WAAW,OAAO,YAAY,YAAY,MAAM,QAAQ,OAAO,GAClE,MAAM,IAAI,MAAM,4CAA4C;CAE9D,IAAI,CAAC,OAAO,OAAO,SAAS,MAAM,GAAG,OAAO,KAAA;CAC5C,IAAI;EAAC;EAAQ;EAAO;EAAQ;EAAU;EAAU;CAAQ,CAAC,CAAC,SAAS,MAAM,GACvE,MAAM,IAAI,MAAM,oCAAoC;CAEtD,MAAM,QAAS,QAAoC;CACnD,IAAI,CAAC,SAAS,OAAO,UAAU,YAAY,MAAM,QAAQ,KAAK,GAC5D,MAAM,IAAI,MAAM,oCAAoC;CAEtD,MAAM,QAAQ;CACd,IACE,CAAC;EAAC;EAAQ;EAAU;EAAU;CAAQ,CAAC,CAAC,SAAS,MAAM,MAAM,KAC7D,OAAO,KAAK,KAAK,CAAC,CAAC,MAChB,QAAQ,QAAQ,YAAY,QAAQ,iBACvC,KACC,MAAM,oBAAoB,KAAA,MACxB,CAAC,MAAM,QAAQ,MAAM,eAAe,KACnC,MAAM,gBAAgB,MACnB,UAAU,CAAC;EAAC;EAAU;EAAU;EAAU;CAAQ,CAAC,CAAC,SAAS,KAAK,CACrE,IAEJ,MAAM,IAAI,MAAM,oCAAoC;CAEtD,OAAO;AACT"}
@@ -1 +1 @@
1
- {"version":3,"file":"class-registration.d.ts","sourceRoot":"","sources":["../../src/registry/class-registration.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAwBH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAW,CAAC;AACvC,OAAO,KAAK,EAKV,qBAAqB,EAGtB,MAAM,qBAAqB,CAAC;AAsD7B,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AAkDpB;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAS3E;AA4BD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAeT;AAstBD;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,OAAO,UAAU,EACvB,MAAM,GAAE,iBAAsB,GAC7B,IAAI,CASN;AA8nCD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAMlB,qBAAqB,EAAE,WAAW,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC,GAC3E,IAAI,CAeN;AA+BD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACpC,kBAAkB,EAAE,eAAe,CAAC,oBAAoB,CAAC,GAAG,SAAS,GACpE,IAAI,CAyCN;AAoHD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,eAAe,EACzB,gBAAgB,CAAC,EAAE;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,IAAI,CA4CN;AA0LD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,qBAAqB,EAChC,mBAAmB,CAAC,EAAE,MAAM,GAC3B,IAAI,CAUN"}
1
+ {"version":3,"file":"class-registration.d.ts","sourceRoot":"","sources":["../../src/registry/class-registration.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAwBH,OAAO,EAAE,UAAU,EAAE,MAAM,cAAW,CAAC;AACvC,OAAO,KAAK,EAKV,qBAAqB,EAGtB,MAAM,qBAAqB,CAAC;AAsD7B,OAAO,KAAK,EACV,eAAe,EACf,eAAe,EACf,iBAAiB,EAElB,MAAM,YAAY,CAAC;AA0EpB;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,GAAG,OAAO,CAS3E;AA4BD;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAeT;AAstBD;;;;GAIG;AACH,wBAAgB,QAAQ,CACtB,IAAI,EAAE,OAAO,UAAU,EACvB,MAAM,GAAE,iBAAsB,GAC7B,IAAI,CASN;AA+nCD,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAMlB,qBAAqB,EAAE,WAAW,CAAC,eAAe,CAAC,uBAAuB,CAAC,CAAC,GAC3E,IAAI,CAeN;AA+BD,wBAAgB,uBAAuB,CACrC,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC,EACpC,kBAAkB,EAAE,eAAe,CAAC,oBAAoB,CAAC,GAAG,SAAS,GACpE,IAAI,CAyCN;AAoHD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,eAAe,EACzB,gBAAgB,CAAC,EAAE;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB,GACA,IAAI,CA4CN;AA0LD,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,SAAS,EAAE,qBAAqB,EAChC,mBAAmB,CAAC,EAAE,MAAM,GAC3B,IAAI,CAUN"}
@@ -65,6 +65,17 @@ function inheritedStiCollection(ctor) {
65
65
  }
66
66
  return base?.collection;
67
67
  }
68
+ function assertRegisteredStiParent(ctor) {
69
+ const directParent = Object.getPrototypeOf(ctor);
70
+ if (!directParent || directParent === SmrtObject || getConstructorIndex().has(directParent)) return;
71
+ for (let ancestor = Object.getPrototypeOf(directParent); ancestor && ancestor !== SmrtObject && ancestor !== Function.prototype; ancestor = Object.getPrototypeOf(ancestor)) {
72
+ const key = getConstructorIndex().get(ancestor);
73
+ if (key && getClasses().get(key)?.config.tableStrategy === "sti") throw new ConfigurationError(`STI descendant ${ctor.name} has unregistered direct parent ${directParent.name}; decorate the intermediate with @smrt()`, "CONFIG_STI_UNREGISTERED_PARENT", {
74
+ className: ctor.name,
75
+ parentName: directParent.name
76
+ });
77
+ }
78
+ }
68
79
  /**
69
80
  * Shared bundled-context detector. Source files in these output
70
81
  * directories come from a bundler (Vite library mode, webpack, Next.js,
@@ -860,6 +871,7 @@ function registerUntracked(ctor, config = {}) {
860
871
  if (validationRules === void 0) validators = compileValidators(name, fields);
861
872
  else verboseLog(`[registry] Using ${validationRules.length} pre-computed validation rules for ${name}`);
862
873
  let extendsClass = manifestEntry?.extendsQualified ?? manifestEntry?.extends;
874
+ assertRegisteredStiParent(ctor);
863
875
  if (!extendsClass) {
864
876
  const proto = Object.getPrototypeOf(ctor);
865
877
  if (proto?.name && proto.name !== "SmrtObject" && proto.name !== "Object") extendsClass = proto.name;