@prisma-next/emitter 0.12.0 → 0.13.0-dev.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{domain-type-generation-By4D1JcL.d.mts → domain-type-generation-DXblsIrF.d.mts} +14 -8
- package/dist/domain-type-generation-DXblsIrF.d.mts.map +1 -0
- package/dist/domain-type-generation.d.mts +2 -2
- package/dist/domain-type-generation.mjs +48 -10
- package/dist/domain-type-generation.mjs.map +1 -1
- package/dist/exports/index.d.mts +3 -3
- package/dist/exports/index.mjs +1 -1
- package/dist/{exports-kyH5YvAl.mjs → exports-lo90ks1p.mjs} +29 -15
- package/dist/exports-lo90ks1p.mjs.map +1 -0
- package/dist/{index-I5F4dZMR.d.mts → index-Cjiwoga9.d.mts} +1 -1
- package/dist/{index-I5F4dZMR.d.mts.map → index-Cjiwoga9.d.mts.map} +1 -1
- package/dist/test/utils.d.mts +3 -1
- package/dist/test/utils.d.mts.map +1 -1
- package/dist/test/utils.mjs +13 -13
- package/dist/test/utils.mjs.map +1 -1
- package/package.json +12 -12
- package/src/domain-type-generation.ts +91 -8
- package/src/generate-contract-dts.ts +90 -23
- package/dist/domain-type-generation-By4D1JcL.d.mts.map +0 -1
- package/dist/exports-kyH5YvAl.mjs.map +0 -1
package/dist/{domain-type-generation-By4D1JcL.d.mts → domain-type-generation-DXblsIrF.d.mts}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ContractField, ContractModel, ContractValueObject, CrossReference } from "@prisma-next/contract/types";
|
|
1
|
+
import { ContractField, ContractModel, ContractValueObject, CrossReference, JsonValue, ValueSetRef } from "@prisma-next/contract/types";
|
|
2
2
|
import { CodecLookup } from "@prisma-next/framework-components/codec";
|
|
3
3
|
import { TypesImportSpec } from "@prisma-next/framework-components/emission";
|
|
4
4
|
|
|
@@ -30,17 +30,23 @@ type ResolvedFieldType = {
|
|
|
30
30
|
*
|
|
31
31
|
* Returns `undefined` when the field has no resolvable typeParams (i.e. the column isn't parameterized, isn't a `typeRef`, or the family doesn't support named storage types).
|
|
32
32
|
*/
|
|
33
|
-
type FieldTypeParamsResolver = (modelName: string, fieldName: string) => Record<string, unknown> | undefined;
|
|
34
|
-
|
|
33
|
+
type FieldTypeParamsResolver = (modelName: string, fieldName: string, model: ContractModel) => Record<string, unknown> | undefined;
|
|
34
|
+
/**
|
|
35
|
+
* Resolves a domain field's `valueSet` ref to the member values of the referenced enum.
|
|
36
|
+
* Returns `undefined` when the ref cannot be resolved to a domain enum, so the emit path
|
|
37
|
+
* falls back to the codec channel.
|
|
38
|
+
*/
|
|
39
|
+
type EnumValuesResolver = (ref: ValueSetRef) => readonly JsonValue[] | undefined;
|
|
40
|
+
declare function resolveFieldType(field: ContractField, codecLookup?: CodecLookup, resolvedTypeParams?: Record<string, unknown>, resolveEnumValues?: EnumValuesResolver): ResolvedFieldType;
|
|
35
41
|
declare function generateFieldResolvedType(field: ContractField, codecLookup?: CodecLookup, side?: 'input' | 'output'): string;
|
|
36
|
-
declare function generateBothFieldTypesMaps(models: Record<string, ContractModel> | undefined, codecLookup?: CodecLookup, resolveFieldTypeParams?: FieldTypeParamsResolver): ResolvedFieldType;
|
|
37
|
-
declare function generateFieldOutputTypesMap(models: Record<string, ContractModel> | undefined, codecLookup?: CodecLookup, resolveFieldTypeParams?: FieldTypeParamsResolver): string;
|
|
38
|
-
declare function generateFieldInputTypesMap(models: Record<string, ContractModel> | undefined, codecLookup?: CodecLookup, resolveFieldTypeParams?: FieldTypeParamsResolver): string;
|
|
42
|
+
declare function generateBothFieldTypesMaps(models: Record<string, ContractModel> | undefined, codecLookup?: CodecLookup, resolveFieldTypeParams?: FieldTypeParamsResolver, resolveEnumValues?: EnumValuesResolver): ResolvedFieldType;
|
|
43
|
+
declare function generateFieldOutputTypesMap(models: Record<string, ContractModel> | undefined, codecLookup?: CodecLookup, resolveFieldTypeParams?: FieldTypeParamsResolver, resolveEnumValues?: EnumValuesResolver): string;
|
|
44
|
+
declare function generateFieldInputTypesMap(models: Record<string, ContractModel> | undefined, codecLookup?: CodecLookup, resolveFieldTypeParams?: FieldTypeParamsResolver, resolveEnumValues?: EnumValuesResolver): string;
|
|
39
45
|
declare function generateValueObjectType(_voName: string, vo: ContractValueObject, _valueObjects: Record<string, ContractValueObject>, side?: 'input' | 'output', codecLookup?: CodecLookup): string;
|
|
40
46
|
declare function resolveValueObjectType(_voName: string, vo: ContractValueObject, _valueObjects: Record<string, ContractValueObject>, codecLookup?: CodecLookup): ResolvedFieldType;
|
|
41
47
|
declare function generateContractFieldDescriptor(fieldName: string, field: ContractField): string;
|
|
42
48
|
declare function generateValueObjectsDescriptorType(valueObjects: Record<string, ContractValueObject> | undefined): string;
|
|
43
49
|
declare function generateValueObjectTypeAliases(valueObjects: Record<string, ContractValueObject> | undefined, codecLookup?: CodecLookup): string;
|
|
44
50
|
//#endregion
|
|
45
|
-
export {
|
|
46
|
-
//# sourceMappingURL=domain-type-generation-
|
|
51
|
+
export { serializeCrossReference as C, serializeValue as D, serializeObjectKey as E, resolveValueObjectType as S, serializeNamespaceId as T, generateRootsType as _, generateBothFieldTypesMaps as a, generateValueObjectsDescriptorType as b, generateFieldInputTypesMap as c, generateHashTypeAliases as d, generateImportLines as f, generateModelsType as g, generateModelRelationsType as h, deduplicateImports as i, generateFieldOutputTypesMap as l, generateModelFieldsType as m, FieldTypeParamsResolver as n, generateCodecTypeIntersection as o, generateModelFieldEntry as p, ResolvedFieldType as r, generateContractFieldDescriptor as s, EnumValuesResolver as t, generateFieldResolvedType as u, generateValueObjectType as v, serializeExecutionType as w, resolveFieldType as x, generateValueObjectTypeAliases as y };
|
|
52
|
+
//# sourceMappingURL=domain-type-generation-DXblsIrF.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-type-generation-DXblsIrF.d.mts","names":[],"sources":["../src/domain-type-generation.ts"],"mappings":";;;;;iBAegB,cAAA,CAAe,KAAc;AAAA,iBA+B7B,kBAAA,CAAmB,GAAW;AAAA,iBAO9B,oBAAA,CAAqB,KAAa;AAAA,iBAIlC,uBAAA,CAAwB,GAAmB,EAAd,cAAc;AAAA,iBAO3C,iBAAA,CAAkB,KAAA,EAAO,MAAM,SAAS,cAAA;AAAA,iBAgBxC,uBAAA,CAAwB,SAAA,UAAmB,KAAA,EAAO,aAAa;AAAA,iBAgB/D,uBAAA,CAAwB,MAAA,EAAQ,MAAM,SAAS,aAAA;AAAA,iBAQ/C,0BAAA,CAA2B,SAAkC,EAAvB,MAAM;AAAA,iBA4E5C,kBAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,GACvB,oBAAA,GAAuB,SAAA,UAAmB,KAAA,EAAO,aAAA;AAAA,iBAqCnC,kBAAA,CAAmB,OAAA,EAAS,eAAA,KAAoB,eAAe;AAAA,iBAa/D,mBAAA,CAAoB,OAA0B,EAAjB,eAAe;AAAA,iBAW5C,6BAAA,CACd,OAAA,EAAS,aAAa,CAAC,eAAA,GACvB,KAAA;AAAA,iBAMc,sBAAA,CAAuB,SAAkC,EAAvB,MAAM;AAAA,iBASxC,uBAAA,CAAwB,MAAA;EAAA,SAC7B,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;AAAA;AAAA,KAaC,iBAAA;EAAA,SAA+B,KAAA;EAAA,SAAwB,MAAM;AAAA;AApNzE;;;;;AAAA,KAmOY,uBAAA,IACV,SAAA,UACA,SAAA,UACA,KAAA,EAAO,aAAA,KACJ,MAAM;;;AAvOwE;AAgBnF;;KA8NY,kBAAA,IAAsB,GAAA,EAAK,WAAA,cAAyB,SAAS;AAAA,iBAqBzD,gBAAA,CACd,KAAA,EAAO,aAAA,EACP,WAAA,GAAc,WAAA,EACd,kBAAA,GAAqB,MAAA,mBACrB,iBAAA,GAAoB,kBAAA,GACnB,iBAAA;AAAA,iBA4Da,yBAAA,CACd,KAAA,EAAO,aAAA,EACP,WAAA,GAAc,WAAW,EACzB,IAAA;AAAA,iBAKc,0BAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,eACvB,WAAA,GAAc,WAAA,EACd,sBAAA,GAAyB,uBAAA,EACzB,iBAAA,GAAoB,kBAAA,GACnB,iBAAA;AAAA,iBA4Ca,2BAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,eACvB,WAAA,GAAc,WAAA,EACd,sBAAA,GAAyB,uBAAA,EACzB,iBAAA,GAAoB,kBAAA;AAAA,iBAMN,0BAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,eACvB,WAAA,GAAc,WAAA,EACd,sBAAA,GAAyB,uBAAA,EACzB,iBAAA,GAAoB,kBAAA;AAAA,iBAMN,uBAAA,CACd,OAAA,UACA,EAAA,EAAI,mBAAA,EACJ,aAAA,EAAe,MAAA,SAAe,mBAAA,GAC9B,IAAA,uBACA,WAAA,GAAc,WAAA;AAAA,iBAKA,sBAAA,CACd,OAAA,UACA,EAAA,EAAI,mBAAA,EACJ,aAAA,EAAe,MAAA,SAAe,mBAAA,GAC9B,WAAA,GAAc,WAAA,GACb,iBAAA;AAAA,iBAgBa,+BAAA,CAAgC,SAAA,UAAmB,KAAA,EAAO,aAAa;AAAA,iBAoBvE,kCAAA,CACd,YAAA,EAAc,MAAM,SAAS,mBAAA;AAAA,iBAoBf,8BAAA,CACd,YAAA,EAAc,MAAA,SAAe,mBAAA,eAC7B,WAAA,GAAc,WAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { C as
|
|
2
|
-
export { FieldTypeParamsResolver, ResolvedFieldType, deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateContractFieldDescriptor, generateFieldInputTypesMap, generateFieldOutputTypesMap, generateFieldResolvedType, generateHashTypeAliases, generateImportLines, generateModelFieldEntry, generateModelFieldsType, generateModelRelationsType, generateModelsType, generateRootsType, generateValueObjectType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, resolveFieldType, resolveValueObjectType, serializeCrossReference, serializeExecutionType, serializeNamespaceId, serializeObjectKey, serializeValue };
|
|
1
|
+
import { C as serializeCrossReference, D as serializeValue, E as serializeObjectKey, S as resolveValueObjectType, T as serializeNamespaceId, _ as generateRootsType, a as generateBothFieldTypesMaps, b as generateValueObjectsDescriptorType, c as generateFieldInputTypesMap, d as generateHashTypeAliases, f as generateImportLines, g as generateModelsType, h as generateModelRelationsType, i as deduplicateImports, l as generateFieldOutputTypesMap, m as generateModelFieldsType, n as FieldTypeParamsResolver, o as generateCodecTypeIntersection, p as generateModelFieldEntry, r as ResolvedFieldType, s as generateContractFieldDescriptor, t as EnumValuesResolver, u as generateFieldResolvedType, v as generateValueObjectType, w as serializeExecutionType, x as resolveFieldType, y as generateValueObjectTypeAliases } from "./domain-type-generation-DXblsIrF.mjs";
|
|
2
|
+
export { EnumValuesResolver, FieldTypeParamsResolver, ResolvedFieldType, deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateContractFieldDescriptor, generateFieldInputTypesMap, generateFieldOutputTypesMap, generateFieldResolvedType, generateHashTypeAliases, generateImportLines, generateModelFieldEntry, generateModelFieldsType, generateModelRelationsType, generateModelsType, generateRootsType, generateValueObjectType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, resolveFieldType, resolveValueObjectType, serializeCrossReference, serializeExecutionType, serializeNamespaceId, serializeObjectKey, serializeValue };
|
|
@@ -24,7 +24,7 @@ function serializeNamespaceId(value) {
|
|
|
24
24
|
return `${serializeValue(value)} & NamespaceId`;
|
|
25
25
|
}
|
|
26
26
|
function serializeCrossReference(ref) {
|
|
27
|
-
return `{ readonly namespace: ${serializeNamespaceId(String(ref.namespace))}; readonly model: ${serializeValue(ref.model)} }`;
|
|
27
|
+
return `{ readonly namespace: ${serializeNamespaceId(String(ref.namespace))}; readonly model: ${serializeValue(ref.model)}${ref.space !== void 0 ? `; readonly space: ${serializeValue(ref.space)}` : ""} }`;
|
|
28
28
|
}
|
|
29
29
|
function generateRootsType(roots) {
|
|
30
30
|
if (!roots || Object.keys(roots).length === 0) return "Record<string, never>";
|
|
@@ -53,8 +53,13 @@ function generateModelRelationsType(relations) {
|
|
|
53
53
|
for (const [relName, rel] of Object.entries(relations)) {
|
|
54
54
|
if (typeof rel !== "object" || rel === null) continue;
|
|
55
55
|
const relObj = rel;
|
|
56
|
+
const toRef = relObj["to"];
|
|
57
|
+
if (toRef !== null && typeof toRef === "object" && "space" in toRef && toRef.space !== void 0) {
|
|
58
|
+
relationEntries.push(`readonly ${serializeObjectKey(relName)}: never`);
|
|
59
|
+
continue;
|
|
60
|
+
}
|
|
56
61
|
const parts = [];
|
|
57
|
-
if (
|
|
62
|
+
if (toRef) parts.push(`readonly to: ${serializeCrossReference(blindCast(toRef))}`);
|
|
58
63
|
if (relObj["cardinality"]) parts.push(`readonly cardinality: ${serializeValue(relObj["cardinality"])}`);
|
|
59
64
|
const on = relObj["on"];
|
|
60
65
|
if (on && (!on.localFields || !on.targetFields)) throw new Error(`Relation "${relName}" has an "on" block but is missing localFields or targetFields`);
|
|
@@ -63,7 +68,16 @@ function generateModelRelationsType(relations) {
|
|
|
63
68
|
const targetFields = on.targetFields.map((f) => serializeValue(f)).join(", ");
|
|
64
69
|
parts.push(`readonly on: { readonly localFields: readonly [${localFields}]; readonly targetFields: readonly [${targetFields}] }`);
|
|
65
70
|
}
|
|
66
|
-
if (
|
|
71
|
+
if (relObj["cardinality"] === "N:M") {
|
|
72
|
+
const { through } = blindCast(relObj);
|
|
73
|
+
const table = serializeValue(through.table);
|
|
74
|
+
const namespaceId = serializeValue(through.namespaceId);
|
|
75
|
+
const parentColumns = through.parentColumns.map((c) => serializeValue(c)).join(", ");
|
|
76
|
+
const childColumns = through.childColumns.map((c) => serializeValue(c)).join(", ");
|
|
77
|
+
const targetColumns = through.targetColumns.map((c) => serializeValue(c)).join(", ");
|
|
78
|
+
parts.push(`readonly through: { readonly table: ${table}; readonly namespaceId: ${namespaceId}; readonly parentColumns: readonly [${parentColumns}]; readonly childColumns: readonly [${childColumns}]; readonly targetColumns: readonly [${targetColumns}] }`);
|
|
79
|
+
}
|
|
80
|
+
if (parts.length > 0) relationEntries.push(`readonly ${serializeObjectKey(relName)}: { ${parts.join("; ")} }`);
|
|
67
81
|
}
|
|
68
82
|
if (relationEntries.length === 0) return "Record<string, never>";
|
|
69
83
|
return `{ ${relationEntries.join("; ")} }`;
|
|
@@ -135,10 +149,34 @@ function applyModifiers(base, field) {
|
|
|
135
149
|
if (field.nullable) result = `${result} | null`;
|
|
136
150
|
return result;
|
|
137
151
|
}
|
|
138
|
-
function
|
|
152
|
+
function renderEnumMemberLiteral(value) {
|
|
153
|
+
if (value === null) return "null";
|
|
154
|
+
if (typeof value === "string") return serializeValue(value);
|
|
155
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
156
|
+
}
|
|
157
|
+
function renderEnumValueUnion(values) {
|
|
158
|
+
if (values.length === 0) return void 0;
|
|
159
|
+
const literals = [];
|
|
160
|
+
for (const value of values) {
|
|
161
|
+
const literal = renderEnumMemberLiteral(value);
|
|
162
|
+
if (literal === void 0) return void 0;
|
|
163
|
+
literals.push(literal);
|
|
164
|
+
}
|
|
165
|
+
const union = literals.join(" | ");
|
|
166
|
+
return isSafeTypeExpression(union) ? union : void 0;
|
|
167
|
+
}
|
|
168
|
+
function resolveFieldType(field, codecLookup, resolvedTypeParams, resolveEnumValues) {
|
|
139
169
|
const { type } = field;
|
|
140
170
|
switch (type.kind) {
|
|
141
171
|
case "scalar": {
|
|
172
|
+
if (field.valueSet?.entityKind === "enum" && resolveEnumValues) {
|
|
173
|
+
const values = resolveEnumValues(field.valueSet);
|
|
174
|
+
const union = values ? renderEnumValueUnion(values) : void 0;
|
|
175
|
+
if (union !== void 0) return {
|
|
176
|
+
output: applyModifiers(union, field),
|
|
177
|
+
input: applyModifiers(union, field)
|
|
178
|
+
};
|
|
179
|
+
}
|
|
142
180
|
let outputResolved;
|
|
143
181
|
const effectiveTypeParams = (type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : void 0) ?? resolvedTypeParams;
|
|
144
182
|
if (codecLookup && effectiveTypeParams && Object.keys(effectiveTypeParams).length > 0) {
|
|
@@ -172,7 +210,7 @@ function resolveFieldType(field, codecLookup, resolvedTypeParams) {
|
|
|
172
210
|
function generateFieldResolvedType(field, codecLookup, side = "output") {
|
|
173
211
|
return resolveFieldType(field, codecLookup)[side];
|
|
174
212
|
}
|
|
175
|
-
function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams) {
|
|
213
|
+
function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues) {
|
|
176
214
|
if (!models || Object.keys(models).length === 0) return {
|
|
177
215
|
output: "Record<string, never>",
|
|
178
216
|
input: "Record<string, never>"
|
|
@@ -184,7 +222,7 @@ function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
|
184
222
|
const outputFieldEntries = [];
|
|
185
223
|
const inputFieldEntries = [];
|
|
186
224
|
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
187
|
-
const resolved = resolveFieldType(field, codecLookup, (field.type.kind === "scalar" && field.type.typeParams && Object.keys(field.type.typeParams).length > 0 ? field.type.typeParams : void 0) ?? resolveFieldTypeParams?.(modelName, fieldName));
|
|
225
|
+
const resolved = resolveFieldType(field, codecLookup, (field.type.kind === "scalar" && field.type.typeParams && Object.keys(field.type.typeParams).length > 0 ? field.type.typeParams : void 0) ?? resolveFieldTypeParams?.(modelName, fieldName, model), resolveEnumValues);
|
|
188
226
|
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
189
227
|
outputFieldEntries.push(`${key}: ${resolved.output}`);
|
|
190
228
|
inputFieldEntries.push(`${key}: ${resolved.input}`);
|
|
@@ -200,11 +238,11 @@ function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
|
200
238
|
input: `{ ${inputModelEntries.join("; ")} }`
|
|
201
239
|
};
|
|
202
240
|
}
|
|
203
|
-
function generateFieldOutputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
204
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).output;
|
|
241
|
+
function generateFieldOutputTypesMap(models, codecLookup, resolveFieldTypeParams, resolveEnumValues) {
|
|
242
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues).output;
|
|
205
243
|
}
|
|
206
|
-
function generateFieldInputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
207
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).input;
|
|
244
|
+
function generateFieldInputTypesMap(models, codecLookup, resolveFieldTypeParams, resolveEnumValues) {
|
|
245
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues).input;
|
|
208
246
|
}
|
|
209
247
|
function generateValueObjectType(_voName, vo, _valueObjects, side = "output", codecLookup) {
|
|
210
248
|
return resolveValueObjectType(_voName, vo, _valueObjects, codecLookup)[side];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain-type-generation.mjs","names":[],"sources":["../src/domain-type-generation.ts"],"sourcesContent":["import type {\n ContractField,\n ContractModel,\n ContractValueObject,\n CrossReference,\n} from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type { TypesImportSpec } from '@prisma-next/framework-components/emission';\nimport { type ImportRequirement, renderImports } from '@prisma-next/ts-render';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { isSafeTypeExpression } from './type-expression-safety';\n\nexport function serializeValue(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n if (value === undefined) {\n return 'undefined';\n }\n if (typeof value === 'string') {\n const escaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n return `'${escaped}'`;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n if (typeof value === 'bigint') {\n return `${value}n`;\n }\n if (Array.isArray(value)) {\n const items = value.map((v) => serializeValue(v)).join(', ');\n return `readonly [${items}]`;\n }\n if (typeof value === 'object') {\n const entries: string[] = [];\n for (const [k, v] of Object.entries(value)) {\n entries.push(`readonly ${serializeObjectKey(k)}: ${serializeValue(v)}`);\n }\n return `{ ${entries.join('; ')} }`;\n }\n return 'unknown';\n}\n\nexport function serializeObjectKey(key: string): string {\n if (/^[$A-Z_a-z][$\\w]*$/.test(key)) {\n return key;\n }\n return serializeValue(key);\n}\n\nexport function serializeNamespaceId(value: string): string {\n return `${serializeValue(value)} & NamespaceId`;\n}\n\nexport function serializeCrossReference(ref: CrossReference): string {\n const namespace = serializeNamespaceId(String(ref.namespace));\n const model = serializeValue(ref.model);\n return `{ readonly namespace: ${namespace}; readonly model: ${model} }`;\n}\n\nexport function generateRootsType(roots: Record<string, CrossReference> | undefined): string {\n if (!roots || Object.keys(roots).length === 0) {\n return 'Record<string, never>';\n }\n const entries = Object.entries(roots)\n .map(([key, value]) => `readonly ${serializeObjectKey(key)}: ${serializeCrossReference(value)}`)\n .join('; ');\n return `{ ${entries} }`;\n}\n\nfunction contractFieldModifierSuffix(field: ContractField): string {\n const many = field.many === true ? '; readonly many: true' : '';\n const dict = field.dict === true ? '; readonly dict: true' : '';\n return many + dict;\n}\n\nexport function generateModelFieldEntry(fieldName: string, field: ContractField): string {\n const mods = contractFieldModifierSuffix(field);\n const { nullable, type } = field;\n if (type.kind === 'scalar') {\n const typeParamsSpec =\n type.typeParams && Object.keys(type.typeParams).length > 0\n ? `; readonly typeParams: ${serializeValue(type.typeParams)}`\n : '';\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${mods} }`;\n }\n if (type.kind === 'valueObject') {\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${mods} }`;\n }\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: ${serializeValue(type)}${mods} }`;\n}\n\nexport function generateModelFieldsType(fields: Record<string, ContractField>): string {\n const fieldEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(fields)) {\n fieldEntries.push(generateModelFieldEntry(fieldName, field));\n }\n return fieldEntries.length > 0 ? `{ ${fieldEntries.join('; ')} }` : 'Record<string, never>';\n}\n\nexport function generateModelRelationsType(relations: Record<string, unknown>): string {\n const relationEntries: string[] = [];\n\n for (const [relName, rel] of Object.entries(relations)) {\n if (typeof rel !== 'object' || rel === null) continue;\n const relObj = rel as Record<string, unknown>;\n const parts: string[] = [];\n\n if (relObj['to'])\n parts.push(\n `readonly to: ${serializeCrossReference(blindCast<CrossReference, 'contract JSON schema-validated before serialization; truthy check above confirms presence'>(relObj['to']))}`,\n );\n if (relObj['cardinality'])\n parts.push(`readonly cardinality: ${serializeValue(relObj['cardinality'])}`);\n\n const on = relObj['on'] as { localFields?: string[]; targetFields?: string[] } | undefined;\n if (on && (!on.localFields || !on.targetFields)) {\n throw new Error(\n `Relation \"${relName}\" has an \"on\" block but is missing localFields or targetFields`,\n );\n }\n if (on?.localFields && on.targetFields) {\n const localFields = on.localFields.map((f) => serializeValue(f)).join(', ');\n const targetFields = on.targetFields.map((f) => serializeValue(f)).join(', ');\n parts.push(\n `readonly on: { readonly localFields: readonly [${localFields}]; readonly targetFields: readonly [${targetFields}] }`,\n );\n }\n\n if (parts.length > 0) {\n relationEntries.push(`readonly ${relName}: { ${parts.join('; ')} }`);\n }\n }\n\n if (relationEntries.length === 0) {\n return 'Record<string, never>';\n }\n\n return `{ ${relationEntries.join('; ')} }`;\n}\n\nexport function generateModelsType(\n models: Record<string, ContractModel>,\n generateModelStorage: (modelName: string, model: ContractModel) => string,\n): string {\n if (!models || Object.keys(models).length === 0) {\n return 'Record<string, never>';\n }\n\n const modelTypes: string[] = [];\n for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {\n const fieldsType = generateModelFieldsType(model.fields);\n const relationsType = generateModelRelationsType(model.relations);\n const storageType = generateModelStorage(modelName, model);\n\n const modelParts: string[] = [\n `readonly fields: ${fieldsType}`,\n `readonly relations: ${relationsType}`,\n `readonly storage: ${storageType}`,\n ];\n\n if (model.owner) {\n modelParts.push(`readonly owner: ${serializeValue(model.owner)}`);\n }\n if (model.discriminator) {\n modelParts.push(`readonly discriminator: ${serializeValue(model.discriminator)}`);\n }\n if (model.variants) {\n modelParts.push(`readonly variants: ${serializeValue(model.variants)}`);\n }\n if (model.base) {\n modelParts.push(`readonly base: ${serializeCrossReference(model.base)}`);\n }\n\n modelTypes.push(`readonly ${modelName}: { ${modelParts.join('; ')} }`);\n }\n\n return `{ ${modelTypes.join('; ')} }`;\n}\n\nexport function deduplicateImports(imports: TypesImportSpec[]): TypesImportSpec[] {\n const seenKeys = new Set<string>();\n const result: TypesImportSpec[] = [];\n for (const imp of imports) {\n const key = `${imp.package}::${imp.named}`;\n if (!seenKeys.has(key)) {\n seenKeys.add(key);\n result.push(imp);\n }\n }\n return result;\n}\n\nexport function generateImportLines(imports: TypesImportSpec[]): string[] {\n const requirements: ImportRequirement[] = imports.map((imp) => ({\n moduleSpecifier: imp.package,\n symbol: imp.named,\n alias: imp.alias,\n typeOnly: true,\n }));\n const rendered = renderImports(requirements);\n return rendered === '' ? [] : rendered.split('\\n');\n}\n\nexport function generateCodecTypeIntersection(\n imports: ReadonlyArray<TypesImportSpec>,\n named: string,\n): string {\n const aliases = imports.filter((imp) => imp.named === named).map((imp) => imp.alias);\n return aliases.join(' & ') || 'Record<string, never>';\n}\n\nexport function serializeExecutionType(execution: Record<string, unknown>): string {\n const parts: string[] = ['readonly executionHash: ExecutionHash'];\n for (const [key, value] of Object.entries(execution)) {\n if (key === 'executionHash') continue;\n parts.push(`readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`);\n }\n return `{ ${parts.join('; ')} }`;\n}\n\nexport function generateHashTypeAliases(hashes: {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n}): string {\n const executionHashType = hashes.executionHash\n ? `ExecutionHashBase<'${hashes.executionHash}'>`\n : 'ExecutionHashBase<string>';\n\n return [\n `export type StorageHash = StorageHashBase<'${hashes.storageHash}'>;`,\n `export type ExecutionHash = ${executionHashType};`,\n `export type ProfileHash = ProfileHashBase<'${hashes.profileHash}'>;`,\n ].join('\\n');\n}\n\nexport type ResolvedFieldType = { readonly input: string; readonly output: string };\n\nfunction applyModifiers(base: string, field: ContractField): string {\n let result = base;\n if (field.many === true) result = `ReadonlyArray<${result}>`;\n if (field.dict === true) result = `Readonly<Record<string, ${result}>>`;\n if (field.nullable) result = `${result} | null`;\n return result;\n}\n\n/**\n * Per-family resolver for typeParams that don't live inline on the framework-domain `ContractField`. SQL columns authored via a named `storage.types` entry carry their `typeRef` on the storage column (family-specific) rather than on the framework's domain field; the per-family emitter walks `storage.types[ref].typeParams` here so the framework emit path can render the parameterized output type.\n *\n * Returns `undefined` when the field has no resolvable typeParams (i.e. the column isn't parameterized, isn't a `typeRef`, or the family doesn't support named storage types).\n */\nexport type FieldTypeParamsResolver = (\n modelName: string,\n fieldName: string,\n) => Record<string, unknown> | undefined;\n\nexport function resolveFieldType(\n field: ContractField,\n codecLookup?: CodecLookup,\n resolvedTypeParams?: Record<string, unknown>,\n): ResolvedFieldType {\n const { type } = field;\n\n switch (type.kind) {\n case 'scalar': {\n let outputResolved: string | undefined;\n const inlineTypeParams =\n type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : undefined;\n const effectiveTypeParams = inlineTypeParams ?? resolvedTypeParams;\n if (codecLookup && effectiveTypeParams && Object.keys(effectiveTypeParams).length > 0) {\n const rendered = codecLookup.renderOutputTypeFor(type.codecId, effectiveTypeParams);\n if (rendered && isSafeTypeExpression(rendered)) {\n outputResolved = rendered;\n }\n }\n const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;\n return {\n output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),\n input: applyModifiers(`${codecAccessor}['input']`, field),\n };\n }\n case 'valueObject':\n return {\n output: applyModifiers(`${type.name}Output`, field),\n input: applyModifiers(`${type.name}Input`, field),\n };\n case 'union': {\n const outputMembers = type.members.map((m) =>\n m.kind === 'scalar'\n ? `CodecTypes[${serializeValue(m.codecId)}]['output']`\n : `${m.name}Output`,\n );\n const inputMembers = type.members.map((m) =>\n m.kind === 'scalar'\n ? `CodecTypes[${serializeValue(m.codecId)}]['input']`\n : `${m.name}Input`,\n );\n return {\n output: applyModifiers(outputMembers.join(' | '), field),\n input: applyModifiers(inputMembers.join(' | '), field),\n };\n }\n default:\n return {\n output: applyModifiers('unknown', field),\n input: applyModifiers('unknown', field),\n };\n }\n}\n\nexport function generateFieldResolvedType(\n field: ContractField,\n codecLookup?: CodecLookup,\n side: 'input' | 'output' = 'output',\n): string {\n return resolveFieldType(field, codecLookup)[side];\n}\n\nexport function generateBothFieldTypesMaps(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n): ResolvedFieldType {\n if (!models || Object.keys(models).length === 0) {\n return { output: 'Record<string, never>', input: 'Record<string, never>' };\n }\n\n const outputModelEntries: string[] = [];\n const inputModelEntries: string[] = [];\n for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {\n if (!model) continue;\n const outputFieldEntries: string[] = [];\n const inputFieldEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(model.fields)) {\n const inlineTypeParams =\n field.type.kind === 'scalar' &&\n field.type.typeParams &&\n Object.keys(field.type.typeParams).length > 0\n ? field.type.typeParams\n : undefined;\n const resolvedTypeParams = inlineTypeParams ?? resolveFieldTypeParams?.(modelName, fieldName);\n const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams);\n const key = `readonly ${serializeObjectKey(fieldName)}`;\n outputFieldEntries.push(`${key}: ${resolved.output}`);\n inputFieldEntries.push(`${key}: ${resolved.input}`);\n }\n const outputFields =\n outputFieldEntries.length > 0\n ? `{ ${outputFieldEntries.join('; ')} }`\n : 'Record<string, never>';\n const inputFields =\n inputFieldEntries.length > 0\n ? `{ ${inputFieldEntries.join('; ')} }`\n : 'Record<string, never>';\n const modelKey = `readonly ${serializeObjectKey(modelName)}`;\n outputModelEntries.push(`${modelKey}: ${outputFields}`);\n inputModelEntries.push(`${modelKey}: ${inputFields}`);\n }\n\n return {\n output: `{ ${outputModelEntries.join('; ')} }`,\n input: `{ ${inputModelEntries.join('; ')} }`,\n };\n}\n\nexport function generateFieldOutputTypesMap(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n): string {\n return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).output;\n}\n\nexport function generateFieldInputTypesMap(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n): string {\n return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).input;\n}\n\nexport function generateValueObjectType(\n _voName: string,\n vo: ContractValueObject,\n _valueObjects: Record<string, ContractValueObject>,\n side: 'input' | 'output' = 'output',\n codecLookup?: CodecLookup,\n): string {\n return resolveValueObjectType(_voName, vo, _valueObjects, codecLookup)[side];\n}\n\nexport function resolveValueObjectType(\n _voName: string,\n vo: ContractValueObject,\n _valueObjects: Record<string, ContractValueObject>,\n codecLookup?: CodecLookup,\n): ResolvedFieldType {\n const outputEntries: string[] = [];\n const inputEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(vo.fields)) {\n const resolved = resolveFieldType(field, codecLookup);\n const key = `readonly ${serializeObjectKey(fieldName)}`;\n outputEntries.push(`${key}: ${resolved.output}`);\n inputEntries.push(`${key}: ${resolved.input}`);\n }\n const empty = 'Record<string, never>';\n return {\n output: outputEntries.length > 0 ? `{ ${outputEntries.join('; ')} }` : empty,\n input: inputEntries.length > 0 ? `{ ${inputEntries.join('; ')} }` : empty,\n };\n}\n\nexport function generateContractFieldDescriptor(fieldName: string, field: ContractField): string {\n const mods: string[] = [];\n if (field.many === true) mods.push('; readonly many: true');\n if (field.dict === true) mods.push('; readonly dict: true');\n const modStr = mods.join('');\n\n const { type } = field;\n if (type.kind === 'scalar') {\n const typeParamsSpec =\n type.typeParams && Object.keys(type.typeParams).length > 0\n ? `; readonly typeParams: ${serializeValue(type.typeParams)}`\n : '';\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${modStr} }`;\n }\n if (type.kind === 'valueObject') {\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${modStr} }`;\n }\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: ${serializeValue(type)}${modStr} }`;\n}\n\nexport function generateValueObjectsDescriptorType(\n valueObjects: Record<string, ContractValueObject> | undefined,\n): string {\n if (!valueObjects || Object.keys(valueObjects).length === 0) {\n return 'Record<string, never>';\n }\n\n const voEntries: string[] = [];\n for (const [voName, vo] of Object.entries(valueObjects)) {\n const fieldEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(vo.fields)) {\n fieldEntries.push(generateContractFieldDescriptor(fieldName, field));\n }\n const fieldsType =\n fieldEntries.length > 0 ? `{ ${fieldEntries.join('; ')} }` : 'Record<string, never>';\n voEntries.push(`readonly ${serializeObjectKey(voName)}: { readonly fields: ${fieldsType} }`);\n }\n\n return `{ ${voEntries.join('; ')} }`;\n}\n\nexport function generateValueObjectTypeAliases(\n valueObjects: Record<string, ContractValueObject> | undefined,\n codecLookup?: CodecLookup,\n): string {\n if (!valueObjects || Object.keys(valueObjects).length === 0) {\n return '';\n }\n\n const aliases: string[] = [];\n for (const [voName, vo] of Object.entries(valueObjects)) {\n const resolved = resolveValueObjectType(voName, vo, valueObjects, codecLookup);\n aliases.push(`export type ${voName}Output = ${resolved.output};`);\n aliases.push(`export type ${voName}Input = ${resolved.input};`);\n }\n return aliases.join('\\n');\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"domain-type-generation.mjs","names":[],"sources":["../src/domain-type-generation.ts"],"sourcesContent":["import type {\n ContractField,\n ContractManyToManyRelation,\n ContractModel,\n ContractValueObject,\n CrossReference,\n JsonValue,\n ValueSetRef,\n} from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type { TypesImportSpec } from '@prisma-next/framework-components/emission';\nimport { type ImportRequirement, renderImports } from '@prisma-next/ts-render';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { isSafeTypeExpression } from './type-expression-safety';\n\nexport function serializeValue(value: unknown): string {\n if (value === null) {\n return 'null';\n }\n if (value === undefined) {\n return 'undefined';\n }\n if (typeof value === 'string') {\n const escaped = value.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"\\\\'\");\n return `'${escaped}'`;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n if (typeof value === 'bigint') {\n return `${value}n`;\n }\n if (Array.isArray(value)) {\n const items = value.map((v) => serializeValue(v)).join(', ');\n return `readonly [${items}]`;\n }\n if (typeof value === 'object') {\n const entries: string[] = [];\n for (const [k, v] of Object.entries(value)) {\n entries.push(`readonly ${serializeObjectKey(k)}: ${serializeValue(v)}`);\n }\n return `{ ${entries.join('; ')} }`;\n }\n return 'unknown';\n}\n\nexport function serializeObjectKey(key: string): string {\n if (/^[$A-Z_a-z][$\\w]*$/.test(key)) {\n return key;\n }\n return serializeValue(key);\n}\n\nexport function serializeNamespaceId(value: string): string {\n return `${serializeValue(value)} & NamespaceId`;\n}\n\nexport function serializeCrossReference(ref: CrossReference): string {\n const namespace = serializeNamespaceId(String(ref.namespace));\n const model = serializeValue(ref.model);\n const space = ref.space !== undefined ? `; readonly space: ${serializeValue(ref.space)}` : '';\n return `{ readonly namespace: ${namespace}; readonly model: ${model}${space} }`;\n}\n\nexport function generateRootsType(roots: Record<string, CrossReference> | undefined): string {\n if (!roots || Object.keys(roots).length === 0) {\n return 'Record<string, never>';\n }\n const entries = Object.entries(roots)\n .map(([key, value]) => `readonly ${serializeObjectKey(key)}: ${serializeCrossReference(value)}`)\n .join('; ');\n return `{ ${entries} }`;\n}\n\nfunction contractFieldModifierSuffix(field: ContractField): string {\n const many = field.many === true ? '; readonly many: true' : '';\n const dict = field.dict === true ? '; readonly dict: true' : '';\n return many + dict;\n}\n\nexport function generateModelFieldEntry(fieldName: string, field: ContractField): string {\n const mods = contractFieldModifierSuffix(field);\n const { nullable, type } = field;\n if (type.kind === 'scalar') {\n const typeParamsSpec =\n type.typeParams && Object.keys(type.typeParams).length > 0\n ? `; readonly typeParams: ${serializeValue(type.typeParams)}`\n : '';\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${mods} }`;\n }\n if (type.kind === 'valueObject') {\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${mods} }`;\n }\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: ${serializeValue(type)}${mods} }`;\n}\n\nexport function generateModelFieldsType(fields: Record<string, ContractField>): string {\n const fieldEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(fields)) {\n fieldEntries.push(generateModelFieldEntry(fieldName, field));\n }\n return fieldEntries.length > 0 ? `{ ${fieldEntries.join('; ')} }` : 'Record<string, never>';\n}\n\nexport function generateModelRelationsType(relations: Record<string, unknown>): string {\n const relationEntries: string[] = [];\n\n for (const [relName, rel] of Object.entries(relations)) {\n if (typeof rel !== 'object' || rel === null) continue;\n const relObj = rel as Record<string, unknown>;\n\n // Option B: cross-space relations are declared but non-navigable.\n // A relation whose `to.space` is set lives in a foreign contract space;\n // emitting `never` for its entry makes `include` of it a compile error\n // while the relation is still present in the contract JSON for introspection.\n const toRef = relObj['to'];\n // Option B: cross-space relations are declared but non-navigable.\n // When the relation's `to` ref carries a `space` field the target lives\n // in a foreign contract space; emit `never` so `include` of it is a\n // compile error while the relation stays in the contract JSON.\n if (\n toRef !== null &&\n typeof toRef === 'object' &&\n 'space' in toRef &&\n toRef.space !== undefined\n ) {\n relationEntries.push(`readonly ${serializeObjectKey(relName)}: never`);\n continue;\n }\n\n const parts: string[] = [];\n\n if (toRef)\n parts.push(\n `readonly to: ${serializeCrossReference(blindCast<CrossReference, 'contract JSON schema-validated before serialization; truthy check above confirms presence'>(toRef))}`,\n );\n if (relObj['cardinality'])\n parts.push(`readonly cardinality: ${serializeValue(relObj['cardinality'])}`);\n\n const on = relObj['on'] as { localFields?: string[]; targetFields?: string[] } | undefined;\n if (on && (!on.localFields || !on.targetFields)) {\n throw new Error(\n `Relation \"${relName}\" has an \"on\" block but is missing localFields or targetFields`,\n );\n }\n if (on?.localFields && on.targetFields) {\n const localFields = on.localFields.map((f) => serializeValue(f)).join(', ');\n const targetFields = on.targetFields.map((f) => serializeValue(f)).join(', ');\n parts.push(\n `readonly on: { readonly localFields: readonly [${localFields}]; readonly targetFields: readonly [${targetFields}] }`,\n );\n }\n\n if (relObj['cardinality'] === 'N:M') {\n const { through } = blindCast<\n ContractManyToManyRelation,\n 'contract JSON schema-validated before serialization; cardinality N:M check above confirms the junction variant carries through'\n >(relObj);\n const table = serializeValue(through.table);\n const namespaceId = serializeValue(through.namespaceId);\n const parentColumns = through.parentColumns.map((c) => serializeValue(c)).join(', ');\n const childColumns = through.childColumns.map((c) => serializeValue(c)).join(', ');\n const targetColumns = through.targetColumns.map((c) => serializeValue(c)).join(', ');\n parts.push(\n `readonly through: { readonly table: ${table}; readonly namespaceId: ${namespaceId}; readonly parentColumns: readonly [${parentColumns}]; readonly childColumns: readonly [${childColumns}]; readonly targetColumns: readonly [${targetColumns}] }`,\n );\n }\n\n if (parts.length > 0) {\n relationEntries.push(`readonly ${serializeObjectKey(relName)}: { ${parts.join('; ')} }`);\n }\n }\n\n if (relationEntries.length === 0) {\n return 'Record<string, never>';\n }\n\n return `{ ${relationEntries.join('; ')} }`;\n}\n\nexport function generateModelsType(\n models: Record<string, ContractModel>,\n generateModelStorage: (modelName: string, model: ContractModel) => string,\n): string {\n if (!models || Object.keys(models).length === 0) {\n return 'Record<string, never>';\n }\n\n const modelTypes: string[] = [];\n for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {\n const fieldsType = generateModelFieldsType(model.fields);\n const relationsType = generateModelRelationsType(model.relations);\n const storageType = generateModelStorage(modelName, model);\n\n const modelParts: string[] = [\n `readonly fields: ${fieldsType}`,\n `readonly relations: ${relationsType}`,\n `readonly storage: ${storageType}`,\n ];\n\n if (model.owner) {\n modelParts.push(`readonly owner: ${serializeValue(model.owner)}`);\n }\n if (model.discriminator) {\n modelParts.push(`readonly discriminator: ${serializeValue(model.discriminator)}`);\n }\n if (model.variants) {\n modelParts.push(`readonly variants: ${serializeValue(model.variants)}`);\n }\n if (model.base) {\n modelParts.push(`readonly base: ${serializeCrossReference(model.base)}`);\n }\n\n modelTypes.push(`readonly ${modelName}: { ${modelParts.join('; ')} }`);\n }\n\n return `{ ${modelTypes.join('; ')} }`;\n}\n\nexport function deduplicateImports(imports: TypesImportSpec[]): TypesImportSpec[] {\n const seenKeys = new Set<string>();\n const result: TypesImportSpec[] = [];\n for (const imp of imports) {\n const key = `${imp.package}::${imp.named}`;\n if (!seenKeys.has(key)) {\n seenKeys.add(key);\n result.push(imp);\n }\n }\n return result;\n}\n\nexport function generateImportLines(imports: TypesImportSpec[]): string[] {\n const requirements: ImportRequirement[] = imports.map((imp) => ({\n moduleSpecifier: imp.package,\n symbol: imp.named,\n alias: imp.alias,\n typeOnly: true,\n }));\n const rendered = renderImports(requirements);\n return rendered === '' ? [] : rendered.split('\\n');\n}\n\nexport function generateCodecTypeIntersection(\n imports: ReadonlyArray<TypesImportSpec>,\n named: string,\n): string {\n const aliases = imports.filter((imp) => imp.named === named).map((imp) => imp.alias);\n return aliases.join(' & ') || 'Record<string, never>';\n}\n\nexport function serializeExecutionType(execution: Record<string, unknown>): string {\n const parts: string[] = ['readonly executionHash: ExecutionHash'];\n for (const [key, value] of Object.entries(execution)) {\n if (key === 'executionHash') continue;\n parts.push(`readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`);\n }\n return `{ ${parts.join('; ')} }`;\n}\n\nexport function generateHashTypeAliases(hashes: {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n}): string {\n const executionHashType = hashes.executionHash\n ? `ExecutionHashBase<'${hashes.executionHash}'>`\n : 'ExecutionHashBase<string>';\n\n return [\n `export type StorageHash = StorageHashBase<'${hashes.storageHash}'>;`,\n `export type ExecutionHash = ${executionHashType};`,\n `export type ProfileHash = ProfileHashBase<'${hashes.profileHash}'>;`,\n ].join('\\n');\n}\n\nexport type ResolvedFieldType = { readonly input: string; readonly output: string };\n\nfunction applyModifiers(base: string, field: ContractField): string {\n let result = base;\n if (field.many === true) result = `ReadonlyArray<${result}>`;\n if (field.dict === true) result = `Readonly<Record<string, ${result}>>`;\n if (field.nullable) result = `${result} | null`;\n return result;\n}\n\n/**\n * Per-family resolver for typeParams that don't live inline on the framework-domain `ContractField`. SQL columns authored via a named `storage.types` entry carry their `typeRef` on the storage column (family-specific) rather than on the framework's domain field; the per-family emitter walks `storage.types[ref].typeParams` here so the framework emit path can render the parameterized output type.\n *\n * Returns `undefined` when the field has no resolvable typeParams (i.e. the column isn't parameterized, isn't a `typeRef`, or the family doesn't support named storage types).\n */\nexport type FieldTypeParamsResolver = (\n modelName: string,\n fieldName: string,\n model: ContractModel,\n) => Record<string, unknown> | undefined;\n\n/**\n * Resolves a domain field's `valueSet` ref to the member values of the referenced enum.\n * Returns `undefined` when the ref cannot be resolved to a domain enum, so the emit path\n * falls back to the codec channel.\n */\nexport type EnumValuesResolver = (ref: ValueSetRef) => readonly JsonValue[] | undefined;\n\nfunction renderEnumMemberLiteral(value: JsonValue): string | undefined {\n if (value === null) return 'null';\n if (typeof value === 'string') return serializeValue(value);\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n return undefined;\n}\n\nfunction renderEnumValueUnion(values: readonly JsonValue[]): string | undefined {\n if (values.length === 0) return undefined;\n const literals: string[] = [];\n for (const value of values) {\n const literal = renderEnumMemberLiteral(value);\n if (literal === undefined) return undefined;\n literals.push(literal);\n }\n const union = literals.join(' | ');\n return isSafeTypeExpression(union) ? union : undefined;\n}\n\nexport function resolveFieldType(\n field: ContractField,\n codecLookup?: CodecLookup,\n resolvedTypeParams?: Record<string, unknown>,\n resolveEnumValues?: EnumValuesResolver,\n): ResolvedFieldType {\n const { type } = field;\n\n switch (type.kind) {\n case 'scalar': {\n if (field.valueSet?.entityKind === 'enum' && resolveEnumValues) {\n const values = resolveEnumValues(field.valueSet);\n const union = values ? renderEnumValueUnion(values) : undefined;\n if (union !== undefined) {\n return {\n output: applyModifiers(union, field),\n input: applyModifiers(union, field),\n };\n }\n }\n let outputResolved: string | undefined;\n const inlineTypeParams =\n type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : undefined;\n const effectiveTypeParams = inlineTypeParams ?? resolvedTypeParams;\n if (codecLookup && effectiveTypeParams && Object.keys(effectiveTypeParams).length > 0) {\n const rendered = codecLookup.renderOutputTypeFor(type.codecId, effectiveTypeParams);\n if (rendered && isSafeTypeExpression(rendered)) {\n outputResolved = rendered;\n }\n }\n const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;\n return {\n output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),\n input: applyModifiers(`${codecAccessor}['input']`, field),\n };\n }\n case 'valueObject':\n return {\n output: applyModifiers(`${type.name}Output`, field),\n input: applyModifiers(`${type.name}Input`, field),\n };\n case 'union': {\n const outputMembers = type.members.map((m) =>\n m.kind === 'scalar'\n ? `CodecTypes[${serializeValue(m.codecId)}]['output']`\n : `${m.name}Output`,\n );\n const inputMembers = type.members.map((m) =>\n m.kind === 'scalar'\n ? `CodecTypes[${serializeValue(m.codecId)}]['input']`\n : `${m.name}Input`,\n );\n return {\n output: applyModifiers(outputMembers.join(' | '), field),\n input: applyModifiers(inputMembers.join(' | '), field),\n };\n }\n default:\n return {\n output: applyModifiers('unknown', field),\n input: applyModifiers('unknown', field),\n };\n }\n}\n\nexport function generateFieldResolvedType(\n field: ContractField,\n codecLookup?: CodecLookup,\n side: 'input' | 'output' = 'output',\n): string {\n return resolveFieldType(field, codecLookup)[side];\n}\n\nexport function generateBothFieldTypesMaps(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n resolveEnumValues?: EnumValuesResolver,\n): ResolvedFieldType {\n if (!models || Object.keys(models).length === 0) {\n return { output: 'Record<string, never>', input: 'Record<string, never>' };\n }\n\n const outputModelEntries: string[] = [];\n const inputModelEntries: string[] = [];\n for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {\n if (!model) continue;\n const outputFieldEntries: string[] = [];\n const inputFieldEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(model.fields)) {\n const inlineTypeParams =\n field.type.kind === 'scalar' &&\n field.type.typeParams &&\n Object.keys(field.type.typeParams).length > 0\n ? field.type.typeParams\n : undefined;\n const resolvedTypeParams =\n inlineTypeParams ?? resolveFieldTypeParams?.(modelName, fieldName, model);\n const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams, resolveEnumValues);\n const key = `readonly ${serializeObjectKey(fieldName)}`;\n outputFieldEntries.push(`${key}: ${resolved.output}`);\n inputFieldEntries.push(`${key}: ${resolved.input}`);\n }\n const outputFields =\n outputFieldEntries.length > 0\n ? `{ ${outputFieldEntries.join('; ')} }`\n : 'Record<string, never>';\n const inputFields =\n inputFieldEntries.length > 0\n ? `{ ${inputFieldEntries.join('; ')} }`\n : 'Record<string, never>';\n const modelKey = `readonly ${serializeObjectKey(modelName)}`;\n outputModelEntries.push(`${modelKey}: ${outputFields}`);\n inputModelEntries.push(`${modelKey}: ${inputFields}`);\n }\n\n return {\n output: `{ ${outputModelEntries.join('; ')} }`,\n input: `{ ${inputModelEntries.join('; ')} }`,\n };\n}\n\nexport function generateFieldOutputTypesMap(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n resolveEnumValues?: EnumValuesResolver,\n): string {\n return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues)\n .output;\n}\n\nexport function generateFieldInputTypesMap(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n resolveEnumValues?: EnumValuesResolver,\n): string {\n return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues)\n .input;\n}\n\nexport function generateValueObjectType(\n _voName: string,\n vo: ContractValueObject,\n _valueObjects: Record<string, ContractValueObject>,\n side: 'input' | 'output' = 'output',\n codecLookup?: CodecLookup,\n): string {\n return resolveValueObjectType(_voName, vo, _valueObjects, codecLookup)[side];\n}\n\nexport function resolveValueObjectType(\n _voName: string,\n vo: ContractValueObject,\n _valueObjects: Record<string, ContractValueObject>,\n codecLookup?: CodecLookup,\n): ResolvedFieldType {\n const outputEntries: string[] = [];\n const inputEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(vo.fields)) {\n const resolved = resolveFieldType(field, codecLookup);\n const key = `readonly ${serializeObjectKey(fieldName)}`;\n outputEntries.push(`${key}: ${resolved.output}`);\n inputEntries.push(`${key}: ${resolved.input}`);\n }\n const empty = 'Record<string, never>';\n return {\n output: outputEntries.length > 0 ? `{ ${outputEntries.join('; ')} }` : empty,\n input: inputEntries.length > 0 ? `{ ${inputEntries.join('; ')} }` : empty,\n };\n}\n\nexport function generateContractFieldDescriptor(fieldName: string, field: ContractField): string {\n const mods: string[] = [];\n if (field.many === true) mods.push('; readonly many: true');\n if (field.dict === true) mods.push('; readonly dict: true');\n const modStr = mods.join('');\n\n const { type } = field;\n if (type.kind === 'scalar') {\n const typeParamsSpec =\n type.typeParams && Object.keys(type.typeParams).length > 0\n ? `; readonly typeParams: ${serializeValue(type.typeParams)}`\n : '';\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${modStr} }`;\n }\n if (type.kind === 'valueObject') {\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${modStr} }`;\n }\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: ${serializeValue(type)}${modStr} }`;\n}\n\nexport function generateValueObjectsDescriptorType(\n valueObjects: Record<string, ContractValueObject> | undefined,\n): string {\n if (!valueObjects || Object.keys(valueObjects).length === 0) {\n return 'Record<string, never>';\n }\n\n const voEntries: string[] = [];\n for (const [voName, vo] of Object.entries(valueObjects)) {\n const fieldEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(vo.fields)) {\n fieldEntries.push(generateContractFieldDescriptor(fieldName, field));\n }\n const fieldsType =\n fieldEntries.length > 0 ? `{ ${fieldEntries.join('; ')} }` : 'Record<string, never>';\n voEntries.push(`readonly ${serializeObjectKey(voName)}: { readonly fields: ${fieldsType} }`);\n }\n\n return `{ ${voEntries.join('; ')} }`;\n}\n\nexport function generateValueObjectTypeAliases(\n valueObjects: Record<string, ContractValueObject> | undefined,\n codecLookup?: CodecLookup,\n): string {\n if (!valueObjects || Object.keys(valueObjects).length === 0) {\n return '';\n }\n\n const aliases: string[] = [];\n for (const [voName, vo] of Object.entries(valueObjects)) {\n const resolved = resolveValueObjectType(voName, vo, valueObjects, codecLookup);\n aliases.push(`export type ${voName}Output = ${resolved.output};`);\n aliases.push(`export type ${voName}Input = ${resolved.input};`);\n }\n return aliases.join('\\n');\n}\n"],"mappings":"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"}
|
package/dist/exports/index.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { a as EmitStackInput, i as EmitResult, n as emit, o as EmittedArtifactPaths, r as EmitOptions, s as getEmittedArtifactPaths, t as generateContractDts } from "../index-
|
|
3
|
-
export { EmitOptions, EmitResult, EmitStackInput, EmittedArtifactPaths, deduplicateImports, emit, generateCodecTypeIntersection, generateContractDts, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, getEmittedArtifactPaths, serializeObjectKey, serializeValue };
|
|
1
|
+
import { D as serializeValue, E as serializeObjectKey, _ as generateRootsType, d as generateHashTypeAliases, f as generateImportLines, h as generateModelRelationsType, i as deduplicateImports, l as generateFieldOutputTypesMap, o as generateCodecTypeIntersection } from "../domain-type-generation-DXblsIrF.mjs";
|
|
2
|
+
import { a as EmitStackInput, i as EmitResult, n as emit, o as EmittedArtifactPaths, r as EmitOptions, s as getEmittedArtifactPaths, t as generateContractDts } from "../index-Cjiwoga9.mjs";
|
|
3
|
+
export { type EmitOptions, type EmitResult, type EmitStackInput, type EmittedArtifactPaths, deduplicateImports, emit, generateCodecTypeIntersection, generateContractDts, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, getEmittedArtifactPaths, serializeObjectKey, serializeValue };
|
package/dist/exports/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { n as generateContractDts, r as getEmittedArtifactPaths, t as emit } from "../exports-
|
|
1
|
+
import { n as generateContractDts, r as getEmittedArtifactPaths, t as emit } from "../exports-lo90ks1p.mjs";
|
|
2
2
|
import { deduplicateImports, generateCodecTypeIntersection, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, serializeObjectKey, serializeValue } from "../domain-type-generation.mjs";
|
|
3
3
|
export { deduplicateImports, emit, generateCodecTypeIntersection, generateContractDts, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, getEmittedArtifactPaths, serializeObjectKey, serializeValue };
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateHashTypeAliases, generateImportLines, generateModelsType, generateRootsType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, serializeExecutionType, serializeValue } from "./domain-type-generation.mjs";
|
|
2
|
+
import { blindCast } from "@prisma-next/utils/casts";
|
|
2
3
|
import { canonicalizeContractToObject } from "@prisma-next/contract/hashing";
|
|
3
4
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
4
5
|
import { format } from "prettier";
|
|
5
|
-
import {
|
|
6
|
+
import { DomainNamespaceResolutionError } from "@prisma-next/contract/types";
|
|
6
7
|
//#region src/artifact-paths.ts
|
|
7
8
|
const JSON_EXTENSION = ".json";
|
|
8
9
|
function getEmittedArtifactPaths(outputJsonPath) {
|
|
@@ -24,19 +25,33 @@ function generateContractDts(contract, emitter, codecTypeImports, hashes, option
|
|
|
24
25
|
const familyTypeAliases = emitter.getFamilyTypeAliases(options);
|
|
25
26
|
const typeMapsExpr = emitter.getTypeMapsExpression();
|
|
26
27
|
const storageType = emitter.generateStorageType(contract, "StorageHash");
|
|
27
|
-
const
|
|
28
|
-
|
|
28
|
+
const namespaceEntries = Object.entries(contract.domain.namespaces);
|
|
29
|
+
if (namespaceEntries.length === 0) throw new DomainNamespaceResolutionError("domain has no namespaces");
|
|
30
|
+
for (const [nsId, ns] of namespaceEntries) if (ns === void 0) throw new Error(`domain namespace "${nsId}" is not present on the contract`);
|
|
31
|
+
const modelsRecord = {};
|
|
32
|
+
for (const [, ns] of namespaceEntries) for (const [modelName, model] of Object.entries(blindCast(ns.models))) if (!(modelName in modelsRecord)) modelsRecord[modelName] = model;
|
|
29
33
|
const modelsType = generateModelsType(modelsRecord, (name, model) => emitter.generateModelStorageType(name, model));
|
|
30
34
|
const rootsType = generateRootsType(contract.roots);
|
|
31
|
-
const
|
|
35
|
+
const flatValueObjects = {};
|
|
36
|
+
for (const [, ns] of namespaceEntries) for (const [voName, vo] of Object.entries(blindCast(ns.valueObjects ?? {}))) if (!(voName in flatValueObjects)) flatValueObjects[voName] = vo;
|
|
37
|
+
const valueObjects = Object.keys(flatValueObjects).length > 0 ? flatValueObjects : void 0;
|
|
32
38
|
const valueObjectTypeAliases = generateValueObjectTypeAliases(valueObjects, codecLookup);
|
|
33
39
|
const valueObjectsDescriptor = generateValueObjectsDescriptorType(valueObjects);
|
|
40
|
+
const domainNamespacesType = namespaceEntries.map(([nsId, ns]) => {
|
|
41
|
+
const nsModelsType = generateModelsType(blindCast(ns.models), (name, model) => emitter.generateModelStorageType(name, model));
|
|
42
|
+
const nsValueObjects = blindCast(ns.valueObjects);
|
|
43
|
+
return [
|
|
44
|
+
nsId,
|
|
45
|
+
nsModelsType,
|
|
46
|
+
nsValueObjects !== void 0 && Object.keys(nsValueObjects).length > 0 ? generateValueObjectsDescriptorType(nsValueObjects) : void 0
|
|
47
|
+
];
|
|
48
|
+
}).map(([nsId, nsModelsType, nsValueObjectsDescriptor]) => {
|
|
49
|
+
return ` readonly ${nsId}: {\n readonly models: ${nsModelsType};${nsValueObjectsDescriptor !== void 0 ? `\n readonly valueObjects: ${nsValueObjectsDescriptor};` : ""}\n }`;
|
|
50
|
+
}).join(";\n");
|
|
34
51
|
const executionClause = contract.execution !== void 0 ? `\n readonly execution: ${serializeExecutionType(contract.execution)};` : "";
|
|
35
|
-
const
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
return emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract);
|
|
39
|
-
} : void 0);
|
|
52
|
+
const resolveFieldTypeParams = emitter.resolveFieldTypeParams ? (modelName, fieldName, model) => emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract) : void 0;
|
|
53
|
+
const resolveEnumValues = (ref) => ref.entityKind === "enum" ? contract.domain.namespaces[ref.namespaceId]?.enum?.[ref.name]?.members.map((m) => m.value) : void 0;
|
|
54
|
+
const fieldTypesMaps = generateBothFieldTypesMaps(modelsRecord, codecLookup, resolveFieldTypeParams, resolveEnumValues);
|
|
40
55
|
const contractWrapper = emitter.getContractWrapper("ContractBase", "TypeMaps");
|
|
41
56
|
return `// ⚠️ GENERATED FILE - DO NOT EDIT
|
|
42
57
|
// This file is automatically generated by 'prisma-next contract emit'.
|
|
@@ -46,7 +61,7 @@ ${importLines.join("\n")}
|
|
|
46
61
|
${familyImportLines.join("\n")}
|
|
47
62
|
import type {
|
|
48
63
|
Contract as ContractType,
|
|
49
|
-
|
|
64
|
+
ContractModelDefinitions,
|
|
50
65
|
ExecutionHashBase,
|
|
51
66
|
NamespaceId,
|
|
52
67
|
ProfileHashBase,
|
|
@@ -74,10 +89,7 @@ ${modelsType}
|
|
|
74
89
|
readonly roots: ${rootsType};
|
|
75
90
|
readonly domain: {
|
|
76
91
|
readonly namespaces: {
|
|
77
|
-
|
|
78
|
-
readonly models: ${modelsType};
|
|
79
|
-
${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ""}
|
|
80
|
-
};
|
|
92
|
+
${domainNamespacesType};
|
|
81
93
|
};
|
|
82
94
|
};
|
|
83
95
|
readonly capabilities: ${serializeValue(contract.capabilities)};
|
|
@@ -87,6 +99,8 @@ ${modelsType}
|
|
|
87
99
|
readonly profileHash: ProfileHash;
|
|
88
100
|
};
|
|
89
101
|
|
|
102
|
+
export type Models = ContractModelDefinitions<Contract>;
|
|
103
|
+
|
|
90
104
|
${contractWrapper}
|
|
91
105
|
`;
|
|
92
106
|
}
|
|
@@ -135,4 +149,4 @@ async function emit(contract, stack, targetFamily, options) {
|
|
|
135
149
|
//#endregion
|
|
136
150
|
export { generateContractDts as n, getEmittedArtifactPaths as r, emit as t };
|
|
137
151
|
|
|
138
|
-
//# sourceMappingURL=exports-
|
|
152
|
+
//# sourceMappingURL=exports-lo90ks1p.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports-lo90ks1p.mjs","names":[],"sources":["../src/artifact-paths.ts","../src/generate-contract-dts.ts","../src/emit.ts"],"sourcesContent":["const JSON_EXTENSION = '.json';\n\nexport interface EmittedArtifactPaths {\n readonly jsonPath: string;\n readonly dtsPath: string;\n}\n\nexport function getEmittedArtifactPaths(outputJsonPath: string): EmittedArtifactPaths {\n if (!outputJsonPath.endsWith(JSON_EXTENSION)) {\n throw new Error('Contract output path must end with .json');\n }\n\n return {\n jsonPath: outputJsonPath,\n dtsPath: `${outputJsonPath.slice(0, -JSON_EXTENSION.length)}.d.ts`,\n };\n}\n","import type { Contract, ContractModel, ContractValueObject } from '@prisma-next/contract/types';\nimport { DomainNamespaceResolutionError } from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type {\n EmissionSpi,\n GenerateContractTypesOptions,\n TypesImportSpec,\n} from '@prisma-next/framework-components/emission';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport {\n deduplicateImports,\n type EnumValuesResolver,\n generateBothFieldTypesMaps,\n generateCodecTypeIntersection,\n generateHashTypeAliases,\n generateImportLines,\n generateModelsType,\n generateRootsType,\n generateValueObjectsDescriptorType,\n generateValueObjectTypeAliases,\n serializeExecutionType,\n serializeValue,\n} from './domain-type-generation';\n\nexport function generateContractDts(\n contract: Contract,\n emitter: EmissionSpi,\n codecTypeImports: ReadonlyArray<TypesImportSpec>,\n hashes: {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n },\n options?: GenerateContractTypesOptions,\n codecLookup?: CodecLookup,\n): string {\n const allImports: TypesImportSpec[] = [...codecTypeImports];\n if (options?.queryOperationTypeImports) {\n allImports.push(...options.queryOperationTypeImports);\n }\n const uniqueImports = deduplicateImports(allImports);\n const importLines = generateImportLines(uniqueImports);\n\n const familyImportLines = emitter.getFamilyImports();\n\n const hashAliases = generateHashTypeAliases(hashes);\n\n const codecTypes = generateCodecTypeIntersection(codecTypeImports, 'CodecTypes');\n\n const familyTypeAliases = emitter.getFamilyTypeAliases(options);\n\n const typeMapsExpr = emitter.getTypeMapsExpression();\n\n const storageType = emitter.generateStorageType(contract, 'StorageHash');\n\n const namespaceEntries = Object.entries(contract.domain.namespaces);\n if (namespaceEntries.length === 0) {\n throw new DomainNamespaceResolutionError('domain has no namespaces');\n }\n\n // Validate all namespace entries are present.\n for (const [nsId, ns] of namespaceEntries) {\n if (ns === undefined) {\n throw new Error(`domain namespace \"${nsId}\" is not present on the contract`);\n }\n }\n\n // Flatten all namespace models into one record — first-name-wins on bare-name collision.\n // This is the documented ORM flatten behaviour; the proper per-namespace .d.ts redesign\n // is explicit-namespace-dsl's job (not this interim unblock).\n const modelsRecord: Record<string, ContractModel> = {};\n for (const [, ns] of namespaceEntries) {\n for (const [modelName, model] of Object.entries(\n blindCast<\n Record<string, ContractModel>,\n 'ns.models is a ContractModel record in the emitted IR'\n >(ns.models),\n )) {\n if (!(modelName in modelsRecord)) {\n modelsRecord[modelName] = model;\n }\n }\n }\n const modelsType = generateModelsType(modelsRecord, (name, model) =>\n emitter.generateModelStorageType(name, model),\n );\n\n const rootsType = generateRootsType(contract.roots);\n\n // Flatten value objects across all namespaces — first-name-wins on collision.\n const flatValueObjects: Record<string, ContractValueObject> = {};\n for (const [, ns] of namespaceEntries) {\n for (const [voName, vo] of Object.entries(\n blindCast<\n Record<string, ContractValueObject>,\n 'ns.valueObjects is a ContractValueObject record in the emitted IR (default to {} when absent)'\n >(ns.valueObjects ?? {}),\n )) {\n if (!(voName in flatValueObjects)) {\n flatValueObjects[voName] = vo;\n }\n }\n }\n const valueObjects = Object.keys(flatValueObjects).length > 0 ? flatValueObjects : undefined;\n const valueObjectTypeAliases = generateValueObjectTypeAliases(valueObjects, codecLookup);\n const valueObjectsDescriptor = generateValueObjectsDescriptorType(valueObjects);\n\n // Per-namespace models and value objects types for the domain.namespaces section of ContractBase.\n const perNamespaceTypes: Array<readonly [string, string, string | undefined]> =\n namespaceEntries.map(([nsId, ns]) => {\n const nsModels = blindCast<\n Record<string, ContractModel>,\n 'ns.models is a ContractModel record in the emitted IR'\n >(ns.models);\n const nsModelsType = generateModelsType(nsModels, (name, model) =>\n emitter.generateModelStorageType(name, model),\n );\n const nsValueObjects = blindCast<\n Record<string, ContractValueObject> | undefined,\n 'ns.valueObjects is an optional ContractValueObject record in the emitted IR'\n >(ns.valueObjects);\n const nsValueObjectsDescriptor =\n nsValueObjects !== undefined && Object.keys(nsValueObjects).length > 0\n ? generateValueObjectsDescriptorType(nsValueObjects)\n : undefined;\n return [nsId, nsModelsType, nsValueObjectsDescriptor] as const;\n });\n\n const domainNamespacesType = perNamespaceTypes\n .map(([nsId, nsModelsType, nsValueObjectsDescriptor]) => {\n const voLine =\n nsValueObjectsDescriptor !== undefined\n ? `\\n readonly valueObjects: ${nsValueObjectsDescriptor};`\n : '';\n return ` readonly ${nsId}: {\\n readonly models: ${nsModelsType};${voLine}\\n }`;\n })\n .join(';\\n');\n\n const executionClause =\n contract.execution !== undefined\n ? `\\n readonly execution: ${serializeExecutionType(contract.execution)};`\n : '';\n\n const resolveFieldTypeParams = emitter.resolveFieldTypeParams\n ? (modelName: string, fieldName: string, model: ContractModel) =>\n emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract)\n : undefined;\n\n const resolveEnumValues: EnumValuesResolver = (ref) =>\n ref.entityKind === 'enum'\n ? contract.domain.namespaces[ref.namespaceId]?.enum?.[ref.name]?.members.map((m) => m.value)\n : undefined;\n\n const fieldTypesMaps = generateBothFieldTypesMaps(\n modelsRecord,\n codecLookup,\n resolveFieldTypeParams,\n resolveEnumValues,\n );\n\n const contractWrapper = emitter.getContractWrapper('ContractBase', 'TypeMaps');\n\n return `// ⚠️ GENERATED FILE - DO NOT EDIT\n// This file is automatically generated by 'prisma-next contract emit'.\n// To regenerate, run: prisma-next contract emit\n${importLines.join('\\n')}\n\n${familyImportLines.join('\\n')}\nimport type {\n Contract as ContractType,\n ContractModelDefinitions,\n ExecutionHashBase,\n NamespaceId,\n ProfileHashBase,\n StorageHashBase,\n} from '@prisma-next/contract/types';\n\n${hashAliases}\n\nexport type CodecTypes = ${codecTypes};\n${familyTypeAliases}\n${valueObjectTypeAliases}\nexport type FieldOutputTypes = ${fieldTypesMaps.output};\nexport type FieldInputTypes = ${fieldTypesMaps.input};\nexport type TypeMaps = ${typeMapsExpr};\n\ntype ContractBase = Omit<\n ContractType<\n${storageType},\n${modelsType}\n >,\n 'roots' | 'domain'\n> & {\n readonly target: ${serializeValue(contract.target)};\n readonly targetFamily: ${serializeValue(contract.targetFamily)};\n readonly roots: ${rootsType};\n readonly domain: {\n readonly namespaces: {\n${domainNamespacesType};\n };\n };\n readonly capabilities: ${serializeValue(contract.capabilities)};\n readonly extensionPacks: ${serializeValue(contract.extensionPacks)};${executionClause}\n readonly meta: ${serializeValue(contract.meta)};\n ${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ''}\n readonly profileHash: ProfileHash;\n};\n\nexport type Models = ContractModelDefinitions<Contract>;\n\n${contractWrapper}\n`;\n}\n","import { canonicalizeContractToObject } from '@prisma-next/contract/hashing';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { EmissionSpi } from '@prisma-next/framework-components/emission';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { format } from 'prettier';\nimport { getEmittedArtifactPaths } from './artifact-paths';\nimport type { EmitOptions, EmitResult, EmitStackInput } from './emit-types';\nimport { generateContractDts } from './generate-contract-dts';\n\nconst SCHEMA_VERSION = '1';\n\nexport async function emit(\n contract: Contract,\n stack: EmitStackInput,\n targetFamily: EmissionSpi,\n options: EmitOptions,\n): Promise<EmitResult> {\n if (options.outputJsonPath !== undefined) {\n getEmittedArtifactPaths(options.outputJsonPath);\n }\n\n const { codecTypeImports, queryOperationTypeImports } = stack;\n\n const { storageHash } = contract.storage;\n const executionHash = contract.execution?.executionHash;\n const { profileHash } = contract;\n\n const canonicalized = canonicalizeContractToObject(contract, {\n schemaVersion: SCHEMA_VERSION,\n serializeContract: options.serializeContract,\n ...ifDefined('shouldPreserveEmpty', options.shouldPreserveEmpty),\n ...ifDefined('sortStorage', options.sortStorage),\n });\n const contractJsonString = JSON.stringify(\n {\n ...canonicalized,\n _generated: {\n warning: '⚠️ GENERATED FILE - DO NOT EDIT',\n message: 'This file is automatically generated by \"prisma-next contract emit\".',\n regenerate: 'To regenerate, run: prisma-next contract emit',\n },\n },\n null,\n 2,\n );\n\n const generateOptions = queryOperationTypeImports ? { queryOperationTypeImports } : undefined;\n\n const contractTypeHashes = {\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n const contractDtsRaw = generateContractDts(\n contract,\n targetFamily,\n codecTypeImports ?? [],\n contractTypeHashes,\n generateOptions,\n stack.codecLookup,\n );\n const contractDts = await format(contractDtsRaw, {\n parser: 'typescript',\n singleQuote: true,\n semi: true,\n printWidth: 100,\n });\n\n return {\n contractJson: contractJsonString,\n contractDts,\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n}\n"],"mappings":";;;;;;;AAAA,MAAM,iBAAiB;AAOvB,SAAgB,wBAAwB,gBAA8C;CACpF,IAAI,CAAC,eAAe,SAAS,cAAc,GACzC,MAAM,IAAI,MAAM,0CAA0C;CAG5D,OAAO;EACL,UAAU;EACV,SAAS,GAAG,eAAe,MAAM,GAAG,EAAsB,EAAE;CAC9D;AACF;;;ACQA,SAAgB,oBACd,UACA,SACA,kBACA,QAKA,SACA,aACQ;CACR,MAAM,aAAgC,CAAC,GAAG,gBAAgB;CAC1D,IAAI,SAAS,2BACX,WAAW,KAAK,GAAG,QAAQ,yBAAyB;CAGtD,MAAM,cAAc,oBADE,mBAAmB,UACW,CAAC;CAErD,MAAM,oBAAoB,QAAQ,iBAAiB;CAEnD,MAAM,cAAc,wBAAwB,MAAM;CAElD,MAAM,aAAa,8BAA8B,kBAAkB,YAAY;CAE/E,MAAM,oBAAoB,QAAQ,qBAAqB,OAAO;CAE9D,MAAM,eAAe,QAAQ,sBAAsB;CAEnD,MAAM,cAAc,QAAQ,oBAAoB,UAAU,aAAa;CAEvE,MAAM,mBAAmB,OAAO,QAAQ,SAAS,OAAO,UAAU;CAClE,IAAI,iBAAiB,WAAW,GAC9B,MAAM,IAAI,+BAA+B,0BAA0B;CAIrE,KAAK,MAAM,CAAC,MAAM,OAAO,kBACvB,IAAI,OAAO,KAAA,GACT,MAAM,IAAI,MAAM,qBAAqB,KAAK,iCAAiC;CAO/E,MAAM,eAA8C,CAAC;CACrD,KAAK,MAAM,GAAG,OAAO,kBACnB,KAAK,MAAM,CAAC,WAAW,UAAU,OAAO,QACtC,UAGE,GAAG,MAAM,CACb,GACE,IAAI,EAAE,aAAa,eACjB,aAAa,aAAa;CAIhC,MAAM,aAAa,mBAAmB,eAAe,MAAM,UACzD,QAAQ,yBAAyB,MAAM,KAAK,CAC9C;CAEA,MAAM,YAAY,kBAAkB,SAAS,KAAK;CAGlD,MAAM,mBAAwD,CAAC;CAC/D,KAAK,MAAM,GAAG,OAAO,kBACnB,KAAK,MAAM,CAAC,QAAQ,OAAO,OAAO,QAChC,UAGE,GAAG,gBAAgB,CAAC,CAAC,CACzB,GACE,IAAI,EAAE,UAAU,mBACd,iBAAiB,UAAU;CAIjC,MAAM,eAAe,OAAO,KAAK,gBAAgB,CAAC,CAAC,SAAS,IAAI,mBAAmB,KAAA;CACnF,MAAM,yBAAyB,+BAA+B,cAAc,WAAW;CACvF,MAAM,yBAAyB,mCAAmC,YAAY;CAuB9E,MAAM,uBAnBJ,iBAAiB,KAAK,CAAC,MAAM,QAAQ;EAKnC,MAAM,eAAe,mBAJJ,UAGf,GAAG,MAC0C,IAAI,MAAM,UACvD,QAAQ,yBAAyB,MAAM,KAAK,CAC9C;EACA,MAAM,iBAAiB,UAGrB,GAAG,YAAY;EAKjB,OAAO;GAAC;GAAM;GAHZ,mBAAmB,KAAA,KAAa,OAAO,KAAK,cAAc,CAAC,CAAC,SAAS,IACjE,mCAAmC,cAAc,IACjD,KAAA;EAC8C;CACtD,CAE2C,CAAC,CAC3C,KAAK,CAAC,MAAM,cAAc,8BAA8B;EAKvD,OAAO,kBAAkB,KAAK,gCAAgC,aAAa,GAHzE,6BAA6B,KAAA,IACzB,oCAAoC,yBAAyB,KAC7D,GAC+E;CACvF,CAAC,CAAC,CACD,KAAK,KAAK;CAEb,MAAM,kBACJ,SAAS,cAAc,KAAA,IACnB,2BAA2B,uBAAuB,SAAS,SAAS,EAAE,KACtE;CAEN,MAAM,yBAAyB,QAAQ,0BAClC,WAAmB,WAAmB,UACrC,QAAQ,yBAAyB,WAAW,WAAW,OAAO,QAAQ,IACxE,KAAA;CAEJ,MAAM,qBAAyC,QAC7C,IAAI,eAAe,SACf,SAAS,OAAO,WAAW,IAAI,YAAY,EAAE,OAAO,IAAI,KAAK,EAAE,QAAQ,KAAK,MAAM,EAAE,KAAK,IACzF,KAAA;CAEN,MAAM,iBAAiB,2BACrB,cACA,aACA,wBACA,iBACF;CAEA,MAAM,kBAAkB,QAAQ,mBAAmB,gBAAgB,UAAU;CAE7E,OAAO;;;EAGP,YAAY,KAAK,IAAI,EAAE;;EAEvB,kBAAkB,KAAK,IAAI,EAAE;;;;;;;;;;EAU7B,YAAY;;2BAEa,WAAW;EACpC,kBAAkB;EAClB,uBAAuB;iCACQ,eAAe,OAAO;gCACvB,eAAe,MAAM;yBAC5B,aAAa;;;;EAIpC,YAAY;EACZ,WAAW;;;;qBAIQ,eAAe,SAAS,MAAM,EAAE;2BAC1B,eAAe,SAAS,YAAY,EAAE;oBAC7C,UAAU;;;EAG5B,qBAAqB;;;2BAGI,eAAe,SAAS,YAAY,EAAE;6BACpC,eAAe,SAAS,cAAc,EAAE,GAAG,gBAAgB;mBACrE,eAAe,SAAS,IAAI,EAAE;IAC7C,eAAe,0BAA0B,uBAAuB,KAAK,GAAG;;;;;;EAM1E,gBAAgB;;AAElB;;;AC3MA,MAAM,iBAAiB;AAEvB,eAAsB,KACpB,UACA,OACA,cACA,SACqB;CACrB,IAAI,QAAQ,mBAAmB,KAAA,GAC7B,wBAAwB,QAAQ,cAAc;CAGhD,MAAM,EAAE,kBAAkB,8BAA8B;CAExD,MAAM,EAAE,gBAAgB,SAAS;CACjC,MAAM,gBAAgB,SAAS,WAAW;CAC1C,MAAM,EAAE,gBAAgB;CAExB,MAAM,gBAAgB,6BAA6B,UAAU;EAC3D,eAAe;EACf,mBAAmB,QAAQ;EAC3B,GAAG,UAAU,uBAAuB,QAAQ,mBAAmB;EAC/D,GAAG,UAAU,eAAe,QAAQ,WAAW;CACjD,CAAC;CACD,MAAM,qBAAqB,KAAK,UAC9B;EACE,GAAG;EACH,YAAY;GACV,SAAS;GACT,SAAS;GACT,YAAY;EACd;CACF,GACA,MACA,CACF;CAEA,MAAM,kBAAkB,4BAA4B,EAAE,0BAA0B,IAAI,KAAA;CAEpF,MAAM,qBAAqB;EACzB;EACA,GAAG,UAAU,iBAAiB,aAAa;EAC3C;CACF;CAgBA,OAAO;EACL,cAAc;EACd,aAAA,MATwB,OARH,oBACrB,UACA,cACA,oBAAoB,CAAC,GACrB,oBACA,iBACA,MAAM,WAEsC,GAAG;GAC/C,QAAQ;GACR,aAAa;GACb,MAAM;GACN,YAAY;EACd,CAAC;EAKC;EACA,GAAG,UAAU,iBAAiB,aAAa;EAC3C;CACF;AACF"}
|
|
@@ -64,4 +64,4 @@ declare function generateContractDts(contract: Contract, emitter: EmissionSpi, c
|
|
|
64
64
|
}, options?: GenerateContractTypesOptions, codecLookup?: CodecLookup): string;
|
|
65
65
|
//#endregion
|
|
66
66
|
export { EmitStackInput as a, EmitResult as i, emit as n, EmittedArtifactPaths as o, EmitOptions as r, getEmittedArtifactPaths as s, generateContractDts as t };
|
|
67
|
-
//# sourceMappingURL=index-
|
|
67
|
+
//# sourceMappingURL=index-Cjiwoga9.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-
|
|
1
|
+
{"version":3,"file":"index-Cjiwoga9.d.mts","names":[],"sources":["../src/artifact-paths.ts","../src/emit-types.ts","../src/emit.ts","../src/generate-contract-dts.ts"],"mappings":";;;;;;UAEiB,oBAAA;EAAA,SACN,QAAA;EAAA,SACA,OAAO;AAAA;AAAA,iBAGF,uBAAA,CAAwB,cAAA,WAAyB,oBAAoB;;;;;;;AALrF;UCWiB,cAAA;EAAA,SACN,gBAAA,GAAmB,aAAA,CAAc,eAAA;EAAA,SACjC,yBAAA,GAA4B,aAAA,CAAc,eAAA;EAAA,SAC1C,YAAA,GAAe,aAAA;EAAA,SACf,WAAA,GAAc,WAAA;AAAA;AAAA,UAGR,WAAA;EAAA,SACN,cAAA;EDd0E;;;;ACMrF;;;;;EDNqF,SCwB1E,iBAAA,EAAmB,iBAAA;EAhBS;;;;EAAA,SAqB5B,mBAAA,GAAsB,sBAAA;EAtBtB;;;;EAAA,SA2BA,WAAA,GAAc,WAAA;AAAA;AAAA,UAGR,UAAA;EAAA,SACN,YAAA;EAAA,SACA,WAAA;EAAA,SACA,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;AAAA;;;iBCtCW,IAAA,CACpB,QAAA,EAAU,QAAA,EACV,KAAA,EAAO,cAAA,EACP,YAAA,EAAc,WAAA,EACd,OAAA,EAAS,WAAA,GACR,OAAA,CAAQ,UAAA;;;iBCQK,mBAAA,CACd,QAAA,EAAU,QAAA,EACV,OAAA,EAAS,WAAA,EACT,gBAAA,EAAkB,aAAA,CAAc,eAAA,GAChC,MAAA;EAAA,SACW,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;AAAA,GAEX,OAAA,GAAU,4BAAA,EACV,WAAA,GAAc,WAAA"}
|
package/dist/test/utils.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as EmitStackInput, i as EmitResult, r as EmitOptions } from "../index-
|
|
1
|
+
import { a as EmitStackInput, i as EmitResult, r as EmitOptions } from "../index-Cjiwoga9.mjs";
|
|
2
2
|
import { Contract, CrossReference } from "@prisma-next/contract/types";
|
|
3
3
|
import { EmissionSpi } from "@prisma-next/framework-components/emission";
|
|
4
4
|
|
|
@@ -14,6 +14,8 @@ type TestContractOverrides = {
|
|
|
14
14
|
targetFamily?: string;
|
|
15
15
|
roots?: Record<string, CrossReference>;
|
|
16
16
|
models?: Record<string, unknown>;
|
|
17
|
+
valueObjects?: Record<string, unknown>;
|
|
18
|
+
enum?: Record<string, unknown>;
|
|
17
19
|
storage?: Record<string, unknown>;
|
|
18
20
|
capabilities?: Record<string, Record<string, boolean>>;
|
|
19
21
|
extensionPacks?: Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../test/utils.ts"],"mappings":";;;;;;;
|
|
1
|
+
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../test/utils.ts"],"mappings":";;;;;;;AA2CA;;;iBAAgB,IAAA,CACd,QAAA,EAAU,QAAA,EACV,KAAA,EAAO,cAAA,EACP,MAAA,EAAQ,WAAA,EACR,OAAA,GAAU,IAAA,CAAK,WAAA,yBACd,OAAA,CAAQ,UAAA;AAAA,KAQN,qBAAA;EACH,MAAA;EACA,YAAA;EACA,KAAA,GAAQ,MAAA,SAAe,cAAA;EACvB,MAAA,GAAS,MAAA;EACT,YAAA,GAAe,MAAA;EACf,IAAA,GAAO,MAAA;EACP,OAAA,GAAU,MAAA;EACV,YAAA,GAAe,MAAA,SAAe,MAAA;EAC9B,cAAA,GAAiB,MAAA;EACjB,SAAA,GAAY,MAAA;EACZ,IAAA,GAAO,MAAA;EACP,WAAA;EACA,aAAA;EACA,OAAA,GAAU,MAAA;AAAA;;iBAII,2BAAA,CACd,IAAA,EAAM,MAAA,oBACL,MAAM;AAAA,iBAoBO,kBAAA,CAAmB,SAAA,GAAW,qBAAA,GAA6B,QAAQ"}
|
package/dist/test/utils.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as emit$1 } from "../exports-
|
|
1
|
+
import { t as emit$1 } from "../exports-lo90ks1p.mjs";
|
|
2
2
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
3
3
|
import { computeExecutionHash, computeProfileHash, computeStorageHash } from "@prisma-next/contract/hashing";
|
|
4
4
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
@@ -33,7 +33,8 @@ function createContract(overrides = {}) {
|
|
|
33
33
|
roots: overrides.roots ?? {},
|
|
34
34
|
domain: { namespaces: { [UNBOUND_DOMAIN_NAMESPACE_ID]: {
|
|
35
35
|
models: overrides.models ?? blindCast({}),
|
|
36
|
-
...ifDefined("valueObjects", overrides.valueObjects)
|
|
36
|
+
...ifDefined("valueObjects", overrides.valueObjects),
|
|
37
|
+
...ifDefined("enum", overrides.enum)
|
|
37
38
|
} } },
|
|
38
39
|
storage,
|
|
39
40
|
capabilities,
|
|
@@ -59,20 +60,23 @@ const SQL_EMIT_HOOKS = {
|
|
|
59
60
|
"storage",
|
|
60
61
|
"namespaces",
|
|
61
62
|
"*",
|
|
62
|
-
"
|
|
63
|
+
"entries",
|
|
64
|
+
"table"
|
|
63
65
|
],
|
|
64
66
|
[
|
|
65
67
|
"storage",
|
|
66
68
|
"namespaces",
|
|
67
69
|
"*",
|
|
68
|
-
"
|
|
70
|
+
"entries",
|
|
71
|
+
"table",
|
|
69
72
|
"*"
|
|
70
73
|
],
|
|
71
74
|
[
|
|
72
75
|
"storage",
|
|
73
76
|
"namespaces",
|
|
74
77
|
"*",
|
|
75
|
-
"
|
|
78
|
+
"entries",
|
|
79
|
+
"table",
|
|
76
80
|
"*",
|
|
77
81
|
[
|
|
78
82
|
"uniques",
|
|
@@ -84,23 +88,19 @@ const SQL_EMIT_HOOKS = {
|
|
|
84
88
|
"storage",
|
|
85
89
|
"namespaces",
|
|
86
90
|
"*",
|
|
87
|
-
"
|
|
91
|
+
"entries",
|
|
92
|
+
"table",
|
|
88
93
|
"*",
|
|
89
94
|
"foreignKeys",
|
|
90
95
|
["constraint", "index"]
|
|
91
|
-
],
|
|
92
|
-
[
|
|
93
|
-
"storage",
|
|
94
|
-
"types",
|
|
95
|
-
"*",
|
|
96
|
-
"typeParams"
|
|
97
96
|
]
|
|
98
97
|
]),
|
|
99
98
|
sortStorage: createStorageSort([{
|
|
100
99
|
path: [
|
|
101
100
|
"namespaces",
|
|
102
101
|
"*",
|
|
103
|
-
"
|
|
102
|
+
"entries",
|
|
103
|
+
"table",
|
|
104
104
|
"*"
|
|
105
105
|
],
|
|
106
106
|
arrayKeys: ["indexes", "uniques"]
|
package/dist/test/utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":["emitImpl"],"sources":["../../../../../../test/utils/dist/exports/contract-factories.mjs","../../test/utils.ts"],"sourcesContent":["import { UNBOUND_DOMAIN_NAMESPACE_ID, coreHash } from \"@prisma-next/contract/types\";\nimport { blindCast } from \"@prisma-next/utils/casts\";\nimport { computeExecutionHash, computeProfileHash, computeStorageHash } from \"@prisma-next/contract/hashing\";\nimport { ifDefined } from \"@prisma-next/utils/defined\";\n//#region src/contract-factories.ts\nconst DUMMY_HASH = coreHash(\"sha256:test\");\nconst DEFAULT_FRAMEWORK_STORAGE = { namespaces: {} };\nconst UNBOUND_NAMESPACE_ID = \"__unbound__\";\nconst DEFAULT_SQL_STORAGE = { namespaces: { [UNBOUND_NAMESPACE_ID]: {\n\tid: UNBOUND_NAMESPACE_ID,\n\
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":["emitImpl"],"sources":["../../../../../../test/utils/dist/exports/contract-factories.mjs","../../test/utils.ts"],"sourcesContent":["import { UNBOUND_DOMAIN_NAMESPACE_ID, coreHash } from \"@prisma-next/contract/types\";\nimport { blindCast } from \"@prisma-next/utils/casts\";\nimport { computeExecutionHash, computeProfileHash, computeStorageHash } from \"@prisma-next/contract/hashing\";\nimport { ifDefined } from \"@prisma-next/utils/defined\";\n//#region src/contract-factories.ts\nconst DUMMY_HASH = coreHash(\"sha256:test\");\nconst DEFAULT_FRAMEWORK_STORAGE = { namespaces: {} };\nconst UNBOUND_NAMESPACE_ID = \"__unbound__\";\nconst DEFAULT_SQL_STORAGE = { namespaces: { [UNBOUND_NAMESPACE_ID]: {\n\tid: UNBOUND_NAMESPACE_ID,\n\tentries: { table: {} }\n} } };\nfunction createContract(overrides = {}) {\n\tconst target = overrides.target ?? \"postgres\";\n\tconst targetFamily = overrides.targetFamily ?? \"sql\";\n\tconst capabilities = overrides.capabilities ?? {};\n\tconst rawStorage = overrides.storage ?? DEFAULT_FRAMEWORK_STORAGE;\n\tconst storageHash = computeStorageHash({\n\t\ttarget,\n\t\ttargetFamily,\n\t\tstorage: rawStorage,\n\t\t...ifDefined(\"shouldPreserveEmpty\", overrides.shouldPreserveEmpty),\n\t\t...ifDefined(\"sortStorage\", overrides.sortStorage)\n\t});\n\tconst storage = {\n\t\t...rawStorage,\n\t\tstorageHash\n\t};\n\tconst computedProfileHash = overrides.profileHash ?? computeProfileHash({\n\t\ttarget,\n\t\ttargetFamily,\n\t\tcapabilities\n\t});\n\treturn {\n\t\ttarget,\n\t\ttargetFamily,\n\t\troots: overrides.roots ?? {},\n\t\tdomain: { namespaces: { [UNBOUND_DOMAIN_NAMESPACE_ID]: {\n\t\t\tmodels: overrides.models ?? blindCast({}),\n\t\t\t...ifDefined(\"valueObjects\", overrides.valueObjects),\n\t\t\t...ifDefined(\"enum\", overrides.enum)\n\t\t} } },\n\t\tstorage,\n\t\tcapabilities,\n\t\textensionPacks: overrides.extensionPacks ?? {},\n\t\t...overrides.execution !== void 0 ? { execution: {\n\t\t\t...overrides.execution,\n\t\t\texecutionHash: computeExecutionHash({\n\t\t\t\ttarget,\n\t\t\t\ttargetFamily,\n\t\t\t\texecution: overrides.execution\n\t\t\t})\n\t\t} } : {},\n\t\tprofileHash: computedProfileHash,\n\t\tmeta: overrides.meta ?? {}\n\t};\n}\nfunction createSqlContract(overrides = {}) {\n\treturn createContract({\n\t\t...overrides,\n\t\ttarget: overrides.target ?? \"postgres\",\n\t\ttargetFamily: overrides.targetFamily ?? \"sql\",\n\t\tstorage: overrides.storage ?? DEFAULT_SQL_STORAGE\n\t});\n}\n//#endregion\nexport { DUMMY_HASH, createContract, createSqlContract };\n\n//# sourceMappingURL=contract-factories.mjs.map","import type {\n CanonicalizeContractOptions,\n PreserveEmptyPredicate,\n} from '@prisma-next/contract/hashing';\nimport {\n createPreserveEmptyPredicate,\n createStorageSort,\n type NamedArraySortTarget,\n type PathPattern,\n} from '@prisma-next/contract/hashing-utils';\nimport type { Contract, CrossReference } from '@prisma-next/contract/types';\nimport type { EmissionSpi } from '@prisma-next/framework-components/emission';\nimport { createContract } from '@prisma-next/test-utils/contract-factories';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport type { EmitOptions, EmitResult, EmitStackInput } from '../src/exports';\nimport { emit as emitImpl } from '../src/exports';\n\nconst identitySerialize = (c: Contract): JsonObject => c as unknown as JsonObject;\n\nconst sqlPreserveEmptyPatterns = [\n ['storage', 'namespaces', '*', 'entries', 'table'],\n ['storage', 'namespaces', '*', 'entries', 'table', '*'],\n ['storage', 'namespaces', '*', 'entries', 'table', '*', ['uniques', 'indexes', 'foreignKeys']],\n ['storage', 'namespaces', '*', 'entries', 'table', '*', 'foreignKeys', ['constraint', 'index']],\n] as const satisfies readonly PathPattern[];\n\nconst sqlSortTargets = [\n { path: ['namespaces', '*', 'entries', 'table', '*'], arrayKeys: ['indexes', 'uniques'] },\n] as const satisfies readonly NamedArraySortTarget[];\n\nconst sqlPreserveEmpty = createPreserveEmptyPredicate(sqlPreserveEmptyPatterns);\nconst sqlSortStorage = createStorageSort(sqlSortTargets);\n\nconst SQL_EMIT_HOOKS = {\n shouldPreserveEmpty: sqlPreserveEmpty satisfies PreserveEmptyPredicate,\n sortStorage: sqlSortStorage,\n} satisfies Pick<CanonicalizeContractOptions, 'shouldPreserveEmpty' | 'sortStorage'>;\n\n/**\n * Tests author JSON-clean contracts directly, so the canonicalisation\n * hook trivially passes through. Production callers thread the target\n * descriptor's `contractSerializer.serializeContract` instead.\n */\nexport function emit(\n contract: Contract,\n stack: EmitStackInput,\n family: EmissionSpi,\n options?: Omit<EmitOptions, 'serializeContract'>,\n): Promise<EmitResult> {\n return emitImpl(contract, stack, family, {\n ...SQL_EMIT_HOOKS,\n ...options,\n serializeContract: identitySerialize,\n });\n}\n\ntype TestContractOverrides = {\n target?: string;\n targetFamily?: string;\n roots?: Record<string, CrossReference>;\n models?: Record<string, unknown>;\n valueObjects?: Record<string, unknown>;\n enum?: Record<string, unknown>;\n storage?: Record<string, unknown>;\n capabilities?: Record<string, Record<string, boolean>>;\n extensionPacks?: Record<string, unknown>;\n execution?: Record<string, unknown>;\n meta?: Record<string, unknown>;\n storageHash?: string;\n schemaVersion?: string;\n sources?: Record<string, unknown>;\n};\n\n/** Models map from canonical contract JSON (`domain.namespaces`, single namespace only). */\nexport function modelsFromCanonicalContract(\n json: Record<string, unknown>,\n): Record<string, unknown> {\n const domain = json['domain'] as Record<string, unknown> | undefined;\n const namespaces = domain?.['namespaces'] as Record<string, unknown> | undefined;\n if (namespaces === undefined) {\n return {};\n }\n const namespaceIds = Object.keys(namespaces);\n if (namespaceIds.length !== 1) {\n throw new Error(\n `expected exactly one domain namespace in canonical JSON, found ${namespaceIds.length}`,\n );\n }\n const slice = namespaces[namespaceIds[0]!] as Record<string, unknown> | undefined;\n const models = slice?.['models'];\n if (models !== undefined && typeof models === 'object' && models !== null) {\n return models as Record<string, unknown>;\n }\n return {};\n}\n\nexport function createTestContract(overrides: TestContractOverrides = {}): Contract {\n const { storageHash: _sh, schemaVersion: _sv, sources: _src, storage, ...rest } = overrides;\n const cleanStorage = storage\n ? (() => {\n const { storageHash: _innerSh, ...storageRest } = storage as Record<string, unknown>;\n return storageRest;\n })()\n : undefined;\n return createContract({\n ...rest,\n ...(cleanStorage ? { storage: cleanStorage } : {}),\n } as Parameters<typeof createContract>[0]);\n}\n"],"mappings":";;;;;;AAKmB,SAAS,aAAa;AACzC,MAAM,4BAA4B,EAAE,YAAY,CAAC,EAAE;AAMnD,SAAS,eAAe,YAAY,CAAC,GAAG;CACvC,MAAM,SAAS,UAAU,UAAU;CACnC,MAAM,eAAe,UAAU,gBAAgB;CAC/C,MAAM,eAAe,UAAU,gBAAgB,CAAC;CAChD,MAAM,aAAa,UAAU,WAAW;CACxC,MAAM,cAAc,mBAAmB;EACtC;EACA;EACA,SAAS;EACT,GAAG,UAAU,uBAAuB,UAAU,mBAAmB;EACjE,GAAG,UAAU,eAAe,UAAU,WAAW;CAClD,CAAC;CACD,MAAM,UAAU;EACf,GAAG;EACH;CACD;CACA,MAAM,sBAAsB,UAAU,eAAe,mBAAmB;EACvE;EACA;EACA;CACD,CAAC;CACD,OAAO;EACN;EACA;EACA,OAAO,UAAU,SAAS,CAAC;EAC3B,QAAQ,EAAE,YAAY,GAAG,8BAA8B;GACtD,QAAQ,UAAU,UAAU,UAAU,CAAC,CAAC;GACxC,GAAG,UAAU,gBAAgB,UAAU,YAAY;GACnD,GAAG,UAAU,QAAQ,UAAU,IAAI;EACpC,EAAE,EAAE;EACJ;EACA;EACA,gBAAgB,UAAU,kBAAkB,CAAC;EAC7C,GAAG,UAAU,cAAc,KAAK,IAAI,EAAE,WAAW;GAChD,GAAG,UAAU;GACb,eAAe,qBAAqB;IACnC;IACA;IACA,WAAW,UAAU;GACtB,CAAC;EACF,EAAE,IAAI,CAAC;EACP,aAAa;EACb,MAAM,UAAU,QAAQ,CAAC;CAC1B;AACD;;;ACvCA,MAAM,qBAAqB,MAA4B;AAgBvD,MAAM,iBAAiB;CACrB,qBAJuB,6BAA6B;EAVpD;GAAC;GAAW;GAAc;GAAK;GAAW;EAAO;EACjD;GAAC;GAAW;GAAc;GAAK;GAAW;GAAS;EAAG;EACtD;GAAC;GAAW;GAAc;GAAK;GAAW;GAAS;GAAK;IAAC;IAAW;IAAW;GAAa;EAAC;EAC7F;GAAC;GAAW;GAAc;GAAK;GAAW;GAAS;GAAK;GAAe,CAAC,cAAc,OAAO;EAAC;CAOnB,CAIvC;CACpC,aAJqB,kBAAkB,CAJvC;EAAE,MAAM;GAAC;GAAc;GAAK;GAAW;GAAS;EAAG;EAAG,WAAW,CAAC,WAAW,SAAS;CAAE,CAIpC,CAI1B;AAC5B;;;;;;AAOA,SAAgB,KACd,UACA,OACA,QACA,SACqB;CACrB,OAAOA,OAAS,UAAU,OAAO,QAAQ;EACvC,GAAG;EACH,GAAG;EACH,mBAAmB;CACrB,CAAC;AACH;;AAoBA,SAAgB,4BACd,MACyB;CAEzB,MAAM,aADS,KAAK,SACK,GAAG;CAC5B,IAAI,eAAe,KAAA,GACjB,OAAO,CAAC;CAEV,MAAM,eAAe,OAAO,KAAK,UAAU;CAC3C,IAAI,aAAa,WAAW,GAC1B,MAAM,IAAI,MACR,kEAAkE,aAAa,QACjF;CAGF,MAAM,SADQ,WAAW,aAAa,GAClB,GAAG;CACvB,IAAI,WAAW,KAAA,KAAa,OAAO,WAAW,YAAY,WAAW,MACnE,OAAO;CAET,OAAO,CAAC;AACV;AAEA,SAAgB,mBAAmB,YAAmC,CAAC,GAAa;CAClF,MAAM,EAAE,aAAa,KAAK,eAAe,KAAK,SAAS,MAAM,SAAS,GAAG,SAAS;CAClF,MAAM,eAAe,iBACV;EACL,MAAM,EAAE,aAAa,UAAU,GAAG,gBAAgB;EAClD,OAAO;CACT,EAAA,CAAG,IACH,KAAA;CACJ,OAAO,eAAe;EACpB,GAAG;EACH,GAAI,eAAe,EAAE,SAAS,aAAa,IAAI,CAAC;CAClD,CAAyC;AAC3C"}
|
package/package.json
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/emitter",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0-dev.10",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@prisma-next/contract": "0.
|
|
9
|
-
"@prisma-next/framework-components": "0.
|
|
10
|
-
"@prisma-next/operations": "0.
|
|
11
|
-
"@prisma-next/ts-render": "0.
|
|
12
|
-
"@prisma-next/utils": "0.
|
|
8
|
+
"@prisma-next/contract": "0.13.0-dev.10",
|
|
9
|
+
"@prisma-next/framework-components": "0.13.0-dev.10",
|
|
10
|
+
"@prisma-next/operations": "0.13.0-dev.10",
|
|
11
|
+
"@prisma-next/ts-render": "0.13.0-dev.10",
|
|
12
|
+
"@prisma-next/utils": "0.13.0-dev.10",
|
|
13
13
|
"arktype": "^2.2.0",
|
|
14
14
|
"prettier": "^3.8.3"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@prisma-next/test-utils": "0.
|
|
18
|
-
"@prisma-next/tsconfig": "0.
|
|
19
|
-
"@types/node": "25.
|
|
20
|
-
"@prisma-next/tsdown": "0.
|
|
21
|
-
"tsdown": "0.22.
|
|
17
|
+
"@prisma-next/test-utils": "0.13.0-dev.10",
|
|
18
|
+
"@prisma-next/tsconfig": "0.13.0-dev.10",
|
|
19
|
+
"@types/node": "25.9.1",
|
|
20
|
+
"@prisma-next/tsdown": "0.13.0-dev.10",
|
|
21
|
+
"tsdown": "0.22.1",
|
|
22
22
|
"typescript": "5.9.3",
|
|
23
|
-
"vitest": "4.1.
|
|
23
|
+
"vitest": "4.1.8"
|
|
24
24
|
},
|
|
25
25
|
"peerDependencies": {
|
|
26
26
|
"typescript": ">=5.9"
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import type {
|
|
2
2
|
ContractField,
|
|
3
|
+
ContractManyToManyRelation,
|
|
3
4
|
ContractModel,
|
|
4
5
|
ContractValueObject,
|
|
5
6
|
CrossReference,
|
|
7
|
+
JsonValue,
|
|
8
|
+
ValueSetRef,
|
|
6
9
|
} from '@prisma-next/contract/types';
|
|
7
10
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
8
11
|
import type { TypesImportSpec } from '@prisma-next/framework-components/emission';
|
|
@@ -55,7 +58,8 @@ export function serializeNamespaceId(value: string): string {
|
|
|
55
58
|
export function serializeCrossReference(ref: CrossReference): string {
|
|
56
59
|
const namespace = serializeNamespaceId(String(ref.namespace));
|
|
57
60
|
const model = serializeValue(ref.model);
|
|
58
|
-
|
|
61
|
+
const space = ref.space !== undefined ? `; readonly space: ${serializeValue(ref.space)}` : '';
|
|
62
|
+
return `{ readonly namespace: ${namespace}; readonly model: ${model}${space} }`;
|
|
59
63
|
}
|
|
60
64
|
|
|
61
65
|
export function generateRootsType(roots: Record<string, CrossReference> | undefined): string {
|
|
@@ -104,11 +108,31 @@ export function generateModelRelationsType(relations: Record<string, unknown>):
|
|
|
104
108
|
for (const [relName, rel] of Object.entries(relations)) {
|
|
105
109
|
if (typeof rel !== 'object' || rel === null) continue;
|
|
106
110
|
const relObj = rel as Record<string, unknown>;
|
|
111
|
+
|
|
112
|
+
// Option B: cross-space relations are declared but non-navigable.
|
|
113
|
+
// A relation whose `to.space` is set lives in a foreign contract space;
|
|
114
|
+
// emitting `never` for its entry makes `include` of it a compile error
|
|
115
|
+
// while the relation is still present in the contract JSON for introspection.
|
|
116
|
+
const toRef = relObj['to'];
|
|
117
|
+
// Option B: cross-space relations are declared but non-navigable.
|
|
118
|
+
// When the relation's `to` ref carries a `space` field the target lives
|
|
119
|
+
// in a foreign contract space; emit `never` so `include` of it is a
|
|
120
|
+
// compile error while the relation stays in the contract JSON.
|
|
121
|
+
if (
|
|
122
|
+
toRef !== null &&
|
|
123
|
+
typeof toRef === 'object' &&
|
|
124
|
+
'space' in toRef &&
|
|
125
|
+
toRef.space !== undefined
|
|
126
|
+
) {
|
|
127
|
+
relationEntries.push(`readonly ${serializeObjectKey(relName)}: never`);
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
|
|
107
131
|
const parts: string[] = [];
|
|
108
132
|
|
|
109
|
-
if (
|
|
133
|
+
if (toRef)
|
|
110
134
|
parts.push(
|
|
111
|
-
`readonly to: ${serializeCrossReference(blindCast<CrossReference, 'contract JSON schema-validated before serialization; truthy check above confirms presence'>(
|
|
135
|
+
`readonly to: ${serializeCrossReference(blindCast<CrossReference, 'contract JSON schema-validated before serialization; truthy check above confirms presence'>(toRef))}`,
|
|
112
136
|
);
|
|
113
137
|
if (relObj['cardinality'])
|
|
114
138
|
parts.push(`readonly cardinality: ${serializeValue(relObj['cardinality'])}`);
|
|
@@ -127,8 +151,23 @@ export function generateModelRelationsType(relations: Record<string, unknown>):
|
|
|
127
151
|
);
|
|
128
152
|
}
|
|
129
153
|
|
|
154
|
+
if (relObj['cardinality'] === 'N:M') {
|
|
155
|
+
const { through } = blindCast<
|
|
156
|
+
ContractManyToManyRelation,
|
|
157
|
+
'contract JSON schema-validated before serialization; cardinality N:M check above confirms the junction variant carries through'
|
|
158
|
+
>(relObj);
|
|
159
|
+
const table = serializeValue(through.table);
|
|
160
|
+
const namespaceId = serializeValue(through.namespaceId);
|
|
161
|
+
const parentColumns = through.parentColumns.map((c) => serializeValue(c)).join(', ');
|
|
162
|
+
const childColumns = through.childColumns.map((c) => serializeValue(c)).join(', ');
|
|
163
|
+
const targetColumns = through.targetColumns.map((c) => serializeValue(c)).join(', ');
|
|
164
|
+
parts.push(
|
|
165
|
+
`readonly through: { readonly table: ${table}; readonly namespaceId: ${namespaceId}; readonly parentColumns: readonly [${parentColumns}]; readonly childColumns: readonly [${childColumns}]; readonly targetColumns: readonly [${targetColumns}] }`,
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
|
|
130
169
|
if (parts.length > 0) {
|
|
131
|
-
relationEntries.push(`readonly ${relName}: { ${parts.join('; ')} }`);
|
|
170
|
+
relationEntries.push(`readonly ${serializeObjectKey(relName)}: { ${parts.join('; ')} }`);
|
|
132
171
|
}
|
|
133
172
|
}
|
|
134
173
|
|
|
@@ -253,17 +292,55 @@ function applyModifiers(base: string, field: ContractField): string {
|
|
|
253
292
|
export type FieldTypeParamsResolver = (
|
|
254
293
|
modelName: string,
|
|
255
294
|
fieldName: string,
|
|
295
|
+
model: ContractModel,
|
|
256
296
|
) => Record<string, unknown> | undefined;
|
|
257
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Resolves a domain field's `valueSet` ref to the member values of the referenced enum.
|
|
300
|
+
* Returns `undefined` when the ref cannot be resolved to a domain enum, so the emit path
|
|
301
|
+
* falls back to the codec channel.
|
|
302
|
+
*/
|
|
303
|
+
export type EnumValuesResolver = (ref: ValueSetRef) => readonly JsonValue[] | undefined;
|
|
304
|
+
|
|
305
|
+
function renderEnumMemberLiteral(value: JsonValue): string | undefined {
|
|
306
|
+
if (value === null) return 'null';
|
|
307
|
+
if (typeof value === 'string') return serializeValue(value);
|
|
308
|
+
if (typeof value === 'number' || typeof value === 'boolean') return String(value);
|
|
309
|
+
return undefined;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function renderEnumValueUnion(values: readonly JsonValue[]): string | undefined {
|
|
313
|
+
if (values.length === 0) return undefined;
|
|
314
|
+
const literals: string[] = [];
|
|
315
|
+
for (const value of values) {
|
|
316
|
+
const literal = renderEnumMemberLiteral(value);
|
|
317
|
+
if (literal === undefined) return undefined;
|
|
318
|
+
literals.push(literal);
|
|
319
|
+
}
|
|
320
|
+
const union = literals.join(' | ');
|
|
321
|
+
return isSafeTypeExpression(union) ? union : undefined;
|
|
322
|
+
}
|
|
323
|
+
|
|
258
324
|
export function resolveFieldType(
|
|
259
325
|
field: ContractField,
|
|
260
326
|
codecLookup?: CodecLookup,
|
|
261
327
|
resolvedTypeParams?: Record<string, unknown>,
|
|
328
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
262
329
|
): ResolvedFieldType {
|
|
263
330
|
const { type } = field;
|
|
264
331
|
|
|
265
332
|
switch (type.kind) {
|
|
266
333
|
case 'scalar': {
|
|
334
|
+
if (field.valueSet?.entityKind === 'enum' && resolveEnumValues) {
|
|
335
|
+
const values = resolveEnumValues(field.valueSet);
|
|
336
|
+
const union = values ? renderEnumValueUnion(values) : undefined;
|
|
337
|
+
if (union !== undefined) {
|
|
338
|
+
return {
|
|
339
|
+
output: applyModifiers(union, field),
|
|
340
|
+
input: applyModifiers(union, field),
|
|
341
|
+
};
|
|
342
|
+
}
|
|
343
|
+
}
|
|
267
344
|
let outputResolved: string | undefined;
|
|
268
345
|
const inlineTypeParams =
|
|
269
346
|
type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : undefined;
|
|
@@ -321,6 +398,7 @@ export function generateBothFieldTypesMaps(
|
|
|
321
398
|
models: Record<string, ContractModel> | undefined,
|
|
322
399
|
codecLookup?: CodecLookup,
|
|
323
400
|
resolveFieldTypeParams?: FieldTypeParamsResolver,
|
|
401
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
324
402
|
): ResolvedFieldType {
|
|
325
403
|
if (!models || Object.keys(models).length === 0) {
|
|
326
404
|
return { output: 'Record<string, never>', input: 'Record<string, never>' };
|
|
@@ -339,8 +417,9 @@ export function generateBothFieldTypesMaps(
|
|
|
339
417
|
Object.keys(field.type.typeParams).length > 0
|
|
340
418
|
? field.type.typeParams
|
|
341
419
|
: undefined;
|
|
342
|
-
const resolvedTypeParams =
|
|
343
|
-
|
|
420
|
+
const resolvedTypeParams =
|
|
421
|
+
inlineTypeParams ?? resolveFieldTypeParams?.(modelName, fieldName, model);
|
|
422
|
+
const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams, resolveEnumValues);
|
|
344
423
|
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
345
424
|
outputFieldEntries.push(`${key}: ${resolved.output}`);
|
|
346
425
|
inputFieldEntries.push(`${key}: ${resolved.input}`);
|
|
@@ -368,16 +447,20 @@ export function generateFieldOutputTypesMap(
|
|
|
368
447
|
models: Record<string, ContractModel> | undefined,
|
|
369
448
|
codecLookup?: CodecLookup,
|
|
370
449
|
resolveFieldTypeParams?: FieldTypeParamsResolver,
|
|
450
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
371
451
|
): string {
|
|
372
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
452
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues)
|
|
453
|
+
.output;
|
|
373
454
|
}
|
|
374
455
|
|
|
375
456
|
export function generateFieldInputTypesMap(
|
|
376
457
|
models: Record<string, ContractModel> | undefined,
|
|
377
458
|
codecLookup?: CodecLookup,
|
|
378
459
|
resolveFieldTypeParams?: FieldTypeParamsResolver,
|
|
460
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
379
461
|
): string {
|
|
380
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
462
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues)
|
|
463
|
+
.input;
|
|
381
464
|
}
|
|
382
465
|
|
|
383
466
|
export function generateValueObjectType(
|
|
@@ -1,19 +1,15 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
type ContractModel,
|
|
4
|
-
type ContractValueObject,
|
|
5
|
-
contractModels,
|
|
6
|
-
contractValueObjects,
|
|
7
|
-
resolveSingleDomainNamespaceId,
|
|
8
|
-
} from '@prisma-next/contract/types';
|
|
1
|
+
import type { Contract, ContractModel, ContractValueObject } from '@prisma-next/contract/types';
|
|
2
|
+
import { DomainNamespaceResolutionError } from '@prisma-next/contract/types';
|
|
9
3
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
10
4
|
import type {
|
|
11
5
|
EmissionSpi,
|
|
12
6
|
GenerateContractTypesOptions,
|
|
13
7
|
TypesImportSpec,
|
|
14
8
|
} from '@prisma-next/framework-components/emission';
|
|
9
|
+
import { blindCast } from '@prisma-next/utils/casts';
|
|
15
10
|
import {
|
|
16
11
|
deduplicateImports,
|
|
12
|
+
type EnumValuesResolver,
|
|
17
13
|
generateBothFieldTypesMaps,
|
|
18
14
|
generateCodecTypeIntersection,
|
|
19
15
|
generateHashTypeAliases,
|
|
@@ -57,37 +53,109 @@ export function generateContractDts(
|
|
|
57
53
|
|
|
58
54
|
const storageType = emitter.generateStorageType(contract, 'StorageHash');
|
|
59
55
|
|
|
60
|
-
const
|
|
61
|
-
|
|
56
|
+
const namespaceEntries = Object.entries(contract.domain.namespaces);
|
|
57
|
+
if (namespaceEntries.length === 0) {
|
|
58
|
+
throw new DomainNamespaceResolutionError('domain has no namespaces');
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Validate all namespace entries are present.
|
|
62
|
+
for (const [nsId, ns] of namespaceEntries) {
|
|
63
|
+
if (ns === undefined) {
|
|
64
|
+
throw new Error(`domain namespace "${nsId}" is not present on the contract`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Flatten all namespace models into one record — first-name-wins on bare-name collision.
|
|
69
|
+
// This is the documented ORM flatten behaviour; the proper per-namespace .d.ts redesign
|
|
70
|
+
// is explicit-namespace-dsl's job (not this interim unblock).
|
|
71
|
+
const modelsRecord: Record<string, ContractModel> = {};
|
|
72
|
+
for (const [, ns] of namespaceEntries) {
|
|
73
|
+
for (const [modelName, model] of Object.entries(
|
|
74
|
+
blindCast<
|
|
75
|
+
Record<string, ContractModel>,
|
|
76
|
+
'ns.models is a ContractModel record in the emitted IR'
|
|
77
|
+
>(ns.models),
|
|
78
|
+
)) {
|
|
79
|
+
if (!(modelName in modelsRecord)) {
|
|
80
|
+
modelsRecord[modelName] = model;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
62
84
|
const modelsType = generateModelsType(modelsRecord, (name, model) =>
|
|
63
85
|
emitter.generateModelStorageType(name, model),
|
|
64
86
|
);
|
|
65
87
|
|
|
66
88
|
const rootsType = generateRootsType(contract.roots);
|
|
67
89
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
90
|
+
// Flatten value objects across all namespaces — first-name-wins on collision.
|
|
91
|
+
const flatValueObjects: Record<string, ContractValueObject> = {};
|
|
92
|
+
for (const [, ns] of namespaceEntries) {
|
|
93
|
+
for (const [voName, vo] of Object.entries(
|
|
94
|
+
blindCast<
|
|
95
|
+
Record<string, ContractValueObject>,
|
|
96
|
+
'ns.valueObjects is a ContractValueObject record in the emitted IR (default to {} when absent)'
|
|
97
|
+
>(ns.valueObjects ?? {}),
|
|
98
|
+
)) {
|
|
99
|
+
if (!(voName in flatValueObjects)) {
|
|
100
|
+
flatValueObjects[voName] = vo;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
const valueObjects = Object.keys(flatValueObjects).length > 0 ? flatValueObjects : undefined;
|
|
71
105
|
const valueObjectTypeAliases = generateValueObjectTypeAliases(valueObjects, codecLookup);
|
|
72
106
|
const valueObjectsDescriptor = generateValueObjectsDescriptorType(valueObjects);
|
|
73
107
|
|
|
108
|
+
// Per-namespace models and value objects types for the domain.namespaces section of ContractBase.
|
|
109
|
+
const perNamespaceTypes: Array<readonly [string, string, string | undefined]> =
|
|
110
|
+
namespaceEntries.map(([nsId, ns]) => {
|
|
111
|
+
const nsModels = blindCast<
|
|
112
|
+
Record<string, ContractModel>,
|
|
113
|
+
'ns.models is a ContractModel record in the emitted IR'
|
|
114
|
+
>(ns.models);
|
|
115
|
+
const nsModelsType = generateModelsType(nsModels, (name, model) =>
|
|
116
|
+
emitter.generateModelStorageType(name, model),
|
|
117
|
+
);
|
|
118
|
+
const nsValueObjects = blindCast<
|
|
119
|
+
Record<string, ContractValueObject> | undefined,
|
|
120
|
+
'ns.valueObjects is an optional ContractValueObject record in the emitted IR'
|
|
121
|
+
>(ns.valueObjects);
|
|
122
|
+
const nsValueObjectsDescriptor =
|
|
123
|
+
nsValueObjects !== undefined && Object.keys(nsValueObjects).length > 0
|
|
124
|
+
? generateValueObjectsDescriptorType(nsValueObjects)
|
|
125
|
+
: undefined;
|
|
126
|
+
return [nsId, nsModelsType, nsValueObjectsDescriptor] as const;
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
const domainNamespacesType = perNamespaceTypes
|
|
130
|
+
.map(([nsId, nsModelsType, nsValueObjectsDescriptor]) => {
|
|
131
|
+
const voLine =
|
|
132
|
+
nsValueObjectsDescriptor !== undefined
|
|
133
|
+
? `\n readonly valueObjects: ${nsValueObjectsDescriptor};`
|
|
134
|
+
: '';
|
|
135
|
+
return ` readonly ${nsId}: {\n readonly models: ${nsModelsType};${voLine}\n }`;
|
|
136
|
+
})
|
|
137
|
+
.join(';\n');
|
|
138
|
+
|
|
74
139
|
const executionClause =
|
|
75
140
|
contract.execution !== undefined
|
|
76
141
|
? `\n readonly execution: ${serializeExecutionType(contract.execution)};`
|
|
77
142
|
: '';
|
|
78
143
|
|
|
79
144
|
const resolveFieldTypeParams = emitter.resolveFieldTypeParams
|
|
80
|
-
? (modelName: string, fieldName: string) =>
|
|
81
|
-
|
|
82
|
-
if (!model) return undefined;
|
|
83
|
-
return emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract);
|
|
84
|
-
}
|
|
145
|
+
? (modelName: string, fieldName: string, model: ContractModel) =>
|
|
146
|
+
emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract)
|
|
85
147
|
: undefined;
|
|
86
148
|
|
|
149
|
+
const resolveEnumValues: EnumValuesResolver = (ref) =>
|
|
150
|
+
ref.entityKind === 'enum'
|
|
151
|
+
? contract.domain.namespaces[ref.namespaceId]?.enum?.[ref.name]?.members.map((m) => m.value)
|
|
152
|
+
: undefined;
|
|
153
|
+
|
|
87
154
|
const fieldTypesMaps = generateBothFieldTypesMaps(
|
|
88
155
|
modelsRecord,
|
|
89
156
|
codecLookup,
|
|
90
157
|
resolveFieldTypeParams,
|
|
158
|
+
resolveEnumValues,
|
|
91
159
|
);
|
|
92
160
|
|
|
93
161
|
const contractWrapper = emitter.getContractWrapper('ContractBase', 'TypeMaps');
|
|
@@ -100,7 +168,7 @@ ${importLines.join('\n')}
|
|
|
100
168
|
${familyImportLines.join('\n')}
|
|
101
169
|
import type {
|
|
102
170
|
Contract as ContractType,
|
|
103
|
-
|
|
171
|
+
ContractModelDefinitions,
|
|
104
172
|
ExecutionHashBase,
|
|
105
173
|
NamespaceId,
|
|
106
174
|
ProfileHashBase,
|
|
@@ -128,10 +196,7 @@ ${modelsType}
|
|
|
128
196
|
readonly roots: ${rootsType};
|
|
129
197
|
readonly domain: {
|
|
130
198
|
readonly namespaces: {
|
|
131
|
-
|
|
132
|
-
readonly models: ${modelsType};
|
|
133
|
-
${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ''}
|
|
134
|
-
};
|
|
199
|
+
${domainNamespacesType};
|
|
135
200
|
};
|
|
136
201
|
};
|
|
137
202
|
readonly capabilities: ${serializeValue(contract.capabilities)};
|
|
@@ -141,6 +206,8 @@ ${modelsType}
|
|
|
141
206
|
readonly profileHash: ProfileHash;
|
|
142
207
|
};
|
|
143
208
|
|
|
209
|
+
export type Models = ContractModelDefinitions<Contract>;
|
|
210
|
+
|
|
144
211
|
${contractWrapper}
|
|
145
212
|
`;
|
|
146
213
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domain-type-generation-By4D1JcL.d.mts","names":[],"sources":["../src/domain-type-generation.ts"],"mappings":";;;;;iBAYgB,cAAA,CAAe,KAAc;AAAA,iBA+B7B,kBAAA,CAAmB,GAAW;AAAA,iBAO9B,oBAAA,CAAqB,KAAa;AAAA,iBAIlC,uBAAA,CAAwB,GAAmB,EAAd,cAAc;AAAA,iBAM3C,iBAAA,CAAkB,KAAA,EAAO,MAAM,SAAS,cAAA;AAAA,iBAgBxC,uBAAA,CAAwB,SAAA,UAAmB,KAAA,EAAO,aAAa;AAAA,iBAgB/D,uBAAA,CAAwB,MAAA,EAAQ,MAAM,SAAS,aAAA;AAAA,iBAQ/C,0BAAA,CAA2B,SAAkC,EAAvB,MAAM;AAAA,iBAyC5C,kBAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,GACvB,oBAAA,GAAuB,SAAA,UAAmB,KAAA,EAAO,aAAA;AAAA,iBAqCnC,kBAAA,CAAmB,OAAA,EAAS,eAAA,KAAoB,eAAe;AAAA,iBAa/D,mBAAA,CAAoB,OAA0B,EAAjB,eAAe;AAAA,iBAW5C,6BAAA,CACd,OAAA,EAAS,aAAa,CAAC,eAAA,GACvB,KAAA;AAAA,iBAMc,sBAAA,CAAuB,SAAkC,EAAvB,MAAM;AAAA,iBASxC,uBAAA,CAAwB,MAAA;EAAA,SAC7B,WAAA;EAAA,SACA,aAAA;EAAA,SACA,WAAA;AAAA;AAAA,KAaC,iBAAA;EAAA,SAA+B,KAAA;EAAA,SAAwB,MAAM;AAAA;AAjLzE;;;;;AAAA,KAgMY,uBAAA,IACV,SAAA,UACA,SAAA,aACG,MAAM;AAAA,iBAEK,gBAAA,CACd,KAAA,EAAO,aAAA,EACP,WAAA,GAAc,WAAA,EACd,kBAAA,GAAqB,MAAA,oBACpB,iBAAA;AAAA,iBAkDa,yBAAA,CACd,KAAA,EAAO,aAAA,EACP,WAAA,GAAc,WAAW,EACzB,IAAA;AAAA,iBAKc,0BAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,eACvB,WAAA,GAAc,WAAA,EACd,sBAAA,GAAyB,uBAAA,GACxB,iBAAA;AAAA,iBA2Ca,2BAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,eACvB,WAAA,GAAc,WAAA,EACd,sBAAA,GAAyB,uBAAA;AAAA,iBAKX,0BAAA,CACd,MAAA,EAAQ,MAAA,SAAe,aAAA,eACvB,WAAA,GAAc,WAAA,EACd,sBAAA,GAAyB,uBAAA;AAAA,iBAKX,uBAAA,CACd,OAAA,UACA,EAAA,EAAI,mBAAA,EACJ,aAAA,EAAe,MAAA,SAAe,mBAAA,GAC9B,IAAA,uBACA,WAAA,GAAc,WAAA;AAAA,iBAKA,sBAAA,CACd,OAAA,UACA,EAAA,EAAI,mBAAA,EACJ,aAAA,EAAe,MAAA,SAAe,mBAAA,GAC9B,WAAA,GAAc,WAAA,GACb,iBAAA;AAAA,iBAgBa,+BAAA,CAAgC,SAAA,UAAmB,KAAA,EAAO,aAAa;AAAA,iBAoBvE,kCAAA,CACd,YAAA,EAAc,MAAM,SAAS,mBAAA;AAAA,iBAoBf,8BAAA,CACd,YAAA,EAAc,MAAA,SAAe,mBAAA,eAC7B,WAAA,GAAc,WAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exports-kyH5YvAl.mjs","names":[],"sources":["../src/artifact-paths.ts","../src/generate-contract-dts.ts","../src/emit.ts"],"sourcesContent":["const JSON_EXTENSION = '.json';\n\nexport interface EmittedArtifactPaths {\n readonly jsonPath: string;\n readonly dtsPath: string;\n}\n\nexport function getEmittedArtifactPaths(outputJsonPath: string): EmittedArtifactPaths {\n if (!outputJsonPath.endsWith(JSON_EXTENSION)) {\n throw new Error('Contract output path must end with .json');\n }\n\n return {\n jsonPath: outputJsonPath,\n dtsPath: `${outputJsonPath.slice(0, -JSON_EXTENSION.length)}.d.ts`,\n };\n}\n","import {\n type Contract,\n type ContractModel,\n type ContractValueObject,\n contractModels,\n contractValueObjects,\n resolveSingleDomainNamespaceId,\n} from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type {\n EmissionSpi,\n GenerateContractTypesOptions,\n TypesImportSpec,\n} from '@prisma-next/framework-components/emission';\nimport {\n deduplicateImports,\n generateBothFieldTypesMaps,\n generateCodecTypeIntersection,\n generateHashTypeAliases,\n generateImportLines,\n generateModelsType,\n generateRootsType,\n generateValueObjectsDescriptorType,\n generateValueObjectTypeAliases,\n serializeExecutionType,\n serializeValue,\n} from './domain-type-generation';\n\nexport function generateContractDts(\n contract: Contract,\n emitter: EmissionSpi,\n codecTypeImports: ReadonlyArray<TypesImportSpec>,\n hashes: {\n readonly storageHash: string;\n readonly executionHash?: string;\n readonly profileHash: string;\n },\n options?: GenerateContractTypesOptions,\n codecLookup?: CodecLookup,\n): string {\n const allImports: TypesImportSpec[] = [...codecTypeImports];\n if (options?.queryOperationTypeImports) {\n allImports.push(...options.queryOperationTypeImports);\n }\n const uniqueImports = deduplicateImports(allImports);\n const importLines = generateImportLines(uniqueImports);\n\n const familyImportLines = emitter.getFamilyImports();\n\n const hashAliases = generateHashTypeAliases(hashes);\n\n const codecTypes = generateCodecTypeIntersection(codecTypeImports, 'CodecTypes');\n\n const familyTypeAliases = emitter.getFamilyTypeAliases(options);\n\n const typeMapsExpr = emitter.getTypeMapsExpression();\n\n const storageType = emitter.generateStorageType(contract, 'StorageHash');\n\n const domainNamespaceId = resolveSingleDomainNamespaceId(contract.domain);\n const modelsRecord = contractModels(contract, domainNamespaceId) as Record<string, ContractModel>;\n const modelsType = generateModelsType(modelsRecord, (name, model) =>\n emitter.generateModelStorageType(name, model),\n );\n\n const rootsType = generateRootsType(contract.roots);\n\n const valueObjects = contractValueObjects(contract, domainNamespaceId) as\n | Record<string, ContractValueObject>\n | undefined;\n const valueObjectTypeAliases = generateValueObjectTypeAliases(valueObjects, codecLookup);\n const valueObjectsDescriptor = generateValueObjectsDescriptorType(valueObjects);\n\n const executionClause =\n contract.execution !== undefined\n ? `\\n readonly execution: ${serializeExecutionType(contract.execution)};`\n : '';\n\n const resolveFieldTypeParams = emitter.resolveFieldTypeParams\n ? (modelName: string, fieldName: string) => {\n const model = modelsRecord[modelName];\n if (!model) return undefined;\n return emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract);\n }\n : undefined;\n\n const fieldTypesMaps = generateBothFieldTypesMaps(\n modelsRecord,\n codecLookup,\n resolveFieldTypeParams,\n );\n\n const contractWrapper = emitter.getContractWrapper('ContractBase', 'TypeMaps');\n\n return `// ⚠️ GENERATED FILE - DO NOT EDIT\n// This file is automatically generated by 'prisma-next contract emit'.\n// To regenerate, run: prisma-next contract emit\n${importLines.join('\\n')}\n\n${familyImportLines.join('\\n')}\nimport type {\n Contract as ContractType,\n ContractModelsMap,\n ExecutionHashBase,\n NamespaceId,\n ProfileHashBase,\n StorageHashBase,\n} from '@prisma-next/contract/types';\n\n${hashAliases}\n\nexport type CodecTypes = ${codecTypes};\n${familyTypeAliases}\n${valueObjectTypeAliases}\nexport type FieldOutputTypes = ${fieldTypesMaps.output};\nexport type FieldInputTypes = ${fieldTypesMaps.input};\nexport type TypeMaps = ${typeMapsExpr};\n\ntype ContractBase = Omit<\n ContractType<\n${storageType},\n${modelsType}\n >,\n 'roots' | 'domain'\n> & {\n readonly target: ${serializeValue(contract.target)};\n readonly targetFamily: ${serializeValue(contract.targetFamily)};\n readonly roots: ${rootsType};\n readonly domain: {\n readonly namespaces: {\n readonly ${domainNamespaceId}: {\n readonly models: ${modelsType};\n ${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ''}\n };\n };\n };\n readonly capabilities: ${serializeValue(contract.capabilities)};\n readonly extensionPacks: ${serializeValue(contract.extensionPacks)};${executionClause}\n readonly meta: ${serializeValue(contract.meta)};\n ${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ''}\n readonly profileHash: ProfileHash;\n};\n\n${contractWrapper}\n`;\n}\n","import { canonicalizeContractToObject } from '@prisma-next/contract/hashing';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { EmissionSpi } from '@prisma-next/framework-components/emission';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { format } from 'prettier';\nimport { getEmittedArtifactPaths } from './artifact-paths';\nimport type { EmitOptions, EmitResult, EmitStackInput } from './emit-types';\nimport { generateContractDts } from './generate-contract-dts';\n\nconst SCHEMA_VERSION = '1';\n\nexport async function emit(\n contract: Contract,\n stack: EmitStackInput,\n targetFamily: EmissionSpi,\n options: EmitOptions,\n): Promise<EmitResult> {\n if (options.outputJsonPath !== undefined) {\n getEmittedArtifactPaths(options.outputJsonPath);\n }\n\n const { codecTypeImports, queryOperationTypeImports } = stack;\n\n const { storageHash } = contract.storage;\n const executionHash = contract.execution?.executionHash;\n const { profileHash } = contract;\n\n const canonicalized = canonicalizeContractToObject(contract, {\n schemaVersion: SCHEMA_VERSION,\n serializeContract: options.serializeContract,\n ...ifDefined('shouldPreserveEmpty', options.shouldPreserveEmpty),\n ...ifDefined('sortStorage', options.sortStorage),\n });\n const contractJsonString = JSON.stringify(\n {\n ...canonicalized,\n _generated: {\n warning: '⚠️ GENERATED FILE - DO NOT EDIT',\n message: 'This file is automatically generated by \"prisma-next contract emit\".',\n regenerate: 'To regenerate, run: prisma-next contract emit',\n },\n },\n null,\n 2,\n );\n\n const generateOptions = queryOperationTypeImports ? { queryOperationTypeImports } : undefined;\n\n const contractTypeHashes = {\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n const contractDtsRaw = generateContractDts(\n contract,\n targetFamily,\n codecTypeImports ?? [],\n contractTypeHashes,\n generateOptions,\n stack.codecLookup,\n );\n const contractDts = await format(contractDtsRaw, {\n parser: 'typescript',\n singleQuote: true,\n semi: true,\n printWidth: 100,\n });\n\n return {\n contractJson: contractJsonString,\n contractDts,\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n}\n"],"mappings":"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"}
|