@prisma-next/family-sql 0.14.0-dev.46 → 0.14.0-dev.48

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/control.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  import { i as sqlFamilyPslBlockDescriptors, n as sqlFamilyAuthoringFieldPresets, r as sqlFamilyEntityTypes, t as sqlFamilyAuthoringTypes } from "./authoring-type-constructors-CXd-8ydc.mjs";
2
- import { t as SqlContractSerializer } from "./sql-contract-serializer-CYtXg_zs.mjs";
2
+ import { t as SqlContractSerializer } from "./sql-contract-serializer-DwUSJ4PO.mjs";
3
3
  import { t as collectSupportedCodecTypeIds } from "./verify-C-G0obRm.mjs";
4
4
  import { a as extractCodecControlHooks, i as resolveValueSetValues, n as contractToSchemaIR, r as detectDestructiveChanges, t as contractNamespaceToSchemaIR } from "./contract-to-schema-ir-S-evq8E6.mjs";
5
5
  import { n as temporalAuthoringPresets, r as timestampNowControlDescriptor } from "./timestamp-now-generator-CloimujU.mjs";
package/dist/ir.d.mts CHANGED
@@ -45,6 +45,20 @@ declare abstract class SqlContractSerializerBase<TContract extends Contract<SqlS
45
45
  protected hydrateSqlNamespaceEntry(nsId: string, raw: Record<string, unknown>): Namespace | SqlNamespaceInput;
46
46
  protected hydrateStorageTypeEntry(entry: SqlStorageTypeEntry): SqlStorageTypeEntry;
47
47
  protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract;
48
+ /**
49
+ * Serializes a namespace's `entries` dict by walking every enumerable
50
+ * kind — no kind is named here, mirroring the generic hydrate walk in
51
+ * `hydrateSqlNamespaceEntry` above. `table` is the SQL family's one
52
+ * universal base kind (every namespace carries it), so it is always
53
+ * emitted, even when empty; every other kind — target- or
54
+ * pack-contributed — is emitted only when it holds at least one entry.
55
+ * A kind carried non-enumerable on `entries` is excluded here for free,
56
+ * since `Object.entries` honors enumerability.
57
+ */
58
+ protected serializeNamespaceEntries(entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>): Record<string, Record<string, JsonObject>>;
59
+ private serializeEntries;
60
+ protected serializeJsonObject(value: unknown): JsonObject;
61
+ private serializeJsonValue;
48
62
  }
49
63
  //#endregion
50
64
  //#region src/core/ir/sql-contract-serializer.d.ts
