@prisma-next/family-sql 0.15.0 → 0.16.0-dev.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/{control-adapter-BQgad8Zc.d.mts → control-adapter-CW7FdxeS.d.mts} +1 -2
  2. package/dist/control-adapter-CW7FdxeS.d.mts.map +1 -0
  3. package/dist/control-adapter.d.mts +1 -1
  4. package/dist/control.d.mts +127 -5
  5. package/dist/control.d.mts.map +1 -1
  6. package/dist/control.mjs +71 -33
  7. package/dist/control.mjs.map +1 -1
  8. package/dist/diff.d.mts +3 -4
  9. package/dist/diff.d.mts.map +1 -1
  10. package/dist/diff.mjs +1 -1
  11. package/dist/ir.d.mts +0 -1
  12. package/dist/ir.d.mts.map +1 -1
  13. package/dist/migration.d.mts +1 -2
  14. package/dist/migration.d.mts.map +1 -1
  15. package/dist/pack.d.mts.map +1 -1
  16. package/dist/psl-infer.d.mts +2 -2
  17. package/dist/psl-infer.d.mts.map +1 -1
  18. package/dist/psl-infer.mjs +3 -4
  19. package/dist/psl-infer.mjs.map +1 -1
  20. package/dist/runtime.d.mts +0 -1
  21. package/dist/runtime.d.mts.map +1 -1
  22. package/dist/runtime.mjs +1 -1
  23. package/dist/{schema-differ-DnoopSXm.d.mts → schema-differ-C8OHo1V5.d.mts} +1 -2
  24. package/dist/schema-differ-C8OHo1V5.d.mts.map +1 -0
  25. package/dist/{schema-verify-W3r631Jh.mjs → schema-verify-DY21bMwy.mjs} +8 -8
  26. package/dist/schema-verify-DY21bMwy.mjs.map +1 -0
  27. package/dist/{timestamp-now-generator-CloimujU.mjs → timestamp-now-generator-DRXygu32.mjs} +88 -2
  28. package/dist/timestamp-now-generator-DRXygu32.mjs.map +1 -0
  29. package/dist/{types-BPv_y7iS.d.mts → types-DhAmOoxA.d.mts} +13 -7
  30. package/dist/types-DhAmOoxA.d.mts.map +1 -0
  31. package/dist/verify.d.mts +0 -1
  32. package/dist/verify.d.mts.map +1 -1
  33. package/package.json +25 -23
  34. package/src/core/diff/schema-verify.ts +5 -5
  35. package/src/core/diff/verifier-disposition.ts +3 -3
  36. package/src/core/migrations/contract-to-schema-ir.ts +96 -29
  37. package/src/core/migrations/types.ts +20 -13
  38. package/src/core/psl-contract-infer/name-transforms.ts +3 -13
  39. package/src/core/psl-contract-infer/relation-inference.ts +4 -1
  40. package/src/core/timestamp-now-generator.ts +88 -0
  41. package/src/exports/control.ts +3 -0
  42. package/dist/control-adapter-BQgad8Zc.d.mts.map +0 -1
  43. package/dist/foreign-key-index-backing-BP71iI-Q.mjs +0 -32
  44. package/dist/foreign-key-index-backing-BP71iI-Q.mjs.map +0 -1
  45. package/dist/schema-differ-DnoopSXm.d.mts.map +0 -1
  46. package/dist/schema-verify-W3r631Jh.mjs.map +0 -1
  47. package/dist/timestamp-now-generator-CloimujU.mjs.map +0 -1
  48. package/dist/types-BPv_y7iS.d.mts.map +0 -1
  49. package/src/core/foreign-key-index-backing.ts +0 -37
package/dist/diff.d.mts CHANGED
@@ -1,12 +1,11 @@
1
- import { a as NativeTypeNormalizer, o as arraysEqual } from "./control-adapter-BQgad8Zc.mjs";
2
- import { n as CodecControlHooks } from "./types-BPv_y7iS.mjs";
3
- import { t as SqlSchemaDiffFn } from "./schema-differ-DnoopSXm.mjs";
1
+ import { a as NativeTypeNormalizer, o as arraysEqual } from "./control-adapter-CW7FdxeS.mjs";
2
+ import { n as CodecControlHooks } from "./types-DhAmOoxA.mjs";
3
+ import { t as SqlSchemaDiffFn } from "./schema-differ-C8OHo1V5.mjs";
4
4
  import { DiffSubjectGranularity, SchemaDiffIssue, VerifierIssueCategory, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
5
5
  import { Contract, ControlPolicy } from "@prisma-next/contract/types";
6
6
  import { SqlStorage } from "@prisma-next/sql-contract/types";
7
7
  import { SqlSchemaIRNode } from "@prisma-next/sql-schema-ir/types";
8
8
  import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
9
-
10
9
  //#region src/core/diff/schema-verify.d.ts
11
10
  /**
12
11
  * Resolves an issue's framework-neutral {@link DiffSubjectGranularity} on
@@ -1 +1 @@
1
- {"version":3,"file":"diff.d.mts","names":[],"sources":["../src/core/diff/schema-verify.ts"],"mappings":";;;;;;;;;;;;;;AA6DyB;AAsCzB;;;;;iBAzCgB,8BAAA,CACd,KAAA,EAAO,eAAA,EACP,aAAA,GAAgB,QAAA,aAAqB,sBAAA,GACpC,sBAAA;AAqFH;;;;;;;;;;;;AAAA,iBA/CgB,oBAAA,CACd,KAAA,EAAO,eAAA,EACP,aAAA,GAAgB,QAAA,aAAqB,sBAAA,GACpC,qBAAA;AAAA,UA4Cc,mBAAA;EAIiB;EAAA,SAFvB,MAAA,WAAiB,eAAA;EAGjB;EAAA,SADA,oBAAA,GAAuB,KAAA,EAAO,eAAA,KAAoB,aAAA;EAAA,SAClD,MAAA;EAAA,SACA,oBAAA,EAAsB,aAAA;EAEN;EAAA,SAAhB,aAAA,GAAgB,QAAA,aAAqB,sBAAA;AAAA;AAAA,UAG/B,cAAA;EAAA,SACN,QAAA,WAAmB,eAAA;EAAA,SACnB,QAAA,WAAmB,eAAe;AAAA;;;;;;;AAAA;iBAU7B,qBAAA,CAAsB,KAAA,EAAO,mBAAA,GAAsB,cAAc;AAAA,UA+BhE,uBAAA;EAAA,SACN,QAAA,EAAU,QAAA,CAAS,UAAA;EAhCmD;;;;;AAAA;EAAA,SAuCtE,cAAA,EAAgB,aAAA;IAAA,SACd,MAAA,EAAQ,eAAA;EAAA;EAAA,SAEV,UAAA,EAAY,WAAA,SAAoB,iBAAA;AAAA;;;;;;;;UAU1B,kBAAA;EAAA,SACN,QAAA,WAAmB,eAAA;EAAA,SACnB,QAAA,WAAmB,eAAe;AAAA;AAAA,iBAG7B,yBAAA,CAA0B,KAAA,EAAO,uBAAA,GAA0B,kBAAkB;AAAA,UA6B5E,0BAAA;EAAA,SACN,QAAA,EAAU,QAAA,CAAS,UAAA;EAAA,SACnB,MAAA,EAAQ,eAAA;EAAA,SACR,MAAA;EAAA,SACA,mBAAA,EAAqB,aAAA,CAAc,8BAAA;EAhDc;EAAA,SAkDjD,UAAA,EAAY,eAAA;EAxCY;EAAA,SA0CxB,aAAA,GAAgB,QAAA,aAAqB,sBAAA;AAAA;;;;;;AAxCH;AAG7C;iBA+CgB,qBAAA,CACd,KAAA,EAAO,0BAAA,GACN,0BAA0B"}
1
+ {"version":3,"file":"diff.d.mts","names":[],"sources":["../src/core/diff/schema-verify.ts"],"mappings":";;;;;;;;;;;;;;;;;;;iBA0DgB,+BACd,OAAO,iBACP,gBAAgB,qBAAqB,yBACpC;;;;;;;;;;;;;iBAsCa,qBACd,OAAO,iBACP,gBAAgB,qBAAqB,yBACpC;UA4Cc;;WAEN,iBAAiB;;WAEjB,uBAAuB,OAAO,oBAAoB;WAClD;WACA,sBAAsB;;WAEtB,gBAAgB,qBAAqB;;UAG/B;WACN,mBAAmB;WACnB,mBAAmB;;;;;;;;;iBAUd,sBAAsB,OAAO,sBAAsB;UA+BlD;WACN,UAAU,SAAS;;;;;;;WAOnB,gBAAgB;aACd,QAAQ;;WAEV,YAAY,oBAAoB;;;;;;;;;UAU1B;WACN,mBAAmB;WACnB,mBAAmB;;iBAGd,0BAA0B,OAAO,0BAA0B;UA6B1D;WACN,UAAU,SAAS;WACnB,QAAQ;WACR;WACA,qBAAqB,cAAc;;WAEnC,YAAY;;WAEZ,gBAAgB,qBAAqB;;;;;;;;;iBAUhC,sBACd,OAAO,6BACN"}
package/dist/diff.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { a as computeStorageTypeVerdict, i as computeSqlDiffVerdict, n as classifyDiffSubjectGranularity, o as verifySqlSchemaByDiff, r as classifySqlDiffIssue } from "./schema-verify-W3r631Jh.mjs";
1
+ import { a as computeStorageTypeVerdict, i as computeSqlDiffVerdict, n as classifyDiffSubjectGranularity, o as verifySqlSchemaByDiff, r as classifySqlDiffIssue } from "./schema-verify-DY21bMwy.mjs";
2
2
  //#region src/core/diff/sql-schema-diff.ts
3
3
  /**
4
4
  * Compares two arrays of strings for equality (order-sensitive).
package/dist/ir.d.mts CHANGED
@@ -3,7 +3,6 @@ import { AnyEntityKindDescriptor, Namespace } from "@prisma-next/framework-compo
3
3
  import { Contract } from "@prisma-next/contract/types";
4
4
  import { SqlNamespaceInput, SqlStorage, SqlStorageTypeEntry } from "@prisma-next/sql-contract/types";
5
5
  import { JsonObject } from "@prisma-next/utils/json";
6
-
7
6
  //#region src/core/ir/sql-contract-serializer-base.d.ts
8
7
  type SqlEntityHydrationFactory = (entry: unknown) => unknown;
9
8
  /**
package/dist/ir.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts","../src/core/ir/sql-schema-verifier-base.ts"],"mappings":";;;;;;;KAmCY,yBAAA,IAA6B,KAAc;;AAAvD;;;;AAAuD;AA0BvD;;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,mBAMT,uBAAA,EAAyB,WAAA,SAE1C,yBAAA;EAAA,iBANa,cAAA;EAAA,iBACA,UAAA;cAGI,uBAAA,GAAyB,WAAA,SAE1C,yBAAA,GAEF,eAAA,YAA0B,uBAAA;EAO5B,mBAAA,WAA8B,SAAA,GAAY,SAAA,EAAW,IAAA,YAAgB,CAAA;EAMrE,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAIxC,mBAAA,0CAAmB,sBAAA;EAEnB,WAAA,0CAAW,WAAA;EAAA,UAED,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EAAA,UAOnD,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EAAA,UAuC7D,sBAAA,CACR,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,MAAA,sBACnC,QAAA,CAAS,MAAA,SAAe,SAAA;EAAA,UAcjB,wBAAA,CACR,IAAA,UACA,GAAA,EAAK,MAAA,oBACJ,SAAA,GAAY,iBAAA;EAAA,UA+BL,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAAA,UAkBrD,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;EAAd;;;;;;;;;;EAAA,UAc3C,yBAAA,CACR,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA,uBACzC,MAAA,SAAe,MAAA,SAAe,UAAA;EAAA,QAazB,gBAAA;EAAA,UAQE,mBAAA,CAAoB,KAAA,YAAiB,UAAA;EAAA,QAOvC,kBAAA;AAAA;;;;;;;AAxNV;;;;AAAuD;AA0BvD;;;;;cC3Ca,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;;;;;;;;;;ADiB9E;;;;AAAuD;AA0BvD;;;;;;;;;uBElCsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EFiDlC;;;;;;EAAA,mBEpCX,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,eAAA;EFuDoC;;;;;EAAA,mBEhD7B,sBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,eAAA;AAAA"}
1
+ {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts","../src/core/ir/sql-schema-verifier-base.ts"],"mappings":";;;;;;KAmCY,6BAA6B;;;;;;;;;;;;;;;;;;;;;;;;;uBA0BnB,0BAA0B,kBAAkB,SAAS,wBAC9D,mBAAmB;qBAMT,yBAAyB,oBAE1C;mBANa;mBACA;cAGI,0BAAyB,oBAE1C,4BAEF,2BAA0B;EAO5B,oBAAoB,UAAU,YAAY,WAAW,gBAAgB;EAMrE,kBAAkB,UAAU,YAAY;EAIxC,6DAAmB;EAEnB,qDAAW;YAED,0BAA0B,gBAAgB,SAAS;YAOnD,kBAAkB,WAAW,SAAS,cAAc,SAAS;YAuC7D,uBACR,YAAY,SAAS,eAAe,4BACnC,SAAS,eAAe;YAcjB,yBACR,cACA,KAAK,0BACJ,YAAY;YA+BL,wBAAwB,OAAO,sBAAsB;YAkBrD,wBAAwB,UAAU,SAAS,cAAc;;;;;;;;;;;YAczD,0BACR,SAAS,SAAS,eAAe,SAAS,6BACzC,eAAe,eAAe;UAazB;YAQE,oBAAoB,iBAAiB;UAOvC;;;;;;;;;;;;;;;;;;cCzOG,8BAA8B,0BAA0B,SAAS;;;;;;;;;;;;;;;;;;;;;;;;;uBCSxD,sBAAsB,WAAW,oBAC1C,eAAe,WAAW;EAErC,aAAa,SAAS,oBAAoB,WAAW,WAAW;;;;;;;qBAa7C,sBACjB,SAAS,oBAAoB,WAAW,oBAC9B;;;;;;qBAOO,uBACjB,SAAS,oBAAoB,WAAW,oBAC9B"}
@@ -1,8 +1,7 @@
1
- import { f as SqlMigrationPlanOperation, w as SqlPlanTargetDetails } from "./types-BPv_y7iS.mjs";
1
+ import { f as SqlMigrationPlanOperation, w as SqlPlanTargetDetails } from "./types-DhAmOoxA.mjs";
2
2
  import { Contract } from "@prisma-next/contract/types";
3
3
  import { SqlStorage } from "@prisma-next/sql-contract/types";
4
4
  import { Migration } from "@prisma-next/migration-tools/migration";
5
-
6
5
  //#region src/core/sql-migration.d.ts
7
6
  /**
8
7
  * Family-owned base class for SQL migrations.
@@ -1 +1 @@
1
- {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/sql-migration.ts"],"mappings":";;;;;;;;AA4BA;;;;;;;;;;;;;;;;;;;uBAAsB,YAAA,kBACH,oBAAA,mDAEH,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA,eAClC,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA,WACpC,SAAA,CAAU,yBAAA,CAA0B,QAAA,UAAkB,SAAA,EAAW,KAAA,EAAO,GAAA;EAJhF;;;;;;;;;;EAAA,IAeI,kBAAA;AAAA"}
1
+ {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/sql-migration.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;uBA4BsB,aACpB,iBAAiB,sBACjB,mCACA,cAAc,SAAS,cAAc,SAAS,aAC9C,YAAY,SAAS,cAAc,SAAS,qBACpC,UAAU,0BAA0B,kBAAkB,WAAW,OAAO;;;;;;;;;;;MAW5E"}
@@ -1 +1 @@
1
- {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/exports/pack.ts"],"mappings":";cAKM,aAAA;EAAA"}
1
+ {"version":3,"file":"pack.d.mts","names":[],"sources":["../src/exports/pack.ts"],"mappings":";cAKM"}
@@ -1,6 +1,5 @@
1
1
  import { ColumnDefault } from "@prisma-next/contract/types";
2
2
  import { SqlForeignKeyIR, SqlTableIR } from "@prisma-next/sql-schema-ir/types";
3
-
4
3
  //#region src/core/psl-contract-infer/default-mapping.d.ts
5
4
  interface DefaultMappingOptions {
6
5
  readonly functionAttributes?: Readonly<Record<string, string>>;
@@ -83,7 +82,8 @@ type RelationField = {
83
82
  readonly fields?: readonly string[] | undefined;
84
83
  readonly references?: readonly string[] | undefined;
85
84
  readonly onDelete?: string | undefined;
86
- readonly onUpdate?: string | undefined; /** `false` when the FK's source columns have no live backing index; omitted (the default) otherwise. */
85
+ readonly onUpdate?: string | undefined;
86
+ /** `false` when the FK's source columns have no live backing index; omitted (the default) otherwise. */
87
87
  readonly index?: boolean | undefined;
88
88
  };
