@prisma-next/emitter 0.3.0-pr.99.6 → 0.3.0

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.
Files changed (47) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +45 -35
  3. package/dist/domain-type-generation.d.mts +38 -0
  4. package/dist/domain-type-generation.d.mts.map +1 -0
  5. package/dist/domain-type-generation.mjs +255 -0
  6. package/dist/domain-type-generation.mjs.map +1 -0
  7. package/dist/exports/index.d.mts +39 -0
  8. package/dist/exports/index.d.mts.map +1 -0
  9. package/dist/exports/index.mjs +106 -0
  10. package/dist/exports/index.mjs.map +1 -0
  11. package/dist/test/utils.d.mts +21 -0
  12. package/dist/test/utils.d.mts.map +1 -0
  13. package/dist/test/utils.mjs +18 -0
  14. package/dist/test/utils.mjs.map +1 -0
  15. package/dist/type-expression-safety-7_1tfJXA.mjs +8 -0
  16. package/dist/type-expression-safety-7_1tfJXA.mjs.map +1 -0
  17. package/dist/type-expression-safety.d.mts +5 -0
  18. package/dist/type-expression-safety.d.mts.map +1 -0
  19. package/dist/type-expression-safety.mjs +3 -0
  20. package/package.json +27 -11
  21. package/src/domain-type-generation.ts +429 -0
  22. package/src/emit-types.ts +23 -0
  23. package/src/emit.ts +68 -0
  24. package/src/exports/index.ts +14 -9
  25. package/src/generate-contract-dts.ts +117 -0
  26. package/src/type-expression-safety.ts +3 -0
  27. package/test/canonicalization.test.ts +196 -19
  28. package/test/domain-type-generation.test.ts +997 -0
  29. package/test/emitter.integration.test.ts +132 -187
  30. package/test/emitter.roundtrip.test.ts +117 -191
  31. package/test/emitter.test.ts +123 -494
  32. package/test/hashing.test.ts +9 -34
  33. package/test/mock-spi.ts +18 -0
  34. package/test/type-expression-safety.test.ts +34 -0
  35. package/test/utils.ts +30 -165
  36. package/dist/exports/index.js +0 -6
  37. package/dist/exports/index.js.map +0 -1
  38. package/dist/src/exports/index.d.ts +0 -4
  39. package/dist/src/exports/index.d.ts.map +0 -1
  40. package/dist/src/target-family.d.ts +0 -2
  41. package/dist/src/target-family.d.ts.map +0 -1
  42. package/dist/test/utils.d.ts +0 -14
  43. package/dist/test/utils.d.ts.map +0 -1
  44. package/dist/test/utils.js +0 -78
  45. package/dist/test/utils.js.map +0 -1
  46. package/src/target-family.ts +0 -7
  47. package/test/factories.test.ts +0 -274
