@prisma-next/emitter 0.16.0-dev.3 → 0.16.0-dev.31
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-BpLtcnoV.mjs +335 -0
- package/dist/domain-type-generation-BpLtcnoV.mjs.map +1 -0
- package/dist/domain-type-generation-egQOP6Jp.d.mts.map +1 -1
- package/dist/domain-type-generation.mjs +1 -328
- package/dist/exports/index.mjs +2 -2
- package/dist/{exports-Bsc1vgw7.mjs → exports-CNvUZ1K7.mjs} +10 -7
- package/dist/exports-CNvUZ1K7.mjs.map +1 -0
- package/dist/index-P9tB7OkF.d.mts.map +1 -1
- package/dist/test/utils.d.mts +1 -1
- package/dist/test/utils.d.mts.map +1 -1
- package/dist/test/utils.mjs +4 -4
- package/dist/test/utils.mjs.map +1 -1
- package/package.json +9 -9
- package/src/artifact-paths.ts +5 -1
- package/src/domain-type-generation.ts +4 -1
- package/src/emitter-errors.ts +15 -0
- package/src/generate-contract-dts.ts +7 -4
- package/dist/domain-type-generation.mjs.map +0 -1
- package/dist/exports-Bsc1vgw7.mjs.map +0 -1
|
@@ -0,0 +1,335 @@
|
|
|
1
|
+
import { isSafeTypeExpression } from "./type-expression-safety.mjs";
|
|
2
|
+
import { structuredError } from "@prisma-next/utils/structured-error";
|
|
3
|
+
import { renderImports } from "@prisma-next/ts-render";
|
|
4
|
+
import { blindCast } from "@prisma-next/utils/casts";
|
|
5
|
+
//#region src/emitter-errors.ts
|
|
6
|
+
function emitterError(code, message, options) {
|
|
7
|
+
return structuredError(code, message, options);
|
|
8
|
+
}
|
|
9
|
+
//#endregion
|
|
10
|
+
//#region src/domain-type-generation.ts
|
|
11
|
+
function serializeValue(value) {
|
|
12
|
+
if (value === null) return "null";
|
|
13
|
+
if (value === void 0) return "undefined";
|
|
14
|
+
if (typeof value === "string") return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
15
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
16
|
+
if (typeof value === "bigint") return `${value}n`;
|
|
17
|
+
if (Array.isArray(value)) return `readonly [${value.map((v) => serializeValue(v)).join(", ")}]`;
|
|
18
|
+
if (typeof value === "object") {
|
|
19
|
+
const entries = [];
|
|
20
|
+
for (const [k, v] of Object.entries(value)) entries.push(`readonly ${serializeObjectKey(k)}: ${serializeValue(v)}`);
|
|
21
|
+
return `{ ${entries.join("; ")} }`;
|
|
22
|
+
}
|
|
23
|
+
return "unknown";
|
|
24
|
+
}
|
|
25
|
+
function serializeObjectKey(key) {
|
|
26
|
+
if (/^[$A-Z_a-z][$\w]*$/.test(key)) return key;
|
|
27
|
+
return serializeValue(key);
|
|
28
|
+
}
|
|
29
|
+
function serializeNamespaceId(value) {
|
|
30
|
+
return `${serializeValue(value)} & NamespaceId`;
|
|
31
|
+
}
|
|
32
|
+
function serializeCrossReference(ref) {
|
|
33
|
+
return `{ readonly namespace: ${serializeNamespaceId(String(ref.namespace))}; readonly model: ${serializeValue(ref.model)}${ref.space !== void 0 ? `; readonly space: ${serializeValue(ref.space)}` : ""} }`;
|
|
34
|
+
}
|
|
35
|
+
function generateRootsType(roots) {
|
|
36
|
+
if (!roots || Object.keys(roots).length === 0) return "Record<string, never>";
|
|
37
|
+
return `{ ${Object.entries(roots).map(([key, value]) => `readonly ${serializeObjectKey(key)}: ${serializeCrossReference(value)}`).join("; ")} }`;
|
|
38
|
+
}
|
|
39
|
+
function contractFieldModifierSuffix(field) {
|
|
40
|
+
return (field.many === true ? "; readonly many: true" : "") + (field.dict === true ? "; readonly dict: true" : "");
|
|
41
|
+
}
|
|
42
|
+
function generateModelFieldEntry(fieldName, field) {
|
|
43
|
+
const mods = contractFieldModifierSuffix(field);
|
|
44
|
+
const { nullable, type } = field;
|
|
45
|
+
if (type.kind === "scalar") {
|
|
46
|
+
const typeParamsSpec = type.typeParams && Object.keys(type.typeParams).length > 0 ? `; readonly typeParams: ${serializeValue(type.typeParams)}` : "";
|
|
47
|
+
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${mods} }`;
|
|
48
|
+
}
|
|
49
|
+
if (type.kind === "valueObject") return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${mods} }`;
|
|
50
|
+
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: ${serializeValue(type)}${mods} }`;
|
|
51
|
+
}
|
|
52
|
+
function generateModelFieldsType(fields) {
|
|
53
|
+
const fieldEntries = [];
|
|
54
|
+
for (const [fieldName, field] of Object.entries(fields)) fieldEntries.push(generateModelFieldEntry(fieldName, field));
|
|
55
|
+
return fieldEntries.length > 0 ? `{ ${fieldEntries.join("; ")} }` : "Record<string, never>";
|
|
56
|
+
}
|
|
57
|
+
function generateModelRelationsType(relations) {
|
|
58
|
+
const relationEntries = [];
|
|
59
|
+
for (const [relName, rel] of Object.entries(relations)) {
|
|
60
|
+
if (typeof rel !== "object" || rel === null) continue;
|
|
61
|
+
const relObj = rel;
|
|
62
|
+
const toRef = relObj["to"];
|
|
63
|
+
if (toRef !== null && typeof toRef === "object" && "space" in toRef && toRef.space !== void 0) {
|
|
64
|
+
relationEntries.push(`readonly ${serializeObjectKey(relName)}: never`);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
const parts = [];
|
|
68
|
+
if (toRef) parts.push(`readonly to: ${serializeCrossReference(blindCast(toRef))}`);
|
|
69
|
+
if (relObj["cardinality"]) parts.push(`readonly cardinality: ${serializeValue(relObj["cardinality"])}`);
|
|
70
|
+
const on = relObj["on"];
|
|
71
|
+
if (on && (!on.localFields || !on.targetFields)) throw emitterError("CONTRACT.RELATION_INVALID", `Relation "${relName}" has an "on" block but is missing localFields or targetFields`, { meta: { relation: relName } });
|
|
72
|
+
if (on?.localFields && on.targetFields) {
|
|
73
|
+
const localFields = on.localFields.map((f) => serializeValue(f)).join(", ");
|
|
74
|
+
const targetFields = on.targetFields.map((f) => serializeValue(f)).join(", ");
|
|
75
|
+
parts.push(`readonly on: { readonly localFields: readonly [${localFields}]; readonly targetFields: readonly [${targetFields}] }`);
|
|
76
|
+
}
|
|
77
|
+
if (relObj["cardinality"] === "N:M") {
|
|
78
|
+
const { through } = blindCast(relObj);
|
|
79
|
+
const table = serializeValue(through.table);
|
|
80
|
+
const namespaceId = serializeValue(through.namespaceId);
|
|
81
|
+
const parentColumns = through.parentColumns.map((c) => serializeValue(c)).join(", ");
|
|
82
|
+
const childColumns = through.childColumns.map((c) => serializeValue(c)).join(", ");
|
|
83
|
+
const targetColumns = through.targetColumns.map((c) => serializeValue(c)).join(", ");
|
|
84
|
+
parts.push(`readonly through: { readonly table: ${table}; readonly namespaceId: ${namespaceId}; readonly parentColumns: readonly [${parentColumns}]; readonly childColumns: readonly [${childColumns}]; readonly targetColumns: readonly [${targetColumns}] }`);
|
|
85
|
+
}
|
|
86
|
+
if (parts.length > 0) relationEntries.push(`readonly ${serializeObjectKey(relName)}: { ${parts.join("; ")} }`);
|
|
87
|
+
}
|
|
88
|
+
if (relationEntries.length === 0) return "Record<string, never>";
|
|
89
|
+
return `{ ${relationEntries.join("; ")} }`;
|
|
90
|
+
}
|
|
91
|
+
function generateModelsType(models, generateModelStorage) {
|
|
92
|
+
if (!models || Object.keys(models).length === 0) return "Record<string, never>";
|
|
93
|
+
const modelTypes = [];
|
|
94
|
+
for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {
|
|
95
|
+
const fieldsType = generateModelFieldsType(model.fields);
|
|
96
|
+
const relationsType = generateModelRelationsType(model.relations);
|
|
97
|
+
const storageType = generateModelStorage(modelName, model);
|
|
98
|
+
const modelParts = [
|
|
99
|
+
`readonly fields: ${fieldsType}`,
|
|
100
|
+
`readonly relations: ${relationsType}`,
|
|
101
|
+
`readonly storage: ${storageType}`
|
|
102
|
+
];
|
|
103
|
+
if (model.owner) modelParts.push(`readonly owner: ${serializeValue(model.owner)}`);
|
|
104
|
+
if (model.discriminator) modelParts.push(`readonly discriminator: ${serializeValue(model.discriminator)}`);
|
|
105
|
+
if (model.variants) modelParts.push(`readonly variants: ${serializeValue(model.variants)}`);
|
|
106
|
+
if (model.base) modelParts.push(`readonly base: ${serializeCrossReference(model.base)}`);
|
|
107
|
+
modelTypes.push(`readonly ${modelName}: { ${modelParts.join("; ")} }`);
|
|
108
|
+
}
|
|
109
|
+
return `{ ${modelTypes.join("; ")} }`;
|
|
110
|
+
}
|
|
111
|
+
function deduplicateImports(imports) {
|
|
112
|
+
const seenKeys = /* @__PURE__ */ new Set();
|
|
113
|
+
const result = [];
|
|
114
|
+
for (const imp of imports) {
|
|
115
|
+
const key = `${imp.package}::${imp.named}`;
|
|
116
|
+
if (!seenKeys.has(key)) {
|
|
117
|
+
seenKeys.add(key);
|
|
118
|
+
result.push(imp);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
function generateImportLines(imports) {
|
|
124
|
+
const rendered = renderImports(imports.map((imp) => ({
|
|
125
|
+
moduleSpecifier: imp.package,
|
|
126
|
+
symbol: imp.named,
|
|
127
|
+
alias: imp.alias,
|
|
128
|
+
typeOnly: true
|
|
129
|
+
})));
|
|
130
|
+
return rendered === "" ? [] : rendered.split("\n");
|
|
131
|
+
}
|
|
132
|
+
function generateCodecTypeIntersection(imports, named) {
|
|
133
|
+
return imports.filter((imp) => imp.named === named).map((imp) => imp.alias).join(" & ") || "Record<string, never>";
|
|
134
|
+
}
|
|
135
|
+
function serializeExecutionType(execution) {
|
|
136
|
+
const parts = ["readonly executionHash: ExecutionHash"];
|
|
137
|
+
for (const [key, value] of Object.entries(execution)) {
|
|
138
|
+
if (key === "executionHash") continue;
|
|
139
|
+
parts.push(`readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`);
|
|
140
|
+
}
|
|
141
|
+
return `{ ${parts.join("; ")} }`;
|
|
142
|
+
}
|
|
143
|
+
function generateHashTypeAliases(hashes) {
|
|
144
|
+
const executionHashType = hashes.executionHash ? `ExecutionHashBase<'${hashes.executionHash}'>` : "ExecutionHashBase<string>";
|
|
145
|
+
return [
|
|
146
|
+
`export type StorageHash = StorageHashBase<'${hashes.storageHash}'>;`,
|
|
147
|
+
`export type ExecutionHash = ${executionHashType};`,
|
|
148
|
+
`export type ProfileHash = ProfileHashBase<'${hashes.profileHash}'>;`
|
|
149
|
+
].join("\n");
|
|
150
|
+
}
|
|
151
|
+
function applyModifiers(base, field) {
|
|
152
|
+
let result = base;
|
|
153
|
+
if (field.many === true) result = `ReadonlyArray<${result}>`;
|
|
154
|
+
if (field.dict === true) result = `Readonly<Record<string, ${result}>>`;
|
|
155
|
+
if (field.nullable) result = `${result} | null`;
|
|
156
|
+
return result;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Renders a value set (a field/column's permitted values, codec-encoded) into a TS literal union by
|
|
160
|
+
* routing **each** value through the codec's `renderValueLiteral` — the seam owned by the codec, not
|
|
161
|
+
* a generic serializer. `side`: `output` = read type, `input` = create/update type.
|
|
162
|
+
*
|
|
163
|
+
* Returns `undefined` — signalling the caller to fall back to the codec's full output type — when
|
|
164
|
+
* the lookup is absent, has no `renderValueLiteralFor`, the value set is empty, or **any** value
|
|
165
|
+
* isn't literal-expressible. A caller that needs column and field types to agree shares this so both
|
|
166
|
+
* compute the union identically.
|
|
167
|
+
*/
|
|
168
|
+
function renderValueSetType(values, codecId, side, codecLookup) {
|
|
169
|
+
if (values.length === 0 || codecLookup?.renderValueLiteralFor === void 0) return void 0;
|
|
170
|
+
const literals = [];
|
|
171
|
+
for (const value of values) {
|
|
172
|
+
const lit = codecLookup.renderValueLiteralFor(codecId, value, side);
|
|
173
|
+
if (lit === void 0 || !isSafeTypeExpression(lit)) return void 0;
|
|
174
|
+
literals.push(lit);
|
|
175
|
+
}
|
|
176
|
+
return literals.join(" | ");
|
|
177
|
+
}
|
|
178
|
+
function resolveFieldType(field, codecLookup, resolvedTypeParams, resolvedValueSet) {
|
|
179
|
+
const { type } = field;
|
|
180
|
+
switch (type.kind) {
|
|
181
|
+
case "scalar": {
|
|
182
|
+
if (resolvedValueSet) {
|
|
183
|
+
const output = renderValueSetType(resolvedValueSet.encodedValues, resolvedValueSet.codecId, "output", codecLookup);
|
|
184
|
+
const input = renderValueSetType(resolvedValueSet.encodedValues, resolvedValueSet.codecId, "input", codecLookup);
|
|
185
|
+
if (output !== void 0 && input !== void 0) return {
|
|
186
|
+
output: applyModifiers(output, field),
|
|
187
|
+
input: applyModifiers(input, field)
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
let outputResolved;
|
|
191
|
+
let inputResolved;
|
|
192
|
+
const effectiveTypeParams = (type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : void 0) ?? resolvedTypeParams;
|
|
193
|
+
if (codecLookup && effectiveTypeParams && Object.keys(effectiveTypeParams).length > 0) {
|
|
194
|
+
const rendered = codecLookup.renderOutputTypeFor(type.codecId, effectiveTypeParams);
|
|
195
|
+
if (rendered && isSafeTypeExpression(rendered)) outputResolved = rendered;
|
|
196
|
+
const renderedInput = codecLookup.renderInputTypeFor?.(type.codecId, effectiveTypeParams);
|
|
197
|
+
if (renderedInput && isSafeTypeExpression(renderedInput)) inputResolved = renderedInput;
|
|
198
|
+
}
|
|
199
|
+
const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;
|
|
200
|
+
return {
|
|
201
|
+
output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),
|
|
202
|
+
input: applyModifiers(inputResolved ?? `${codecAccessor}['input']`, field)
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
case "valueObject": return {
|
|
206
|
+
output: applyModifiers(`${type.name}Output`, field),
|
|
207
|
+
input: applyModifiers(`${type.name}Input`, field)
|
|
208
|
+
};
|
|
209
|
+
case "union": {
|
|
210
|
+
const outputMembers = type.members.map((m) => m.kind === "scalar" ? `CodecTypes[${serializeValue(m.codecId)}]['output']` : `${m.name}Output`);
|
|
211
|
+
const inputMembers = type.members.map((m) => m.kind === "scalar" ? `CodecTypes[${serializeValue(m.codecId)}]['input']` : `${m.name}Input`);
|
|
212
|
+
return {
|
|
213
|
+
output: applyModifiers(outputMembers.join(" | "), field),
|
|
214
|
+
input: applyModifiers(inputMembers.join(" | "), field)
|
|
215
|
+
};
|
|
216
|
+
}
|
|
217
|
+
default: return {
|
|
218
|
+
output: applyModifiers("unknown", field),
|
|
219
|
+
input: applyModifiers("unknown", field)
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
function generateFieldResolvedType(field, codecLookup, side = "output") {
|
|
224
|
+
return resolveFieldType(field, codecLookup)[side];
|
|
225
|
+
}
|
|
226
|
+
function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveFieldValueSet) {
|
|
227
|
+
if (!models || Object.keys(models).length === 0) return {
|
|
228
|
+
output: "Record<string, never>",
|
|
229
|
+
input: "Record<string, never>"
|
|
230
|
+
};
|
|
231
|
+
const outputModelEntries = [];
|
|
232
|
+
const inputModelEntries = [];
|
|
233
|
+
for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {
|
|
234
|
+
if (!model) continue;
|
|
235
|
+
const outputFieldEntries = [];
|
|
236
|
+
const inputFieldEntries = [];
|
|
237
|
+
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
238
|
+
const resolvedTypeParams = (field.type.kind === "scalar" && field.type.typeParams && Object.keys(field.type.typeParams).length > 0 ? field.type.typeParams : void 0) ?? resolveFieldTypeParams?.(modelName, fieldName, model);
|
|
239
|
+
const resolvedValueSet = resolveFieldValueSet?.(modelName, fieldName, model);
|
|
240
|
+
const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams, resolvedValueSet);
|
|
241
|
+
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
242
|
+
outputFieldEntries.push(`${key}: ${resolved.output}`);
|
|
243
|
+
inputFieldEntries.push(`${key}: ${resolved.input}`);
|
|
244
|
+
}
|
|
245
|
+
const outputFields = outputFieldEntries.length > 0 ? `{ ${outputFieldEntries.join("; ")} }` : "Record<string, never>";
|
|
246
|
+
const inputFields = inputFieldEntries.length > 0 ? `{ ${inputFieldEntries.join("; ")} }` : "Record<string, never>";
|
|
247
|
+
const modelKey = `readonly ${serializeObjectKey(modelName)}`;
|
|
248
|
+
outputModelEntries.push(`${modelKey}: ${outputFields}`);
|
|
249
|
+
inputModelEntries.push(`${modelKey}: ${inputFields}`);
|
|
250
|
+
}
|
|
251
|
+
return {
|
|
252
|
+
output: `{ ${outputModelEntries.join("; ")} }`,
|
|
253
|
+
input: `{ ${inputModelEntries.join("; ")} }`
|
|
254
|
+
};
|
|
255
|
+
}
|
|
256
|
+
function generateFieldTypesMapsByNamespace(namespaceModels, codecLookup, resolveFieldTypeParams, resolveFieldValueSet) {
|
|
257
|
+
if (namespaceModels.length === 0) return {
|
|
258
|
+
output: "Record<string, never>",
|
|
259
|
+
input: "Record<string, never>"
|
|
260
|
+
};
|
|
261
|
+
const outputNamespaceEntries = [];
|
|
262
|
+
const inputNamespaceEntries = [];
|
|
263
|
+
for (const [nsId, models] of namespaceModels) {
|
|
264
|
+
const inner = generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveFieldValueSet);
|
|
265
|
+
const nsKey = `readonly ${serializeObjectKey(nsId)}`;
|
|
266
|
+
outputNamespaceEntries.push(`${nsKey}: ${inner.output}`);
|
|
267
|
+
inputNamespaceEntries.push(`${nsKey}: ${inner.input}`);
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
output: `{ ${outputNamespaceEntries.join("; ")} }`,
|
|
271
|
+
input: `{ ${inputNamespaceEntries.join("; ")} }`
|
|
272
|
+
};
|
|
273
|
+
}
|
|
274
|
+
function generateFieldOutputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
275
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).output;
|
|
276
|
+
}
|
|
277
|
+
function generateFieldInputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
278
|
+
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).input;
|
|
279
|
+
}
|
|
280
|
+
function generateValueObjectType(_voName, vo, _valueObjects, side = "output", codecLookup) {
|
|
281
|
+
return resolveValueObjectType(_voName, vo, _valueObjects, codecLookup)[side];
|
|
282
|
+
}
|
|
283
|
+
function resolveValueObjectType(_voName, vo, _valueObjects, codecLookup) {
|
|
284
|
+
const outputEntries = [];
|
|
285
|
+
const inputEntries = [];
|
|
286
|
+
for (const [fieldName, field] of Object.entries(vo.fields)) {
|
|
287
|
+
const resolved = resolveFieldType(field, codecLookup);
|
|
288
|
+
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
289
|
+
outputEntries.push(`${key}: ${resolved.output}`);
|
|
290
|
+
inputEntries.push(`${key}: ${resolved.input}`);
|
|
291
|
+
}
|
|
292
|
+
const empty = "Record<string, never>";
|
|
293
|
+
return {
|
|
294
|
+
output: outputEntries.length > 0 ? `{ ${outputEntries.join("; ")} }` : empty,
|
|
295
|
+
input: inputEntries.length > 0 ? `{ ${inputEntries.join("; ")} }` : empty
|
|
296
|
+
};
|
|
297
|
+
}
|
|
298
|
+
function generateContractFieldDescriptor(fieldName, field) {
|
|
299
|
+
const mods = [];
|
|
300
|
+
if (field.many === true) mods.push("; readonly many: true");
|
|
301
|
+
if (field.dict === true) mods.push("; readonly dict: true");
|
|
302
|
+
const modStr = mods.join("");
|
|
303
|
+
const { type } = field;
|
|
304
|
+
if (type.kind === "scalar") {
|
|
305
|
+
const typeParamsSpec = type.typeParams && Object.keys(type.typeParams).length > 0 ? `; readonly typeParams: ${serializeValue(type.typeParams)}` : "";
|
|
306
|
+
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${modStr} }`;
|
|
307
|
+
}
|
|
308
|
+
if (type.kind === "valueObject") return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${modStr} }`;
|
|
309
|
+
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: ${serializeValue(type)}${modStr} }`;
|
|
310
|
+
}
|
|
311
|
+
function generateValueObjectsDescriptorType(valueObjects) {
|
|
312
|
+
if (!valueObjects || Object.keys(valueObjects).length === 0) return "Record<string, never>";
|
|
313
|
+
const voEntries = [];
|
|
314
|
+
for (const [voName, vo] of Object.entries(valueObjects)) {
|
|
315
|
+
const fieldEntries = [];
|
|
316
|
+
for (const [fieldName, field] of Object.entries(vo.fields)) fieldEntries.push(generateContractFieldDescriptor(fieldName, field));
|
|
317
|
+
const fieldsType = fieldEntries.length > 0 ? `{ ${fieldEntries.join("; ")} }` : "Record<string, never>";
|
|
318
|
+
voEntries.push(`readonly ${serializeObjectKey(voName)}: { readonly fields: ${fieldsType} }`);
|
|
319
|
+
}
|
|
320
|
+
return `{ ${voEntries.join("; ")} }`;
|
|
321
|
+
}
|
|
322
|
+
function generateValueObjectTypeAliases(valueObjects, codecLookup) {
|
|
323
|
+
if (!valueObjects || Object.keys(valueObjects).length === 0) return "";
|
|
324
|
+
const aliases = [];
|
|
325
|
+
for (const [voName, vo] of Object.entries(valueObjects)) {
|
|
326
|
+
const resolved = resolveValueObjectType(voName, vo, valueObjects, codecLookup);
|
|
327
|
+
aliases.push(`export type ${voName}Output = ${resolved.output};`);
|
|
328
|
+
aliases.push(`export type ${voName}Input = ${resolved.input};`);
|
|
329
|
+
}
|
|
330
|
+
return aliases.join("\n");
|
|
331
|
+
}
|
|
332
|
+
//#endregion
|
|
333
|
+
export { serializeExecutionType as C, emitterError as D, serializeValue as E, serializeCrossReference as S, serializeObjectKey as T, generateValueObjectTypeAliases as _, generateFieldInputTypesMap as a, resolveFieldType as b, generateFieldTypesMapsByNamespace as c, generateModelFieldEntry as d, generateModelFieldsType as f, generateValueObjectType as g, generateRootsType as h, generateContractFieldDescriptor as i, generateHashTypeAliases as l, generateModelsType as m, generateBothFieldTypesMaps as n, generateFieldOutputTypesMap as o, generateModelRelationsType as p, generateCodecTypeIntersection as r, generateFieldResolvedType as s, deduplicateImports as t, generateImportLines as u, generateValueObjectsDescriptorType as v, serializeNamespaceId as w, resolveValueObjectType as x, renderValueSetType as y };
|
|
334
|
+
|
|
335
|
+
//# sourceMappingURL=domain-type-generation-BpLtcnoV.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"domain-type-generation-BpLtcnoV.mjs","names":[],"sources":["../src/emitter-errors.ts","../src/domain-type-generation.ts"],"sourcesContent":["import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error';\nimport { structuredError } from '@prisma-next/utils/structured-error';\n\nexport type EmitterErrorCode =\n | 'CONFIG.VALIDATION_FAILED'\n | 'CONTRACT.NAMESPACE_INVALID'\n | 'CONTRACT.RELATION_INVALID';\n\nexport function emitterError(\n code: EmitterErrorCode,\n message: string,\n options?: StructuredErrorOptions,\n): StructuredError {\n return structuredError(code, message, options);\n}\n","import type {\n ContractField,\n ContractManyToManyRelation,\n ContractModelBase,\n ContractValueObject,\n CrossReference,\n JsonValue,\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 { emitterError } from './emitter-errors';\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 emitterError(\n 'CONTRACT.RELATION_INVALID',\n `Relation \"${relName}\" has an \"on\" block but is missing localFields or targetFields`,\n { meta: { relation: relName } },\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, ContractModelBase>,\n generateModelStorage: (modelName: string, model: ContractModelBase) => 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\nexport type FieldTypeParamsResolver = (\n modelName: string,\n fieldName: string,\n model: ContractModelBase,\n) => Record<string, unknown> | undefined;\n\n/**\n * A field's permitted values (codec-encoded) plus the codec that types them, as supplied by the\n * family-specific {@link EmissionSpi.resolveFieldValueSet}. The framework renders these into a TS\n * literal union through the codec seam ({@link renderValueSetType}).\n */\nexport type ResolvedFieldValueSet = {\n readonly encodedValues: readonly JsonValue[];\n readonly codecId: string;\n};\n\nexport type FieldValueSetResolver = (\n modelName: string,\n fieldName: string,\n model: ContractModelBase,\n) => ResolvedFieldValueSet | undefined;\n\n/**\n * Renders a value set (a field/column's permitted values, codec-encoded) into a TS literal union by\n * routing **each** value through the codec's `renderValueLiteral` — the seam owned by the codec, not\n * a generic serializer. `side`: `output` = read type, `input` = create/update type.\n *\n * Returns `undefined` — signalling the caller to fall back to the codec's full output type — when\n * the lookup is absent, has no `renderValueLiteralFor`, the value set is empty, or **any** value\n * isn't literal-expressible. A caller that needs column and field types to agree shares this so both\n * compute the union identically.\n */\nexport function renderValueSetType(\n values: readonly JsonValue[],\n codecId: string,\n side: 'output' | 'input',\n codecLookup: CodecLookup | undefined,\n): string | undefined {\n if (values.length === 0 || codecLookup?.renderValueLiteralFor === undefined) return undefined;\n const literals: string[] = [];\n for (const value of values) {\n const lit = codecLookup.renderValueLiteralFor(codecId, value, side);\n if (lit === undefined || !isSafeTypeExpression(lit)) return undefined;\n literals.push(lit);\n }\n return literals.join(' | ');\n}\n\nexport function resolveFieldType(\n field: ContractField,\n codecLookup?: CodecLookup,\n resolvedTypeParams?: Record<string, unknown>,\n resolvedValueSet?: ResolvedFieldValueSet,\n): ResolvedFieldType {\n const { type } = field;\n\n switch (type.kind) {\n case 'scalar': {\n if (resolvedValueSet) {\n const output = renderValueSetType(\n resolvedValueSet.encodedValues,\n resolvedValueSet.codecId,\n 'output',\n codecLookup,\n );\n const input = renderValueSetType(\n resolvedValueSet.encodedValues,\n resolvedValueSet.codecId,\n 'input',\n codecLookup,\n );\n if (output !== undefined && input !== undefined) {\n return {\n output: applyModifiers(output, field),\n input: applyModifiers(input, 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, ContractModelBase> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n resolveFieldValueSet?: FieldValueSetResolver,\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 resolvedValueSet = resolveFieldValueSet?.(modelName, fieldName, model);\n const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams, resolvedValueSet);\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 generateFieldTypesMapsByNamespace(\n namespaceModels: ReadonlyArray<readonly [string, Record<string, ContractModelBase>]>,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n resolveFieldValueSet?: FieldValueSetResolver,\n): ResolvedFieldType {\n if (namespaceModels.length === 0) {\n return { output: 'Record<string, never>', input: 'Record<string, never>' };\n }\n\n const outputNamespaceEntries: string[] = [];\n const inputNamespaceEntries: string[] = [];\n for (const [nsId, models] of namespaceModels) {\n const inner = generateBothFieldTypesMaps(\n models,\n codecLookup,\n resolveFieldTypeParams,\n resolveFieldValueSet,\n );\n const nsKey = `readonly ${serializeObjectKey(nsId)}`;\n outputNamespaceEntries.push(`${nsKey}: ${inner.output}`);\n inputNamespaceEntries.push(`${nsKey}: ${inner.input}`);\n }\n\n return {\n output: `{ ${outputNamespaceEntries.join('; ')} }`,\n input: `{ ${inputNamespaceEntries.join('; ')} }`,\n };\n}\n\nexport function generateFieldOutputTypesMap(\n models: Record<string, ContractModelBase> | 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, ContractModelBase> | 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 +1 @@
|
|
|
1
|
-
{"version":3,"file":"domain-type-generation-egQOP6Jp.d.mts","names":[],"sources":["../src/domain-type-generation.ts"],"mappings":";;;;
|
|
1
|
+
{"version":3,"file":"domain-type-generation-egQOP6Jp.d.mts","names":[],"sources":["../src/domain-type-generation.ts"],"mappings":";;;;iBAegB,eAAe;iBA+Bf,mBAAmB;iBAOnB,qBAAqB;iBAIrB,wBAAwB,KAAK;iBAO7B,kBAAkB,OAAO,eAAe;iBAgBxC,wBAAwB,mBAAmB,OAAO;iBAgBlD,wBAAwB,QAAQ,eAAe;iBAQ/C,2BAA2B,WAAW;iBA8EtC,mBACd,QAAQ,eAAe,oBACvB,uBAAuB,mBAAmB,OAAO;iBAqCnC,mBAAmB,SAAS,oBAAoB;iBAahD,oBAAoB,SAAS;iBAW7B,8BACd,SAAS,cAAc,kBACvB;iBAMc,uBAAuB,WAAW;iBASlC,wBAAwB;WAC7B;WACA;WACA;;KAaC;WAA+B;WAAwB;;KAUvD,2BACV,mBACA,mBACA,OAAO,sBACJ;;;;;;KAOO;WACD,wBAAwB;WACxB;;KAGC,yBACV,mBACA,mBACA,OAAO,sBACJ;;;;;;;;;;;iBAYW,mBACd,iBAAiB,aACjB,iBACA,0BACA,aAAa;iBAYC,iBACd,OAAO,eACP,cAAc,aACd,qBAAqB,yBACrB,mBAAmB,wBAClB;iBA2Ea,0BACd,OAAO,eACP,cAAc,aACd;iBAKc,2BACd,QAAQ,eAAe,gCACvB,cAAc,aACd,yBAAyB,yBACzB,uBAAuB,wBACtB;iBA6Ca,kCACd,iBAAiB,gCAAgC,eAAe,sBAChE,cAAc,aACd,yBAAyB,yBACzB,uBAAuB,wBACtB;iBAyBa,4BACd,QAAQ,eAAe,gCACvB,cAAc,aACd,yBAAyB;iBAKX,2BACd,QAAQ,eAAe,gCACvB,cAAc,aACd,yBAAyB;iBAKX,wBACd,iBACA,IAAI,qBACJ,eAAe,eAAe,sBAC9B,2BACA,cAAc;iBAKA,uBACd,iBACA,IAAI,qBACJ,eAAe,eAAe,sBAC9B,cAAc,cACb;iBAgBa,gCAAgC,mBAAmB,OAAO;iBAoB1D,mCACd,cAAc,eAAe;iBAoBf,+BACd,cAAc,eAAe,kCAC7B,cAAc"}
|
|
@@ -1,329 +1,2 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { renderImports } from "@prisma-next/ts-render";
|
|
3
|
-
import { blindCast } from "@prisma-next/utils/casts";
|
|
4
|
-
//#region src/domain-type-generation.ts
|
|
5
|
-
function serializeValue(value) {
|
|
6
|
-
if (value === null) return "null";
|
|
7
|
-
if (value === void 0) return "undefined";
|
|
8
|
-
if (typeof value === "string") return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
|
|
9
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
10
|
-
if (typeof value === "bigint") return `${value}n`;
|
|
11
|
-
if (Array.isArray(value)) return `readonly [${value.map((v) => serializeValue(v)).join(", ")}]`;
|
|
12
|
-
if (typeof value === "object") {
|
|
13
|
-
const entries = [];
|
|
14
|
-
for (const [k, v] of Object.entries(value)) entries.push(`readonly ${serializeObjectKey(k)}: ${serializeValue(v)}`);
|
|
15
|
-
return `{ ${entries.join("; ")} }`;
|
|
16
|
-
}
|
|
17
|
-
return "unknown";
|
|
18
|
-
}
|
|
19
|
-
function serializeObjectKey(key) {
|
|
20
|
-
if (/^[$A-Z_a-z][$\w]*$/.test(key)) return key;
|
|
21
|
-
return serializeValue(key);
|
|
22
|
-
}
|
|
23
|
-
function serializeNamespaceId(value) {
|
|
24
|
-
return `${serializeValue(value)} & NamespaceId`;
|
|
25
|
-
}
|
|
26
|
-
function serializeCrossReference(ref) {
|
|
27
|
-
return `{ readonly namespace: ${serializeNamespaceId(String(ref.namespace))}; readonly model: ${serializeValue(ref.model)}${ref.space !== void 0 ? `; readonly space: ${serializeValue(ref.space)}` : ""} }`;
|
|
28
|
-
}
|
|
29
|
-
function generateRootsType(roots) {
|
|
30
|
-
if (!roots || Object.keys(roots).length === 0) return "Record<string, never>";
|
|
31
|
-
return `{ ${Object.entries(roots).map(([key, value]) => `readonly ${serializeObjectKey(key)}: ${serializeCrossReference(value)}`).join("; ")} }`;
|
|
32
|
-
}
|
|
33
|
-
function contractFieldModifierSuffix(field) {
|
|
34
|
-
return (field.many === true ? "; readonly many: true" : "") + (field.dict === true ? "; readonly dict: true" : "");
|
|
35
|
-
}
|
|
36
|
-
function generateModelFieldEntry(fieldName, field) {
|
|
37
|
-
const mods = contractFieldModifierSuffix(field);
|
|
38
|
-
const { nullable, type } = field;
|
|
39
|
-
if (type.kind === "scalar") {
|
|
40
|
-
const typeParamsSpec = type.typeParams && Object.keys(type.typeParams).length > 0 ? `; readonly typeParams: ${serializeValue(type.typeParams)}` : "";
|
|
41
|
-
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${mods} }`;
|
|
42
|
-
}
|
|
43
|
-
if (type.kind === "valueObject") return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${mods} }`;
|
|
44
|
-
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: ${serializeValue(type)}${mods} }`;
|
|
45
|
-
}
|
|
46
|
-
function generateModelFieldsType(fields) {
|
|
47
|
-
const fieldEntries = [];
|
|
48
|
-
for (const [fieldName, field] of Object.entries(fields)) fieldEntries.push(generateModelFieldEntry(fieldName, field));
|
|
49
|
-
return fieldEntries.length > 0 ? `{ ${fieldEntries.join("; ")} }` : "Record<string, never>";
|
|
50
|
-
}
|
|
51
|
-
function generateModelRelationsType(relations) {
|
|
52
|
-
const relationEntries = [];
|
|
53
|
-
for (const [relName, rel] of Object.entries(relations)) {
|
|
54
|
-
if (typeof rel !== "object" || rel === null) continue;
|
|
55
|
-
const relObj = rel;
|
|
56
|
-
const toRef = relObj["to"];
|
|
57
|
-
if (toRef !== null && typeof toRef === "object" && "space" in toRef && toRef.space !== void 0) {
|
|
58
|
-
relationEntries.push(`readonly ${serializeObjectKey(relName)}: never`);
|
|
59
|
-
continue;
|
|
60
|
-
}
|
|
61
|
-
const parts = [];
|
|
62
|
-
if (toRef) parts.push(`readonly to: ${serializeCrossReference(blindCast(toRef))}`);
|
|
63
|
-
if (relObj["cardinality"]) parts.push(`readonly cardinality: ${serializeValue(relObj["cardinality"])}`);
|
|
64
|
-
const on = relObj["on"];
|
|
65
|
-
if (on && (!on.localFields || !on.targetFields)) throw new Error(`Relation "${relName}" has an "on" block but is missing localFields or targetFields`);
|
|
66
|
-
if (on?.localFields && on.targetFields) {
|
|
67
|
-
const localFields = on.localFields.map((f) => serializeValue(f)).join(", ");
|
|
68
|
-
const targetFields = on.targetFields.map((f) => serializeValue(f)).join(", ");
|
|
69
|
-
parts.push(`readonly on: { readonly localFields: readonly [${localFields}]; readonly targetFields: readonly [${targetFields}] }`);
|
|
70
|
-
}
|
|
71
|
-
if (relObj["cardinality"] === "N:M") {
|
|
72
|
-
const { through } = blindCast(relObj);
|
|
73
|
-
const table = serializeValue(through.table);
|
|
74
|
-
const namespaceId = serializeValue(through.namespaceId);
|
|
75
|
-
const parentColumns = through.parentColumns.map((c) => serializeValue(c)).join(", ");
|
|
76
|
-
const childColumns = through.childColumns.map((c) => serializeValue(c)).join(", ");
|
|
77
|
-
const targetColumns = through.targetColumns.map((c) => serializeValue(c)).join(", ");
|
|
78
|
-
parts.push(`readonly through: { readonly table: ${table}; readonly namespaceId: ${namespaceId}; readonly parentColumns: readonly [${parentColumns}]; readonly childColumns: readonly [${childColumns}]; readonly targetColumns: readonly [${targetColumns}] }`);
|
|
79
|
-
}
|
|
80
|
-
if (parts.length > 0) relationEntries.push(`readonly ${serializeObjectKey(relName)}: { ${parts.join("; ")} }`);
|
|
81
|
-
}
|
|
82
|
-
if (relationEntries.length === 0) return "Record<string, never>";
|
|
83
|
-
return `{ ${relationEntries.join("; ")} }`;
|
|
84
|
-
}
|
|
85
|
-
function generateModelsType(models, generateModelStorage) {
|
|
86
|
-
if (!models || Object.keys(models).length === 0) return "Record<string, never>";
|
|
87
|
-
const modelTypes = [];
|
|
88
|
-
for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {
|
|
89
|
-
const fieldsType = generateModelFieldsType(model.fields);
|
|
90
|
-
const relationsType = generateModelRelationsType(model.relations);
|
|
91
|
-
const storageType = generateModelStorage(modelName, model);
|
|
92
|
-
const modelParts = [
|
|
93
|
-
`readonly fields: ${fieldsType}`,
|
|
94
|
-
`readonly relations: ${relationsType}`,
|
|
95
|
-
`readonly storage: ${storageType}`
|
|
96
|
-
];
|
|
97
|
-
if (model.owner) modelParts.push(`readonly owner: ${serializeValue(model.owner)}`);
|
|
98
|
-
if (model.discriminator) modelParts.push(`readonly discriminator: ${serializeValue(model.discriminator)}`);
|
|
99
|
-
if (model.variants) modelParts.push(`readonly variants: ${serializeValue(model.variants)}`);
|
|
100
|
-
if (model.base) modelParts.push(`readonly base: ${serializeCrossReference(model.base)}`);
|
|
101
|
-
modelTypes.push(`readonly ${modelName}: { ${modelParts.join("; ")} }`);
|
|
102
|
-
}
|
|
103
|
-
return `{ ${modelTypes.join("; ")} }`;
|
|
104
|
-
}
|
|
105
|
-
function deduplicateImports(imports) {
|
|
106
|
-
const seenKeys = /* @__PURE__ */ new Set();
|
|
107
|
-
const result = [];
|
|
108
|
-
for (const imp of imports) {
|
|
109
|
-
const key = `${imp.package}::${imp.named}`;
|
|
110
|
-
if (!seenKeys.has(key)) {
|
|
111
|
-
seenKeys.add(key);
|
|
112
|
-
result.push(imp);
|
|
113
|
-
}
|
|
114
|
-
}
|
|
115
|
-
return result;
|
|
116
|
-
}
|
|
117
|
-
function generateImportLines(imports) {
|
|
118
|
-
const rendered = renderImports(imports.map((imp) => ({
|
|
119
|
-
moduleSpecifier: imp.package,
|
|
120
|
-
symbol: imp.named,
|
|
121
|
-
alias: imp.alias,
|
|
122
|
-
typeOnly: true
|
|
123
|
-
})));
|
|
124
|
-
return rendered === "" ? [] : rendered.split("\n");
|
|
125
|
-
}
|
|
126
|
-
function generateCodecTypeIntersection(imports, named) {
|
|
127
|
-
return imports.filter((imp) => imp.named === named).map((imp) => imp.alias).join(" & ") || "Record<string, never>";
|
|
128
|
-
}
|
|
129
|
-
function serializeExecutionType(execution) {
|
|
130
|
-
const parts = ["readonly executionHash: ExecutionHash"];
|
|
131
|
-
for (const [key, value] of Object.entries(execution)) {
|
|
132
|
-
if (key === "executionHash") continue;
|
|
133
|
-
parts.push(`readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`);
|
|
134
|
-
}
|
|
135
|
-
return `{ ${parts.join("; ")} }`;
|
|
136
|
-
}
|
|
137
|
-
function generateHashTypeAliases(hashes) {
|
|
138
|
-
const executionHashType = hashes.executionHash ? `ExecutionHashBase<'${hashes.executionHash}'>` : "ExecutionHashBase<string>";
|
|
139
|
-
return [
|
|
140
|
-
`export type StorageHash = StorageHashBase<'${hashes.storageHash}'>;`,
|
|
141
|
-
`export type ExecutionHash = ${executionHashType};`,
|
|
142
|
-
`export type ProfileHash = ProfileHashBase<'${hashes.profileHash}'>;`
|
|
143
|
-
].join("\n");
|
|
144
|
-
}
|
|
145
|
-
function applyModifiers(base, field) {
|
|
146
|
-
let result = base;
|
|
147
|
-
if (field.many === true) result = `ReadonlyArray<${result}>`;
|
|
148
|
-
if (field.dict === true) result = `Readonly<Record<string, ${result}>>`;
|
|
149
|
-
if (field.nullable) result = `${result} | null`;
|
|
150
|
-
return result;
|
|
151
|
-
}
|
|
152
|
-
/**
|
|
153
|
-
* Renders a value set (a field/column's permitted values, codec-encoded) into a TS literal union by
|
|
154
|
-
* routing **each** value through the codec's `renderValueLiteral` — the seam owned by the codec, not
|
|
155
|
-
* a generic serializer. `side`: `output` = read type, `input` = create/update type.
|
|
156
|
-
*
|
|
157
|
-
* Returns `undefined` — signalling the caller to fall back to the codec's full output type — when
|
|
158
|
-
* the lookup is absent, has no `renderValueLiteralFor`, the value set is empty, or **any** value
|
|
159
|
-
* isn't literal-expressible. A caller that needs column and field types to agree shares this so both
|
|
160
|
-
* compute the union identically.
|
|
161
|
-
*/
|
|
162
|
-
function renderValueSetType(values, codecId, side, codecLookup) {
|
|
163
|
-
if (values.length === 0 || codecLookup?.renderValueLiteralFor === void 0) return void 0;
|
|
164
|
-
const literals = [];
|
|
165
|
-
for (const value of values) {
|
|
166
|
-
const lit = codecLookup.renderValueLiteralFor(codecId, value, side);
|
|
167
|
-
if (lit === void 0 || !isSafeTypeExpression(lit)) return void 0;
|
|
168
|
-
literals.push(lit);
|
|
169
|
-
}
|
|
170
|
-
return literals.join(" | ");
|
|
171
|
-
}
|
|
172
|
-
function resolveFieldType(field, codecLookup, resolvedTypeParams, resolvedValueSet) {
|
|
173
|
-
const { type } = field;
|
|
174
|
-
switch (type.kind) {
|
|
175
|
-
case "scalar": {
|
|
176
|
-
if (resolvedValueSet) {
|
|
177
|
-
const output = renderValueSetType(resolvedValueSet.encodedValues, resolvedValueSet.codecId, "output", codecLookup);
|
|
178
|
-
const input = renderValueSetType(resolvedValueSet.encodedValues, resolvedValueSet.codecId, "input", codecLookup);
|
|
179
|
-
if (output !== void 0 && input !== void 0) return {
|
|
180
|
-
output: applyModifiers(output, field),
|
|
181
|
-
input: applyModifiers(input, field)
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
let outputResolved;
|
|
185
|
-
let inputResolved;
|
|
186
|
-
const effectiveTypeParams = (type.typeParams && Object.keys(type.typeParams).length > 0 ? type.typeParams : void 0) ?? resolvedTypeParams;
|
|
187
|
-
if (codecLookup && effectiveTypeParams && Object.keys(effectiveTypeParams).length > 0) {
|
|
188
|
-
const rendered = codecLookup.renderOutputTypeFor(type.codecId, effectiveTypeParams);
|
|
189
|
-
if (rendered && isSafeTypeExpression(rendered)) outputResolved = rendered;
|
|
190
|
-
const renderedInput = codecLookup.renderInputTypeFor?.(type.codecId, effectiveTypeParams);
|
|
191
|
-
if (renderedInput && isSafeTypeExpression(renderedInput)) inputResolved = renderedInput;
|
|
192
|
-
}
|
|
193
|
-
const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;
|
|
194
|
-
return {
|
|
195
|
-
output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),
|
|
196
|
-
input: applyModifiers(inputResolved ?? `${codecAccessor}['input']`, field)
|
|
197
|
-
};
|
|
198
|
-
}
|
|
199
|
-
case "valueObject": return {
|
|
200
|
-
output: applyModifiers(`${type.name}Output`, field),
|
|
201
|
-
input: applyModifiers(`${type.name}Input`, field)
|
|
202
|
-
};
|
|
203
|
-
case "union": {
|
|
204
|
-
const outputMembers = type.members.map((m) => m.kind === "scalar" ? `CodecTypes[${serializeValue(m.codecId)}]['output']` : `${m.name}Output`);
|
|
205
|
-
const inputMembers = type.members.map((m) => m.kind === "scalar" ? `CodecTypes[${serializeValue(m.codecId)}]['input']` : `${m.name}Input`);
|
|
206
|
-
return {
|
|
207
|
-
output: applyModifiers(outputMembers.join(" | "), field),
|
|
208
|
-
input: applyModifiers(inputMembers.join(" | "), field)
|
|
209
|
-
};
|
|
210
|
-
}
|
|
211
|
-
default: return {
|
|
212
|
-
output: applyModifiers("unknown", field),
|
|
213
|
-
input: applyModifiers("unknown", field)
|
|
214
|
-
};
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
function generateFieldResolvedType(field, codecLookup, side = "output") {
|
|
218
|
-
return resolveFieldType(field, codecLookup)[side];
|
|
219
|
-
}
|
|
220
|
-
function generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveFieldValueSet) {
|
|
221
|
-
if (!models || Object.keys(models).length === 0) return {
|
|
222
|
-
output: "Record<string, never>",
|
|
223
|
-
input: "Record<string, never>"
|
|
224
|
-
};
|
|
225
|
-
const outputModelEntries = [];
|
|
226
|
-
const inputModelEntries = [];
|
|
227
|
-
for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {
|
|
228
|
-
if (!model) continue;
|
|
229
|
-
const outputFieldEntries = [];
|
|
230
|
-
const inputFieldEntries = [];
|
|
231
|
-
for (const [fieldName, field] of Object.entries(model.fields)) {
|
|
232
|
-
const resolvedTypeParams = (field.type.kind === "scalar" && field.type.typeParams && Object.keys(field.type.typeParams).length > 0 ? field.type.typeParams : void 0) ?? resolveFieldTypeParams?.(modelName, fieldName, model);
|
|
233
|
-
const resolvedValueSet = resolveFieldValueSet?.(modelName, fieldName, model);
|
|
234
|
-
const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams, resolvedValueSet);
|
|
235
|
-
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
236
|
-
outputFieldEntries.push(`${key}: ${resolved.output}`);
|
|
237
|
-
inputFieldEntries.push(`${key}: ${resolved.input}`);
|
|
238
|
-
}
|
|
239
|
-
const outputFields = outputFieldEntries.length > 0 ? `{ ${outputFieldEntries.join("; ")} }` : "Record<string, never>";
|
|
240
|
-
const inputFields = inputFieldEntries.length > 0 ? `{ ${inputFieldEntries.join("; ")} }` : "Record<string, never>";
|
|
241
|
-
const modelKey = `readonly ${serializeObjectKey(modelName)}`;
|
|
242
|
-
outputModelEntries.push(`${modelKey}: ${outputFields}`);
|
|
243
|
-
inputModelEntries.push(`${modelKey}: ${inputFields}`);
|
|
244
|
-
}
|
|
245
|
-
return {
|
|
246
|
-
output: `{ ${outputModelEntries.join("; ")} }`,
|
|
247
|
-
input: `{ ${inputModelEntries.join("; ")} }`
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
function generateFieldTypesMapsByNamespace(namespaceModels, codecLookup, resolveFieldTypeParams, resolveFieldValueSet) {
|
|
251
|
-
if (namespaceModels.length === 0) return {
|
|
252
|
-
output: "Record<string, never>",
|
|
253
|
-
input: "Record<string, never>"
|
|
254
|
-
};
|
|
255
|
-
const outputNamespaceEntries = [];
|
|
256
|
-
const inputNamespaceEntries = [];
|
|
257
|
-
for (const [nsId, models] of namespaceModels) {
|
|
258
|
-
const inner = generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams, resolveFieldValueSet);
|
|
259
|
-
const nsKey = `readonly ${serializeObjectKey(nsId)}`;
|
|
260
|
-
outputNamespaceEntries.push(`${nsKey}: ${inner.output}`);
|
|
261
|
-
inputNamespaceEntries.push(`${nsKey}: ${inner.input}`);
|
|
262
|
-
}
|
|
263
|
-
return {
|
|
264
|
-
output: `{ ${outputNamespaceEntries.join("; ")} }`,
|
|
265
|
-
input: `{ ${inputNamespaceEntries.join("; ")} }`
|
|
266
|
-
};
|
|
267
|
-
}
|
|
268
|
-
function generateFieldOutputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
269
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).output;
|
|
270
|
-
}
|
|
271
|
-
function generateFieldInputTypesMap(models, codecLookup, resolveFieldTypeParams) {
|
|
272
|
-
return generateBothFieldTypesMaps(models, codecLookup, resolveFieldTypeParams).input;
|
|
273
|
-
}
|
|
274
|
-
function generateValueObjectType(_voName, vo, _valueObjects, side = "output", codecLookup) {
|
|
275
|
-
return resolveValueObjectType(_voName, vo, _valueObjects, codecLookup)[side];
|
|
276
|
-
}
|
|
277
|
-
function resolveValueObjectType(_voName, vo, _valueObjects, codecLookup) {
|
|
278
|
-
const outputEntries = [];
|
|
279
|
-
const inputEntries = [];
|
|
280
|
-
for (const [fieldName, field] of Object.entries(vo.fields)) {
|
|
281
|
-
const resolved = resolveFieldType(field, codecLookup);
|
|
282
|
-
const key = `readonly ${serializeObjectKey(fieldName)}`;
|
|
283
|
-
outputEntries.push(`${key}: ${resolved.output}`);
|
|
284
|
-
inputEntries.push(`${key}: ${resolved.input}`);
|
|
285
|
-
}
|
|
286
|
-
const empty = "Record<string, never>";
|
|
287
|
-
return {
|
|
288
|
-
output: outputEntries.length > 0 ? `{ ${outputEntries.join("; ")} }` : empty,
|
|
289
|
-
input: inputEntries.length > 0 ? `{ ${inputEntries.join("; ")} }` : empty
|
|
290
|
-
};
|
|
291
|
-
}
|
|
292
|
-
function generateContractFieldDescriptor(fieldName, field) {
|
|
293
|
-
const mods = [];
|
|
294
|
-
if (field.many === true) mods.push("; readonly many: true");
|
|
295
|
-
if (field.dict === true) mods.push("; readonly dict: true");
|
|
296
|
-
const modStr = mods.join("");
|
|
297
|
-
const { type } = field;
|
|
298
|
-
if (type.kind === "scalar") {
|
|
299
|
-
const typeParamsSpec = type.typeParams && Object.keys(type.typeParams).length > 0 ? `; readonly typeParams: ${serializeValue(type.typeParams)}` : "";
|
|
300
|
-
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${modStr} }`;
|
|
301
|
-
}
|
|
302
|
-
if (type.kind === "valueObject") return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${modStr} }`;
|
|
303
|
-
return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: ${serializeValue(type)}${modStr} }`;
|
|
304
|
-
}
|
|
305
|
-
function generateValueObjectsDescriptorType(valueObjects) {
|
|
306
|
-
if (!valueObjects || Object.keys(valueObjects).length === 0) return "Record<string, never>";
|
|
307
|
-
const voEntries = [];
|
|
308
|
-
for (const [voName, vo] of Object.entries(valueObjects)) {
|
|
309
|
-
const fieldEntries = [];
|
|
310
|
-
for (const [fieldName, field] of Object.entries(vo.fields)) fieldEntries.push(generateContractFieldDescriptor(fieldName, field));
|
|
311
|
-
const fieldsType = fieldEntries.length > 0 ? `{ ${fieldEntries.join("; ")} }` : "Record<string, never>";
|
|
312
|
-
voEntries.push(`readonly ${serializeObjectKey(voName)}: { readonly fields: ${fieldsType} }`);
|
|
313
|
-
}
|
|
314
|
-
return `{ ${voEntries.join("; ")} }`;
|
|
315
|
-
}
|
|
316
|
-
function generateValueObjectTypeAliases(valueObjects, codecLookup) {
|
|
317
|
-
if (!valueObjects || Object.keys(valueObjects).length === 0) return "";
|
|
318
|
-
const aliases = [];
|
|
319
|
-
for (const [voName, vo] of Object.entries(valueObjects)) {
|
|
320
|
-
const resolved = resolveValueObjectType(voName, vo, valueObjects, codecLookup);
|
|
321
|
-
aliases.push(`export type ${voName}Output = ${resolved.output};`);
|
|
322
|
-
aliases.push(`export type ${voName}Input = ${resolved.input};`);
|
|
323
|
-
}
|
|
324
|
-
return aliases.join("\n");
|
|
325
|
-
}
|
|
326
|
-
//#endregion
|
|
1
|
+
import { C as serializeExecutionType, E as serializeValue, S as serializeCrossReference, T as serializeObjectKey, _ as generateValueObjectTypeAliases, a as generateFieldInputTypesMap, b as resolveFieldType, c as generateFieldTypesMapsByNamespace, d as generateModelFieldEntry, f as generateModelFieldsType, g as generateValueObjectType, h as generateRootsType, i as generateContractFieldDescriptor, l as generateHashTypeAliases, m as generateModelsType, n as generateBothFieldTypesMaps, o as generateFieldOutputTypesMap, p as generateModelRelationsType, r as generateCodecTypeIntersection, s as generateFieldResolvedType, t as deduplicateImports, u as generateImportLines, v as generateValueObjectsDescriptorType, w as serializeNamespaceId, x as resolveValueObjectType, y as renderValueSetType } from "./domain-type-generation-BpLtcnoV.mjs";
|
|
327
2
|
export { deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateContractFieldDescriptor, generateFieldInputTypesMap, generateFieldOutputTypesMap, generateFieldResolvedType, generateFieldTypesMapsByNamespace, generateHashTypeAliases, generateImportLines, generateModelFieldEntry, generateModelFieldsType, generateModelRelationsType, generateModelsType, generateRootsType, generateValueObjectType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, renderValueSetType, resolveFieldType, resolveValueObjectType, serializeCrossReference, serializeExecutionType, serializeNamespaceId, serializeObjectKey, serializeValue };
|
|
328
|
-
|
|
329
|
-
//# sourceMappingURL=domain-type-generation.mjs.map
|
package/dist/exports/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { E as serializeValue, T as serializeObjectKey, h as generateRootsType, l as generateHashTypeAliases, o as generateFieldOutputTypesMap, p as generateModelRelationsType, r as generateCodecTypeIntersection, t as deduplicateImports, u as generateImportLines } from "../domain-type-generation-BpLtcnoV.mjs";
|
|
2
|
+
import { n as generateContractDts, r as getEmittedArtifactPaths, t as emit } from "../exports-CNvUZ1K7.mjs";
|
|
3
3
|
export { deduplicateImports, emit, generateCodecTypeIntersection, generateContractDts, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, getEmittedArtifactPaths, serializeObjectKey, serializeValue };
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { C as serializeExecutionType, D as emitterError, E as serializeValue, T as serializeObjectKey, _ as generateValueObjectTypeAliases, c as generateFieldTypesMapsByNamespace, h as generateRootsType, l as generateHashTypeAliases, m as generateModelsType, r as generateCodecTypeIntersection, t as deduplicateImports, u as generateImportLines, v as generateValueObjectsDescriptorType } from "./domain-type-generation-BpLtcnoV.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";
|
|
5
5
|
import { format } from "prettier";
|
|
6
|
-
import {
|
|
6
|
+
import { InternalError } from "@prisma-next/utils/internal-error";
|
|
7
7
|
//#region src/artifact-paths.ts
|
|
8
8
|
const JSON_EXTENSION = ".json";
|
|
9
9
|
function getEmittedArtifactPaths(outputJsonPath) {
|
|
10
|
-
if (!outputJsonPath.endsWith(JSON_EXTENSION)) throw
|
|
10
|
+
if (!outputJsonPath.endsWith(JSON_EXTENSION)) throw emitterError("CONFIG.VALIDATION_FAILED", "Contract output path must end with .json", { meta: {
|
|
11
|
+
field: "contract.output",
|
|
12
|
+
outputJsonPath
|
|
13
|
+
} });
|
|
11
14
|
return {
|
|
12
15
|
jsonPath: outputJsonPath,
|
|
13
16
|
dtsPath: `${outputJsonPath.slice(0, -5)}.d.ts`
|
|
@@ -32,8 +35,8 @@ function generateContractDts(contract, emitter, codecTypeImports, hashes, option
|
|
|
32
35
|
const typeMapsExpr = emitter.getTypeMapsExpression();
|
|
33
36
|
const storageType = emitter.generateStorageType(contract, "StorageHash");
|
|
34
37
|
const namespaceEntries = Object.entries(contract.domain.namespaces);
|
|
35
|
-
if (namespaceEntries.length === 0) throw
|
|
36
|
-
for (const [nsId, ns] of namespaceEntries) if (ns === void 0) throw new
|
|
38
|
+
if (namespaceEntries.length === 0) throw emitterError("CONTRACT.NAMESPACE_INVALID", "domain has no namespaces", { meta: { reason: "no-domain-namespaces" } });
|
|
39
|
+
for (const [nsId, ns] of namespaceEntries) if (ns === void 0) throw new InternalError(`domain namespace "${nsId}" is not present on the contract`);
|
|
37
40
|
const rootsType = generateRootsType(contract.roots);
|
|
38
41
|
const flatValueObjects = {};
|
|
39
42
|
for (const [, ns] of namespaceEntries) for (const [voName, vo] of Object.entries(blindCast(ns.valueObjects ?? {}))) if (!(voName in flatValueObjects)) flatValueObjects[voName] = vo;
|
|
@@ -97,7 +100,7 @@ ${domainNamespacesType};
|
|
|
97
100
|
};
|
|
98
101
|
};
|
|
99
102
|
readonly capabilities: ${serializeValue(contract.capabilities)};
|
|
100
|
-
readonly
|
|
103
|
+
readonly extensions: ${serializeValue(contract.extensions)};${executionClause}
|
|
101
104
|
readonly meta: ${serializeValue(contract.meta)};
|
|
102
105
|
${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ""}
|
|
103
106
|
readonly profileHash: ProfileHash;
|
|
@@ -151,4 +154,4 @@ async function emit(contract, stack, targetFamily, options) {
|
|
|
151
154
|
//#endregion
|
|
152
155
|
export { generateContractDts as n, getEmittedArtifactPaths as r, emit as t };
|
|
153
156
|
|
|
154
|
-
//# sourceMappingURL=exports-
|
|
157
|
+
//# sourceMappingURL=exports-CNvUZ1K7.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"exports-CNvUZ1K7.mjs","names":[],"sources":["../src/artifact-paths.ts","../src/generate-contract-dts.ts","../src/emit.ts"],"sourcesContent":["import { emitterError } from './emitter-errors';\n\nconst 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 emitterError('CONFIG.VALIDATION_FAILED', 'Contract output path must end with .json', {\n meta: { field: 'contract.output', outputJsonPath },\n });\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 ContractModelBase,\n ContractValueObject,\n} from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type {\n EmissionSpi,\n GenerateContractTypesOptions,\n TypesImportSpec,\n} from '@prisma-next/framework-components/emission';\nimport { blindCast } from '@prisma-next/utils/casts';\nimport { InternalError } from '@prisma-next/utils/internal-error';\nimport {\n deduplicateImports,\n generateCodecTypeIntersection,\n generateFieldTypesMapsByNamespace,\n generateHashTypeAliases,\n generateImportLines,\n generateModelsType,\n generateRootsType,\n generateValueObjectsDescriptorType,\n generateValueObjectTypeAliases,\n serializeExecutionType,\n serializeObjectKey,\n serializeValue,\n} from './domain-type-generation';\nimport { emitterError } from './emitter-errors';\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 emitterError('CONTRACT.NAMESPACE_INVALID', 'domain has no namespaces', {\n meta: { reason: 'no-domain-namespaces' },\n });\n }\n\n // Validate all namespace entries are present.\n for (const [nsId, ns] of namespaceEntries) {\n if (ns === undefined) {\n throw new InternalError(`domain namespace \"${nsId}\" is not present on the contract`);\n }\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 = 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: ContractModelBase) =>\n emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract)\n : undefined;\n\n const resolveFieldValueSet = emitter.resolveFieldValueSet\n ? (modelName: string, fieldName: string, model: ContractModelBase) =>\n emitter.resolveFieldValueSet?.(modelName, fieldName, model, contract)\n : undefined;\n\n const namespaceModelsForFieldTypes = namespaceEntries.map(\n ([nsId, ns]) => [nsId, ns.models] as const,\n );\n\n const fieldTypesMaps = generateFieldTypesMapsByNamespace(\n namespaceModelsForFieldTypes,\n codecLookup,\n resolveFieldTypeParams,\n resolveFieldValueSet,\n );\n\n const extraTypeExports = emitter.getStorageTypeExports?.(contract, codecLookup);\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 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};\n${extraTypeExports ? `${extraTypeExports}\\n` : ''}export type TypeMaps = ${typeMapsExpr};\n\ntype ContractBase = Omit<\n ContractType<${storageType}>,\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 extensions: ${serializeValue(contract.extensions)};${executionClause}\n readonly meta: ${serializeValue(contract.meta)};\n ${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ''}\n readonly profileHash: ProfileHash;\n};\n\n${contractWrapper}\n`;\n}\n","import { canonicalizeContractToObject } from '@prisma-next/contract/hashing';\nimport type { Contract } from '@prisma-next/contract/types';\nimport type { EmissionSpi } from '@prisma-next/framework-components/emission';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { format } from 'prettier';\nimport { getEmittedArtifactPaths } from './artifact-paths';\nimport type { EmitOptions, EmitResult, EmitStackInput } from './emit-types';\nimport { generateContractDts } from './generate-contract-dts';\n\nconst SCHEMA_VERSION = '1';\n\nexport async function emit(\n contract: Contract,\n stack: EmitStackInput,\n targetFamily: EmissionSpi,\n options: EmitOptions,\n): Promise<EmitResult> {\n if (options.outputJsonPath !== undefined) {\n getEmittedArtifactPaths(options.outputJsonPath);\n }\n\n const { codecTypeImports, queryOperationTypeImports } = stack;\n\n const { storageHash } = contract.storage;\n const executionHash = contract.execution?.executionHash;\n const { profileHash } = contract;\n\n const canonicalized = canonicalizeContractToObject(contract, {\n schemaVersion: SCHEMA_VERSION,\n serializeContract: options.serializeContract,\n ...ifDefined('shouldPreserveEmpty', options.shouldPreserveEmpty),\n ...ifDefined('sortStorage', options.sortStorage),\n });\n const contractJsonString = JSON.stringify(\n {\n ...canonicalized,\n _generated: {\n warning: '⚠️ GENERATED FILE - DO NOT EDIT',\n message: 'This file is automatically generated by \"prisma-next contract emit\".',\n regenerate: 'To regenerate, run: prisma-next contract emit',\n },\n },\n null,\n 2,\n );\n\n const generateOptions = queryOperationTypeImports ? { queryOperationTypeImports } : undefined;\n\n const contractTypeHashes = {\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n const contractDtsRaw = generateContractDts(\n contract,\n targetFamily,\n codecTypeImports ?? [],\n contractTypeHashes,\n generateOptions,\n stack.codecLookup,\n );\n const contractDts = await format(contractDtsRaw, {\n parser: 'typescript',\n singleQuote: true,\n semi: true,\n printWidth: 100,\n });\n\n return {\n contractJson: contractJsonString,\n contractDts,\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index-P9tB7OkF.d.mts","names":[],"sources":["../src/artifact-paths.ts","../src/emit-types.ts","../src/emit.ts","../src/generate-contract-dts.ts"],"mappings":";;;;;;
|
|
1
|
+
{"version":3,"file":"index-P9tB7OkF.d.mts","names":[],"sources":["../src/artifact-paths.ts","../src/emit-types.ts","../src/emit.ts","../src/generate-contract-dts.ts"],"mappings":";;;;;;UAIiB;WACN;WACA;;iBAGK,wBAAwB,yBAAyB;;;;;;;;UCIhD;WACN,mBAAmB,cAAc;WACjC,4BAA4B,cAAc;WAC1C,eAAe;WACf,cAAc;;UAGR;WACN;;;;;;;;;;WAUA,mBAAmB;;;;;WAKnB,sBAAsB;;;;;WAKtB,cAAc;;UAGR;WACN;WACA;WACA;WACA;WACA;;;;iBCtCW,KACpB,UAAU,UACV,OAAO,gBACP,cAAc,aACd,SAAS,cACR,QAAQ;;;iBC0BK,oBACd,UAAU,UACV,SAAS,aACT,kBAAkB,cAAc,kBAChC;WACW;WACA;WACA;GAEX,UAAU,8BACV,cAAc"}
|
package/dist/test/utils.d.mts
CHANGED
|
@@ -17,7 +17,7 @@ type TestContractOverrides = {
|
|
|
17
17
|
enum?: Record<string, unknown>;
|
|
18
18
|
storage?: Record<string, unknown>;
|
|
19
19
|
capabilities?: Record<string, Record<string, boolean>>;
|
|
20
|
-
|
|
20
|
+
extensions?: Record<string, unknown>;
|
|
21
21
|
execution?: Record<string, unknown>;
|
|
22
22
|
meta?: Record<string, unknown>;
|
|
23
23
|
storageHash?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../test/utils.ts"],"mappings":";;;;;;;;;iBA2CgB,KACd,UAAU,UACV,OAAO,gBACP,QAAQ,aACR,UAAU,KAAK,oCACd,QAAQ;KAQN;EACH;EACA;EACA,QAAQ,eAAe;EACvB,SAAS;EACT,eAAe;EACf,OAAO;EACP,UAAU;EACV,eAAe,eAAe;EAC9B,
|
|
1
|
+
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../test/utils.ts"],"mappings":";;;;;;;;;iBA2CgB,KACd,UAAU,UACV,OAAO,gBACP,QAAQ,aACR,UAAU,KAAK,oCACd,QAAQ;KAQN;EACH;EACA;EACA,QAAQ,eAAe;EACvB,SAAS;EACT,eAAe;EACf,OAAO;EACP,UAAU;EACV,eAAe,eAAe;EAC9B,aAAa;EACb,YAAY;EACZ,OAAO;EACP;EACA;EACA,UAAU;;;iBAII,4BACd,MAAM,0BACL;iBAoBa,mBAAmB,YAAW,wBAA6B"}
|
package/dist/test/utils.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { t as emit$1 } from "../exports-
|
|
1
|
+
import { t as emit$1 } from "../exports-CNvUZ1K7.mjs";
|
|
2
2
|
import { computeExecutionHash, computeProfileHash, computeStorageHash } from "@prisma-next/contract/hashing";
|
|
3
3
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
4
|
-
import { UNBOUND_DOMAIN_NAMESPACE_ID, coreHash } from "@prisma-next/contract/types";
|
|
5
4
|
import { createPreserveEmptyPredicate, createStorageSort } from "@prisma-next/contract/hashing-utils";
|
|
6
|
-
coreHash
|
|
5
|
+
import { UNBOUND_DOMAIN_NAMESPACE_ID, coreHash } from "@prisma-next/contract/types";
|
|
6
|
+
coreHash("test");
|
|
7
7
|
const DEFAULT_FRAMEWORK_STORAGE = { namespaces: {} };
|
|
8
8
|
function createContract(overrides = {}) {
|
|
9
9
|
const target = overrides.target ?? "postgres";
|
|
@@ -37,7 +37,7 @@ function createContract(overrides = {}) {
|
|
|
37
37
|
} } },
|
|
38
38
|
storage,
|
|
39
39
|
capabilities,
|
|
40
|
-
|
|
40
|
+
extensions: overrides.extensions ?? {},
|
|
41
41
|
...overrides.execution !== void 0 ? { execution: {
|
|
42
42
|
...overrides.execution,
|
|
43
43
|
executionHash: computeExecutionHash({
|
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 { 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(\"
|
|
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 { 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(\"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 ?? {},\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\textensions: overrides.extensions ?? {},\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 extensions?: 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":";;;;;AAImB,SAAS,MAAM;AAClC,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,CAAC;GAC7B,GAAG,UAAU,gBAAgB,UAAU,YAAY;GACnD,GAAG,UAAU,QAAQ,UAAU,IAAI;EACpC,EAAE,EAAE;EACJ;EACA;EACA,YAAY,UAAU,cAAc,CAAC;EACrC,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;;;ACtCA,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.16.0-dev.
|
|
3
|
+
"version": "0.16.0-dev.31",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@prisma-next/contract": "0.16.0-dev.
|
|
9
|
-
"@prisma-next/framework-components": "0.16.0-dev.
|
|
10
|
-
"@prisma-next/operations": "0.16.0-dev.
|
|
11
|
-
"@prisma-next/ts-render": "0.16.0-dev.
|
|
12
|
-
"@prisma-next/utils": "0.16.0-dev.
|
|
8
|
+
"@prisma-next/contract": "0.16.0-dev.31",
|
|
9
|
+
"@prisma-next/framework-components": "0.16.0-dev.31",
|
|
10
|
+
"@prisma-next/operations": "0.16.0-dev.31",
|
|
11
|
+
"@prisma-next/ts-render": "0.16.0-dev.31",
|
|
12
|
+
"@prisma-next/utils": "0.16.0-dev.31",
|
|
13
13
|
"arktype": "^2.2.2",
|
|
14
14
|
"prettier": "^3.9.5"
|
|
15
15
|
},
|
|
16
16
|
"devDependencies": {
|
|
17
|
-
"@prisma-next/test-utils": "0.16.0-dev.
|
|
18
|
-
"@prisma-next/tsconfig": "0.16.0-dev.
|
|
17
|
+
"@prisma-next/test-utils": "0.16.0-dev.31",
|
|
18
|
+
"@prisma-next/tsconfig": "0.16.0-dev.31",
|
|
19
19
|
"@types/node": "25.9.4",
|
|
20
|
-
"@prisma-next/tsdown": "0.16.0-dev.
|
|
20
|
+
"@prisma-next/tsdown": "0.16.0-dev.31",
|
|
21
21
|
"tsdown": "0.22.8",
|
|
22
22
|
"typescript": "5.9.3",
|
|
23
23
|
"vitest": "4.1.10"
|
package/src/artifact-paths.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { emitterError } from './emitter-errors';
|
|
2
|
+
|
|
1
3
|
const JSON_EXTENSION = '.json';
|
|
2
4
|
|
|
3
5
|
export interface EmittedArtifactPaths {
|
|
@@ -7,7 +9,9 @@ export interface EmittedArtifactPaths {
|
|
|
7
9
|
|
|
8
10
|
export function getEmittedArtifactPaths(outputJsonPath: string): EmittedArtifactPaths {
|
|
9
11
|
if (!outputJsonPath.endsWith(JSON_EXTENSION)) {
|
|
10
|
-
throw
|
|
12
|
+
throw emitterError('CONFIG.VALIDATION_FAILED', 'Contract output path must end with .json', {
|
|
13
|
+
meta: { field: 'contract.output', outputJsonPath },
|
|
14
|
+
});
|
|
11
15
|
}
|
|
12
16
|
|
|
13
17
|
return {
|
|
@@ -10,6 +10,7 @@ import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
|
10
10
|
import type { TypesImportSpec } from '@prisma-next/framework-components/emission';
|
|
11
11
|
import { type ImportRequirement, renderImports } from '@prisma-next/ts-render';
|
|
12
12
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
13
|
+
import { emitterError } from './emitter-errors';
|
|
13
14
|
import { isSafeTypeExpression } from './type-expression-safety';
|
|
14
15
|
|
|
15
16
|
export function serializeValue(value: unknown): string {
|
|
@@ -138,8 +139,10 @@ export function generateModelRelationsType(relations: Record<string, unknown>):
|
|
|
138
139
|
|
|
139
140
|
const on = relObj['on'] as { localFields?: string[]; targetFields?: string[] } | undefined;
|
|
140
141
|
if (on && (!on.localFields || !on.targetFields)) {
|
|
141
|
-
throw
|
|
142
|
+
throw emitterError(
|
|
143
|
+
'CONTRACT.RELATION_INVALID',
|
|
142
144
|
`Relation "${relName}" has an "on" block but is missing localFields or targetFields`,
|
|
145
|
+
{ meta: { relation: relName } },
|
|
143
146
|
);
|
|
144
147
|
}
|
|
145
148
|
if (on?.localFields && on.targetFields) {
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { StructuredError, StructuredErrorOptions } from '@prisma-next/utils/structured-error';
|
|
2
|
+
import { structuredError } from '@prisma-next/utils/structured-error';
|
|
3
|
+
|
|
4
|
+
export type EmitterErrorCode =
|
|
5
|
+
| 'CONFIG.VALIDATION_FAILED'
|
|
6
|
+
| 'CONTRACT.NAMESPACE_INVALID'
|
|
7
|
+
| 'CONTRACT.RELATION_INVALID';
|
|
8
|
+
|
|
9
|
+
export function emitterError(
|
|
10
|
+
code: EmitterErrorCode,
|
|
11
|
+
message: string,
|
|
12
|
+
options?: StructuredErrorOptions,
|
|
13
|
+
): StructuredError {
|
|
14
|
+
return structuredError(code, message, options);
|
|
15
|
+
}
|
|
@@ -4,7 +4,6 @@ import type {
|
|
|
4
4
|
ContractModelBase,
|
|
5
5
|
ContractValueObject,
|
|
6
6
|
} from '@prisma-next/contract/types';
|
|
7
|
-
import { DomainNamespaceResolutionError } from '@prisma-next/contract/types';
|
|
8
7
|
import type { CodecLookup } from '@prisma-next/framework-components/codec';
|
|
9
8
|
import type {
|
|
10
9
|
EmissionSpi,
|
|
@@ -12,6 +11,7 @@ import type {
|
|
|
12
11
|
TypesImportSpec,
|
|
13
12
|
} from '@prisma-next/framework-components/emission';
|
|
14
13
|
import { blindCast } from '@prisma-next/utils/casts';
|
|
14
|
+
import { InternalError } from '@prisma-next/utils/internal-error';
|
|
15
15
|
import {
|
|
16
16
|
deduplicateImports,
|
|
17
17
|
generateCodecTypeIntersection,
|
|
@@ -26,6 +26,7 @@ import {
|
|
|
26
26
|
serializeObjectKey,
|
|
27
27
|
serializeValue,
|
|
28
28
|
} from './domain-type-generation';
|
|
29
|
+
import { emitterError } from './emitter-errors';
|
|
29
30
|
|
|
30
31
|
function generateEnumBlockType(enums: Record<string, ContractEnum>): string {
|
|
31
32
|
const entries = Object.entries(enums).map(([name, entry]) => {
|
|
@@ -72,13 +73,15 @@ export function generateContractDts(
|
|
|
72
73
|
|
|
73
74
|
const namespaceEntries = Object.entries(contract.domain.namespaces);
|
|
74
75
|
if (namespaceEntries.length === 0) {
|
|
75
|
-
throw
|
|
76
|
+
throw emitterError('CONTRACT.NAMESPACE_INVALID', 'domain has no namespaces', {
|
|
77
|
+
meta: { reason: 'no-domain-namespaces' },
|
|
78
|
+
});
|
|
76
79
|
}
|
|
77
80
|
|
|
78
81
|
// Validate all namespace entries are present.
|
|
79
82
|
for (const [nsId, ns] of namespaceEntries) {
|
|
80
83
|
if (ns === undefined) {
|
|
81
|
-
throw new
|
|
84
|
+
throw new InternalError(`domain namespace "${nsId}" is not present on the contract`);
|
|
82
85
|
}
|
|
83
86
|
}
|
|
84
87
|
|
|
@@ -206,7 +209,7 @@ ${domainNamespacesType};
|
|
|
206
209
|
};
|
|
207
210
|
};
|
|
208
211
|
readonly capabilities: ${serializeValue(contract.capabilities)};
|
|
209
|
-
readonly
|
|
212
|
+
readonly extensions: ${serializeValue(contract.extensions)};${executionClause}
|
|
210
213
|
readonly meta: ${serializeValue(contract.meta)};
|
|
211
214
|
${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ''}
|
|
212
215
|
readonly profileHash: ProfileHash;
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"domain-type-generation.mjs","names":[],"sources":["../src/domain-type-generation.ts"],"sourcesContent":["import type {\n ContractField,\n ContractManyToManyRelation,\n ContractModelBase,\n ContractValueObject,\n CrossReference,\n JsonValue,\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, ContractModelBase>,\n generateModelStorage: (modelName: string, model: ContractModelBase) => 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\nexport type FieldTypeParamsResolver = (\n modelName: string,\n fieldName: string,\n model: ContractModelBase,\n) => Record<string, unknown> | undefined;\n\n/**\n * A field's permitted values (codec-encoded) plus the codec that types them, as supplied by the\n * family-specific {@link EmissionSpi.resolveFieldValueSet}. The framework renders these into a TS\n * literal union through the codec seam ({@link renderValueSetType}).\n */\nexport type ResolvedFieldValueSet = {\n readonly encodedValues: readonly JsonValue[];\n readonly codecId: string;\n};\n\nexport type FieldValueSetResolver = (\n modelName: string,\n fieldName: string,\n model: ContractModelBase,\n) => ResolvedFieldValueSet | undefined;\n\n/**\n * Renders a value set (a field/column's permitted values, codec-encoded) into a TS literal union by\n * routing **each** value through the codec's `renderValueLiteral` — the seam owned by the codec, not\n * a generic serializer. `side`: `output` = read type, `input` = create/update type.\n *\n * Returns `undefined` — signalling the caller to fall back to the codec's full output type — when\n * the lookup is absent, has no `renderValueLiteralFor`, the value set is empty, or **any** value\n * isn't literal-expressible. A caller that needs column and field types to agree shares this so both\n * compute the union identically.\n */\nexport function renderValueSetType(\n values: readonly JsonValue[],\n codecId: string,\n side: 'output' | 'input',\n codecLookup: CodecLookup | undefined,\n): string | undefined {\n if (values.length === 0 || codecLookup?.renderValueLiteralFor === undefined) return undefined;\n const literals: string[] = [];\n for (const value of values) {\n const lit = codecLookup.renderValueLiteralFor(codecId, value, side);\n if (lit === undefined || !isSafeTypeExpression(lit)) return undefined;\n literals.push(lit);\n }\n return literals.join(' | ');\n}\n\nexport function resolveFieldType(\n field: ContractField,\n codecLookup?: CodecLookup,\n resolvedTypeParams?: Record<string, unknown>,\n resolvedValueSet?: ResolvedFieldValueSet,\n): ResolvedFieldType {\n const { type } = field;\n\n switch (type.kind) {\n case 'scalar': {\n if (resolvedValueSet) {\n const output = renderValueSetType(\n resolvedValueSet.encodedValues,\n resolvedValueSet.codecId,\n 'output',\n codecLookup,\n );\n const input = renderValueSetType(\n resolvedValueSet.encodedValues,\n resolvedValueSet.codecId,\n 'input',\n codecLookup,\n );\n if (output !== undefined && input !== undefined) {\n return {\n output: applyModifiers(output, field),\n input: applyModifiers(input, 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, ContractModelBase> | undefined,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n resolveFieldValueSet?: FieldValueSetResolver,\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 resolvedValueSet = resolveFieldValueSet?.(modelName, fieldName, model);\n const resolved = resolveFieldType(field, codecLookup, resolvedTypeParams, resolvedValueSet);\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 generateFieldTypesMapsByNamespace(\n namespaceModels: ReadonlyArray<readonly [string, Record<string, ContractModelBase>]>,\n codecLookup?: CodecLookup,\n resolveFieldTypeParams?: FieldTypeParamsResolver,\n resolveFieldValueSet?: FieldValueSetResolver,\n): ResolvedFieldType {\n if (namespaceModels.length === 0) {\n return { output: 'Record<string, never>', input: 'Record<string, never>' };\n }\n\n const outputNamespaceEntries: string[] = [];\n const inputNamespaceEntries: string[] = [];\n for (const [nsId, models] of namespaceModels) {\n const inner = generateBothFieldTypesMaps(\n models,\n codecLookup,\n resolveFieldTypeParams,\n resolveFieldValueSet,\n );\n const nsKey = `readonly ${serializeObjectKey(nsId)}`;\n outputNamespaceEntries.push(`${nsKey}: ${inner.output}`);\n inputNamespaceEntries.push(`${nsKey}: ${inner.input}`);\n }\n\n return {\n output: `{ ${outputNamespaceEntries.join('; ')} }`,\n input: `{ ${inputNamespaceEntries.join('; ')} }`,\n };\n}\n\nexport function generateFieldOutputTypesMap(\n models: Record<string, ContractModelBase> | 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, ContractModelBase> | 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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"exports-Bsc1vgw7.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 ContractModelBase,\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 generateCodecTypeIntersection,\n generateFieldTypesMapsByNamespace,\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 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 = 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: ContractModelBase) =>\n emitter.resolveFieldTypeParams?.(modelName, fieldName, model, contract)\n : undefined;\n\n const resolveFieldValueSet = emitter.resolveFieldValueSet\n ? (modelName: string, fieldName: string, model: ContractModelBase) =>\n emitter.resolveFieldValueSet?.(modelName, fieldName, model, contract)\n : undefined;\n\n const namespaceModelsForFieldTypes = namespaceEntries.map(\n ([nsId, ns]) => [nsId, ns.models] as const,\n );\n\n const fieldTypesMaps = generateFieldTypesMapsByNamespace(\n namespaceModelsForFieldTypes,\n codecLookup,\n resolveFieldTypeParams,\n resolveFieldValueSet,\n );\n\n const extraTypeExports = emitter.getStorageTypeExports?.(contract, codecLookup);\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 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};\n${extraTypeExports ? `${extraTypeExports}\\n` : ''}export type TypeMaps = ${typeMapsExpr};\n\ntype ContractBase = Omit<\n ContractType<${storageType}>,\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\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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"}
|