@prisma-next/contract 0.7.0 → 0.8.0-dev.2

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.
@@ -133,20 +133,26 @@ function orderTopLevel(obj) {
133
133
  for (const key of Array.from(remaining).sort()) ordered[key] = obj[key];
134
134
  return ordered;
135
135
  }
136
+ /**
137
+ * Object-form variant of {@link canonicalizeContract}. Exported because the
138
+ * emitter writes the canonical contract through a separate JSON-stringify
139
+ * pass and consumes the structured object directly.
140
+ */
136
141
  function canonicalizeContractToObject(contract, options) {
142
+ const serialized = options.serializeContract(contract);
137
143
  const withDefaultsOmitted = omitDefaults({
138
- ...ifDefined("schemaVersion", options?.schemaVersion),
139
- targetFamily: contract.targetFamily,
140
- target: contract.target,
141
- profileHash: contract.profileHash,
142
- roots: contract.roots,
143
- models: contract.models,
144
- ...ifDefined("valueObjects", contract.valueObjects),
145
- storage: contract.storage,
146
- ...ifDefined("execution", contract.execution),
147
- extensionPacks: contract.extensionPacks,
148
- capabilities: contract.capabilities,
149
- meta: contract.meta
144
+ ...ifDefined("schemaVersion", options.schemaVersion),
145
+ targetFamily: serialized["targetFamily"],
146
+ target: serialized["target"],
147
+ profileHash: serialized["profileHash"],
148
+ roots: serialized["roots"],
149
+ models: serialized["models"],
150
+ ...ifDefined("valueObjects", serialized["valueObjects"]),
151
+ storage: serialized["storage"],
152
+ ...ifDefined("execution", serialized["execution"]),
153
+ extensionPacks: serialized["extensionPacks"],
154
+ capabilities: serialized["capabilities"],
155
+ meta: serialized["meta"]
150
156
  }, []);
151
157
  const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted["storage"]);
152
158
  return orderTopLevel(sortObjectKeys({
@@ -178,7 +184,10 @@ function hashContract(section) {
178
184
  meta: {},
179
185
  profileHash: "",
180
186
  ...section
181
- }, { schemaVersion: SCHEMA_VERSION });
187
+ }, {
188
+ schemaVersion: SCHEMA_VERSION,
189
+ serializeContract: (c) => JSON.parse(JSON.stringify(c))
190
+ });
182
191
  }