89
89
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"psl-infer.d.mts","names":[],"sources":["../src/core/psl-contract-infer/default-mapping.ts","../src/core/psl-contract-infer/name-transforms.ts","../src/core/psl-contract-infer/printer-config.ts","../src/core/psl-contract-infer/raw-default-parser.ts","../src/core/psl-contract-infer/relation-inference.ts"],"mappings":";;;;UAOiB,qBAAA;EAAA,SACN,kBAAA,GAAqB,QAAQ,CAAC,MAAA;EAAA,SAC9B,yBAAA,KAA8B,UAAA;AAAA;AAAA,KAG7B,oBAAA;EAAA,SAAkC,SAAA;AAAA;EAAA,SAAiC,OAAO;AAAA;AAAA,iBAEtE,UAAA,CACd,aAAA,EAAe,aAAA,EACf,OAAA,GAAU,qBAAA,GACT,oBAAA;;;KCbE,UAAA;EAAA,SACM,IAAA;EAAA,SACA,GAAG;AAAA;AAAA,iBA4DE,WAAA,CAAY,SAAA,WAAoB,UAAU;AAAA,iBAqB1C,WAAA,CAAY,UAAA,WAAqB,UAAU;AAAA,iBAqB3C,UAAA,CAAW,UAAA,WAAqB,UAAU;;;;;;;iBA6B1C,gBAAA,CAAiB,KAAa;AAAA,iBAO9B,SAAA,CAAU,IAAY;AAAA,iBAgBtB,uBAAA,CACd,SAAA,qBACA,mBAA2B;AAAA,iBAeb,2BAAA,CAA4B,cAAA,UAAwB,UAAmB;AAAA,iBAKvE,eAAA,CAAgB,UAAkB;;;KCnLtC,sBAAA;EAAA,SACD,IAAA;EAAA,SACA,IAAI;AAAA;AAAA,KAGH,iBAAA;EAAA,SAEG,OAAA;EAAA,SACA,UAAA;EAAA,SACA,UAAA,GAAa,MAAA;EAAA,SACb,mBAAA,GAAsB,sBAAsB;AAAA;EAAA,SAG5C,WAAA;EAAA,SACA,UAAA;AAAA;AAAA,UAGE,UAAA;EACf,OAAA,CAAQ,UAAA,UAAoB,WAAA,GAAc,MAAA,oBAA0B,iBAAiB;AAAA;AAAA,UAGtE,QAAA;EAAA,SACN,SAAA,EAAW,WAAA;EAAA,SACX,WAAA,EAAa,WAAW;AAAA;AAAA,UAGlB,iBAAA;EAAA,SACN,OAAA,EAAS,UAAA;EAAA,SACT,cAAA,GAAiB,qBAAA;EAAA,SACjB,QAAA,GAAW,QAAA;EAAA,SACX,eAAA,IAAmB,UAAA,UAAoB,UAAA,cAAwB,aAAA;AAAA;AAAA,KAG9D,aAAA;EAAA,SACD,SAAA;EAAA,SACA,QAAA;EFtBT;;;AACqB;;EADrB,SE4BS,eAAA;;;;;;WAMA,mBAAA;EAAA,SACA,mBAAA;EAAA,SACA,QAAA;EAAA,SACA,IAAA;EAAA,SACA,YAAA;EAAA,SACA,MAAA;EAAA,SACA,MAAA;EAAA,SACA,UAAA;EAAA,SACA,QAAA;EAAA,SACA,QAAA,uBD4BgD;EAAA,SC1BhD,KAAA;AAAA;;;iBCxBK,eAAA,CACd,UAAA,UACA,UAAA,YACC,aAAa;;;KCxBJ,iBAAA;EAAA,SACD,gBAAA,EAAkB,WAAW,kBAAkB,aAAA;AAAA;AAAA,iBAG1C,cAAA,CACd,MAAA,EAAQ,MAAA,SAAe,UAAA,GACvB,YAAA,EAAc,WAAA,mBACb,iBAAA;;;;;;;;;AJdwD;AAG3D;;;;AAAsF;AAEtF;;;;iBIgJgB,uBAAA,CACd,SAAA,UACA,eAAA,UACA,EAAA,EAAI,eAAA,EACJ,QAAA,WACA,YAAA,WACA,SAAA,GAAY,UAAA,GACX,aAAA"}
1
+ {"version":3,"file":"psl-infer.d.mts","names":[],"sources":["../src/core/psl-contract-infer/default-mapping.ts","../src/core/psl-contract-infer/name-transforms.ts","../src/core/psl-contract-infer/printer-config.ts","../src/core/psl-contract-infer/raw-default-parser.ts","../src/core/psl-contract-infer/relation-inference.ts"],"mappings":";;;UAOiB;WACN,qBAAqB,SAAS;WAC9B,8BAA8B;;KAG7B;WAAkC;;WAAiC;;iBAE/D,WACd,eAAe,eACf,UAAU,wBACT;;;KCXE;WACM;WACA;;iBA4DK,YAAY,oBAAoB;iBAqBhC,YAAY,qBAAqB;iBAqBjC,WAAW,qBAAqB;;;;;;;iBA6BhC,iBAAiB;iBAOjB,UAAU;iBAIV,wBACd,8BACA;iBAec,4BAA4B,wBAAwB;iBAKpD,gBAAgB;;;KCzKpB;WACD;WACA;;KAGC;WAEG;WACA;WACA,aAAa;WACb,sBAAsB;;WAGtB;WACA;;UAGE;EACf,QAAQ,oBAAoB,cAAc,0BAA0B;;UAGrD;WACN,WAAW;WACX,aAAa;;UAGP;WACN,SAAS;WACT,iBAAiB;WACjB,WAAW;WACX,mBAAmB,oBAAoB,wBAAwB;;KAG9D;WACD;WACA;;;;;;WAMA;;;;;;WAMA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;WAEA;;;;iBCxBK,gBACd,oBACA,sBACC;;;KCrBS;WACD,kBAAkB,6BAA6B;;iBAG1C,eACd,QAAQ,eAAe,aACvB,cAAc,8BACb;;;;;;;;;;;;;;;;;;;iBAuIa,wBACd,mBACA,yBACA,IAAI,iBACJ,mBACA,uBACA,YAAY,aACX"}
@@ -1,4 +1,5 @@
1
- import { n as isBackedByColumnKeys, t as backingIndexColumnKeys } from "./foreign-key-index-backing-BP71iI-Q.mjs";
1
+ import pluralizeLib from "pluralize";
2
+ import { backingIndexColumnKeys, isBackedByColumnKeys } from "@prisma-next/sql-contract/foreign-key-materialization";
2
3
  //#region src/core/psl-contract-infer/default-mapping.ts