package/dist/ir.d.mts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"ir.d.mts","names":[],"sources":["../src/core/ir/sql-contract-serializer-base.ts","../src/core/ir/sql-contract-serializer.ts","../src/core/ir/sql-schema-verifier-base.ts"],"mappings":";;;;;;;KAmCY,yBAAA,IAA6B,KAAc;;AAAvD;;;;AAAuD;AA0BvD;;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,mBAMT,uBAAA,EAAyB,WAAA,SAE1C,yBAAA;EAAA,iBANa,cAAA;EAAA,iBACA,UAAA;cAGI,uBAAA,GAAyB,WAAA,SAE1C,yBAAA,GAEF,eAAA,YAA0B,uBAAA;EAO5B,mBAAA,WAA8B,SAAA,GAAY,SAAA,EAAW,IAAA,YAAgB,CAAA;EAMrE,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAIxC,mBAAA,0CAAmB,sBAAA;EAEnB,WAAA,0CAAW,WAAA;EAAA,UAED,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EAAA,UAOnD,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EAAA,UAuC7D,sBAAA,CACR,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,MAAA,sBACnC,QAAA,CAAS,MAAA,SAAe,SAAA;EAAA,UAcjB,wBAAA,CACR,IAAA,UACA,GAAA,EAAK,MAAA,oBACJ,SAAA,GAAY,iBAAA;EAAA,UA+BL,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAAA,UAkBrD,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;AAAA;;;;;;;AA5KrE;;;;AAAuD;AA0BvD;;;;;cC3Ca,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;;;;;;;;;;ADiB9E;;;;AAAuD;AA0BvD;;;;;;;;;uBElCsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EFiDlC;;;;;;EAAA,mBEpCX,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;EFuDoC;;;;;EAAA,mBEhD7B,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":";;;;;;;KAmCY,yBAAA,IAA6B,KAAc;;AAAvD;;;;AAAuD;AA0BvD;;;;;;;;;;;;;;;;;;uBAAsB,yBAAA,mBAA4C,QAAA,CAAS,UAAA,cAC9D,kBAAA,CAAmB,SAAA;EAAA,mBAMT,uBAAA,EAAyB,WAAA,SAE1C,yBAAA;EAAA,iBANa,cAAA;EAAA,iBACA,UAAA;cAGI,uBAAA,GAAyB,WAAA,SAE1C,yBAAA,GAEF,eAAA,YAA0B,uBAAA;EAO5B,mBAAA,WAA8B,SAAA,GAAY,SAAA,EAAW,IAAA,YAAgB,CAAA;EAMrE,iBAAA,CAAkB,QAAA,EAAU,SAAA,GAAY,UAAA;EAIxC,mBAAA,0CAAmB,sBAAA;EAEnB,WAAA,0CAAW,WAAA;EAAA,UAED,yBAAA,CAA0B,IAAA,YAAgB,QAAA,CAAS,UAAA;EAAA,UAOnD,iBAAA,CAAkB,SAAA,EAAW,QAAA,CAAS,UAAA,IAAc,QAAA,CAAS,UAAA;EAAA,UAuC7D,sBAAA,CACR,UAAA,EAAY,QAAA,CAAS,MAAA,SAAe,MAAA,sBACnC,QAAA,CAAS,MAAA,SAAe,SAAA;EAAA,UAcjB,wBAAA,CACR,IAAA,UACA,GAAA,EAAK,MAAA,oBACJ,SAAA,GAAY,iBAAA;EAAA,UA+BL,uBAAA,CAAwB,KAAA,EAAO,mBAAA,GAAsB,mBAAA;EAAA,UAkBrD,uBAAA,CAAwB,QAAA,EAAU,QAAA,CAAS,UAAA,IAAc,SAAA;EAAd;;;;;;;;;;EAAA,UAc3C,yBAAA,CACR,OAAA,EAAS,QAAA,CAAS,MAAA,SAAe,QAAA,CAAS,MAAA,uBACzC,MAAA,SAAe,MAAA,SAAe,UAAA;EAAA,QAazB,gBAAA;EAAA,UAQE,mBAAA,CAAoB,KAAA,YAAiB,UAAA;EAAA,QAOvC,kBAAA;AAAA;;;;;;;AAxNV;;;;AAAuD;AA0BvD;;;;;cC3Ca,qBAAA,SAA8B,yBAAA,CAA0B,QAAA,CAAS,UAAA;;;;;;;;;;;ADiB9E;;;;AAAuD;AA0BvD;;;;;;;;;uBElCsB,qBAAA,gCACT,cAAA,CAAe,SAAA,EAAW,OAAA;EAErC,YAAA,CAAa,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,IAAW,kBAAA;EFiDlC;;;;;;EAAA,mBEpCX,qBAAA,CACjB,OAAA,EAAS,mBAAA,CAAoB,SAAA,EAAW,OAAA,aAC9B,WAAA;EFuDoC;;;;;EAAA,mBEhD7B,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-CYtXg_zs.mjs";
1
+ import { n as SqlContractSerializerBase, t as SqlContractSerializer } from "./sql-contract-serializer-DwUSJ4PO.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
@@ -111,6 +111,35 @@ var SqlContractSerializerBase = class {
111
111
  constructTargetContract(hydrated) {
112
112
  return hydrated;
113
113
  }
114
+ /**
115
+ * Serializes a namespace's `entries` dict by walking every enumerable
116
+ * kind — no kind is named here, mirroring the generic hydrate walk in
117
+ * `hydrateSqlNamespaceEntry` above. `table` is the SQL family's one
118
+ * universal base kind (every namespace carries it), so it is always
119
+ * emitted, even when empty; every other kind — target- or
120
+ * pack-contributed — is emitted only when it holds at least one entry.
121
+ * A kind carried non-enumerable on `entries` is excluded here for free,
122
+ * since `Object.entries` honors enumerability.
123
+ */
124
+ serializeNamespaceEntries(entries) {
125
+ const out = { table: this.serializeEntries(entries["table"] ?? {}) };
126
+ for (const [kind, record] of Object.entries(entries)) {
127
+ if (kind === "table" || record == null || Object.keys(record).length === 0) continue;
128
+ out[kind] = this.serializeEntries(record);
129
+ }
130
+ return out;
131
+ }
132
+ serializeEntries(entries) {
133
+ const out = {};
134
+ for (const [name, entry] of Object.entries(entries)) out[name] = this.serializeJsonObject(entry);
135
+ return out;
136
+ }
137
+ serializeJsonObject(value) {
138
+ return blindCast(this.serializeJsonValue(value));
139
+ }
140
+ serializeJsonValue(value) {
141
+ return blindCast(JSON.parse(JSON.stringify(value)));
142
+ }
114
143
  };