@@ -0,0 +1,255 @@
1
+ import { t as isSafeTypeExpression } from "./type-expression-safety-7_1tfJXA.mjs";
2
+
3
+ //#region src/domain-type-generation.ts
4
+ function serializeValue(value) {
5
+ if (value === null) return "null";
6
+ if (value === void 0) return "undefined";
7
+ if (typeof value === "string") return `'${value.replace(/\\/g, "\\\\").replace(/'/g, "\\'")}'`;
8
+ if (typeof value === "number" || typeof value === "boolean") return String(value);
9
+ if (typeof value === "bigint") return `${value}n`;
10
+ if (Array.isArray(value)) return `readonly [${value.map((v) => serializeValue(v)).join(", ")}]`;
11
+ if (typeof value === "object") {
12
+ const entries = [];
13
+ for (const [k, v] of Object.entries(value)) entries.push(`readonly ${serializeObjectKey(k)}: ${serializeValue(v)}`);
14
+ return `{ ${entries.join("; ")} }`;
15
+ }
16
+ return "unknown";
17
+ }
18
+ function serializeObjectKey(key) {
19
+ if (/^[$A-Z_a-z][$\w]*$/.test(key)) return key;
20
+ return serializeValue(key);
21
+ }
22
+ function generateRootsType(roots) {
23
+ if (!roots || Object.keys(roots).length === 0) return "Record<string, string>";
24
+ return `{ ${Object.entries(roots).map(([key, value]) => `readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`).join("; ")} }`;
25
+ }
26
+ function contractFieldModifierSuffix(field) {
27
+ return (field.many === true ? "; readonly many: true" : "") + (field.dict === true ? "; readonly dict: true" : "");
28
+ }
29
+ function generateModelFieldEntry(fieldName, field) {
30
+ const mods = contractFieldModifierSuffix(field);
31
+ const { nullable, type } = field;
32
+ if (type.kind === "scalar") {
33
+ const typeParamsSpec = type.typeParams && Object.keys(type.typeParams).length > 0 ? `; readonly typeParams: ${serializeValue(type.typeParams)}` : "";
34
+ return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${mods} }`;
35
+ }
36
+ if (type.kind === "valueObject") return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${mods} }`;
37
+ return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: ${serializeValue(type)}${mods} }`;
38
+ }
39
+ function generateModelFieldsType(fields) {
40
+ const fieldEntries = [];
41
+ for (const [fieldName, field] of Object.entries(fields)) fieldEntries.push(generateModelFieldEntry(fieldName, field));
42
+ return fieldEntries.length > 0 ? `{ ${fieldEntries.join("; ")} }` : "Record<string, never>";
43
+ }
44
+ function generateModelRelationsType(relations) {
45
+ const relationEntries = [];
46
+ for (const [relName, rel] of Object.entries(relations)) {
47
+ if (typeof rel !== "object" || rel === null) continue;
48
+ const relObj = rel;
49
+ const parts = [];
50
+ if (relObj["to"]) parts.push(`readonly to: ${serializeValue(relObj["to"])}`);
51
+ if (relObj["cardinality"]) parts.push(`readonly cardinality: ${serializeValue(relObj["cardinality"])}`);
52
+ const on = relObj["on"];
53
+ if (on && (!on.localFields || !on.targetFields)) throw new Error(`Relation "${relName}" has an "on" block but is missing localFields or targetFields`);
54
+ if (on?.localFields && on.targetFields) {
55
+ const localFields = on.localFields.map((f) => serializeValue(f)).join(", ");
56
+ const targetFields = on.targetFields.map((f) => serializeValue(f)).join(", ");
57
+ parts.push(`readonly on: { readonly localFields: readonly [${localFields}]; readonly targetFields: readonly [${targetFields}] }`);
58
+ }
59
+ if (parts.length > 0) relationEntries.push(`readonly ${relName}: { ${parts.join("; ")} }`);
60
+ }
61
+ if (relationEntries.length === 0) return "Record<string, never>";
62
+ return `{ ${relationEntries.join("; ")} }`;
63
+ }
64
+ function generateModelsType(models, generateModelStorage) {
65
+ if (!models || Object.keys(models).length === 0) return "Record<string, never>";
66
+ const modelTypes = [];
67
+ for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {
68
+ const fieldsType = generateModelFieldsType(model.fields);
69
+ const relationsType = generateModelRelationsType(model.relations);
70
+ const storageType = generateModelStorage(modelName, model);
71
+ const modelParts = [
72
+ `readonly fields: ${fieldsType}`,
73
+ `readonly relations: ${relationsType}`,
74
+ `readonly storage: ${storageType}`
75
+ ];
76
+ if (model.owner) modelParts.push(`readonly owner: ${serializeValue(model.owner)}`);
77
+ if (model.discriminator) modelParts.push(`readonly discriminator: ${serializeValue(model.discriminator)}`);
78
+ if (model.variants) modelParts.push(`readonly variants: ${serializeValue(model.variants)}`);
79
+ if (model.base) modelParts.push(`readonly base: ${serializeValue(model.base)}`);
80
+ modelTypes.push(`readonly ${modelName}: { ${modelParts.join("; ")} }`);
81
+ }
82
+ return `{ ${modelTypes.join("; ")} }`;
83
+ }
84
+ function deduplicateImports(imports) {
85
+ const seenKeys = /* @__PURE__ */ new Set();
86
+ const result = [];
87
+ for (const imp of imports) {
88
+ const key = `${imp.package}::${imp.named}`;
89
+ if (!seenKeys.has(key)) {
90
+ seenKeys.add(key);
91
+ result.push(imp);
92
+ }
93
+ }
94
+ return result;
95
+ }
96
+ function generateImportLines(imports) {
97
+ return imports.map((imp) => {
98
+ return `import type { ${imp.named === imp.alias ? imp.named : `${imp.named} as ${imp.alias}`} } from '${imp.package}';`;
99
+ });
100
+ }
101
+ function generateCodecTypeIntersection(imports, named) {
102
+ return imports.filter((imp) => imp.named === named).map((imp) => imp.alias).join(" & ") || "Record<string, never>";
103
+ }
104
+ function serializeExecutionType(execution) {
105
+ const parts = ["readonly executionHash: ExecutionHash"];
106
+ for (const [key, value] of Object.entries(execution)) {
107
+ if (key === "executionHash") continue;
108
+ parts.push(`readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`);
109
+ }
110
+ return `{ ${parts.join("; ")} }`;
111
+ }
112
+ function generateHashTypeAliases(hashes) {
113
+ const executionHashType = hashes.executionHash ? `ExecutionHashBase<'${hashes.executionHash}'>` : "ExecutionHashBase<string>";
114
+ return [
115
+ `export type StorageHash = StorageHashBase<'${hashes.storageHash}'>;`,
116
+ `export type ExecutionHash = ${executionHashType};`,
117
+ `export type ProfileHash = ProfileHashBase<'${hashes.profileHash}'>;`
118
+ ].join("\n");
119
+ }
120
+ function applyModifiers(base, field) {
121
+ let result = base;
122
+ if (field.many === true) result = `ReadonlyArray<${result}>`;
123
+ if (field.dict === true) result = `Readonly<Record<string, ${result}>>`;
124
+ if (field.nullable) result = `${result} | null`;
125
+ return result;
126
+ }
127
+ function resolveFieldType(field, codecLookup) {
128
+ const { type } = field;
129
+ switch (type.kind) {
130
+ case "scalar": {
131
+ let outputResolved;
132
+ if (codecLookup && type.typeParams && Object.keys(type.typeParams).length > 0) {
133
+ const codec = codecLookup.get(type.codecId);
134
+ if (codec?.renderOutputType) {
135
+ const rendered = codec.renderOutputType(type.typeParams);
136
+ if (rendered && isSafeTypeExpression(rendered)) outputResolved = rendered;
137
+ }
138
+ }
139
+ const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;
140
+ return {
141
+ output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),
142
+ input: applyModifiers(`${codecAccessor}['input']`, field)
143
+ };
144
+ }
145
+ case "valueObject": return {
146
+ output: applyModifiers(`${type.name}Output`, field),
147
+ input: applyModifiers(`${type.name}Input`, field)
148
+ };
149
+ case "union": {
150
+ const outputMembers = type.members.map((m) => m.kind === "scalar" ? `CodecTypes[${serializeValue(m.codecId)}]['output']` : `${m.name}Output`);
151
+ const inputMembers = type.members.map((m) => m.kind === "scalar" ? `CodecTypes[${serializeValue(m.codecId)}]['input']` : `${m.name}Input`);
152
+ return {
153
+ output: applyModifiers(outputMembers.join(" | "), field),
154
+ input: applyModifiers(inputMembers.join(" | "), field)
155
+ };
156
+ }
157
+ default: return {
158
+ output: applyModifiers("unknown", field),
159
+ input: applyModifiers("unknown", field)
160
+ };
161
+ }
162
+ }
163
+ function generateFieldResolvedType(field, codecLookup, side = "output") {
164
+ return resolveFieldType(field, codecLookup)[side];
165
+ }
166
+ function generateBothFieldTypesMaps(models, codecLookup) {
167
+ if (!models || Object.keys(models).length === 0) return {
168
+ output: "Record<string, never>",
169
+ input: "Record<string, never>"
170
+ };
171
+ const outputModelEntries = [];
172
+ const inputModelEntries = [];
173
+ for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {
174
+ if (!model) continue;
175
+ const outputFieldEntries = [];
176
+ const inputFieldEntries = [];
177
+ for (const [fieldName, field] of Object.entries(model.fields)) {
178
+ const resolved = resolveFieldType(field, codecLookup);
179
+ const key = `readonly ${serializeObjectKey(fieldName)}`;
180
+ outputFieldEntries.push(`${key}: ${resolved.output}`);
181
+ inputFieldEntries.push(`${key}: ${resolved.input}`);
182
+ }
183
+ const outputFields = outputFieldEntries.length > 0 ? `{ ${outputFieldEntries.join("; ")} }` : "Record<string, never>";
184
+ const inputFields = inputFieldEntries.length > 0 ? `{ ${inputFieldEntries.join("; ")} }` : "Record<string, never>";
185
+ const modelKey = `readonly ${serializeObjectKey(modelName)}`;
186
+ outputModelEntries.push(`${modelKey}: ${outputFields}`);
187
+ inputModelEntries.push(`${modelKey}: ${inputFields}`);
188
+ }
189
+ return {
190
+ output: `{ ${outputModelEntries.join("; ")} }`,
191
+ input: `{ ${inputModelEntries.join("; ")} }`
192
+ };
193
+ }
194
+ function generateFieldOutputTypesMap(models, codecLookup) {
195
+ return generateBothFieldTypesMaps(models, codecLookup).output;
196
+ }
197
+ function generateFieldInputTypesMap(models, codecLookup) {
198
+ return generateBothFieldTypesMaps(models, codecLookup).input;
199
+ }
200
+ function generateValueObjectType(_voName, vo, _valueObjects, side = "output", codecLookup) {
201
+ return resolveValueObjectType(_voName, vo, _valueObjects, codecLookup)[side];
202
+ }
203
+ function resolveValueObjectType(_voName, vo, _valueObjects, codecLookup) {
204
+ const outputEntries = [];
205
+ const inputEntries = [];
206
+ for (const [fieldName, field] of Object.entries(vo.fields)) {
207
+ const resolved = resolveFieldType(field, codecLookup);
208
+ const key = `readonly ${serializeObjectKey(fieldName)}`;
209
+ outputEntries.push(`${key}: ${resolved.output}`);
210
+ inputEntries.push(`${key}: ${resolved.input}`);
211
+ }
212
+ const empty = "Record<string, never>";
213
+ return {
214
+ output: outputEntries.length > 0 ? `{ ${outputEntries.join("; ")} }` : empty,
215
+ input: inputEntries.length > 0 ? `{ ${inputEntries.join("; ")} }` : empty
216
+ };
217
+ }
218
+ function generateContractFieldDescriptor(fieldName, field) {
219
+ const mods = [];
220
+ if (field.many === true) mods.push("; readonly many: true");
221
+ if (field.dict === true) mods.push("; readonly dict: true");
222
+ const modStr = mods.join("");
223
+ const { type } = field;
224
+ if (type.kind === "scalar") {
225
+ const typeParamsSpec = type.typeParams && Object.keys(type.typeParams).length > 0 ? `; readonly typeParams: ${serializeValue(type.typeParams)}` : "";
226
+ return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${modStr} }`;
227
+ }
228
+ if (type.kind === "valueObject") return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${modStr} }`;
229
+ return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${field.nullable}; readonly type: ${serializeValue(type)}${modStr} }`;
230
+ }
231
+ function generateValueObjectsDescriptorType(valueObjects) {
232
+ if (!valueObjects || Object.keys(valueObjects).length === 0) return "Record<string, never>";
233
+ const voEntries = [];
234
+ for (const [voName, vo] of Object.entries(valueObjects)) {
235
+ const fieldEntries = [];
236
+ for (const [fieldName, field] of Object.entries(vo.fields)) fieldEntries.push(generateContractFieldDescriptor(fieldName, field));
237
+ const fieldsType = fieldEntries.length > 0 ? `{ ${fieldEntries.join("; ")} }` : "Record<string, never>";
238
+ voEntries.push(`readonly ${serializeObjectKey(voName)}: { readonly fields: ${fieldsType} }`);
239
+ }
240
+ return `{ ${voEntries.join("; ")} }`;
241
+ }
242
+ function generateValueObjectTypeAliases(valueObjects, codecLookup) {
243
+ if (!valueObjects || Object.keys(valueObjects).length === 0) return "";
244
+ const aliases = [];
245
+ for (const [voName, vo] of Object.entries(valueObjects)) {
246
+ const resolved = resolveValueObjectType(voName, vo, valueObjects, codecLookup);
247
+ aliases.push(`export type ${voName}Output = ${resolved.output};`);
248
+ aliases.push(`export type ${voName}Input = ${resolved.input};`);
249
+ }
250
+ return aliases.join("\n");
251
+ }
252
+
253
+ //#endregion
254
+ export { deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateContractFieldDescriptor, generateFieldInputTypesMap, generateFieldOutputTypesMap, generateFieldResolvedType, generateHashTypeAliases, generateImportLines, generateModelFieldEntry, generateModelFieldsType, generateModelRelationsType, generateModelsType, generateRootsType, generateValueObjectType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, resolveFieldType, resolveValueObjectType, serializeExecutionType, serializeObjectKey, serializeValue };
255
+ //# sourceMappingURL=domain-type-generation.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-type-generation.mjs","names":["entries: string[]","fieldEntries: string[]","relationEntries: string[]","parts: string[]","modelTypes: string[]","modelParts: string[]","result: TypesImportSpec[]","outputResolved: string | undefined","outputModelEntries: string[]","inputModelEntries: string[]","outputFieldEntries: string[]","inputFieldEntries: string[]","outputEntries: string[]","inputEntries: string[]","mods: string[]","voEntries: string[]","aliases: string[]"],"sources":["../src/domain-type-generation.ts"],"sourcesContent":["import type {\n ContractField,\n ContractModel,\n ContractValueObject,\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 { 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 generateRootsType(roots: Record<string, string> | undefined): string {\n if (!roots || Object.keys(roots).length === 0) {\n return 'Record<string, string>';\n }\n const entries = Object.entries(roots)\n .map(([key, value]) => `readonly ${serializeObjectKey(key)}: ${serializeValue(value)}`)\n .join('; ');\n return `{ ${entries} }`;\n}\n\nfunction contractFieldModifierSuffix(field: ContractField): string {\n const many = field.many === true ? '; readonly many: true' : '';\n const dict = field.dict === true ? '; readonly dict: true' : '';\n return many + dict;\n}\n\nexport function generateModelFieldEntry(fieldName: string, field: ContractField): string {\n const mods = contractFieldModifierSuffix(field);\n const { nullable, type } = field;\n if (type.kind === 'scalar') {\n const typeParamsSpec =\n type.typeParams && Object.keys(type.typeParams).length > 0\n ? `; readonly typeParams: ${serializeValue(type.typeParams)}`\n : '';\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'scalar'; readonly codecId: ${serializeValue(type.codecId)}${typeParamsSpec} }${mods} }`;\n }\n if (type.kind === 'valueObject') {\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: { readonly kind: 'valueObject'; readonly name: ${serializeValue(type.name)} }${mods} }`;\n }\n return `readonly ${serializeObjectKey(fieldName)}: { readonly nullable: ${nullable}; readonly type: ${serializeValue(type)}${mods} }`;\n}\n\nexport function generateModelFieldsType(fields: Record<string, ContractField>): string {\n const fieldEntries: string[] = [];\n for (const [fieldName, field] of Object.entries(fields)) {\n fieldEntries.push(generateModelFieldEntry(fieldName, field));\n }\n return fieldEntries.length > 0 ? `{ ${fieldEntries.join('; ')} }` : 'Record<string, never>';\n}\n\nexport function generateModelRelationsType(relations: Record<string, unknown>): string {\n const relationEntries: string[] = [];\n\n for (const [relName, rel] of Object.entries(relations)) {\n if (typeof rel !== 'object' || rel === null) continue;\n const relObj = rel as Record<string, unknown>;\n const parts: string[] = [];\n\n if (relObj['to']) parts.push(`readonly to: ${serializeValue(relObj['to'])}`);\n if (relObj['cardinality'])\n parts.push(`readonly cardinality: ${serializeValue(relObj['cardinality'])}`);\n\n const on = relObj['on'] as { localFields?: string[]; targetFields?: string[] } | undefined;\n if (on && (!on.localFields || !on.targetFields)) {\n throw new Error(\n `Relation \"${relName}\" has an \"on\" block but is missing localFields or targetFields`,\n );\n }\n if (on?.localFields && on.targetFields) {\n const localFields = on.localFields.map((f) => serializeValue(f)).join(', ');\n const targetFields = on.targetFields.map((f) => serializeValue(f)).join(', ');\n parts.push(\n `readonly on: { readonly localFields: readonly [${localFields}]; readonly targetFields: readonly [${targetFields}] }`,\n );\n }\n\n if (parts.length > 0) {\n relationEntries.push(`readonly ${relName}: { ${parts.join('; ')} }`);\n }\n }\n\n if (relationEntries.length === 0) {\n return 'Record<string, never>';\n }\n\n return `{ ${relationEntries.join('; ')} }`;\n}\n\nexport function generateModelsType(\n models: Record<string, ContractModel>,\n generateModelStorage: (modelName: string, model: ContractModel) => string,\n): string {\n if (!models || Object.keys(models).length === 0) {\n return 'Record<string, never>';\n }\n\n const modelTypes: string[] = [];\n for (const [modelName, model] of Object.entries(models).sort(([a], [b]) => a.localeCompare(b))) {\n const fieldsType = generateModelFieldsType(model.fields);\n const relationsType = generateModelRelationsType(model.relations);\n const storageType = generateModelStorage(modelName, model);\n\n const modelParts: string[] = [\n `readonly fields: ${fieldsType}`,\n `readonly relations: ${relationsType}`,\n `readonly storage: ${storageType}`,\n ];\n\n if (model.owner) {\n modelParts.push(`readonly owner: ${serializeValue(model.owner)}`);\n }\n if (model.discriminator) {\n modelParts.push(`readonly discriminator: ${serializeValue(model.discriminator)}`);\n }\n if (model.variants) {\n modelParts.push(`readonly variants: ${serializeValue(model.variants)}`);\n }\n if (model.base) {\n modelParts.push(`readonly base: ${serializeValue(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 return imports.map((imp) => {\n const importClause = imp.named === imp.alias ? imp.named : `${imp.named} as ${imp.alias}`;\n return `import type { ${importClause} } from '${imp.package}';`;\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 function resolveFieldType(\n field: ContractField,\n codecLookup?: CodecLookup,\n): ResolvedFieldType {\n const { type } = field;\n\n switch (type.kind) {\n case 'scalar': {\n let outputResolved: string | undefined;\n if (codecLookup && type.typeParams && Object.keys(type.typeParams).length > 0) {\n const codec = codecLookup.get(type.codecId);\n if (codec?.renderOutputType) {\n const rendered = codec.renderOutputType(type.typeParams);\n if (rendered && isSafeTypeExpression(rendered)) {\n outputResolved = rendered;\n }\n }\n }\n const codecAccessor = `CodecTypes[${serializeValue(type.codecId)}]`;\n return {\n output: applyModifiers(outputResolved ?? `${codecAccessor}['output']`, field),\n input: applyModifiers(`${codecAccessor}['input']`, field),\n };\n }\n case 'valueObject':\n return {\n output: applyModifiers(`${type.name}Output`, field),\n input: applyModifiers(`${type.name}Input`, field),\n };\n case 'union': {\n const outputMembers = type.members.map((m) =>\n m.kind === 'scalar'\n ? `CodecTypes[${serializeValue(m.codecId)}]['output']`\n : `${m.name}Output`,\n );\n const inputMembers = type.members.map((m) =>\n m.kind === 'scalar'\n ? `CodecTypes[${serializeValue(m.codecId)}]['input']`\n : `${m.name}Input`,\n );\n return {\n output: applyModifiers(outputMembers.join(' | '), field),\n input: applyModifiers(inputMembers.join(' | '), field),\n };\n }\n default:\n return {\n output: applyModifiers('unknown', field),\n input: applyModifiers('unknown', field),\n };\n }\n}\n\nexport function generateFieldResolvedType(\n field: ContractField,\n codecLookup?: CodecLookup,\n side: 'input' | 'output' = 'output',\n): string {\n return resolveFieldType(field, codecLookup)[side];\n}\n\nexport function generateBothFieldTypesMaps(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n): 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 resolved = resolveFieldType(field, codecLookup);\n const key = `readonly ${serializeObjectKey(fieldName)}`;\n outputFieldEntries.push(`${key}: ${resolved.output}`);\n inputFieldEntries.push(`${key}: ${resolved.input}`);\n }\n const outputFields =\n outputFieldEntries.length > 0\n ? `{ ${outputFieldEntries.join('; ')} }`\n : 'Record<string, never>';\n const inputFields =\n inputFieldEntries.length > 0\n ? `{ ${inputFieldEntries.join('; ')} }`\n : 'Record<string, never>';\n const modelKey = `readonly ${serializeObjectKey(modelName)}`;\n outputModelEntries.push(`${modelKey}: ${outputFields}`);\n inputModelEntries.push(`${modelKey}: ${inputFields}`);\n }\n\n return {\n output: `{ ${outputModelEntries.join('; ')} }`,\n input: `{ ${inputModelEntries.join('; ')} }`,\n };\n}\n\nexport function generateFieldOutputTypesMap(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n): string {\n return generateBothFieldTypesMaps(models, codecLookup).output;\n}\n\nexport function generateFieldInputTypesMap(\n models: Record<string, ContractModel> | undefined,\n codecLookup?: CodecLookup,\n): string {\n return generateBothFieldTypesMaps(models, codecLookup).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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"}
@@ -0,0 +1,39 @@
1
+ import { deduplicateImports, generateCodecTypeIntersection, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, serializeObjectKey, serializeValue } from "../domain-type-generation.mjs";
2
+ import { Contract } from "@prisma-next/contract/types";
3
+ import { CodecLookup } from "@prisma-next/framework-components/codec";
4
+ import { EmissionSpi, GenerateContractTypesOptions, TypesImportSpec } from "@prisma-next/framework-components/emission";
5
+
6
+ //#region src/emit-types.d.ts
7
+
8
+ /**
9
+ * The subset of ControlStack that emit() reads.
10
+ * All fields are optional so tests can pass minimal objects.
11
+ * A full ControlStack satisfies this via structural typing.
12
+ */
13
+ interface EmitStackInput {
14
+ readonly codecTypeImports?: ReadonlyArray<TypesImportSpec>;
15
+ readonly operationTypeImports?: ReadonlyArray<TypesImportSpec>;
16
+ readonly queryOperationTypeImports?: ReadonlyArray<TypesImportSpec>;
17
+ readonly extensionIds?: ReadonlyArray<string>;
18
+ readonly codecLookup?: CodecLookup;
19
+ }
20
+ interface EmitResult {
21
+ readonly contractJson: string;
22
+ readonly contractDts: string;
23
+ readonly storageHash: string;
24
+ readonly executionHash?: string;
25
+ readonly profileHash: string;
26
+ }
27
+ //#endregion
28
+ //#region src/emit.d.ts
29
+ declare function emit(contract: Contract, stack: EmitStackInput, targetFamily: EmissionSpi): Promise<EmitResult>;
30
+ //#endregion
31
+ //#region src/generate-contract-dts.d.ts
32
+ declare function generateContractDts(contract: Contract, emitter: EmissionSpi, codecTypeImports: ReadonlyArray<TypesImportSpec>, operationTypeImports: ReadonlyArray<TypesImportSpec>, hashes: {
33
+ readonly storageHash: string;
34
+ readonly executionHash?: string;
35
+ readonly profileHash: string;
36
+ }, options?: GenerateContractTypesOptions, codecLookup?: CodecLookup): string;
37
+ //#endregion
38
+ export { type EmitResult, type EmitStackInput, deduplicateImports, emit, generateCodecTypeIntersection, generateContractDts, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, serializeObjectKey, serializeValue };
39
+ //# sourceMappingURL=index.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../../src/emit-types.ts","../../src/emit.ts","../../src/generate-contract-dts.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;AAQA;AAC4C,UAD3B,cAAA,CAC2B;EAAd,SAAA,gBAAA,CAAA,EAAA,aAAA,CAAc,eAAd,CAAA;EACkB,SAAA,oBAAA,CAAA,EAAd,aAAc,CAAA,eAAA,CAAA;EAAd,SAAA,yBAAA,CAAA,EACK,aADL,CACmB,eADnB,CAAA;EACmB,SAAA,YAAA,CAAA,EAC3B,aAD2B,CAAA,MAAA,CAAA;EAAd,SAAA,WAAA,CAAA,EAEd,WAFc;;AAEd,UAGR,UAAA,CAHQ;EAAW,SAAA,YAAA,EAAA,MAAA;EAGnB,SAAA,WAAU,EAAA,MAAA;;;;ACN3B;;;iBAAsB,IAAA,WACV,iBACH,8BACO,cACb,QAAQ;;;iBCOK,mBAAA,WACJ,mBACD,+BACS,cAAc,wCACV,cAAc;;;EFjBrB,SAAA,WAAc,EAAA,MAAA;CACa,EAAA,OAAA,CAAA,EEsBhC,4BFtBgC,EAAA,WAAA,CAAA,EEuB5B,WFvB4B,CAAA,EAAA,MAAA"}
@@ -0,0 +1,106 @@
1
+ import { deduplicateImports, generateBothFieldTypesMaps, generateCodecTypeIntersection, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateModelsType, generateRootsType, generateValueObjectTypeAliases, generateValueObjectsDescriptorType, serializeExecutionType, serializeObjectKey, serializeValue } from "../domain-type-generation.mjs";
2
+ import { canonicalizeContractToObject } from "@prisma-next/contract/hashing";
3
+ import { ifDefined } from "@prisma-next/utils/defined";
4
+ import { format } from "prettier";
5
+
6
+ //#region src/generate-contract-dts.ts
7
+ function generateContractDts(contract, emitter, codecTypeImports, operationTypeImports, hashes, options, codecLookup) {
8
+ const allImports = [...codecTypeImports, ...operationTypeImports];
9
+ if (options?.queryOperationTypeImports) allImports.push(...options.queryOperationTypeImports);
10
+ const importLines = generateImportLines(deduplicateImports(allImports));
11
+ const familyImportLines = emitter.getFamilyImports();
12
+ const hashAliases = generateHashTypeAliases(hashes);
13
+ const codecTypes = generateCodecTypeIntersection(codecTypeImports, "CodecTypes");
14
+ const operationTypes = generateCodecTypeIntersection(operationTypeImports, "OperationTypes");
15
+ const familyTypeAliases = emitter.getFamilyTypeAliases(options);
16
+ const typeMapsExpr = emitter.getTypeMapsExpression();
17
+ const storageType = emitter.generateStorageType(contract, "StorageHash");
18
+ const modelsType = generateModelsType(contract.models, (name, model) => emitter.generateModelStorageType(name, model));
19
+ const rootsType = generateRootsType(contract.roots);
20
+ const valueObjects = contract.valueObjects;
21
+ const valueObjectTypeAliases = generateValueObjectTypeAliases(valueObjects, codecLookup);
22
+ const valueObjectsDescriptor = generateValueObjectsDescriptorType(valueObjects);
23
+ const executionClause = contract.execution !== void 0 ? `\n readonly execution: ${serializeExecutionType(contract.execution)};` : "";
24
+ const fieldTypesMaps = generateBothFieldTypesMaps(contract.models, codecLookup);
25
+ const contractWrapper = emitter.getContractWrapper("ContractBase", "TypeMaps");
26
+ return `// ⚠️ GENERATED FILE - DO NOT EDIT
27
+ // This file is automatically generated by 'prisma-next contract emit'.
28
+ // To regenerate, run: prisma-next contract emit
29
+ ${importLines.join("\n")}
30
+
31
+ ${familyImportLines.join("\n")}
32
+ import type {
33
+ Contract as ContractType,
34
+ ExecutionHashBase,
35
+ ProfileHashBase,
36
+ StorageHashBase,
37
+ } from '@prisma-next/contract/types';
38
+
39
+ ${hashAliases}
40
+
41
+ export type CodecTypes = ${codecTypes};
42
+ export type OperationTypes = ${operationTypes};
43
+ ${familyTypeAliases}
44
+ ${valueObjectTypeAliases}
45
+ export type FieldOutputTypes = ${fieldTypesMaps.output};
46
+ export type FieldInputTypes = ${fieldTypesMaps.input};
47
+ export type TypeMaps = ${typeMapsExpr};
48
+
49
+ type ContractBase = ContractType<
50
+ ${storageType},
51
+ ${modelsType}
52
+ > & {
53
+ readonly target: ${serializeValue(contract.target)};
54
+ readonly targetFamily: ${serializeValue(contract.targetFamily)};
55
+ readonly roots: ${rootsType};
56
+ readonly capabilities: ${serializeValue(contract.capabilities)};
57
+ readonly extensionPacks: ${serializeValue(contract.extensionPacks)};${executionClause}
58
+ readonly meta: ${serializeValue(contract.meta)};
59
+ ${valueObjects ? `readonly valueObjects: ${valueObjectsDescriptor};` : ""}
60
+ readonly profileHash: ProfileHash;
61
+ };
62
+
63
+ ${contractWrapper}
64
+ `;
65
+ }
66
+
67
+ //#endregion
68
+ //#region src/emit.ts
69
+ const SCHEMA_VERSION = "1";
70
+ async function emit(contract, stack, targetFamily) {
71
+ const { codecTypeImports, operationTypeImports, queryOperationTypeImports } = stack;
72
+ const { storageHash } = contract.storage;
73
+ const executionHash = contract.execution?.executionHash;
74
+ const { profileHash } = contract;
75
+ const canonicalized = canonicalizeContractToObject(contract, { schemaVersion: SCHEMA_VERSION });
76
+ const contractJsonString = JSON.stringify({
77
+ ...canonicalized,
78
+ _generated: {
79
+ warning: "⚠️ GENERATED FILE - DO NOT EDIT",
80
+ message: "This file is automatically generated by \"prisma-next contract emit\".",
81
+ regenerate: "To regenerate, run: prisma-next contract emit"
82
+ }
83
+ }, null, 2);
84
+ const generateOptions = queryOperationTypeImports ? { queryOperationTypeImports } : void 0;
85
+ const contractTypeHashes = {
86
+ storageHash,
87
+ ...ifDefined("executionHash", executionHash),
88
+ profileHash
89
+ };
90
+ return {
91
+ contractJson: contractJsonString,
92
+ contractDts: await format(generateContractDts(contract, targetFamily, codecTypeImports ?? [], operationTypeImports ?? [], contractTypeHashes, generateOptions, stack.codecLookup), {
93
+ parser: "typescript",
94
+ singleQuote: true,
95
+ semi: true,
96
+ printWidth: 100
97
+ }),
98
+ storageHash,
99
+ ...ifDefined("executionHash", executionHash),
100
+ profileHash
101
+ };
102
+ }
103
+
104
+ //#endregion
105
+ export { deduplicateImports, emit, generateCodecTypeIntersection, generateContractDts, generateFieldOutputTypesMap, generateHashTypeAliases, generateImportLines, generateModelRelationsType, generateRootsType, serializeObjectKey, serializeValue };
106
+ //# sourceMappingURL=index.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.mjs","names":["allImports: TypesImportSpec[]"],"sources":["../../src/generate-contract-dts.ts","../../src/emit.ts"],"sourcesContent":["import type { Contract, ContractModel, ContractValueObject } from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport type {\n EmissionSpi,\n GenerateContractTypesOptions,\n TypesImportSpec,\n} from '@prisma-next/framework-components/emission';\nimport {\n deduplicateImports,\n generateBothFieldTypesMaps,\n generateCodecTypeIntersection,\n generateHashTypeAliases,\n generateImportLines,\n generateModelsType,\n generateRootsType,\n generateValueObjectsDescriptorType,\n generateValueObjectTypeAliases,\n serializeExecutionType,\n serializeValue,\n} from './domain-type-generation';\n\nexport function generateContractDts(\n contract: Contract,\n emitter: EmissionSpi,\n codecTypeImports: ReadonlyArray<TypesImportSpec>,\n operationTypeImports: 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, ...operationTypeImports];\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 const operationTypes = generateCodecTypeIntersection(operationTypeImports, 'OperationTypes');\n\n const familyTypeAliases = emitter.getFamilyTypeAliases(options);\n\n const typeMapsExpr = emitter.getTypeMapsExpression();\n\n const storageType = emitter.generateStorageType(contract, 'StorageHash');\n\n const modelsType = generateModelsType(\n contract.models as Record<string, ContractModel>,\n (name, model) => emitter.generateModelStorageType(name, model),\n );\n\n const rootsType = generateRootsType(contract.roots);\n\n const valueObjects = contract.valueObjects as Record<string, ContractValueObject> | undefined;\n const valueObjectTypeAliases = generateValueObjectTypeAliases(valueObjects, codecLookup);\n const valueObjectsDescriptor = generateValueObjectsDescriptorType(valueObjects);\n\n const executionClause =\n contract.execution !== undefined\n ? `\\n readonly execution: ${serializeExecutionType(contract.execution)};`\n : '';\n\n const fieldTypesMaps = generateBothFieldTypesMaps(\n contract.models as Record<string, ContractModel> | undefined,\n codecLookup,\n );\n\n const contractWrapper = emitter.getContractWrapper('ContractBase', 'TypeMaps');\n\n return `// ⚠️ GENERATED FILE - DO NOT EDIT\n// This file is automatically generated by 'prisma-next contract emit'.\n// To regenerate, run: prisma-next contract emit\n${importLines.join('\\n')}\n\n${familyImportLines.join('\\n')}\nimport type {\n Contract as ContractType,\n ExecutionHashBase,\n ProfileHashBase,\n StorageHashBase,\n} from '@prisma-next/contract/types';\n\n${hashAliases}\n\nexport type CodecTypes = ${codecTypes};\nexport type OperationTypes = ${operationTypes};\n${familyTypeAliases}\n${valueObjectTypeAliases}\nexport type FieldOutputTypes = ${fieldTypesMaps.output};\nexport type FieldInputTypes = ${fieldTypesMaps.input};\nexport type TypeMaps = ${typeMapsExpr};\n\ntype ContractBase = ContractType<\n${storageType},\n${modelsType}\n> & {\n readonly target: ${serializeValue(contract.target)};\n readonly targetFamily: ${serializeValue(contract.targetFamily)};\n readonly roots: ${rootsType};\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 type { 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): Promise<EmitResult> {\n const { codecTypeImports, operationTypeImports, 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 });\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 operationTypeImports ?? [],\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":";;;;;;AAqBA,SAAgB,oBACd,UACA,SACA,kBACA,sBACA,QAKA,SACA,aACQ;CACR,MAAMA,aAAgC,CAAC,GAAG,kBAAkB,GAAG,qBAAqB;AACpF,KAAI,SAAS,0BACX,YAAW,KAAK,GAAG,QAAQ,0BAA0B;CAGvD,MAAM,cAAc,oBADE,mBAAmB,WAAW,CACE;CAEtD,MAAM,oBAAoB,QAAQ,kBAAkB;CAEpD,MAAM,cAAc,wBAAwB,OAAO;CAEnD,MAAM,aAAa,8BAA8B,kBAAkB,aAAa;CAChF,MAAM,iBAAiB,8BAA8B,sBAAsB,iBAAiB;CAE5F,MAAM,oBAAoB,QAAQ,qBAAqB,QAAQ;CAE/D,MAAM,eAAe,QAAQ,uBAAuB;CAEpD,MAAM,cAAc,QAAQ,oBAAoB,UAAU,cAAc;CAExE,MAAM,aAAa,mBACjB,SAAS,SACR,MAAM,UAAU,QAAQ,yBAAyB,MAAM,MAAM,CAC/D;CAED,MAAM,YAAY,kBAAkB,SAAS,MAAM;CAEnD,MAAM,eAAe,SAAS;CAC9B,MAAM,yBAAyB,+BAA+B,cAAc,YAAY;CACxF,MAAM,yBAAyB,mCAAmC,aAAa;CAE/E,MAAM,kBACJ,SAAS,cAAc,SACnB,2BAA2B,uBAAuB,SAAS,UAAU,CAAC,KACtE;CAEN,MAAM,iBAAiB,2BACrB,SAAS,QACT,YACD;CAED,MAAM,kBAAkB,QAAQ,mBAAmB,gBAAgB,WAAW;AAE9E,QAAO;;;EAGP,YAAY,KAAK,KAAK,CAAC;;EAEvB,kBAAkB,KAAK,KAAK,CAAC;;;;;;;;EAQ7B,YAAY;;2BAEa,WAAW;+BACP,eAAe;EAC5C,kBAAkB;EAClB,uBAAuB;iCACQ,eAAe,OAAO;gCACvB,eAAe,MAAM;yBAC5B,aAAa;;;EAGpC,YAAY;EACZ,WAAW;;qBAEQ,eAAe,SAAS,OAAO,CAAC;2BAC1B,eAAe,SAAS,aAAa,CAAC;oBAC7C,UAAU;2BACH,eAAe,SAAS,aAAa,CAAC;6BACpC,eAAe,SAAS,eAAe,CAAC,GAAG,gBAAgB;mBACrE,eAAe,SAAS,KAAK,CAAC;IAC7C,eAAe,0BAA0B,uBAAuB,KAAK,GAAG;;;;EAI1E,gBAAgB;;;;;;AC1GlB,MAAM,iBAAiB;AAEvB,eAAsB,KACpB,UACA,OACA,cACqB;CACrB,MAAM,EAAE,kBAAkB,sBAAsB,8BAA8B;CAE9E,MAAM,EAAE,gBAAgB,SAAS;CACjC,MAAM,gBAAgB,SAAS,WAAW;CAC1C,MAAM,EAAE,gBAAgB;CAExB,MAAM,gBAAgB,6BAA6B,UAAU,EAC3D,eAAe,gBAChB,CAAC;CACF,MAAM,qBAAqB,KAAK,UAC9B;EACE,GAAG;EACH,YAAY;GACV,SAAS;GACT,SAAS;GACT,YAAY;GACb;EACF,EACD,MACA,EACD;CAED,MAAM,kBAAkB,4BAA4B,EAAE,2BAA2B,GAAG;CAEpF,MAAM,qBAAqB;EACzB;EACA,GAAG,UAAU,iBAAiB,cAAc;EAC5C;EACD;AAiBD,QAAO;EACL,cAAc;EACd,aATkB,MAAM,OATH,oBACrB,UACA,cACA,oBAAoB,EAAE,EACtB,wBAAwB,EAAE,EAC1B,oBACA,iBACA,MAAM,YACP,EACgD;GAC/C,QAAQ;GACR,aAAa;GACb,MAAM;GACN,YAAY;GACb,CAAC;EAKA;EACA,GAAG,UAAU,iBAAiB,cAAc;EAC5C;EACD"}
@@ -0,0 +1,21 @@
1
+ import { Contract } from "@prisma-next/contract/types";
2
+
3
+ //#region test/utils.d.ts
4
+ type TestContractOverrides = {
5
+ target?: string;
6
+ targetFamily?: string;
7
+ roots?: Record<string, string>;
8
+ models?: Record<string, unknown>;
9
+ storage?: Record<string, unknown>;
10
+ capabilities?: Record<string, Record<string, boolean>>;
11
+ extensionPacks?: Record<string, unknown>;
12
+ execution?: Record<string, unknown>;
13
+ meta?: Record<string, unknown>;
14
+ storageHash?: string;
15
+ schemaVersion?: string;
16
+ sources?: Record<string, unknown>;
17
+ };
18
+ declare function createTestContract(overrides?: TestContractOverrides): Contract;
19
+ //#endregion
20
+ export { createTestContract };
21
+ //# sourceMappingURL=utils.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.mts","names":[],"sources":["../../test/utils.ts"],"sourcesContent":[],"mappings":";;;KAGK,qBAAA;;EAAA,YAAA,CAAA,EAAA,MAAA;EAGK,KAAA,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,MAAA,CAAA;EACC,MAAA,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;EACC,OAAA,CAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA;EACoB,YAAA,CAAA,EAAf,MAAe,CAAA,MAAA,EAAA,MAAA,CAAA,MAAA,EAAA,OAAA,CAAA,CAAA;EAAf,cAAA,CAAA,EACE,MADF,CAAA,MAAA,EAAA,OAAA,CAAA;EACE,SAAA,CAAA,EACL,MADK,CAAA,MAAA,EAAA,OAAA,CAAA;EACL,IAAA,CAAA,EACL,MADK,CAAA,MAAA,EAAA,OAAA,CAAA;EACL,WAAA,CAAA,EAAA,MAAA;EAGG,aAAA,CAAA,EAAA,MAAA;EAAM,OAAA,CAAA,EAAN,MAAM,CAAA,MAAA,EAAA,OAAA,CAAA;AAGlB,CAAA;iBAAgB,kBAAA,aAA8B,wBAA6B"}
@@ -0,0 +1,18 @@
1
+ import { createContract } from "@prisma-next/contract/testing";
2
+
3
+ //#region test/utils.ts
4
+ function createTestContract(overrides = {}) {
5
+ const { storageHash: _sh, schemaVersion: _sv, sources: _src, storage, ...rest } = overrides;
6
+ const cleanStorage = storage ? (() => {
7
+ const { storageHash: _innerSh, ...storageRest } = storage;
8
+ return storageRest;
9
+ })() : void 0;
10
+ return createContract({
11
+ ...rest,
12
+ ...cleanStorage ? { storage: cleanStorage } : {}
13
+ });
14
+ }
15
+
16
+ //#endregion
17
+ export { createTestContract };
18
+ //# sourceMappingURL=utils.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.mjs","names":[],"sources":["../../test/utils.ts"],"sourcesContent":["import { createContract } from '@prisma-next/contract/testing';\nimport type { Contract } from '@prisma-next/contract/types';\n\ntype TestContractOverrides = {\n target?: string;\n targetFamily?: string;\n roots?: Record<string, string>;\n models?: Record<string, unknown>;\n storage?: Record<string, unknown>;\n capabilities?: Record<string, Record<string, boolean>>;\n extensionPacks?: Record<string, unknown>;\n execution?: Record<string, unknown>;\n meta?: Record<string, unknown>;\n storageHash?: string;\n schemaVersion?: string;\n sources?: Record<string, unknown>;\n};\n\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":";;;AAkBA,SAAgB,mBAAmB,YAAmC,EAAE,EAAY;CAClF,MAAM,EAAE,aAAa,KAAK,eAAe,KAAK,SAAS,MAAM,SAAS,GAAG,SAAS;CAClF,MAAM,eAAe,iBACV;EACL,MAAM,EAAE,aAAa,UAAU,GAAG,gBAAgB;AAClD,SAAO;KACL,GACJ;AACJ,QAAO,eAAe;EACpB,GAAG;EACH,GAAI,eAAe,EAAE,SAAS,cAAc,GAAG,EAAE;EAClD,CAAyC"}
@@ -0,0 +1,8 @@
1
+ //#region src/type-expression-safety.ts
2
+ function isSafeTypeExpression(expr) {
3
+ return !/import\s*\(|require\s*\(|declare\s|export\s|eval\s*\(/.test(expr);
4
+ }
5
+
6
+ //#endregion
7
+ export { isSafeTypeExpression as t };
8
+ //# sourceMappingURL=type-expression-safety-7_1tfJXA.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-expression-safety-7_1tfJXA.mjs","names":[],"sources":["../src/type-expression-safety.ts"],"sourcesContent":["export function isSafeTypeExpression(expr: string): boolean {\n return !/import\\s*\\(|require\\s*\\(|declare\\s|export\\s|eval\\s*\\(/.test(expr);\n}\n"],"mappings":";AAAA,SAAgB,qBAAqB,MAAuB;AAC1D,QAAO,CAAC,wDAAwD,KAAK,KAAK"}
@@ -0,0 +1,5 @@
1
+ //#region src/type-expression-safety.d.ts
2
+ declare function isSafeTypeExpression(expr: string): boolean;
3
+ //#endregion
4
+ export { isSafeTypeExpression };
5
+ //# sourceMappingURL=type-expression-safety.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"type-expression-safety.d.mts","names":[],"sources":["../src/type-expression-safety.ts"],"sourcesContent":[],"mappings":";iBAAgB,oBAAA"}
@@ -0,0 +1,3 @@
1
+ import { t as isSafeTypeExpression } from "./type-expression-safety-7_1tfJXA.mjs";
2
+
3
+ export { isSafeTypeExpression };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma-next/emitter",
3
- "version": "0.3.0-pr.99.6",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "sideEffects": false,
6
6
  "files": [
@@ -10,30 +10,46 @@
10
10
  ],
11
11
  "dependencies": {
12
12
  "arktype": "^2.0.0",
13
- "@prisma-next/contract": "0.3.0-pr.99.6",
14
- "@prisma-next/core-control-plane": "0.3.0-pr.99.6"
13
+ "prettier": "^3.3.3",
14
+ "@prisma-next/framework-components": "0.3.0",
15
+ "@prisma-next/contract": "0.3.0",
16
+ "@prisma-next/operations": "0.3.0",
17
+ "@prisma-next/utils": "0.3.0"
15
18
  },
16
19
  "devDependencies": {
17
20
  "@types/node": "24.10.4",
18
- "tsup": "8.5.1",
21
+ "tsdown": "0.18.4",
19
22
  "typescript": "5.9.3",
20
- "vitest": "4.0.16",
21
- "@prisma-next/operations": "0.3.0-pr.99.6",
23
+ "vitest": "4.0.17",
22
24
  "@prisma-next/test-utils": "0.0.1",
25
+ "@prisma-next/tsdown": "0.0.0",
23
26
  "@prisma-next/tsconfig": "0.0.0"
24
27
  },
25
28
  "exports": {
26
29
  ".": {
27
- "types": "./dist/src/exports/index.d.ts",
28
- "import": "./dist/exports/index.js"
30
+ "types": "./dist/exports/index.d.mts",
31
+ "import": "./dist/exports/index.mjs"
32
+ },
33
+ "./domain-type-generation": {
34
+ "types": "./dist/domain-type-generation.d.mts",
35
+ "import": "./dist/domain-type-generation.mjs"
36
+ },
37
+ "./type-expression-safety": {
38
+ "types": "./dist/type-expression-safety.d.mts",
39
+ "import": "./dist/type-expression-safety.mjs"
29
40
  },
30
41
  "./test/utils": {
31
- "types": "./dist/test/utils.d.ts",
32
- "import": "./dist/test/utils.js"
42
+ "types": "./dist/test/utils.d.mts",
43
+ "import": "./dist/test/utils.mjs"
33
44
  }
34
45
  },
46
+ "repository": {
47
+ "type": "git",
48
+ "url": "https://github.com/prisma/prisma-next.git",
49
+ "directory": "packages/1-framework/3-tooling/emitter"
50
+ },
35
51
  "scripts": {
36
- "build": "tsup --config tsup.config.ts && tsc --project tsconfig.build.json",
52
+ "build": "tsdown",
37
53
  "test": "vitest run",
38
54
  "test:coverage": "vitest run --coverage",
39
55
  "typecheck": "tsc --project tsconfig.json --noEmit",