@prisma-next/emitter 0.13.0-dev.3 → 0.13.0-dev.30
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-BSbwyYur.d.mts → domain-type-generation-DXblsIrF.d.mts} +13 -7
- 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 +35 -8
- package/dist/domain-type-generation.mjs.map +1 -1
- package/dist/exports/index.d.mts +1 -1
- package/dist/exports/index.mjs +1 -1
- package/dist/{exports-sTwie_d1.mjs → exports-DJ4VgkiL.mjs} +17 -6
- package/dist/exports-DJ4VgkiL.mjs.map +1 -0
- package/dist/index-Cjiwoga9.d.mts.map +1 -1
- package/dist/test/utils.d.mts +1 -0
- package/dist/test/utils.d.mts.map +1 -1
- package/dist/test/utils.mjs +3 -2
- package/dist/test/utils.mjs.map +1 -1
- package/package.json +9 -9
- package/src/domain-type-generation.ts +53 -4
- package/src/generate-contract-dts.ts +60 -23
- package/dist/domain-type-generation-BSbwyYur.d.mts.map +0 -1
- package/dist/exports-sTwie_d1.mjs.map +0 -1
package/dist/{domain-type-generation-BSbwyYur.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
|
|
|
@@ -31,16 +31,22 @@ type ResolvedFieldType = {
|
|
|
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
33
|
type FieldTypeParamsResolver = (modelName: string, fieldName: string, model: ContractModel) => Record<string, unknown> | undefined;
|
|
34
|
-
|
|
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,iBAiEa,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 };
|
|
@@ -149,20 +149,47 @@ function applyModifiers(base, field) {
|
|
|
149
149
|
if (field.nullable) result = `${result} | null`;
|
|
150
150
|
return result;
|
|
151
151
|
}
|
|
152
|
-
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) {
|
|
153
169
|
const { type } = field;
|
|
154
170
|
switch (type.kind) {
|
|
155
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
|
+
}
|
|
156
180
|
let outputResolved;
|
|
181
|
+
let inputResolved;
|
|
157
182
|
const effectiveTypeParams = (type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : void 0) ?? resolvedTypeParams;
|
|
158
183
|
if (codecLookup && effectiveTypeParams && Object.keys(effectiveTypeParams).length > 0) {
|
|
159
184
|
const rendered = codecLookup.renderOutputTypeFor(type.codecId, effectiveTypeParams);
|
|
160
185
|
if (rendered && isSafeTypeExpression(rendered)) outputResolved = rendered;
|
|
186
|
+
const renderedInput = codecLookup.renderInputTypeFor?.(type.codecId, effectiveTypeParams);
|
|
187
|
+
if (renderedInput && isSafeTypeExpression(renderedInput)) inputResolved = renderedInput;
|
|
161
188
|
}
|
|
162
189
|
const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;
|
|
163
190
|
return {
|
|
164
191
|
output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),
|
|
165
|
-
input: applyModifiers(`${codecAccessor}['input']`, field)
|
|
192
|
+
input: applyModifiers(inputResolved ?? `${codecAccessor}['input']`, field)
|
|
166
193
|
};
|
|
167
194
|
}
|
|
168
195
|
case "valueObject": return {
|
|
@@ -186,7 +213,7 @@ function resolveFieldType(field, codecLookup, resolvedTypeParams) {
|
|
|
186
213
|
function generateFieldResolvedType(field, codecLookup, side = "output") {
|
|
187
214
|
return resolveFieldType(field, codecLookup)[side];
|
|
188
215
|
}
|
|
189
|
-
function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams) {
|
|
216
|
+
function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues) {
|
|
190
217
|
if (!models || Object.keys(models).length === 0) return {
|
|
191
218
|
output: "Record<string, never>",
|
|
192
219
|
input: "Record<string, never>"
|
|
@@ -198,7 +225,7 @@ function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
|
198
225
|
const outputFieldEntries = [];
|
|
199
226
|
const inputFieldEntries = [];
|
|
200
227
|
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
201
|
-
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));
|
|
228
|
+
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);
|
|
202
229
|
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
203
230
|
outputFieldEntries.push(`${key}: ${resolved.output}`);
|
|
204
231
|
inputFieldEntries.push(`${key}: ${resolved.input}`);
|
|
@@ -214,11 +241,11 @@ function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
|
214
241
|
input: `{ ${inputModelEntries.join("; ")} }`
|
|
215
242
|
};
|
|
216
243
|
}
|
|
217
|
-
function generateFieldOutputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
218
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).output;
|
|
244
|
+
function generateFieldOutputTypesMap(models, codecLookup, resolveFieldTypeParams, resolveEnumValues) {
|
|
245
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues).output;
|
|
219
246
|
}
|
|
220
|
-
function generateFieldInputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
221
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).input;
|
|
247
|
+
function generateFieldInputTypesMap(models, codecLookup, resolveFieldTypeParams, resolveEnumValues) {
|
|
248
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues).input;
|
|
222
249
|
}
|
|
223
250
|
function generateValueObjectType(_voName, vo, _valueObjects, side = "output", codecLookup) {
|
|
224
251
|
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 ContractManyToManyRelation,\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 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\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 =\n inlineTypeParams ?? resolveFieldTypeParams?.(modelName, fieldName, model);\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 let inputResolved: 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 const renderedInput = codecLookup.renderInputTypeFor?.(type.codecId, effectiveTypeParams);\n if (renderedInput && isSafeTypeExpression(renderedInput)) {\n inputResolved = renderedInput;\n }\n }\n const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;\n return {\n output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),\n input: applyModifiers(inputResolved ?? `${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 {
|
|
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
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
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-DJ4VgkiL.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,4 +1,4 @@
|
|
|
1
|
-
import { deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateHashTypeAliases, generateImportLines, generateModelsType, generateRootsType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, serializeExecutionType, serializeValue } from "./domain-type-generation.mjs";
|
|
1
|
+
import { deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateHashTypeAliases, generateImportLines, generateModelsType, generateRootsType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, serializeExecutionType, serializeObjectKey, serializeValue } from "./domain-type-generation.mjs";
|
|
2
2
|
import { blindCast } from "@prisma-next/utils/casts";
|
|
3
3
|
import { canonicalizeContractToObject } from "@prisma-next/contract/hashing";
|
|
4
4
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
@@ -15,6 +15,12 @@ function getEmittedArtifactPaths(outputJsonPath) {
|
|
|
15
15
|
}
|
|
16
16
|
//#endregion
|
|
17
17
|
//#region src/generate-contract-dts.ts
|
|
18
|
+
function generateEnumBlockType(enums) {
|
|
19
|
+
return `{ ${Object.entries(enums).map(([name, entry]) => {
|
|
20
|
+
const membersType = `readonly [${entry.members.map((m) => `{ readonly name: ${serializeValue(m.name)}; readonly value: ${serializeValue(m.value)} }`).join(", ")}]`;
|
|
21
|
+
return `readonly ${serializeObjectKey(name)}: { readonly codecId: ${serializeValue(entry.codecId)}; readonly members: ${membersType} }`;
|
|
22
|
+
}).join("; ")} }`;
|
|
23
|
+
}
|
|
18
24
|
function generateContractDts(contract, emitter, codecTypeImports, hashes, options, codecLookup) {
|
|
19
25
|
const allImports = [...codecTypeImports];
|
|
20
26
|
if (options?.queryOperationTypeImports) allImports.push(...options.queryOperationTypeImports);
|
|
@@ -40,16 +46,21 @@ function generateContractDts(contract, emitter, codecTypeImports, hashes, option
|
|
|
40
46
|
const domainNamespacesType = namespaceEntries.map(([nsId, ns]) => {
|
|
41
47
|
const nsModelsType = generateModelsType(blindCast(ns.models), (name, model) => emitter.generateModelStorageType(name, model));
|
|
42
48
|
const nsValueObjects = blindCast(ns.valueObjects);
|
|
49
|
+
const nsValueObjectsDescriptor = nsValueObjects !== void 0 && Object.keys(nsValueObjects).length > 0 ? generateValueObjectsDescriptorType(nsValueObjects) : void 0;
|
|
50
|
+
const nsEnums = blindCast(ns.enum);
|
|
43
51
|
return [
|
|
44
52
|
nsId,
|
|
45
53
|
nsModelsType,
|
|
46
|
-
|
|
54
|
+
nsValueObjectsDescriptor,
|
|
55
|
+
nsEnums !== void 0 && Object.keys(nsEnums).length > 0 ? generateEnumBlockType(nsEnums) : void 0
|
|
47
56
|
];
|
|
48
|
-
}).map(([nsId, nsModelsType, nsValueObjectsDescriptor]) => {
|
|
49
|
-
return ` readonly ${nsId}: {\n readonly models: ${nsModelsType};${nsValueObjectsDescriptor !== void 0 ? `\n readonly valueObjects: ${nsValueObjectsDescriptor};` : ""}\n }`;
|
|
57
|
+
}).map(([nsId, nsModelsType, nsValueObjectsDescriptor, nsEnumBlock]) => {
|
|
58
|
+
return ` readonly ${nsId}: {\n readonly models: ${nsModelsType};${nsValueObjectsDescriptor !== void 0 ? `\n readonly valueObjects: ${nsValueObjectsDescriptor};` : ""}${nsEnumBlock !== void 0 ? `\n readonly enum: ${nsEnumBlock};` : ""}\n }`;
|
|
50
59
|
}).join(";\n");
|
|
51
60
|
const executionClause = contract.execution !== void 0 ? `\n readonly execution: ${serializeExecutionType(contract.execution)};` : "";
|
|
52
|
-
const
|
|
61
|
+
const resolveFieldTypeParams = emitter.resolveFieldTypeParams ? (modelName, fieldName, model) => emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract) : void 0;
|
|
62
|
+
const resolveEnumValues = (ref) => ref.entityKind === "enum" ? contract.domain.namespaces[ref.namespaceId]?.enum?.[ref.entityName]?.members.map((m) => m.value) : void 0;
|
|
63
|
+
const fieldTypesMaps = generateBothFieldTypesMaps(modelsRecord, codecLookup, resolveFieldTypeParams, resolveEnumValues);
|
|
53
64
|
const contractWrapper = emitter.getContractWrapper("ContractBase", "TypeMaps");
|
|
54
65
|
return `// ⚠️ GENERATED FILE - DO NOT EDIT
|
|
55
66
|
// This file is automatically generated by 'prisma-next contract emit'.
|
|
@@ -147,4 +158,4 @@ async function emit(contract, stack, targetFamily, options) {
|
|
|
147
158
|
//#endregion
|
|
148
159
|
export { generateContractDts as n, getEmittedArtifactPaths as r, emit as t };
|
|
149
160
|
|
|
150
|
-
//# sourceMappingURL=exports-
|
|
161
|
+
//# sourceMappingURL=exports-DJ4VgkiL.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports-DJ4VgkiL.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 {\n Contract,\n ContractEnum,\n ContractModel,\n ContractValueObject,\n} 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 serializeObjectKey,\n serializeValue,\n} from './domain-type-generation';\n\nfunction generateEnumBlockType(enums: Record<string, ContractEnum>): string {\n const entries = Object.entries(enums).map(([name, entry]) => {\n const memberTupleItems = entry.members.map(\n (m) =>\n `{ readonly name: ${serializeValue(m.name)}; readonly value: ${serializeValue(m.value)} }`,\n );\n const membersType = `readonly [${memberTupleItems.join(', ')}]`;\n return `readonly ${serializeObjectKey(name)}: { readonly codecId: ${serializeValue(entry.codecId)}; readonly members: ${membersType} }`;\n });\n return `{ ${entries.join('; ')} }`;\n}\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, value objects, and enum types for the domain.namespaces section.\n const perNamespaceTypes: Array<\n readonly [string, string, string | undefined, 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 const nsEnums = blindCast<\n Record<string, ContractEnum> | undefined,\n 'ns.enum is an optional ContractEnum record in the emitted IR'\n >(ns.enum);\n const nsEnumBlock =\n nsEnums !== undefined && Object.keys(nsEnums).length > 0\n ? generateEnumBlockType(nsEnums)\n : undefined;\n return [nsId, nsModelsType, nsValueObjectsDescriptor, nsEnumBlock] as const;\n });\n\n const domainNamespacesType = perNamespaceTypes\n .map(([nsId, nsModelsType, nsValueObjectsDescriptor, nsEnumBlock]) => {\n const voLine =\n nsValueObjectsDescriptor !== undefined\n ? `\\n readonly valueObjects: ${nsValueObjectsDescriptor};`\n : '';\n const enumLine = nsEnumBlock !== undefined ? `\\n readonly enum: ${nsEnumBlock};` : '';\n return ` readonly ${nsId}: {\\n readonly models: ${nsModelsType};${voLine}${enumLine}\\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.entityName]?.members.map(\n (m) => m.value,\n )\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":"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"}
|
|
@@ -1 +1 @@
|
|
|
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;;;
|
|
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;;;iBC0BK,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
|
@@ -15,6 +15,7 @@ type TestContractOverrides = {
|
|
|
15
15
|
roots?: Record<string, CrossReference>;
|
|
16
16
|
models?: Record<string, unknown>;
|
|
17
17
|
valueObjects?: Record<string, unknown>;
|
|
18
|
+
enum?: Record<string, unknown>;
|
|
18
19
|
storage?: Record<string, unknown>;
|
|
19
20
|
capabilities?: Record<string, Record<string, boolean>>;
|
|
20
21
|
extensionPacks?: Record<string, unknown>;
|
|
@@ -1 +1 @@
|
|
|
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,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"}
|
|
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-DJ4VgkiL.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,
|
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\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} } },\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 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;
|
|
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,23 +1,23 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/emitter",
|
|
3
|
-
"version": "0.13.0-dev.
|
|
3
|
+
"version": "0.13.0-dev.30",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@prisma-next/contract": "0.13.0-dev.
|
|
9
|
-
"@prisma-next/framework-components": "0.13.0-dev.
|
|
10
|
-
"@prisma-next/operations": "0.13.0-dev.
|
|
11
|
-
"@prisma-next/ts-render": "0.13.0-dev.
|
|
12
|
-
"@prisma-next/utils": "0.13.0-dev.
|
|
8
|
+
"@prisma-next/contract": "0.13.0-dev.30",
|
|
9
|
+
"@prisma-next/framework-components": "0.13.0-dev.30",
|
|
10
|
+
"@prisma-next/operations": "0.13.0-dev.30",
|
|
11
|
+
"@prisma-next/ts-render": "0.13.0-dev.30",
|
|
12
|
+
"@prisma-next/utils": "0.13.0-dev.30",
|
|
13
13
|
"arktype": "^2.2.0",
|
|
14
14
|
"prettier": "^3.8.3"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@prisma-next/test-utils": "0.13.0-dev.
|
|
18
|
-
"@prisma-next/tsconfig": "0.13.0-dev.
|
|
17
|
+
"@prisma-next/test-utils": "0.13.0-dev.30",
|
|
18
|
+
"@prisma-next/tsconfig": "0.13.0-dev.30",
|
|
19
19
|
"@types/node": "25.9.1",
|
|
20
|
-
"@prisma-next/tsdown": "0.13.0-dev.
|
|
20
|
+
"@prisma-next/tsdown": "0.13.0-dev.30",
|
|
21
21
|
"tsdown": "0.22.1",
|
|
22
22
|
"typescript": "5.9.3",
|
|
23
23
|
"vitest": "4.1.8"
|
|
@@ -4,6 +4,8 @@ import type {
|
|
|
4
4
|
ContractModel,
|
|
5
5
|
ContractValueObject,
|
|
6
6
|
CrossReference,
|
|
7
|
+
JsonValue,
|
|
8
|
+
ValueSetRef,
|
|
7
9
|
} from '@prisma-next/contract/types';
|
|
8
10
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
9
11
|
import type { TypesImportSpec } from '@prisma-next/framework-components/emission';
|
|
@@ -293,16 +295,54 @@ export type FieldTypeParamsResolver = (
|
|
|
293
295
|
model: ContractModel,
|
|
294
296
|
) => Record<string, unknown> | undefined;
|
|
295
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
|
+
|
|
296
324
|
export function resolveFieldType(
|
|
297
325
|
field: ContractField,
|
|
298
326
|
codecLookup?: CodecLookup,
|
|
299
327
|
resolvedTypeParams?: Record<string, unknown>,
|
|
328
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
300
329
|
): ResolvedFieldType {
|
|
301
330
|
const { type } = field;
|
|
302
331
|
|
|
303
332
|
switch (type.kind) {
|
|
304
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
|
+
}
|
|
305
344
|
let outputResolved: string | undefined;
|
|
345
|
+
let inputResolved: string | undefined;
|
|
306
346
|
const inlineTypeParams =
|
|
307
347
|
type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : undefined;
|
|
308
348
|
const effectiveTypeParams = inlineTypeParams ?? resolvedTypeParams;
|
|
@@ -311,11 +351,15 @@ export function resolveFieldType(
|
|
|
311
351
|
if (rendered && isSafeTypeExpression(rendered)) {
|
|
312
352
|
outputResolved = rendered;
|
|
313
353
|
}
|
|
354
|
+
const renderedInput = codecLookup.renderInputTypeFor?.(type.codecId, effectiveTypeParams);
|
|
355
|
+
if (renderedInput && isSafeTypeExpression(renderedInput)) {
|
|
356
|
+
inputResolved = renderedInput;
|
|
357
|
+
}
|
|
314
358
|
}
|
|
315
359
|
const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;
|
|
316
360
|
return {
|
|
317
361
|
output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),
|
|
318
|
-
input: applyModifiers(`${codecAccessor}['input']`, field),
|
|
362
|
+
input: applyModifiers(inputResolved ?? `${codecAccessor}['input']`, field),
|
|
319
363
|
};
|
|
320
364
|
}
|
|
321
365
|
case 'valueObject':
|
|
@@ -359,6 +403,7 @@ export function generateBothFieldTypesMaps(
|
|
|
359
403
|
models: Record<string, ContractModel> | undefined,
|
|
360
404
|
codecLookup?: CodecLookup,
|
|
361
405
|
resolveFieldTypeParams?: FieldTypeParamsResolver,
|
|
406
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
362
407
|
): ResolvedFieldType {
|
|
363
408
|
if (!models || Object.keys(models).length === 0) {
|
|
364
409
|
return { output: 'Record<string, never>', input: 'Record<string, never>' };
|
|
@@ -379,7 +424,7 @@ export function generateBothFieldTypesMaps(
|
|
|
379
424
|
: undefined;
|
|
380
425
|
const resolvedTypeParams =
|
|
381
426
|
inlineTypeParams ?? resolveFieldTypeParams?.(modelName, fieldName, model);
|
|
382
|
-
const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams);
|
|
427
|
+
const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams, resolveEnumValues);
|
|
383
428
|
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
384
429
|
outputFieldEntries.push(`${key}: ${resolved.output}`);
|
|
385
430
|
inputFieldEntries.push(`${key}: ${resolved.input}`);
|
|
@@ -407,16 +452,20 @@ export function generateFieldOutputTypesMap(
|
|
|
407
452
|
models: Record<string, ContractModel> | undefined,
|
|
408
453
|
codecLookup?: CodecLookup,
|
|
409
454
|
resolveFieldTypeParams?: FieldTypeParamsResolver,
|
|
455
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
410
456
|
): string {
|
|
411
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
457
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues)
|
|
458
|
+
.output;
|
|
412
459
|
}
|
|
413
460
|
|
|
414
461
|
export function generateFieldInputTypesMap(
|
|
415
462
|
models: Record<string, ContractModel> | undefined,
|
|
416
463
|
codecLookup?: CodecLookup,
|
|
417
464
|
resolveFieldTypeParams?: FieldTypeParamsResolver,
|
|
465
|
+
resolveEnumValues?: EnumValuesResolver,
|
|
418
466
|
): string {
|
|
419
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams)
|
|
467
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveEnumValues)
|
|
468
|
+
.input;
|
|
420
469
|
}
|
|
421
470
|
|
|
422
471
|
export function generateValueObjectType(
|
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
Contract,
|
|
3
|
+
ContractEnum,
|
|
4
|
+
ContractModel,
|
|
5
|
+
ContractValueObject,
|
|
6
|
+
} from '@prisma-next/contract/types';
|
|
2
7
|
import { DomainNamespaceResolutionError } from '@prisma-next/contract/types';
|
|
3
8
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
4
9
|
import type {
|
|
@@ -9,6 +14,7 @@ import type {
|
|
|
9
14
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
10
15
|
import {
|
|
11
16
|
deduplicateImports,
|
|
17
|
+
type EnumValuesResolver,
|
|
12
18
|
generateBothFieldTypesMaps,
|
|
13
19
|
generateCodecTypeIntersection,
|
|
14
20
|
generateHashTypeAliases,
|
|
@@ -18,9 +24,22 @@ import {
|
|
|
18
24
|
generateValueObjectsDescriptorType,
|
|
19
25
|
generateValueObjectTypeAliases,
|
|
20
26
|
serializeExecutionType,
|
|
27
|
+
serializeObjectKey,
|
|
21
28
|
serializeValue,
|
|
22
29
|
} from './domain-type-generation';
|
|
23
30
|
|
|
31
|
+
function generateEnumBlockType(enums: Record<string, ContractEnum>): string {
|
|
32
|
+
const entries = Object.entries(enums).map(([name, entry]) => {
|
|
33
|
+
const memberTupleItems = entry.members.map(
|
|
34
|
+
(m) =>
|
|
35
|
+
`{ readonly name: ${serializeValue(m.name)}; readonly value: ${serializeValue(m.value)} }`,
|
|
36
|
+
);
|
|
37
|
+
const membersType = `readonly [${memberTupleItems.join(', ')}]`;
|
|
38
|
+
return `readonly ${serializeObjectKey(name)}: { readonly codecId: ${serializeValue(entry.codecId)}; readonly members: ${membersType} }`;
|
|
39
|
+
});
|
|
40
|
+
return `{ ${entries.join('; ')} }`;
|
|
41
|
+
}
|
|
42
|
+
|
|
24
43
|
export function generateContractDts(
|
|
25
44
|
contract: Contract,
|
|
26
45
|
emitter: EmissionSpi,
|
|
@@ -104,34 +123,44 @@ export function generateContractDts(
|
|
|
104
123
|
const valueObjectTypeAliases = generateValueObjectTypeAliases(valueObjects, codecLookup);
|
|
105
124
|
const valueObjectsDescriptor = generateValueObjectsDescriptorType(valueObjects);
|
|
106
125
|
|
|
107
|
-
// Per-namespace models
|
|
108
|
-
const perNamespaceTypes: Array<
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
126
|
+
// Per-namespace models, value objects, and enum types for the domain.namespaces section.
|
|
127
|
+
const perNamespaceTypes: Array<
|
|
128
|
+
readonly [string, string, string | undefined, string | undefined]
|
|
129
|
+
> = namespaceEntries.map(([nsId, ns]) => {
|
|
130
|
+
const nsModels = blindCast<
|
|
131
|
+
Record<string, ContractModel>,
|
|
132
|
+
'ns.models is a ContractModel record in the emitted IR'
|
|
133
|
+
>(ns.models);
|
|
134
|
+
const nsModelsType = generateModelsType(nsModels, (name, model) =>
|
|
135
|
+
emitter.generateModelStorageType(name, model),
|
|
136
|
+
);
|
|
137
|
+
const nsValueObjects = blindCast<
|
|
138
|
+
Record<string, ContractValueObject> | undefined,
|
|
139
|
+
'ns.valueObjects is an optional ContractValueObject record in the emitted IR'
|
|
140
|
+
>(ns.valueObjects);
|
|
141
|
+
const nsValueObjectsDescriptor =
|
|
142
|
+
nsValueObjects !== undefined && Object.keys(nsValueObjects).length > 0
|
|
143
|
+
? generateValueObjectsDescriptorType(nsValueObjects)
|
|
144
|
+
: undefined;
|
|
145
|
+
const nsEnums = blindCast<
|
|
146
|
+
Record<string, ContractEnum> | undefined,
|
|
147
|
+
'ns.enum is an optional ContractEnum record in the emitted IR'
|
|
148
|
+
>(ns.enum);
|
|
149
|
+
const nsEnumBlock =
|
|
150
|
+
nsEnums !== undefined && Object.keys(nsEnums).length > 0
|
|
151
|
+
? generateEnumBlockType(nsEnums)
|
|
152
|
+
: undefined;
|
|
153
|
+
return [nsId, nsModelsType, nsValueObjectsDescriptor, nsEnumBlock] as const;
|
|
154
|
+
});
|
|
127
155
|
|
|
128
156
|
const domainNamespacesType = perNamespaceTypes
|
|
129
|
-
.map(([nsId, nsModelsType, nsValueObjectsDescriptor]) => {
|
|
157
|
+
.map(([nsId, nsModelsType, nsValueObjectsDescriptor, nsEnumBlock]) => {
|
|
130
158
|
const voLine =
|
|
131
159
|
nsValueObjectsDescriptor !== undefined
|
|
132
160
|
? `\n readonly valueObjects: ${nsValueObjectsDescriptor};`
|
|
133
161
|
: '';
|
|
134
|
-
|
|
162
|
+
const enumLine = nsEnumBlock !== undefined ? `\n readonly enum: ${nsEnumBlock};` : '';
|
|
163
|
+
return ` readonly ${nsId}: {\n readonly models: ${nsModelsType};${voLine}${enumLine}\n }`;
|
|
135
164
|
})
|
|
136
165
|
.join(';\n');
|
|
137
166
|
|
|
@@ -145,10 +174,18 @@ export function generateContractDts(
|
|
|
145
174
|
emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract)
|
|
146
175
|
: undefined;
|
|
147
176
|
|
|
177
|
+
const resolveEnumValues: EnumValuesResolver = (ref) =>
|
|
178
|
+
ref.entityKind === 'enum'
|
|
179
|
+
? contract.domain.namespaces[ref.namespaceId]?.enum?.[ref.entityName]?.members.map(
|
|
180
|
+
(m) => m.value,
|
|
181
|
+
)
|
|
182
|
+
: undefined;
|
|
183
|
+
|
|
148
184
|
const fieldTypesMaps = generateBothFieldTypesMaps(
|
|
149
185
|
modelsRecord,
|
|
150
186
|
codecLookup,
|
|
151
187
|
resolveFieldTypeParams,
|
|
188
|
+
resolveEnumValues,
|
|
152
189
|
);
|
|
153
190
|
|
|
154
191
|
const contractWrapper = emitter.getContractWrapper('ContractBase', 'TypeMaps');
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domain-type-generation-BSbwyYur.d.mts","names":[],"sources":["../src/domain-type-generation.ts"],"mappings":";;;;;iBAagB,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;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,iBA4Ca,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-sTwie_d1.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 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 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 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":"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"}
|