@happyvertical/smrt-core 0.51.39 → 0.53.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.
- package/AGENTS.md +9 -0
- package/README.md +8 -2
- package/agents/model-moves.md +114 -0
- package/agents/object-runtime.md +3 -1
- package/agents/run-once.md +16 -7
- package/agents/schema-paths.md +79 -0
- package/dist/cascade.d.ts.map +1 -1
- package/dist/cascade.js +6 -3
- package/dist/cascade.js.map +1 -1
- package/dist/collection.d.ts +10 -1
- package/dist/collection.d.ts.map +1 -1
- package/dist/collection.js +14 -4
- package/dist/collection.js.map +1 -1
- package/dist/errors.d.ts +18 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +21 -0
- package/dist/errors.js.map +1 -1
- package/dist/generators/preflight-route.d.ts.map +1 -1
- package/dist/generators/preflight-route.js +1 -1
- package/dist/generators/preflight-route.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/knowledge.d.ts.map +1 -1
- package/dist/knowledge.js +3 -0
- package/dist/knowledge.js.map +1 -1
- package/dist/manifest/static-manifest.d.ts.map +1 -1
- package/dist/manifest/static-manifest.js +9 -1
- package/dist/manifest/static-manifest.js.map +1 -1
- package/dist/manifest/store.js +1 -1
- package/dist/manifest/store.js.map +1 -1
- package/dist/manifest.json +9 -1
- package/dist/migrations/differ.d.ts +56 -0
- package/dist/migrations/differ.d.ts.map +1 -1
- package/dist/migrations/differ.js +152 -27
- package/dist/migrations/differ.js.map +1 -1
- package/dist/migrations/index.d.ts +1 -0
- package/dist/migrations/index.d.ts.map +1 -1
- package/dist/migrations/index.js +2 -1
- package/dist/migrations/null-equal-indexes.js +1 -1
- package/dist/migrations/orchestrate.d.ts +7 -0
- package/dist/migrations/orchestrate.d.ts.map +1 -1
- package/dist/migrations/orchestrate.js +4 -2
- package/dist/migrations/orchestrate.js.map +1 -1
- package/dist/migrations/qualified-name-aliases.d.ts +134 -0
- package/dist/migrations/qualified-name-aliases.d.ts.map +1 -0
- package/dist/migrations/qualified-name-aliases.js +294 -0
- package/dist/migrations/qualified-name-aliases.js.map +1 -0
- package/dist/migrations/tracker.d.ts +29 -1
- package/dist/migrations/tracker.d.ts.map +1 -1
- package/dist/migrations/tracker.js +92 -7
- package/dist/migrations/tracker.js.map +1 -1
- package/dist/migrations.js +2 -1
- package/dist/object.d.ts +128 -0
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +333 -44
- package/dist/object.js.map +1 -1
- package/dist/polymorphic-association.d.ts +18 -0
- package/dist/polymorphic-association.d.ts.map +1 -1
- package/dist/polymorphic-association.js +27 -2
- package/dist/polymorphic-association.js.map +1 -1
- package/dist/registry/class-registration.d.ts.map +1 -1
- package/dist/registry/class-registration.js +27 -4
- package/dist/registry/class-registration.js.map +1 -1
- package/dist/registry/name-resolver.d.ts +8 -2
- package/dist/registry/name-resolver.d.ts.map +1 -1
- package/dist/registry/name-resolver.js +17 -8
- package/dist/registry/name-resolver.js.map +1 -1
- package/dist/registry/qualified-name-aliases.d.ts +109 -0
- package/dist/registry/qualified-name-aliases.d.ts.map +1 -0
- package/dist/registry/qualified-name-aliases.js +286 -0
- package/dist/registry/qualified-name-aliases.js.map +1 -0
- package/dist/registry/relationship-graph.d.ts.map +1 -1
- package/dist/registry/relationship-graph.js +1 -1
- package/dist/registry/relationship-graph.js.map +1 -1
- package/dist/registry/schema-builder.d.ts.map +1 -1
- package/dist/registry/schema-builder.js +7 -5
- package/dist/registry/schema-builder.js.map +1 -1
- package/dist/registry/types.d.ts +26 -0
- package/dist/registry/types.d.ts.map +1 -1
- package/dist/registry.d.ts +127 -6
- package/dist/registry.d.ts.map +1 -1
- package/dist/registry.js +234 -14
- package/dist/registry.js.map +1 -1
- package/dist/scanner/index.d.ts +1 -1
- package/dist/scanner/index.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.d.ts +14 -2
- package/dist/scanner/manifest-generator.d.ts.map +1 -1
- package/dist/scanner/manifest-generator.js +48 -9
- package/dist/scanner/manifest-generator.js.map +1 -1
- package/dist/scanner/types.d.ts +21 -0
- package/dist/scanner/types.d.ts.map +1 -1
- package/dist/scanner/types.js.map +1 -1
- package/dist/schema/conflict-target.d.ts +68 -11
- package/dist/schema/conflict-target.d.ts.map +1 -1
- package/dist/schema/conflict-target.js +75 -12
- package/dist/schema/conflict-target.js.map +1 -1
- package/dist/schema/foreign-key-ddl.d.ts +17 -1
- package/dist/schema/foreign-key-ddl.d.ts.map +1 -1
- package/dist/schema/foreign-key-ddl.js +29 -3
- package/dist/schema/foreign-key-ddl.js.map +1 -1
- package/dist/schema/foreign-key-policy.d.ts +8 -0
- package/dist/schema/foreign-key-policy.d.ts.map +1 -1
- package/dist/schema/foreign-key-policy.js +2 -1
- package/dist/schema/foreign-key-policy.js.map +1 -1
- package/dist/schema/generator.d.ts +7 -0
- package/dist/schema/generator.d.ts.map +1 -1
- package/dist/schema/generator.js +18 -10
- package/dist/schema/generator.js.map +1 -1
- package/dist/schema/text-cast-probe.d.ts +50 -1
- package/dist/schema/text-cast-probe.d.ts.map +1 -1
- package/dist/schema/text-cast-probe.js +46 -11
- package/dist/schema/text-cast-probe.js.map +1 -1
- package/dist/schema/types.d.ts +6 -0
- package/dist/schema/types.d.ts.map +1 -1
- package/dist/scripts/browser-plain-json-regression.mjs +4 -1
- package/dist/smrt-knowledge.json +22 -11
- package/dist/utils/qualified-names.d.ts +11 -0
- package/dist/utils/qualified-names.d.ts.map +1 -1
- package/dist/utils/qualified-names.js +21 -1
- package/dist/utils/qualified-names.js.map +1 -1
- package/package.json +11 -11
package/dist/errors.d.ts
CHANGED
|
@@ -244,6 +244,24 @@ export declare class TenantIsolationError extends SmrtError {
|
|
|
244
244
|
targetClass?: string;
|
|
245
245
|
targetTenantId: string;
|
|
246
246
|
}): TenantIsolationError;
|
|
247
|
+
/**
|
|
248
|
+
* Builds a {@link TenantIsolationError} for a natural-key save whose
|
|
249
|
+
* conflict target matched a row owned by a different tenant (or a global
|
|
250
|
+
* row, or — for a global save — a tenant's row). `save()` refuses instead of
|
|
251
|
+
* letting `ON CONFLICT … DO UPDATE` rewrite that row's `id` and tenant.
|
|
252
|
+
*
|
|
253
|
+
* The other row's owner is deliberately NOT reported: naming it would
|
|
254
|
+
* disclose another tenant's identity to the caller. Only the caller's own
|
|
255
|
+
* values appear in the message and details.
|
|
256
|
+
*/
|
|
257
|
+
static naturalKeyOwnedElsewhere(details: {
|
|
258
|
+
className: string;
|
|
259
|
+
tableName: string;
|
|
260
|
+
conflictColumns: string[];
|
|
261
|
+
conflictValues: Record<string, unknown>;
|
|
262
|
+
ownershipColumns: string[];
|
|
263
|
+
tenantId?: string | null;
|
|
264
|
+
}): TenantIsolationError;
|
|
247
265
|
}
|
|
248
266
|
/**
|
|
249
267
|
* Error thrown by `runOnce()` (`./run-once.ts`, #3080) when a submission's
|
package/dist/errors.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAiCH,8BAAsB,SAAU,SAAQ,KAAK;IAC3C,SAAgB,IAAI,EAAE,MAAM,CAAC;IAC7B,SAAgB,QAAQ,EACpB,UAAU,GACV,IAAI,GACJ,YAAY,GACZ,YAAY,GACZ,SAAS,GACT,eAAe,GACf,SAAS,CAAC;IACd,SAAgB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClD,SAAgB,KAAK,CAAC,EAAE,KAAK,CAAC;gBAG5B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,SAAS,CAAC,UAAU,CAAC,EAC/B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAef;;OAEG;IACH,MAAM;;;;;;;;;;;;;CAiBP;AAsED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,aAAc,SAAQ,SAAS;gBAExC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAKf,MAAM,CAAC,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,aAAa;IASpE,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,aAAa;IAgB/D,MAAM,CAAC,WAAW,CAChB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,KAAK,GACZ,aAAa;IAShB,MAAM,CAAC,mBAAmB,CACxB,UAAU,EAAE,MAAM,EAClB,KAAK,EAAE,OAAO,EACd,KAAK,CAAC,EAAE,KAAK,GACZ,aAAa;IAShB,MAAM,CAAC,aAAa,CAClB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,KAAK,GACZ,aAAa;IAWhB,MAAM,CAAC,oBAAoB,CACzB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,MAAM,GACb,aAAa;IAUhB,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE;QACvC,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,MAAM,CAAC;QACb,OAAO,EAAE,MAAM,CAAC;QAChB,gBAAgB,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC1C,cAAc,EAAE,MAAM,CAAC;QACvB,iBAAiB,EAAE,MAAM,CAAC;QAC1B,WAAW,EAAE,MAAM,CAAC;KACrB,GAAG,aAAa;IAejB,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,aAAa;CAQ1E;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,OAAQ,SAAQ,SAAS;gBAElC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAKf,MAAM,CAAC,aAAa,CAClB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,KAAK,GACZ,OAAO;IASV,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,OAAO;IAQxE,MAAM,CAAC,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,OAAO,GAAG,OAAO;IAQpE,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;CAOvD;AAED;;;;;;;;;GASG;AACH,qBAAa,eAAgB,SAAQ,SAAS;gBAE1C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAKf,MAAM,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe;IAMlD,MAAM,CAAC,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,eAAe;IAQzE,MAAM,CAAC,iBAAiB,CACtB,IAAI,EAAE,MAAM,EACZ,aAAa,EAAE,MAAM,GACpB,eAAe;CAOnB;AAED;;;;;;;;;;;;;;GAcG;AACH,qBAAa,eAAgB,SAAQ,SAAS;gBAE1C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAKf,MAAM,CAAC,aAAa,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,eAAe;IAQ5E,MAAM,CAAC,YAAY,CACjB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,YAAY,EAAE,MAAM,GACnB,eAAe;IAQlB,MAAM,CAAC,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,eAAe;IAQ3E,MAAM,CAAC,UAAU,CACf,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,eAAe;CAcnB;AAED;;;;;;;;;;GAUG;AACH,qBAAa,YAAa,SAAQ,SAAS;gBAEvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAKf,MAAM,CAAC,aAAa,CAClB,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,MAAM,EACf,YAAY,CAAC,EAAE,MAAM,GAAG,KAAK,GAC5B,YAAY;IAWf,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,YAAY;IAQ5D,MAAM,CAAC,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,YAAY;CAS1E;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,kBAAmB,SAAQ,SAAS;gBAE7C,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAKf,MAAM,CAAC,oBAAoB,CACzB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,GACf,kBAAkB;IAQrB,MAAM,CAAC,oBAAoB,CACzB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,QAAQ,EAAE,MAAM,GACf,kBAAkB;IAQrB,MAAM,CAAC,oBAAoB,CACzB,SAAS,EAAE,MAAM,EACjB,KAAK,CAAC,EAAE,KAAK,GACZ,kBAAkB;IASrB,MAAM,CAAC,mBAAmB,CACxB,SAAS,EAAE,MAAM,EACjB,gBAAgB,EAAE,MAAM,EAAE,GACzB,kBAAkB;IAUrB,MAAM,CAAC,oBAAoB,CACzB,SAAS,EAAE,MAAM,EACjB,aAAa,EAAE,MAAM,EACrB,WAAW,EAAE,MAAM,EACnB,cAAc,EAAE,MAAM,GACrB,kBAAkB;IAWrB,MAAM,CAAC,qBAAqB,CAC1B,UAAU,EAAE,MAAM,EAClB,SAAS,EAAE,MAAM,GAChB,kBAAkB;CAStB;AAED;;;;;;;;;;;;;GAaG;AACH,qBAAa,YAAa,SAAQ,SAAS;gBAEvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EACjC,KAAK,CAAC,EAAE,KAAK;IAKf,MAAM,CAAC,eAAe,CACpB,SAAS,EAAE,MAAM,EACjB,OAAO,CAAC,EAAE,MAAM,EAChB,KAAK,CAAC,EAAE,KAAK,GACZ,YAAY;IASf,MAAM,CAAC,YAAY,CACjB,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,YAAY;IAIf,MAAM,CAAC,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,YAAY;CAOxE;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AACH,qBAAa,oBAAqB,SAAQ,SAAS;IACjD,8DAA8D;IAC9D,SAAgB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClC,2EAA2E;IAC3E,SAAgB,iBAAiB,CAAC,EAAE,MAAM,CAAC;gBAGzC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,EAAE,MAAM,CAAC;QAClB,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;KACxB,EACD,KAAK,CAAC,EAAE,KAAK;IAOf;;;OAGG;IACH,MAAM,CAAC,oBAAoB,CAAC,OAAO,EAAE;QACnC,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;QAClB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,CAAC,EAAE,MAAM,CAAC;QACrB,cAAc,EAAE,MAAM,CAAC;KACxB,GAAG,oBAAoB;IAkBxB;;;;;;;;;OASG;IACH,MAAM,CAAC,wBAAwB,CAAC,OAAO,EAAE;QACvC,SAAS,EAAE,MAAM,CAAC;QAClB,SAAS,EAAE,MAAM,CAAC;QAClB,eAAe,EAAE,MAAM,EAAE,CAAC;QAC1B,cAAc,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QACxC,gBAAgB,EAAE,MAAM,EAAE,CAAC;QAC3B,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;KAC1B,GAAG,oBAAoB;CAwBzB;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,iBAAkB,SAAQ,SAAS;IAC9C,iDAAiD;IACjD,SAAgB,QAAQ,EAAE,MAAM,CAAC;gBAG/B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,oBAAoB,GAAG,0BAA0B,EACvD,QAAQ,EAAE,MAAM;IAMlB,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB;IASpD,MAAM,CAAC,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,iBAAiB;CAS3D;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;WACU,SAAS,CAAC,CAAC,EACtB,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,UAAU,SAAI,EACd,KAAK,SAAO,EACZ,iBAAiB,SAAI,GACpB,OAAO,CAAC,CAAC,CAAC;IAgDb;;;;;;;;;OASG;IACH,MAAM,CAAC,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAyBzC;;OAEG;IACH,MAAM,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;CAkC5D;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,MAAM,CAAyB;IACvC,OAAO,CAAC,UAAU,CAAS;gBAEf,UAAU,EAAE,MAAM;IAI9B;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI;IAItC;;OAEG;IACH,SAAS,IAAI,OAAO;IAIpB;;OAEG;IACH,SAAS,IAAI,eAAe,EAAE;IAI9B;;OAEG;IACH,aAAa,IAAI,MAAM;IAIvB;;OAEG;IACH,QAAQ,IAAI,MAAM;IAYlB;;OAEG;IACH,MAAM,IAAI,MAAM;IAQhB;;OAEG;IACH,aAAa,IAAI,IAAI;IAMrB;;OAEG;IACH,KAAK,IAAI,IAAI;CAGd;AAED;;GAEG;AACH,qBAAa,eAAe;IAC1B;;;;;;;OAOG;WACU,aAAa,CACxB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,OAAO,EAAE;QACP,QAAQ,CAAC,EAAE,OAAO,CAAC;QACnB,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,GAAG,CAAC,EAAE,MAAM,CAAC;QACb,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;QAC1B,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,eAAe,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;QACjE,aAAa,CAAC,EAAE,MAAM,CAAC;KACxB,EACD,UAAU,GAAE,MAAiB,GAC5B,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC;IA0FlC;;OAEG;IACH,MAAM,CAAC,gBAAgB,CACrB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,OAAO,EACd,UAAU,GAAE,MAAiB,GAC5B,eAAe,GAAG,IAAI;IAOzB;;OAEG;IACH,MAAM,CAAC,aAAa,CAClB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,GAAG,CAAC,EAAE,MAAM,EACZ,GAAG,CAAC,EAAE,MAAM,GACX,eAAe,GAAG,IAAI;IAUzB;;OAEG;IACH,MAAM,CAAC,cAAc,CACnB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,SAAS,CAAC,EAAE,MAAM,EAClB,SAAS,CAAC,EAAE,MAAM,GACjB,eAAe,GAAG,IAAI;IAkBzB;;OAEG;IACH,MAAM,CAAC,eAAe,CACpB,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,OAAO,EAAE,MAAM,GAAG,MAAM,GACvB,eAAe,GAAG,IAAI;CAW1B"}
|
package/dist/errors.js
CHANGED
|
@@ -467,6 +467,27 @@ var TenantIsolationError = class TenantIsolationError extends SmrtError {
|
|
|
467
467
|
targetClass: details.targetClass
|
|
468
468
|
});
|
|
469
469
|
}
|
|
470
|
+
/**
|
|
471
|
+
* Builds a {@link TenantIsolationError} for a natural-key save whose
|
|
472
|
+
* conflict target matched a row owned by a different tenant (or a global
|
|
473
|
+
* row, or — for a global save — a tenant's row). `save()` refuses instead of
|
|
474
|
+
* letting `ON CONFLICT … DO UPDATE` rewrite that row's `id` and tenant.
|
|
475
|
+
*
|
|
476
|
+
* The other row's owner is deliberately NOT reported: naming it would
|
|
477
|
+
* disclose another tenant's identity to the caller. Only the caller's own
|
|
478
|
+
* values appear in the message and details.
|
|
479
|
+
*/
|
|
480
|
+
static naturalKeyOwnedElsewhere(details) {
|
|
481
|
+
const key = details.conflictColumns.map((column) => `${column}=${JSON.stringify(details.conflictValues[column] ?? null)}`).join(", ");
|
|
482
|
+
return new TenantIsolationError(`Refusing to save ${details.className}: its natural key (${key}) on "${details.tableName}" already belongs to a row with a different owner (${details.ownershipColumns.join(", ")}). Saving would overwrite that row's id and owner. Give the table a tenant-inclusive unique key (declare tenant scope, or drop the explicit conflictColumns that omit the tenant column, then run \`smrt db:migrate\`), or choose another natural key.`, {
|
|
483
|
+
tenantId: details.tenantId ?? void 0,
|
|
484
|
+
className: details.className,
|
|
485
|
+
tableName: details.tableName,
|
|
486
|
+
conflictColumns: details.conflictColumns,
|
|
487
|
+
ownershipColumns: details.ownershipColumns,
|
|
488
|
+
reason: "natural_key_owned_elsewhere"
|
|
489
|
+
});
|
|
490
|
+
}
|
|
470
491
|
};
|
|
471
492
|
/**
|
|
472
493
|
* Error thrown by `runOnce()` (`./run-once.ts`, #3080) when a submission's
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Comprehensive error handling system for SMRT framework\n *\n * Provides specialized error types for different failure scenarios\n * with proper error codes, messages, and debugging information.\n */\n\n/**\n * Abstract base class for all SMRT framework errors.\n *\n * Adds a structured `code` (machine-readable string constant), a `category`\n * (coarse error domain), optional structured `details`, and an optional\n * causal `Error` chain on top of the standard `Error` class.\n *\n * Never throw `SmrtError` directly — use one of the concrete subclasses\n * (`DatabaseError`, `AIError`, `ValidationError`, etc.) or their static\n * factory methods for consistent error codes and messages.\n *\n * @example\n * ```typescript\n * try {\n * await product.save();\n * } catch (err) {\n * if (err instanceof ValidationError) {\n * console.error(err.code, err.details); // 'VALIDATION_REQUIRED_FIELD', { fieldName, objectType }\n * }\n * if (err instanceof SmrtError) {\n * logger.error(ErrorUtils.sanitizeError(err));\n * }\n * }\n * ```\n */\n\nimport { createLogger } from '@happyvertical/logger';\nimport { classifyDatabaseError } from './db-errors';\n\nconst logger = createLogger({ level: 'info' });\n\nexport abstract class SmrtError extends Error {\n public readonly code: string;\n public readonly category:\n | 'database'\n | 'ai'\n | 'filesystem'\n | 'validation'\n | 'network'\n | 'configuration'\n | 'runtime';\n public readonly details?: Record<string, unknown>;\n public readonly cause?: Error;\n\n constructor(\n message: string,\n code: string,\n category: SmrtError['category'],\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.category = category;\n this.details = details;\n this.cause = cause;\n\n // Maintain proper stack trace for V8\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Converts error to a serializable object for logging/debugging\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n category: this.category,\n details: this.details,\n stack: this.stack,\n cause: this.cause\n ? {\n name: this.cause.name,\n message: this.cause.message,\n stack: this.cause.stack,\n }\n : undefined,\n };\n }\n}\n\ntype ErrorLikeWithContext = Error & {\n cause?: unknown;\n context?: {\n originalError?: unknown;\n };\n};\n\nfunction collectErrorMessages(\n value: unknown,\n messages: string[],\n visited: Set<unknown>,\n depth = 0,\n): void {\n if (!value || visited.has(value) || depth > 10) {\n return;\n }\n\n visited.add(value);\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed) {\n messages.push(trimmed);\n }\n return;\n }\n\n if (!(value instanceof Error)) {\n return;\n }\n\n const message = value.message?.trim();\n if (message) {\n messages.push(message);\n }\n\n const errorWithContext = value as ErrorLikeWithContext;\n collectErrorMessages(\n errorWithContext.context?.originalError,\n messages,\n visited,\n depth + 1,\n );\n collectErrorMessages(errorWithContext.cause, messages, visited, depth + 1);\n}\n\nfunction getPrimaryCauseMessage(cause?: Error): {\n message?: string;\n messages?: string[];\n} {\n if (!cause) {\n return {};\n }\n\n const collected: string[] = [];\n collectErrorMessages(cause, collected, new Set<unknown>());\n\n const uniqueMessages = [...new Set(collected.filter(Boolean))];\n if (uniqueMessages.length === 0) {\n return {};\n }\n\n return {\n message: uniqueMessages[uniqueMessages.length - 1],\n messages: uniqueMessages,\n };\n}\n\n/**\n * Errors originating from database operations.\n *\n * Use the static factory methods rather than the constructor directly:\n * - `DatabaseError.connectionFailed(url, cause)` — DB connection failure\n * - `DatabaseError.queryFailed(query, cause)` — SQL execution error\n * - `DatabaseError.schemaError(table, op, cause)` — DDL/migration error\n * - `DatabaseError.constraintViolation(constraint, value, cause)` — FK/CHECK/UNIQUE\n * - `DatabaseError.corruptedData(field, class, cause)` — unparse-able column data\n * - `DatabaseError.missingDiscriminator(class, rowId)` — STI row missing `_meta_type`\n * - `DatabaseError.stiDiscriminatorConflict(...)` — legacy STI discriminator collides during qualification\n * - `DatabaseError.schemaMissing(table, class)` — table not yet migrated\n *\n * All errors have `category: 'database'` and codes prefixed with `DB_`.\n */\nexport class DatabaseError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'database', details, cause);\n }\n\n static connectionFailed(dbUrl: string, cause?: Error): DatabaseError {\n return new DatabaseError(\n `Failed to connect to database: ${dbUrl}`,\n 'DB_CONNECTION_FAILED',\n { dbUrl },\n cause,\n );\n }\n\n static queryFailed(query: string, cause?: Error): DatabaseError {\n // Include the deepest actionable cause message for better debugging.\n const causeInfo = getPrimaryCauseMessage(cause);\n const causeMsg = causeInfo.message ? `\\nCause: ${causeInfo.message}` : '';\n return new DatabaseError(\n `Database query failed: ${query.substring(0, 100)}${query.length > 100 ? '...' : ''}${causeMsg}`,\n 'DB_QUERY_FAILED',\n {\n query,\n causeMessage: causeInfo.message,\n causeMessages: causeInfo.messages,\n },\n cause,\n );\n }\n\n static schemaError(\n tableName: string,\n operation: string,\n cause?: Error,\n ): DatabaseError {\n return new DatabaseError(\n `Schema operation failed for table '${tableName}': ${operation}`,\n 'DB_SCHEMA_ERROR',\n { tableName, operation },\n cause,\n );\n }\n\n static constraintViolation(\n constraint: string,\n value: unknown,\n cause?: Error,\n ): DatabaseError {\n return new DatabaseError(\n `Database constraint violation: ${constraint}`,\n 'DB_CONSTRAINT_VIOLATION',\n { constraint, value },\n cause,\n );\n }\n\n static corruptedData(\n fieldName: string,\n className: string,\n cause?: Error,\n ): DatabaseError {\n return new DatabaseError(\n `Corrupted data in field '${fieldName}' for ${className}. ` +\n `The data cannot be parsed or is malformed. ` +\n `This may indicate database corruption or incompatible schema changes.`,\n 'DB_CORRUPTED_DATA',\n { fieldName, className },\n cause,\n );\n }\n\n static missingDiscriminator(\n className: string,\n rowId?: string,\n ): DatabaseError {\n return new DatabaseError(\n `Missing discriminator (_meta_type) for STI class ${className}${rowId ? ` (row id: ${rowId})` : ''}. ` +\n `STI classes require a discriminator column to determine the correct subclass. ` +\n `This may indicate a schema mismatch or manual database modification.`,\n 'DB_MISSING_DISCRIMINATOR',\n { className, rowId },\n );\n }\n\n static stiDiscriminatorConflict(details: {\n className: string;\n tableName: string;\n id: string;\n slug: string;\n context: string;\n conflictIdentity: Record<string, unknown>;\n legacyMetaType: string;\n qualifiedMetaType: string;\n duplicateId: string;\n }): DatabaseError {\n const identityText = Object.entries(details.conflictIdentity)\n .map(([key, value]) => `${key} '${String(value)}'`)\n .join(', ');\n\n return new DatabaseError(\n `Legacy STI discriminator collision for ${details.className} (${details.tableName}). ` +\n `Row '${details.id}' would upgrade _meta_type from '${details.legacyMetaType}' to '${details.qualifiedMetaType}', ` +\n `but row '${details.duplicateId}' already uses the qualified discriminator for ${identityText || 'the same conflict identity'}. ` +\n `Merge or remove the duplicate legacy/qualified rows before saving.`,\n 'DB_STI_DISCRIMINATOR_CONFLICT',\n details,\n );\n }\n\n static schemaMissing(tableName: string, className: string): DatabaseError {\n return new DatabaseError(\n `Table '${tableName}' does not exist for class '${className}'. ` +\n `Run 'smrt db:migrate' to create database schema.`,\n 'DB_SCHEMA_MISSING',\n { tableName, className },\n );\n }\n}\n\n/**\n * Errors from AI provider integrations.\n *\n * Use the static factory methods:\n * - `AIError.providerError(provider, operation, cause)` — generic provider failure\n * - `AIError.rateLimitExceeded(provider, retryAfter)` — rate limit hit\n * - `AIError.invalidResponse(provider, response)` — unexpected response shape\n * - `AIError.authenticationFailed(provider)` — bad API key / credentials\n *\n * All errors have `category: 'ai'` and codes prefixed with `AI_`.\n * AI errors are considered retryable by `ErrorUtils.isRetryable()`.\n */\nexport class AIError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'ai', details, cause);\n }\n\n static providerError(\n provider: string,\n operation: string,\n cause?: Error,\n ): AIError {\n return new AIError(\n `AI provider '${provider}' failed during ${operation}`,\n 'AI_PROVIDER_ERROR',\n { provider, operation },\n cause,\n );\n }\n\n static rateLimitExceeded(provider: string, retryAfter?: number): AIError {\n return new AIError(\n `AI provider '${provider}' rate limit exceeded`,\n 'AI_RATE_LIMIT',\n { provider, retryAfter },\n );\n }\n\n static invalidResponse(provider: string, response: unknown): AIError {\n return new AIError(\n `AI provider '${provider}' returned invalid response`,\n 'AI_INVALID_RESPONSE',\n { provider, response },\n );\n }\n\n static authenticationFailed(provider: string): AIError {\n return new AIError(\n `AI provider '${provider}' authentication failed`,\n 'AI_AUTH_FAILED',\n { provider },\n );\n }\n}\n\n/**\n * Errors from filesystem operations.\n *\n * Use the static factory methods:\n * - `FilesystemError.fileNotFound(path)` — file does not exist\n * - `FilesystemError.permissionDenied(path, operation)` — access denied\n * - `FilesystemError.diskSpaceExceeded(path, requiredBytes)` — insufficient space\n *\n * All errors have `category: 'filesystem'` and codes prefixed with `FS_`.\n */\nexport class FilesystemError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'filesystem', details, cause);\n }\n\n static fileNotFound(path: string): FilesystemError {\n return new FilesystemError(`File not found: ${path}`, 'FS_FILE_NOT_FOUND', {\n path,\n });\n }\n\n static permissionDenied(path: string, operation: string): FilesystemError {\n return new FilesystemError(\n `Permission denied for ${operation} on: ${path}`,\n 'FS_PERMISSION_DENIED',\n { path, operation },\n );\n }\n\n static diskSpaceExceeded(\n path: string,\n requiredBytes: number,\n ): FilesystemError {\n return new FilesystemError(\n `Insufficient disk space for operation on: ${path}`,\n 'FS_DISK_SPACE_EXCEEDED',\n { path, requiredBytes },\n );\n }\n}\n\n/**\n * Input/data validation errors thrown before or during a database operation.\n *\n * `save()` throws `ValidationError` when field validation fails. The collection's\n * `convertWhereKeys()` throws it for invalid WHERE clause operators or field names.\n * `ValidationError` is **not** retried by `ErrorUtils.withRetry()`.\n *\n * Use the static factory methods:\n * - `ValidationError.requiredField(field, objectType)` — missing required field\n * - `ValidationError.invalidValue(field, value, expected)` — wrong type/format\n * - `ValidationError.uniqueConstraint(field, value)` — duplicate unique value\n * - `ValidationError.rangeError(field, value, min?, max?)` — out of allowed range\n *\n * All errors have `category: 'validation'` and codes prefixed with `VALIDATION_`.\n */\nexport class ValidationError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'validation', details, cause);\n }\n\n static requiredField(fieldName: string, objectType: string): ValidationError {\n return new ValidationError(\n `Required field '${fieldName}' is missing for ${objectType}`,\n 'VALIDATION_REQUIRED_FIELD',\n { fieldName, objectType },\n );\n }\n\n static invalidValue(\n fieldName: string,\n value: unknown,\n expectedType: string,\n ): ValidationError {\n return new ValidationError(\n `Invalid value for field '${fieldName}': expected ${expectedType}, got ${typeof value}`,\n 'VALIDATION_INVALID_VALUE',\n { fieldName, value, expectedType },\n );\n }\n\n static uniqueConstraint(fieldName: string, value: unknown): ValidationError {\n return new ValidationError(\n `Unique constraint violation for field '${fieldName}' with value: ${String(value)}`,\n 'VALIDATION_UNIQUE_CONSTRAINT',\n { fieldName, value },\n );\n }\n\n static rangeError(\n fieldName: string,\n value: number,\n min?: number,\n max?: number,\n ): ValidationError {\n const range =\n min !== undefined && max !== undefined\n ? `between ${min} and ${max}`\n : min !== undefined\n ? `>= ${min}`\n : `<= ${max}`;\n\n return new ValidationError(\n `Value for field '${fieldName}' must be ${range}, got: ${value}`,\n 'VALIDATION_RANGE_ERROR',\n { fieldName, value, min, max },\n );\n }\n}\n\n/**\n * Errors from HTTP and external network operations.\n *\n * Use the static factory methods:\n * - `NetworkError.requestFailed(url, status?, body?)` — non-2xx response or connection failure\n * - `NetworkError.timeout(url, timeoutMs)` — request exceeded timeout\n * - `NetworkError.serviceUnavailable(service, reason?)` — external service down\n *\n * All errors have `category: 'network'` and codes prefixed with `NETWORK_`.\n * Network errors are considered retryable by `ErrorUtils.isRetryable()`.\n */\nexport class NetworkError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'network', details, cause);\n }\n\n static requestFailed(\n url: string,\n status?: number,\n responseBody?: string | Error,\n ): NetworkError {\n const cause = responseBody instanceof Error ? responseBody : undefined;\n const body = typeof responseBody === 'string' ? responseBody : undefined;\n return new NetworkError(\n `Network request failed: ${url}${status ? ` (Status: ${status})` : ''}${body ? ` - ${body.substring(0, 200)}` : ''}`,\n 'NETWORK_REQUEST_FAILED',\n { url, status, responseBody: body },\n cause,\n );\n }\n\n static timeout(url: string, timeoutMs: number): NetworkError {\n return new NetworkError(\n `Network request timed out after ${timeoutMs}ms: ${url}`,\n 'NETWORK_TIMEOUT',\n { url, timeoutMs },\n );\n }\n\n static serviceUnavailable(service: string, reason?: string): NetworkError {\n return new NetworkError(\n reason\n ? `External service unavailable: ${service} - ${reason}`\n : `External service unavailable: ${service}`,\n 'NETWORK_SERVICE_UNAVAILABLE',\n { service, reason },\n );\n }\n}\n\n/**\n * Errors from misconfigured or incompatible class/framework setup.\n *\n * These are typically thrown during class registration (i.e. at module load time),\n * not during normal request handling.\n *\n * Use the static factory methods:\n * - `ConfigurationError.missingConfiguration(key, context?)` — missing required config\n * - `ConfigurationError.invalidConfiguration(key, value, expected)` — wrong config type/value\n * - `ConfigurationError.initializationFailed(component, cause?)` — component failed to start\n * - `ConfigurationError.circularInheritance(class, chain)` — circular class inheritance\n * - `ConfigurationError.incompatibleStrategy(class, strategy, parent, parentStrategy)` — STI mismatch\n * - `ConfigurationError.unregisteredBaseClass(child, base)` — STI base not yet registered\n *\n * All errors have `category: 'configuration'` and codes prefixed with `CONFIG_`.\n * Configuration errors are **not** retried by `ErrorUtils.withRetry()`.\n */\nexport class ConfigurationError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'configuration', details, cause);\n }\n\n static missingConfiguration(\n configKey: string,\n context?: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `Missing required configuration: ${configKey}${context ? ` in ${context}` : ''}`,\n 'CONFIG_MISSING',\n { configKey, context },\n );\n }\n\n static invalidConfiguration(\n configKey: string,\n value: unknown,\n expected: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `Invalid configuration for ${configKey}: expected ${expected}, got ${typeof value}`,\n 'CONFIG_INVALID',\n { configKey, value, expected },\n );\n }\n\n static initializationFailed(\n component: string,\n cause?: Error,\n ): ConfigurationError {\n return new ConfigurationError(\n `Failed to initialize component: ${component}`,\n 'CONFIG_INIT_FAILED',\n { component },\n cause,\n );\n }\n\n static circularInheritance(\n className: string,\n inheritanceChain: string[],\n ): ConfigurationError {\n return new ConfigurationError(\n `Circular inheritance detected for class '${className}'. ` +\n `Inheritance chain: ${inheritanceChain.join(' → ')} → ${className}. ` +\n `Classes cannot inherit from themselves directly or indirectly.`,\n 'CONFIG_CIRCULAR_INHERITANCE',\n { className, inheritanceChain },\n );\n }\n\n static incompatibleStrategy(\n className: string,\n classStrategy: string,\n parentClass: string,\n parentStrategy: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `Incompatible table strategy for class '${className}' (${classStrategy}). ` +\n `Parent class '${parentClass}' uses ${parentStrategy} strategy. ` +\n `Child classes must use the same table strategy as their parent. ` +\n `Either change ${className} to use ${parentStrategy}, or remove the inheritance.`,\n 'CONFIG_INCOMPATIBLE_STRATEGY',\n { className, classStrategy, parentClass, parentStrategy },\n );\n }\n\n static unregisteredBaseClass(\n childClass: string,\n baseClass: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `STI base class '${baseClass}' is not registered for child class '${childClass}'. ` +\n `When using Single Table Inheritance, the base class must be registered before any child classes. ` +\n `Ensure ${baseClass} is decorated with @smrt({ tableStrategy: 'sti' }) and imported before ${childClass}.`,\n 'CONFIG_UNREGISTERED_BASE',\n { childClass, baseClass },\n );\n }\n}\n\n/**\n * Errors representing unexpected runtime failures not covered by other categories.\n *\n * `RuntimeError` is the catch-all for internal framework errors — invalid object\n * state, exhausted resources, or failures in operations like `save()` and `loadFromId()`\n * that propagate from an unknown cause.\n *\n * Use the static factory methods:\n * - `RuntimeError.operationFailed(operation, context?, cause?)` — generic operation failure\n * - `RuntimeError.invalidState(message, context?)` — unexpected object/system state\n * - `RuntimeError.resourceExhausted(resource, limit)` — limit exceeded (e.g. connections)\n *\n * All errors have `category: 'runtime'` and codes prefixed with `RUNTIME_`.\n */\nexport class RuntimeError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'runtime', details, cause);\n }\n\n static operationFailed(\n operation: string,\n context?: string,\n cause?: Error,\n ): RuntimeError {\n return new RuntimeError(\n `Operation failed: ${operation}${context ? ` in ${context}` : ''}`,\n 'RUNTIME_OPERATION_FAILED',\n { operation, context },\n cause,\n );\n }\n\n static invalidState(\n message: string,\n context?: Record<string, unknown>,\n ): RuntimeError {\n return new RuntimeError(message, 'RUNTIME_INVALID_STATE', context);\n }\n\n static resourceExhausted(resource: string, limit: number): RuntimeError {\n return new RuntimeError(\n `Resource exhausted: ${resource} exceeded limit of ${limit}`,\n 'RUNTIME_RESOURCE_EXHAUSTED',\n { resource, limit },\n );\n }\n}\n\n/**\n * Error thrown when a tenant isolation boundary is crossed while resolving a\n * relationship.\n *\n * Raised by {@link SmrtObject.loadRelated} / {@link SmrtObject.loadRelatedMany}\n * (and {@link SmrtObject.getRelated}, which delegates to them) when a\n * tenant-scoped object resolves a relationship to an object belonging to a\n * *different*, non-null tenant — the genuine cross-tenant data leak. The guard\n * is a no-op when either side has a `null` tenant (global / non-tenant-scoped\n * models) and when both sides share the same tenant, so it only fires on real\n * leaks. Pass `{ allowCrossTenant: true }` to the loader to deliberately opt out.\n *\n * The `code` is always `'TENANT_ISOLATION_VIOLATION'` and the category is\n * `'validation'`. It is never retried — `ErrorUtils.withRetry()` rethrows it\n * immediately and `ErrorUtils.isRetryable()` returns `false` — because a tenant\n * boundary violation is deterministic. `tenantId` is the owning object's tenant\n * and `attemptedTenantId` is the tenant of the object that was reached.\n *\n * This shares its stable `code`, `name`, `tenantId`, and `attemptedTenantId`\n * shape with the interceptor-level `TenantIsolationError` in\n * `@happyvertical/smrt-tenancy`, so cross-cutting handlers can match either via\n * `err.code === 'TENANT_ISOLATION_VIOLATION'`. They are intentionally distinct\n * classes because `@happyvertical/smrt-core` cannot depend on the tenancy\n * package (the dependency runs the other way).\n *\n * @example\n * ```typescript\n * try {\n * await order.loadRelated('customerId');\n * } catch (err) {\n * if (err instanceof TenantIsolationError) {\n * // err.tenantId — the order's tenant\n * // err.attemptedTenantId — the customer's tenant\n * }\n * }\n * ```\n *\n * @see SmrtObject.loadRelated\n * @see SmrtObject.loadRelatedMany\n */\nexport class TenantIsolationError extends SmrtError {\n /** The tenant ID of the object that owns the relationship. */\n public readonly tenantId?: string;\n /** The tenant ID of the related object that was reached (and rejected). */\n public readonly attemptedTenantId?: string;\n\n constructor(\n message: string,\n details?: {\n tenantId?: string;\n attemptedTenantId?: string;\n [key: string]: unknown;\n },\n cause?: Error,\n ) {\n super(message, 'TENANT_ISOLATION_VIOLATION', 'validation', details, cause);\n this.tenantId = details?.tenantId;\n this.attemptedTenantId = details?.attemptedTenantId;\n }\n\n /**\n * Builds a {@link TenantIsolationError} for a blocked cross-tenant\n * relationship resolution, with a descriptive message and structured details.\n */\n static crossTenantReference(details: {\n sourceClass: string;\n fieldName: string;\n sourceTenantId: string;\n targetClass?: string;\n targetTenantId: string;\n }): TenantIsolationError {\n const target = details.targetClass\n ? `${details.targetClass} (tenant '${details.targetTenantId}')`\n : `tenant '${details.targetTenantId}'`;\n return new TenantIsolationError(\n `Cross-tenant relationship access blocked on ${details.sourceClass}.${details.fieldName}: ` +\n `owning tenant '${details.sourceTenantId}' does not match ${target}. ` +\n `Pass { allowCrossTenant: true } to loadRelated()/loadRelatedMany()/getRelated() to override.`,\n {\n tenantId: details.sourceTenantId,\n attemptedTenantId: details.targetTenantId,\n sourceClass: details.sourceClass,\n fieldName: details.fieldName,\n targetClass: details.targetClass,\n },\n );\n }\n}\n\n/**\n * Error thrown by `runOnce()` (`./run-once.ts`, #3080) when a submission's\n * claim cannot be resolved to a definite, replayable result.\n *\n * Mirrors the \"refused vs unknown outcome\" distinction #2990 drew for\n * `AssistantDock` actions:\n * - `RUN_ONCE_IN_FLIGHT` — a claim for this key exists and has not completed.\n * This is a definite decision, not an unknown one: some execution currently\n * holds the key. Retry later with the SAME token and content — minting a\n * fresh token would create an unrelated claim and defeat the guard.\n * - `RUN_ONCE_OUTCOME_UNKNOWN` — the claim insert reported a conflict but no\n * claim row could be read back. Genuinely indeterminate: retrying with the\n * SAME token and content is still safe (a completed claim replays; anything\n * else runs as a fresh attempt), but the caller must not treat this as\n * either success or failure.\n *\n * Both are `category: 'runtime'` and neither is retried automatically —\n * `runOnce()` never loops on them, because only the caller knows whether\n * retrying inline is appropriate for its own request (a SvelteKit action may\n * prefer to tell the user \"still processing\" over blocking on a retry loop).\n */\nexport class RunOnceClaimError extends SmrtError {\n /** The derived claim key this error concerns. */\n public readonly claimKey: string;\n\n constructor(\n message: string,\n code: 'RUN_ONCE_IN_FLIGHT' | 'RUN_ONCE_OUTCOME_UNKNOWN',\n claimKey: string,\n ) {\n super(message, code, 'runtime', { claimKey });\n this.claimKey = claimKey;\n }\n\n static inFlight(claimKey: string): RunOnceClaimError {\n return new RunOnceClaimError(\n `runOnce: claim \"${claimKey}\" is already in flight. Retry later with ` +\n `the same token and content — do not mint a new token.`,\n 'RUN_ONCE_IN_FLIGHT',\n claimKey,\n );\n }\n\n static outcomeUnknown(claimKey: string): RunOnceClaimError {\n return new RunOnceClaimError(\n `runOnce: outcome for claim \"${claimKey}\" is unknown. Retrying with ` +\n `the same token and content is safe, but do not treat this as ` +\n `either success or failure.`,\n 'RUN_ONCE_OUTCOME_UNKNOWN',\n claimKey,\n );\n }\n}\n\n/**\n * Utility functions for error handling\n */\nexport class ErrorUtils {\n /**\n * Wraps a function with error handling and automatic retry logic.\n *\n * Retries are for failures a later attempt might survive. An error is\n * rethrown immediately, with no backoff, when it is:\n *\n * - a {@link ValidationError} or {@link ConfigurationError} — the input is\n * wrong, and the same input will be wrong next time;\n * - a {@link TenantIsolationError} — a security boundary, and deterministic;\n * - a **deterministic database failure** (#2366), classified through the\n * driver-error cause chain by {@link classifyDatabaseError}: constraint\n * violations, invalid input syntax, missing tables/columns, and statements\n * issued inside an already-aborted PostgreSQL transaction (`25P02`).\n *\n * The database check matters because `@happyvertical/sql` wraps every driver\n * error as `DatabaseError('Failed to upsert record into table', …)`, hiding\n * the constraint wording from `error.message`. Without it, a unique-key\n * collision burned the full 500 + 1000 + 2000 ms backoff and — inside a\n * caller-managed transaction — replaced the real cause with\n * `25P02 current transaction is aborted` on the way out.\n *\n * Errors the classifier has no opinion about (`kind: 'unknown'`) keep the\n * original permissive behavior and are retried.\n */\n static async withRetry<T>(\n operation: () => Promise<T>,\n maxRetries = 3,\n delay = 1000,\n backoffMultiplier = 2,\n ): Promise<T> {\n let lastError: Error = new Error('Operation failed without error details');\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt === maxRetries) {\n throw lastError;\n }\n\n // Skip retry for certain error types. A tenant isolation violation is\n // deterministic — retrying re-fetches the same cross-tenant target — and\n // is a security boundary, so it must never be retried.\n if (\n error instanceof ValidationError ||\n error instanceof ConfigurationError ||\n error instanceof TenantIsolationError\n ) {\n throw error;\n }\n\n // A deterministic database failure cannot be retried into success, and\n // retrying it inside a transaction actively destroys evidence: every\n // later attempt runs on the aborted client and reports `25P02` instead\n // of the constraint that actually failed (#2366).\n if (classifyDatabaseError(error).deterministic) {\n throw lastError;\n }\n\n // Wait before retrying with exponential backoff\n // Wrap in try-catch to handle any potential timer errors\n try {\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), delay * backoffMultiplier ** attempt);\n });\n } catch (timerError) {\n // Log timer error but don't fail the retry\n logger.error('Timer error during retry', { error: timerError });\n }\n }\n }\n\n throw lastError;\n }\n\n /**\n * Checks if an error is retryable.\n *\n * A database failure is classified through its driver-error cause chain\n * first (#2366), so a wrapped `40001 serialization_failure` or `SQLITE_BUSY`\n * reports retryable while a wrapped `23505 unique_violation` does not —\n * neither of which the `category === 'database'` test alone could tell\n * apart. Only when the chain yields no opinion do the original\n * category/message heuristics apply.\n */\n static isRetryable(error: Error): boolean {\n const databaseClassification = classifyDatabaseError(error);\n if (databaseClassification.kind !== 'unknown') {\n return databaseClassification.retryable;\n }\n\n if (error instanceof SmrtError) {\n return error.category === 'network' || error.category === 'ai';\n }\n\n // Check for common retryable error patterns\n const retryablePatterns = [\n /ECONNRESET/,\n /ETIMEDOUT/,\n /ENOTFOUND/,\n /rate.?limit/i,\n /timeout/i,\n /503/,\n /502/,\n /500/,\n ];\n\n return retryablePatterns.some((pattern) => pattern.test(error.message));\n }\n\n /**\n * Sanitizes an error for safe logging (removes sensitive information)\n */\n static sanitizeError(error: Error): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n\n if (error instanceof SmrtError) {\n sanitized.code = error.code;\n sanitized.category = error.category;\n\n // Sanitize details to remove potential sensitive information\n if (error.details) {\n const details: Record<string, unknown> = { ...error.details };\n sanitized.details = details;\n\n // Remove common sensitive fields\n const sensitiveFields = [\n 'password',\n 'token',\n 'key',\n 'secret',\n 'apiKey',\n ];\n for (const field of sensitiveFields) {\n if (details[field]) {\n details[field] = '[REDACTED]';\n }\n }\n }\n }\n\n return sanitized;\n }\n}\n\n/**\n * Validation report that collects multiple validation errors\n *\n * Useful for validating an entire object and reporting all errors\n * at once rather than stopping at the first error.\n *\n * @example\n * ```typescript\n * const report = new ValidationReport('Product');\n * report.addError(ValidationError.requiredField('name', 'Product'));\n * report.addError(ValidationError.rangeError('price', -10, 0));\n *\n * if (report.hasErrors()) {\n * console.error(report.toString());\n * // Output:\n * // Validation failed for Product with 2 errors:\n * // - name: Required field 'name' is missing for Product\n * // - price: Value -10 for field 'price' is outside allowed range [0, undefined]\n * }\n * ```\n */\nexport class ValidationReport {\n private errors: ValidationError[] = [];\n private objectType: string;\n\n constructor(objectType: string) {\n this.objectType = objectType;\n }\n\n /**\n * Add a validation error to the report\n */\n addError(error: ValidationError): void {\n this.errors.push(error);\n }\n\n /**\n * Check if there are any validation errors\n */\n hasErrors(): boolean {\n return this.errors.length > 0;\n }\n\n /**\n * Get all validation errors\n */\n getErrors(): ValidationError[] {\n return [...this.errors];\n }\n\n /**\n * Get the number of validation errors\n */\n getErrorCount(): number {\n return this.errors.length;\n }\n\n /**\n * Convert to a human-readable string\n */\n toString(): string {\n if (this.errors.length === 0) {\n return `Validation passed for ${this.objectType}`;\n }\n\n const errorList = this.errors\n .map((err, idx) => ` ${idx + 1}. ${err.message}`)\n .join('\\n');\n\n return `Validation failed for ${this.objectType} with ${this.errors.length} error(s):\\n${errorList}`;\n }\n\n /**\n * Convert to JSON format\n */\n toJSON(): object {\n return {\n objectType: this.objectType,\n errorCount: this.errors.length,\n errors: this.errors.map((err) => err.toJSON()),\n };\n }\n\n /**\n * Throw the first error if there are any errors\n */\n throwIfErrors(): void {\n if (this.errors.length > 0) {\n throw this.errors[0];\n }\n }\n\n /**\n * Clear all errors\n */\n clear(): void {\n this.errors = [];\n }\n}\n\n/**\n * Validation utility functions\n */\nexport class ValidationUtils {\n /**\n * Validate a single field value\n *\n * @param fieldName - Name of the field\n * @param value - Value to validate\n * @param options - Validation options (required, min, max, etc.)\n * @returns ValidationError if validation fails, null otherwise\n */\n static async validateField(\n fieldName: string,\n value: unknown,\n options: {\n required?: boolean;\n min?: number;\n max?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string | RegExp;\n type?: string;\n customValidator?: (value: unknown) => boolean | Promise<boolean>;\n customMessage?: string;\n },\n objectType: string = 'Object',\n ): Promise<ValidationError | null> {\n // Required check\n if (\n options.required &&\n (value === null || value === undefined || value === '')\n ) {\n return ValidationError.requiredField(fieldName, objectType);\n }\n\n // Skip further validation if value is null/undefined and not required\n if (value === null || value === undefined) {\n return null;\n }\n\n // Numeric range validation\n if (typeof value === 'number') {\n if (options.min !== undefined && value < options.min) {\n return ValidationError.rangeError(\n fieldName,\n value,\n options.min,\n options.max,\n );\n }\n if (options.max !== undefined && value > options.max) {\n return ValidationError.rangeError(\n fieldName,\n value,\n options.min,\n options.max,\n );\n }\n }\n\n // String length validation\n if (typeof value === 'string') {\n if (options.minLength !== undefined && value.length < options.minLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with minimum length ${options.minLength}`,\n );\n }\n if (options.maxLength !== undefined && value.length > options.maxLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with maximum length ${options.maxLength}`,\n );\n }\n\n // Pattern validation\n if (options.pattern) {\n const regex =\n typeof options.pattern === 'string'\n ? new RegExp(options.pattern)\n : options.pattern;\n if (!regex.test(value)) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string matching pattern ${options.pattern}`,\n );\n }\n }\n }\n\n // Custom validator\n if (options.customValidator) {\n try {\n const isValid = await options.customValidator(value);\n if (!isValid) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n options.customMessage || 'custom validation failed',\n );\n }\n } catch (error) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `custom validation error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return null;\n }\n\n /**\n * Validate required field\n */\n static validateRequired(\n fieldName: string,\n value: unknown,\n objectType: string = 'Object',\n ): ValidationError | null {\n if (value === null || value === undefined || value === '') {\n return ValidationError.requiredField(fieldName, objectType);\n }\n return null;\n }\n\n /**\n * Validate numeric range\n */\n static validateRange(\n fieldName: string,\n value: number,\n min?: number,\n max?: number,\n ): ValidationError | null {\n if (min !== undefined && value < min) {\n return ValidationError.rangeError(fieldName, value, min, max);\n }\n if (max !== undefined && value > max) {\n return ValidationError.rangeError(fieldName, value, min, max);\n }\n return null;\n }\n\n /**\n * Validate string length\n */\n static validateLength(\n fieldName: string,\n value: string,\n minLength?: number,\n maxLength?: number,\n ): ValidationError | null {\n if (minLength !== undefined && value.length < minLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with minimum length ${minLength}`,\n );\n }\n if (maxLength !== undefined && value.length > maxLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with maximum length ${maxLength}`,\n );\n }\n return null;\n }\n\n /**\n * Validate string pattern\n */\n static validatePattern(\n fieldName: string,\n value: string,\n pattern: string | RegExp,\n ): ValidationError | null {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n if (!regex.test(value)) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string matching pattern ${pattern}`,\n );\n }\n return null;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"errors.js","names":[],"sources":["../src/errors.ts"],"sourcesContent":["/**\n * Comprehensive error handling system for SMRT framework\n *\n * Provides specialized error types for different failure scenarios\n * with proper error codes, messages, and debugging information.\n */\n\n/**\n * Abstract base class for all SMRT framework errors.\n *\n * Adds a structured `code` (machine-readable string constant), a `category`\n * (coarse error domain), optional structured `details`, and an optional\n * causal `Error` chain on top of the standard `Error` class.\n *\n * Never throw `SmrtError` directly — use one of the concrete subclasses\n * (`DatabaseError`, `AIError`, `ValidationError`, etc.) or their static\n * factory methods for consistent error codes and messages.\n *\n * @example\n * ```typescript\n * try {\n * await product.save();\n * } catch (err) {\n * if (err instanceof ValidationError) {\n * console.error(err.code, err.details); // 'VALIDATION_REQUIRED_FIELD', { fieldName, objectType }\n * }\n * if (err instanceof SmrtError) {\n * logger.error(ErrorUtils.sanitizeError(err));\n * }\n * }\n * ```\n */\n\nimport { createLogger } from '@happyvertical/logger';\nimport { classifyDatabaseError } from './db-errors';\n\nconst logger = createLogger({ level: 'info' });\n\nexport abstract class SmrtError extends Error {\n public readonly code: string;\n public readonly category:\n | 'database'\n | 'ai'\n | 'filesystem'\n | 'validation'\n | 'network'\n | 'configuration'\n | 'runtime';\n public readonly details?: Record<string, unknown>;\n public readonly cause?: Error;\n\n constructor(\n message: string,\n code: string,\n category: SmrtError['category'],\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message);\n this.name = this.constructor.name;\n this.code = code;\n this.category = category;\n this.details = details;\n this.cause = cause;\n\n // Maintain proper stack trace for V8\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, this.constructor);\n }\n }\n\n /**\n * Converts error to a serializable object for logging/debugging\n */\n toJSON() {\n return {\n name: this.name,\n message: this.message,\n code: this.code,\n category: this.category,\n details: this.details,\n stack: this.stack,\n cause: this.cause\n ? {\n name: this.cause.name,\n message: this.cause.message,\n stack: this.cause.stack,\n }\n : undefined,\n };\n }\n}\n\ntype ErrorLikeWithContext = Error & {\n cause?: unknown;\n context?: {\n originalError?: unknown;\n };\n};\n\nfunction collectErrorMessages(\n value: unknown,\n messages: string[],\n visited: Set<unknown>,\n depth = 0,\n): void {\n if (!value || visited.has(value) || depth > 10) {\n return;\n }\n\n visited.add(value);\n\n if (typeof value === 'string') {\n const trimmed = value.trim();\n if (trimmed) {\n messages.push(trimmed);\n }\n return;\n }\n\n if (!(value instanceof Error)) {\n return;\n }\n\n const message = value.message?.trim();\n if (message) {\n messages.push(message);\n }\n\n const errorWithContext = value as ErrorLikeWithContext;\n collectErrorMessages(\n errorWithContext.context?.originalError,\n messages,\n visited,\n depth + 1,\n );\n collectErrorMessages(errorWithContext.cause, messages, visited, depth + 1);\n}\n\nfunction getPrimaryCauseMessage(cause?: Error): {\n message?: string;\n messages?: string[];\n} {\n if (!cause) {\n return {};\n }\n\n const collected: string[] = [];\n collectErrorMessages(cause, collected, new Set<unknown>());\n\n const uniqueMessages = [...new Set(collected.filter(Boolean))];\n if (uniqueMessages.length === 0) {\n return {};\n }\n\n return {\n message: uniqueMessages[uniqueMessages.length - 1],\n messages: uniqueMessages,\n };\n}\n\n/**\n * Errors originating from database operations.\n *\n * Use the static factory methods rather than the constructor directly:\n * - `DatabaseError.connectionFailed(url, cause)` — DB connection failure\n * - `DatabaseError.queryFailed(query, cause)` — SQL execution error\n * - `DatabaseError.schemaError(table, op, cause)` — DDL/migration error\n * - `DatabaseError.constraintViolation(constraint, value, cause)` — FK/CHECK/UNIQUE\n * - `DatabaseError.corruptedData(field, class, cause)` — unparse-able column data\n * - `DatabaseError.missingDiscriminator(class, rowId)` — STI row missing `_meta_type`\n * - `DatabaseError.stiDiscriminatorConflict(...)` — legacy STI discriminator collides during qualification\n * - `DatabaseError.schemaMissing(table, class)` — table not yet migrated\n *\n * All errors have `category: 'database'` and codes prefixed with `DB_`.\n */\nexport class DatabaseError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'database', details, cause);\n }\n\n static connectionFailed(dbUrl: string, cause?: Error): DatabaseError {\n return new DatabaseError(\n `Failed to connect to database: ${dbUrl}`,\n 'DB_CONNECTION_FAILED',\n { dbUrl },\n cause,\n );\n }\n\n static queryFailed(query: string, cause?: Error): DatabaseError {\n // Include the deepest actionable cause message for better debugging.\n const causeInfo = getPrimaryCauseMessage(cause);\n const causeMsg = causeInfo.message ? `\\nCause: ${causeInfo.message}` : '';\n return new DatabaseError(\n `Database query failed: ${query.substring(0, 100)}${query.length > 100 ? '...' : ''}${causeMsg}`,\n 'DB_QUERY_FAILED',\n {\n query,\n causeMessage: causeInfo.message,\n causeMessages: causeInfo.messages,\n },\n cause,\n );\n }\n\n static schemaError(\n tableName: string,\n operation: string,\n cause?: Error,\n ): DatabaseError {\n return new DatabaseError(\n `Schema operation failed for table '${tableName}': ${operation}`,\n 'DB_SCHEMA_ERROR',\n { tableName, operation },\n cause,\n );\n }\n\n static constraintViolation(\n constraint: string,\n value: unknown,\n cause?: Error,\n ): DatabaseError {\n return new DatabaseError(\n `Database constraint violation: ${constraint}`,\n 'DB_CONSTRAINT_VIOLATION',\n { constraint, value },\n cause,\n );\n }\n\n static corruptedData(\n fieldName: string,\n className: string,\n cause?: Error,\n ): DatabaseError {\n return new DatabaseError(\n `Corrupted data in field '${fieldName}' for ${className}. ` +\n `The data cannot be parsed or is malformed. ` +\n `This may indicate database corruption or incompatible schema changes.`,\n 'DB_CORRUPTED_DATA',\n { fieldName, className },\n cause,\n );\n }\n\n static missingDiscriminator(\n className: string,\n rowId?: string,\n ): DatabaseError {\n return new DatabaseError(\n `Missing discriminator (_meta_type) for STI class ${className}${rowId ? ` (row id: ${rowId})` : ''}. ` +\n `STI classes require a discriminator column to determine the correct subclass. ` +\n `This may indicate a schema mismatch or manual database modification.`,\n 'DB_MISSING_DISCRIMINATOR',\n { className, rowId },\n );\n }\n\n static stiDiscriminatorConflict(details: {\n className: string;\n tableName: string;\n id: string;\n slug: string;\n context: string;\n conflictIdentity: Record<string, unknown>;\n legacyMetaType: string;\n qualifiedMetaType: string;\n duplicateId: string;\n }): DatabaseError {\n const identityText = Object.entries(details.conflictIdentity)\n .map(([key, value]) => `${key} '${String(value)}'`)\n .join(', ');\n\n return new DatabaseError(\n `Legacy STI discriminator collision for ${details.className} (${details.tableName}). ` +\n `Row '${details.id}' would upgrade _meta_type from '${details.legacyMetaType}' to '${details.qualifiedMetaType}', ` +\n `but row '${details.duplicateId}' already uses the qualified discriminator for ${identityText || 'the same conflict identity'}. ` +\n `Merge or remove the duplicate legacy/qualified rows before saving.`,\n 'DB_STI_DISCRIMINATOR_CONFLICT',\n details,\n );\n }\n\n static schemaMissing(tableName: string, className: string): DatabaseError {\n return new DatabaseError(\n `Table '${tableName}' does not exist for class '${className}'. ` +\n `Run 'smrt db:migrate' to create database schema.`,\n 'DB_SCHEMA_MISSING',\n { tableName, className },\n );\n }\n}\n\n/**\n * Errors from AI provider integrations.\n *\n * Use the static factory methods:\n * - `AIError.providerError(provider, operation, cause)` — generic provider failure\n * - `AIError.rateLimitExceeded(provider, retryAfter)` — rate limit hit\n * - `AIError.invalidResponse(provider, response)` — unexpected response shape\n * - `AIError.authenticationFailed(provider)` — bad API key / credentials\n *\n * All errors have `category: 'ai'` and codes prefixed with `AI_`.\n * AI errors are considered retryable by `ErrorUtils.isRetryable()`.\n */\nexport class AIError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'ai', details, cause);\n }\n\n static providerError(\n provider: string,\n operation: string,\n cause?: Error,\n ): AIError {\n return new AIError(\n `AI provider '${provider}' failed during ${operation}`,\n 'AI_PROVIDER_ERROR',\n { provider, operation },\n cause,\n );\n }\n\n static rateLimitExceeded(provider: string, retryAfter?: number): AIError {\n return new AIError(\n `AI provider '${provider}' rate limit exceeded`,\n 'AI_RATE_LIMIT',\n { provider, retryAfter },\n );\n }\n\n static invalidResponse(provider: string, response: unknown): AIError {\n return new AIError(\n `AI provider '${provider}' returned invalid response`,\n 'AI_INVALID_RESPONSE',\n { provider, response },\n );\n }\n\n static authenticationFailed(provider: string): AIError {\n return new AIError(\n `AI provider '${provider}' authentication failed`,\n 'AI_AUTH_FAILED',\n { provider },\n );\n }\n}\n\n/**\n * Errors from filesystem operations.\n *\n * Use the static factory methods:\n * - `FilesystemError.fileNotFound(path)` — file does not exist\n * - `FilesystemError.permissionDenied(path, operation)` — access denied\n * - `FilesystemError.diskSpaceExceeded(path, requiredBytes)` — insufficient space\n *\n * All errors have `category: 'filesystem'` and codes prefixed with `FS_`.\n */\nexport class FilesystemError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'filesystem', details, cause);\n }\n\n static fileNotFound(path: string): FilesystemError {\n return new FilesystemError(`File not found: ${path}`, 'FS_FILE_NOT_FOUND', {\n path,\n });\n }\n\n static permissionDenied(path: string, operation: string): FilesystemError {\n return new FilesystemError(\n `Permission denied for ${operation} on: ${path}`,\n 'FS_PERMISSION_DENIED',\n { path, operation },\n );\n }\n\n static diskSpaceExceeded(\n path: string,\n requiredBytes: number,\n ): FilesystemError {\n return new FilesystemError(\n `Insufficient disk space for operation on: ${path}`,\n 'FS_DISK_SPACE_EXCEEDED',\n { path, requiredBytes },\n );\n }\n}\n\n/**\n * Input/data validation errors thrown before or during a database operation.\n *\n * `save()` throws `ValidationError` when field validation fails. The collection's\n * `convertWhereKeys()` throws it for invalid WHERE clause operators or field names.\n * `ValidationError` is **not** retried by `ErrorUtils.withRetry()`.\n *\n * Use the static factory methods:\n * - `ValidationError.requiredField(field, objectType)` — missing required field\n * - `ValidationError.invalidValue(field, value, expected)` — wrong type/format\n * - `ValidationError.uniqueConstraint(field, value)` — duplicate unique value\n * - `ValidationError.rangeError(field, value, min?, max?)` — out of allowed range\n *\n * All errors have `category: 'validation'` and codes prefixed with `VALIDATION_`.\n */\nexport class ValidationError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'validation', details, cause);\n }\n\n static requiredField(fieldName: string, objectType: string): ValidationError {\n return new ValidationError(\n `Required field '${fieldName}' is missing for ${objectType}`,\n 'VALIDATION_REQUIRED_FIELD',\n { fieldName, objectType },\n );\n }\n\n static invalidValue(\n fieldName: string,\n value: unknown,\n expectedType: string,\n ): ValidationError {\n return new ValidationError(\n `Invalid value for field '${fieldName}': expected ${expectedType}, got ${typeof value}`,\n 'VALIDATION_INVALID_VALUE',\n { fieldName, value, expectedType },\n );\n }\n\n static uniqueConstraint(fieldName: string, value: unknown): ValidationError {\n return new ValidationError(\n `Unique constraint violation for field '${fieldName}' with value: ${String(value)}`,\n 'VALIDATION_UNIQUE_CONSTRAINT',\n { fieldName, value },\n );\n }\n\n static rangeError(\n fieldName: string,\n value: number,\n min?: number,\n max?: number,\n ): ValidationError {\n const range =\n min !== undefined && max !== undefined\n ? `between ${min} and ${max}`\n : min !== undefined\n ? `>= ${min}`\n : `<= ${max}`;\n\n return new ValidationError(\n `Value for field '${fieldName}' must be ${range}, got: ${value}`,\n 'VALIDATION_RANGE_ERROR',\n { fieldName, value, min, max },\n );\n }\n}\n\n/**\n * Errors from HTTP and external network operations.\n *\n * Use the static factory methods:\n * - `NetworkError.requestFailed(url, status?, body?)` — non-2xx response or connection failure\n * - `NetworkError.timeout(url, timeoutMs)` — request exceeded timeout\n * - `NetworkError.serviceUnavailable(service, reason?)` — external service down\n *\n * All errors have `category: 'network'` and codes prefixed with `NETWORK_`.\n * Network errors are considered retryable by `ErrorUtils.isRetryable()`.\n */\nexport class NetworkError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'network', details, cause);\n }\n\n static requestFailed(\n url: string,\n status?: number,\n responseBody?: string | Error,\n ): NetworkError {\n const cause = responseBody instanceof Error ? responseBody : undefined;\n const body = typeof responseBody === 'string' ? responseBody : undefined;\n return new NetworkError(\n `Network request failed: ${url}${status ? ` (Status: ${status})` : ''}${body ? ` - ${body.substring(0, 200)}` : ''}`,\n 'NETWORK_REQUEST_FAILED',\n { url, status, responseBody: body },\n cause,\n );\n }\n\n static timeout(url: string, timeoutMs: number): NetworkError {\n return new NetworkError(\n `Network request timed out after ${timeoutMs}ms: ${url}`,\n 'NETWORK_TIMEOUT',\n { url, timeoutMs },\n );\n }\n\n static serviceUnavailable(service: string, reason?: string): NetworkError {\n return new NetworkError(\n reason\n ? `External service unavailable: ${service} - ${reason}`\n : `External service unavailable: ${service}`,\n 'NETWORK_SERVICE_UNAVAILABLE',\n { service, reason },\n );\n }\n}\n\n/**\n * Errors from misconfigured or incompatible class/framework setup.\n *\n * These are typically thrown during class registration (i.e. at module load time),\n * not during normal request handling.\n *\n * Use the static factory methods:\n * - `ConfigurationError.missingConfiguration(key, context?)` — missing required config\n * - `ConfigurationError.invalidConfiguration(key, value, expected)` — wrong config type/value\n * - `ConfigurationError.initializationFailed(component, cause?)` — component failed to start\n * - `ConfigurationError.circularInheritance(class, chain)` — circular class inheritance\n * - `ConfigurationError.incompatibleStrategy(class, strategy, parent, parentStrategy)` — STI mismatch\n * - `ConfigurationError.unregisteredBaseClass(child, base)` — STI base not yet registered\n *\n * All errors have `category: 'configuration'` and codes prefixed with `CONFIG_`.\n * Configuration errors are **not** retried by `ErrorUtils.withRetry()`.\n */\nexport class ConfigurationError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'configuration', details, cause);\n }\n\n static missingConfiguration(\n configKey: string,\n context?: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `Missing required configuration: ${configKey}${context ? ` in ${context}` : ''}`,\n 'CONFIG_MISSING',\n { configKey, context },\n );\n }\n\n static invalidConfiguration(\n configKey: string,\n value: unknown,\n expected: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `Invalid configuration for ${configKey}: expected ${expected}, got ${typeof value}`,\n 'CONFIG_INVALID',\n { configKey, value, expected },\n );\n }\n\n static initializationFailed(\n component: string,\n cause?: Error,\n ): ConfigurationError {\n return new ConfigurationError(\n `Failed to initialize component: ${component}`,\n 'CONFIG_INIT_FAILED',\n { component },\n cause,\n );\n }\n\n static circularInheritance(\n className: string,\n inheritanceChain: string[],\n ): ConfigurationError {\n return new ConfigurationError(\n `Circular inheritance detected for class '${className}'. ` +\n `Inheritance chain: ${inheritanceChain.join(' → ')} → ${className}. ` +\n `Classes cannot inherit from themselves directly or indirectly.`,\n 'CONFIG_CIRCULAR_INHERITANCE',\n { className, inheritanceChain },\n );\n }\n\n static incompatibleStrategy(\n className: string,\n classStrategy: string,\n parentClass: string,\n parentStrategy: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `Incompatible table strategy for class '${className}' (${classStrategy}). ` +\n `Parent class '${parentClass}' uses ${parentStrategy} strategy. ` +\n `Child classes must use the same table strategy as their parent. ` +\n `Either change ${className} to use ${parentStrategy}, or remove the inheritance.`,\n 'CONFIG_INCOMPATIBLE_STRATEGY',\n { className, classStrategy, parentClass, parentStrategy },\n );\n }\n\n static unregisteredBaseClass(\n childClass: string,\n baseClass: string,\n ): ConfigurationError {\n return new ConfigurationError(\n `STI base class '${baseClass}' is not registered for child class '${childClass}'. ` +\n `When using Single Table Inheritance, the base class must be registered before any child classes. ` +\n `Ensure ${baseClass} is decorated with @smrt({ tableStrategy: 'sti' }) and imported before ${childClass}.`,\n 'CONFIG_UNREGISTERED_BASE',\n { childClass, baseClass },\n );\n }\n}\n\n/**\n * Errors representing unexpected runtime failures not covered by other categories.\n *\n * `RuntimeError` is the catch-all for internal framework errors — invalid object\n * state, exhausted resources, or failures in operations like `save()` and `loadFromId()`\n * that propagate from an unknown cause.\n *\n * Use the static factory methods:\n * - `RuntimeError.operationFailed(operation, context?, cause?)` — generic operation failure\n * - `RuntimeError.invalidState(message, context?)` — unexpected object/system state\n * - `RuntimeError.resourceExhausted(resource, limit)` — limit exceeded (e.g. connections)\n *\n * All errors have `category: 'runtime'` and codes prefixed with `RUNTIME_`.\n */\nexport class RuntimeError extends SmrtError {\n constructor(\n message: string,\n code: string,\n details?: Record<string, unknown>,\n cause?: Error,\n ) {\n super(message, code, 'runtime', details, cause);\n }\n\n static operationFailed(\n operation: string,\n context?: string,\n cause?: Error,\n ): RuntimeError {\n return new RuntimeError(\n `Operation failed: ${operation}${context ? ` in ${context}` : ''}`,\n 'RUNTIME_OPERATION_FAILED',\n { operation, context },\n cause,\n );\n }\n\n static invalidState(\n message: string,\n context?: Record<string, unknown>,\n ): RuntimeError {\n return new RuntimeError(message, 'RUNTIME_INVALID_STATE', context);\n }\n\n static resourceExhausted(resource: string, limit: number): RuntimeError {\n return new RuntimeError(\n `Resource exhausted: ${resource} exceeded limit of ${limit}`,\n 'RUNTIME_RESOURCE_EXHAUSTED',\n { resource, limit },\n );\n }\n}\n\n/**\n * Error thrown when a tenant isolation boundary is crossed while resolving a\n * relationship.\n *\n * Raised by {@link SmrtObject.loadRelated} / {@link SmrtObject.loadRelatedMany}\n * (and {@link SmrtObject.getRelated}, which delegates to them) when a\n * tenant-scoped object resolves a relationship to an object belonging to a\n * *different*, non-null tenant — the genuine cross-tenant data leak. The guard\n * is a no-op when either side has a `null` tenant (global / non-tenant-scoped\n * models) and when both sides share the same tenant, so it only fires on real\n * leaks. Pass `{ allowCrossTenant: true }` to the loader to deliberately opt out.\n *\n * The `code` is always `'TENANT_ISOLATION_VIOLATION'` and the category is\n * `'validation'`. It is never retried — `ErrorUtils.withRetry()` rethrows it\n * immediately and `ErrorUtils.isRetryable()` returns `false` — because a tenant\n * boundary violation is deterministic. `tenantId` is the owning object's tenant\n * and `attemptedTenantId` is the tenant of the object that was reached.\n *\n * This shares its stable `code`, `name`, `tenantId`, and `attemptedTenantId`\n * shape with the interceptor-level `TenantIsolationError` in\n * `@happyvertical/smrt-tenancy`, so cross-cutting handlers can match either via\n * `err.code === 'TENANT_ISOLATION_VIOLATION'`. They are intentionally distinct\n * classes because `@happyvertical/smrt-core` cannot depend on the tenancy\n * package (the dependency runs the other way).\n *\n * @example\n * ```typescript\n * try {\n * await order.loadRelated('customerId');\n * } catch (err) {\n * if (err instanceof TenantIsolationError) {\n * // err.tenantId — the order's tenant\n * // err.attemptedTenantId — the customer's tenant\n * }\n * }\n * ```\n *\n * @see SmrtObject.loadRelated\n * @see SmrtObject.loadRelatedMany\n */\nexport class TenantIsolationError extends SmrtError {\n /** The tenant ID of the object that owns the relationship. */\n public readonly tenantId?: string;\n /** The tenant ID of the related object that was reached (and rejected). */\n public readonly attemptedTenantId?: string;\n\n constructor(\n message: string,\n details?: {\n tenantId?: string;\n attemptedTenantId?: string;\n [key: string]: unknown;\n },\n cause?: Error,\n ) {\n super(message, 'TENANT_ISOLATION_VIOLATION', 'validation', details, cause);\n this.tenantId = details?.tenantId;\n this.attemptedTenantId = details?.attemptedTenantId;\n }\n\n /**\n * Builds a {@link TenantIsolationError} for a blocked cross-tenant\n * relationship resolution, with a descriptive message and structured details.\n */\n static crossTenantReference(details: {\n sourceClass: string;\n fieldName: string;\n sourceTenantId: string;\n targetClass?: string;\n targetTenantId: string;\n }): TenantIsolationError {\n const target = details.targetClass\n ? `${details.targetClass} (tenant '${details.targetTenantId}')`\n : `tenant '${details.targetTenantId}'`;\n return new TenantIsolationError(\n `Cross-tenant relationship access blocked on ${details.sourceClass}.${details.fieldName}: ` +\n `owning tenant '${details.sourceTenantId}' does not match ${target}. ` +\n `Pass { allowCrossTenant: true } to loadRelated()/loadRelatedMany()/getRelated() to override.`,\n {\n tenantId: details.sourceTenantId,\n attemptedTenantId: details.targetTenantId,\n sourceClass: details.sourceClass,\n fieldName: details.fieldName,\n targetClass: details.targetClass,\n },\n );\n }\n\n /**\n * Builds a {@link TenantIsolationError} for a natural-key save whose\n * conflict target matched a row owned by a different tenant (or a global\n * row, or — for a global save — a tenant's row). `save()` refuses instead of\n * letting `ON CONFLICT … DO UPDATE` rewrite that row's `id` and tenant.\n *\n * The other row's owner is deliberately NOT reported: naming it would\n * disclose another tenant's identity to the caller. Only the caller's own\n * values appear in the message and details.\n */\n static naturalKeyOwnedElsewhere(details: {\n className: string;\n tableName: string;\n conflictColumns: string[];\n conflictValues: Record<string, unknown>;\n ownershipColumns: string[];\n tenantId?: string | null;\n }): TenantIsolationError {\n const key = details.conflictColumns\n .map(\n (column) =>\n `${column}=${JSON.stringify(details.conflictValues[column] ?? null)}`,\n )\n .join(', ');\n return new TenantIsolationError(\n `Refusing to save ${details.className}: its natural key (${key}) on ` +\n `\"${details.tableName}\" already belongs to a row with a different owner ` +\n `(${details.ownershipColumns.join(', ')}). Saving would overwrite that row's ` +\n `id and owner. Give the table a tenant-inclusive unique key ` +\n `(declare tenant scope, or drop the explicit conflictColumns that omit ` +\n `the tenant column, then run \\`smrt db:migrate\\`), or choose another natural key.`,\n {\n tenantId: details.tenantId ?? undefined,\n className: details.className,\n tableName: details.tableName,\n conflictColumns: details.conflictColumns,\n ownershipColumns: details.ownershipColumns,\n reason: 'natural_key_owned_elsewhere',\n },\n );\n }\n}\n\n/**\n * Error thrown by `runOnce()` (`./run-once.ts`, #3080) when a submission's\n * claim cannot be resolved to a definite, replayable result.\n *\n * Mirrors the \"refused vs unknown outcome\" distinction #2990 drew for\n * `AssistantDock` actions:\n * - `RUN_ONCE_IN_FLIGHT` — a claim for this key exists and has not completed.\n * This is a definite decision, not an unknown one: some execution currently\n * holds the key. Retry later with the SAME token and content — minting a\n * fresh token would create an unrelated claim and defeat the guard.\n * - `RUN_ONCE_OUTCOME_UNKNOWN` — the claim insert reported a conflict but no\n * claim row could be read back. Genuinely indeterminate: retrying with the\n * SAME token and content is still safe (a completed claim replays; anything\n * else runs as a fresh attempt), but the caller must not treat this as\n * either success or failure.\n *\n * Both are `category: 'runtime'` and neither is retried automatically —\n * `runOnce()` never loops on them, because only the caller knows whether\n * retrying inline is appropriate for its own request (a SvelteKit action may\n * prefer to tell the user \"still processing\" over blocking on a retry loop).\n */\nexport class RunOnceClaimError extends SmrtError {\n /** The derived claim key this error concerns. */\n public readonly claimKey: string;\n\n constructor(\n message: string,\n code: 'RUN_ONCE_IN_FLIGHT' | 'RUN_ONCE_OUTCOME_UNKNOWN',\n claimKey: string,\n ) {\n super(message, code, 'runtime', { claimKey });\n this.claimKey = claimKey;\n }\n\n static inFlight(claimKey: string): RunOnceClaimError {\n return new RunOnceClaimError(\n `runOnce: claim \"${claimKey}\" is already in flight. Retry later with ` +\n `the same token and content — do not mint a new token.`,\n 'RUN_ONCE_IN_FLIGHT',\n claimKey,\n );\n }\n\n static outcomeUnknown(claimKey: string): RunOnceClaimError {\n return new RunOnceClaimError(\n `runOnce: outcome for claim \"${claimKey}\" is unknown. Retrying with ` +\n `the same token and content is safe, but do not treat this as ` +\n `either success or failure.`,\n 'RUN_ONCE_OUTCOME_UNKNOWN',\n claimKey,\n );\n }\n}\n\n/**\n * Utility functions for error handling\n */\nexport class ErrorUtils {\n /**\n * Wraps a function with error handling and automatic retry logic.\n *\n * Retries are for failures a later attempt might survive. An error is\n * rethrown immediately, with no backoff, when it is:\n *\n * - a {@link ValidationError} or {@link ConfigurationError} — the input is\n * wrong, and the same input will be wrong next time;\n * - a {@link TenantIsolationError} — a security boundary, and deterministic;\n * - a **deterministic database failure** (#2366), classified through the\n * driver-error cause chain by {@link classifyDatabaseError}: constraint\n * violations, invalid input syntax, missing tables/columns, and statements\n * issued inside an already-aborted PostgreSQL transaction (`25P02`).\n *\n * The database check matters because `@happyvertical/sql` wraps every driver\n * error as `DatabaseError('Failed to upsert record into table', …)`, hiding\n * the constraint wording from `error.message`. Without it, a unique-key\n * collision burned the full 500 + 1000 + 2000 ms backoff and — inside a\n * caller-managed transaction — replaced the real cause with\n * `25P02 current transaction is aborted` on the way out.\n *\n * Errors the classifier has no opinion about (`kind: 'unknown'`) keep the\n * original permissive behavior and are retried.\n */\n static async withRetry<T>(\n operation: () => Promise<T>,\n maxRetries = 3,\n delay = 1000,\n backoffMultiplier = 2,\n ): Promise<T> {\n let lastError: Error = new Error('Operation failed without error details');\n\n for (let attempt = 0; attempt <= maxRetries; attempt++) {\n try {\n return await operation();\n } catch (error) {\n lastError = error instanceof Error ? error : new Error(String(error));\n\n if (attempt === maxRetries) {\n throw lastError;\n }\n\n // Skip retry for certain error types. A tenant isolation violation is\n // deterministic — retrying re-fetches the same cross-tenant target — and\n // is a security boundary, so it must never be retried.\n if (\n error instanceof ValidationError ||\n error instanceof ConfigurationError ||\n error instanceof TenantIsolationError\n ) {\n throw error;\n }\n\n // A deterministic database failure cannot be retried into success, and\n // retrying it inside a transaction actively destroys evidence: every\n // later attempt runs on the aborted client and reports `25P02` instead\n // of the constraint that actually failed (#2366).\n if (classifyDatabaseError(error).deterministic) {\n throw lastError;\n }\n\n // Wait before retrying with exponential backoff\n // Wrap in try-catch to handle any potential timer errors\n try {\n await new Promise<void>((resolve) => {\n setTimeout(() => resolve(), delay * backoffMultiplier ** attempt);\n });\n } catch (timerError) {\n // Log timer error but don't fail the retry\n logger.error('Timer error during retry', { error: timerError });\n }\n }\n }\n\n throw lastError;\n }\n\n /**\n * Checks if an error is retryable.\n *\n * A database failure is classified through its driver-error cause chain\n * first (#2366), so a wrapped `40001 serialization_failure` or `SQLITE_BUSY`\n * reports retryable while a wrapped `23505 unique_violation` does not —\n * neither of which the `category === 'database'` test alone could tell\n * apart. Only when the chain yields no opinion do the original\n * category/message heuristics apply.\n */\n static isRetryable(error: Error): boolean {\n const databaseClassification = classifyDatabaseError(error);\n if (databaseClassification.kind !== 'unknown') {\n return databaseClassification.retryable;\n }\n\n if (error instanceof SmrtError) {\n return error.category === 'network' || error.category === 'ai';\n }\n\n // Check for common retryable error patterns\n const retryablePatterns = [\n /ECONNRESET/,\n /ETIMEDOUT/,\n /ENOTFOUND/,\n /rate.?limit/i,\n /timeout/i,\n /503/,\n /502/,\n /500/,\n ];\n\n return retryablePatterns.some((pattern) => pattern.test(error.message));\n }\n\n /**\n * Sanitizes an error for safe logging (removes sensitive information)\n */\n static sanitizeError(error: Error): Record<string, unknown> {\n const sanitized: Record<string, unknown> = {\n name: error.name,\n message: error.message,\n stack: error.stack,\n };\n\n if (error instanceof SmrtError) {\n sanitized.code = error.code;\n sanitized.category = error.category;\n\n // Sanitize details to remove potential sensitive information\n if (error.details) {\n const details: Record<string, unknown> = { ...error.details };\n sanitized.details = details;\n\n // Remove common sensitive fields\n const sensitiveFields = [\n 'password',\n 'token',\n 'key',\n 'secret',\n 'apiKey',\n ];\n for (const field of sensitiveFields) {\n if (details[field]) {\n details[field] = '[REDACTED]';\n }\n }\n }\n }\n\n return sanitized;\n }\n}\n\n/**\n * Validation report that collects multiple validation errors\n *\n * Useful for validating an entire object and reporting all errors\n * at once rather than stopping at the first error.\n *\n * @example\n * ```typescript\n * const report = new ValidationReport('Product');\n * report.addError(ValidationError.requiredField('name', 'Product'));\n * report.addError(ValidationError.rangeError('price', -10, 0));\n *\n * if (report.hasErrors()) {\n * console.error(report.toString());\n * // Output:\n * // Validation failed for Product with 2 errors:\n * // - name: Required field 'name' is missing for Product\n * // - price: Value -10 for field 'price' is outside allowed range [0, undefined]\n * }\n * ```\n */\nexport class ValidationReport {\n private errors: ValidationError[] = [];\n private objectType: string;\n\n constructor(objectType: string) {\n this.objectType = objectType;\n }\n\n /**\n * Add a validation error to the report\n */\n addError(error: ValidationError): void {\n this.errors.push(error);\n }\n\n /**\n * Check if there are any validation errors\n */\n hasErrors(): boolean {\n return this.errors.length > 0;\n }\n\n /**\n * Get all validation errors\n */\n getErrors(): ValidationError[] {\n return [...this.errors];\n }\n\n /**\n * Get the number of validation errors\n */\n getErrorCount(): number {\n return this.errors.length;\n }\n\n /**\n * Convert to a human-readable string\n */\n toString(): string {\n if (this.errors.length === 0) {\n return `Validation passed for ${this.objectType}`;\n }\n\n const errorList = this.errors\n .map((err, idx) => ` ${idx + 1}. ${err.message}`)\n .join('\\n');\n\n return `Validation failed for ${this.objectType} with ${this.errors.length} error(s):\\n${errorList}`;\n }\n\n /**\n * Convert to JSON format\n */\n toJSON(): object {\n return {\n objectType: this.objectType,\n errorCount: this.errors.length,\n errors: this.errors.map((err) => err.toJSON()),\n };\n }\n\n /**\n * Throw the first error if there are any errors\n */\n throwIfErrors(): void {\n if (this.errors.length > 0) {\n throw this.errors[0];\n }\n }\n\n /**\n * Clear all errors\n */\n clear(): void {\n this.errors = [];\n }\n}\n\n/**\n * Validation utility functions\n */\nexport class ValidationUtils {\n /**\n * Validate a single field value\n *\n * @param fieldName - Name of the field\n * @param value - Value to validate\n * @param options - Validation options (required, min, max, etc.)\n * @returns ValidationError if validation fails, null otherwise\n */\n static async validateField(\n fieldName: string,\n value: unknown,\n options: {\n required?: boolean;\n min?: number;\n max?: number;\n minLength?: number;\n maxLength?: number;\n pattern?: string | RegExp;\n type?: string;\n customValidator?: (value: unknown) => boolean | Promise<boolean>;\n customMessage?: string;\n },\n objectType: string = 'Object',\n ): Promise<ValidationError | null> {\n // Required check\n if (\n options.required &&\n (value === null || value === undefined || value === '')\n ) {\n return ValidationError.requiredField(fieldName, objectType);\n }\n\n // Skip further validation if value is null/undefined and not required\n if (value === null || value === undefined) {\n return null;\n }\n\n // Numeric range validation\n if (typeof value === 'number') {\n if (options.min !== undefined && value < options.min) {\n return ValidationError.rangeError(\n fieldName,\n value,\n options.min,\n options.max,\n );\n }\n if (options.max !== undefined && value > options.max) {\n return ValidationError.rangeError(\n fieldName,\n value,\n options.min,\n options.max,\n );\n }\n }\n\n // String length validation\n if (typeof value === 'string') {\n if (options.minLength !== undefined && value.length < options.minLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with minimum length ${options.minLength}`,\n );\n }\n if (options.maxLength !== undefined && value.length > options.maxLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with maximum length ${options.maxLength}`,\n );\n }\n\n // Pattern validation\n if (options.pattern) {\n const regex =\n typeof options.pattern === 'string'\n ? new RegExp(options.pattern)\n : options.pattern;\n if (!regex.test(value)) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string matching pattern ${options.pattern}`,\n );\n }\n }\n }\n\n // Custom validator\n if (options.customValidator) {\n try {\n const isValid = await options.customValidator(value);\n if (!isValid) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n options.customMessage || 'custom validation failed',\n );\n }\n } catch (error) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `custom validation error: ${error instanceof Error ? error.message : String(error)}`,\n );\n }\n }\n\n return null;\n }\n\n /**\n * Validate required field\n */\n static validateRequired(\n fieldName: string,\n value: unknown,\n objectType: string = 'Object',\n ): ValidationError | null {\n if (value === null || value === undefined || value === '') {\n return ValidationError.requiredField(fieldName, objectType);\n }\n return null;\n }\n\n /**\n * Validate numeric range\n */\n static validateRange(\n fieldName: string,\n value: number,\n min?: number,\n max?: number,\n ): ValidationError | null {\n if (min !== undefined && value < min) {\n return ValidationError.rangeError(fieldName, value, min, max);\n }\n if (max !== undefined && value > max) {\n return ValidationError.rangeError(fieldName, value, min, max);\n }\n return null;\n }\n\n /**\n * Validate string length\n */\n static validateLength(\n fieldName: string,\n value: string,\n minLength?: number,\n maxLength?: number,\n ): ValidationError | null {\n if (minLength !== undefined && value.length < minLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with minimum length ${minLength}`,\n );\n }\n if (maxLength !== undefined && value.length > maxLength) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string with maximum length ${maxLength}`,\n );\n }\n return null;\n }\n\n /**\n * Validate string pattern\n */\n static validatePattern(\n fieldName: string,\n value: string,\n pattern: string | RegExp,\n ): ValidationError | null {\n const regex = typeof pattern === 'string' ? new RegExp(pattern) : pattern;\n if (!regex.test(value)) {\n return ValidationError.invalidValue(\n fieldName,\n value,\n `string matching pattern ${pattern}`,\n );\n }\n return null;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight-route.d.ts","sourceRoot":"","sources":["../../src/generators/preflight-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAWH,8EAA8E;AAC9E,eAAO,MAAM,gCAAgC,eAAe,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B;;;;EAI/B,CAAC;AAEZ;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,KAAK,EAAE,SAAS,CAAC;IACjB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,8EAA8E;IAC9E,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uCAAuC;IACvC,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,6BAA6B,KACnC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAYD;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAwBnB;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,
|
|
1
|
+
{"version":3,"file":"preflight-route.d.ts","sourceRoot":"","sources":["../../src/generators/preflight-route.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAWH,8EAA8E;AAC9E,eAAO,MAAM,gCAAgC,eAAe,CAAC;AAE7D;;;;;GAKG;AACH,eAAO,MAAM,6BAA6B;;;;EAI/B,CAAC;AAEZ;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,kCAAkC;IAClC,GAAG,EAAE,MAAM,CAAC;IACZ,0CAA0C;IAC1C,KAAK,EAAE,SAAS,CAAC;IACjB,8EAA8E;IAC9E,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,8EAA8E;IAC9E,iBAAiB,EAAE,OAAO,CAAC;IAC3B,uCAAuC;IACvC,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAED;;;GAGG;AACH,MAAM,MAAM,yBAAyB,GAAG,CACtC,OAAO,EAAE,6BAA6B,KACnC,OAAO,CAAC,OAAO,CAAC,CAAC;AAEtB;;;;GAIG;AACH,MAAM,WAAW,6BAA6B;IAC5C,QAAQ,CAAC,EAAE,yBAAyB,CAAC;IACrC,WAAW,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,CAAC;IAC/B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,EAAE,CAAC,EAAE,OAAO,CAAC;CACd;AAYD;;;;;;;GAOG;AACH,wBAAsB,4BAA4B,CAChD,GAAG,EAAE,OAAO,EACZ,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,QAAQ,CAAC,CAwBnB;AAED;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAO7E;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,MAAM,EACd,UAAU,CAAC,EAAE,MAAM,GAClB,MAAM,CAgCR;AAgBD;;;;;;;;;;;;GAYG;AACH,wBAAgB,2BAA2B,CACzC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAsBT;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAuCT;AAeD;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,UAAU,EAAE,MAAM,GAAG,SAAS,EAC9B,MAAM,EAAE,MAAM,GACb,OAAO,CAQT;AAED;;;;;;;GAOG;AACH,wBAAgB,wBAAwB,CACtC,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,MAAM,EAAE,CAiBV"}
|
|
@@ -86,7 +86,7 @@ async function handlePlaybookPreflightRoute(req, options) {
|
|
|
86
86
|
* fails closed rather than reporting on a model that has no route.
|
|
87
87
|
*/
|
|
88
88
|
function resolveRegisteredObjectName(model) {
|
|
89
|
-
return (model.includes(":") ? ObjectRegistry.getClassByQualifiedName(model) : ObjectRegistry.getClass(model))?.name;
|
|
89
|
+
return (model.includes(":") ? ObjectRegistry.getClassByQualifiedName(model, { source: "playbook step model (REST preflight)" }) : ObjectRegistry.getClass(model))?.name;
|
|
90
90
|
}
|
|
91
91
|
/**
|
|
92
92
|
* The HTTP method a REST action is served by.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"preflight-route.js","names":[],"sources":["../../src/generators/preflight-route.ts"],"sourcesContent":["/**\n * Generated `_preflight` HTTP route for browser-plane playbook preflight\n * (issue #2590).\n *\n * Handles `GET {basePath}/_preflight?key=<playbook key>` in the REST generator:\n * an advisory, read-effect, idempotent report of what a caller's playbook would\n * be allowed to do — *predicted*, never granted. Every step is authorized again\n * where it executes; this route is capability **selection**, never\n * authorization (epic #2585 invariant 2).\n *\n * ## `authMiddleware` is never invoked here\n *\n * Generated REST authorization is\n * `authMiddleware?: (objectName, action) => (req) => Promise<Request | Response>`\n * — request-bound, `Response`-returning rather than boolean, and free to consult\n * session stores, rate-limit, or audit. It is not a dry-run predicate, and a\n * synthetic-`Request` dry run of it would be a side effect the caller never\n * asked for.\n *\n * That is enforced **structurally**, not by discipline:\n * {@link PlaybookPreflightRouteOptions} has no `authMiddleware` member and no\n * function-valued auth member of any kind. `rest.ts` passes the boolean\n * `appAuthConfigured` and nothing else, so there is no handle in this module to\n * invoke even by mistake. The app-auth layer is consequently reported as\n * `unknown`, which is the honest answer.\n *\n * ## Why the provider is injected\n *\n * Resolution and verdict shaping live in `@happyvertical/smrt-playbooks`, which\n * depends on this package. Core therefore owns the route and the static-layer\n * facts (`ObjectRegistry` is core's), and takes the evaluator as a seam — the\n * dependency stays one-way.\n */\n\nimport { ObjectRegistry } from '../registry.js';\nimport type { MethodDefinition } from '../scanner/types.js';\nimport { PRIVATE_READ_CACHE_CONTROL } from './conditional-get.js';\nimport {\n declaresRuntimeRestRoute,\n readMethodDecoratorConfig,\n resolveEffectiveActionMetadata,\n} from './custom-action.js';\n\n/** Path segment the preflight route is served at, under the API base path. */\nexport const PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT = '_preflight';\n\n/**\n * Capability classification of the preflight route: a read, safely repeatable,\n * and closed-world. It is admitted by a default read-only browser exposure\n * policy without an opt-in, because it reports on the system rather than\n * changing it.\n */\nexport const PLAYBOOK_PREFLIGHT_CAPABILITY = Object.freeze({\n effect: 'read',\n idempotent: true,\n openWorld: false,\n} as const);\n\n/**\n * The request handed to a preflight provider. Deliberately carries no request,\n * no headers, and no auth handle — only the caller-scoped facts the static\n * layers need.\n */\nexport interface PlaybookPreflightRouteRequest {\n /** The requested playbook key. */\n key: string;\n /** Always `'browser'` from this route. */\n plane: 'browser';\n /** The caller's published permission slugs, when the API context has them. */\n permissions?: Iterable<string>;\n /** Whether an app auth middleware is wired. A boolean; never the function. */\n appAuthConfigured: boolean;\n /** The generator's `APIContext.db`. */\n db?: unknown;\n}\n\n/**\n * Host-supplied browser-plane preflight evaluator, wired from\n * `@happyvertical/smrt-playbooks`. Returns a JSON-serializable report.\n */\nexport type PlaybookPreflightProvider = (\n request: PlaybookPreflightRouteRequest,\n) => Promise<unknown>;\n\n/**\n * Options for {@link handlePlaybookPreflightRoute}.\n *\n * There is intentionally no `authMiddleware` member — see the module docs.\n */\nexport interface PlaybookPreflightRouteOptions {\n provider?: PlaybookPreflightProvider;\n permissions?: Iterable<string>;\n appAuthConfigured: boolean;\n db?: unknown;\n}\n\nfunction jsonResponse(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': PRIVATE_READ_CACHE_CONTROL,\n },\n });\n}\n\n/**\n * Serves `GET {basePath}/_preflight?key=<key>`.\n *\n * Unresolvable keys are the provider's concern: it returns the same uniform\n * \"unavailable\" body for an unknown key as for an unauthorized one, and this\n * route serves whatever it returns with an unconditional 200, so the HTTP layer\n * adds no way to tell them apart either.\n */\nexport async function handlePlaybookPreflightRoute(\n req: Request,\n options: PlaybookPreflightRouteOptions,\n): Promise<Response> {\n if (!options.provider) {\n // Route not wired for this deployment. Says nothing about any key.\n return jsonResponse({ error: 'Not found' }, 404);\n }\n\n if (req.method !== 'GET') {\n return jsonResponse({ error: 'Method not allowed' }, 405);\n }\n\n const key = new URL(req.url).searchParams.get('key');\n if (!key) {\n return jsonResponse({ error: \"Query parameter 'key' is required\" }, 400);\n }\n\n const report = await options.provider({\n key,\n plane: 'browser',\n ...(options.permissions ? { permissions: options.permissions } : {}),\n appAuthConfigured: options.appAuthConfigured,\n db: options.db,\n });\n\n return jsonResponse(report, 200);\n}\n\n/**\n * Resolves a qualified model reference (`@happyvertical/smrt-commerce:Order`)\n * to the name the registry and the REST generator key configuration by.\n *\n * Returns `undefined` for anything this build does not register, so the caller\n * fails closed rather than reporting on a model that has no route.\n */\nexport function resolveRegisteredObjectName(model: string): string | undefined {\n const registered = model.includes(':')\n ? ObjectRegistry.getClassByQualifiedName(model)\n : ObjectRegistry.getClass(model);\n return registered?.name;\n}\n\n/**\n * The HTTP method a REST action is served by.\n *\n * CRUD actions map to their fixed verbs. A custom action is served under the\n * method its own declaration supplies — `@method({ httpMethod })` first, then\n * `api.routes[action].method`, defaulting to `POST` exactly as\n * `dispatchCustomCollectionAction` does — because guessing `POST` for a\n * declared `GET` action would make preflight report a false `deny` on a\n * `public: 'read'` model, hiding a playbook the caller can actually run, which\n * is the tool-listing case this exists to serve. Without an `objectName` to\n * read the declaration from, the fail-closed `POST` remains.\n */\nexport function restMethodForApiAction(\n action: string,\n objectName?: string,\n): string {\n switch (action) {\n case 'list':\n case 'get':\n return 'GET';\n case 'create':\n return 'POST';\n case 'update':\n return 'PUT';\n case 'delete':\n return 'DELETE';\n default:\n break;\n }\n\n if (!objectName) {\n return 'POST';\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return 'POST';\n }\n\n const effective = resolveEffectiveActionMetadata({\n actionName: action,\n ...(readRegisteredMethod(objectName, action)\n ? { method: readRegisteredMethod(objectName, action) }\n : {}),\n apiConfig,\n });\n return (effective.httpMethod ?? 'POST').toUpperCase();\n}\n\n/**\n * The method view backing `action`: the manifest entry when the registry has\n * one, with its `@method()` config backfilled from the live decorator store\n * when it does not — the unscanned-runtime posture, where reading only the\n * manifest would silently ignore `@method({ expose: false })` (#2686). Mirrors\n * `APIGenerator.runtimeMethod`, which decides the dispatch this predicts.\n */\nfunction readRegisteredMethod(\n objectName: string,\n action: string,\n): MethodDefinition | undefined {\n return ObjectRegistry.resolveRuntimeMethod(objectName, action).method;\n}\n\n/**\n * Whether `@smrt({ api })` exposes `action` on `objectName`.\n *\n * The generator's own action gate, lifted to a module function so preflight and\n * the live route read the same rule from one place. Accepts any action name so\n * a custom action is gated by the same `include`/`exclude` lists.\n *\n * @remarks An absent `objectName` returns `true` — fail-**open**, because the\n * live route reaches this only after it has already resolved a model, and an\n * unnamed object there means \"not gated by this rule\". A caller *predicting*\n * rather than serving has no such guarantee and must reject an unresolvable\n * model before asking (see `createRestPreflightLayerSource`).\n */\nexport function isApiActionEnabledForObject(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) {\n return true;\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName).api;\n\n if (apiConfig === false) {\n return false;\n }\n\n if (apiConfig && typeof apiConfig === 'object') {\n if (apiConfig.include && !apiConfig.include.includes(action)) {\n return false;\n }\n\n if (apiConfig.exclude?.includes(action)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Whether `action` names a route the generated REST surface can actually\n * dispatch on `objectName`.\n *\n * CRUD actions always have a route. A custom action exists only when it is\n * DECLARED — historically an `api.routes` entry, and since #2686 also a\n * `@method()` supplying route-shaping metadata. `dispatchCustomCollectionAction`\n * iterates exactly that union, so an action outside it can never execute no\n * matter what `include`/`exclude` say. Exposure alone would report a typo'd or\n * removed custom action as `allow`, and an agent would then start the earlier\n * steps of a non-atomic playbook before dying on it — the failure preflight\n * exists to prevent. This prediction and that dispatch must stay one rule.\n */\nexport function isRestActionRoutable(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) return false;\n if (\n action === 'list' ||\n action === 'get' ||\n action === 'create' ||\n action === 'update' ||\n action === 'delete'\n ) {\n return true;\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return false;\n }\n\n const registered = readRegisteredMethod(objectName, action);\n\n // `@method({ expose: false })` outranks a legacy `api.routes` entry for the\n // same method, and dispatch honors that. Checking it BEFORE the routes map is\n // what keeps the two one rule: otherwise a withheld action that still carried\n // a route declaration predicted `allow` for an operation the transport\n // refuses (#2686).\n if (readMethodDecoratorConfig(registered)?.expose === false) return false;\n\n if (\n apiConfig.routes &&\n Object.hasOwn(apiConfig.routes as Record<string, unknown>, action)\n ) {\n return isHostableByRuntimeRest(objectName, action);\n }\n\n // Shared with `APIGenerator.declaredCollectionActions`, which decides the\n // dispatch this predicate exists to predict.\n return (\n declaresRuntimeRestRoute(registered) &&\n isHostableByRuntimeRest(objectName, action)\n );\n}\n\n/**\n * Whether this transport can HOST the action at all.\n *\n * It serves only collection-scoped custom actions, so an item-scoped\n * declaration — the `@method()` decorator's most common shape, on a model\n * instance method — answers 404 in dispatch. Predicting `allow` for it is the\n * false-`allow` this module exists to prevent, so routability is the\n * conjunction of \"declared\" and \"hostable\" (#2686).\n */\nfunction isHostableByRuntimeRest(objectName: string, action: string): boolean {\n return ObjectRegistry.isCollectionHostedMethod(objectName, action);\n}\n\n/**\n * Fail-closed authorization posture (#1540): true only when the object opts out\n * of auth via `@smrt({ api: { public } })` — `true` for every method, `'read'`\n * for safe (GET) methods only.\n */\nexport function isRestRoutePublic(\n objectName: string | undefined,\n method: string,\n): boolean {\n if (!objectName) return false;\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') return false;\n const publicAccess = (apiConfig as { public?: boolean | 'read' }).public;\n if (publicAccess === true) return true;\n if (publicAccess === 'read') return method.toUpperCase() === 'GET';\n return false;\n}\n\n/**\n * Field-level read-permission slugs declared by `objectName`.\n *\n * Reads the model's own and inherited fields only — deliberately **not** the\n * STI base-plus-descendants union used for cache policy. That union answers\n * \"does any variant carry a read-permission field?\"; used here it would report\n * a sibling variant's slugs as required for a step naming this concrete model.\n */\nexport function restFieldReadPermissions(\n objectName: string | undefined,\n): string[] {\n if (!objectName) return [];\n const registered = ObjectRegistry.getClass(objectName);\n const className = registered?.qualifiedName ?? registered?.name ?? objectName;\n const fields =\n registered?.inheritedFields ?? ObjectRegistry.getFields(className);\n const slugs = new Set<string>();\n for (const [, def] of fields) {\n const slug =\n typeof def?.readPermission === 'string'\n ? def.readPermission\n : typeof def?._meta?.readPermission === 'string'\n ? (def._meta.readPermission as string)\n : undefined;\n if (slug) slugs.add(slug);\n }\n return [...slugs].sort();\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"preflight-route.js","names":[],"sources":["../../src/generators/preflight-route.ts"],"sourcesContent":["/**\n * Generated `_preflight` HTTP route for browser-plane playbook preflight\n * (issue #2590).\n *\n * Handles `GET {basePath}/_preflight?key=<playbook key>` in the REST generator:\n * an advisory, read-effect, idempotent report of what a caller's playbook would\n * be allowed to do — *predicted*, never granted. Every step is authorized again\n * where it executes; this route is capability **selection**, never\n * authorization (epic #2585 invariant 2).\n *\n * ## `authMiddleware` is never invoked here\n *\n * Generated REST authorization is\n * `authMiddleware?: (objectName, action) => (req) => Promise<Request | Response>`\n * — request-bound, `Response`-returning rather than boolean, and free to consult\n * session stores, rate-limit, or audit. It is not a dry-run predicate, and a\n * synthetic-`Request` dry run of it would be a side effect the caller never\n * asked for.\n *\n * That is enforced **structurally**, not by discipline:\n * {@link PlaybookPreflightRouteOptions} has no `authMiddleware` member and no\n * function-valued auth member of any kind. `rest.ts` passes the boolean\n * `appAuthConfigured` and nothing else, so there is no handle in this module to\n * invoke even by mistake. The app-auth layer is consequently reported as\n * `unknown`, which is the honest answer.\n *\n * ## Why the provider is injected\n *\n * Resolution and verdict shaping live in `@happyvertical/smrt-playbooks`, which\n * depends on this package. Core therefore owns the route and the static-layer\n * facts (`ObjectRegistry` is core's), and takes the evaluator as a seam — the\n * dependency stays one-way.\n */\n\nimport { ObjectRegistry } from '../registry.js';\nimport type { MethodDefinition } from '../scanner/types.js';\nimport { PRIVATE_READ_CACHE_CONTROL } from './conditional-get.js';\nimport {\n declaresRuntimeRestRoute,\n readMethodDecoratorConfig,\n resolveEffectiveActionMetadata,\n} from './custom-action.js';\n\n/** Path segment the preflight route is served at, under the API base path. */\nexport const PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT = '_preflight';\n\n/**\n * Capability classification of the preflight route: a read, safely repeatable,\n * and closed-world. It is admitted by a default read-only browser exposure\n * policy without an opt-in, because it reports on the system rather than\n * changing it.\n */\nexport const PLAYBOOK_PREFLIGHT_CAPABILITY = Object.freeze({\n effect: 'read',\n idempotent: true,\n openWorld: false,\n} as const);\n\n/**\n * The request handed to a preflight provider. Deliberately carries no request,\n * no headers, and no auth handle — only the caller-scoped facts the static\n * layers need.\n */\nexport interface PlaybookPreflightRouteRequest {\n /** The requested playbook key. */\n key: string;\n /** Always `'browser'` from this route. */\n plane: 'browser';\n /** The caller's published permission slugs, when the API context has them. */\n permissions?: Iterable<string>;\n /** Whether an app auth middleware is wired. A boolean; never the function. */\n appAuthConfigured: boolean;\n /** The generator's `APIContext.db`. */\n db?: unknown;\n}\n\n/**\n * Host-supplied browser-plane preflight evaluator, wired from\n * `@happyvertical/smrt-playbooks`. Returns a JSON-serializable report.\n */\nexport type PlaybookPreflightProvider = (\n request: PlaybookPreflightRouteRequest,\n) => Promise<unknown>;\n\n/**\n * Options for {@link handlePlaybookPreflightRoute}.\n *\n * There is intentionally no `authMiddleware` member — see the module docs.\n */\nexport interface PlaybookPreflightRouteOptions {\n provider?: PlaybookPreflightProvider;\n permissions?: Iterable<string>;\n appAuthConfigured: boolean;\n db?: unknown;\n}\n\nfunction jsonResponse(body: unknown, status: number): Response {\n return new Response(JSON.stringify(body), {\n status,\n headers: {\n 'Content-Type': 'application/json',\n 'Cache-Control': PRIVATE_READ_CACHE_CONTROL,\n },\n });\n}\n\n/**\n * Serves `GET {basePath}/_preflight?key=<key>`.\n *\n * Unresolvable keys are the provider's concern: it returns the same uniform\n * \"unavailable\" body for an unknown key as for an unauthorized one, and this\n * route serves whatever it returns with an unconditional 200, so the HTTP layer\n * adds no way to tell them apart either.\n */\nexport async function handlePlaybookPreflightRoute(\n req: Request,\n options: PlaybookPreflightRouteOptions,\n): Promise<Response> {\n if (!options.provider) {\n // Route not wired for this deployment. Says nothing about any key.\n return jsonResponse({ error: 'Not found' }, 404);\n }\n\n if (req.method !== 'GET') {\n return jsonResponse({ error: 'Method not allowed' }, 405);\n }\n\n const key = new URL(req.url).searchParams.get('key');\n if (!key) {\n return jsonResponse({ error: \"Query parameter 'key' is required\" }, 400);\n }\n\n const report = await options.provider({\n key,\n plane: 'browser',\n ...(options.permissions ? { permissions: options.permissions } : {}),\n appAuthConfigured: options.appAuthConfigured,\n db: options.db,\n });\n\n return jsonResponse(report, 200);\n}\n\n/**\n * Resolves a qualified model reference (`@happyvertical/smrt-commerce:Order`)\n * to the name the registry and the REST generator key configuration by.\n *\n * Returns `undefined` for anything this build does not register, so the caller\n * fails closed rather than reporting on a model that has no route.\n */\nexport function resolveRegisteredObjectName(model: string): string | undefined {\n const registered = model.includes(':')\n ? ObjectRegistry.getClassByQualifiedName(model, {\n source: 'playbook step model (REST preflight)',\n })\n : ObjectRegistry.getClass(model);\n return registered?.name;\n}\n\n/**\n * The HTTP method a REST action is served by.\n *\n * CRUD actions map to their fixed verbs. A custom action is served under the\n * method its own declaration supplies — `@method({ httpMethod })` first, then\n * `api.routes[action].method`, defaulting to `POST` exactly as\n * `dispatchCustomCollectionAction` does — because guessing `POST` for a\n * declared `GET` action would make preflight report a false `deny` on a\n * `public: 'read'` model, hiding a playbook the caller can actually run, which\n * is the tool-listing case this exists to serve. Without an `objectName` to\n * read the declaration from, the fail-closed `POST` remains.\n */\nexport function restMethodForApiAction(\n action: string,\n objectName?: string,\n): string {\n switch (action) {\n case 'list':\n case 'get':\n return 'GET';\n case 'create':\n return 'POST';\n case 'update':\n return 'PUT';\n case 'delete':\n return 'DELETE';\n default:\n break;\n }\n\n if (!objectName) {\n return 'POST';\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return 'POST';\n }\n\n const effective = resolveEffectiveActionMetadata({\n actionName: action,\n ...(readRegisteredMethod(objectName, action)\n ? { method: readRegisteredMethod(objectName, action) }\n : {}),\n apiConfig,\n });\n return (effective.httpMethod ?? 'POST').toUpperCase();\n}\n\n/**\n * The method view backing `action`: the manifest entry when the registry has\n * one, with its `@method()` config backfilled from the live decorator store\n * when it does not — the unscanned-runtime posture, where reading only the\n * manifest would silently ignore `@method({ expose: false })` (#2686). Mirrors\n * `APIGenerator.runtimeMethod`, which decides the dispatch this predicts.\n */\nfunction readRegisteredMethod(\n objectName: string,\n action: string,\n): MethodDefinition | undefined {\n return ObjectRegistry.resolveRuntimeMethod(objectName, action).method;\n}\n\n/**\n * Whether `@smrt({ api })` exposes `action` on `objectName`.\n *\n * The generator's own action gate, lifted to a module function so preflight and\n * the live route read the same rule from one place. Accepts any action name so\n * a custom action is gated by the same `include`/`exclude` lists.\n *\n * @remarks An absent `objectName` returns `true` — fail-**open**, because the\n * live route reaches this only after it has already resolved a model, and an\n * unnamed object there means \"not gated by this rule\". A caller *predicting*\n * rather than serving has no such guarantee and must reject an unresolvable\n * model before asking (see `createRestPreflightLayerSource`).\n */\nexport function isApiActionEnabledForObject(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) {\n return true;\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName).api;\n\n if (apiConfig === false) {\n return false;\n }\n\n if (apiConfig && typeof apiConfig === 'object') {\n if (apiConfig.include && !apiConfig.include.includes(action)) {\n return false;\n }\n\n if (apiConfig.exclude?.includes(action)) {\n return false;\n }\n }\n\n return true;\n}\n\n/**\n * Whether `action` names a route the generated REST surface can actually\n * dispatch on `objectName`.\n *\n * CRUD actions always have a route. A custom action exists only when it is\n * DECLARED — historically an `api.routes` entry, and since #2686 also a\n * `@method()` supplying route-shaping metadata. `dispatchCustomCollectionAction`\n * iterates exactly that union, so an action outside it can never execute no\n * matter what `include`/`exclude` say. Exposure alone would report a typo'd or\n * removed custom action as `allow`, and an agent would then start the earlier\n * steps of a non-atomic playbook before dying on it — the failure preflight\n * exists to prevent. This prediction and that dispatch must stay one rule.\n */\nexport function isRestActionRoutable(\n objectName: string | undefined,\n action: string,\n): boolean {\n if (!objectName) return false;\n if (\n action === 'list' ||\n action === 'get' ||\n action === 'create' ||\n action === 'update' ||\n action === 'delete'\n ) {\n return true;\n }\n\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') {\n return false;\n }\n\n const registered = readRegisteredMethod(objectName, action);\n\n // `@method({ expose: false })` outranks a legacy `api.routes` entry for the\n // same method, and dispatch honors that. Checking it BEFORE the routes map is\n // what keeps the two one rule: otherwise a withheld action that still carried\n // a route declaration predicted `allow` for an operation the transport\n // refuses (#2686).\n if (readMethodDecoratorConfig(registered)?.expose === false) return false;\n\n if (\n apiConfig.routes &&\n Object.hasOwn(apiConfig.routes as Record<string, unknown>, action)\n ) {\n return isHostableByRuntimeRest(objectName, action);\n }\n\n // Shared with `APIGenerator.declaredCollectionActions`, which decides the\n // dispatch this predicate exists to predict.\n return (\n declaresRuntimeRestRoute(registered) &&\n isHostableByRuntimeRest(objectName, action)\n );\n}\n\n/**\n * Whether this transport can HOST the action at all.\n *\n * It serves only collection-scoped custom actions, so an item-scoped\n * declaration — the `@method()` decorator's most common shape, on a model\n * instance method — answers 404 in dispatch. Predicting `allow` for it is the\n * false-`allow` this module exists to prevent, so routability is the\n * conjunction of \"declared\" and \"hostable\" (#2686).\n */\nfunction isHostableByRuntimeRest(objectName: string, action: string): boolean {\n return ObjectRegistry.isCollectionHostedMethod(objectName, action);\n}\n\n/**\n * Fail-closed authorization posture (#1540): true only when the object opts out\n * of auth via `@smrt({ api: { public } })` — `true` for every method, `'read'`\n * for safe (GET) methods only.\n */\nexport function isRestRoutePublic(\n objectName: string | undefined,\n method: string,\n): boolean {\n if (!objectName) return false;\n const apiConfig = ObjectRegistry.getConfig(objectName)?.api;\n if (!apiConfig || typeof apiConfig !== 'object') return false;\n const publicAccess = (apiConfig as { public?: boolean | 'read' }).public;\n if (publicAccess === true) return true;\n if (publicAccess === 'read') return method.toUpperCase() === 'GET';\n return false;\n}\n\n/**\n * Field-level read-permission slugs declared by `objectName`.\n *\n * Reads the model's own and inherited fields only — deliberately **not** the\n * STI base-plus-descendants union used for cache policy. That union answers\n * \"does any variant carry a read-permission field?\"; used here it would report\n * a sibling variant's slugs as required for a step naming this concrete model.\n */\nexport function restFieldReadPermissions(\n objectName: string | undefined,\n): string[] {\n if (!objectName) return [];\n const registered = ObjectRegistry.getClass(objectName);\n const className = registered?.qualifiedName ?? registered?.name ?? objectName;\n const fields =\n registered?.inheritedFields ?? ObjectRegistry.getFields(className);\n const slugs = new Set<string>();\n for (const [, def] of fields) {\n const slug =\n typeof def?.readPermission === 'string'\n ? def.readPermission\n : typeof def?._meta?.readPermission === 'string'\n ? (def._meta.readPermission as string)\n : undefined;\n if (slug) slugs.add(slug);\n }\n return [...slugs].sort();\n}\n"],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -78,6 +78,7 @@ export { getTestDatabase, type TestDatabaseOptions, } from './testing/database';
|
|
|
78
78
|
export * from './tools/index';
|
|
79
79
|
export { chunkArray, IN_LIST_CHUNK_SIZE } from './utils/chunk';
|
|
80
80
|
export { clone, getAdapterInfo, isValid, type JSONAdapter, type ParseError, parse, type Result, type StringifyError, safeParse, safeStringify, stringify, } from './utils/json';
|
|
81
|
+
export { toSnakeCase } from './utils/naming';
|
|
81
82
|
export { createQualifiedName, getClassName, getPackageFromQualifiedName, isFromPackage, isQualifiedName, isType, type ParsedQualifiedName, parseQualifiedName, qualifiedNamesEqual, } from './utils/qualified-names';
|
|
82
83
|
export { smrtPlugin } from './vite-plugin/index';
|
|
83
84
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import "./adapters/index.js";
|
|
|
6
6
|
import { classifyDatabaseError, classifyDialectMessage, isAbortedTransactionError, isDeterministicDatabaseError, isNotNullViolationError, isTransientDatabaseError, isUniqueViolationError } from "./db-errors.js";
|
|
7
7
|
import { AIError, ConfigurationError, DatabaseError, ErrorUtils, FilesystemError, NetworkError, RunOnceClaimError, RuntimeError, SmrtError, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils } from "./errors.js";
|
|
8
8
|
import { IN_LIST_CHUNK_SIZE, chunkArray } from "./utils/chunk.js";
|
|
9
|
+
import { toSnakeCase } from "./utils/naming.js";
|
|
9
10
|
import { buildCascadePlan, cascadeReferencesTo, normalizeOnDelete, runCascadeDelete } from "./cascade.js";
|
|
10
11
|
import { CHANGE_FEED_CREDENTIAL_TABLES, declareChangeFeedSensitiveTable, getChangeFeedSensitiveTables, isChangeFeedSensitiveTable } from "./change-feed-sensitivity.js";
|
|
11
12
|
import { CACHE_INVALIDATION_CHANNEL, broadcastCacheInvalidation, ensureCacheInvalidationListener, getCacheGeneration, invalidateCollectionCache, resetCollectionCache, resolveDbCacheKey, stopCacheInvalidationListeners } from "./collection-cache.js";
|
|
@@ -101,4 +102,4 @@ import "./system/index.js";
|
|
|
101
102
|
import { getTestDatabase } from "./testing/database.js";
|
|
102
103
|
import "./tools/index.js";
|
|
103
104
|
import { smrtPlugin } from "./vite-plugin/index.js";
|
|
104
|
-
export { AGENT_SURFACE_HASH_PREFIX, AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, BOOTED_PROVENANCE, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_CREDENTIAL_TABLES, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CRUD_OPERATIONS, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_FACET_LIMIT, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DEFAULT_RETENTION_POLICY, DIAGNOSTICS_DEFAULT_LIMIT, DataQueryValidationError, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, EmbeddingUnavailableError, ErrorUtils, FilesystemError, GlobalInterceptors, IN_LIST_CHUNK_SIZE, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, MAX_FACET_FIELDS, MAX_FACET_LIMIT, MAX_LIST_LIMIT, MAX_STI_READ_SCOPE_TYPES, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, POSTGRES_REVISION_GUARD_EXPRESSION, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RUN_ONCE_CLAIMS_TABLE, RunOnceClaimError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SMRT_SCHEMA_VERSION, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SYSTEM_DIAGNOSTICS_TABLES, SYSTEM_TABLE_NAMES, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, appendChanges, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresPermissions, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPlainJson, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildCascadePlan, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, buildKnowledgeGraph, bumpChangeFeed, canonicalReadRepresentation, canonicalizeDataQuery, cascadeReferencesTo, changeEventSubscribersAtCapacity, checkKnowledgeGraphFreshness, checkLiveSchemaParity, childAccessorName, chunkArray, classifyDatabaseError, classifyDialectMessage, classifyMethodWireability, classifyParameterWireability, clearRetentionTasks, clone, coerceCustomActionArgument, collectForeignKeyOrphanCounts, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createClassNamePredicate, createDataQueryFingerprint, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createManifestClassNamePredicate, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, declareChangeFeedSensitiveTable, declaredTypeAcceptsDate, declaresRuntimeRestRoute, declaresRuntimeRestRouteShape, deriveRunOnceClaimKey, detectEngine, digestRunOnceContent, discoverKnowledgeArtifactPaths, discoverManifestEntry, discoverScopedPackageDirectories, drainChangeFeed, ensureBootstrapSystemTableCompatibility, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, ensureSystemTables, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeDecision, executeToolCall, executeToolCalls, field, filterVisibleChangeFeedEntries, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getAuthorizedChangesSince, getAuthorizedTenantScopedChangesSince, getCacheGeneration, getChangeFeedSensitiveTables, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getRetentionTasks, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, handlePlaybookPreflightRoute, hasActionableChanges, hasChangeFeedEntryVisibilityHook, hasChangeFeedTableAuthorizerHook, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isApiActionEnabledForObject, isChangeFeedDenyAll, isChangeFeedEntryVisible, isChangeFeedSensitiveTable, isCrudOperation, isCrudToolAction, isDatabaseInterface, isDeterministicDatabaseError, isEmbeddedDatabase, isFrameworkBaseClass, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isPostgresDatabase, isQualifiedName, isRestActionRoutable, isRestRoutePublic, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, method, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema, normalizeEventsMaxSubscribers, normalizeOnDelete, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planForeignKeyCreation, planPostgresPermissions, planPostgresSystemTimestampMigrations, postgresRevisionCandidates, postgresRevisionCondition, processSyncApplyBatch, pruneAiUsage, pruneChangeFeed, pruneExpiredContexts, pruneRunOnceClaims, publishArtifactFiles, publishAtomicArtifact, qualifiedNamesEqual, queryStringDecoderFor, readAgentModuleDocs, readDispatchHealth, readJobHealth, readMethodDecoratorConfig, readMigrationStatus, readPackageAgentDoc, readRecentChanges, readRegistryDrift, readScheduleHealth, readSystemDiagnostics, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerCompatibleMethodDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, registerRetentionTask, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveApiMethodExposure, resolveAuthorizedChangeFeedTables, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDeclaredScopeMismatch, resolveDispatchTenantId, resolveDispatchTenantScope, resolveEffectiveActionMetadata, resolveExistingRunOnceClaim, resolveFileKnowledgeConfig, resolveGetStringFilter, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runCascadeDelete, runOnce, runRetentionSweep, runWithTenantGate, safeParse, safeStringify, sanitizeMessagePaths, setChangeFeedAuthorizer, setChangeFeedEntryVisibility, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, snapshotRegistry, sortMCPTools, stableStringify, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, toCustomActionBoolean, toCustomActionDate, toCustomActionNumber, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, unregisterRetentionTask, usesEmbeddedRevisionFallback, validatePostgresPermissionContract, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized, withEmbeddedWriteQueue, withEmbeddedWriteTransaction };
|
|
105
|
+
export { AGENT_SURFACE_HASH_PREFIX, AIError, APIGenerator, AiUsageCollector, AiUsagePersistenceHandler, BOOTED_PROVENANCE, CACHE_INVALIDATION_CHANNEL, CHANGE_FEED_CREDENTIAL_TABLES, CHANGE_FEED_INTERCEPTOR_NAME, CHANGE_FEED_TABLE, CHANGE_SIGNAL_CHANNEL, CRUD_OPERATIONS, ConfigurationError, ContentHasher, CosineSimilarity, DEFAULT_AI_COST_RATES, DEFAULT_CHANGES_LIMIT, DEFAULT_DATA_QUERY_PAGE_LIMIT, DEFAULT_DATA_QUERY_RESULT_BYTES, DEFAULT_EMBEDDING_CONFIG, DEFAULT_EVENTS_HEARTBEAT_MS, DEFAULT_EVENTS_MAX_SUBSCRIBERS, DEFAULT_EVENTS_RETRY_AFTER_SECONDS, DEFAULT_FACET_LIMIT, DEFAULT_LEARNING_CONFIG, DEFAULT_LIST_LIMIT, DEFAULT_LIST_ORDER_BY, DEFAULT_POSTGRES_TIMEOUTS, DEFAULT_RETENTION_POLICY, DIAGNOSTICS_DEFAULT_LIMIT, DataQueryValidationError, DatabaseError, Dispatch, DispatchBus, DispatchCollection, DispatchSubscription, DispatchSubscriptionCollection, EmbeddingProvider, EmbeddingStorage, EmbeddingUnavailableError, ErrorUtils, FilesystemError, GlobalInterceptors, IN_LIST_CHUNK_SIZE, LearningMemory, LiveSchemaParityError, MAX_CHANGES_LIMIT, MAX_DATA_QUERY_CURSOR_LENGTH, MAX_DATA_QUERY_FACETS, MAX_DATA_QUERY_FILTERS, MAX_DATA_QUERY_FILTER_DEPTH, MAX_DATA_QUERY_IN_VALUES, MAX_DATA_QUERY_OFFSET, MAX_DATA_QUERY_PAGE_LIMIT, MAX_DATA_QUERY_REQUEST_BYTES, MAX_DATA_QUERY_RESULT_BYTES, MAX_DATA_QUERY_WARNINGS, MAX_FACET_FIELDS, MAX_FACET_LIMIT, MAX_LIST_LIMIT, MAX_STI_READ_SCOPE_TYPES, MAX_SYNC_APPLY_BATCH_SIZE, MCPGenerator, MCP_STABLE_CATALOG_TTL_MS, MODULE_DOC_HASH_PREFIX, ManifestBuilder, ManifestGenerator, ManifestManager, MetricsAdapter, NetworkError, ObjectRegistry, PLAYBOOK_PREFLIGHT_CAPABILITY, PLAYBOOK_PREFLIGHT_ROUTE_SEGMENT, POSTGRES_REVISION_GUARD_EXPRESSION, POSTGRES_TIMEOUT_ENV_VARS, PRIVATE_READ_CACHE_CONTROL, PubSubAdapter, QueryBoundsError, QueryOrderByError, RUN_ONCE_CLAIMS_TABLE, RunOnceClaimError, RuntimeError, SMRT_COLLECTION_BASE_NAMES, SMRT_CUSTOM_ACTION_ERROR_METADATA_KEY, SMRT_SCHEMA_VERSION, SYNC_APPLY_ROUTE_SEGMENTS, SYNC_APPLY_UUID_PATTERN, SYSTEM_DIAGNOSTICS_TABLES, SYSTEM_TABLE_NAMES, SchemaComparer, SignalBus, SignalSanitizer, SmrtClass, SmrtCollection, SmrtError, SmrtHierarchical, SmrtJunction, SmrtMCPServer, SmrtObject, SmrtPolymorphicAssociation, TenantIsolationError, ValidationError, ValidationReport, ValidationUtils, appendChange, appendChanges, applyOneToManyChildAccessors, applyPendingDecoratorRegistrations, applyPostgresPermissions, applyPostgresRuntimeTimeouts, applySyncWritablePolicy, assertPlainJson, assertPostgresSystemTimestampsCurrent, broadcastCacheInvalidation, buildCascadePlan, buildChangeEventStream, buildCustomActionInputSchema, buildCustomActionInvocationArgs, buildDefaultListOrderBy, buildDomainKnowledgeManifest, buildKnowledgeGraph, bumpChangeFeed, canonicalReadRepresentation, canonicalizeDataQuery, cascadeReferencesTo, changeEventSubscribersAtCapacity, checkKnowledgeGraphFreshness, checkLiveSchemaParity, childAccessorName, chunkArray, classifyDatabaseError, classifyDialectMessage, classifyMethodWireability, classifyParameterWireability, clearRetentionTasks, clone, coerceCustomActionArgument, collectForeignKeyOrphanCounts, computeBodyEtag, computeRuntimeWebManifestHash, computeTableVersionEtag, conditionalJsonResponse, config, convertTypeToJsonSchema, createClassNamePredicate, createDataQueryFingerprint, createDispatchBus, createFilesystemAdapter, createInterceptorContext, createMCPServer, createManifestClassNamePredicate, createQualifiedName, createRestServer, createSmrtClient, createSmrtServer, crossPackageRef, customActionParameterInputName, declareChangeFeedSensitiveTable, declaredTypeAcceptsDate, declaresRuntimeRestRoute, declaresRuntimeRestRouteShape, deriveRunOnceClaimKey, detectEngine, digestRunOnceContent, discoverKnowledgeArtifactPaths, discoverManifestEntry, discoverScopedPackageDirectories, drainChangeFeed, ensureBootstrapSystemTableCompatibility, ensureCacheInvalidationListener, ensureChangeFeedTable, ensureDeferredSystemTableCompatibility, ensureDispatchSubscriptionsSystemTableCompatibility, ensureDispatchSystemTableCompatibility, ensureJobEventsSystemTableCompatibility, ensureJobsSystemTableCompatibility, ensureLegacySystemTableCompatibility, ensureSystemTables, estimateAiUsageCost, eventStreamCapacityExceededResponse, executeCollectionReadPlan, executeDecision, executeToolCall, executeToolCalls, field, filterVisibleChangeFeedEntries, findManifestEntryByQualifiedName, foreignKey, formatToolResults, generateDDLForEngine, generateOpenAPISpec, generateSchemaDiff, generateToolFromMethod, generateToolManifest, getAdapterInfo, getAuthorizedChangesSince, getAuthorizedTenantScopedChangesSince, getCacheGeneration, getChangeFeedSensitiveTables, getChangesSince, getClassConfigResolvers, getClassName, getConfigResolver, getDatabaseEngine, getManifest, getPackageFromQualifiedName, getRetentionTasks, getSQLFromDiff, getSystemTableShapes, getTableVersion, getTenantScopedChangesSince, getTestDatabase, handlePlaybookPreflightRoute, hasActionableChanges, hasChangeFeedEntryVisibilityHook, hasChangeFeedTableAuthorizerHook, ifNoneMatchHasConcreteMatch, ifNoneMatchSatisfied, importOptionalDependency, invalidateCollectionCache, isAbortedTransactionError, isAdvisoryOnlyChange, isApiActionEnabledForObject, isChangeFeedDenyAll, isChangeFeedEntryVisible, isChangeFeedSensitiveTable, isCrudOperation, isCrudToolAction, isDatabaseInterface, isDeterministicDatabaseError, isEmbeddedDatabase, isFrameworkBaseClass, isFromPackage, isLazyConfigSentinel, isManualOrAdvisoryChange, isNotNullViolationError, isPostgresDatabase, isQualifiedName, isRestActionRoutable, isRestRoutePublic, isSmrtCollectionExtendsName, isStaleWrite, isTenantScopedClassResolved, isTransientDatabaseError, isType, isUniqueViolationError, isValid, listConfigResolvers, loadExternalManifest, loadExternalManifestSync, loadLocalTestManifestSync, loadManifestFromPathSync, manifest, manyToMany, meta, method, migratePostgresSystemTimestamps, normalizeCustomActionFailure, normalizeDataQueryRequest, normalizeDataQueryResult, normalizeDataQuerySchema, normalizeEventsMaxSubscribers, normalizeOnDelete, normalizeTypedHttpError, oneToMany, parse, parseQualifiedName, parseSyncApplyBatch, payloadMatchesRow, planForeignKeyCreation, planPostgresPermissions, planPostgresSystemTimestampMigrations, postgresRevisionCandidates, postgresRevisionCondition, processSyncApplyBatch, pruneAiUsage, pruneChangeFeed, pruneExpiredContexts, pruneRunOnceClaims, publishArtifactFiles, publishAtomicArtifact, qualifiedNamesEqual, queryStringDecoderFor, readAgentModuleDocs, readDispatchHealth, readJobHealth, readMethodDecoratorConfig, readMigrationStatus, readPackageAgentDoc, readRecentChanges, readRegistryDrift, readScheduleHealth, readSystemDiagnostics, registerChangeFeedWriter, registerCompatibleFieldDecorator, registerCompatibleMethodDecorator, registerConfigResolver, registerFilesystemAdapterFactory, registerOptionalDependency, registerRetentionTask, resetChangeFeedWarnings, resetChangeSignals, resetCollectionCache, resetConfigResolvers, resetVerifiedTables, resolveAgentModuleDocPaths, resolveApiMethodExposure, resolveAuthorizedChangeFeedTables, resolveCustomActionMetadata, resolveDatabase, resolveDbCacheKey, resolveDeclaredScopeMismatch, resolveDispatchTenantId, resolveDispatchTenantScope, resolveEffectiveActionMetadata, resolveExistingRunOnceClaim, resolveFileKnowledgeConfig, resolveGetStringFilter, resolveLazyConfig, resolveListLimit, resolveListOffset, resolveMCPToolListCacheHint, resolvePostgresTimeouts, resolveReadCacheControl, resolveRegisteredObjectName, resolveTenantEtagDiscriminator, restFieldReadPermissions, restMethodForApiAction, runCascadeDelete, runOnce, runRetentionSweep, runWithTenantGate, safeParse, safeStringify, sanitizeMessagePaths, setChangeFeedAuthorizer, setChangeFeedEntryVisibility, setDispatchTenantResolver, setTenantEntryPointRunner, setTenantScopedClassResolver, setupSwaggerUI, shouldIncludeMethod, signalVisibleToTenant, smrt, smrtPlugin, smrt as smrtRegistry, snapshotRegistry, sortMCPTools, stableStringify, startRestServer, staticManifest, stopCacheInvalidationListeners, stopChangeSignalListeners, stringify, subscribeToChangeSignals, tableExists, toCustomActionBoolean, toCustomActionDate, toCustomActionNumber, toSnakeCase, tryReserveChangeEventSubscriberSlot, unregisterChangeFeedWriter, unregisterConfigResolver, unregisterRetentionTask, usesEmbeddedRevisionFallback, validatePostgresPermissionContract, validateSyncApplyItem, validateToolCall, versionConditionalResponse, warnIfSharedCacheNeutralized, withEmbeddedWriteQueue, withEmbeddedWriteTransaction };
|
package/dist/knowledge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,8BAA8B,EAC9B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,GAC3B,CAAC;AAKF,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EAGrB,uBAAuB,EAMxB,MAAM,2BAA2B,CAAC;AAanC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"knowledge.d.ts","sourceRoot":"","sources":["../src/knowledge.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,EAC3B,MAAM,uCAAuC,CAAC;AAE/C,OAAO,EACL,oBAAoB,EACpB,qBAAqB,GACtB,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,uBAAuB,CAAC;AACnE,OAAO,EACL,gCAAgC,EAChC,mBAAmB,EACnB,KAAK,sBAAsB,GAC5B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EACL,mBAAmB,EACnB,4BAA4B,EAC5B,8BAA8B,EAC9B,KAAK,kBAAkB,EACvB,KAAK,sBAAsB,EAC3B,KAAK,4BAA4B,EACjC,KAAK,mBAAmB,EACxB,KAAK,wBAAwB,EAC7B,KAAK,yBAAyB,EAC9B,KAAK,kBAAkB,EACvB,eAAe,GAChB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EACL,yBAAyB,EACzB,sBAAsB,EACtB,mBAAmB,EACnB,0BAA0B,GAC3B,CAAC;AAKF,OAAO,KAAK,EACV,2BAA2B,EAC3B,qBAAqB,EAGrB,uBAAuB,EAMxB,MAAM,2BAA2B,CAAC;AAanC,OAAO,KAAK,EAEV,mBAAmB,EACpB,MAAM,oBAAoB,CAAC;AAI5B;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,eAAe,CAAC;IAC9B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,CAAC,EAAE,qBAAqB,CAAC;IAC/B;;;;;;;;;OASG;IACH,YAAY,CAAC,EAAE,2BAA2B,CAAC;CAC5C;AA0CD,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,2BAA2B,GACnC,uBAAuB,CA0FzB"}
|
package/dist/knowledge.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { toSnakeCase } from "./utils/naming.js";
|
|
2
|
+
import { readPreviousQualifiedNames } from "./utils/qualified-names.js";
|
|
2
3
|
import { publishArtifactFiles, publishAtomicArtifact } from "./consumer-plugin/artifact-publication.js";
|
|
3
4
|
import { CRUD_OPERATIONS, createManifestClassNamePredicate, isCrudOperation, isCrudToolAction, isFrameworkLifecycleMethod, resolveApiMethodExposure, resolveCustomActionMetadata, resolveEffectiveActionMetadata } from "./generators/custom-action.js";
|
|
4
5
|
import { isFrameworkBaseClass } from "./registry/framework-base-classes.js";
|
|
@@ -151,9 +152,11 @@ function buildKnowledgeObject(object, manifest) {
|
|
|
151
152
|
related: field.related,
|
|
152
153
|
columnType: field.columnType
|
|
153
154
|
}));
|
|
155
|
+
const previousQualifiedNames = readPreviousQualifiedNames(object.decoratorConfig).sort();
|
|
154
156
|
return {
|
|
155
157
|
name: object.className,
|
|
156
158
|
qualifiedName: object.qualifiedName,
|
|
159
|
+
...previousQualifiedNames.length > 0 ? { previousQualifiedNames } : {},
|
|
157
160
|
collection: object.collection,
|
|
158
161
|
tableName: object.schema?.tableName,
|
|
159
162
|
packageName: object.packageName,
|