3
4
  const DEFAULT_FUNCTION_ATTRIBUTES = {
4
5
  "autoincrement()": "@default(autoincrement())",
@@ -134,9 +135,7 @@ function toEnumMemberName(value) {
134
135
  return escapeIfNeeded(snakeToCamelCase(value));
135
136
  }
136
137
  function pluralize(word) {
137
- if (word.endsWith("s") || word.endsWith("x") || word.endsWith("z") || word.endsWith("ch") || word.endsWith("sh")) return `${word}es`;
138
- if (word.endsWith("y") && !/[aeiou]y$/i.test(word)) return `${word.slice(0, -1)}ies`;
139
- return `${word}s`;
138
+ return pluralizeLib.plural(word);
140
139
  }
141
140
  function deriveRelationFieldName(fkColumns, referencedTableName) {
142
141
  if (fkColumns.length === 1) {
@@ -1 +1 @@
1
- {"version":3,"file":"psl-infer.mjs","names":[],"sources":["../src/core/psl-contract-infer/default-mapping.ts","../src/core/psl-contract-infer/name-transforms.ts","../src/core/psl-contract-infer/raw-default-parser.ts","../src/core/psl-contract-infer/relation-inference.ts"],"sourcesContent":["import type { ColumnDefault } from '@prisma-next/contract/types';\n\nconst DEFAULT_FUNCTION_ATTRIBUTES: Readonly<Record<string, string>> = {\n 'autoincrement()': '@default(autoincrement())',\n 'now()': '@default(now())',\n};\n\nexport interface DefaultMappingOptions {\n readonly functionAttributes?: Readonly<Record<string, string>>;\n readonly fallbackFunctionAttribute?: ((expression: string) => string | undefined) | undefined;\n}\n\nexport type DefaultMappingResult = { readonly attribute: string } | { readonly comment: string };\n\nexport function mapDefault(\n columnDefault: ColumnDefault,\n options?: DefaultMappingOptions,\n): DefaultMappingResult {\n switch (columnDefault.kind) {\n case 'literal':\n return { attribute: `@default(${formatLiteralValue(columnDefault.value)})` };\n case 'function': {\n const attribute =\n options?.functionAttributes?.[columnDefault.expression] ??\n DEFAULT_FUNCTION_ATTRIBUTES[columnDefault.expression] ??\n options?.fallbackFunctionAttribute?.(columnDefault.expression);\n return attribute\n ? { attribute }\n : { comment: `// Raw default: ${columnDefault.expression.replace(/[\\r\\n]+/g, ' ')}` };\n }\n }\n}\n\nfunction formatLiteralValue(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n\n switch (typeof value) {\n case 'boolean':\n case 'number':\n return String(value);\n case 'string':\n return quoteString(value);\n default:\n return quoteString(JSON.stringify(value));\n }\n}\n\nfunction quoteString(str: string): string {\n return `\"${escapeString(str)}\"`;\n}\n\nfunction escapeString(str: string): string {\n return JSON.stringify(str).slice(1, -1);\n}\n","const PSL_RESERVED_WORDS = new Set(['model', 'enum', 'types', 'type', 'generator', 'datasource']);\n\nconst IDENTIFIER_PART_PATTERN = /[A-Za-z0-9]+/g;\n\ntype NameResult = {\n readonly name: string;\n readonly map?: string;\n};\n\nfunction hasSeparators(input: string): boolean {\n return /[^A-Za-z0-9]/.test(input);\n}\n\nfunction extractIdentifierParts(input: string): string[] {\n return input.match(IDENTIFIER_PART_PATTERN) ?? [];\n}\n\nfunction createSyntheticIdentifier(input: string): string {\n let hash = 2166136261;\n\n for (const char of input) {\n hash ^= char.codePointAt(0) ?? 0;\n hash = Math.imul(hash, 16777619);\n }\n\n return `x${(hash >>> 0).toString(16)}`;\n}\n\nfunction sanitizeIdentifierCharacters(input: string): string {\n const sanitized = input.replace(/[^\\w]/g, '');\n return sanitized.length > 0 ? sanitized : createSyntheticIdentifier(input);\n}\n\nfunction capitalize(word: string): string {\n return word.charAt(0).toUpperCase() + word.slice(1);\n}\n\nfunction snakeToPascalCase(input: string): string {\n const parts = extractIdentifierParts(input);\n if (parts.length === 0) {\n return capitalize(sanitizeIdentifierCharacters(input));\n }\n return parts.map(capitalize).join('');\n}\n\nfunction snakeToCamelCase(input: string): string {\n const parts = extractIdentifierParts(input);\n if (parts.length === 0) {\n return sanitizeIdentifierCharacters(input);\n }\n const [firstPart = input, ...rest] = parts;\n return firstPart.charAt(0).toLowerCase() + firstPart.slice(1) + rest.map(capitalize).join('');\n}\n\nfunction needsEscaping(name: string): boolean {\n return PSL_RESERVED_WORDS.has(name.toLowerCase()) || /^\\d/.test(name);\n}\n\nfunction escapeName(name: string): string {\n return `_${name}`;\n}\n\nfunction escapeIfNeeded(name: string): string {\n return needsEscaping(name) ? escapeName(name) : name;\n}\n\nexport function toModelName(tableName: string): NameResult {\n let name: string;\n\n if (hasSeparators(tableName)) {\n name = snakeToPascalCase(tableName);\n } else {\n name = tableName.charAt(0).toUpperCase() + tableName.slice(1);\n }\n\n if (needsEscaping(name)) {\n const escaped = escapeName(name);\n return { name: escaped, map: tableName };\n }\n\n if (name !== tableName) {\n return { name, map: tableName };\n }\n\n return { name };\n}\n\nexport function toFieldName(columnName: string): NameResult {\n let name: string;\n\n if (hasSeparators(columnName)) {\n name = snakeToCamelCase(columnName);\n } else {\n name = columnName.charAt(0).toLowerCase() + columnName.slice(1);\n }\n\n if (needsEscaping(name)) {\n const escaped = escapeName(name);\n return { name: escaped, map: columnName };\n }\n\n if (name !== columnName) {\n return { name, map: columnName };\n }\n\n return { name };\n}\n\nexport function toEnumName(pgTypeName: string): NameResult {\n let name: string;\n\n if (hasSeparators(pgTypeName)) {\n name = snakeToPascalCase(pgTypeName);\n } else {\n name = pgTypeName.charAt(0).toUpperCase() + pgTypeName.slice(1);\n }\n\n if (needsEscaping(name)) {\n const escaped = escapeName(name);\n return { name: escaped, map: pgTypeName };\n }\n\n if (name !== pgTypeName) {\n return { name, map: pgTypeName };\n }\n\n return { name };\n}\n\nconst VALID_IDENTIFIER_PATTERN = /^[A-Za-z_]\\w*$/;\n\n/**\n * PSL member name for a native-enum value. The value itself always prints\n * explicitly (`member = \"value\"`), so the returned name never needs a map:\n * a value that already is a valid, non-reserved identifier is kept verbatim\n * (case included); anything else is camelCased/escaped like a field name.\n */\nexport function toEnumMemberName(value: string): string {\n if (VALID_IDENTIFIER_PATTERN.test(value) && !needsEscaping(value)) {\n return value;\n }\n return escapeIfNeeded(snakeToCamelCase(value));\n}\n\nexport function pluralize(word: string): string {\n if (\n word.endsWith('s') ||\n word.endsWith('x') ||\n word.endsWith('z') ||\n word.endsWith('ch') ||\n word.endsWith('sh')\n ) {\n return `${word}es`;\n }\n if (word.endsWith('y') && !/[aeiou]y$/i.test(word)) {\n return `${word.slice(0, -1)}ies`;\n }\n return `${word}s`;\n}\n\nexport function deriveRelationFieldName(\n fkColumns: readonly string[],\n referencedTableName: string,\n): string {\n if (fkColumns.length === 1) {\n const [col = referencedTableName] = fkColumns;\n const stripped = col.replace(/_id$/i, '').replace(/Id$/, '');\n\n if (stripped.length > 0 && stripped !== col) {\n return escapeIfNeeded(snakeToCamelCase(stripped));\n }\n return escapeIfNeeded(snakeToCamelCase(referencedTableName));\n }\n\n return escapeIfNeeded(snakeToCamelCase(referencedTableName));\n}\n\nexport function deriveBackRelationFieldName(childModelName: string, isOneToOne: boolean): string {\n const base = childModelName.charAt(0).toLowerCase() + childModelName.slice(1);\n return isOneToOne ? base : pluralize(base);\n}\n\nexport function toNamedTypeName(columnName: string): string {\n let name: string;\n\n if (hasSeparators(columnName)) {\n name = snakeToPascalCase(columnName);\n } else {\n name = columnName.charAt(0).toUpperCase() + columnName.slice(1);\n }\n\n return escapeIfNeeded(name);\n}\n","import type { ColumnDefault } from '@prisma-next/contract/types';\n\nconst NEXTVAL_PATTERN = /^nextval\\s*\\(/i;\nconst NOW_FUNCTION_PATTERN = /^(now\\s*\\(\\s*\\)|CURRENT_TIMESTAMP)$/i;\nconst CLOCK_TIMESTAMP_PATTERN = /^clock_timestamp\\s*\\(\\s*\\)$/i;\nconst TIMESTAMP_CAST_SUFFIX = /::timestamp(?:tz|\\s+(?:with|without)\\s+time\\s+zone)?$/i;\nconst TEXT_CAST_SUFFIX = /::text$/i;\nconst NOW_LITERAL_PATTERN = /^'now'$/i;\nconst UUID_PATTERN = /^gen_random_uuid\\s*\\(\\s*\\)$/i;\nconst UUID_OSSP_PATTERN = /^uuid_generate_v4\\s*\\(\\s*\\)$/i;\nconst NULL_PATTERN = /^NULL(?:::.+)?$/i;\nconst TRUE_PATTERN = /^true$/i;\nconst FALSE_PATTERN = /^false$/i;\nconst NUMERIC_PATTERN = /^-?\\d+(\\.\\d+)?$/;\nconst JSON_CAST_SUFFIX = /::jsonb?$/i;\nconst STRING_LITERAL_PATTERN = /^'((?:[^']|'')*)'(?:::(?:\"[^\"]+\"|[\\w\\s]+)(?:\\(\\d+\\))?)?$/;\n\nfunction canonicalizeTimestampDefault(expr: string): string | undefined {\n if (NOW_FUNCTION_PATTERN.test(expr)) return 'now()';\n if (CLOCK_TIMESTAMP_PATTERN.test(expr)) return 'clock_timestamp()';\n\n if (!TIMESTAMP_CAST_SUFFIX.test(expr)) return undefined;\n\n let inner = expr.replace(TIMESTAMP_CAST_SUFFIX, '').trim();\n if (inner.startsWith('(') && inner.endsWith(')')) {\n inner = inner.slice(1, -1).trim();\n }\n\n if (NOW_FUNCTION_PATTERN.test(inner)) return 'now()';\n if (CLOCK_TIMESTAMP_PATTERN.test(inner)) return 'clock_timestamp()';\n\n inner = inner.replace(TEXT_CAST_SUFFIX, '').trim();\n if (NOW_LITERAL_PATTERN.test(inner)) return 'now()';\n\n return undefined;\n}\n\nexport function parseRawDefault(\n rawDefault: string,\n nativeType?: string,\n): ColumnDefault | undefined {\n const trimmed = rawDefault.trim();\n const normalizedType = nativeType?.toLowerCase();\n\n if (NEXTVAL_PATTERN.test(trimmed)) {\n return { kind: 'function', expression: 'autoincrement()' };\n }\n\n const canonicalTimestamp = canonicalizeTimestampDefault(trimmed);\n if (canonicalTimestamp) {\n return { kind: 'function', expression: canonicalTimestamp };\n }\n\n if (UUID_PATTERN.test(trimmed) || UUID_OSSP_PATTERN.test(trimmed)) {\n return { kind: 'function', expression: 'gen_random_uuid()' };\n }\n\n if (NULL_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: null };\n }\n\n if (TRUE_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: true };\n }\n\n if (FALSE_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: false };\n }\n\n if (NUMERIC_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: Number(trimmed) };\n }\n\n const stringMatch = trimmed.match(STRING_LITERAL_PATTERN);\n if (stringMatch?.[1] !== undefined) {\n const unescaped = stringMatch[1].replace(/''/g, \"'\");\n if (normalizedType === 'json' || normalizedType === 'jsonb') {\n if (JSON_CAST_SUFFIX.test(trimmed)) {\n return { kind: 'function', expression: trimmed };\n }\n try {\n return { kind: 'literal', value: JSON.parse(unescaped) };\n } catch {\n // Fall through to the string form for malformed/non-JSON values.\n }\n }\n return { kind: 'literal', value: unescaped };\n }\n\n return { kind: 'function', expression: trimmed };\n}\n","import type { SqlForeignKeyIR, SqlTableIR } from '@prisma-next/sql-schema-ir/types';\nimport { backingIndexColumnKeys, isBackedByColumnKeys } from '../foreign-key-index-backing';\nimport { deriveBackRelationFieldName, deriveRelationFieldName, pluralize } from './name-transforms';\nimport type { RelationField } from './printer-config';\n\nconst DEFAULT_ON_DELETE = 'noAction';\nconst DEFAULT_ON_UPDATE = 'noAction';\n\nconst REFERENTIAL_ACTION_PSL: Record<string, string> = {\n noAction: 'NoAction',\n restrict: 'Restrict',\n cascade: 'Cascade',\n setNull: 'SetNull',\n setDefault: 'SetDefault',\n};\n\nexport type InferredRelations = {\n readonly relationsByTable: ReadonlyMap<string, readonly RelationField[]>;\n};\n\nexport function inferRelations(\n tables: Record<string, SqlTableIR>,\n modelNameMap: ReadonlyMap<string, string>,\n): InferredRelations {\n const relationsByTable = new Map<string, RelationField[]>();\n\n const fkCountByPair = new Map<string, number>();\n for (const table of Object.values(tables)) {\n for (const fk of table.foreignKeys) {\n const pairKey = `${table.name}→${fk.referencedTable}`;\n fkCountByPair.set(pairKey, (fkCountByPair.get(pairKey) ?? 0) + 1);\n }\n }\n\n const usedFieldNames = new Map<string, Set<string>>();\n for (const table of Object.values(tables)) {\n const names = new Set<string>();\n for (const col of Object.values(table.columns)) {\n names.add(col.name);\n }\n usedFieldNames.set(table.name, names);\n }\n\n for (const table of Object.values(tables)) {\n for (const fk of table.foreignKeys) {\n const childTableName = table.name;\n const parentTableName = fk.referencedTable;\n const childUsed = usedFieldNames.get(childTableName) as Set<string>;\n const childModelName = modelNameMap.get(childTableName) ?? childTableName;\n const parentModelName = modelNameMap.get(parentTableName) ?? parentTableName;\n const pairKey = `${childTableName}→${parentTableName}`;\n const isSelfRelation = childTableName === parentTableName;\n const needsRelationName = (fkCountByPair.get(pairKey) as number) > 1 || isSelfRelation;\n\n const isOneToOne = detectOneToOne(fk, table);\n\n const childRelFieldName = resolveUniqueFieldName(\n deriveRelationFieldName(fk.columns, parentTableName),\n childUsed,\n parentModelName,\n );\n const relationName = needsRelationName\n ? deriveRelationName(fk, childRelFieldName, parentModelName, isSelfRelation)\n : undefined;\n const childOptional = fk.columns.some(\n (columnName) => table.columns[columnName]?.nullable ?? false,\n );\n\n const childRelField = buildChildRelationField(\n childRelFieldName,\n parentModelName,\n fk,\n childOptional,\n relationName,\n table,\n );\n\n addRelationField(relationsByTable, childTableName, childRelField);\n childUsed.add(childRelFieldName);\n\n const parentUsed = usedFieldNames.get(parentTableName) ?? new Set();\n usedFieldNames.set(parentTableName, parentUsed);\n\n const backRelFieldName = resolveUniqueFieldName(\n deriveBackRelationFieldName(childModelName, isOneToOne),\n parentUsed,\n childModelName,\n );\n\n const backRelField: RelationField = {\n fieldName: backRelFieldName,\n typeName: childModelName,\n optional: isOneToOne,\n list: !isOneToOne,\n relationName,\n };\n\n addRelationField(relationsByTable, parentTableName, backRelField);\n parentUsed.add(backRelFieldName);\n }\n }\n\n return { relationsByTable };\n}\n\nfunction detectOneToOne(fk: SqlForeignKeyIR, table: SqlTableIR): boolean {\n const fkCols = [...fk.columns].sort();\n\n if (table.primaryKey) {\n const pkCols = [...table.primaryKey.columns].sort();\n if (pkCols.length === fkCols.length && pkCols.every((c, i) => c === fkCols[i])) {\n return true;\n }\n }\n\n for (const unique of table.uniques) {\n const uniqueCols = [...unique.columns].sort();\n if (uniqueCols.length === fkCols.length && uniqueCols.every((c, i) => c === fkCols[i])) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction deriveRelationName(\n fk: SqlForeignKeyIR,\n childRelationFieldName: string,\n parentModelName: string,\n isSelfRelation: boolean,\n): string {\n if (fk.name) {\n return fk.name;\n }\n if (isSelfRelation) {\n return `${childRelationFieldName.charAt(0).toUpperCase() + childRelationFieldName.slice(1)}${pluralize(parentModelName)}`;\n }\n return fk.columns.join('_');\n}\n\n/**\n * Builds the child-side {@link RelationField} for a single foreign key:\n * `typeName` is the parent model name, `fields`/`references` are the FK's raw\n * columns, and `onDelete`/`onUpdate` are normalized to their PSL spelling.\n * Exported so a caller resolving a foreign key against a model outside\n * `tables` (e.g. a cross-space reference into another contract) can reuse the\n * same normalization instead of duplicating it.\n *\n * `hostTable` is the table the FK is declared on (i.e. `table`, not the\n * referenced parent) — its own indexes/uniques/primary key are what a\n * backing index for this FK would be. When none of them exactly match the\n * FK's source columns (in order), `index: false` is stamped so the emitted\n * `@relation` opts out of the framework's default derived backing-index\n * expectation, matching what `db verify` will find live. Passing the table\n * is optional so existing single-FK callers (e.g. cross-space resolution\n * before a host table reference is threaded through) can omit it and keep\n * the framework default.\n */\nexport function buildChildRelationField(\n fieldName: string,\n parentModelName: string,\n fk: SqlForeignKeyIR,\n optional: boolean,\n relationName?: string,\n hostTable?: SqlTableIR,\n): RelationField {\n const onDelete = fk.onDelete && fk.onDelete !== DEFAULT_ON_DELETE ? fk.onDelete : undefined;\n const onUpdate = fk.onUpdate && fk.onUpdate !== DEFAULT_ON_UPDATE ? fk.onUpdate : undefined;\n const index =\n hostTable && !isBackedByColumnKeys(fk.columns, backingIndexColumnKeys(hostTable))\n ? false\n : undefined;\n\n return {\n fieldName,\n typeName: parentModelName,\n referencedTableName: fk.referencedTable,\n optional,\n list: false,\n relationName,\n fkName: fk.name,\n fields: fk.columns,\n references: fk.referencedColumns,\n onDelete: onDelete ? REFERENTIAL_ACTION_PSL[onDelete] : undefined,\n onUpdate: onUpdate ? REFERENTIAL_ACTION_PSL[onUpdate] : undefined,\n index,\n };\n}\n\nfunction resolveUniqueFieldName(\n desired: string,\n usedNames: ReadonlySet<string>,\n fallbackSuffix: string,\n): string {\n if (!usedNames.has(desired)) {\n return desired;\n }\n\n const withSuffix = `${desired}${fallbackSuffix}`;\n if (!usedNames.has(withSuffix)) {\n return withSuffix;\n }\n\n let counter = 2;\n while (usedNames.has(`${desired}${counter}`)) {\n counter++;\n }\n return `${desired}${counter}`;\n}\n\nfunction addRelationField(\n map: Map<string, RelationField[]>,\n tableName: string,\n field: RelationField,\n): void {\n const existing = map.get(tableName);\n if (existing) {\n existing.push(field);\n } else {\n map.set(tableName, [field]);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"psl-infer.mjs","names":[],"sources":["../src/core/psl-contract-infer/default-mapping.ts","../src/core/psl-contract-infer/name-transforms.ts","../src/core/psl-contract-infer/raw-default-parser.ts","../src/core/psl-contract-infer/relation-inference.ts"],"sourcesContent":["import type { ColumnDefault } from '@prisma-next/contract/types';\n\nconst DEFAULT_FUNCTION_ATTRIBUTES: Readonly<Record<string, string>> = {\n 'autoincrement()': '@default(autoincrement())',\n 'now()': '@default(now())',\n};\n\nexport interface DefaultMappingOptions {\n readonly functionAttributes?: Readonly<Record<string, string>>;\n readonly fallbackFunctionAttribute?: ((expression: string) => string | undefined) | undefined;\n}\n\nexport type DefaultMappingResult = { readonly attribute: string } | { readonly comment: string };\n\nexport function mapDefault(\n columnDefault: ColumnDefault,\n options?: DefaultMappingOptions,\n): DefaultMappingResult {\n switch (columnDefault.kind) {\n case 'literal':\n return { attribute: `@default(${formatLiteralValue(columnDefault.value)})` };\n case 'function': {\n const attribute =\n options?.functionAttributes?.[columnDefault.expression] ??\n DEFAULT_FUNCTION_ATTRIBUTES[columnDefault.expression] ??\n options?.fallbackFunctionAttribute?.(columnDefault.expression);\n return attribute\n ? { attribute }\n : { comment: `// Raw default: ${columnDefault.expression.replace(/[\\r\\n]+/g, ' ')}` };\n }\n }\n}\n\nfunction formatLiteralValue(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n\n switch (typeof value) {\n case 'boolean':\n case 'number':\n return String(value);\n case 'string':\n return quoteString(value);\n default:\n return quoteString(JSON.stringify(value));\n }\n}\n\nfunction quoteString(str: string): string {\n return `\"${escapeString(str)}\"`;\n}\n\nfunction escapeString(str: string): string {\n return JSON.stringify(str).slice(1, -1);\n}\n","import pluralizeLib from 'pluralize';\n\nconst PSL_RESERVED_WORDS = new Set(['model', 'enum', 'types', 'type', 'generator', 'datasource']);\n\nconst IDENTIFIER_PART_PATTERN = /[A-Za-z0-9]+/g;\n\ntype NameResult = {\n readonly name: string;\n readonly map?: string;\n};\n\nfunction hasSeparators(input: string): boolean {\n return /[^A-Za-z0-9]/.test(input);\n}\n\nfunction extractIdentifierParts(input: string): string[] {\n return input.match(IDENTIFIER_PART_PATTERN) ?? [];\n}\n\nfunction createSyntheticIdentifier(input: string): string {\n let hash = 2166136261;\n\n for (const char of input) {\n hash ^= char.codePointAt(0) ?? 0;\n hash = Math.imul(hash, 16777619);\n }\n\n return `x${(hash >>> 0).toString(16)}`;\n}\n\nfunction sanitizeIdentifierCharacters(input: string): string {\n const sanitized = input.replace(/[^\\w]/g, '');\n return sanitized.length > 0 ? sanitized : createSyntheticIdentifier(input);\n}\n\nfunction capitalize(word: string): string {\n return word.charAt(0).toUpperCase() + word.slice(1);\n}\n\nfunction snakeToPascalCase(input: string): string {\n const parts = extractIdentifierParts(input);\n if (parts.length === 0) {\n return capitalize(sanitizeIdentifierCharacters(input));\n }\n return parts.map(capitalize).join('');\n}\n\nfunction snakeToCamelCase(input: string): string {\n const parts = extractIdentifierParts(input);\n if (parts.length === 0) {\n return sanitizeIdentifierCharacters(input);\n }\n const [firstPart = input, ...rest] = parts;\n return firstPart.charAt(0).toLowerCase() + firstPart.slice(1) + rest.map(capitalize).join('');\n}\n\nfunction needsEscaping(name: string): boolean {\n return PSL_RESERVED_WORDS.has(name.toLowerCase()) || /^\\d/.test(name);\n}\n\nfunction escapeName(name: string): string {\n return `_${name}`;\n}\n\nfunction escapeIfNeeded(name: string): string {\n return needsEscaping(name) ? escapeName(name) : name;\n}\n\nexport function toModelName(tableName: string): NameResult {\n let name: string;\n\n if (hasSeparators(tableName)) {\n name = snakeToPascalCase(tableName);\n } else {\n name = tableName.charAt(0).toUpperCase() + tableName.slice(1);\n }\n\n if (needsEscaping(name)) {\n const escaped = escapeName(name);\n return { name: escaped, map: tableName };\n }\n\n if (name !== tableName) {\n return { name, map: tableName };\n }\n\n return { name };\n}\n\nexport function toFieldName(columnName: string): NameResult {\n let name: string;\n\n if (hasSeparators(columnName)) {\n name = snakeToCamelCase(columnName);\n } else {\n name = columnName.charAt(0).toLowerCase() + columnName.slice(1);\n }\n\n if (needsEscaping(name)) {\n const escaped = escapeName(name);\n return { name: escaped, map: columnName };\n }\n\n if (name !== columnName) {\n return { name, map: columnName };\n }\n\n return { name };\n}\n\nexport function toEnumName(pgTypeName: string): NameResult {\n let name: string;\n\n if (hasSeparators(pgTypeName)) {\n name = snakeToPascalCase(pgTypeName);\n } else {\n name = pgTypeName.charAt(0).toUpperCase() + pgTypeName.slice(1);\n }\n\n if (needsEscaping(name)) {\n const escaped = escapeName(name);\n return { name: escaped, map: pgTypeName };\n }\n\n if (name !== pgTypeName) {\n return { name, map: pgTypeName };\n }\n\n return { name };\n}\n\nconst VALID_IDENTIFIER_PATTERN = /^[A-Za-z_]\\w*$/;\n\n/**\n * PSL member name for a native-enum value. The value itself always prints\n * explicitly (`member = \"value\"`), so the returned name never needs a map:\n * a value that already is a valid, non-reserved identifier is kept verbatim\n * (case included); anything else is camelCased/escaped like a field name.\n */\nexport function toEnumMemberName(value: string): string {\n if (VALID_IDENTIFIER_PATTERN.test(value) && !needsEscaping(value)) {\n return value;\n }\n return escapeIfNeeded(snakeToCamelCase(value));\n}\n\nexport function pluralize(word: string): string {\n return pluralizeLib.plural(word);\n}\n\nexport function deriveRelationFieldName(\n fkColumns: readonly string[],\n referencedTableName: string,\n): string {\n if (fkColumns.length === 1) {\n const [col = referencedTableName] = fkColumns;\n const stripped = col.replace(/_id$/i, '').replace(/Id$/, '');\n\n if (stripped.length > 0 && stripped !== col) {\n return escapeIfNeeded(snakeToCamelCase(stripped));\n }\n return escapeIfNeeded(snakeToCamelCase(referencedTableName));\n }\n\n return escapeIfNeeded(snakeToCamelCase(referencedTableName));\n}\n\nexport function deriveBackRelationFieldName(childModelName: string, isOneToOne: boolean): string {\n const base = childModelName.charAt(0).toLowerCase() + childModelName.slice(1);\n return isOneToOne ? base : pluralize(base);\n}\n\nexport function toNamedTypeName(columnName: string): string {\n let name: string;\n\n if (hasSeparators(columnName)) {\n name = snakeToPascalCase(columnName);\n } else {\n name = columnName.charAt(0).toUpperCase() + columnName.slice(1);\n }\n\n return escapeIfNeeded(name);\n}\n","import type { ColumnDefault } from '@prisma-next/contract/types';\n\nconst NEXTVAL_PATTERN = /^nextval\\s*\\(/i;\nconst NOW_FUNCTION_PATTERN = /^(now\\s*\\(\\s*\\)|CURRENT_TIMESTAMP)$/i;\nconst CLOCK_TIMESTAMP_PATTERN = /^clock_timestamp\\s*\\(\\s*\\)$/i;\nconst TIMESTAMP_CAST_SUFFIX = /::timestamp(?:tz|\\s+(?:with|without)\\s+time\\s+zone)?$/i;\nconst TEXT_CAST_SUFFIX = /::text$/i;\nconst NOW_LITERAL_PATTERN = /^'now'$/i;\nconst UUID_PATTERN = /^gen_random_uuid\\s*\\(\\s*\\)$/i;\nconst UUID_OSSP_PATTERN = /^uuid_generate_v4\\s*\\(\\s*\\)$/i;\nconst NULL_PATTERN = /^NULL(?:::.+)?$/i;\nconst TRUE_PATTERN = /^true$/i;\nconst FALSE_PATTERN = /^false$/i;\nconst NUMERIC_PATTERN = /^-?\\d+(\\.\\d+)?$/;\nconst JSON_CAST_SUFFIX = /::jsonb?$/i;\nconst STRING_LITERAL_PATTERN = /^'((?:[^']|'')*)'(?:::(?:\"[^\"]+\"|[\\w\\s]+)(?:\\(\\d+\\))?)?$/;\n\nfunction canonicalizeTimestampDefault(expr: string): string | undefined {\n if (NOW_FUNCTION_PATTERN.test(expr)) return 'now()';\n if (CLOCK_TIMESTAMP_PATTERN.test(expr)) return 'clock_timestamp()';\n\n if (!TIMESTAMP_CAST_SUFFIX.test(expr)) return undefined;\n\n let inner = expr.replace(TIMESTAMP_CAST_SUFFIX, '').trim();\n if (inner.startsWith('(') && inner.endsWith(')')) {\n inner = inner.slice(1, -1).trim();\n }\n\n if (NOW_FUNCTION_PATTERN.test(inner)) return 'now()';\n if (CLOCK_TIMESTAMP_PATTERN.test(inner)) return 'clock_timestamp()';\n\n inner = inner.replace(TEXT_CAST_SUFFIX, '').trim();\n if (NOW_LITERAL_PATTERN.test(inner)) return 'now()';\n\n return undefined;\n}\n\nexport function parseRawDefault(\n rawDefault: string,\n nativeType?: string,\n): ColumnDefault | undefined {\n const trimmed = rawDefault.trim();\n const normalizedType = nativeType?.toLowerCase();\n\n if (NEXTVAL_PATTERN.test(trimmed)) {\n return { kind: 'function', expression: 'autoincrement()' };\n }\n\n const canonicalTimestamp = canonicalizeTimestampDefault(trimmed);\n if (canonicalTimestamp) {\n return { kind: 'function', expression: canonicalTimestamp };\n }\n\n if (UUID_PATTERN.test(trimmed) || UUID_OSSP_PATTERN.test(trimmed)) {\n return { kind: 'function', expression: 'gen_random_uuid()' };\n }\n\n if (NULL_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: null };\n }\n\n if (TRUE_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: true };\n }\n\n if (FALSE_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: false };\n }\n\n if (NUMERIC_PATTERN.test(trimmed)) {\n return { kind: 'literal', value: Number(trimmed) };\n }\n\n const stringMatch = trimmed.match(STRING_LITERAL_PATTERN);\n if (stringMatch?.[1] !== undefined) {\n const unescaped = stringMatch[1].replace(/''/g, \"'\");\n if (normalizedType === 'json' || normalizedType === 'jsonb') {\n if (JSON_CAST_SUFFIX.test(trimmed)) {\n return { kind: 'function', expression: trimmed };\n }\n try {\n return { kind: 'literal', value: JSON.parse(unescaped) };\n } catch {\n // Fall through to the string form for malformed/non-JSON values.\n }\n }\n return { kind: 'literal', value: unescaped };\n }\n\n return { kind: 'function', expression: trimmed };\n}\n","import {\n backingIndexColumnKeys,\n isBackedByColumnKeys,\n} from '@prisma-next/sql-contract/foreign-key-materialization';\nimport type { SqlForeignKeyIR, SqlTableIR } from '@prisma-next/sql-schema-ir/types';\nimport { deriveBackRelationFieldName, deriveRelationFieldName, pluralize } from './name-transforms';\nimport type { RelationField } from './printer-config';\n\nconst DEFAULT_ON_DELETE = 'noAction';\nconst DEFAULT_ON_UPDATE = 'noAction';\n\nconst REFERENTIAL_ACTION_PSL: Record<string, string> = {\n noAction: 'NoAction',\n restrict: 'Restrict',\n cascade: 'Cascade',\n setNull: 'SetNull',\n setDefault: 'SetDefault',\n};\n\nexport type InferredRelations = {\n readonly relationsByTable: ReadonlyMap<string, readonly RelationField[]>;\n};\n\nexport function inferRelations(\n tables: Record<string, SqlTableIR>,\n modelNameMap: ReadonlyMap<string, string>,\n): InferredRelations {\n const relationsByTable = new Map<string, RelationField[]>();\n\n const fkCountByPair = new Map<string, number>();\n for (const table of Object.values(tables)) {\n for (const fk of table.foreignKeys) {\n const pairKey = `${table.name}→${fk.referencedTable}`;\n fkCountByPair.set(pairKey, (fkCountByPair.get(pairKey) ?? 0) + 1);\n }\n }\n\n const usedFieldNames = new Map<string, Set<string>>();\n for (const table of Object.values(tables)) {\n const names = new Set<string>();\n for (const col of Object.values(table.columns)) {\n names.add(col.name);\n }\n usedFieldNames.set(table.name, names);\n }\n\n for (const table of Object.values(tables)) {\n for (const fk of table.foreignKeys) {\n const childTableName = table.name;\n const parentTableName = fk.referencedTable;\n const childUsed = usedFieldNames.get(childTableName) as Set<string>;\n const childModelName = modelNameMap.get(childTableName) ?? childTableName;\n const parentModelName = modelNameMap.get(parentTableName) ?? parentTableName;\n const pairKey = `${childTableName}→${parentTableName}`;\n const isSelfRelation = childTableName === parentTableName;\n const needsRelationName = (fkCountByPair.get(pairKey) as number) > 1 || isSelfRelation;\n\n const isOneToOne = detectOneToOne(fk, table);\n\n const childRelFieldName = resolveUniqueFieldName(\n deriveRelationFieldName(fk.columns, parentTableName),\n childUsed,\n parentModelName,\n );\n const relationName = needsRelationName\n ? deriveRelationName(fk, childRelFieldName, parentModelName, isSelfRelation)\n : undefined;\n const childOptional = fk.columns.some(\n (columnName) => table.columns[columnName]?.nullable ?? false,\n );\n\n const childRelField = buildChildRelationField(\n childRelFieldName,\n parentModelName,\n fk,\n childOptional,\n relationName,\n table,\n );\n\n addRelationField(relationsByTable, childTableName, childRelField);\n childUsed.add(childRelFieldName);\n\n const parentUsed = usedFieldNames.get(parentTableName) ?? new Set();\n usedFieldNames.set(parentTableName, parentUsed);\n\n const backRelFieldName = resolveUniqueFieldName(\n deriveBackRelationFieldName(childModelName, isOneToOne),\n parentUsed,\n childModelName,\n );\n\n const backRelField: RelationField = {\n fieldName: backRelFieldName,\n typeName: childModelName,\n optional: isOneToOne,\n list: !isOneToOne,\n relationName,\n };\n\n addRelationField(relationsByTable, parentTableName, backRelField);\n parentUsed.add(backRelFieldName);\n }\n }\n\n return { relationsByTable };\n}\n\nfunction detectOneToOne(fk: SqlForeignKeyIR, table: SqlTableIR): boolean {\n const fkCols = [...fk.columns].sort();\n\n if (table.primaryKey) {\n const pkCols = [...table.primaryKey.columns].sort();\n if (pkCols.length === fkCols.length && pkCols.every((c, i) => c === fkCols[i])) {\n return true;\n }\n }\n\n for (const unique of table.uniques) {\n const uniqueCols = [...unique.columns].sort();\n if (uniqueCols.length === fkCols.length && uniqueCols.every((c, i) => c === fkCols[i])) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction deriveRelationName(\n fk: SqlForeignKeyIR,\n childRelationFieldName: string,\n parentModelName: string,\n isSelfRelation: boolean,\n): string {\n if (fk.name) {\n return fk.name;\n }\n if (isSelfRelation) {\n return `${childRelationFieldName.charAt(0).toUpperCase() + childRelationFieldName.slice(1)}${pluralize(parentModelName)}`;\n }\n return fk.columns.join('_');\n}\n\n/**\n * Builds the child-side {@link RelationField} for a single foreign key:\n * `typeName` is the parent model name, `fields`/`references` are the FK's raw\n * columns, and `onDelete`/`onUpdate` are normalized to their PSL spelling.\n * Exported so a caller resolving a foreign key against a model outside\n * `tables` (e.g. a cross-space reference into another contract) can reuse the\n * same normalization instead of duplicating it.\n *\n * `hostTable` is the table the FK is declared on (i.e. `table`, not the\n * referenced parent) — its own indexes/uniques/primary key are what a\n * backing index for this FK would be. When none of them exactly match the\n * FK's source columns (in order), `index: false` is stamped so the emitted\n * `@relation` opts out of the framework's default derived backing-index\n * expectation, matching what `db verify` will find live. Passing the table\n * is optional so existing single-FK callers (e.g. cross-space resolution\n * before a host table reference is threaded through) can omit it and keep\n * the framework default.\n */\nexport function buildChildRelationField(\n fieldName: string,\n parentModelName: string,\n fk: SqlForeignKeyIR,\n optional: boolean,\n relationName?: string,\n hostTable?: SqlTableIR,\n): RelationField {\n const onDelete = fk.onDelete && fk.onDelete !== DEFAULT_ON_DELETE ? fk.onDelete : undefined;\n const onUpdate = fk.onUpdate && fk.onUpdate !== DEFAULT_ON_UPDATE ? fk.onUpdate : undefined;\n const index =\n hostTable && !isBackedByColumnKeys(fk.columns, backingIndexColumnKeys(hostTable))\n ? false\n : undefined;\n\n return {\n fieldName,\n typeName: parentModelName,\n referencedTableName: fk.referencedTable,\n optional,\n list: false,\n relationName,\n fkName: fk.name,\n fields: fk.columns,\n references: fk.referencedColumns,\n onDelete: onDelete ? REFERENTIAL_ACTION_PSL[onDelete] : undefined,\n onUpdate: onUpdate ? REFERENTIAL_ACTION_PSL[onUpdate] : undefined,\n index,\n };\n}\n\nfunction resolveUniqueFieldName(\n desired: string,\n usedNames: ReadonlySet<string>,\n fallbackSuffix: string,\n): string {\n if (!usedNames.has(desired)) {\n return desired;\n }\n\n const withSuffix = `${desired}${fallbackSuffix}`;\n if (!usedNames.has(withSuffix)) {\n return withSuffix;\n }\n\n let counter = 2;\n while (usedNames.has(`${desired}${counter}`)) {\n counter++;\n }\n return `${desired}${counter}`;\n}\n\nfunction addRelationField(\n map: Map<string, RelationField[]>,\n tableName: string,\n field: RelationField,\n): void {\n const existing = map.get(tableName);\n if (existing) {\n existing.push(field);\n } else {\n map.set(tableName, [field]);\n }\n}\n"],"mappings":";;;AAEA,MAAM,8BAAgE;CACpE,mBAAmB;CACnB,SAAS;AACX;AASA,SAAgB,WACd,eACA,SACsB;CACtB,QAAQ,cAAc,MAAtB;EACE,KAAK,WACH,OAAO,EAAE,WAAW,YAAY,mBAAmB,cAAc,KAAK,EAAE,GAAG;EAC7E,KAAK,YAAY;GACf,MAAM,YACJ,SAAS,qBAAqB,cAAc,eAC5C,4BAA4B,cAAc,eAC1C,SAAS,4BAA4B,cAAc,UAAU;GAC/D,OAAO,YACH,EAAE,UAAU,IACZ,EAAE,SAAS,mBAAmB,cAAc,WAAW,QAAQ,YAAY,GAAG,IAAI;EACxF;CACF;AACF;AAEA,SAAS,mBAAmB,OAAwB;CAClD,IAAI,UAAU,MACZ,OAAO;CAGT,QAAQ,OAAO,OAAf;EACE,KAAK;EACL,KAAK,UACH,OAAO,OAAO,KAAK;EACrB,KAAK,UACH,OAAO,YAAY,KAAK;EAC1B,SACE,OAAO,YAAY,KAAK,UAAU,KAAK,CAAC;CAC5C;AACF;AAEA,SAAS,YAAY,KAAqB;CACxC,OAAO,IAAI,aAAa,GAAG,EAAE;AAC/B;AAEA,SAAS,aAAa,KAAqB;CACzC,OAAO,KAAK,UAAU,GAAG,CAAC,CAAC,MAAM,GAAG,EAAE;AACxC;;;ACrDA,MAAM,qCAAqB,IAAI,IAAI;CAAC;CAAS;CAAQ;CAAS;CAAQ;CAAa;AAAY,CAAC;AAEhG,MAAM,0BAA0B;AAOhC,SAAS,cAAc,OAAwB;CAC7C,OAAO,eAAe,KAAK,KAAK;AAClC;AAEA,SAAS,uBAAuB,OAAyB;CACvD,OAAO,MAAM,MAAM,uBAAuB,KAAK,CAAC;AAClD;AAEA,SAAS,0BAA0B,OAAuB;CACxD,IAAI,OAAO;CAEX,KAAK,MAAM,QAAQ,OAAO;EACxB,QAAQ,KAAK,YAAY,CAAC,KAAK;EAC/B,OAAO,KAAK,KAAK,MAAM,QAAQ;CACjC;CAEA,OAAO,KAAK,SAAS,EAAA,CAAG,SAAS,EAAE;AACrC;AAEA,SAAS,6BAA6B,OAAuB;CAC3D,MAAM,YAAY,MAAM,QAAQ,UAAU,EAAE;CAC5C,OAAO,UAAU,SAAS,IAAI,YAAY,0BAA0B,KAAK;AAC3E;AAEA,SAAS,WAAW,MAAsB;CACxC,OAAO,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC;AACpD;AAEA,SAAS,kBAAkB,OAAuB;CAChD,MAAM,QAAQ,uBAAuB,KAAK;CAC1C,IAAI,MAAM,WAAW,GACnB,OAAO,WAAW,6BAA6B,KAAK,CAAC;CAEvD,OAAO,MAAM,IAAI,UAAU,CAAC,CAAC,KAAK,EAAE;AACtC;AAEA,SAAS,iBAAiB,OAAuB;CAC/C,MAAM,QAAQ,uBAAuB,KAAK;CAC1C,IAAI,MAAM,WAAW,GACnB,OAAO,6BAA6B,KAAK;CAE3C,MAAM,CAAC,YAAY,OAAO,GAAG,QAAQ;CACrC,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,UAAU,MAAM,CAAC,IAAI,KAAK,IAAI,UAAU,CAAC,CAAC,KAAK,EAAE;AAC9F;AAEA,SAAS,cAAc,MAAuB;CAC5C,OAAO,mBAAmB,IAAI,KAAK,YAAY,CAAC,KAAK,MAAM,KAAK,IAAI;AACtE;AAEA,SAAS,WAAW,MAAsB;CACxC,OAAO,IAAI;AACb;AAEA,SAAS,eAAe,MAAsB;CAC5C,OAAO,cAAc,IAAI,IAAI,WAAW,IAAI,IAAI;AAClD;AAEA,SAAgB,YAAY,WAA+B;CACzD,IAAI;CAEJ,IAAI,cAAc,SAAS,GACzB,OAAO,kBAAkB,SAAS;MAElC,OAAO,UAAU,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,UAAU,MAAM,CAAC;CAG9D,IAAI,cAAc,IAAI,GAEpB,OAAO;EAAE,MADO,WAAW,IACN;EAAG,KAAK;CAAU;CAGzC,IAAI,SAAS,WACX,OAAO;EAAE;EAAM,KAAK;CAAU;CAGhC,OAAO,EAAE,KAAK;AAChB;AAEA,SAAgB,YAAY,YAAgC;CAC1D,IAAI;CAEJ,IAAI,cAAc,UAAU,GAC1B,OAAO,iBAAiB,UAAU;MAElC,OAAO,WAAW,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,WAAW,MAAM,CAAC;CAGhE,IAAI,cAAc,IAAI,GAEpB,OAAO;EAAE,MADO,WAAW,IACN;EAAG,KAAK;CAAW;CAG1C,IAAI,SAAS,YACX,OAAO;EAAE;EAAM,KAAK;CAAW;CAGjC,OAAO,EAAE,KAAK;AAChB;AAEA,SAAgB,WAAW,YAAgC;CACzD,IAAI;CAEJ,IAAI,cAAc,UAAU,GAC1B,OAAO,kBAAkB,UAAU;MAEnC,OAAO,WAAW,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,WAAW,MAAM,CAAC;CAGhE,IAAI,cAAc,IAAI,GAEpB,OAAO;EAAE,MADO,WAAW,IACN;EAAG,KAAK;CAAW;CAG1C,IAAI,SAAS,YACX,OAAO;EAAE;EAAM,KAAK;CAAW;CAGjC,OAAO,EAAE,KAAK;AAChB;AAEA,MAAM,2BAA2B;;;;;;;AAQjC,SAAgB,iBAAiB,OAAuB;CACtD,IAAI,yBAAyB,KAAK,KAAK,KAAK,CAAC,cAAc,KAAK,GAC9D,OAAO;CAET,OAAO,eAAe,iBAAiB,KAAK,CAAC;AAC/C;AAEA,SAAgB,UAAU,MAAsB;CAC9C,OAAO,aAAa,OAAO,IAAI;AACjC;AAEA,SAAgB,wBACd,WACA,qBACQ;CACR,IAAI,UAAU,WAAW,GAAG;EAC1B,MAAM,CAAC,MAAM,uBAAuB;EACpC,MAAM,WAAW,IAAI,QAAQ,SAAS,EAAE,CAAC,CAAC,QAAQ,OAAO,EAAE;EAE3D,IAAI,SAAS,SAAS,KAAK,aAAa,KACtC,OAAO,eAAe,iBAAiB,QAAQ,CAAC;EAElD,OAAO,eAAe,iBAAiB,mBAAmB,CAAC;CAC7D;CAEA,OAAO,eAAe,iBAAiB,mBAAmB,CAAC;AAC7D;AAEA,SAAgB,4BAA4B,gBAAwB,YAA6B;CAC/F,MAAM,OAAO,eAAe,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,eAAe,MAAM,CAAC;CAC5E,OAAO,aAAa,OAAO,UAAU,IAAI;AAC3C;AAEA,SAAgB,gBAAgB,YAA4B;CAC1D,IAAI;CAEJ,IAAI,cAAc,UAAU,GAC1B,OAAO,kBAAkB,UAAU;MAEnC,OAAO,WAAW,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,WAAW,MAAM,CAAC;CAGhE,OAAO,eAAe,IAAI;AAC5B;;;ACpLA,MAAM,kBAAkB;AACxB,MAAM,uBAAuB;AAC7B,MAAM,0BAA0B;AAChC,MAAM,wBAAwB;AAC9B,MAAM,mBAAmB;AACzB,MAAM,sBAAsB;AAC5B,MAAM,eAAe;AACrB,MAAM,oBAAoB;AAC1B,MAAM,eAAe;AACrB,MAAM,eAAe;AACrB,MAAM,gBAAgB;AACtB,MAAM,kBAAkB;AACxB,MAAM,mBAAmB;AACzB,MAAM,yBAAyB;AAE/B,SAAS,6BAA6B,MAAkC;CACtE,IAAI,qBAAqB,KAAK,IAAI,GAAG,OAAO;CAC5C,IAAI,wBAAwB,KAAK,IAAI,GAAG,OAAO;CAE/C,IAAI,CAAC,sBAAsB,KAAK,IAAI,GAAG,OAAO,KAAA;CAE9C,IAAI,QAAQ,KAAK,QAAQ,uBAAuB,EAAE,CAAC,CAAC,KAAK;CACzD,IAAI,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAC7C,QAAQ,MAAM,MAAM,GAAG,EAAE,CAAC,CAAC,KAAK;CAGlC,IAAI,qBAAqB,KAAK,KAAK,GAAG,OAAO;CAC7C,IAAI,wBAAwB,KAAK,KAAK,GAAG,OAAO;CAEhD,QAAQ,MAAM,QAAQ,kBAAkB,EAAE,CAAC,CAAC,KAAK;CACjD,IAAI,oBAAoB,KAAK,KAAK,GAAG,OAAO;AAG9C;AAEA,SAAgB,gBACd,YACA,YAC2B;CAC3B,MAAM,UAAU,WAAW,KAAK;CAChC,MAAM,iBAAiB,YAAY,YAAY;CAE/C,IAAI,gBAAgB,KAAK,OAAO,GAC9B,OAAO;EAAE,MAAM;EAAY,YAAY;CAAkB;CAG3D,MAAM,qBAAqB,6BAA6B,OAAO;CAC/D,IAAI,oBACF,OAAO;EAAE,MAAM;EAAY,YAAY;CAAmB;CAG5D,IAAI,aAAa,KAAK,OAAO,KAAK,kBAAkB,KAAK,OAAO,GAC9D,OAAO;EAAE,MAAM;EAAY,YAAY;CAAoB;CAG7D,IAAI,aAAa,KAAK,OAAO,GAC3B,OAAO;EAAE,MAAM;EAAW,OAAO;CAAK;CAGxC,IAAI,aAAa,KAAK,OAAO,GAC3B,OAAO;EAAE,MAAM;EAAW,OAAO;CAAK;CAGxC,IAAI,cAAc,KAAK,OAAO,GAC5B,OAAO;EAAE,MAAM;EAAW,OAAO;CAAM;CAGzC,IAAI,gBAAgB,KAAK,OAAO,GAC9B,OAAO;EAAE,MAAM;EAAW,OAAO,OAAO,OAAO;CAAE;CAGnD,MAAM,cAAc,QAAQ,MAAM,sBAAsB;CACxD,IAAI,cAAc,OAAO,KAAA,GAAW;EAClC,MAAM,YAAY,YAAY,EAAE,CAAC,QAAQ,OAAO,GAAG;EACnD,IAAI,mBAAmB,UAAU,mBAAmB,SAAS;GAC3D,IAAI,iBAAiB,KAAK,OAAO,GAC/B,OAAO;IAAE,MAAM;IAAY,YAAY;GAAQ;GAEjD,IAAI;IACF,OAAO;KAAE,MAAM;KAAW,OAAO,KAAK,MAAM,SAAS;IAAE;GACzD,QAAQ,CAER;EACF;EACA,OAAO;GAAE,MAAM;GAAW,OAAO;EAAU;CAC7C;CAEA,OAAO;EAAE,MAAM;EAAY,YAAY;CAAQ;AACjD;;;AClFA,MAAM,oBAAoB;AAC1B,MAAM,oBAAoB;AAE1B,MAAM,yBAAiD;CACrD,UAAU;CACV,UAAU;CACV,SAAS;CACT,SAAS;CACT,YAAY;AACd;AAMA,SAAgB,eACd,QACA,cACmB;CACnB,MAAM,mCAAmB,IAAI,IAA6B;CAE1D,MAAM,gCAAgB,IAAI,IAAoB;CAC9C,KAAK,MAAM,SAAS,OAAO,OAAO,MAAM,GACtC,KAAK,MAAM,MAAM,MAAM,aAAa;EAClC,MAAM,UAAU,GAAG,MAAM,KAAK,GAAG,GAAG;EACpC,cAAc,IAAI,UAAU,cAAc,IAAI,OAAO,KAAK,KAAK,CAAC;CAClE;CAGF,MAAM,iCAAiB,IAAI,IAAyB;CACpD,KAAK,MAAM,SAAS,OAAO,OAAO,MAAM,GAAG;EACzC,MAAM,wBAAQ,IAAI,IAAY;EAC9B,KAAK,MAAM,OAAO,OAAO,OAAO,MAAM,OAAO,GAC3C,MAAM,IAAI,IAAI,IAAI;EAEpB,eAAe,IAAI,MAAM,MAAM,KAAK;CACtC;CAEA,KAAK,MAAM,SAAS,OAAO,OAAO,MAAM,GACtC,KAAK,MAAM,MAAM,MAAM,aAAa;EAClC,MAAM,iBAAiB,MAAM;EAC7B,MAAM,kBAAkB,GAAG;EAC3B,MAAM,YAAY,eAAe,IAAI,cAAc;EACnD,MAAM,iBAAiB,aAAa,IAAI,cAAc,KAAK;EAC3D,MAAM,kBAAkB,aAAa,IAAI,eAAe,KAAK;EAC7D,MAAM,UAAU,GAAG,eAAe,GAAG;EACrC,MAAM,iBAAiB,mBAAmB;EAC1C,MAAM,oBAAqB,cAAc,IAAI,OAAO,IAAe,KAAK;EAExE,MAAM,aAAa,eAAe,IAAI,KAAK;EAE3C,MAAM,oBAAoB,uBACxB,wBAAwB,GAAG,SAAS,eAAe,GACnD,WACA,eACF;EACA,MAAM,eAAe,oBACjB,mBAAmB,IAAI,mBAAmB,iBAAiB,cAAc,IACzE,KAAA;EAcJ,iBAAiB,kBAAkB,gBATb,wBACpB,mBACA,iBACA,IAPoB,GAAG,QAAQ,MAC9B,eAAe,MAAM,QAAQ,WAAW,EAAE,YAAY,KAO3C,GACZ,cACA,KAG6D,CAAC;EAChE,UAAU,IAAI,iBAAiB;EAE/B,MAAM,aAAa,eAAe,IAAI,eAAe,qBAAK,IAAI,IAAI;EAClE,eAAe,IAAI,iBAAiB,UAAU;EAE9C,MAAM,mBAAmB,uBACvB,4BAA4B,gBAAgB,UAAU,GACtD,YACA,cACF;EAUA,iBAAiB,kBAAkB,iBAAiB;GAPlD,WAAW;GACX,UAAU;GACV,UAAU;GACV,MAAM,CAAC;GACP;EAG6D,CAAC;EAChE,WAAW,IAAI,gBAAgB;CACjC;CAGF,OAAO,EAAE,iBAAiB;AAC5B;AAEA,SAAS,eAAe,IAAqB,OAA4B;CACvE,MAAM,SAAS,CAAC,GAAG,GAAG,OAAO,CAAC,CAAC,KAAK;CAEpC,IAAI,MAAM,YAAY;EACpB,MAAM,SAAS,CAAC,GAAG,MAAM,WAAW,OAAO,CAAC,CAAC,KAAK;EAClD,IAAI,OAAO,WAAW,OAAO,UAAU,OAAO,OAAO,GAAG,MAAM,MAAM,OAAO,EAAE,GAC3E,OAAO;CAEX;CAEA,KAAK,MAAM,UAAU,MAAM,SAAS;EAClC,MAAM,aAAa,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC,KAAK;EAC5C,IAAI,WAAW,WAAW,OAAO,UAAU,WAAW,OAAO,GAAG,MAAM,MAAM,OAAO,EAAE,GACnF,OAAO;CAEX;CAEA,OAAO;AACT;AAEA,SAAS,mBACP,IACA,wBACA,iBACA,gBACQ;CACR,IAAI,GAAG,MACL,OAAO,GAAG;CAEZ,IAAI,gBACF,OAAO,GAAG,uBAAuB,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,uBAAuB,MAAM,CAAC,IAAI,UAAU,eAAe;CAExH,OAAO,GAAG,QAAQ,KAAK,GAAG;AAC5B;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,wBACd,WACA,iBACA,IACA,UACA,cACA,WACe;CACf,MAAM,WAAW,GAAG,YAAY,GAAG,aAAa,oBAAoB,GAAG,WAAW,KAAA;CAClF,MAAM,WAAW,GAAG,YAAY,GAAG,aAAa,oBAAoB,GAAG,WAAW,KAAA;CAClF,MAAM,QACJ,aAAa,CAAC,qBAAqB,GAAG,SAAS,uBAAuB,SAAS,CAAC,IAC5E,QACA,KAAA;CAEN,OAAO;EACL;EACA,UAAU;EACV,qBAAqB,GAAG;EACxB;EACA,MAAM;EACN;EACA,QAAQ,GAAG;EACX,QAAQ,GAAG;EACX,YAAY,GAAG;EACf,UAAU,WAAW,uBAAuB,YAAY,KAAA;EACxD,UAAU,WAAW,uBAAuB,YAAY,KAAA;EACxD;CACF;AACF;AAEA,SAAS,uBACP,SACA,WACA,gBACQ;CACR,IAAI,CAAC,UAAU,IAAI,OAAO,GACxB,OAAO;CAGT,MAAM,aAAa,GAAG,UAAU;CAChC,IAAI,CAAC,UAAU,IAAI,UAAU,GAC3B,OAAO;CAGT,IAAI,UAAU;CACd,OAAO,UAAU,IAAI,GAAG,UAAU,SAAS,GACzC;CAEF,OAAO,GAAG,UAAU;AACtB;AAEA,SAAS,iBACP,KACA,WACA,OACM;CACN,MAAM,WAAW,IAAI,IAAI,SAAS;CAClC,IAAI,UACF,SAAS,KAAK,KAAK;MAEnB,IAAI,IAAI,WAAW,CAAC,KAAK,CAAC;AAE9B"}
@@ -2,7 +2,6 @@ import { ResolvedDomainModel, UNBOUND_DOMAIN_NAMESPACE_ID, resolveDomainModel }
2
2
  import { ResolvedStorageTable, resolveStorageTable } from "@prisma-next/sql-contract/resolve-storage-table";
3
3
  import { RuntimeFamilyDescriptor, RuntimeFamilyInstance } from "@prisma-next/framework-components/execution";
4
4
  import { RuntimeMutationDefaultGenerator } from "@prisma-next/sql-runtime";
5
-
6
5
  //#region src/core/runtime-instance.d.ts
7
6
  /**
8
7
  * SQL execution-plane family instance interface.
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/core/runtime-instance.ts","../src/core/runtime-descriptor.ts","../src/core/timestamp-now-runtime-generator.ts"],"mappings":";;;;;;;;;;;AAUA;;;UAAiB,wBAAA,SAAiC,qBAAqB;;;;;;;AAAvE;;;;cCCa,0BAAA,EAA4B,uBAAuB,QAAQ,wBAAA;;;;;;;;ADDxE;;;;AAAuE;;;;ACCvE;iBCMgB,4BAAA,IAAgC,+BAA+B"}
1
+ {"version":3,"file":"runtime.d.mts","names":[],"sources":["../src/core/runtime-instance.ts","../src/core/runtime-descriptor.ts","../src/core/timestamp-now-runtime-generator.ts"],"mappings":";;;;;;;;;;;;;UAUiB,iCAAiC;;;;;;;;;;;cCCrC,4BAA4B,+BAA+B;;;;;;;;;;;;;;;;;iBCMxD,gCAAgC"}
package/dist/runtime.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { t as TIMESTAMP_NOW_GENERATOR_ID } from "./timestamp-now-generator-CloimujU.mjs";
1
+ import { t as TIMESTAMP_NOW_GENERATOR_ID } from "./timestamp-now-generator-DRXygu32.mjs";
2
2
  import { UNBOUND_DOMAIN_NAMESPACE_ID, resolveDomainModel } from "@prisma-next/contract/types";
3
3
  import { resolveStorageTable } from "@prisma-next/sql-contract/resolve-storage-table";
4
4
  //#region src/core/runtime-instance.ts
@@ -3,7 +3,6 @@ import { Contract, ControlPolicy } from "@prisma-next/contract/types";
3
3
  import { SqlStorage } from "@prisma-next/sql-contract/types";
4
4
  import { SqlSchemaIRNode } from "@prisma-next/sql-schema-ir/types";
5
5
  import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
6
-
7
6
  //#region src/core/migrations/schema-differ.d.ts
8
7
  /**
9
8
  * The full-tree node diff a SQL target produces for the family verify
@@ -42,4 +41,4 @@ interface SqlSchemaDiffInput {
42
41
  type SqlSchemaDiffFn = (input: SqlSchemaDiffInput) => SqlSchemaDiffResult;
43
42
  //#endregion
44
43
  export { SqlSchemaDiffInput as n, SqlSchemaDiffResult as r, SqlSchemaDiffFn as t };
45
- //# sourceMappingURL=schema-differ-DnoopSXm.d.mts.map
44
+ //# sourceMappingURL=schema-differ-C8OHo1V5.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-differ-C8OHo1V5.d.mts","names":[],"sources":["../src/core/migrations/schema-differ.ts"],"mappings":";;;;;;;;;;;;;;UAciB;;WAEN,iBAAiB;;;;;;;;;WASjB,uBAAuB,OAAO,oBAAoB;;;;;;WAMlD,gBAAgB;aAAyB,QAAQ;;;UAG3C;WACN,UAAU,SAAS;WACnB,QAAQ;WACR,qBAAqB,cAAc;;KAGlC,mBAAmB,OAAO,uBAAuB"}
@@ -1,5 +1,5 @@
1
1
  import { blindCast } from "@prisma-next/utils/casts";
2
- import { assertUniqueCodecOwner, dispositionForCategory } from "@prisma-next/framework-components/control";
2
+ import { assertUniqueCodecOwner, dispositionForCategory, issueOutcome } from "@prisma-next/framework-components/control";
3
3
  import { ifDefined } from "@prisma-next/utils/defined";
4
4
  import { effectiveControlPolicy } from "@prisma-next/contract/types";
5
5
  import { isStorageTypeInstance } from "@prisma-next/sql-contract/types";
@@ -40,8 +40,8 @@ function extractCodecControlHooks(descriptors) {
40
40
  * to its value set, so a paired mismatch always classifies as `valueDrift`.
41
41
  */
42
42
  function classifyStorageTypeDiffIssue(issue) {
43
- if (issue.reason === "not-found") return "declaredMissing";
44
- if (issue.reason === "not-expected") return "extraAuxiliary";
43
+ if (issueOutcome(issue) === "not-found") return "declaredMissing";
44
+ if (issueOutcome(issue) === "not-expected") return "extraAuxiliary";
45
45
  return "valueDrift";
46
46
  }
47
47
  function verifierDisposition(controlPolicy, issue) {
@@ -94,8 +94,8 @@ function classifyDiffEntityKind(issue, entityKindOf) {
94
94
  * kinds classify without the family importing them.
95
95
  */
96
96
  function classifySqlDiffIssue(issue, granularityOf) {
97
- if (issue.reason === "not-found") return "declaredMissing";
98
- if (issue.reason === "not-expected") {
97
+ if (issueOutcome(issue) === "not-found") return "declaredMissing";
98
+ if (issueOutcome(issue) === "not-expected") {
99
99
  const granularity = classifyDiffSubjectGranularity(issue, granularityOf);
100
100
  if (granularity === "entity" || granularity === "namespace") return "extraTopLevelObject";
101
101
  if (granularity === "field") return "extraNestedElement";
@@ -126,7 +126,7 @@ function computeSqlDiffVerdict(input) {
126
126
  const failures = [];
127
127
  const warnings = [];
128
128
  for (const issue of input.issues) {
129
- if (!input.strict && issue.reason === "not-expected" && isStrictOnlyExtra(issue, input.granularityOf)) continue;
129
+ if (!input.strict && issueOutcome(issue) === "not-expected" && isStrictOnlyExtra(issue, input.granularityOf)) continue;
130
130
  const disposition = dispositionForCategory(effectiveControlPolicy(input.resolveControlPolicy(issue), input.defaultControlPolicy), classifySqlDiffIssue(issue, input.granularityOf));
131
131
  if (disposition === "suppress") continue;
132
132
  if (disposition === "warn") {
@@ -202,7 +202,7 @@ function verifySqlSchemaByDiff(input) {
202
202
  const profileHash = "profileHash" in input.contract && typeof input.contract.profileHash === "string" ? input.contract.profileHash : void 0;
203
203
  return {
204
204
  ok,
205
- ...ok ? {} : { code: "PN-SCHEMA-0001" },
205
+ ...ok ? {} : { code: "CONTRACT.SCHEMA_VERIFICATION_FAILED" },
206
206
  summary: ok ? "Database schema satisfies contract" : `Database schema does not satisfy contract (${failCount} failure${failCount === 1 ? "" : "s"})`,
207
207
  contract: {
208
208
  storageHash: input.contract.storage.storageHash,
@@ -223,4 +223,4 @@ function verifySqlSchemaByDiff(input) {
223
223
  //#endregion
224
224
  export { computeStorageTypeVerdict as a, computeSqlDiffVerdict as i, classifyDiffSubjectGranularity as n, verifySqlSchemaByDiff as o, classifySqlDiffIssue as r, extractCodecControlHooks as s, classifyDiffEntityKind as t };
225
225
 
226
- //# sourceMappingURL=schema-verify-W3r631Jh.mjs.map
226
+ //# sourceMappingURL=schema-verify-DY21bMwy.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-verify-DY21bMwy.mjs","names":["d"],"sources":["../src/core/assembly.ts","../src/core/diff/verifier-disposition.ts","../src/core/diff/schema-verify.ts"],"sourcesContent":["import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport { assertUniqueCodecOwner } from '@prisma-next/framework-components/control';\nimport type { CodecControlHooks } from './migrations/types';\n\ntype CodecControlHooksMap = Record<string, CodecControlHooks>;\n\nfunction hasCodecControlHooks(descriptor: unknown): descriptor is {\n readonly id: string;\n readonly types: {\n readonly codecTypes: {\n readonly controlPlaneHooks: CodecControlHooksMap;\n };\n };\n} {\n if (typeof descriptor !== 'object' || descriptor === null) {\n return false;\n }\n const d = descriptor as { types?: { codecTypes?: { controlPlaneHooks?: unknown } } };\n const hooks = d.types?.codecTypes?.controlPlaneHooks;\n return hooks !== null && hooks !== undefined && typeof hooks === 'object';\n}\n\nexport function extractCodecControlHooks(\n descriptors: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>,\n): Map<string, CodecControlHooks> {\n const hooks = new Map<string, CodecControlHooks>();\n const owners = new Map<string, string>();\n\n for (const descriptor of descriptors) {\n if (typeof descriptor !== 'object' || descriptor === null) {\n continue;\n }\n if (!hasCodecControlHooks(descriptor)) {\n continue;\n }\n const controlPlaneHooks = descriptor.types.codecTypes.controlPlaneHooks;\n for (const [codecId, hook] of Object.entries(controlPlaneHooks)) {\n assertUniqueCodecOwner({\n codecId,\n owners,\n descriptorId: descriptor.id,\n entityLabel: 'control hooks',\n entityOwnershipLabel: 'owner',\n });\n hooks.set(codecId, hook);\n owners.set(codecId, descriptor.id);\n }\n }\n\n return hooks;\n}\n","import type { ControlPolicy } from '@prisma-next/contract/types';\nimport type {\n SchemaDiffIssue,\n VerifierIssueCategory,\n VerifierOutcome,\n} from '@prisma-next/framework-components/control';\nimport { dispositionForCategory, issueOutcome } from '@prisma-next/framework-components/control';\n\n/**\n * Classifies a codec `verifyType` hook finding into the target-neutral\n * categories the framework grades. A storage type is a named type instance\n * (e.g. a native enum); the only shape divergence it can carry is a change\n * to its value set, so a paired mismatch always classifies as `valueDrift`.\n */\nexport function classifyStorageTypeDiffIssue(issue: SchemaDiffIssue): VerifierIssueCategory {\n if (issueOutcome(issue) === 'not-found') {\n return 'declaredMissing';\n }\n if (issueOutcome(issue) === 'not-expected') {\n return 'extraAuxiliary';\n }\n return 'valueDrift';\n}\n\nexport function verifierDisposition(\n controlPolicy: ControlPolicy,\n issue: SchemaDiffIssue,\n): VerifierOutcome {\n return dispositionForCategory(controlPolicy, classifyStorageTypeDiffIssue(issue));\n}\n","/**\n * The differ-based SQL schema verify: post-diff filters and verdict.\n *\n * The generic node differ (`diffSchemas`) reports every node-level\n * difference between the derived expected tree and the introspected actual\n * tree. This module is the consumer side the spec assigns to the SQL\n * family: strict-mode extras gating and control-policy disposition are\n * reason/kind-keyed filters applied AFTER the diff — never inside it — and\n * the verify verdict derives from the filtered issue list.\n *\n * `verifySqlSchemaByDiff` wraps the verdict in the issue-based result\n * envelope — this is THE SQL schema verify (the legacy relational walk and\n * its verification tree are retired).\n */\n\nimport type { Contract, ControlPolicy } from '@prisma-next/contract/types';\nimport { effectiveControlPolicy } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n DiffSubjectGranularity,\n SchemaDiffIssue,\n VerifierIssueCategory,\n VerifierOutcome,\n VerifyDatabaseSchemaResult,\n} from '@prisma-next/framework-components/control';\nimport { dispositionForCategory, issueOutcome } from '@prisma-next/framework-components/control';\nimport { isStorageTypeInstance, type SqlStorage } from '@prisma-next/sql-contract/types';\nimport { RelationalSchemaNodeKind, type SqlSchemaIRNode } from '@prisma-next/sql-schema-ir/types';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { extractCodecControlHooks } from '../assembly';\nimport type { SqlSchemaDiffFn } from '../migrations/schema-differ';\nimport type { CodecControlHooks } from '../migrations/types';\nimport { verifierDisposition } from './verifier-disposition';\n\n// ============================================================================\n// Subject-granularity classification — nodeKind → framework-neutral granularity\n// ============================================================================\n\nfunction issueNode(issue: SchemaDiffIssue): SqlSchemaIRNode | undefined {\n const node = issue.expected ?? issue.actual;\n if (node === undefined) return undefined;\n return blindCast<\n SqlSchemaIRNode,\n 'every node in a SQL schema diff tree is a SqlSchemaIRNode; nodeKind is its identity'\n >(node);\n}\n\n/**\n * Resolves an issue's framework-neutral {@link DiffSubjectGranularity} on\n * demand, from the issue's node's `nodeKind` via the target-provided\n * `granularityOf` map. The node carries only its `nodeKind` identity, never a\n * classification, and nothing is stamped onto the issue — every consumer\n * (the family verdict below, the framework aggregate's unclaimed-elements\n * sweep via {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable})\n * calls this the same way, resolved by the family/target that owns the node\n * vocabulary. `undefined` for an issue with no node.\n */\nexport function classifyDiffSubjectGranularity(\n issue: SchemaDiffIssue,\n granularityOf: (nodeKind: string) => DiffSubjectGranularity,\n): DiffSubjectGranularity | undefined {\n const node = issueNode(issue);\n return node === undefined ? undefined : granularityOf(node.nodeKind);\n}\n\n/**\n * Resolves an issue's storage `entityKind` on demand, from the issue's\n * node's `nodeKind` via the target-provided `entityKindOf` map — the sibling\n * of {@link classifyDiffSubjectGranularity}, called the same way by the same\n * consumers (via\n * {@link import('@prisma-next/framework-components/control').SchemaSubjectClassifierCapable}).\n * `undefined` for an issue with no node, or for a node kind with no storage\n * entity of its own.\n */\nexport function classifyDiffEntityKind(\n issue: SchemaDiffIssue,\n entityKindOf: (nodeKind: string) => string | undefined,\n): string | undefined {\n const node = issueNode(issue);\n return node === undefined ? undefined : entityKindOf(node.nodeKind);\n}\n\n// ============================================================================\n// Issue classification — subject granularity + reason → target-neutral category\n// ============================================================================\n\n/**\n * Re-keys the legacy `classifySqlVerifierIssueKind` category mapping on the\n * issue's {@link DiffSubjectGranularity} (resolved via `granularityOf`) + the\n * issue reason. The vocabulary maps one-to-one: an undeclared live entity or\n * namespace is `extraTopLevelObject`, an undeclared live field\n * `extraNestedElement`, undeclared auxiliaries (constraints, indexes,\n * defaults) and structural leaves (policies) `extraAuxiliary`; a value-set\n * drift on a check node is `valueDrift`; every other paired divergence is\n * `declaredIncompatible`; anything the database lacks is `declaredMissing`.\n * `granularityOf` is the target's classifier, so target and extension node\n * kinds classify without the family importing them.\n */\nexport function classifySqlDiffIssue(\n issue: SchemaDiffIssue,\n granularityOf: (nodeKind: string) => DiffSubjectGranularity,\n): VerifierIssueCategory {\n if (issueOutcome(issue) === 'not-found') {\n return 'declaredMissing';\n }\n if (issueOutcome(issue) === 'not-expected') {\n const granularity = classifyDiffSubjectGranularity(issue, granularityOf);\n if (granularity === 'entity' || granularity === 'namespace') {\n return 'extraTopLevelObject';\n }\n if (granularity === 'field') {\n return 'extraNestedElement';\n }\n return 'extraAuxiliary';\n }\n if (issueNode(issue)?.nodeKind === RelationalSchemaNodeKind.check) {\n return 'valueDrift';\n }\n return 'declaredIncompatible';\n}\n\n/**\n * Whether a `not-expected` issue is a strict-mode-only finding. The legacy\n * walk detected every relational extra (namespaces, entities, fields, and\n * their auxiliaries) only under `--strict`; the structural diff (roots, RLS\n * policies, roles) was never strict-gated — its extras fail in both modes.\n * Keyed on the issue's granularity, resolved via `granularityOf`.\n */\nfunction isStrictOnlyExtra(\n issue: SchemaDiffIssue,\n granularityOf: (nodeKind: string) => DiffSubjectGranularity,\n): boolean {\n const granularity = classifyDiffSubjectGranularity(issue, granularityOf);\n return (\n granularity === 'namespace' ||\n granularity === 'entity' ||\n granularity === 'field' ||\n granularity === 'auxiliary'\n );\n}\n\n// ============================================================================\n// The post-diff filter + verdict\n// ============================================================================\n\nexport interface SqlDiffVerdictInput {\n /** The full, ownership-scoped diff issue list from the target's differ. */\n readonly issues: readonly SchemaDiffIssue[];\n /** Resolves a diff issue's subject table's declared control policy directly from the contract. */\n readonly resolveControlPolicy: (issue: SchemaDiffIssue) => ControlPolicy | undefined;\n readonly strict: boolean;\n readonly defaultControlPolicy: ControlPolicy | undefined;\n /** The target's classifier: a diff issue node's `nodeKind` → its subject granularity. */\n readonly granularityOf: (nodeKind: string) => DiffSubjectGranularity;\n}\n\nexport interface SqlDiffVerdict {\n readonly failures: readonly SchemaDiffIssue[];\n readonly warnings: readonly SchemaDiffIssue[];\n}\n\n/**\n * Applies the two consumer filters to a diff issue list: strict gating\n * (relational `not-expected` findings drop in lenient mode) and\n * control-policy disposition (each surviving issue grades against its\n * subject table's effective policy; suppressed issues drop, `observed`\n * subjects warn). The verify verdict is `failures.length === 0`.\n */\nexport function computeSqlDiffVerdict(input: SqlDiffVerdictInput): SqlDiffVerdict {\n const failures: SchemaDiffIssue[] = [];\n const warnings: SchemaDiffIssue[] = [];\n for (const issue of input.issues) {\n if (\n !input.strict &&\n issueOutcome(issue) === 'not-expected' &&\n isStrictOnlyExtra(issue, input.granularityOf)\n ) {\n continue;\n }\n const tablePolicy = input.resolveControlPolicy(issue);\n const policy = effectiveControlPolicy(tablePolicy, input.defaultControlPolicy);\n const disposition: VerifierOutcome = dispositionForCategory(\n policy,\n classifySqlDiffIssue(issue, input.granularityOf),\n );\n if (disposition === 'suppress') continue;\n if (disposition === 'warn') {\n warnings.push(issue);\n continue;\n }\n failures.push(issue);\n }\n return { failures, warnings };\n}\n\n// ============================================================================\n// Storage-types check — the codec verifyType hook path\n// ============================================================================\n\nexport interface StorageTypeVerdictInput {\n readonly contract: Contract<SqlStorage>;\n /**\n * Expected/actual namespace-node pairs the target's differ input produced:\n * for a namespaced tree, one entry per expected namespace with a\n * non-empty table set, paired by DDL schema name (absent actual side for\n * a schema the database lacks); a flat tree is the sole pair.\n */\n readonly namespacePairs: ReadonlyArray<{\n readonly actual: SqlSchemaIRNode | undefined;\n }>;\n readonly codecHooks: ReadonlyMap<string, CodecControlHooks>;\n}\n\n/**\n * Runs the codec `verifyType` hooks the way the legacy walk did: once per\n * contract namespace with tables, against that namespace's paired actual\n * node (the hook reads namespace-scoped state such as `enums` off it).\n * Issue dispositions grade against the contract default policy, matching\n * the legacy `pushTypeNode` semantics.\n */\nexport interface StorageTypeVerdict {\n readonly failures: readonly SchemaDiffIssue[];\n readonly warnings: readonly SchemaDiffIssue[];\n}\n\nexport function computeStorageTypeVerdict(input: StorageTypeVerdictInput): StorageTypeVerdict {\n const failures: SchemaDiffIssue[] = [];\n const warnings: SchemaDiffIssue[] = [];\n const policy = effectiveControlPolicy(undefined, input.contract.defaultControlPolicy);\n for (const pair of input.namespacePairs) {\n if (pair.actual === undefined) continue;\n for (const [typeName, typeInstance] of Object.entries(input.contract.storage.types ?? {})) {\n if (!isStorageTypeInstance(typeInstance)) continue;\n const hook = input.codecHooks.get(typeInstance.codecId);\n if (!hook?.verifyType) continue;\n const typeIssues = hook.verifyType({ typeName, typeInstance, schema: pair.actual });\n for (const issue of typeIssues) {\n const disposition = verifierDisposition(policy, issue);\n if (disposition === 'suppress') continue;\n if (disposition === 'warn') {\n warnings.push(issue);\n continue;\n }\n failures.push(issue);\n }\n }\n }\n return { failures, warnings };\n}\n\n// ============================================================================\n// The issue-based verify envelope\n// ============================================================================\n\nexport interface VerifySqlSchemaByDiffInput {\n readonly contract: Contract<SqlStorage>;\n readonly schema: SqlSchemaIRNode;\n readonly strict: boolean;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'sql', string>>;\n /** The target's full-tree node diff (`diffSchema` descriptor hook). */\n readonly diffSchema: SqlSchemaDiffFn;\n /** The target's classifier: a diff issue node's `nodeKind` → its subject granularity. */\n readonly granularityOf: (nodeKind: string) => DiffSubjectGranularity;\n}\n\n/**\n * THE SQL schema verify: runs the target's full-tree node diff, grades it\n * through the family's post-diff filters (strict gating + control-policy\n * disposition) plus the codec `verifyType` hook findings, and wraps the\n * verdict in the issue-based result envelope. `ok` holds exactly when both\n * issue lists are empty — the lists carry the verdict's failures.\n */\nexport function verifySqlSchemaByDiff(\n input: VerifySqlSchemaByDiffInput,\n): VerifyDatabaseSchemaResult {\n const startTime = Date.now();\n const verdictDiff = input.diffSchema({\n contract: input.contract,\n schema: input.schema,\n frameworkComponents: input.frameworkComponents,\n });\n const diffVerdict = computeSqlDiffVerdict({\n issues: verdictDiff.issues,\n resolveControlPolicy: verdictDiff.resolveControlPolicy,\n strict: input.strict,\n defaultControlPolicy: input.contract.defaultControlPolicy,\n granularityOf: input.granularityOf,\n });\n const storageTypeVerdict = computeStorageTypeVerdict({\n contract: input.contract,\n namespacePairs: verdictDiff.namespacePairs,\n codecHooks: extractCodecControlHooks(input.frameworkComponents),\n });\n const failCount = diffVerdict.failures.length + storageTypeVerdict.failures.length;\n const ok = failCount === 0;\n const profileHash =\n 'profileHash' in input.contract && typeof input.contract.profileHash === 'string'\n ? input.contract.profileHash\n : undefined;\n return {\n ok,\n ...(ok ? {} : { code: 'CONTRACT.SCHEMA_VERIFICATION_FAILED' }),\n summary: ok\n ? 'Database schema satisfies contract'\n : `Database schema does not satisfy contract (${failCount} failure${failCount === 1 ? '' : 's'})`,\n contract: {\n storageHash: input.contract.storage.storageHash,\n ...ifDefined('profileHash', profileHash),\n },\n target: {\n expected: input.contract.target,\n actual: input.contract.target,\n },\n schema: {\n issues: [...diffVerdict.failures, ...storageTypeVerdict.failures],\n warnings: {\n issues: [...diffVerdict.warnings, ...storageTypeVerdict.warnings],\n },\n },\n meta: { strict: input.strict },\n timings: { total: Date.now() - startTime },\n };\n}\n"],"mappings":";;;;;;;AAMA,SAAS,qBAAqB,YAO5B;CACA,IAAI,OAAO,eAAe,YAAY,eAAe,MACnD,OAAO;CAGT,MAAM,QAAQA,WAAE,OAAO,YAAY;CACnC,OAAO,UAAU,QAAQ,UAAU,KAAA,KAAa,OAAO,UAAU;AACnE;AAEA,SAAgB,yBACd,aACgC;CAChC,MAAM,wBAAQ,IAAI,IAA+B;CACjD,MAAM,yBAAS,IAAI,IAAoB;CAEvC,KAAK,MAAM,cAAc,aAAa;EACpC,IAAI,OAAO,eAAe,YAAY,eAAe,MACnD;EAEF,IAAI,CAAC,qBAAqB,UAAU,GAClC;EAEF,MAAM,oBAAoB,WAAW,MAAM,WAAW;EACtD,KAAK,MAAM,CAAC,SAAS,SAAS,OAAO,QAAQ,iBAAiB,GAAG;GAC/D,uBAAuB;IACrB;IACA;IACA,cAAc,WAAW;IACzB,aAAa;IACb,sBAAsB;GACxB,CAAC;GACD,MAAM,IAAI,SAAS,IAAI;GACvB,OAAO,IAAI,SAAS,WAAW,EAAE;EACnC;CACF;CAEA,OAAO;AACT;;;;;;;;;ACpCA,SAAgB,6BAA6B,OAA+C;CAC1F,IAAI,aAAa,KAAK,MAAM,aAC1B,OAAO;CAET,IAAI,aAAa,KAAK,MAAM,gBAC1B,OAAO;CAET,OAAO;AACT;AAEA,SAAgB,oBACd,eACA,OACiB;CACjB,OAAO,uBAAuB,eAAe,6BAA6B,KAAK,CAAC;AAClF;;;ACUA,SAAS,UAAU,OAAqD;CACtE,MAAM,OAAO,MAAM,YAAY,MAAM;CACrC,IAAI,SAAS,KAAA,GAAW,OAAO,KAAA;CAC/B,OAAO,UAGL,IAAI;AACR;;;;;;;;;;;AAYA,SAAgB,+BACd,OACA,eACoC;CACpC,MAAM,OAAO,UAAU,KAAK;CAC5B,OAAO,SAAS,KAAA,IAAY,KAAA,IAAY,cAAc,KAAK,QAAQ;AACrE;;;;;;;;;;AAWA,SAAgB,uBACd,OACA,cACoB;CACpB,MAAM,OAAO,UAAU,KAAK;CAC5B,OAAO,SAAS,KAAA,IAAY,KAAA,IAAY,aAAa,KAAK,QAAQ;AACpE;;;;;;;;;;;;;AAkBA,SAAgB,qBACd,OACA,eACuB;CACvB,IAAI,aAAa,KAAK,MAAM,aAC1B,OAAO;CAET,IAAI,aAAa,KAAK,MAAM,gBAAgB;EAC1C,MAAM,cAAc,+BAA+B,OAAO,aAAa;EACvE,IAAI,gBAAgB,YAAY,gBAAgB,aAC9C,OAAO;EAET,IAAI,gBAAgB,SAClB,OAAO;EAET,OAAO;CACT;CACA,IAAI,UAAU,KAAK,CAAC,EAAE,aAAa,yBAAyB,OAC1D,OAAO;CAET,OAAO;AACT;;;;;;;;AASA,SAAS,kBACP,OACA,eACS;CACT,MAAM,cAAc,+BAA+B,OAAO,aAAa;CACvE,OACE,gBAAgB,eAChB,gBAAgB,YAChB,gBAAgB,WAChB,gBAAgB;AAEpB;;;;;;;;AA6BA,SAAgB,sBAAsB,OAA4C;CAChF,MAAM,WAA8B,CAAC;CACrC,MAAM,WAA8B,CAAC;CACrC,KAAK,MAAM,SAAS,MAAM,QAAQ;EAChC,IACE,CAAC,MAAM,UACP,aAAa,KAAK,MAAM,kBACxB,kBAAkB,OAAO,MAAM,aAAa,GAE5C;EAIF,MAAM,cAA+B,uBADtB,uBADK,MAAM,qBAAqB,KACC,GAAG,MAAM,oBAElD,GACL,qBAAqB,OAAO,MAAM,aAAa,CACjD;EACA,IAAI,gBAAgB,YAAY;EAChC,IAAI,gBAAgB,QAAQ;GAC1B,SAAS,KAAK,KAAK;GACnB;EACF;EACA,SAAS,KAAK,KAAK;CACrB;CACA,OAAO;EAAE;EAAU;CAAS;AAC9B;AAgCA,SAAgB,0BAA0B,OAAoD;CAC5F,MAAM,WAA8B,CAAC;CACrC,MAAM,WAA8B,CAAC;CACrC,MAAM,SAAS,uBAAuB,KAAA,GAAW,MAAM,SAAS,oBAAoB;CACpF,KAAK,MAAM,QAAQ,MAAM,gBAAgB;EACvC,IAAI,KAAK,WAAW,KAAA,GAAW;EAC/B,KAAK,MAAM,CAAC,UAAU,iBAAiB,OAAO,QAAQ,MAAM,SAAS,QAAQ,SAAS,CAAC,CAAC,GAAG;GACzF,IAAI,CAAC,sBAAsB,YAAY,GAAG;GAC1C,MAAM,OAAO,MAAM,WAAW,IAAI,aAAa,OAAO;GACtD,IAAI,CAAC,MAAM,YAAY;GACvB,MAAM,aAAa,KAAK,WAAW;IAAE;IAAU;IAAc,QAAQ,KAAK;GAAO,CAAC;GAClF,KAAK,MAAM,SAAS,YAAY;IAC9B,MAAM,cAAc,oBAAoB,QAAQ,KAAK;IACrD,IAAI,gBAAgB,YAAY;IAChC,IAAI,gBAAgB,QAAQ;KAC1B,SAAS,KAAK,KAAK;KACnB;IACF;IACA,SAAS,KAAK,KAAK;GACrB;EACF;CACF;CACA,OAAO;EAAE;EAAU;CAAS;AAC9B;;;;;;;;AAwBA,SAAgB,sBACd,OAC4B;CAC5B,MAAM,YAAY,KAAK,IAAI;CAC3B,MAAM,cAAc,MAAM,WAAW;EACnC,UAAU,MAAM;EAChB,QAAQ,MAAM;EACd,qBAAqB,MAAM;CAC7B,CAAC;CACD,MAAM,cAAc,sBAAsB;EACxC,QAAQ,YAAY;EACpB,sBAAsB,YAAY;EAClC,QAAQ,MAAM;EACd,sBAAsB,MAAM,SAAS;EACrC,eAAe,MAAM;CACvB,CAAC;CACD,MAAM,qBAAqB,0BAA0B;EACnD,UAAU,MAAM;EAChB,gBAAgB,YAAY;EAC5B,YAAY,yBAAyB,MAAM,mBAAmB;CAChE,CAAC;CACD,MAAM,YAAY,YAAY,SAAS,SAAS,mBAAmB,SAAS;CAC5E,MAAM,KAAK,cAAc;CACzB,MAAM,cACJ,iBAAiB,MAAM,YAAY,OAAO,MAAM,SAAS,gBAAgB,WACrE,MAAM,SAAS,cACf,KAAA;CACN,OAAO;EACL;EACA,GAAI,KAAK,CAAC,IAAI,EAAE,MAAM,sCAAsC;EAC5D,SAAS,KACL,uCACA,8CAA8C,UAAU,UAAU,cAAc,IAAI,KAAK,IAAI;EACjG,UAAU;GACR,aAAa,MAAM,SAAS,QAAQ;GACpC,GAAG,UAAU,eAAe,WAAW;EACzC;EACA,QAAQ;GACN,UAAU,MAAM,SAAS;GACzB,QAAQ,MAAM,SAAS;EACzB;EACA,QAAQ;GACN,QAAQ,CAAC,GAAG,YAAY,UAAU,GAAG,mBAAmB,QAAQ;GAChE,UAAU,EACR,QAAQ,CAAC,GAAG,YAAY,UAAU,GAAG,mBAAmB,QAAQ,EAClE;EACF;EACA,MAAM,EAAE,QAAQ,MAAM,OAAO;EAC7B,SAAS,EAAE,OAAO,KAAK,IAAI,IAAI,UAAU;CAC3C;AACF"}
@@ -81,7 +81,93 @@ function temporalAuthoringPresets(input) {
81
81
  }
82
82
  };
83
83
  }
84
+ const TEMPORAL_PRECISION_ARG = {
85
+ name: "precision",
86
+ kind: "number",
87
+ optional: true,
88
+ integer: true,
89
+ minimum: 0
90
+ };
91
+ const TEMPORAL_ON_CREATE_ARG = {
92
+ name: "onCreate",
93
+ kind: "option",
94
+ values: ["now"],
95
+ optional: true
96
+ };
97
+ const TEMPORAL_ON_UPDATE_ARG = {
98
+ name: "onUpdate",
99
+ kind: "option",
100
+ values: ["now"],
101
+ optional: true
102
+ };
103
+ /**
104
+ * Selects the `timestampNow` generator descriptor for the preset's `now`
105
+ * token. The token is preset vocabulary; the generator id never appears in a
106
+ * user's spelling (ADR 169 — `timestampNow` is preset-only).
107
+ */
108
+ function temporalPhaseTemplate(index) {
109
+ return {
110
+ kind: "select",
111
+ index,
112
+ cases: { now: {
113
+ kind: "generator",
114
+ id: TIMESTAMP_NOW_GENERATOR_ID
115
+ } }
116
+ };
117
+ }
118
+ /**
119
+ * Builds a `temporal.<codec>` field preset for a codec that takes a precision
120
+ * parameter (`pg/timestamp@1`, `pg/timestamptz@1`). Arguments change field
121
+ * properties only — never the codec, which the caller fixes here.
122
+ *
123
+ * All three arguments are optional: omitting `precision` omits `typeParams`
124
+ * entirely, and omitting a phase omits that phase (both omitted omits
125
+ * `executionDefaults`).
126
+ */
127
+ /* @__NO_SIDE_EFFECTS__ */
128
+ function temporalCodecPresetWithPrecision(input) {
129
+ return {
130
+ kind: "fieldPreset",
131
+ args: [
132
+ TEMPORAL_PRECISION_ARG,
133
+ TEMPORAL_ON_CREATE_ARG,
134
+ TEMPORAL_ON_UPDATE_ARG
135
+ ],
136
+ output: {
137
+ codecId: input.codecId,
138
+ nativeType: input.nativeType,
139
+ typeParams: { precision: {
140
+ kind: "arg",
141
+ index: 0
142
+ } },
143
+ executionDefaults: {
144
+ onCreate: temporalPhaseTemplate(1),
145
+ onUpdate: temporalPhaseTemplate(2)
146
+ }
147
+ }
148
+ };
149
+ }
150
+ /**
151
+ * Builds a `temporal.<codec>` field preset for a codec with no type
152
+ * parameters (`sqlite/datetime@1`). As with the precision-bearing variant,
153
+ * both phase arguments are optional and omitting one omits that phase.
154
+ */
155
+ /* @__NO_SIDE_EFFECTS__ */
156
+ function temporalCodecPreset(input) {
157
+ return {
158
+ kind: "fieldPreset",
159
+ args: [TEMPORAL_ON_CREATE_ARG, TEMPORAL_ON_UPDATE_ARG],
160
+ output: {
161
+ codecId: input.codecId,
162
+ nativeType: input.nativeType,
163
+ executionDefaults: {
164
+ onCreate: temporalPhaseTemplate(0),
165
+ onUpdate: temporalPhaseTemplate(1)
166
+ }
167
+ }
168
+ };
169
+ }
84
170
  //#endregion
85
- export { temporalAuthoringPresets as n, timestampNowControlDescriptor as r, TIMESTAMP_NOW_GENERATOR_ID as t };
171
+ export { timestampNowControlDescriptor as a, temporalCodecPresetWithPrecision as i, temporalAuthoringPresets as n, temporalCodecPreset as r, TIMESTAMP_NOW_GENERATOR_ID as t };
86
172
 
87
- //# sourceMappingURL=timestamp-now-generator-CloimujU.mjs.map
173
+ //# sourceMappingURL=timestamp-now-generator-DRXygu32.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"timestamp-now-generator-DRXygu32.mjs","names":[],"sources":["../src/core/timestamp-now-generator.ts"],"sourcesContent":["import type { AuthoringFieldPresetDescriptor } from '@prisma-next/framework-components/authoring';\nimport type { MutationDefaultGeneratorDescriptor } from '@prisma-next/framework-components/control';\n\n/**\n * Canonical id for the wall-clock-now mutation default generator.\n *\n * Owned by `family-sql` because that's where the generator lives. The\n * id flows out from here to (1) the control-plane descriptor and the\n * temporal field-preset pair below, (2) the runtime-plane sibling\n * `timestamp-now-runtime-generator.ts`, and (3) authoring surfaces\n * (PSL `temporal.updatedAt()`, TS `field.temporal.updatedAt()`) via\n * the descriptor flow. Co-locating the constant with its only owner\n * keeps the framework layer free of concrete generator ids.\n */\nexport const TIMESTAMP_NOW_GENERATOR_ID = 'timestampNow' as const;\n\n/**\n * Builds the canonical control-plane descriptor for the wall-clock-now\n * mutation default generator. The descriptor's `id` and `buildPhases`\n * are target-agnostic so PSL `temporal.updatedAt()` and TS\n * `field.temporal.updatedAt()` lower to byte-identical contracts.\n *\n * `applicableCodecIds` is omitted: `timestampNow` is preset-only (not\n * reachable via `@default(timestampNow())` lowering), and the codec is\n * co-registered by the preset descriptor itself, so the\n * `@default(...)` compatibility check has no role to play here.\n */\nexport function timestampNowControlDescriptor(): MutationDefaultGeneratorDescriptor {\n return {\n id: TIMESTAMP_NOW_GENERATOR_ID,\n buildPhases: () => ({\n onCreate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n onUpdate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n }),\n };\n}\n\n/**\n * Builds the canonical `temporal.{createdAt,updatedAt}` field-preset pair\n * for a SQL target. `createdAt` lowers to a `now()` storage default;\n * `updatedAt` lowers to the `timestampNow` execution generator on both\n * `onCreate` and `onUpdate` (RD: \"last modified time\", non-null). Targets\n * supply the codec/native-type pair that matches their timestamp column;\n * everything else is shared so PSL `temporal.updatedAt()` and TS\n * `field.temporal.updatedAt()` lower to byte-identical contracts across\n * targets by construction.\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function temporalAuthoringPresets<\n const CodecId extends string,\n const NativeType extends string,\n>(input: { readonly codecId: CodecId; readonly nativeType: NativeType }) {\n const { codecId, nativeType } = input;\n return {\n createdAt: {\n kind: 'fieldPreset',\n output: {\n codecId,\n nativeType,\n default: { kind: 'function', expression: 'now()' },\n },\n },\n updatedAt: {\n kind: 'fieldPreset',\n output: {\n codecId,\n nativeType,\n executionDefaults: {\n onCreate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n onUpdate: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID },\n },\n },\n },\n } as const satisfies Record<string, AuthoringFieldPresetDescriptor>;\n}\n\nconst TEMPORAL_PRECISION_ARG = {\n name: 'precision',\n kind: 'number',\n optional: true,\n integer: true,\n minimum: 0,\n} as const;\n\nconst TEMPORAL_ON_CREATE_ARG = {\n name: 'onCreate',\n kind: 'option',\n values: ['now'],\n optional: true,\n} as const;\n\nconst TEMPORAL_ON_UPDATE_ARG = {\n name: 'onUpdate',\n kind: 'option',\n values: ['now'],\n optional: true,\n} as const;\n\n/**\n * Selects the `timestampNow` generator descriptor for the preset's `now`\n * token. The token is preset vocabulary; the generator id never appears in a\n * user's spelling (ADR 169 — `timestampNow` is preset-only).\n */\nfunction temporalPhaseTemplate<const Index extends number>(index: Index) {\n return {\n kind: 'select',\n index,\n cases: { now: { kind: 'generator', id: TIMESTAMP_NOW_GENERATOR_ID } },\n } as const;\n}\n\n/**\n * Builds a `temporal.<codec>` field preset for a codec that takes a precision\n * parameter (`pg/timestamp@1`, `pg/timestamptz@1`). Arguments change field\n * properties only — never the codec, which the caller fixes here.\n *\n * All three arguments are optional: omitting `precision` omits `typeParams`\n * entirely, and omitting a phase omits that phase (both omitted omits\n * `executionDefaults`).\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function temporalCodecPresetWithPrecision<\n const CodecId extends string,\n const NativeType extends string,\n>(input: { readonly codecId: CodecId; readonly nativeType: NativeType }) {\n return {\n kind: 'fieldPreset',\n args: [TEMPORAL_PRECISION_ARG, TEMPORAL_ON_CREATE_ARG, TEMPORAL_ON_UPDATE_ARG],\n output: {\n codecId: input.codecId,\n nativeType: input.nativeType,\n typeParams: { precision: { kind: 'arg', index: 0 } },\n executionDefaults: {\n onCreate: temporalPhaseTemplate(1),\n onUpdate: temporalPhaseTemplate(2),\n },\n },\n } as const satisfies AuthoringFieldPresetDescriptor;\n}\n\n/**\n * Builds a `temporal.<codec>` field preset for a codec with no type\n * parameters (`sqlite/datetime@1`). As with the precision-bearing variant,\n * both phase arguments are optional and omitting one omits that phase.\n */\n/* @__NO_SIDE_EFFECTS__ */\nexport function temporalCodecPreset<\n const CodecId extends string,\n const NativeType extends string,\n>(input: { readonly codecId: CodecId; readonly nativeType: NativeType }) {\n return {\n kind: 'fieldPreset',\n args: [TEMPORAL_ON_CREATE_ARG, TEMPORAL_ON_UPDATE_ARG],\n output: {\n codecId: input.codecId,\n nativeType: input.nativeType,\n executionDefaults: {\n onCreate: temporalPhaseTemplate(0),\n onUpdate: temporalPhaseTemplate(1),\n },\n },\n } as const satisfies AuthoringFieldPresetDescriptor;\n}\n"],"mappings":";;;;;;;;;;;;AAcA,MAAa,6BAA6B;;;;;;;;;;;;AAa1C,SAAgB,gCAAoE;CAClF,OAAO;EACL,IAAI;EACJ,oBAAoB;GAClB,UAAU;IAAE,MAAM;IAAa,IAAI;GAA2B;GAC9D,UAAU;IAAE,MAAM;IAAa,IAAI;GAA2B;EAChE;CACF;AACF;;;;;;;;;;;;AAaA,SAAgB,yBAGd,OAAuE;CACvE,MAAM,EAAE,SAAS,eAAe;CAChC,OAAO;EACL,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,SAAS;KAAE,MAAM;KAAY,YAAY;IAAQ;GACnD;EACF;EACA,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,mBAAmB;KACjB,UAAU;MAAE,MAAM;MAAa,IAAI;KAA2B;KAC9D,UAAU;MAAE,MAAM;MAAa,IAAI;KAA2B;IAChE;GACF;EACF;CACF;AACF;AAEA,MAAM,yBAAyB;CAC7B,MAAM;CACN,MAAM;CACN,UAAU;CACV,SAAS;CACT,SAAS;AACX;AAEA,MAAM,yBAAyB;CAC7B,MAAM;CACN,MAAM;CACN,QAAQ,CAAC,KAAK;CACd,UAAU;AACZ;AAEA,MAAM,yBAAyB;CAC7B,MAAM;CACN,MAAM;CACN,QAAQ,CAAC,KAAK;CACd,UAAU;AACZ;;;;;;AAOA,SAAS,sBAAkD,OAAc;CACvE,OAAO;EACL,MAAM;EACN;EACA,OAAO,EAAE,KAAK;GAAE,MAAM;GAAa,IAAI;EAA2B,EAAE;CACtE;AACF;;;;;;;;;;;AAYA,SAAgB,iCAGd,OAAuE;CACvE,OAAO;EACL,MAAM;EACN,MAAM;GAAC;GAAwB;GAAwB;EAAsB;EAC7E,QAAQ;GACN,SAAS,MAAM;GACf,YAAY,MAAM;GAClB,YAAY,EAAE,WAAW;IAAE,MAAM;IAAO,OAAO;GAAE,EAAE;GACnD,mBAAmB;IACjB,UAAU,sBAAsB,CAAC;IACjC,UAAU,sBAAsB,CAAC;GACnC;EACF;CACF;AACF;;;;;;;AAQA,SAAgB,oBAGd,OAAuE;CACvE,OAAO;EACL,MAAM;EACN,MAAM,CAAC,wBAAwB,sBAAsB;EACrD,QAAQ;GACN,SAAS,MAAM;GACf,YAAY,MAAM;GAClB,mBAAmB;IACjB,UAAU,sBAAsB,CAAC;IACjC,UAAU,sBAAsB,CAAC;GACnC;EACF;CACF;AACF"}
@@ -1,4 +1,4 @@
1
- import { r as SqlControlAdapter } from "./control-adapter-BQgad8Zc.mjs";
1
+ import { r as SqlControlAdapter } from "./control-adapter-CW7FdxeS.mjs";
2
2
  import { ContractSpace, ControlAdapterDescriptor, ControlExtensionDescriptor, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlannerConflict, MigrationPlannerFailureResult, MigrationPlannerSuccessResult, MigrationRunnerExecutionChecks, MigrationRunnerFailure, MigrationRunnerPerSpaceSuccessValue, MigrationRunnerResult, OpFactoryCall, OperationContext, SchemaDiffIssue, SchemaOwnership } from "@prisma-next/framework-components/control";
3
3
  import { Contract } from "@prisma-next/contract/types";
4
4
  import { SqlControlDriverInstance, SqlStorage, StorageColumn, StorageTable, StorageTypeInstance } from "@prisma-next/sql-contract/types";
@@ -7,7 +7,6 @@ import { Result } from "@prisma-next/utils/result";
7
7
  import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
8
8
  import { AggregateMigrationEdgeRef } from "@prisma-next/migration-tools/aggregate";
9
9
  import { SqlOperationDescriptors } from "@prisma-next/sql-operations";
10
-
11
10
  //#region src/core/migrations/types.d.ts
12
11
  type AnyRecord = Readonly<Record<string, unknown>>;
13
12
  interface StorageTypePlanResult<TTargetDetails> {
@@ -275,9 +274,9 @@ interface SqlMigrationPlannerPlanOptions {
275
274
  * or `null` for reconciliation flows that have no prior contract.
276
275
  *
277
276
  * Required at every call site so the structural fact "I have a prior
278
- * contract / I don't" is visible in the type. `migration plan` reads
279
- * the predecessor bundle's `end-contract.json` from disk and passes
280
- * the parsed value; `db update` / `db init` reconcile against the
277
+ * contract / I don't" is visible in the type. `migration plan` reads the
278
+ * predecessor's contract from the snapshot store by its storage hash and
279
+ * passes the parsed value; `db update` / `db init` reconcile against the
281
280
  * live schema and pass `null`. Strategies that
282
281
  * need from/to column-shape comparisons (unsafe type change, nullability
283
282
  * tightening) use this to decide whether to emit `dataTransform`
@@ -287,6 +286,13 @@ interface SqlMigrationPlannerPlanOptions {
287
286
  * plan's `describe()` as `fromContract?.storage.storageHash ?? null`.
288
287
  */
289
288
  readonly fromContract: Contract<SqlStorage> | null;
289
+ /**
290
+ * POSIX-relative path from the migration package dir to
291
+ * `migrations/snapshots`, e.g. `'../../snapshots'`. Threaded straight
292
+ * into the produced plan's `renderTypeScript()` metadata so the
293
+ * scaffold's contract-snapshot imports point at the deduplicated store.
294
+ */
295
+ readonly snapshotsImportPath: string;
290
296
  /**
291
297
  * Active framework components participating in this composition.
292
298
  * Each component is target-bound so SQL targets can dispatch
@@ -355,7 +361,7 @@ interface SqlMigrationRunnerExecuteOptions<TTargetDetails> {
355
361
  */
356
362
  readonly migrationEdges: readonly AggregateMigrationEdgeRef[];
357
363
  }
358
- type SqlMigrationRunnerErrorCode = 'DESTINATION_CONTRACT_MISMATCH' | 'LEGACY_MARKER_SHAPE' | 'MARKER_ORIGIN_MISMATCH' | 'MARKER_CAS_FAILURE' | 'POLICY_VIOLATION' | 'PRECHECK_FAILED' | 'POSTCHECK_FAILED' | 'SCHEMA_VERIFY_FAILED' | 'FOREIGN_KEY_VIOLATION' | 'EXECUTION_FAILED';
364
+ type SqlMigrationRunnerErrorCode = 'MIGRATION.DESTINATION_CONTRACT_MISMATCH' | 'MIGRATION.LEGACY_MARKER_SHAPE' | 'MIGRATION.MARKER_ORIGIN_MISMATCH' | 'MIGRATION.MARKER_CAS_FAILURE' | 'MIGRATION.POLICY_VIOLATION' | 'MIGRATION.PRECHECK_FAILED' | 'MIGRATION.POSTCHECK_FAILED' | 'MIGRATION.SCHEMA_VERIFY_FAILED' | 'MIGRATION.FOREIGN_KEY_VIOLATION' | 'MIGRATION.EXECUTION_FAILED';
359
365
  interface SqlMigrationRunnerFailure extends MigrationRunnerFailure {
360
366
  readonly code: SqlMigrationRunnerErrorCode;
361
367
  readonly meta?: AnyRecord;
@@ -411,4 +417,4 @@ interface CreateSqlMigrationPlanOptions<TTargetDetails> {
411
417
  }
412
418
  //#endregion
413
419
  export { SqlPlannerSuccessResult as A, SqlMigrationRunnerSuccessValue as C, SqlPlannerConflictLocation as D, SqlPlannerConflictKind as E, SqlPlannerFailureResult as O, SqlMigrationRunnerResult as S, SqlPlannerConflict as T, SqlMigrationRunner as _, FieldEvent as a, SqlMigrationRunnerExecuteOptions as b, SqlControlAdapterDescriptor as c, SqlMigrationPlanContractInfo as d, SqlMigrationPlanOperation as f, SqlMigrationPlannerPlanOptions as g, SqlMigrationPlanner as h, ExpandNativeTypeInput as i, StorageTypePlanResult as j, SqlPlannerResult as k, SqlControlExtensionDescriptor as l, SqlMigrationPlanOperationTarget as m, CodecControlHooks as n, FieldEventContext as o, SqlMigrationPlanOperationStep as p, CreateSqlMigrationPlanOptions as r, ResolveIdentityValueInput as s, AnyRecord as t, SqlMigrationPlan as u, SqlMigrationRunnerErrorCode as v, SqlPlanTargetDetails as w, SqlMigrationRunnerFailure as x, SqlMigrationRunnerExecuteCallbacks as y };
414
- //# sourceMappingURL=types-BPv_y7iS.d.mts.map
420
+ //# sourceMappingURL=types-DhAmOoxA.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-DhAmOoxA.d.mts","names":[],"sources":["../src/core/migrations/types.ts"],"mappings":";;;;;;;;;;KAkCY,YAAY,SAAS;UAEhB,sBAAsB;WAC5B,qBAAqB,0BAA0B;;;;;UAMzC;WACN;WACA;WACA,aAAa;;;;;;;;;UAUP;WACN;WACA;WACA,aAAa;;;;;;;;;;;;;;;;KAiBZ;;;;;;;;;;;;;UAcK;WACN;WACA;WACA;WACA,aAAa;WACb,WAAW;WACX,aAAa;WACb,WAAW;;UAGL,kBAAkB;;;;;;;;;EASjC,sBAAsB;aACX;aACA,cAAc;aACd,UAAU,SAAS;aACnB,QAAQ;aACR;aACA,QAAQ;QACb,sBAAsB;EAC5B,cAAc;aACH;aACA,cAAc;aACd,QAAQ;aACR;iBACI;EACf,mBAAmB;aACR,QAAQ;aACR;QACL,QAAQ,eAAe;;;;;;;;;;;EAW7B,oBAAoB,OAAO;;;;;;;;;;EAU3B,wBAAwB,OAAO;;;;;;;;;;;;;;;EAe/B,gBAAgB,OAAO,YAAY,KAAK,+BAA+B;;UAGxD,8BAA8B,kCACrC,kCAAkC;WACjC,wBAAwB;;;;;;;;;;;;WAYxB,gBAAgB,cAAc,SAAS;;UAGjC,4BAA4B,kCACnC,gCAAgC,WAAW,kBAAkB;WAC5D,wBAAwB;;UAGlB;WACN;WACA;;;;;;;;;WASA;WACA,OAAO;;;;;;;;;UAUD;WACN;WACA;;UAGM,gCAAgC;WACtC;WACA,UAAU;;UAGJ,0BAA0B,wBAAwB;WACxD;WACA,QAAQ,gCAAgC;WACxC,mBAAmB;WACnB,kBAAkB;WAClB,oBAAoB;WACpB,OAAO;;UAGD;WACN;WACA;;UAGM,iBAAiB,wBAAwB;;;;;;;;;;;;;;;WAe/C;;;;;WAKA,SAAS;;;;WAIT,aAAa;WACb,sBACL,0BAA0B,kBAC1B,QAAQ,0BAA0B;;;;;;;;;WAU7B;WACA,OAAO;;KAGN;UASK;WACN;WACA;WACA;WACA;WACA;WACA;;UAGM,2BAA2B;WACjC,MAAM;WACN,WAAW;WACX,OAAO;;UAGD,wBAAwB,wBAC/B,KAAK;WACJ;WACA,MAAM,iBAAiB;;UAGjB,gCAAgC,KAAK;WAC3C;WACA,oBAAoB;;KAGnB,iBAAiB,kBACzB,wBAAwB,kBACxB;UAEa;WACN,UAAU,SAAS;;;;;;WAMnB,QAAQ;WACR,QAAQ;WACR;;;;;;;;WAQA;;;;;;;;;;;;;;;;;WAiBA,cAAc,SAAS;;;;;;;WAOvB;;;;;;;WAOA,qBAAqB,cAAc;;;;;;;;;;WAUnC,YAAY;;UAGN,oBAAoB;EACnC,KAAK,SAAS,iCAAiC,iBAAiB;;UAGjD,mCAAmC;EAClD,kBAAkB,WAAW,0BAA0B;EACvD,qBAAqB,WAAW,0BAA0B;;UAG3C,iCAAiC;WACvC,MAAM,iBAAiB;WACvB,QAAQ;;;;;;;;WAQR;;;;;WAKA,qBAAqB,SAAS;;;;;WAK9B,QAAQ;WACR;WACA;WACA,YAAY,mCAAmC;WAC/C,UAAU;;;;;WAKV,kBAAkB;;;;;;;WAOlB,qBAAqB,cAAc;;;;;WAKnC,yBAAyB;;KAGxB;UAYK,kCAAkC;WACxC,MAAM;WACN,OAAO;;UAGD,uCAAuC;KAE5C,2BAA2B,OACrC,gCACA;UAGe,mBAAmB;;;;;;;;;;;;;;EAclC,QAAQ;aACG,QAAQ;aACR,iBAAiB,cAAc,iCAAiC;MACvE,QAAQ;;;;;;;;;;;EAYZ,oBACE,SAAS,iCAAiC,kBACzC,QAAQ;;UAGI,8BAA8B;WACpC;;;;WAIA;WACA,SAAS;WACT,aAAa;WACb,qBAAqB,0BAA0B;;;;;;WAM/C;WACA,OAAO"}
package/dist/verify.d.mts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { ContractMarkerRecord } from "@prisma-next/contract/types";
2
-
3
2
  //#region src/core/verify.d.ts
4
3
  /**
5
4
  * Wire shape of a `prisma_contract.marker` row as it comes out of a SQL
@@ -1 +1 @@
1
- {"version":3,"file":"verify.d.mts","names":[],"sources":["../src/core/verify.ts"],"mappings":";;;;;AAiDA;;;KAAY,iBAAA;EACV,SAAA;EACA,YAAA;EACA,aAAA;EACA,iBAAA;EACA,UAAA,EAAY,IAAI;EAChB,OAAA;EACA,IAAA;EAIA,UAAA;AAAA;;AAAU;AAkBZ;;iBAAgB,sBAAA,CAAuB,GAAA,YAAe,oBAAoB"}
1
+ {"version":3,"file":"verify.d.mts","names":[],"sources":["../src/core/verify.ts"],"mappings":";;;;;;;KAiDY;EACV;EACA;EACA;EACA;EACA,YAAY;EACZ;EACA;EAIA;;;;;;iBAkBc,uBAAuB,eAAe"}