@prisma-next/family-sql 0.11.0-dev.9 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/dist/authoring-type-constructors-F4JpCJl7.mjs.map +1 -1
  2. package/dist/control-adapter.d.mts +11 -4
  3. package/dist/control-adapter.d.mts.map +1 -1
  4. package/dist/control.d.mts +25 -2
  5. package/dist/control.d.mts.map +1 -1
  6. package/dist/control.mjs +43 -23
  7. package/dist/control.mjs.map +1 -1
  8. package/dist/ir.d.mts +4 -1
  9. package/dist/ir.d.mts.map +1 -1
  10. package/dist/ir.mjs +1 -1
  11. package/dist/ir.mjs.map +1 -1
  12. package/dist/migration.d.mts +1 -1
  13. package/dist/migration.d.mts.map +1 -1
  14. package/dist/migration.mjs.map +1 -1
  15. package/dist/pack.mjs.map +1 -1
  16. package/dist/runtime.d.mts.map +1 -1
  17. package/dist/runtime.mjs.map +1 -1
  18. package/dist/schema-verify.d.mts +1 -1
  19. package/dist/schema-verify.d.mts.map +1 -1
  20. package/dist/schema-verify.mjs +1 -1
  21. package/dist/{sql-contract-serializer-VVoSAnYg.mjs → sql-contract-serializer-8axtK4lg.mjs} +20 -7
  22. package/dist/sql-contract-serializer-8axtK4lg.mjs.map +1 -0
  23. package/dist/timestamp-now-generator-r7BP5n3l.mjs.map +1 -1
  24. package/dist/{types-hQoMXr54.d.mts → types-CeeCStqw.d.mts} +22 -41
  25. package/dist/types-CeeCStqw.d.mts.map +1 -0
  26. package/dist/verify-Crewz6hG.mjs.map +1 -1
  27. package/dist/{verify-sql-schema-Bfvz07Ik.d.mts → verify-sql-schema-CN7pPoTC.d.mts} +2 -2
  28. package/dist/verify-sql-schema-CN7pPoTC.d.mts.map +1 -0
  29. package/dist/{verify-sql-schema-DcP55TWb.mjs → verify-sql-schema-CYLsGCFO.mjs} +50 -36
  30. package/dist/verify-sql-schema-CYLsGCFO.mjs.map +1 -0
  31. package/dist/verify.d.mts.map +1 -1
  32. package/package.json +32 -21
  33. package/src/core/control-adapter.ts +16 -2
  34. package/src/core/control-instance.ts +6 -1
  35. package/src/core/ir/sql-contract-serializer-base.ts +48 -10
  36. package/src/core/migrations/contract-to-schema-ir.ts +83 -34
  37. package/src/core/migrations/types.ts +21 -45
  38. package/src/core/schema-verify/verify-sql-schema.ts +89 -40
  39. package/src/exports/control.ts +1 -3
  40. package/dist/sql-contract-serializer-VVoSAnYg.mjs.map +0 -1
  41. package/dist/types-hQoMXr54.d.mts.map +0 -1
  42. package/dist/verify-sql-schema-Bfvz07Ik.d.mts.map +0 -1
  43. package/dist/verify-sql-schema-DcP55TWb.mjs.map +0 -1
package/dist/ir.d.mts CHANGED
@@ -3,6 +3,7 @@ import { Namespace } from "@prisma-next/framework-components/ir";
3
3
  import { SqlNamespaceTablesInput, SqlStorage, SqlStorageTypeEntry } from "@prisma-next/sql-contract/types";
4
4
  import { Type } from "arktype";
5
5
  import { Contract } from "@prisma-next/contract/types";
6
+ import * as _$_prisma_next_contract_hashing0 from "@prisma-next/contract/hashing";
6
7
  import { JsonObject } from "@prisma-next/utils/json";
7
8
 
8
9
  //#region src/core/ir/sql-contract-serializer-base.d.ts
@@ -37,9 +38,11 @@ declare abstract class SqlContractSerializerBase<TContract extends Contract<SqlS
37
38
  constructor(entityTypeRegistry?: ReadonlyMap<string, SqlEntityHydrationFactory>, validatorFragments?: ReadonlyMap<string, Type<unknown>>);
38
39
  deserializeContract<T extends TContract = TContract>(json: unknown): T;
39
40
  serializeContract(contract: TContract): JsonObject;
41
+ shouldPreserveEmpty: _$_prisma_next_contract_hashing0.PreserveEmptyPredicate;
42
+ sortStorage: _$_prisma_next_contract_hashing0.StorageSort;
40
43
  protected parseSqlContractStructure(json: unknown): Contract<SqlStorage>;
41
44
  protected hydrateSqlStorage(validated: Contract<SqlStorage>): Contract<SqlStorage>;
42
- protected hydrateSqlNamespaceMap(namespaces: Readonly<Record<string, Namespace | Record<string, unknown>>>): Readonly<Record<string, Namespace | SqlNamespaceTablesInput>>;
45
+ protected hydrateSqlNamespaceMap(namespaces: Readonly<Record<string, Namespace | Record<string, unknown>>>): Readonly<Record<string, Namespace>>;
43
46
  protected hydrateSqlNamespaceEntry(nsId: string, raw: Namespace | Record<string, unknown>): Namespace | SqlNamespaceTablesInput;
44
47
  protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry;
45
48
  protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract;
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":";;;;;;;;KA8BY,yBAAA,IAA6B,KAAA,cAAmB,mBAAA;;AAA5D;;;;;AA0BA;;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,iBAKX,kBAAA;EAAA,iBAHF,cAAA;cAGE,kBAAA,GAAoB,WAAA,SAAoB,yBAAA,GACzD,kBAAA,GAAqB,WAAA,SAAoB,IAAA;EAW3C,mBAAA,WAA8B,SAAA,GAAY,SAAA,CAAA,CAAW,IAAA,YAAgB,CAAA;EAMrE,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAAA,UAI9B,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EAAA,UAOnD,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EAAA,UA0B7D,sBAAA,CACR,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,SAAA,GAAY,MAAA,sBAC/C,QAAA,CAAS,MAAA,SAAe,SAAA,GAAY,uBAAA;EAAA,UAS7B,wBAAA,CACR,IAAA,UACA,GAAA,EAAK,SAAA,GAAY,MAAA,oBAChB,SAAA,GAAY,uBAAA;EAAA,UAsEL,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAAA,UAerD,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;AAAA;;;;;;;;AA1LrE;;;;cCjBa,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;;;;;;;;;;;ADiB9E;;;;;AA0BA;;;;;;;;uBE7BsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EF4ClC;;;;;;EAAA,mBE/BX,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;EF8CoC;;;;;EAAA,mBEvC7B,sBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;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":";;;;;;;;;KAwCY,yBAAA,IAA6B,KAAA,cAAmB,mBAAmB;;;AAA/E;;;;AAA+E;AA0B/E;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,iBAKX,kBAAA;EAAA,iBAHF,cAAA;cAGE,kBAAA,GAAoB,WAAA,SAAoB,yBAAA,GACzD,kBAAA,GAAqB,WAAA,SAAoB,IAAA;EAW3C,mBAAA,WAA8B,SAAA,GAAY,SAAA,CAAA,CAAW,IAAA,YAAgB,CAAA;EAMrE,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAIxC,mBAAA,EAJkD,gCAAA,CAI/B,sBAAA;EAEnB,WAAA,EAFmB,gCAAA,CAER,WAAA;EAAA,UAED,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EAAA,UAOnD,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EAAA,UA6C7D,sBAAA,CACR,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,SAAA,GAAY,MAAA,sBAC/C,QAAA,CAAS,MAAA,SAAe,SAAA;EAAA,UAcjB,wBAAA,CACR,IAAA,UACA,GAAA,EAAK,SAAA,GAAY,MAAA,oBAChB,SAAA,GAAY,uBAAA;EAAA,UAsEL,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAAA,UAerD,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;AAAA;;;;;;;;;AAtNrE;;;cC3Ba,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;;;;;;;;;;;;AD2B9E;;;;AAA+E;AA0B/E;;;;;;;uBEvCsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EF2CzC;;;;;;EAAA,mBE9BJ,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;EFiDO;;;;;EAAA,mBE1CA,sBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;AAAA"}
package/dist/ir.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { n as SqlContractSerializerBase, t as SqlContractSerializer } from "./sql-contract-serializer-VVoSAnYg.mjs";
1
+ import { n as SqlContractSerializerBase, t as SqlContractSerializer } from "./sql-contract-serializer-8axtK4lg.mjs";
2
2
  //#region src/core/ir/sql-schema-verifier-base.ts