183
192
  function computeStorageHash(args) {
184
193
  return sha256(hashContract(args));
@@ -192,4 +201,4 @@ function computeProfileHash(args) {
192
201
  //#endregion
193
202
  export { canonicalizeContractToObject as a, canonicalizeContract as i, computeProfileHash as n, computeStorageHash as r, computeExecutionHash as t };
194
203
 
195
- //# sourceMappingURL=hashing-Dz-16T7H.mjs.map
204
+ //# sourceMappingURL=hashing-JryrY8ZF.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hashing-JryrY8ZF.mjs","names":[],"sources":["../src/canonicalization.ts","../src/hashing.ts"],"sourcesContent":["import { isArrayEqual } from '@prisma-next/utils/array-equal';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { JsonObject } from '@prisma-next/utils/json';\n\nimport type { Contract } from './contract-types';\n\n/**\n * Per-target contract serializer hook. The framework canonicalizer uses\n * this to convert an in-memory contract (which may carry class-instance\n * IR nodes whose runtime-only fields must not appear in the on-disk\n * envelope) into a plain JsonObject before applying the family-agnostic\n * canonical-key ordering / default-omission / sort steps. Targets whose\n * contract is JSON-clean by construction return the contract unchanged.\n */\nexport type SerializeContract = (contract: Contract) => JsonObject;\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'profileHash',\n 'roots',\n 'models',\n 'valueObjects',\n 'storage',\n 'execution',\n 'capabilities',\n 'extensionPacks',\n 'meta',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(obj: unknown, path: readonly string[]): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if ((key === 'onDelete' || key === 'onUpdate') && value === 'noAction') {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredModels = isArrayEqual(currentPath, ['models']);\n const isRequiredTables = isArrayEqual(currentPath, ['storage', 'tables']);\n const isRequiredCollections = isArrayEqual(currentPath, ['storage', 'collections']);\n const isCollectionEntry =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[1]], ['storage', 'collections']);\n const isRequiredRoots = isArrayEqual(currentPath, ['roots']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredExecutionDefaults = isArrayEqual(currentPath, [\n 'execution',\n 'mutations',\n 'defaults',\n ]);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'relations']);\n const isModelStorage =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'storage']);\n const isTableUniques =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'uniques'],\n );\n const isTableIndexes =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'indexes'],\n );\n const isTableForeignKeys =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'foreignKeys'],\n );\n\n // `storage.types.<name>.typeParams` is part of the StorageTypeInstance\n // shape (validators require it). Preserve it even when empty so the\n // emitted contract.json remains structurally valid after a round-trip.\n const isStorageTypeTypeParams =\n currentPath.length === 4 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'types' &&\n key === 'typeParams';\n\n const isFkBooleanField =\n currentPath.length === 5 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'tables' &&\n currentPath[3] === 'foreignKeys' &&\n (key === 'constraint' || key === 'index');\n\n const isNullableField = key === 'nullable';\n\n if (\n !isRequiredModels &&\n !isRequiredTables &&\n !isRequiredCollections &&\n !isCollectionEntry &&\n !isRequiredRoots &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredExecutionDefaults &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isModelStorage &&\n !isTableUniques &&\n !isTableIndexes &&\n !isTableForeignKeys &&\n !isFkBooleanField &&\n !isNullableField &&\n !isStorageTypeTypeParams\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\ntype StorageObject = {\n tables?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\ntype TableObject = {\n indexes?: unknown[];\n uniques?: unknown[];\n [key: string]: unknown;\n};\n\nfunction sortIndexesAndUniques(storage: unknown): unknown {\n if (!storage || typeof storage !== 'object') {\n return storage;\n }\n\n const storageObj = storage as StorageObject;\n if (!storageObj.tables || typeof storageObj.tables !== 'object') {\n return storage;\n }\n\n const tables = storageObj.tables;\n const result: StorageObject = { ...storageObj };\n\n result.tables = {};\n const sortedTableNames = Object.keys(tables).sort();\n for (const tableName of sortedTableNames) {\n const table = tables[tableName];\n if (!table || typeof table !== 'object') {\n result.tables[tableName] = table;\n continue;\n }\n\n const tableObj = table as TableObject;\n const sortedTable: TableObject = { ...tableObj };\n\n if (Array.isArray(tableObj.indexes)) {\n sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n if (Array.isArray(tableObj.uniques)) {\n sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n result.tables[tableName] = sortedTable;\n }\n\n return result;\n}\n\nexport function orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport interface CanonicalizeContractOptions {\n readonly schemaVersion?: string;\n /**\n * Per-target hook that converts the in-memory contract (which may\n * carry class-instance IR nodes) into a plain JsonObject before the\n * family-agnostic canonicalization steps run.\n *\n * Routing through the hook is what lets each target decide which\n * fields appear in the on-disk envelope; runtime-only class API\n * fields stay invisible to the canonicalization walk by virtue of\n * the per-target serializer not putting them in the JSON shape.\n */\n readonly serializeContract: SerializeContract;\n}\n\n/**\n * Object-form variant of {@link canonicalizeContract}. Exported because the\n * emitter writes the canonical contract through a separate JSON-stringify\n * pass and consumes the structured object directly.\n */\nexport function canonicalizeContractToObject(\n contract: Contract,\n options: CanonicalizeContractOptions,\n): Record<string, unknown> {\n const serialized = options.serializeContract(contract);\n const normalized: Record<string, unknown> = {\n ...ifDefined('schemaVersion', options.schemaVersion),\n targetFamily: serialized['targetFamily'],\n target: serialized['target'],\n profileHash: serialized['profileHash'],\n roots: serialized['roots'],\n models: serialized['models'],\n ...ifDefined('valueObjects', serialized['valueObjects']),\n storage: serialized['storage'],\n ...ifDefined('execution', serialized['execution']),\n extensionPacks: serialized['extensionPacks'],\n capabilities: serialized['capabilities'],\n meta: serialized['meta'],\n };\n const withDefaultsOmitted = omitDefaults(normalized, []) as Record<string, unknown>;\n const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted['storage']);\n const withSortedStorage = { ...withDefaultsOmitted, storage: withSortedIndexes };\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n return orderTopLevel(withSortedKeys);\n}\n\nexport function canonicalizeContract(\n contract: Contract,\n options: CanonicalizeContractOptions,\n): string {\n return JSON.stringify(canonicalizeContractToObject(contract, options), null, 2);\n}\n","import { createHash } from 'node:crypto';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport { canonicalizeContract } from './canonicalization';\nimport type { Contract } from './contract-types';\nimport type { ExecutionHashBase, ProfileHashBase, StorageHashBase } from './types';\n\nconst SCHEMA_VERSION = '1';\n\nfunction sha256(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\nfunction hashContract(section: Record<string, unknown>): string {\n const contract = {\n targetFamily: section['targetFamily'],\n target: section['target'],\n roots: {},\n models: {},\n storage: section['storage'] ?? {},\n execution: section['execution'],\n extensionPacks: {},\n capabilities: section['capabilities'] ?? {},\n meta: {},\n profileHash: '',\n ...section,\n } as Contract;\n return canonicalizeContract(contract, {\n schemaVersion: SCHEMA_VERSION,\n serializeContract: (c) => JSON.parse(JSON.stringify(c)) as JsonObject,\n });\n}\n\nexport function computeStorageHash(args: {\n target: string;\n targetFamily: string;\n storage: Record<string, unknown>;\n}): StorageHashBase<string> {\n return sha256(hashContract(args)) as StorageHashBase<string>;\n}\n\nexport function computeExecutionHash(args: {\n target: string;\n targetFamily: string;\n execution: Record<string, unknown>;\n}): ExecutionHashBase<string> {\n return sha256(hashContract(args)) as ExecutionHashBase<string>;\n}\n\nexport function computeProfileHash(args: {\n target: string;\n targetFamily: string;\n capabilities: Record<string, Record<string, boolean>>;\n}): ProfileHashBase<string> {\n return sha256(hashContract(args)) as ProfileHashBase<string>;\n}\n"],"mappings":"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"}
@@ -1,12 +1,37 @@
1
1
  import { S as ProfileHashBase, T as StorageHashBase, d as ExecutionHashBase, t as Contract } from "./contract-types-Kl86EaEa.mjs";
2
+ import { JsonObject } from "@prisma-next/utils/json";
2
3
 
3
4
  //#region src/canonicalization.d.ts
4
- declare function canonicalizeContractToObject(contract: Contract, options?: {
5
- schemaVersion?: string;
6
- }): Record<string, unknown>;
7
- declare function canonicalizeContract(contract: Contract, options?: {
8
- schemaVersion?: string;
9
- }): string;
5
+ /**
6
+ * Per-target contract serializer hook. The framework canonicalizer uses
7
+ * this to convert an in-memory contract (which may carry class-instance
8
+ * IR nodes whose runtime-only fields must not appear in the on-disk
9
+ * envelope) into a plain JsonObject before applying the family-agnostic
10
+ * canonical-key ordering / default-omission / sort steps. Targets whose
11
+ * contract is JSON-clean by construction return the contract unchanged.
12
+ */
13
+ type SerializeContract = (contract: Contract) => JsonObject;
14
+ interface CanonicalizeContractOptions {
15
+ readonly schemaVersion?: string;
16
+ /**
17
+ * Per-target hook that converts the in-memory contract (which may
18
+ * carry class-instance IR nodes) into a plain JsonObject before the
19
+ * family-agnostic canonicalization steps run.
20
+ *
21
+ * Routing through the hook is what lets each target decide which
22
+ * fields appear in the on-disk envelope; runtime-only class API
23
+ * fields stay invisible to the canonicalization walk by virtue of
24
+ * the per-target serializer not putting them in the JSON shape.
25
+ */
26
+ readonly serializeContract: SerializeContract;
27
+ }
28
+ /**
29
+ * Object-form variant of {@link canonicalizeContract}. Exported because the
30
+ * emitter writes the canonical contract through a separate JSON-stringify
31
+ * pass and consumes the structured object directly.
32
+ */
33
+ declare function canonicalizeContractToObject(contract: Contract, options: CanonicalizeContractOptions): Record<string, unknown>;
34
+ declare function canonicalizeContract(contract: Contract, options: CanonicalizeContractOptions): string;
10
35
  //#endregion
11
36
  //#region src/hashing.d.ts
12
37
  declare function computeStorageHash(args: {
@@ -25,5 +50,5 @@ declare function computeProfileHash(args: {
25
50
  capabilities: Record<string, Record<string, boolean>>;
26
51
  }): ProfileHashBase<string>;
27
52
  //#endregion
28
- export { canonicalizeContract, canonicalizeContractToObject, computeExecutionHash, computeProfileHash, computeStorageHash };
53
+ export { type CanonicalizeContractOptions, type SerializeContract, canonicalizeContract, canonicalizeContractToObject, computeExecutionHash, computeProfileHash, computeStorageHash };
29
54
  //# sourceMappingURL=hashing.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"hashing.d.mts","names":[],"sources":["../src/canonicalization.ts","../src/hashing.ts"],"mappings":";;;iBAkPgB,4BAAA,CACd,QAAA,EAAU,QAAA,EACV,OAAA;EAAY,aAAA;AAAA,IACX,MAAA;AAAA,iBAsBa,oBAAA,CACd,QAAA,EAAU,QAAA,EACV,OAAA;EAAY,aAAA;AAAA;;;iBC/OE,kBAAA,CAAmB,IAAA;EACjC,MAAA;EACA,YAAA;EACA,OAAA,EAAS,MAAA;AAAA,IACP,eAAA;AAAA,iBAIY,oBAAA,CAAqB,IAAA;EACnC,MAAA;EACA,YAAA;EACA,SAAA,EAAW,MAAA;AAAA,IACT,iBAAA;AAAA,iBAIY,kBAAA,CAAmB,IAAA;EACjC,MAAA;EACA,YAAA;EACA,YAAA,EAAc,MAAA,SAAe,MAAA;AAAA,IAC3B,eAAA"}
1
+ {"version":3,"file":"hashing.d.mts","names":[],"sources":["../src/canonicalization.ts","../src/hashing.ts"],"mappings":";;;;;;AAcA;;;;;;KAAY,iBAAA,IAAqB,QAAA,EAAU,QAAA,KAAa,UAAA;AAAA,UA+OvC,2BAAA;EAAA,SACN,aAAA;EADiC;;;;;;;;AAoB5C;;EApB4C,SAYjC,iBAAA,EAAmB,iBAAA;AAAA;;;;;;iBAQd,4BAAA,CACd,QAAA,EAAU,QAAA,EACV,OAAA,EAAS,2BAAA,GACR,MAAA;AAAA,iBAuBa,oBAAA,CACd,QAAA,EAAU,QAAA,EACV,OAAA,EAAS,2BAAA;;;iBC3QK,kBAAA,CAAmB,IAAA;EACjC,MAAA;EACA,YAAA;EACA,OAAA,EAAS,MAAA;AAAA,IACP,eAAA;AAAA,iBAIY,oBAAA,CAAqB,IAAA;EACnC,MAAA;EACA,YAAA;EACA,SAAA,EAAW,MAAA;AAAA,IACT,iBAAA;AAAA,iBAIY,kBAAA,CAAmB,IAAA;EACjC,MAAA;EACA,YAAA;EACA,YAAA,EAAc,MAAA,SAAe,MAAA;AAAA,IAC3B,eAAA"}
package/dist/hashing.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { a as canonicalizeContractToObject, i as canonicalizeContract, n as computeProfileHash, r as computeStorageHash, t as computeExecutionHash } from "./hashing-Dz-16T7H.mjs";
1
+ import { a as canonicalizeContractToObject, i as canonicalizeContract, n as computeProfileHash, r as computeStorageHash, t as computeExecutionHash } from "./hashing-JryrY8ZF.mjs";
2
2
  export { canonicalizeContract, canonicalizeContractToObject, computeExecutionHash, computeProfileHash, computeStorageHash };
package/dist/testing.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { t as coreHash } from "./types-CVGwkRLa.mjs";
2
- import { n as computeProfileHash, r as computeStorageHash, t as computeExecutionHash } from "./hashing-Dz-16T7H.mjs";
2
+ import { n as computeProfileHash, r as computeStorageHash, t as computeExecutionHash } from "./hashing-JryrY8ZF.mjs";
3
3
  import { ifDefined } from "@prisma-next/utils/defined";
4
4
  //#region src/testing-factories.ts
5
5
  const DUMMY_HASH = coreHash("sha256:test");
package/package.json CHANGED
@@ -1,22 +1,22 @@
1
1
  {
2
2
  "name": "@prisma-next/contract",
3
- "version": "0.7.0",
3
+ "version": "0.8.0-dev.2",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "Data contract type definitions and JSON schema for Prisma Next",
8
8
  "dependencies": {
9
+ "@prisma-next/utils": "0.8.0-dev.2",
9
10
  "@standard-schema/spec": "^1.1.0",
10
- "arktype": "^2.1.29",
11
- "@prisma-next/utils": "0.7.0"
11
+ "arktype": "^2.1.29"
12
12
  },
13
13
  "devDependencies": {
14
+ "@prisma-next/test-utils": "0.8.0-dev.2",
15
+ "@prisma-next/tsconfig": "0.8.0-dev.2",
16
+ "@prisma-next/tsdown": "0.8.0-dev.2",
14
17
  "tsdown": "0.22.0",
15
18
  "typescript": "5.9.3",
16
- "vitest": "4.1.5",
17
- "@prisma-next/test-utils": "0.7.0",
18
- "@prisma-next/tsconfig": "0.7.0",
19
- "@prisma-next/tsdown": "0.7.0"
19
+ "vitest": "4.1.5"
20
20
  },
21
21
  "files": [
22
22
  "dist",
@@ -1,8 +1,19 @@
1
1
  import { isArrayEqual } from '@prisma-next/utils/array-equal';
2
2
  import { ifDefined } from '@prisma-next/utils/defined';
3
+ import type { JsonObject } from '@prisma-next/utils/json';
3
4
 
4
5
  import type { Contract } from './contract-types';
5
6
 
7
+ /**
8
+ * Per-target contract serializer hook. The framework canonicalizer uses
9
+ * this to convert an in-memory contract (which may carry class-instance
10
+ * IR nodes whose runtime-only fields must not appear in the on-disk
11
+ * envelope) into a plain JsonObject before applying the family-agnostic
12
+ * canonical-key ordering / default-omission / sort steps. Targets whose
13
+ * contract is JSON-clean by construction return the contract unchanged.
14
+ */
15
+ export type SerializeContract = (contract: Contract) => JsonObject;
16
+
6
17
  const TOP_LEVEL_ORDER = [
7
18
  'schemaVersion',
8
19
  'canonicalVersion',
@@ -240,23 +251,44 @@ export function orderTopLevel(obj: Record<string, unknown>): Record<string, unkn
240
251
  return ordered;
241
252
  }
242
253
 
254
+ export interface CanonicalizeContractOptions {
255
+ readonly schemaVersion?: string;
256
+ /**
257
+ * Per-target hook that converts the in-memory contract (which may
258
+ * carry class-instance IR nodes) into a plain JsonObject before the
259
+ * family-agnostic canonicalization steps run.
260
+ *
261
+ * Routing through the hook is what lets each target decide which
262
+ * fields appear in the on-disk envelope; runtime-only class API
263
+ * fields stay invisible to the canonicalization walk by virtue of
264
+ * the per-target serializer not putting them in the JSON shape.
265
+ */
266
+ readonly serializeContract: SerializeContract;
267
+ }
268
+
269
+ /**
270
+ * Object-form variant of {@link canonicalizeContract}. Exported because the
271
+ * emitter writes the canonical contract through a separate JSON-stringify
272
+ * pass and consumes the structured object directly.
273
+ */
243
274
  export function canonicalizeContractToObject(
244
275
  contract: Contract,
245
- options?: { schemaVersion?: string },
276
+ options: CanonicalizeContractOptions,
246
277
  ): Record<string, unknown> {
278
+ const serialized = options.serializeContract(contract);
247
279
  const normalized: Record<string, unknown> = {
248
- ...ifDefined('schemaVersion', options?.schemaVersion),
249
- targetFamily: contract.targetFamily,
250
- target: contract.target,
251
- profileHash: contract.profileHash,
252
- roots: contract.roots,
253
- models: contract.models,
254
- ...ifDefined('valueObjects', contract.valueObjects),
255
- storage: contract.storage,
256
- ...ifDefined('execution', contract.execution),
257
- extensionPacks: contract.extensionPacks,
258
- capabilities: contract.capabilities,
259
- meta: contract.meta,
280
+ ...ifDefined('schemaVersion', options.schemaVersion),
281
+ targetFamily: serialized['targetFamily'],
282
+ target: serialized['target'],
283
+ profileHash: serialized['profileHash'],
284
+ roots: serialized['roots'],
285
+ models: serialized['models'],
286
+ ...ifDefined('valueObjects', serialized['valueObjects']),
287
+ storage: serialized['storage'],
288
+ ...ifDefined('execution', serialized['execution']),
289
+ extensionPacks: serialized['extensionPacks'],
290
+ capabilities: serialized['capabilities'],
291
+ meta: serialized['meta'],
260
292
  };
261
293
  const withDefaultsOmitted = omitDefaults(normalized, []) as Record<string, unknown>;
262
294
  const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted['storage']);
@@ -267,7 +299,7 @@ export function canonicalizeContractToObject(
267
299
 
268
300
  export function canonicalizeContract(
269
301
  contract: Contract,
270
- options?: { schemaVersion?: string },
302
+ options: CanonicalizeContractOptions,
271
303
  ): string {
272
304
  return JSON.stringify(canonicalizeContractToObject(contract, options), null, 2);
273
305
  }
@@ -1,2 +1,7 @@
1
- export { canonicalizeContract, canonicalizeContractToObject } from '../canonicalization';
1
+ export {
2
+ type CanonicalizeContractOptions,
3
+ canonicalizeContract,
4
+ canonicalizeContractToObject,
5
+ type SerializeContract,
6
+ } from '../canonicalization';
2
7
  export { computeExecutionHash, computeProfileHash, computeStorageHash } from '../hashing';
@@ -2,5 +2,10 @@ export {
2
2
  ContractValidationError,
3
3
  type ContractValidationPhase,
4
4
  type StorageValidator,
5
+ // Framework-internal structural-validation primitive. Not part of the
6
+ // user-facing surface (consumers go through descriptor.contractSerializer);
7
+ // re-exported here so foundation-package consumers (e.g. sql-contract's
8
+ // codec-aware decode wrapper, which backs the SPI's optional decoding
9
+ // path) can compose it.
5
10
  validateContract,
6
11
  } from '../validate-contract';
package/src/hashing.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { createHash } from 'node:crypto';
2
+ import type { JsonObject } from '@prisma-next/utils/json';
2
3
  import { canonicalizeContract } from './canonicalization';
3
4
  import type { Contract } from './contract-types';
4
5
  import type { ExecutionHashBase, ProfileHashBase, StorageHashBase } from './types';
@@ -25,7 +26,10 @@ function hashContract(section: Record<string, unknown>): string {
25
26
  profileHash: '',
26
27
  ...section,
27
28
  } as Contract;
28
- return canonicalizeContract(contract, { schemaVersion: SCHEMA_VERSION });
29
+ return canonicalizeContract(contract, {
30
+ schemaVersion: SCHEMA_VERSION,
31
+ serializeContract: (c) => JSON.parse(JSON.stringify(c)) as JsonObject,
32
+ });
29
33
  }
30
34
 
31
35
  export function computeStorageHash(args: {
@@ -1 +0,0 @@
1
- {"version":3,"file":"hashing-Dz-16T7H.mjs","names":[],"sources":["../src/canonicalization.ts","../src/hashing.ts"],"sourcesContent":["import { isArrayEqual } from '@prisma-next/utils/array-equal';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\nimport type { Contract } from './contract-types';\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'profileHash',\n 'roots',\n 'models',\n 'valueObjects',\n 'storage',\n 'execution',\n 'capabilities',\n 'extensionPacks',\n 'meta',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(obj: unknown, path: readonly string[]): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n if ((key === 'onDelete' || key === 'onUpdate') && value === 'noAction') {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredModels = isArrayEqual(currentPath, ['models']);\n const isRequiredTables = isArrayEqual(currentPath, ['storage', 'tables']);\n const isRequiredCollections = isArrayEqual(currentPath, ['storage', 'collections']);\n const isCollectionEntry =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[1]], ['storage', 'collections']);\n const isRequiredRoots = isArrayEqual(currentPath, ['roots']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredExecutionDefaults = isArrayEqual(currentPath, [\n 'execution',\n 'mutations',\n 'defaults',\n ]);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'relations']);\n const isModelStorage =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'storage']);\n const isTableUniques =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'uniques'],\n );\n const isTableIndexes =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'indexes'],\n );\n const isTableForeignKeys =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'foreignKeys'],\n );\n\n // `storage.types.<name>.typeParams` is part of the StorageTypeInstance\n // shape (validators require it). Preserve it even when empty so the\n // emitted contract.json remains structurally valid after a round-trip.\n const isStorageTypeTypeParams =\n currentPath.length === 4 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'types' &&\n key === 'typeParams';\n\n const isFkBooleanField =\n currentPath.length === 5 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'tables' &&\n currentPath[3] === 'foreignKeys' &&\n (key === 'constraint' || key === 'index');\n\n const isNullableField = key === 'nullable';\n\n if (\n !isRequiredModels &&\n !isRequiredTables &&\n !isRequiredCollections &&\n !isCollectionEntry &&\n !isRequiredRoots &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredExecutionDefaults &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isModelStorage &&\n !isTableUniques &&\n !isTableIndexes &&\n !isTableForeignKeys &&\n !isFkBooleanField &&\n !isNullableField &&\n !isStorageTypeTypeParams\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\ntype StorageObject = {\n tables?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\ntype TableObject = {\n indexes?: unknown[];\n uniques?: unknown[];\n [key: string]: unknown;\n};\n\nfunction sortIndexesAndUniques(storage: unknown): unknown {\n if (!storage || typeof storage !== 'object') {\n return storage;\n }\n\n const storageObj = storage as StorageObject;\n if (!storageObj.tables || typeof storageObj.tables !== 'object') {\n return storage;\n }\n\n const tables = storageObj.tables;\n const result: StorageObject = { ...storageObj };\n\n result.tables = {};\n const sortedTableNames = Object.keys(tables).sort();\n for (const tableName of sortedTableNames) {\n const table = tables[tableName];\n if (!table || typeof table !== 'object') {\n result.tables[tableName] = table;\n continue;\n }\n\n const tableObj = table as TableObject;\n const sortedTable: TableObject = { ...tableObj };\n\n if (Array.isArray(tableObj.indexes)) {\n sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n if (Array.isArray(tableObj.uniques)) {\n sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n result.tables[tableName] = sortedTable;\n }\n\n return result;\n}\n\nexport function orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport function canonicalizeContractToObject(\n contract: Contract,\n options?: { schemaVersion?: string },\n): Record<string, unknown> {\n const normalized: Record<string, unknown> = {\n ...ifDefined('schemaVersion', options?.schemaVersion),\n targetFamily: contract.targetFamily,\n target: contract.target,\n profileHash: contract.profileHash,\n roots: contract.roots,\n models: contract.models,\n ...ifDefined('valueObjects', contract.valueObjects),\n storage: contract.storage,\n ...ifDefined('execution', contract.execution),\n extensionPacks: contract.extensionPacks,\n capabilities: contract.capabilities,\n meta: contract.meta,\n };\n const withDefaultsOmitted = omitDefaults(normalized, []) as Record<string, unknown>;\n const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted['storage']);\n const withSortedStorage = { ...withDefaultsOmitted, storage: withSortedIndexes };\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n return orderTopLevel(withSortedKeys);\n}\n\nexport function canonicalizeContract(\n contract: Contract,\n options?: { schemaVersion?: string },\n): string {\n return JSON.stringify(canonicalizeContractToObject(contract, options), null, 2);\n}\n","import { createHash } from 'node:crypto';\nimport { canonicalizeContract } from './canonicalization';\nimport type { Contract } from './contract-types';\nimport type { ExecutionHashBase, ProfileHashBase, StorageHashBase } from './types';\n\nconst SCHEMA_VERSION = '1';\n\nfunction sha256(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\nfunction hashContract(section: Record<string, unknown>): string {\n const contract = {\n targetFamily: section['targetFamily'],\n target: section['target'],\n roots: {},\n models: {},\n storage: section['storage'] ?? {},\n execution: section['execution'],\n extensionPacks: {},\n capabilities: section['capabilities'] ?? {},\n meta: {},\n profileHash: '',\n ...section,\n } as Contract;\n return canonicalizeContract(contract, { schemaVersion: SCHEMA_VERSION });\n}\n\nexport function computeStorageHash(args: {\n target: string;\n targetFamily: string;\n storage: Record<string, unknown>;\n}): StorageHashBase<string> {\n return sha256(hashContract(args)) as StorageHashBase<string>;\n}\n\nexport function computeExecutionHash(args: {\n target: string;\n targetFamily: string;\n execution: Record<string, unknown>;\n}): ExecutionHashBase<string> {\n return sha256(hashContract(args)) as ExecutionHashBase<string>;\n}\n\nexport function computeProfileHash(args: {\n target: string;\n targetFamily: string;\n capabilities: Record<string, Record<string, boolean>>;\n}): ProfileHashBase<string> {\n return sha256(hashContract(args)) as ProfileHashBase<string>;\n}\n"],"mappings":"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"}