115
144
  //#endregion
116
145
  //#region src/core/ir/sql-contract-serializer.ts
@@ -136,4 +165,4 @@ var SqlContractSerializer = class extends SqlContractSerializerBase {
136
165
  //#endregion
137
166
  export { SqlContractSerializerBase as n, SqlContractSerializer as t };
138
167
 
139
- //# sourceMappingURL=sql-contract-serializer-CYtXg_zs.mjs.map
168
+ //# sourceMappingURL=sql-contract-serializer-DwUSJ4PO.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sql-contract-serializer-DwUSJ4PO.mjs","names":["isPlainRecord"],"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 { isPlainRecord } from '@prisma-next/contract/is-plain-record';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { ContractSerializer } from '@prisma-next/framework-components/control';\nimport {\n type AnyEntityKindDescriptor,\n hydrateNamespaceEntities,\n type Namespace,\n} from '@prisma-next/framework-components/ir';\nimport { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';\nimport { composeSqlEntityKinds } from '@prisma-next/sql-contract/entity-kinds';\nimport {\n isMaterializedSqlNamespace,\n type SqlNamespaceInput,\n SqlStorage,\n type SqlStorageInput,\n type SqlStorageTypeEntry,\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, JsonValue } from '@prisma-next/utils/json';\nimport { type Type, type } from 'arktype';\n\nconst NamespaceRawSchema = type({\n id: 'string',\n 'kind?': 'string',\n entries: type({\n '+': 'ignore',\n }),\n});\n\nexport type SqlEntityHydrationFactory = (entry: unknown) => unknown;\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 private readonly entryKinds: ReadonlyMap<string, AnyEntityKindDescriptor>;\n\n constructor(\n protected readonly entityHydrationRegistry: ReadonlyMap<\n string,\n SqlEntityHydrationFactory\n > = new Map(),\n packEntityKinds: readonly AnyEntityKindDescriptor[] = [],\n ) {\n this.entryKinds = composeSqlEntityKinds(packEntityKinds);\n this.contractSchema =\n packEntityKinds.length > 0 ? createSqlContractSchema(this.entryKinds) : 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(\n blindCast<\n Readonly<Record<string, Record<string, unknown>>>,\n 'parseSqlContractStructure validated raw JSON; namespace entries are plain objects, not SqlNamespace instances.'\n >(rawNamespaces),\n );\n\n return {\n ...validated,\n storage: new SqlStorage({\n storageHash: validated.storage.storageHash,\n ...ifDefined('types', hydratedTypes),\n namespaces: blindCast<\n SqlStorageInput['namespaces'],\n 'hydrateSqlNamespaceMap builds each namespace through the target serializer override, so every value is a SqlNamespace; the framework return type only promises the base Namespace.'\n >(hydratedNamespaces),\n }),\n };\n }\n\n protected hydrateSqlNamespaceMap(\n namespaces: Readonly<Record<string, Record<string, unknown>>>,\n ): Readonly<Record<string, Namespace>> {\n return Object.fromEntries(\n Object.entries(namespaces).map(([nsId, namespaceEntryRaw]) => {\n const namespaceHydrated = this.hydrateSqlNamespaceEntry(nsId, namespaceEntryRaw);\n if (!isMaterializedSqlNamespace(namespaceHydrated)) {\n throw new Error(\n `Target serializer bug: hydrateSqlNamespaceEntry for namespace \"${nsId}\" returned a non-NamespaceBase value. Override hydrateSqlNamespaceEntry to produce a target namespace concretion.`,\n );\n }\n return [nsId, namespaceHydrated];\n }),\n );\n }\n\n protected hydrateSqlNamespaceEntry(\n nsId: string,\n raw: Record<string, unknown>,\n ): Namespace | SqlNamespaceInput {\n const id = typeof raw['id'] === 'string' ? raw['id'] : nsId;\n const parsed = NamespaceRawSchema({ ...raw, 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 entriesRaw = parsed.entries;\n const rawEntriesMap = isPlainRecord(entriesRaw) ? entriesRaw : {};\n\n const entriesInput: Record<string, Readonly<Record<string, unknown>>> = {};\n for (const [key, innerMap] of Object.entries(rawEntriesMap)) {\n entriesInput[key] = isPlainRecord(innerMap) ? innerMap : Object.freeze({});\n }\n\n const entriesOutput = hydrateNamespaceEntities(entriesInput, this.entryKinds, 'fail', id);\n\n // Always ensure a 'table' key is present (may be empty).\n if (!Object.hasOwn(entriesOutput, 'table')) {\n entriesOutput['table'] = {};\n }\n\n return blindCast<\n SqlNamespaceInput,\n 'entriesOutput holds the hydrated SQL entity-kind maps (table always present); this wraps them as the SqlNamespaceInput the target createNamespace consumes.'\n >({\n id,\n entries: entriesOutput,\n });\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.entityHydrationRegistry.get(kind);\n if (factory === undefined) {\n return entry;\n }\n return blindCast<\n SqlStorageTypeEntry,\n 'entity registry factory returns SqlStorageTypeEntry for storage.types entries'\n >(factory(entry));\n }\n\n protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract {\n return hydrated as TContract;\n }\n\n /**\n * Serializes a namespace's `entries` dict by walking every enumerable\n * kind — no kind is named here, mirroring the generic hydrate walk in\n * `hydrateSqlNamespaceEntry` above. `table` is the SQL family's one\n * universal base kind (every namespace carries it), so it is always\n * emitted, even when empty; every other kind — target- or\n * pack-contributed — is emitted only when it holds at least one entry.\n * A kind carried non-enumerable on `entries` is excluded here for free,\n * since `Object.entries` honors enumerability.\n */\n protected serializeNamespaceEntries(\n entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>,\n ): Record<string, Record<string, JsonObject>> {\n const out: Record<string, Record<string, JsonObject>> = {\n table: this.serializeEntries(entries['table'] ?? {}),\n };\n for (const [kind, record] of Object.entries(entries)) {\n if (kind === 'table' || record == null || Object.keys(record).length === 0) {\n continue;\n }\n out[kind] = this.serializeEntries(record);\n }\n return out;\n }\n\n private serializeEntries(entries: Readonly<Record<string, unknown>>): Record<string, JsonObject> {\n const out: Record<string, JsonObject> = {};\n for (const [name, entry] of Object.entries(entries)) {\n out[name] = this.serializeJsonObject(entry);\n }\n return out;\n }\n\n protected serializeJsonObject(value: unknown): JsonObject {\n return blindCast<\n JsonObject,\n 'serializeJsonValue round-trips an IR node through JSON, yielding a JsonObject'\n >(this.serializeJsonValue(value));\n }\n\n private serializeJsonValue(value: unknown): JsonValue {\n return blindCast<JsonValue, 'JSON.parse(JSON.stringify(x)) yields a JsonValue'>(\n JSON.parse(JSON.stringify(value)),\n );\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 *\n * Because this serializer has no target concretion, deserialization of\n * contracts that include namespace entries from JSON will throw unless\n * the caller provides pre-hydrated `NamespaceBase` instances. Production\n * paths always supply a target-specific serializer.\n */\nexport class SqlContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor() {\n super(new Map());\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,34 +1,34 @@
1
1
  {
2
2
  "name": "@prisma-next/family-sql",
3
- "version": "0.14.0-dev.46",
3
+ "version": "0.14.0-dev.48",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "SQL family descriptor for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/contract": "0.14.0-dev.46",
10
- "@prisma-next/emitter": "0.14.0-dev.46",
11
- "@prisma-next/framework-components": "0.14.0-dev.46",
12
- "@prisma-next/migration-tools": "0.14.0-dev.46",
13
- "@prisma-next/operations": "0.14.0-dev.46",
14
- "@prisma-next/sql-contract": "0.14.0-dev.46",
15
- "@prisma-next/sql-contract-emitter": "0.14.0-dev.46",
16
- "@prisma-next/sql-contract-ts": "0.14.0-dev.46",
17
- "@prisma-next/sql-operations": "0.14.0-dev.46",
18
- "@prisma-next/sql-relational-core": "0.14.0-dev.46",
19
- "@prisma-next/sql-runtime": "0.14.0-dev.46",
20
- "@prisma-next/sql-schema-ir": "0.14.0-dev.46",
21
- "@prisma-next/utils": "0.14.0-dev.46",
9
+ "@prisma-next/contract": "0.14.0-dev.48",
10
+ "@prisma-next/emitter": "0.14.0-dev.48",
11
+ "@prisma-next/framework-components": "0.14.0-dev.48",
12
+ "@prisma-next/migration-tools": "0.14.0-dev.48",
13
+ "@prisma-next/operations": "0.14.0-dev.48",
14
+ "@prisma-next/sql-contract": "0.14.0-dev.48",
15
+ "@prisma-next/sql-contract-emitter": "0.14.0-dev.48",
16
+ "@prisma-next/sql-contract-ts": "0.14.0-dev.48",
17
+ "@prisma-next/sql-operations": "0.14.0-dev.48",
18
+ "@prisma-next/sql-relational-core": "0.14.0-dev.48",
19
+ "@prisma-next/sql-runtime": "0.14.0-dev.48",
20
+ "@prisma-next/sql-schema-ir": "0.14.0-dev.48",
21
+ "@prisma-next/utils": "0.14.0-dev.48",
22
22
  "arktype": "^2.2.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@prisma-next/driver-postgres": "0.14.0-dev.46",
26
- "@prisma-next/psl-parser": "0.14.0-dev.46",
27
- "@prisma-next/psl-printer": "0.14.0-dev.46",
28
- "@prisma-next/sql-contract-psl": "0.14.0-dev.46",
29
- "@prisma-next/test-utils": "0.14.0-dev.46",
30
- "@prisma-next/tsconfig": "0.14.0-dev.46",
31
- "@prisma-next/tsdown": "0.14.0-dev.46",
25
+ "@prisma-next/driver-postgres": "0.14.0-dev.48",
26
+ "@prisma-next/psl-parser": "0.14.0-dev.48",
27
+ "@prisma-next/psl-printer": "0.14.0-dev.48",
28
+ "@prisma-next/sql-contract-psl": "0.14.0-dev.48",
29
+ "@prisma-next/test-utils": "0.14.0-dev.48",
30
+ "@prisma-next/tsconfig": "0.14.0-dev.48",
31
+ "@prisma-next/tsdown": "0.14.0-dev.48",
32
32
  "tsdown": "0.22.1",
33
33
  "typescript": "5.9.3",
34
34
  "vitest": "4.1.8"
@@ -22,7 +22,7 @@ import {
22
22
  } from '@prisma-next/sql-contract/validators';
23
23
  import { blindCast } from '@prisma-next/utils/casts';
24
24
  import { ifDefined } from '@prisma-next/utils/defined';
25
- import type { JsonObject } from '@prisma-next/utils/json';
25
+ import type { JsonObject, JsonValue } from '@prisma-next/utils/json';
26
26
  import { type Type, type } from 'arktype';
27
27
 
28
28
  const NamespaceRawSchema = type({
@@ -208,4 +208,50 @@ export abstract class SqlContractSerializerBase<TContract extends Contract<SqlSt
208
208
  protected constructTargetContract(hydrated: Contract<SqlStorage>): TContract {
209
209
  return hydrated as TContract;
210
210
  }
211
+
212
+ /**
213
+ * Serializes a namespace's `entries` dict by walking every enumerable
214
+ * kind — no kind is named here, mirroring the generic hydrate walk in
215
+ * `hydrateSqlNamespaceEntry` above. `table` is the SQL family's one
216
+ * universal base kind (every namespace carries it), so it is always
217
+ * emitted, even when empty; every other kind — target- or
218
+ * pack-contributed — is emitted only when it holds at least one entry.
219
+ * A kind carried non-enumerable on `entries` is excluded here for free,
220
+ * since `Object.entries` honors enumerability.
221
+ */
222
+ protected serializeNamespaceEntries(
223
+ entries: Readonly<Record<string, Readonly<Record<string, unknown>>>>,
224
+ ): Record<string, Record<string, JsonObject>> {
225
+ const out: Record<string, Record<string, JsonObject>> = {
226
+ table: this.serializeEntries(entries['table'] ?? {}),
227
+ };
228
+ for (const [kind, record] of Object.entries(entries)) {
229
+ if (kind === 'table' || record == null || Object.keys(record).length === 0) {
230
+ continue;
231
+ }
232
+ out[kind] = this.serializeEntries(record);
233
+ }
234
+ return out;
235
+ }
236
+
237
+ private serializeEntries(entries: Readonly<Record<string, unknown>>): Record<string, JsonObject> {
238
+ const out: Record<string, JsonObject> = {};
239
+ for (const [name, entry] of Object.entries(entries)) {
240
+ out[name] = this.serializeJsonObject(entry);
241
+ }
242
+ return out;
243
+ }
244
+
245
+ protected serializeJsonObject(value: unknown): JsonObject {
246
+ return blindCast<
247
+ JsonObject,
248
+ 'serializeJsonValue round-trips an IR node through JSON, yielding a JsonObject'
249
+ >(this.serializeJsonValue(value));
250
+ }
251
+
252
+ private serializeJsonValue(value: unknown): JsonValue {
253
+ return blindCast<JsonValue, 'JSON.parse(JSON.stringify(x)) yields a JsonValue'>(
254
+ JSON.parse(JSON.stringify(value)),
255
+ );
256
+ }
211
257
  }
@@ -1 +0,0 @@
1
- {"version":3,"file":"sql-contract-serializer-CYtXg_zs.mjs","names":["isPlainRecord"],"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 { isPlainRecord } from '@prisma-next/contract/is-plain-record';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { ContractSerializer } from '@prisma-next/framework-components/control';\nimport {\n type AnyEntityKindDescriptor,\n hydrateNamespaceEntities,\n type Namespace,\n} from '@prisma-next/framework-components/ir';\nimport { sqlContractCanonicalizationHooks } from '@prisma-next/sql-contract/canonicalization-hooks';\nimport { composeSqlEntityKinds } from '@prisma-next/sql-contract/entity-kinds';\nimport {\n isMaterializedSqlNamespace,\n type SqlNamespaceInput,\n SqlStorage,\n type SqlStorageInput,\n type SqlStorageTypeEntry,\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 entries: type({\n '+': 'ignore',\n }),\n});\n\nexport type SqlEntityHydrationFactory = (entry: unknown) => unknown;\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 private readonly entryKinds: ReadonlyMap<string, AnyEntityKindDescriptor>;\n\n constructor(\n protected readonly entityHydrationRegistry: ReadonlyMap<\n string,\n SqlEntityHydrationFactory\n > = new Map(),\n packEntityKinds: readonly AnyEntityKindDescriptor[] = [],\n ) {\n this.entryKinds = composeSqlEntityKinds(packEntityKinds);\n this.contractSchema =\n packEntityKinds.length > 0 ? createSqlContractSchema(this.entryKinds) : 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(\n blindCast<\n Readonly<Record<string, Record<string, unknown>>>,\n 'parseSqlContractStructure validated raw JSON; namespace entries are plain objects, not SqlNamespace instances.'\n >(rawNamespaces),\n );\n\n return {\n ...validated,\n storage: new SqlStorage({\n storageHash: validated.storage.storageHash,\n ...ifDefined('types', hydratedTypes),\n namespaces: blindCast<\n SqlStorageInput['namespaces'],\n 'hydrateSqlNamespaceMap builds each namespace through the target serializer override, so every value is a SqlNamespace; the framework return type only promises the base Namespace.'\n >(hydratedNamespaces),\n }),\n };\n }\n\n protected hydrateSqlNamespaceMap(\n namespaces: Readonly<Record<string, Record<string, unknown>>>,\n ): Readonly<Record<string, Namespace>> {\n return Object.fromEntries(\n Object.entries(namespaces).map(([nsId, namespaceEntryRaw]) => {\n const namespaceHydrated = this.hydrateSqlNamespaceEntry(nsId, namespaceEntryRaw);\n if (!isMaterializedSqlNamespace(namespaceHydrated)) {\n throw new Error(\n `Target serializer bug: hydrateSqlNamespaceEntry for namespace \"${nsId}\" returned a non-NamespaceBase value. Override hydrateSqlNamespaceEntry to produce a target namespace concretion.`,\n );\n }\n return [nsId, namespaceHydrated];\n }),\n );\n }\n\n protected hydrateSqlNamespaceEntry(\n nsId: string,\n raw: Record<string, unknown>,\n ): Namespace | SqlNamespaceInput {\n const id = typeof raw['id'] === 'string' ? raw['id'] : nsId;\n const parsed = NamespaceRawSchema({ ...raw, 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 entriesRaw = parsed.entries;\n const rawEntriesMap = isPlainRecord(entriesRaw) ? entriesRaw : {};\n\n const entriesInput: Record<string, Readonly<Record<string, unknown>>> = {};\n for (const [key, innerMap] of Object.entries(rawEntriesMap)) {\n entriesInput[key] = isPlainRecord(innerMap) ? innerMap : Object.freeze({});\n }\n\n const entriesOutput = hydrateNamespaceEntities(entriesInput, this.entryKinds, 'fail', id);\n\n // Always ensure a 'table' key is present (may be empty).\n if (!Object.hasOwn(entriesOutput, 'table')) {\n entriesOutput['table'] = {};\n }\n\n return blindCast<\n SqlNamespaceInput,\n 'entriesOutput holds the hydrated SQL entity-kind maps (table always present); this wraps them as the SqlNamespaceInput the target createNamespace consumes.'\n >({\n id,\n entries: entriesOutput,\n });\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.entityHydrationRegistry.get(kind);\n if (factory === undefined) {\n return entry;\n }\n return blindCast<\n SqlStorageTypeEntry,\n 'entity registry factory returns SqlStorageTypeEntry for storage.types entries'\n >(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 *\n * Because this serializer has no target concretion, deserialization of\n * contracts that include namespace entries from JSON will throw unless\n * the caller provides pre-hydrated `NamespaceBase` instances. Production\n * paths always supply a target-specific serializer.\n */\nexport class SqlContractSerializer extends SqlContractSerializerBase<Contract<SqlStorage>> {\n constructor() {\n super(new Map());\n }\n}\n"],"mappings":"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"}