3
3
  /**
4
4
  * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared
package/dist/ir.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ir.mjs","names":[],"sources":["../src/core/ir/sql-schema-verifier-base.ts"],"sourcesContent":["import type {\n SchemaIssue,\n SchemaVerifier,\n SchemaVerifyOptions,\n SchemaVerifyResult,\n} from '@prisma-next/framework-components/control';\n\n/**\n * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared\n * walk (table-by-table + column-by-column matching keyed by\n * `(namespace.id, name)`, FK / unique / index comparisons via the\n * existing helpers in `verify-helpers.ts`) and exposes a protected hook\n * for target extensions (Postgres functions, RLS policies, future\n * target-only kinds).\n *\n * The base accumulates issues in a single buffer and returns the\n * combined result; the per-SPI family abstract handles the result\n * envelope shape so concrete subclasses focus on target-specific\n * verification logic.\n *\n * The protected hooks (`verifyCommonSqlSchema`,\n * `verifyTargetExtensions`) carry the stable base API that target\n * subclasses (`PostgresSchemaVerifier`, `SqliteSchemaVerifier`)\n * compile against; the SQL-shared walk implementation will be lifted\n * into this base when the verifier behaviour migrates off the\n * legacy adapter shells.\n */\nexport abstract class SqlSchemaVerifierBase<TContract, TSchema>\n implements SchemaVerifier<TContract, TSchema>\n{\n verifySchema(options: SchemaVerifyOptions<TContract, TSchema>): SchemaVerifyResult {\n const issues: SchemaIssue[] = [];\n issues.push(...this.verifyCommonSqlSchema(options));\n issues.push(...this.verifyTargetExtensions(options));\n return { ok: issues.length === 0, issues };\n }\n\n /**\n * SQL-shared verification — table/column/FK/unique/index walks keyed\n * by `(namespace.id, name)`. Concrete subclasses provide the\n * family-shared implementation today; a future iteration will lift\n * the shared walk into this base.\n */\n protected abstract verifyCommonSqlSchema(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaIssue[];\n\n /**\n * Target-specific extensions — e.g. Postgres functions, future RLS\n * policies, namespace-mismatch issues. Returns the empty list when the\n * target ships no extensions over the SQL family alphabet.\n */\n protected abstract verifyTargetExtensions(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaIssue[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAsB,wBAAtB,MAEA;CACE,aAAa,SAAsE;EACjF,MAAM,SAAwB,EAAE;EAChC,OAAO,KAAK,GAAG,KAAK,sBAAsB,QAAQ,CAAC;EACnD,OAAO,KAAK,GAAG,KAAK,uBAAuB,QAAQ,CAAC;EACpD,OAAO;GAAE,IAAI,OAAO,WAAW;GAAG;GAAQ"}
1
+ {"version":3,"file":"ir.mjs","names":[],"sources":["../src/core/ir/sql-schema-verifier-base.ts"],"sourcesContent":["import type {\n SchemaIssue,\n SchemaVerifier,\n SchemaVerifyOptions,\n SchemaVerifyResult,\n} from '@prisma-next/framework-components/control';\n\n/**\n * SQL family `SchemaVerifier` abstract base. Centralises the SQL-shared\n * walk (table-by-table + column-by-column matching keyed by\n * `(namespace.id, name)`, FK / unique / index comparisons via the\n * existing helpers in `verify-helpers.ts`) and exposes a protected hook\n * for target extensions (Postgres functions, RLS policies, future\n * target-only kinds).\n *\n * The base accumulates issues in a single buffer and returns the\n * combined result; the per-SPI family abstract handles the result\n * envelope shape so concrete subclasses focus on target-specific\n * verification logic.\n *\n * The protected hooks (`verifyCommonSqlSchema`,\n * `verifyTargetExtensions`) carry the stable base API that target\n * subclasses (`PostgresSchemaVerifier`, `SqliteSchemaVerifier`)\n * compile against; the SQL-shared walk implementation will be lifted\n * into this base when the verifier behaviour migrates off the\n * legacy adapter shells.\n */\nexport abstract class SqlSchemaVerifierBase<TContract, TSchema>\n implements SchemaVerifier<TContract, TSchema>\n{\n verifySchema(options: SchemaVerifyOptions<TContract, TSchema>): SchemaVerifyResult {\n const issues: SchemaIssue[] = [];\n issues.push(...this.verifyCommonSqlSchema(options));\n issues.push(...this.verifyTargetExtensions(options));\n return { ok: issues.length === 0, issues };\n }\n\n /**\n * SQL-shared verification — table/column/FK/unique/index walks keyed\n * by `(namespace.id, name)`. Concrete subclasses provide the\n * family-shared implementation today; a future iteration will lift\n * the shared walk into this base.\n */\n protected abstract verifyCommonSqlSchema(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaIssue[];\n\n /**\n * Target-specific extensions — e.g. Postgres functions, future RLS\n * policies, namespace-mismatch issues. Returns the empty list when the\n * target ships no extensions over the SQL family alphabet.\n */\n protected abstract verifyTargetExtensions(\n options: SchemaVerifyOptions<TContract, TSchema>,\n ): readonly SchemaIssue[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AA2BA,IAAsB,wBAAtB,MAEA;CACE,aAAa,SAAsE;EACjF,MAAM,SAAwB,CAAC;EAC/B,OAAO,KAAK,GAAG,KAAK,sBAAsB,OAAO,CAAC;EAClD,OAAO,KAAK,GAAG,KAAK,uBAAuB,OAAO,CAAC;EACnD,OAAO;GAAE,IAAI,OAAO,WAAW;GAAG;EAAO;CAC3C;AAoBF"}
@@ -1,4 +1,4 @@
1
- import { O as SqlPlanTargetDetails, g as SqlMigrationPlanOperation } from "./types-hQoMXr54.mjs";
1
+ import { T as SqlPlanTargetDetails, p as SqlMigrationPlanOperation } from "./types-CeeCStqw.mjs";
2
2
  import { Migration } from "@prisma-next/migration-tools/migration";
3
3
 
4
4
  //#region src/core/sql-migration.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/sql-migration.ts"],"mappings":";;;;;;AAkBA;;;;;;;;;;;;uBAAsB,YAAA,kBACH,oBAAA,6CAET,SAAA,CAAU,yBAAA,CAA0B,QAAA,UAAkB,SAAA;EAAtD;;;;;;;;;;EAAA,IAWJ,kBAAA,CAAA;AAAA"}
1
+ {"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/sql-migration.ts"],"mappings":";;;;;;AAkBA;;;;;;;;;;;;uBAAsB,YAAA,kBACH,oBAAA,6CAET,SAAA,CAAU,yBAAA,CAA0B,QAAA,UAAkB,SAAA;EAAtD;;;;;;AAWc;;;;EAXd,IAWJ,kBAAA,CAAA;AAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"migration.mjs","names":[],"sources":["../src/core/sql-migration.ts"],"sourcesContent":["import { deriveProvidedInvariants } from '@prisma-next/migration-tools/invariants';\nimport { Migration } from '@prisma-next/migration-tools/migration';\nimport type { SqlMigrationPlanOperation, SqlPlanTargetDetails } from './migrations/types';\n\n/**\n * Family-owned base class for SQL migrations.\n *\n * Generic in `TDetails` (family plan target details, e.g. Postgres vs SQLite)\n * and in `TTargetId` (the literal target identifier, e.g. `'postgres'`).\n *\n * Adapters (Postgres, SQLite, …) extend this with a concrete `TDetails` and\n * a fixed `TTargetId` literal, so the public `Migration<TOp>` base sees the\n * fully concrete operation shape. Target-free code in SQL family / tooling\n * parameterises over `TDetails` (and usually `TTargetId = string`).\n *\n * Keeps target-free contract/runtime features in the family layer while\n * letting adapters own target shape.\n */\nexport abstract class SqlMigration<\n TDetails extends SqlPlanTargetDetails,\n TTargetId extends string = string,\n> extends Migration<SqlMigrationPlanOperation<TDetails>, 'sql', TTargetId> {\n /**\n * Sorted, deduplicated invariant ids declared by this migration's\n * data-transform ops. Derived from `this.operations` so the field remains\n * consistent with the operation list — planner-built plans (`db init`,\n * `db update`) yield `[]` because they emit no data-transform ops.\n *\n * Required by `SqlMigrationPlan.providedInvariants` (tightened from\n * optional at the SQL-family layer); the framework-level\n * `MigrationPlan.providedInvariants?` stays optional.\n */\n get providedInvariants(): readonly string[] {\n return deriveProvidedInvariants(this.operations);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,IAAsB,eAAtB,cAGU,UAAiE;;;;;;;;;;;CAWzE,IAAI,qBAAwC;EAC1C,OAAO,yBAAyB,KAAK,WAAW"}
1
+ {"version":3,"file":"migration.mjs","names":[],"sources":["../src/core/sql-migration.ts"],"sourcesContent":["import { deriveProvidedInvariants } from '@prisma-next/migration-tools/invariants';\nimport { Migration } from '@prisma-next/migration-tools/migration';\nimport type { SqlMigrationPlanOperation, SqlPlanTargetDetails } from './migrations/types';\n\n/**\n * Family-owned base class for SQL migrations.\n *\n * Generic in `TDetails` (family plan target details, e.g. Postgres vs SQLite)\n * and in `TTargetId` (the literal target identifier, e.g. `'postgres'`).\n *\n * Adapters (Postgres, SQLite, …) extend this with a concrete `TDetails` and\n * a fixed `TTargetId` literal, so the public `Migration<TOp>` base sees the\n * fully concrete operation shape. Target-free code in SQL family / tooling\n * parameterises over `TDetails` (and usually `TTargetId = string`).\n *\n * Keeps target-free contract/runtime features in the family layer while\n * letting adapters own target shape.\n */\nexport abstract class SqlMigration<\n TDetails extends SqlPlanTargetDetails,\n TTargetId extends string = string,\n> extends Migration<SqlMigrationPlanOperation<TDetails>, 'sql', TTargetId> {\n /**\n * Sorted, deduplicated invariant ids declared by this migration's\n * data-transform ops. Derived from `this.operations` so the field remains\n * consistent with the operation list — planner-built plans (`db init`,\n * `db update`) yield `[]` because they emit no data-transform ops.\n *\n * Required by `SqlMigrationPlan.providedInvariants` (tightened from\n * optional at the SQL-family layer); the framework-level\n * `MigrationPlan.providedInvariants?` stays optional.\n */\n get providedInvariants(): readonly string[] {\n return deriveProvidedInvariants(this.operations);\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAkBA,IAAsB,eAAtB,cAGU,UAAiE;;;;;;;;;;;CAWzE,IAAI,qBAAwC;EAC1C,OAAO,yBAAyB,KAAK,UAAU;CACjD;AACF"}
package/dist/pack.mjs.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"pack.mjs","names":[],"sources":["../src/exports/pack.ts"],"sourcesContent":["import type { FamilyPackRef } from '@prisma-next/framework-components/components';\nimport { sqlFamilyAuthoringFieldPresets } from '../core/authoring-field-presets';\nimport { sqlFamilyAuthoringTypes } from '../core/authoring-type-constructors';\n\nconst sqlFamilyPack = {\n kind: 'family',\n id: 'sql',\n familyId: 'sql',\n version: '0.0.1',\n authoring: {\n field: sqlFamilyAuthoringFieldPresets,\n type: sqlFamilyAuthoringTypes,\n },\n} as const satisfies FamilyPackRef<'sql'>;\n\nexport default sqlFamilyPack;\n"],"mappings":";;AAIA,MAAM,gBAAgB;CACpB,MAAM;CACN,IAAI;CACJ,UAAU;CACV,SAAS;CACT,WAAW;EACT,OAAO;EACP,MAAM;EACP;CACF"}
1
+ {"version":3,"file":"pack.mjs","names":[],"sources":["../src/exports/pack.ts"],"sourcesContent":["import type { FamilyPackRef } from '@prisma-next/framework-components/components';\nimport { sqlFamilyAuthoringFieldPresets } from '../core/authoring-field-presets';\nimport { sqlFamilyAuthoringTypes } from '../core/authoring-type-constructors';\n\nconst sqlFamilyPack = {\n kind: 'family',\n id: 'sql',\n familyId: 'sql',\n version: '0.0.1',\n authoring: {\n field: sqlFamilyAuthoringFieldPresets,\n type: sqlFamilyAuthoringTypes,\n },\n} as const satisfies FamilyPackRef<'sql'>;\n\nexport default sqlFamilyPack;\n"],"mappings":";;AAIA,MAAM,gBAAgB;CACpB,MAAM;CACN,IAAI;CACJ,UAAU;CACV,SAAS;CACT,WAAW;EACT,OAAO;EACP,MAAM;CACR;AACF"}
@@ -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,qBAAA;;;;;AAAlD;;;;;;cCCa,0BAAA,EAA4B,uBAAA,QAA+B,wBAAA;;;;;;ADDxE;;;;;;;;ACCA;;;iBCMgB,4BAAA,CAAA,GAAgC,+BAAA"}
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;;;;AAAuE;UAAtD,wBAAA,SAAiC,qBAAqB;;;;;AAAvE;;;;AAAuE;;cCC1D,0BAAA,EAA4B,uBAAuB,QAAQ,wBAAA;;;;;;ADDxE;;;;AAAuE;;;;ACCvE;;;iBCMgB,4BAAA,CAAA,GAAgC,+BAA+B"}
@@ -1 +1 @@
1
- {"version":3,"file":"runtime.mjs","names":[],"sources":["../src/core/runtime-instance.ts","../src/core/runtime-descriptor.ts","../src/core/timestamp-now-runtime-generator.ts","../src/exports/runtime.ts"],"sourcesContent":["import type { RuntimeFamilyInstance } from '@prisma-next/framework-components/execution';\n\n/**\n * SQL execution-plane family instance interface.\n *\n * Note: this is currently named `SqlRuntimeFamilyInstance` because the execution plane\n * framework types are still using the `Runtime*` naming (`RuntimeFamilyInstance`, etc.).\n *\n * This will be renamed to `SqlExecutionFamilyInstance` as part of `TML-1842`.\n */\nexport interface SqlRuntimeFamilyInstance extends RuntimeFamilyInstance<'sql'> {}\n\n/**\n * Creates a SQL execution-plane family instance.\n *\n * This will be renamed to `createSqlExecutionFamilyInstance()` as part of `TML-1842`.\n */\nexport function createSqlRuntimeFamilyInstance(): SqlRuntimeFamilyInstance {\n return {\n familyId: 'sql' as const,\n };\n}\n","import type { RuntimeFamilyDescriptor } from '@prisma-next/framework-components/execution';\nimport { createSqlRuntimeFamilyInstance, type SqlRuntimeFamilyInstance } from './runtime-instance';\n\n/**\n * SQL execution-plane family descriptor.\n *\n * Note: this is currently named `sqlRuntimeFamilyDescriptor` because the execution plane\n * framework types are still using the `Runtime*` naming (`RuntimeFamilyDescriptor`, etc.).\n *\n * This will be renamed to `sqlExecutionFamilyDescriptor` as part of `TML-1842`.\n */\nexport const sqlRuntimeFamilyDescriptor: RuntimeFamilyDescriptor<'sql', SqlRuntimeFamilyInstance> =\n {\n kind: 'family',\n id: 'sql',\n familyId: 'sql',\n version: '0.0.1',\n create() {\n return createSqlRuntimeFamilyInstance();\n },\n };\n\nObject.freeze(sqlRuntimeFamilyDescriptor);\n","import type { RuntimeMutationDefaultGenerator } from '@prisma-next/sql-runtime';\nimport { TIMESTAMP_NOW_GENERATOR_ID } from './timestamp-now-generator';\n\n/**\n * Builds the canonical runtime-plane generator for the wall-clock-now\n * mutation default. Returns `new Date()`; semantics are target-agnostic\n * so all SQL targets share this single implementation.\n *\n * Declares `stability: 'query'` so a single ORM bulk operation\n * (e.g. `createAll([...])`) shares one timestamp across every row and\n * every timestamp-defaulted column. Matches Prisma 6's `@updatedAt`\n * semantics: one `new Date()` per lowered mutation, not per row.\n *\n * Lives in a runtime-plane-only module so the control-plane\n * `timestamp-now-generator.ts` (descriptor + authoring presets) stays\n * free of `@prisma-next/sql-runtime` imports.\n */\nexport function timestampNowRuntimeGenerator(): RuntimeMutationDefaultGenerator {\n return {\n id: TIMESTAMP_NOW_GENERATOR_ID,\n generate: () => new Date(),\n stability: 'query',\n };\n}\n","import { sqlRuntimeFamilyDescriptor } from '../core/runtime-descriptor';\n\nexport { timestampNowRuntimeGenerator } from '../core/timestamp-now-runtime-generator';\n\nexport default sqlRuntimeFamilyDescriptor;\n"],"mappings":";;;;;;;AAiBA,SAAgB,iCAA2D;CACzE,OAAO,EACL,UAAU,OACX;;;;;;;;;;;;ACTH,MAAa,6BACX;CACE,MAAM;CACN,IAAI;CACJ,UAAU;CACV,SAAS;CACT,SAAS;EACP,OAAO,gCAAgC;;CAE1C;AAEH,OAAO,OAAO,2BAA2B;;;;;;;;;;;;;;;;;ACLzC,SAAgB,+BAAgE;CAC9E,OAAO;EACL,IAAI;EACJ,gCAAgB,IAAI,MAAM;EAC1B,WAAW;EACZ;;;;AClBH,IAAA,kBAAe"}
1
+ {"version":3,"file":"runtime.mjs","names":[],"sources":["../src/core/runtime-instance.ts","../src/core/runtime-descriptor.ts","../src/core/timestamp-now-runtime-generator.ts","../src/exports/runtime.ts"],"sourcesContent":["import type { RuntimeFamilyInstance } from '@prisma-next/framework-components/execution';\n\n/**\n * SQL execution-plane family instance interface.\n *\n * Note: this is currently named `SqlRuntimeFamilyInstance` because the execution plane\n * framework types are still using the `Runtime*` naming (`RuntimeFamilyInstance`, etc.).\n *\n * This will be renamed to `SqlExecutionFamilyInstance` as part of `TML-1842`.\n */\nexport interface SqlRuntimeFamilyInstance extends RuntimeFamilyInstance<'sql'> {}\n\n/**\n * Creates a SQL execution-plane family instance.\n *\n * This will be renamed to `createSqlExecutionFamilyInstance()` as part of `TML-1842`.\n */\nexport function createSqlRuntimeFamilyInstance(): SqlRuntimeFamilyInstance {\n return {\n familyId: 'sql' as const,\n };\n}\n","import type { RuntimeFamilyDescriptor } from '@prisma-next/framework-components/execution';\nimport { createSqlRuntimeFamilyInstance, type SqlRuntimeFamilyInstance } from './runtime-instance';\n\n/**\n * SQL execution-plane family descriptor.\n *\n * Note: this is currently named `sqlRuntimeFamilyDescriptor` because the execution plane\n * framework types are still using the `Runtime*` naming (`RuntimeFamilyDescriptor`, etc.).\n *\n * This will be renamed to `sqlExecutionFamilyDescriptor` as part of `TML-1842`.\n */\nexport const sqlRuntimeFamilyDescriptor: RuntimeFamilyDescriptor<'sql', SqlRuntimeFamilyInstance> =\n {\n kind: 'family',\n id: 'sql',\n familyId: 'sql',\n version: '0.0.1',\n create() {\n return createSqlRuntimeFamilyInstance();\n },\n };\n\nObject.freeze(sqlRuntimeFamilyDescriptor);\n","import type { RuntimeMutationDefaultGenerator } from '@prisma-next/sql-runtime';\nimport { TIMESTAMP_NOW_GENERATOR_ID } from './timestamp-now-generator';\n\n/**\n * Builds the canonical runtime-plane generator for the wall-clock-now\n * mutation default. Returns `new Date()`; semantics are target-agnostic\n * so all SQL targets share this single implementation.\n *\n * Declares `stability: 'query'` so a single ORM bulk operation\n * (e.g. `createAll([...])`) shares one timestamp across every row and\n * every timestamp-defaulted column. Matches Prisma 6's `@updatedAt`\n * semantics: one `new Date()` per lowered mutation, not per row.\n *\n * Lives in a runtime-plane-only module so the control-plane\n * `timestamp-now-generator.ts` (descriptor + authoring presets) stays\n * free of `@prisma-next/sql-runtime` imports.\n */\nexport function timestampNowRuntimeGenerator(): RuntimeMutationDefaultGenerator {\n return {\n id: TIMESTAMP_NOW_GENERATOR_ID,\n generate: () => new Date(),\n stability: 'query',\n };\n}\n","import { sqlRuntimeFamilyDescriptor } from '../core/runtime-descriptor';\n\nexport { timestampNowRuntimeGenerator } from '../core/timestamp-now-runtime-generator';\n\nexport default sqlRuntimeFamilyDescriptor;\n"],"mappings":";;;;;;;AAiBA,SAAgB,iCAA2D;CACzE,OAAO,EACL,UAAU,MACZ;AACF;;;;;;;;;;;ACVA,MAAa,6BACX;CACE,MAAM;CACN,IAAI;CACJ,UAAU;CACV,SAAS;CACT,SAAS;EACP,OAAO,+BAA+B;CACxC;AACF;AAEF,OAAO,OAAO,0BAA0B;;;;;;;;;;;;;;;;;ACLxC,SAAgB,+BAAgE;CAC9E,OAAO;EACL,IAAI;EACJ,gCAAgB,IAAI,KAAK;EACzB,WAAW;CACb;AACF;;;ACnBA,IAAA,kBAAe"}
@@ -1,4 +1,4 @@
1
- import { i as verifySqlSchema, n as NativeTypeNormalizer, r as VerifySqlSchemaOptions } from "./verify-sql-schema-Bfvz07Ik.mjs";
1
+ import { i as verifySqlSchema, n as NativeTypeNormalizer, r as VerifySqlSchemaOptions } from "./verify-sql-schema-CN7pPoTC.mjs";
2
2
  import { SchemaIssue } from "@prisma-next/framework-components/control";
3
3
  import { SqlIndexIR, SqlUniqueIR } from "@prisma-next/sql-schema-ir/types";
4
4
 
@@ -1 +1 @@
1
- {"version":3,"file":"schema-verify.d.mts","names":[],"sources":["../src/core/schema-verify/verify-helpers.ts"],"mappings":";;;;;;;;iBAsDgB,WAAA,CAAY,CAAA,qBAAsB,CAAA;AA+BlD;;;;;;;;;;;AA0BA;AA1BA,iBAAgB,2BAAA,CACd,OAAA,WAAkB,WAAA,IAClB,OAAA,WAAkB,UAAA,IAClB,OAAA;;;;;;;;;;;;;iBAuBc,gBAAA,CACd,OAAA,WAAkB,UAAA,IAClB,OAAA,WAAkB,WAAA,IAClB,OAAA"}
1
+ {"version":3,"file":"schema-verify.d.mts","names":[],"sources":["../src/core/schema-verify/verify-helpers.ts"],"mappings":";;;;;;;;iBAsDgB,WAAA,CAAY,CAAA,qBAAsB,CAAoB;AA+BtE;;;;;;;;;;AAG4B;AAuB5B;AA1BA,iBAAgB,2BAAA,CACd,OAAA,WAAkB,WAAA,IAClB,OAAA,WAAkB,UAAU,IAC5B,OAAA;;;;;;;;;AA0B0B;;;;iBAHZ,gBAAA,CACd,OAAA,WAAkB,UAAA,IAClB,OAAA,WAAkB,WAAW,IAC7B,OAAA"}
@@ -1,2 +1,2 @@
1
- import { i as isUniqueConstraintSatisfied, n as arraysEqual, r as isIndexSatisfied, t as verifySqlSchema } from "./verify-sql-schema-DcP55TWb.mjs";
1
+ import { i as isUniqueConstraintSatisfied, n as arraysEqual, r as isIndexSatisfied, t as verifySqlSchema } from "./verify-sql-schema-CYLsGCFO.mjs";
2
2
  export { arraysEqual, isIndexSatisfied, isUniqueConstraintSatisfied, verifySqlSchema };
@@ -1,7 +1,10 @@
1
+ import { sqlContractCanonicalizationHooks } from "@prisma-next/sql-contract/canonicalization-hooks";
2
+ import { ifDefined } from "@prisma-next/utils/defined";
1
3
  import { ContractValidationError } from "@prisma-next/contract/contract-validation-error";
2
- import { NamespaceBase } from "@prisma-next/framework-components/ir";
3
- import { SqlStorage, StorageTable } from "@prisma-next/sql-contract/types";
4
+ import { NamespaceBase, UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
5
+ import { SqlStorage, SqlUnboundNamespace, StorageTable, buildSqlNamespace } from "@prisma-next/sql-contract/types";
4
6
  import { createSqlContractSchema, validateSqlContractFully } from "@prisma-next/sql-contract/validators";
7
+ import { blindCast } from "@prisma-next/utils/casts";
5
8
  import { type } from "arktype";
6
9
  //#region src/core/ir/sql-contract-serializer-base.ts
7
10
  const NamespaceRawSchema = type({
@@ -51,6 +54,8 @@ var SqlContractSerializerBase = class {
51
54
  serializeContract(contract) {
52
55
  return contract;
53
56
  }
57
+ shouldPreserveEmpty = sqlContractCanonicalizationHooks.shouldPreserveEmpty;
58
+ sortStorage = sqlContractCanonicalizationHooks.sortStorage;
54
59
  parseSqlContractStructure(json) {
55
60
  return validateSqlContractFully(json, this.contractSchema !== void 0 ? { contractSchema: this.contractSchema } : void 0);
56
61
  }
@@ -58,18 +63,26 @@ var SqlContractSerializerBase = class {
58
63
  const types = validated.storage.types;
59
64
  const hydratedTypes = types !== void 0 ? Object.fromEntries(Object.entries(types).map(([name, entry]) => [name, this.hydrateStorageTypeEntry(entry)])) : void 0;
60
65
  const rawNamespaces = validated.storage.namespaces;
61
- const hydratedNamespaces = rawNamespaces !== void 0 ? this.hydrateSqlNamespaceMap(rawNamespaces) : void 0;
66
+ if (rawNamespaces === void 0) throw new ContractValidationError("Contract storage.namespaces is required after structural validation", "structural");
67
+ const hydratedNamespaces = this.hydrateSqlNamespaceMap(rawNamespaces);
68
+ const unbound = hydratedNamespaces[UNBOUND_NAMESPACE_ID] ?? SqlUnboundNamespace.instance;
62
69
  return {
63
70
  ...validated,
64
71
  storage: new SqlStorage({
65
72
  storageHash: validated.storage.storageHash,
66
- ...hydratedTypes !== void 0 ? { types: hydratedTypes } : {},
67
- ...hydratedNamespaces !== void 0 ? { namespaces: hydratedNamespaces } : {}
73
+ ...ifDefined("types", hydratedTypes),
74
+ namespaces: blindCast({
75
+ ...hydratedNamespaces,
76
+ [UNBOUND_NAMESPACE_ID]: unbound
77
+ })
68
78
  })
69
79
  };
70
80
  }
71
81
  hydrateSqlNamespaceMap(namespaces) {
72
- return Object.fromEntries(Object.entries(namespaces).map(([nsId, raw]) => [nsId, this.hydrateSqlNamespaceEntry(nsId, raw)]));
82
+ return Object.fromEntries(Object.entries(namespaces).map(([nsId, namespaceEntryRaw]) => {
83
+ const namespaceHydrated = this.hydrateSqlNamespaceEntry(nsId, namespaceEntryRaw);
84
+ return [nsId, namespaceHydrated instanceof NamespaceBase ? namespaceHydrated : buildSqlNamespace(namespaceHydrated)];
85
+ }));
73
86
  }
74
87
  hydrateSqlNamespaceEntry(nsId, raw) {
75
88
  if (raw instanceof NamespaceBase) return raw;
@@ -144,4 +157,4 @@ var SqlContractSerializer = class extends SqlContractSerializerBase {
144
157
  //#endregion
145
158
  export { SqlContractSerializerBase as n, SqlContractSerializer as t };
146
159
 
147
- //# sourceMappingURL=sql-contract-serializer-VVoSAnYg.mjs.map
160
+ //# sourceMappingURL=sql-contract-serializer-8axtK4lg.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-contract-serializer-8axtK4lg.mjs","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts"],"sourcesContent":["import { ContractValidationError } from '@prisma-next/contract/contract-validation-error';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { ContractSerializer } from '@prisma-next/framework-components/control';\nimport {\n type Namespace,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';\nimport {\n buildSqlNamespace,\n type SqlNamespaceTablesInput,\n SqlStorage,\n type SqlStorageInput,\n type SqlStorageTypeEntry,\n SqlUnboundNamespace,\n StorageTable,\n type StorageTableInput,\n} from '@prisma-next/sql-contract/types';\nimport {\n createSqlContractSchema,\n validateSqlContractFully,\n} from '@prisma-next/sql-contract/validators';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { type Type, type } from 'arktype';\n\nconst NamespaceRawSchema = type({\n id: 'string',\n 'kind?': 'string',\n // Undeclared keys (`tables`, `enum`, and any pack-contributed slot maps)\n // intentionally pass through; the slot loop below iterates them by name.\n '+': 'ignore',\n});\n\nfunction isPlainRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport type SqlEntityHydrationFactory = (entry: unknown) => SqlStorageTypeEntry;\n\n/**\n * SQL family `ContractSerializer` abstract base. Carries the SQL-shared\n * deserialization pipeline:\n *\n * 1. `parseSqlContractStructure` validates the on-disk JSON envelope\n * against the SQL contract arktype schema (`validateSqlContractFully`)\n * and returns the validated flat-data shape.\n * 2. `hydrateSqlStorage` walks the validated `storage` subtree and\n * constructs the family-shared SQL Contract IR class hierarchy\n * (`SqlStorage` -> `StorageTable` -> `StorageColumn` / `PrimaryKey`\n * / …). The rest of the contract envelope is JSON-clean primitive\n * data and passes through unchanged.\n * 3. `constructTargetContract` is the target-specific extension hook;\n * defaults to identity. Targets that need to attach target-only\n * fields (e.g. target-specific derived storage fields) override it.\n *\n * Default `serializeContract` is identity over the contract — concrete\n * SQL targets ship JSON-clean class instances, so the contract value\n * can be stringified directly. The non-enumerable family-level `kind`\n * discriminator on `SqlNode` instances stays out of the persisted\n * envelope automatically. Targets that need to canonicalize on the way\n * out (key ordering, dropping computed-only fields) override\n * `serializeContract` directly.\n */\nexport abstract class SqlContractSerializerBase<TContract extends Contract<SqlStorage>>\n implements ContractSerializer<TContract>\n{\n private readonly contractSchema: Type<unknown> | undefined;\n\n constructor(\n private readonly entityTypeRegistry: ReadonlyMap<string, SqlEntityHydrationFactory> = new Map(),\n validatorFragments?: ReadonlyMap<string, Type<unknown>>,\n ) {\n // Only build a fragments-aware contract schema when pack contributions\n // exist. The cached module-level default in `validators.ts` covers the\n // no-contributions case and avoids per-instance schema compilation.\n this.contractSchema =\n validatorFragments !== undefined && validatorFragments.size > 0\n ? createSqlContractSchema(validatorFragments)\n : undefined;\n }\n\n deserializeContract<T extends TContract = TContract>(json: unknown): T {\n const validated = this.parseSqlContractStructure(json);\n const hydrated = this.hydrateSqlStorage(validated);\n return this.constructTargetContract(hydrated) as T;\n }\n\n serializeContract(contract: TContract): JsonObject {\n return contract as unknown as JsonObject;\n }\n\n shouldPreserveEmpty = sqlContractCanonicalizationHooks.shouldPreserveEmpty;\n\n sortStorage = sqlContractCanonicalizationHooks.sortStorage;\n\n protected parseSqlContractStructure(json: unknown): Contract<SqlStorage> {\n return validateSqlContractFully<Contract<SqlStorage>>(\n json,\n this.contractSchema !== undefined ? { contractSchema: this.contractSchema } : undefined,\n );\n }\n\n protected hydrateSqlStorage(validated: Contract<SqlStorage>): Contract<SqlStorage> {\n const types = validated.storage.types;\n const hydratedTypes =\n types !== undefined\n ? Object.fromEntries(\n Object.entries(types).map(([name, entry]) => [\n name,\n this.hydrateStorageTypeEntry(entry),\n ]),\n )\n : undefined;\n\n const rawNamespaces = validated.storage.namespaces;\n if (rawNamespaces === undefined) {\n throw new ContractValidationError(\n 'Contract storage.namespaces is required after structural validation',\n 'structural',\n );\n }\n const hydratedNamespaces = this.hydrateSqlNamespaceMap(rawNamespaces);\n // Compatibility shim: production code that addresses `__unbound__` for table\n // metadata lookups (collection-contract, query-plan-mutations, model-accessor,\n // query-plan-meta, where-binding) uses optional chaining and tolerates absence,\n // but runtime-qualification (TML-2605) has not yet landed cross-namespace table\n // routing. Injecting the empty singleton here keeps helpers that augment the\n // deserialized JSON (e.g. buildMixedPolyContract) working by providing a slot to\n // write into. Once runtime-qualification routes table lookups by namespace, this\n // shim should be removed.\n const unbound = hydratedNamespaces[UNBOUND_NAMESPACE_ID] ?? SqlUnboundNamespace.instance;\n\n return {\n ...validated,\n storage: new SqlStorage({\n storageHash: validated.storage.storageHash,\n ...ifDefined('types', hydratedTypes),\n // Cast narrows the result of hydrateSqlNamespaceMap from the wider\n // framework `Namespace` to the SQL-family `SqlNamespace`.\n namespaces: blindCast<\n SqlStorageInput['namespaces'],\n 'hydrated SQL namespaces are SqlNamespace instances (family hydration guarantees this)'\n >({ ...hydratedNamespaces, [UNBOUND_NAMESPACE_ID]: unbound }),\n }),\n };\n }\n\n protected hydrateSqlNamespaceMap(\n namespaces: Readonly<Record<string, Namespace | Record<string, unknown>>>,\n ): Readonly<Record<string, Namespace>> {\n return Object.fromEntries(\n Object.entries(namespaces).map(([nsId, namespaceEntryRaw]) => {\n // Raw entries passed structural validation; hydrate materialises family IR class instances.\n const namespaceHydrated = this.hydrateSqlNamespaceEntry(nsId, namespaceEntryRaw);\n const namespaceMaterialised =\n namespaceHydrated instanceof NamespaceBase\n ? namespaceHydrated\n : buildSqlNamespace(namespaceHydrated);\n return [nsId, namespaceMaterialised];\n }),\n );\n }\n\n protected hydrateSqlNamespaceEntry(\n nsId: string,\n raw: Namespace | Record<string, unknown>,\n ): Namespace | SqlNamespaceTablesInput {\n if (raw instanceof NamespaceBase) {\n return raw;\n }\n const rawRecord = isPlainRecord(raw) ? raw : {};\n const id = typeof rawRecord['id'] === 'string' ? rawRecord['id'] : nsId;\n const parsed = NamespaceRawSchema({ ...rawRecord, id });\n if (parsed instanceof type.errors) {\n const messages = parsed.map((p: { message: string }) => p.message).join('; ');\n throw new ContractValidationError(`Namespace hydration failed: ${messages}`, 'structural');\n }\n const result: Record<string, unknown> = { id };\n\n for (const [propertyKey, slotValue] of Object.entries(parsed)) {\n if (propertyKey === 'id') continue;\n if (slotValue === null || typeof slotValue !== 'object') continue;\n\n if (propertyKey === 'tables') {\n result['tables'] = Object.fromEntries(\n Object.entries(slotValue as Record<string, unknown>).map(([tableName, table]) => [\n tableName,\n table instanceof StorageTable ? table : new StorageTable(table as StorageTableInput),\n ]),\n );\n continue;\n }\n\n const hydratedSlot = Object.fromEntries(\n Object.entries(slotValue as Record<string, unknown>).map(([entryName, entry]) => {\n if (typeof entry !== 'object' || entry === null) {\n return [entryName, entry];\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string') {\n const factory = this.entityTypeRegistry.get(kind);\n if (factory !== undefined) {\n return [entryName, factory(entry)];\n }\n }\n return [entryName, entry];\n }),\n );\n if (Object.keys(hydratedSlot).length > 0) {\n result[propertyKey] = hydratedSlot;\n }\n }\n\n const enumRaw = rawRecord['enum'];\n if (enumRaw !== undefined && typeof enumRaw === 'object' && enumRaw !== null) {\n for (const entry of Object.values(enumRaw as Record<string, unknown>)) {\n if (typeof entry !== 'object' || entry === null) continue;\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind === 'string' && this.entityTypeRegistry.get(kind) === undefined) {\n throw new ContractValidationError(\n `Entry kind '${kind}' has no registered hydration factory.`,\n 'structural',\n );\n }\n }\n }\n\n const tables = (result['tables'] ?? {}) as Record<string, StorageTable>;\n const enumSlot = result['enum'] as NonNullable<SqlNamespaceTablesInput['enum']> | undefined;\n return {\n ...result,\n tables,\n ...(enumSlot !== undefined ? { enum: enumSlot } : {}),\n } as SqlNamespaceTablesInput;\n }\n\n protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry {\n if (typeof entry !== 'object' || entry === null) {\n return entry;\n }\n const kind = (entry as { kind?: unknown }).kind;\n if (typeof kind !== 'string') {\n return entry;\n }\n const factory = this.entityTypeRegistry.get(kind);\n if (factory === undefined) {\n return entry;\n }\n return factory(entry);\n }\n\n protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract {\n return hydrated as TContract;\n }\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { SqlStorage } from '@prisma-next/sql-contract/types';\nimport { SqlContractSerializerBase } from './sql-contract-serializer-base';\n\n/**\n * Default SQL family `ContractSerializer` concretion. Inherits the\n * full SQL-shared deserialization pipeline (structural validation +\n * IR-class hydration) without pack-registered `storage.types`\n * hydration factories — targets that emit polymorphic JSON outside the\n * codec-typed envelope wire a target-specific subclass with a populated\n * registry (see Postgres). Family-level call sites instantiate this\n * default directly when no target serializer is supplied.\n */\nexport class SqlContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor() {\n super(new Map());\n }\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"timestamp-now-generator-r7BP5n3l.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 */\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"],"mappings":";;;;;;;;;;;;AAcA,MAAa,6BAA6B;;;;;;;;;;;;AAa1C,SAAgB,gCAAoE;CAClF,OAAO;EACL,IAAI;EACJ,oBAAoB;GAClB,UAAU;IAAE,MAAM;IAAa,IAAI;IAA4B;GAC/D,UAAU;IAAE,MAAM;IAAa,IAAI;IAA4B;GAChE;EACF;;;;;;;;;;;;AAaH,SAAgB,yBAGd,OAAuE;CACvE,MAAM,EAAE,SAAS,eAAe;CAChC,OAAO;EACL,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,SAAS;KAAE,MAAM;KAAY,YAAY;KAAS;IACnD;GACF;EACD,WAAW;GACT,MAAM;GACN,QAAQ;IACN;IACA;IACA,mBAAmB;KACjB,UAAU;MAAE,MAAM;MAAa,IAAI;MAA4B;KAC/D,UAAU;MAAE,MAAM;MAAa,IAAI;MAA4B;KAChE;IACF;GACF;EACF"}
1
+ {"version":3,"file":"timestamp-now-generator-r7BP5n3l.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 */\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"],"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;;;;;;;;;;;AAYA,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"}
@@ -1,4 +1,4 @@
1
- import { ContractSerializer, ContractSpace, ControlAdapterDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyInstance, ControlStack, MigratableTargetDescriptor, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlannerConflict, MigrationPlannerFailureResult, MigrationPlannerSuccessResult, MigrationRunnerExecutionChecks, MigrationRunnerFailure, MigrationRunnerSuccessValue, OpFactoryCall, OperationContext, OperationPreview, OperationPreviewCapable, PslContractInferCapable, SchemaIssue, SchemaVerifier, SchemaViewCapable, SignDatabaseResult, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
1
+ import { ContractSerializer, ContractSpace, ControlAdapterDescriptor, ControlDriverInstance, ControlExtensionDescriptor, ControlFamilyInstance, ControlStack, MigratableTargetDescriptor, MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlannerConflict, MigrationPlannerFailureResult, MigrationPlannerSuccessResult, MigrationRunnerExecutionChecks, MigrationRunnerFailure, MigrationRunnerPerSpaceSuccessValue, MigrationRunnerResult, OpFactoryCall, OperationContext, OperationPreview, OperationPreviewCapable, PslContractInferCapable, SchemaIssue, SchemaVerifier, SchemaViewCapable, SignDatabaseResult, VerifyDatabaseResult, VerifyDatabaseSchemaResult } from "@prisma-next/framework-components/control";
2
2
  import { SqlStorage, StorageColumn, StorageTable, StorageTypeInstance } from "@prisma-next/sql-contract/types";
3
3
  import { PslDocumentAst } from "@prisma-next/framework-components/psl-ast";
4
4
  import { Result } from "@prisma-next/utils/result";
@@ -257,7 +257,7 @@ interface SqlMigrationPlan<TTargetDetails> extends MigrationPlan {
257
257
  * pass the extension's space id. Required at every call site so the
258
258
  * type system surfaces every place that needs to thread the value
259
259
  * (rather than letting an `?? APP_SPACE_ID` fall-through silently
260
- * collapse multi-space markers onto the `'app'` row).
260
+ * collapse per-space markers onto the `'app'` row).
261
261
  *
262
262
  * @see specs/framework-mechanism.spec.md § 2.
263
263
  */
@@ -393,57 +393,38 @@ interface SqlMigrationRunnerFailure extends MigrationRunnerFailure {
393
393
  readonly code: SqlMigrationRunnerErrorCode;
394
394
  readonly meta?: AnyRecord;
395
395
  }
396
- interface SqlMigrationRunnerSuccessValue extends MigrationRunnerSuccessValue {}
396
+ interface SqlMigrationRunnerSuccessValue extends MigrationRunnerPerSpaceSuccessValue {}
397
397
  type SqlMigrationRunnerResult = Result<SqlMigrationRunnerSuccessValue, SqlMigrationRunnerFailure>;
398
398
  interface SqlMigrationRunner<TTargetDetails> {
399
399
  /**
400
- * Apply a single migration plan, opening and managing its own
401
- * transaction (and any target-specific connection-level setup, e.g.
402
- * SQLite's `PRAGMA foreign_keys` toggle). Existing single-space
403
- * callers route through here.
400
+ * Apply one or more per-space migration plans, opening and managing the
401
+ * outer transaction (and any target-specific connection-level setup, e.g.
402
+ * SQLite's `PRAGMA foreign_keys` toggle). An apply that targets one space
403
+ * passes a one-element `perSpaceOptions` list.
404
+ *
405
+ * The caller orders the input list (typically via the aggregate planner's
406
+ * `applyOrder`: extensions alphabetical, then app). A failure on any space
407
+ * rolls back every space's writes.
408
+ *
409
+ * Each entry must reference the same `driver` as the top-level `driver`
410
+ * (the connection the outer transaction is open on).
404
411
  */
405
- execute(options: SqlMigrationRunnerExecuteOptions<TTargetDetails>): Promise<SqlMigrationRunnerResult>;
412
+ execute(options: {
413
+ readonly driver: ControlDriverInstance<'sql', string>;
414
+ readonly perSpaceOptions: ReadonlyArray<SqlMigrationRunnerExecuteOptions<TTargetDetails>>;
415
+ }): Promise<MigrationRunnerResult>;
406
416
  /**
407
417
  * Apply a single migration plan against an already-open connection
408
418
  * **without** opening a transaction. The caller is responsible for
409
419
  * wrapping the call (and any siblings) in `BEGIN` / `COMMIT` /
410
- * `ROLLBACK`. Used by the per-space runner wiring to fan out across
411
- * contract spaces inside one outer transaction so a mid-apply
412
- * failure rolls back every space's writes.
420
+ * `ROLLBACK`. Used by {@link SqlMigrationRunner.execute} to fan out
421
+ * across contract spaces inside one outer transaction.
413
422
  *
414
423
  * Idempotent control-table setup (`prisma_contract.*`) and marker
415
424
  * writes use `options.space` to address the per-space marker row.
416
425
  */
417
426
  executeOnConnection(options: SqlMigrationRunnerExecuteOptions<TTargetDetails>): Promise<SqlMigrationRunnerResult>;
418
- /**
419
- * Apply per-space plans across multiple contract spaces inside a
420
- * single outer transaction. The caller orders the input list
421
- * (typically via the aggregate planner's `applyOrder`: extensions
422
- * alphabetical, then app); the runner is responsible for opening
423
- * / committing the outer
424
- * transaction (and any target-specific connection-level setup such
425
- * as the SQLite FK pragma toggle). A failure on any space rolls
426
- * back every space's writes.
427
- *
428
- * Each space's `SqlMigrationRunnerExecuteOptions` must reference the
429
- * same `driver` (the connection the outer transaction is open on).
430
- * Per-space marker writes use `options.space` to address the row.
431
- */
432
- executeAcrossSpaces(options: {
433
- readonly driver: ControlDriverInstance<'sql', string>;
434
- readonly perSpaceOptions: ReadonlyArray<SqlMigrationRunnerExecuteOptions<TTargetDetails>>;
435
- }): Promise<MultiSpaceRunnerResult>;
436
- }
437
- interface MultiSpaceRunnerSuccessValue {
438
- readonly perSpaceResults: ReadonlyArray<{
439
- readonly space: string;
440
- readonly value: SqlMigrationRunnerSuccessValue;
441
- }>;
442
- }
443
- interface MultiSpaceRunnerFailure extends SqlMigrationRunnerFailure {
444
- readonly failingSpace: string;
445
427
  }
446
- type MultiSpaceRunnerResult = Result<MultiSpaceRunnerSuccessValue, MultiSpaceRunnerFailure>;
447
428
  interface SqlControlTargetDescriptor<TTargetId extends string, TTargetDetails, TContract extends Contract<SqlStorage> = Contract<SqlStorage>> extends MigratableTargetDescriptor<'sql', TTargetId, SqlControlFamilyInstance> {
448
429
  readonly queryOperations?: () => SqlOperationDescriptors;
449
430
  /**
@@ -481,5 +462,5 @@ interface CreateSqlMigrationPlanOptions<TTargetDetails> {
481
462
  readonly meta?: AnyRecord;
482
463
  }
483
464
  //#endregion
484
- export { SqlPlannerConflictKind as A, SqlMigrationRunnerExecuteCallbacks as C, SqlMigrationRunnerSuccessValue as D, SqlMigrationRunnerResult as E, StorageTypePlanResult as F, SqlControlFamilyInstance as I, SqlPlannerFailureResult as M, SqlPlannerResult as N, SqlPlanTargetDetails as O, SqlPlannerSuccessResult as P, SqlMigrationRunnerErrorCode as S, SqlMigrationRunnerFailure as T, SqlMigrationPlanOperationStep as _, FieldEvent as a, SqlMigrationPlannerPlanOptions as b, MultiSpaceRunnerResult as c, SqlControlAdapterDescriptor as d, SqlControlExtensionDescriptor as f, SqlMigrationPlanOperation as g, SqlMigrationPlanContractInfo as h, ExpandNativeTypeInput as i, SqlPlannerConflictLocation as j, SqlPlannerConflict as k, MultiSpaceRunnerSuccessValue as l, SqlMigrationPlan as m, CodecControlHooks as n, FieldEventContext as o, SqlControlTargetDescriptor as p, CreateSqlMigrationPlanOptions as r, MultiSpaceRunnerFailure as s, AnyRecord as t, ResolveIdentityValueInput as u, SqlMigrationPlanOperationTarget as v, SqlMigrationRunnerExecuteOptions as w, SqlMigrationRunner as x, SqlMigrationPlanner as y };
485
- //# sourceMappingURL=types-hQoMXr54.d.mts.map
465
+ export { SqlPlannerResult as A, SqlMigrationRunnerResult as C, SqlPlannerConflictKind as D, SqlPlannerConflict as E, StorageTypePlanResult as M, SqlControlFamilyInstance as N, SqlPlannerConflictLocation as O, SqlMigrationRunnerFailure as S, SqlPlanTargetDetails as T, SqlMigrationPlannerPlanOptions as _, FieldEvent as a, SqlMigrationRunnerExecuteCallbacks as b, SqlControlAdapterDescriptor as c, SqlMigrationPlan as d, SqlMigrationPlanContractInfo as f, SqlMigrationPlanner as g, SqlMigrationPlanOperationTarget as h, ExpandNativeTypeInput as i, SqlPlannerSuccessResult as j, SqlPlannerFailureResult as k, SqlControlExtensionDescriptor as l, SqlMigrationPlanOperationStep as m, CodecControlHooks as n, FieldEventContext as o, SqlMigrationPlanOperation as p, CreateSqlMigrationPlanOptions as r, ResolveIdentityValueInput as s, AnyRecord as t, SqlControlTargetDescriptor as u, SqlMigrationRunner as v, SqlMigrationRunnerSuccessValue as w, SqlMigrationRunnerExecuteOptions as x, SqlMigrationRunnerErrorCode as y };
466
+ //# sourceMappingURL=types-CeeCStqw.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types-CeeCStqw.d.mts","names":[],"sources":["../src/core/control-instance.ts","../src/core/migrations/types.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"verify-Crewz6hG.mjs","names":[],"sources":["../src/core/verify.ts"],"sourcesContent":["import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { type } from 'arktype';\n\nconst MetaSchema = type({ '[string]': 'unknown' });\n\nfunction parseMeta(meta: unknown): Record<string, unknown> {\n if (meta === null || meta === undefined) {\n return {};\n }\n\n let parsed: unknown;\n if (typeof meta === 'string') {\n try {\n parsed = JSON.parse(meta);\n } catch {\n return {};\n }\n } else {\n parsed = meta;\n }\n\n const result = MetaSchema(parsed);\n if (result instanceof type.errors) {\n return {};\n }\n\n return result as Record<string, unknown>;\n}\n\n/**\n * SQLite stores `contract_json` as TEXT, so the wire shape is a JSON string;\n * Postgres uses `jsonb` and returns an already-parsed value. Normalize both\n * here so `ContractMarkerRecord.contractJson` is always the structured form.\n */\nfunction parseContractJson(value: unknown): unknown {\n if (value === null || value === undefined) return null;\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n}\n\n/**\n * Wire shape of a `prisma_contract.marker` row as it comes out of a SQL\n * driver. Snake-cased to match the on-disk column names. Shared by every\n * SQL target's `readMarker` so each runner doesn't redeclare it inline.\n */\nexport type ContractMarkerRow = {\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n // SQLite stores arrays as JSON-TEXT, so this is `string` on the wire from\n // a SQLite driver and `string[]` from a Postgres driver. Targets normalize\n // before passing to `parseContractMarkerRow`.\n invariants: unknown;\n};\n\nconst ContractMarkerRowSchema = type({\n core_hash: 'string',\n profile_hash: 'string',\n 'contract_json?': 'unknown | null',\n 'canonical_version?': 'number | null',\n 'updated_at?': 'Date | string',\n 'app_tag?': 'string | null',\n 'meta?': 'unknown | null',\n invariants: type('string').array(),\n});\n\n/**\n * Parses a contract marker row from database query result.\n * This is SQL-specific parsing logic (handles SQL row structure with snake_case columns).\n */\nexport function parseContractMarkerRow(row: unknown): ContractMarkerRecord {\n const result = ContractMarkerRowSchema(row);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Invalid contract marker row: ${messages}`);\n }\n\n const updatedAt = result.updated_at\n ? result.updated_at instanceof Date\n ? result.updated_at\n : new Date(result.updated_at)\n : new Date();\n\n return {\n storageHash: result.core_hash,\n profileHash: result.profile_hash,\n contractJson: parseContractJson(result.contract_json),\n canonicalVersion: result.canonical_version ?? null,\n updatedAt,\n appTag: result.app_tag ?? null,\n meta: parseMeta(result.meta),\n invariants: result.invariants,\n };\n}\n\n/**\n * Collects supported codec type IDs from adapter and extension manifests.\n * Returns a sorted, unique array of type IDs that are declared in the manifests.\n * This enables coverage checks by comparing contract column types against supported types.\n *\n * Note: This extracts type IDs from manifest type imports, not from runtime codec registries.\n * The manifests declare which codec types are available, but the actual type IDs\n * are defined in the codec-types TypeScript modules that are imported.\n *\n * For MVP, we return an empty array since extracting type IDs from TypeScript modules\n * would require runtime evaluation or static analysis. This can be enhanced later.\n */\nexport function collectSupportedCodecTypeIds(\n descriptors: ReadonlyArray<{ readonly id: string }>,\n): readonly string[] {\n // For MVP, return empty array\n // Future enhancement: Extract type IDs from codec-types modules via static analysis\n // or require manifests to explicitly list supported type IDs\n void descriptors;\n return [];\n}\n"],"mappings":";;AAGA,MAAM,aAAa,KAAK,EAAE,YAAY,WAAW,CAAC;AAElD,SAAS,UAAU,MAAwC;CACzD,IAAI,SAAS,QAAQ,SAAS,KAAA,GAC5B,OAAO,EAAE;CAGX,IAAI;CACJ,IAAI,OAAO,SAAS,UAClB,IAAI;EACF,SAAS,KAAK,MAAM,KAAK;SACnB;EACN,OAAO,EAAE;;MAGX,SAAS;CAGX,MAAM,SAAS,WAAW,OAAO;CACjC,IAAI,kBAAkB,KAAK,QACzB,OAAO,EAAE;CAGX,OAAO;;;;;;;AAQT,SAAS,kBAAkB,OAAyB;CAClD,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,OAAO,KAAK,MAAM,MAAM;SAClB;EACN,OAAO;;;AAuBX,MAAM,0BAA0B,KAAK;CACnC,WAAW;CACX,cAAc;CACd,kBAAkB;CAClB,sBAAsB;CACtB,eAAe;CACf,YAAY;CACZ,SAAS;CACT,YAAY,KAAK,SAAS,CAAC,OAAO;CACnC,CAAC;;;;;AAMF,SAAgB,uBAAuB,KAAoC;CACzE,MAAM,SAAS,wBAAwB,IAAI;CAC3C,IAAI,kBAAkB,KAAK,QAAQ;EACjC,MAAM,WAAW,OAAO,KAAK,MAA2B,EAAE,QAAQ,CAAC,KAAK,KAAK;EAC7E,MAAM,IAAI,MAAM,gCAAgC,WAAW;;CAG7D,MAAM,YAAY,OAAO,aACrB,OAAO,sBAAsB,OAC3B,OAAO,aACP,IAAI,KAAK,OAAO,WAAW,mBAC7B,IAAI,MAAM;CAEd,OAAO;EACL,aAAa,OAAO;EACpB,aAAa,OAAO;EACpB,cAAc,kBAAkB,OAAO,cAAc;EACrD,kBAAkB,OAAO,qBAAqB;EAC9C;EACA,QAAQ,OAAO,WAAW;EAC1B,MAAM,UAAU,OAAO,KAAK;EAC5B,YAAY,OAAO;EACpB;;;;;;;;;;;;;;AAeH,SAAgB,6BACd,aACmB;CAKnB,OAAO,EAAE"}
1
+ {"version":3,"file":"verify-Crewz6hG.mjs","names":[],"sources":["../src/core/verify.ts"],"sourcesContent":["import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { type } from 'arktype';\n\nconst MetaSchema = type({ '[string]': 'unknown' });\n\nfunction parseMeta(meta: unknown): Record<string, unknown> {\n if (meta === null || meta === undefined) {\n return {};\n }\n\n let parsed: unknown;\n if (typeof meta === 'string') {\n try {\n parsed = JSON.parse(meta);\n } catch {\n return {};\n }\n } else {\n parsed = meta;\n }\n\n const result = MetaSchema(parsed);\n if (result instanceof type.errors) {\n return {};\n }\n\n return result as Record<string, unknown>;\n}\n\n/**\n * SQLite stores `contract_json` as TEXT, so the wire shape is a JSON string;\n * Postgres uses `jsonb` and returns an already-parsed value. Normalize both\n * here so `ContractMarkerRecord.contractJson` is always the structured form.\n */\nfunction parseContractJson(value: unknown): unknown {\n if (value === null || value === undefined) return null;\n if (typeof value !== 'string') return value;\n try {\n return JSON.parse(value);\n } catch {\n return null;\n }\n}\n\n/**\n * Wire shape of a `prisma_contract.marker` row as it comes out of a SQL\n * driver. Snake-cased to match the on-disk column names. Shared by every\n * SQL target's `readMarker` so each runner doesn't redeclare it inline.\n */\nexport type ContractMarkerRow = {\n core_hash: string;\n profile_hash: string;\n contract_json: unknown | null;\n canonical_version: number | null;\n updated_at: Date | string;\n app_tag: string | null;\n meta: unknown | null;\n // SQLite stores arrays as JSON-TEXT, so this is `string` on the wire from\n // a SQLite driver and `string[]` from a Postgres driver. Targets normalize\n // before passing to `parseContractMarkerRow`.\n invariants: unknown;\n};\n\nconst ContractMarkerRowSchema = type({\n core_hash: 'string',\n profile_hash: 'string',\n 'contract_json?': 'unknown | null',\n 'canonical_version?': 'number | null',\n 'updated_at?': 'Date | string',\n 'app_tag?': 'string | null',\n 'meta?': 'unknown | null',\n invariants: type('string').array(),\n});\n\n/**\n * Parses a contract marker row from database query result.\n * This is SQL-specific parsing logic (handles SQL row structure with snake_case columns).\n */\nexport function parseContractMarkerRow(row: unknown): ContractMarkerRecord {\n const result = ContractMarkerRowSchema(row);\n if (result instanceof type.errors) {\n const messages = result.map((p: { message: string }) => p.message).join('; ');\n throw new Error(`Invalid contract marker row: ${messages}`);\n }\n\n const updatedAt = result.updated_at\n ? result.updated_at instanceof Date\n ? result.updated_at\n : new Date(result.updated_at)\n : new Date();\n\n return {\n storageHash: result.core_hash,\n profileHash: result.profile_hash,\n contractJson: parseContractJson(result.contract_json),\n canonicalVersion: result.canonical_version ?? null,\n updatedAt,\n appTag: result.app_tag ?? null,\n meta: parseMeta(result.meta),\n invariants: result.invariants,\n };\n}\n\n/**\n * Collects supported codec type IDs from adapter and extension manifests.\n * Returns a sorted, unique array of type IDs that are declared in the manifests.\n * This enables coverage checks by comparing contract column types against supported types.\n *\n * Note: This extracts type IDs from manifest type imports, not from runtime codec registries.\n * The manifests declare which codec types are available, but the actual type IDs\n * are defined in the codec-types TypeScript modules that are imported.\n *\n * For MVP, we return an empty array since extracting type IDs from TypeScript modules\n * would require runtime evaluation or static analysis. This can be enhanced later.\n */\nexport function collectSupportedCodecTypeIds(\n descriptors: ReadonlyArray<{ readonly id: string }>,\n): readonly string[] {\n // For MVP, return empty array\n // Future enhancement: Extract type IDs from codec-types modules via static analysis\n // or require manifests to explicitly list supported type IDs\n void descriptors;\n return [];\n}\n"],"mappings":";;AAGA,MAAM,aAAa,KAAK,EAAE,YAAY,UAAU,CAAC;AAEjD,SAAS,UAAU,MAAwC;CACzD,IAAI,SAAS,QAAQ,SAAS,KAAA,GAC5B,OAAO,CAAC;CAGV,IAAI;CACJ,IAAI,OAAO,SAAS,UAClB,IAAI;EACF,SAAS,KAAK,MAAM,IAAI;CAC1B,QAAQ;EACN,OAAO,CAAC;CACV;MAEA,SAAS;CAGX,MAAM,SAAS,WAAW,MAAM;CAChC,IAAI,kBAAkB,KAAK,QACzB,OAAO,CAAC;CAGV,OAAO;AACT;;;;;;AAOA,SAAS,kBAAkB,OAAyB;CAClD,IAAI,UAAU,QAAQ,UAAU,KAAA,GAAW,OAAO;CAClD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI;EACF,OAAO,KAAK,MAAM,KAAK;CACzB,QAAQ;EACN,OAAO;CACT;AACF;AAqBA,MAAM,0BAA0B,KAAK;CACnC,WAAW;CACX,cAAc;CACd,kBAAkB;CAClB,sBAAsB;CACtB,eAAe;CACf,YAAY;CACZ,SAAS;CACT,YAAY,KAAK,QAAQ,EAAE,MAAM;AACnC,CAAC;;;;;AAMD,SAAgB,uBAAuB,KAAoC;CACzE,MAAM,SAAS,wBAAwB,GAAG;CAC1C,IAAI,kBAAkB,KAAK,QAAQ;EACjC,MAAM,WAAW,OAAO,KAAK,MAA2B,EAAE,OAAO,EAAE,KAAK,IAAI;EAC5E,MAAM,IAAI,MAAM,gCAAgC,UAAU;CAC5D;CAEA,MAAM,YAAY,OAAO,aACrB,OAAO,sBAAsB,OAC3B,OAAO,aACP,IAAI,KAAK,OAAO,UAAU,oBAC5B,IAAI,KAAK;CAEb,OAAO;EACL,aAAa,OAAO;EACpB,aAAa,OAAO;EACpB,cAAc,kBAAkB,OAAO,aAAa;EACpD,kBAAkB,OAAO,qBAAqB;EAC9C;EACA,QAAQ,OAAO,WAAW;EAC1B,MAAM,UAAU,OAAO,IAAI;EAC3B,YAAY,OAAO;CACrB;AACF;;;;;;;;;;;;;AAcA,SAAgB,6BACd,aACmB;CAKnB,OAAO,CAAC;AACV"}
@@ -60,7 +60,7 @@ interface VerifySqlSchemaOptions {
60
60
  * verifier emits a `type_missing` issue. A non-null array triggers a
61
61
  * value-set comparison against the contract's `PostgresEnumStorageEntry.values`.
62
62
  */
63
- readonly resolveExistingEnumValues?: (schema: SqlSchemaIR, enumType: PostgresEnumStorageEntry) => readonly string[] | null;
63
+ readonly resolveExistingEnumValues?: (schema: SqlSchemaIR, enumType: PostgresEnumStorageEntry, namespaceId: string) => readonly string[] | null;
64
64
  }
65
65
  /**
66
66
  * Verifies that a SqlSchemaIR matches a Contract.
@@ -75,4 +75,4 @@ interface VerifySqlSchemaOptions {
75
75
  declare function verifySqlSchema(options: VerifySqlSchemaOptions): VerifyDatabaseSchemaResult;
76
76
  //#endregion
77
77
  export { verifySqlSchema as i, NativeTypeNormalizer as n, VerifySqlSchemaOptions as r, DefaultNormalizer as t };
78
- //# sourceMappingURL=verify-sql-schema-Bfvz07Ik.d.mts.map
78
+ //# sourceMappingURL=verify-sql-schema-CN7pPoTC.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-sql-schema-CN7pPoTC.d.mts","names":[],"sources":["../src/core/schema-verify/verify-sql-schema.ts"],"mappings":";;;;;;;;;;AA+CkB;KAHN,iBAAA,IACV,UAAA,UACA,UAAA,aACG,aAAa;;;;AAOoC;AAKtD;KALY,oBAAA,IAAwB,UAAkB;;;;UAKrC,sBAAA;EAQI;EAAA,SANV,QAAA,EAAU,QAAA,CAAS,UAAA;EAagB;EAAA,SAXnC,MAAA,EAAQ,WAAA;EAiBW;EAAA,SAfnB,MAAA;EAkCC;EAAA,SAhCD,OAAA,GAAU,gBAAA;EAiCiB;EAAA,SA/B3B,oBAAA,EAAsB,WAAA;IAAsB,UAAA;EAAA;EARzB;;;;EAAA,SAanB,mBAAA,EAAqB,aAAA,CAAc,8BAAA;EAPzB;;;;;EAAA,SAaV,gBAAA,GAAmB,iBAAA;EANgB;;;;;EAAA,SAYnC,mBAAA,GAAsB,oBAAA;EAarB;;;;;;AAEW;AAcvB;;;;EAhBY,SADD,yBAAA,IACP,MAAA,EAAQ,WAAA,EACR,QAAA,EAAU,wBAAA,EACV,WAAA;AAAA;;;AAcwF;;;;;;;;iBAA5E,eAAA,CAAgB,OAAA,EAAS,sBAAA,GAAyB,0BAA0B"}
@@ -438,52 +438,64 @@ function verifySqlSchema(options) {
438
438
  const nsEnums = ns.enum;
439
439
  if (nsEnums) for (const [k, v] of Object.entries(nsEnums)) allStorageTypesMap[k] = v;
440
440
  }
441
- const storageTypes = allStorageTypesMap;
442
441
  const { issues, rootChildren } = verifySchemaTables({
443
442
  contract,
444
443
  schema,
445
444
  strict,
446
445
  typeMetadataRegistry,
447
446
  codecHooks,
448
- storageTypes,
447
+ storageTypes: allStorageTypesMap,
449
448
  ...ifDefined("normalizeDefault", normalizeDefault),
450
449
  ...ifDefined("normalizeNativeType", normalizeNativeType)
451
450
  });
452
451
  validateFrameworkComponentsForExtensions(contract, options.frameworkComponents);
453
- const storageTypeEntries = Object.entries(storageTypes);
454
- if (storageTypeEntries.length > 0) {
455
- const typeNodes = [];
456
- for (const [typeName, typeInstance] of storageTypeEntries) {
457
- let typeIssues;
458
- if (isPostgresEnumStorageEntry(typeInstance)) typeIssues = verifyEnumType({
452
+ const typeNodes = [];
453
+ const pushTypeNode = (typeName, contractPath, typeIssues) => {
454
+ if (typeIssues.length > 0) issues.push(...typeIssues);
455
+ typeNodes.push({
456
+ status: typeIssues.length > 0 ? "fail" : "pass",
457
+ kind: "storageType",
458
+ name: `type ${typeName}`,
459
+ contractPath,
460
+ code: typeIssues.length > 0 ? typeIssues[0]?.kind ?? "" : "",
461
+ message: typeIssues.length > 0 ? `${typeIssues.length} issue${typeIssues.length === 1 ? "" : "s"}` : "",
462
+ expected: void 0,
463
+ actual: void 0,
464
+ children: []
465
+ });
466
+ };
467
+ for (const [typeName, typeInstance] of Object.entries(contract.storage.types ?? {})) if (isPostgresEnumStorageEntry(typeInstance)) pushTypeNode(typeName, `storage.types.${typeName}`, verifyEnumType({
468
+ typeName,
469
+ typeInstance,
470
+ schema,
471
+ resolveExistingEnumValues,
472
+ namespaceId: UNBOUND_NAMESPACE_ID
473
+ }));
474
+ else if (isStorageTypeInstance(typeInstance)) {
475
+ const hook = codecHooks.get(typeInstance.codecId);
476
+ pushTypeNode(typeName, `storage.types.${typeName}`, hook?.verifyType ? hook.verifyType({
477
+ typeName,
478
+ typeInstance,
479
+ schema
480
+ }) : []);
481
+ }
482
+ for (const nsId of Object.keys(contract.storage.namespaces)) {
483
+ const ns = contract.storage.namespaces[nsId];
484
+ if (!ns) continue;
485
+ const nsEnums = ns.enum;
486
+ if (!nsEnums) continue;
487
+ for (const [typeName, entry] of Object.entries(nsEnums)) {
488
+ if (!isPostgresEnumStorageEntry(entry)) continue;
489
+ pushTypeNode(typeName, `storage.namespaces.${nsId}.enum.${typeName}`, verifyEnumType({
459
490
  typeName,
460
- typeInstance,
491
+ typeInstance: entry,
461
492
  schema,
462
- resolveExistingEnumValues
463
- });
464
- else if (isStorageTypeInstance(typeInstance)) {
465
- const hook = codecHooks.get(typeInstance.codecId);
466
- typeIssues = hook?.verifyType ? hook.verifyType({
467
- typeName,
468
- typeInstance,
469
- schema
470
- }) : [];
471
- } else typeIssues = [];
472
- if (typeIssues.length > 0) issues.push(...typeIssues);
473
- const typeStatus = typeIssues.length > 0 ? "fail" : "pass";
474
- const typeCode = typeIssues.length > 0 ? typeIssues[0]?.kind ?? "" : "";
475
- typeNodes.push({
476
- status: typeStatus,
477
- kind: "storageType",
478
- name: `type ${typeName}`,
479
- contractPath: `storage.types.${typeName}`,
480
- code: typeCode,
481
- message: typeIssues.length > 0 ? `${typeIssues.length} issue${typeIssues.length === 1 ? "" : "s"}` : "",
482
- expected: void 0,
483
- actual: void 0,
484
- children: []
485
- });
493
+ resolveExistingEnumValues,
494
+ namespaceId: nsId
495
+ }));
486
496
  }
497
+ }
498
+ if (typeNodes.length > 0) {
487
499
  const typesStatus = typeNodes.some((n) => n.status === "fail") ? "fail" : "pass";
488
500
  rootChildren.push({
489
501
  status: typesStatus,
@@ -537,12 +549,13 @@ function verifySqlSchema(options) {
537
549
  * is no other way for the family layer to learn about live enum types.
538
550
  */
539
551
  function verifyEnumType(options) {
540
- const { typeName, typeInstance, schema, resolveExistingEnumValues } = options;
552
+ const { typeName, typeInstance, schema, namespaceId, resolveExistingEnumValues } = options;
541
553
  const desired = typeInstance.values;
542
- const existing = resolveExistingEnumValues?.(schema, typeInstance) ?? null;
554
+ const existing = resolveExistingEnumValues?.(schema, typeInstance, namespaceId) ?? null;
543
555
  if (!existing) return [{
544
556
  kind: "type_missing",
545
557
  typeName,
558
+ namespaceId,
546
559
  message: `Type "${typeName}" is missing from database`
547
560
  }];
548
561
  if (arraysEqual(existing, desired)) return [];
@@ -552,6 +565,7 @@ function verifyEnumType(options) {
552
565
  const removedValues = existing.filter((v) => !desiredSet.has(v));
553
566
  return [{
554
567
  kind: "enum_values_changed",
568
+ namespaceId,
555
569
  typeName,
556
570
  addedValues,
557
571
  removedValues,
@@ -1140,4 +1154,4 @@ function formatLiteralValue(value) {
1140
1154
  //#endregion
1141
1155
  export { extractCodecControlHooks as a, isUniqueConstraintSatisfied as i, arraysEqual as n, isIndexSatisfied as r, verifySqlSchema as t };
1142
1156
 
1143
- //# sourceMappingURL=verify-sql-schema-DcP55TWb.mjs.map
1157
+ //# sourceMappingURL=verify-sql-schema-CYLsGCFO.mjs.map