@prisma-next/core-control-plane 0.3.0-dev.5 → 0.3.0-dev.51

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 (93) hide show
  1. package/README.md +35 -1
  2. package/dist/config-types-Ci0VxOEC.d.mts +96 -0
  3. package/dist/config-types-Ci0VxOEC.d.mts.map +1 -0
  4. package/dist/config-types.d.mts +3 -0
  5. package/dist/config-types.mjs +60 -0
  6. package/dist/config-types.mjs.map +1 -0
  7. package/dist/config-validation.d.mts +16 -0
  8. package/dist/config-validation.d.mts.map +1 -0
  9. package/dist/config-validation.mjs +79 -0
  10. package/dist/config-validation.mjs.map +1 -0
  11. package/dist/emission.d.mts +58 -0
  12. package/dist/emission.d.mts.map +1 -0
  13. package/dist/emission.mjs +315 -0
  14. package/dist/emission.mjs.map +1 -0
  15. package/dist/errors-Qlh0sdcb.mjs +276 -0
  16. package/dist/errors-Qlh0sdcb.mjs.map +1 -0
  17. package/dist/errors.d.mts +191 -0
  18. package/dist/errors.d.mts.map +1 -0
  19. package/dist/errors.mjs +3 -0
  20. package/dist/{schema-view.d.ts → schema-view-D9u47nc8.d.mts} +13 -10
  21. package/dist/schema-view-D9u47nc8.d.mts.map +1 -0
  22. package/dist/schema-view.d.mts +2 -0
  23. package/dist/schema-view.mjs +1 -0
  24. package/dist/stack.d.mts +30 -0
  25. package/dist/stack.d.mts.map +1 -0
  26. package/dist/stack.mjs +30 -0
  27. package/dist/stack.mjs.map +1 -0
  28. package/dist/types-CuAauVCJ.d.mts +597 -0
  29. package/dist/types-CuAauVCJ.d.mts.map +1 -0
  30. package/dist/types.d.mts +2 -0
  31. package/dist/types.mjs +1 -0
  32. package/package.json +31 -38
  33. package/src/config-types.ts +30 -35
  34. package/src/config-validation.ts +7 -5
  35. package/src/contract-source-types.ts +28 -0
  36. package/src/emission/canonicalization.ts +68 -21
  37. package/src/emission/emit.ts +82 -21
  38. package/src/emission/hashing.ts +29 -27
  39. package/src/emission/types.ts +13 -2
  40. package/src/errors.ts +24 -5
  41. package/src/exports/config-types.ts +7 -0
  42. package/src/exports/emission.ts +1 -1
  43. package/src/exports/errors.ts +1 -1
  44. package/src/exports/stack.ts +1 -0
  45. package/src/exports/types.ts +1 -0
  46. package/src/migrations.ts +1 -1
  47. package/src/stack.ts +38 -0
  48. package/src/types.ts +41 -17
  49. package/dist/chunk-U5RYT6PT.js +0 -229
  50. package/dist/chunk-U5RYT6PT.js.map +0 -1
  51. package/dist/config-types.d.ts +0 -68
  52. package/dist/config-types.d.ts.map +0 -1
  53. package/dist/config-validation.d.ts +0 -10
  54. package/dist/config-validation.d.ts.map +0 -1
  55. package/dist/emission/canonicalization.d.ts +0 -6
  56. package/dist/emission/canonicalization.d.ts.map +0 -1
  57. package/dist/emission/emit.d.ts +0 -5
  58. package/dist/emission/emit.d.ts.map +0 -1
  59. package/dist/emission/hashing.d.ts +0 -17
  60. package/dist/emission/hashing.d.ts.map +0 -1
  61. package/dist/emission/types.d.ts +0 -16
  62. package/dist/emission/types.d.ts.map +0 -1
  63. package/dist/errors.d.ts +0 -183
  64. package/dist/errors.d.ts.map +0 -1
  65. package/dist/exports/config-types.d.ts +0 -3
  66. package/dist/exports/config-types.d.ts.map +0 -1
  67. package/dist/exports/config-types.js +0 -53
  68. package/dist/exports/config-types.js.map +0 -1
  69. package/dist/exports/config-validation.d.ts +0 -2
  70. package/dist/exports/config-validation.d.ts.map +0 -1
  71. package/dist/exports/config-validation.js +0 -252
  72. package/dist/exports/config-validation.js.map +0 -1
  73. package/dist/exports/emission.d.ts +0 -5
  74. package/dist/exports/emission.d.ts.map +0 -1
  75. package/dist/exports/emission.js +0 -310
  76. package/dist/exports/emission.js.map +0 -1
  77. package/dist/exports/errors.d.ts +0 -3
  78. package/dist/exports/errors.d.ts.map +0 -1
  79. package/dist/exports/errors.js +0 -43
  80. package/dist/exports/errors.js.map +0 -1
  81. package/dist/exports/schema-view.d.ts +0 -2
  82. package/dist/exports/schema-view.d.ts.map +0 -1
  83. package/dist/exports/schema-view.js +0 -1
  84. package/dist/exports/schema-view.js.map +0 -1
  85. package/dist/exports/types.d.ts +0 -2
  86. package/dist/exports/types.d.ts.map +0 -1
  87. package/dist/exports/types.js +0 -1
  88. package/dist/exports/types.js.map +0 -1
  89. package/dist/migrations.d.ts +0 -190
  90. package/dist/migrations.d.ts.map +0 -1
  91. package/dist/schema-view.d.ts.map +0 -1
  92. package/dist/types.d.ts +0 -400
  93. package/dist/types.d.ts.map +0 -1
@@ -0,0 +1,315 @@
1
+ import { type } from "arktype";
2
+ import { bigintJsonReplacer } from "@prisma-next/contract/types";
3
+ import { isArrayEqual } from "@prisma-next/utils/array-equal";
4
+ import { ifDefined } from "@prisma-next/utils/defined";
5
+ import { format } from "prettier";
6
+ import { createHash } from "node:crypto";
7
+
8
+ //#region src/emission/canonicalization.ts
9
+ const TOP_LEVEL_ORDER = [
10
+ "schemaVersion",
11
+ "canonicalVersion",
12
+ "targetFamily",
13
+ "target",
14
+ "storageHash",
15
+ "executionHash",
16
+ "profileHash",
17
+ "models",
18
+ "relations",
19
+ "storage",
20
+ "execution",
21
+ "capabilities",
22
+ "extensionPacks",
23
+ "meta"
24
+ ];
25
+ function isDefaultValue(value) {
26
+ if (value === false) return true;
27
+ if (value === null) return false;
28
+ if (value instanceof Date) return false;
29
+ if (Array.isArray(value) && value.length === 0) return true;
30
+ if (typeof value === "object" && value !== null) return Object.keys(value).length === 0;
31
+ return false;
32
+ }
33
+ function omitDefaults(obj, path) {
34
+ if (obj === null || typeof obj !== "object") return obj;
35
+ if (obj instanceof Date) return obj;
36
+ if (Array.isArray(obj)) return obj.map((item) => omitDefaults(item, path));
37
+ const result = {};
38
+ for (const [key, value] of Object.entries(obj)) {
39
+ const currentPath = [...path, key];
40
+ if (key === "_generated") continue;
41
+ if (key === "nullable" && value === false) continue;
42
+ if (key === "generated" && value === false) continue;
43
+ if ((key === "onDelete" || key === "onUpdate") && value === "noAction") continue;
44
+ if (isDefaultValue(value)) {
45
+ const isRequiredModels = isArrayEqual(currentPath, ["models"]);
46
+ const isRequiredTables = isArrayEqual(currentPath, ["storage", "tables"]);
47
+ const isRequiredRelations = isArrayEqual(currentPath, ["relations"]);
48
+ const isRequiredExtensionPacks = isArrayEqual(currentPath, ["extensionPacks"]);
49
+ const isRequiredCapabilities = isArrayEqual(currentPath, ["capabilities"]);
50
+ const isRequiredMeta = isArrayEqual(currentPath, ["meta"]);
51
+ const isRequiredExecutionDefaults = isArrayEqual(currentPath, [
52
+ "execution",
53
+ "mutations",
54
+ "defaults"
55
+ ]);
56
+ const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === "extensionPacks";
57
+ const isModelRelations = currentPath.length === 3 && isArrayEqual([currentPath[0], currentPath[2]], ["models", "relations"]);
58
+ const isTableUniques = currentPath.length === 4 && isArrayEqual([
59
+ currentPath[0],
60
+ currentPath[1],
61
+ currentPath[3]
62
+ ], [
63
+ "storage",
64
+ "tables",
65
+ "uniques"
66
+ ]);
67
+ const isTableIndexes = currentPath.length === 4 && isArrayEqual([
68
+ currentPath[0],
69
+ currentPath[1],
70
+ currentPath[3]
71
+ ], [
72
+ "storage",
73
+ "tables",
74
+ "indexes"
75
+ ]);
76
+ const isTableForeignKeys = currentPath.length === 4 && isArrayEqual([
77
+ currentPath[0],
78
+ currentPath[1],
79
+ currentPath[3]
80
+ ], [
81
+ "storage",
82
+ "tables",
83
+ "foreignKeys"
84
+ ]);
85
+ const isFkBooleanField = currentPath.length === 5 && currentPath[0] === "storage" && currentPath[1] === "tables" && currentPath[3] === "foreignKeys" && (key === "constraint" || key === "index");
86
+ if (!isRequiredModels && !isRequiredTables && !isRequiredRelations && !isRequiredExtensionPacks && !isRequiredCapabilities && !isRequiredMeta && !isRequiredExecutionDefaults && !isExtensionNamespace && !isModelRelations && !isTableUniques && !isTableIndexes && !isTableForeignKeys && !isFkBooleanField) continue;
87
+ }
88
+ result[key] = omitDefaults(value, currentPath);
89
+ }
90
+ return result;
91
+ }
92
+ function sortObjectKeys(obj) {
93
+ if (obj === null || typeof obj !== "object") return obj;
94
+ if (obj instanceof Date) return obj;
95
+ if (Array.isArray(obj)) return obj.map((item) => sortObjectKeys(item));
96
+ const sorted = {};
97
+ const keys = Object.keys(obj).sort();
98
+ for (const key of keys) sorted[key] = sortObjectKeys(obj[key]);
99
+ return sorted;
100
+ }
101
+ function sortIndexesAndUniques(storage) {
102
+ if (!storage || typeof storage !== "object") return storage;
103
+ const storageObj = storage;
104
+ if (!storageObj.tables || typeof storageObj.tables !== "object") return storage;
105
+ const tables = storageObj.tables;
106
+ const result = { ...storageObj };
107
+ result.tables = {};
108
+ const sortedTableNames = Object.keys(tables).sort();
109
+ for (const tableName of sortedTableNames) {
110
+ const table = tables[tableName];
111
+ if (!table || typeof table !== "object") {
112
+ result.tables[tableName] = table;
113
+ continue;
114
+ }
115
+ const tableObj = table;
116
+ const sortedTable = { ...tableObj };
117
+ if (Array.isArray(tableObj.indexes)) sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {
118
+ const nameA = a?.name || "";
119
+ const nameB = b?.name || "";
120
+ return nameA.localeCompare(nameB);
121
+ });
122
+ if (Array.isArray(tableObj.uniques)) sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {
123
+ const nameA = a?.name || "";
124
+ const nameB = b?.name || "";
125
+ return nameA.localeCompare(nameB);
126
+ });
127
+ result.tables[tableName] = sortedTable;
128
+ }
129
+ return result;
130
+ }
131
+ function orderTopLevel(obj) {
132
+ const ordered = {};
133
+ const remaining = new Set(Object.keys(obj));
134
+ for (const key of TOP_LEVEL_ORDER) if (remaining.has(key)) {
135
+ ordered[key] = obj[key];
136
+ remaining.delete(key);
137
+ }
138
+ for (const key of Array.from(remaining).sort()) ordered[key] = obj[key];
139
+ return ordered;
140
+ }
141
+ function canonicalizeContract(ir) {
142
+ const normalized = {
143
+ schemaVersion: ir.schemaVersion,
144
+ targetFamily: ir.targetFamily,
145
+ target: ir.target,
146
+ models: ir.models,
147
+ relations: ir.relations,
148
+ storage: ir.storage,
149
+ ...ifDefined("execution", ir.execution),
150
+ extensionPacks: ir.extensionPacks,
151
+ capabilities: ir.capabilities,
152
+ meta: ir.meta
153
+ };
154
+ Object.assign(normalized, ifDefined("storageHash", ir.storageHash), ifDefined("executionHash", ir.executionHash), ifDefined("profileHash", ir.profileHash));
155
+ const withDefaultsOmitted = omitDefaults(normalized, []);
156
+ const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);
157
+ const withOrderedTopLevel = orderTopLevel(sortObjectKeys({
158
+ ...withDefaultsOmitted,
159
+ storage: withSortedIndexes
160
+ }));
161
+ return JSON.stringify(withOrderedTopLevel, bigintJsonReplacer, 2);
162
+ }
163
+
164
+ //#endregion
165
+ //#region src/emission/hashing.ts
166
+ function computeHash(content) {
167
+ const hash = createHash("sha256");
168
+ hash.update(content);
169
+ return `sha256:${hash.digest("hex")}`;
170
+ }
171
+ function computeStorageHash(contract) {
172
+ return computeHash(canonicalizeContract({
173
+ schemaVersion: contract.schemaVersion,
174
+ targetFamily: contract.targetFamily,
175
+ target: contract.target,
176
+ storage: contract.storage,
177
+ models: {},
178
+ relations: {},
179
+ extensionPacks: {},
180
+ capabilities: {},
181
+ meta: {}
182
+ }));
183
+ }
184
+ function computeProfileHash(contract) {
185
+ return computeHash(canonicalizeContract({
186
+ schemaVersion: contract.schemaVersion,
187
+ targetFamily: contract.targetFamily,
188
+ target: contract.target,
189
+ models: {},
190
+ relations: {},
191
+ storage: {},
192
+ extensionPacks: {},
193
+ capabilities: contract.capabilities,
194
+ meta: {}
195
+ }));
196
+ }
197
+ function computeExecutionHash(contract) {
198
+ return computeHash(canonicalizeContract({
199
+ schemaVersion: contract.schemaVersion,
200
+ targetFamily: contract.targetFamily,
201
+ target: contract.target,
202
+ models: {},
203
+ relations: {},
204
+ storage: {},
205
+ extensionPacks: {},
206
+ capabilities: {},
207
+ meta: {},
208
+ ...ifDefined("execution", contract.execution)
209
+ }));
210
+ }
211
+
212
+ //#endregion
213
+ //#region src/emission/emit.ts
214
+ const CanonicalMetaSchema = type({ "[string]": "unknown" });
215
+ const CanonicalContractSchema = type({
216
+ "+": "reject",
217
+ schemaVersion: "string",
218
+ targetFamily: "string",
219
+ target: "string",
220
+ models: type({ "[string]": "unknown" }),
221
+ relations: type({ "[string]": "unknown" }),
222
+ storage: type({ "[string]": "unknown" }),
223
+ "execution?": type({ "[string]": "unknown" }),
224
+ extensionPacks: type({ "[string]": "unknown" }),
225
+ capabilities: type({ "[string]": type({ "[string]": "boolean" }) }),
226
+ meta: CanonicalMetaSchema
227
+ });
228
+ function assertCanonicalArtifactShape(value) {
229
+ const result = CanonicalContractSchema(value);
230
+ if (result instanceof type.errors) {
231
+ const issues = result.map((error) => {
232
+ return `${error.path?.toString() ?? "<root>"}: ${error.message}`;
233
+ }).join("; ");
234
+ throw new Error(`ContractIR canonical artifact validation failed: ${issues}`);
235
+ }
236
+ }
237
+ function validateCoreStructure(ir) {
238
+ if (!ir.targetFamily) throw new Error("ContractIR must have targetFamily");
239
+ if (!ir.target) throw new Error("ContractIR must have target");
240
+ if (!ir.schemaVersion) throw new Error("ContractIR must have schemaVersion");
241
+ if (!ir.models || typeof ir.models !== "object") throw new Error("ContractIR must have models");
242
+ if (!ir.storage || typeof ir.storage !== "object") throw new Error("ContractIR must have storage");
243
+ if (!ir.relations || typeof ir.relations !== "object") throw new Error("ContractIR must have relations");
244
+ if (!ir.extensionPacks || typeof ir.extensionPacks !== "object") throw new Error("ContractIR must have extensionPacks");
245
+ if (!ir.capabilities || typeof ir.capabilities !== "object") throw new Error("ContractIR must have capabilities");
246
+ if (!ir.meta || typeof ir.meta !== "object") throw new Error("ContractIR must have meta");
247
+ }
248
+ async function emit(ir, options, targetFamily) {
249
+ const { operationRegistry, codecTypeImports, operationTypeImports, extensionIds, parameterizedRenderers, parameterizedTypeImports } = options;
250
+ validateCoreStructure(ir);
251
+ const ctx = {
252
+ ...ifDefined("operationRegistry", operationRegistry),
253
+ ...ifDefined("codecTypeImports", codecTypeImports),
254
+ ...ifDefined("operationTypeImports", operationTypeImports),
255
+ ...ifDefined("extensionIds", extensionIds)
256
+ };
257
+ targetFamily.validateTypes(ir, ctx);
258
+ targetFamily.validateStructure(ir);
259
+ const canonicalContract = {
260
+ schemaVersion: ir.schemaVersion,
261
+ targetFamily: ir.targetFamily,
262
+ target: ir.target,
263
+ models: ir.models,
264
+ relations: ir.relations,
265
+ storage: ir.storage,
266
+ ...ifDefined("execution", ir.execution),
267
+ extensionPacks: ir.extensionPacks,
268
+ capabilities: ir.capabilities,
269
+ meta: ir.meta
270
+ };
271
+ assertCanonicalArtifactShape(canonicalContract);
272
+ const storageHash = computeStorageHash(canonicalContract);
273
+ const executionHash = canonicalContract.execution ? computeExecutionHash(canonicalContract) : void 0;
274
+ const profileHash = computeProfileHash(canonicalContract);
275
+ const contractWithHashes = {
276
+ ...canonicalContract,
277
+ storageHash,
278
+ ...ifDefined("executionHash", executionHash),
279
+ profileHash
280
+ };
281
+ const contractJsonWithMeta = {
282
+ ...JSON.parse(canonicalizeContract(contractWithHashes)),
283
+ _generated: {
284
+ warning: "⚠️ GENERATED FILE - DO NOT EDIT",
285
+ message: "This file is automatically generated by \"prisma-next contract emit\".",
286
+ regenerate: "To regenerate, run: prisma-next contract emit"
287
+ }
288
+ };
289
+ const contractJsonString = JSON.stringify(contractJsonWithMeta, null, 2);
290
+ const generateOptions = parameterizedRenderers || parameterizedTypeImports ? {
291
+ ...ifDefined("parameterizedRenderers", parameterizedRenderers),
292
+ ...ifDefined("parameterizedTypeImports", parameterizedTypeImports)
293
+ } : void 0;
294
+ const contractTypeHashes = {
295
+ storageHash,
296
+ ...ifDefined("executionHash", executionHash),
297
+ profileHash
298
+ };
299
+ return {
300
+ contractJson: contractJsonString,
301
+ contractDts: await format(targetFamily.generateContractTypes(ir, codecTypeImports ?? [], operationTypeImports ?? [], contractTypeHashes, generateOptions), {
302
+ parser: "typescript",
303
+ singleQuote: true,
304
+ semi: true,
305
+ printWidth: 100
306
+ }),
307
+ storageHash,
308
+ ...ifDefined("executionHash", executionHash),
309
+ profileHash
310
+ };
311
+ }
312
+
313
+ //#endregion
314
+ export { canonicalizeContract, computeExecutionHash, computeProfileHash, computeStorageHash, emit };
315
+ //# sourceMappingURL=emission.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emission.mjs","names":["result: Record<string, unknown>","sorted: Record<string, unknown>","result: StorageObject","sortedTable: TableObject","ordered: Record<string, unknown>","normalized: NormalizedContract","ctx: ValidationContext"],"sources":["../src/emission/canonicalization.ts","../src/emission/hashing.ts","../src/emission/emit.ts"],"sourcesContent":["import { bigintJsonReplacer } from '@prisma-next/contract/types';\nimport { isArrayEqual } from '@prisma-next/utils/array-equal';\nimport { ifDefined } from '@prisma-next/utils/defined';\n\ntype NormalizedContract = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n storageHash?: string;\n executionHash?: string;\n profileHash?: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n execution?: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n};\n\nexport type CanonicalContractInput = {\n schemaVersion: string;\n targetFamily: string;\n target: string;\n models: Record<string, unknown>;\n relations: Record<string, unknown>;\n storage: Record<string, unknown>;\n execution?: Record<string, unknown>;\n extensionPacks: Record<string, unknown>;\n capabilities: Record<string, Record<string, boolean>>;\n meta: Record<string, unknown>;\n storageHash?: string;\n executionHash?: string;\n profileHash?: string;\n};\n\nconst TOP_LEVEL_ORDER = [\n 'schemaVersion',\n 'canonicalVersion',\n 'targetFamily',\n 'target',\n 'storageHash',\n 'executionHash',\n 'profileHash',\n 'models',\n 'relations',\n 'storage',\n 'execution',\n 'capabilities',\n 'extensionPacks',\n 'meta',\n] as const;\n\nfunction isDefaultValue(value: unknown): boolean {\n if (value === false) return true;\n if (value === null) return false;\n if (value instanceof Date) return false;\n if (Array.isArray(value) && value.length === 0) return true;\n if (typeof value === 'object' && value !== null) {\n const keys = Object.keys(value);\n return keys.length === 0;\n }\n return false;\n}\n\nfunction omitDefaults(obj: unknown, path: readonly string[]): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (obj instanceof Date) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => omitDefaults(item, path));\n }\n\n const result: Record<string, unknown> = {};\n\n for (const [key, value] of Object.entries(obj)) {\n const currentPath = [...path, key];\n\n // Exclude metadata fields from canonicalization\n if (key === '_generated') {\n continue;\n }\n\n if (key === 'nullable' && value === false) {\n continue;\n }\n\n if (key === 'generated' && value === false) {\n continue;\n }\n\n // Strip 'noAction' referential actions (the database default) for hash stability.\n // A contract with explicit `onDelete: 'noAction'` is semantically identical to\n // one that omits `onDelete` entirely, so they should produce the same hash.\n if ((key === 'onDelete' || key === 'onUpdate') && value === 'noAction') {\n continue;\n }\n\n if (isDefaultValue(value)) {\n const isRequiredModels = isArrayEqual(currentPath, ['models']);\n const isRequiredTables = isArrayEqual(currentPath, ['storage', 'tables']);\n const isRequiredRelations = isArrayEqual(currentPath, ['relations']);\n const isRequiredExtensionPacks = isArrayEqual(currentPath, ['extensionPacks']);\n const isRequiredCapabilities = isArrayEqual(currentPath, ['capabilities']);\n const isRequiredMeta = isArrayEqual(currentPath, ['meta']);\n const isRequiredExecutionDefaults = isArrayEqual(currentPath, [\n 'execution',\n 'mutations',\n 'defaults',\n ]);\n const isExtensionNamespace = currentPath.length === 2 && currentPath[0] === 'extensionPacks';\n const isModelRelations =\n currentPath.length === 3 &&\n isArrayEqual([currentPath[0], currentPath[2]], ['models', 'relations']);\n const isTableUniques =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'uniques'],\n );\n const isTableIndexes =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'indexes'],\n );\n const isTableForeignKeys =\n currentPath.length === 4 &&\n isArrayEqual(\n [currentPath[0], currentPath[1], currentPath[3]],\n ['storage', 'tables', 'foreignKeys'],\n );\n\n // Preserve per-FK `constraint` and `index` booleans (even when `false`)\n // so that hash distinguishes `false` from absent.\n // Path: ['storage', 'tables', <tableName>, 'foreignKeys', 'constraint' | 'index']\n const isFkBooleanField =\n currentPath.length === 5 &&\n currentPath[0] === 'storage' &&\n currentPath[1] === 'tables' &&\n currentPath[3] === 'foreignKeys' &&\n (key === 'constraint' || key === 'index');\n\n if (\n !isRequiredModels &&\n !isRequiredTables &&\n !isRequiredRelations &&\n !isRequiredExtensionPacks &&\n !isRequiredCapabilities &&\n !isRequiredMeta &&\n !isRequiredExecutionDefaults &&\n !isExtensionNamespace &&\n !isModelRelations &&\n !isTableUniques &&\n !isTableIndexes &&\n !isTableForeignKeys &&\n !isFkBooleanField\n ) {\n continue;\n }\n }\n\n result[key] = omitDefaults(value, currentPath);\n }\n\n return result;\n}\n\nfunction sortObjectKeys(obj: unknown): unknown {\n if (obj === null || typeof obj !== 'object') {\n return obj;\n }\n\n if (obj instanceof Date) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => sortObjectKeys(item));\n }\n\n const sorted: Record<string, unknown> = {};\n const keys = Object.keys(obj).sort();\n for (const key of keys) {\n sorted[key] = sortObjectKeys((obj as Record<string, unknown>)[key]);\n }\n\n return sorted;\n}\n\ntype StorageObject = {\n tables?: Record<string, unknown>;\n [key: string]: unknown;\n};\n\ntype TableObject = {\n indexes?: unknown[];\n uniques?: unknown[];\n [key: string]: unknown;\n};\n\nfunction sortIndexesAndUniques(storage: unknown): unknown {\n if (!storage || typeof storage !== 'object') {\n return storage;\n }\n\n const storageObj = storage as StorageObject;\n if (!storageObj.tables || typeof storageObj.tables !== 'object') {\n return storage;\n }\n\n const tables = storageObj.tables;\n const result: StorageObject = { ...storageObj };\n\n result.tables = {};\n // Sort table names to ensure deterministic ordering\n const sortedTableNames = Object.keys(tables).sort();\n for (const tableName of sortedTableNames) {\n const table = tables[tableName];\n if (!table || typeof table !== 'object') {\n result.tables[tableName] = table;\n continue;\n }\n\n const tableObj = table as TableObject;\n const sortedTable: TableObject = { ...tableObj };\n\n if (Array.isArray(tableObj.indexes)) {\n sortedTable.indexes = [...tableObj.indexes].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n if (Array.isArray(tableObj.uniques)) {\n sortedTable.uniques = [...tableObj.uniques].sort((a, b) => {\n const nameA = (a as { name?: string })?.name || '';\n const nameB = (b as { name?: string })?.name || '';\n return nameA.localeCompare(nameB);\n });\n }\n\n result.tables[tableName] = sortedTable;\n }\n\n return result;\n}\n\nfunction orderTopLevel(obj: Record<string, unknown>): Record<string, unknown> {\n const ordered: Record<string, unknown> = {};\n const remaining = new Set(Object.keys(obj));\n\n for (const key of TOP_LEVEL_ORDER) {\n if (remaining.has(key)) {\n ordered[key] = obj[key];\n remaining.delete(key);\n }\n }\n\n for (const key of Array.from(remaining).sort()) {\n ordered[key] = obj[key];\n }\n\n return ordered;\n}\n\nexport function canonicalizeContract(ir: CanonicalContractInput): string {\n const normalized: NormalizedContract = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n ...ifDefined('execution', ir.execution),\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n };\n Object.assign(\n normalized,\n ifDefined('storageHash', ir.storageHash),\n ifDefined('executionHash', ir.executionHash),\n ifDefined('profileHash', ir.profileHash),\n );\n\n const withDefaultsOmitted = omitDefaults(normalized, []) as NormalizedContract;\n const withSortedIndexes = sortIndexesAndUniques(withDefaultsOmitted.storage);\n const withSortedStorage = { ...withDefaultsOmitted, storage: withSortedIndexes };\n const withSortedKeys = sortObjectKeys(withSortedStorage) as Record<string, unknown>;\n const withOrderedTopLevel = orderTopLevel(withSortedKeys);\n\n return JSON.stringify(withOrderedTopLevel, bigintJsonReplacer, 2);\n}\n","import { createHash } from 'node:crypto';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { CanonicalContractInput } from './canonicalization';\nimport { canonicalizeContract } from './canonicalization';\n\nfunction computeHash(content: string): string {\n const hash = createHash('sha256');\n hash.update(content);\n return `sha256:${hash.digest('hex')}`;\n}\n\nexport function computeStorageHash(contract: CanonicalContractInput): string {\n const storageContract = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n storage: contract.storage,\n models: {},\n relations: {},\n extensionPacks: {},\n capabilities: {},\n meta: {},\n };\n const canonical = canonicalizeContract(storageContract);\n return computeHash(canonical);\n}\n\nexport function computeProfileHash(contract: CanonicalContractInput): string {\n const profileContract = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: {},\n relations: {},\n storage: {},\n extensionPacks: {},\n capabilities: contract.capabilities,\n meta: {},\n };\n const canonical = canonicalizeContract(profileContract);\n return computeHash(canonical);\n}\n\nexport function computeExecutionHash(contract: CanonicalContractInput): string {\n const executionContract = {\n schemaVersion: contract.schemaVersion,\n targetFamily: contract.targetFamily,\n target: contract.target,\n models: {},\n relations: {},\n storage: {},\n extensionPacks: {},\n capabilities: {},\n meta: {},\n ...ifDefined('execution', contract.execution),\n };\n const canonical = canonicalizeContract(executionContract);\n return computeHash(canonical);\n}\n","import type { ContractIR } from '@prisma-next/contract/ir';\nimport type { TargetFamilyHook, ValidationContext } from '@prisma-next/contract/types';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { type } from 'arktype';\nimport { format } from 'prettier';\nimport { canonicalizeContract } from './canonicalization';\nimport { computeExecutionHash, computeProfileHash, computeStorageHash } from './hashing';\nimport type { EmitOptions, EmitResult } from './types';\n\nconst CanonicalMetaSchema = type({\n '[string]': 'unknown',\n});\n\nconst CanonicalContractSchema = type({\n '+': 'reject',\n schemaVersion: 'string',\n targetFamily: 'string',\n target: 'string',\n models: type({ '[string]': 'unknown' }),\n relations: type({ '[string]': 'unknown' }),\n storage: type({ '[string]': 'unknown' }),\n 'execution?': type({ '[string]': 'unknown' }),\n extensionPacks: type({ '[string]': 'unknown' }),\n capabilities: type({\n '[string]': type({\n '[string]': 'boolean',\n }),\n }),\n meta: CanonicalMetaSchema,\n});\n\nfunction assertCanonicalArtifactShape(value: unknown): void {\n const result = CanonicalContractSchema(value);\n if (result instanceof type.errors) {\n const issues = result\n .map((error) => {\n const path = error.path?.toString() ?? '<root>';\n return `${path}: ${error.message}`;\n })\n .join('; ');\n throw new Error(`ContractIR canonical artifact validation failed: ${issues}`);\n }\n}\n\nfunction validateCoreStructure(ir: ContractIR): void {\n if (!ir.targetFamily) {\n throw new Error('ContractIR must have targetFamily');\n }\n if (!ir.target) {\n throw new Error('ContractIR must have target');\n }\n if (!ir.schemaVersion) {\n throw new Error('ContractIR must have schemaVersion');\n }\n if (!ir.models || typeof ir.models !== 'object') {\n throw new Error('ContractIR must have models');\n }\n if (!ir.storage || typeof ir.storage !== 'object') {\n throw new Error('ContractIR must have storage');\n }\n if (!ir.relations || typeof ir.relations !== 'object') {\n throw new Error('ContractIR must have relations');\n }\n if (!ir.extensionPacks || typeof ir.extensionPacks !== 'object') {\n throw new Error('ContractIR must have extensionPacks');\n }\n if (!ir.capabilities || typeof ir.capabilities !== 'object') {\n throw new Error('ContractIR must have capabilities');\n }\n if (!ir.meta || typeof ir.meta !== 'object') {\n throw new Error('ContractIR must have meta');\n }\n}\n\nexport async function emit(\n ir: ContractIR,\n options: EmitOptions,\n targetFamily: TargetFamilyHook,\n): Promise<EmitResult> {\n const {\n operationRegistry,\n codecTypeImports,\n operationTypeImports,\n extensionIds,\n parameterizedRenderers,\n parameterizedTypeImports,\n } = options;\n\n validateCoreStructure(ir);\n\n const ctx: ValidationContext = {\n ...ifDefined('operationRegistry', operationRegistry),\n ...ifDefined('codecTypeImports', codecTypeImports),\n ...ifDefined('operationTypeImports', operationTypeImports),\n ...ifDefined('extensionIds', extensionIds),\n };\n targetFamily.validateTypes(ir, ctx);\n\n targetFamily.validateStructure(ir);\n\n const canonicalContract = {\n schemaVersion: ir.schemaVersion,\n targetFamily: ir.targetFamily,\n target: ir.target,\n models: ir.models,\n relations: ir.relations,\n storage: ir.storage,\n ...ifDefined('execution', ir.execution),\n extensionPacks: ir.extensionPacks,\n capabilities: ir.capabilities,\n meta: ir.meta,\n };\n assertCanonicalArtifactShape(canonicalContract);\n\n const storageHash = computeStorageHash(canonicalContract);\n const executionHash = canonicalContract.execution\n ? computeExecutionHash(canonicalContract)\n : undefined;\n const profileHash = computeProfileHash(canonicalContract);\n\n const contractWithHashes = {\n ...canonicalContract,\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n\n // Add _generated metadata to indicate this is a generated artifact\n // This ensures consistency between CLI emit and programmatic emit\n // Always add/update _generated with standard content for consistency\n const contractJsonObj = JSON.parse(canonicalizeContract(contractWithHashes)) as Record<\n string,\n unknown\n >;\n const contractJsonWithMeta = {\n ...contractJsonObj,\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 const contractJsonString = JSON.stringify(contractJsonWithMeta, null, 2);\n\n const generateOptions =\n parameterizedRenderers || parameterizedTypeImports\n ? {\n ...ifDefined('parameterizedRenderers', parameterizedRenderers),\n ...ifDefined('parameterizedTypeImports', parameterizedTypeImports),\n }\n : undefined;\n\n const contractTypeHashes = {\n storageHash,\n ...ifDefined('executionHash', executionHash),\n profileHash,\n };\n const contractDtsRaw = targetFamily.generateContractTypes(\n ir,\n codecTypeImports ?? [],\n operationTypeImports ?? [],\n contractTypeHashes,\n generateOptions,\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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"}
@@ -0,0 +1,276 @@
1
+ //#region src/errors.ts
2
+ /**
3
+ * Structured CLI error that contains all information needed for error envelopes.
4
+ * Call sites throw these errors with full context.
5
+ */
6
+ var CliStructuredError = class extends Error {
7
+ code;
8
+ domain;
9
+ severity;
10
+ why;
11
+ fix;
12
+ where;
13
+ meta;
14
+ docsUrl;
15
+ constructor(code, summary, options) {
16
+ super(summary);
17
+ this.name = "CliStructuredError";
18
+ this.code = code;
19
+ this.domain = options?.domain ?? "CLI";
20
+ this.severity = options?.severity ?? "error";
21
+ this.why = options?.why;
22
+ this.fix = options?.fix;
23
+ this.where = options?.where ? {
24
+ path: options.where.path,
25
+ line: options.where.line
26
+ } : void 0;
27
+ this.meta = options?.meta;
28
+ this.docsUrl = options?.docsUrl;
29
+ }
30
+ /**
31
+ * Converts this error to a CLI error envelope for output formatting.
32
+ */
33
+ toEnvelope() {
34
+ return {
35
+ code: `${this.domain === "CLI" ? "PN-CLI-" : "PN-RTM-"}${this.code}`,
36
+ domain: this.domain,
37
+ severity: this.severity,
38
+ summary: this.message,
39
+ why: this.why,
40
+ fix: this.fix,
41
+ where: this.where,
42
+ meta: this.meta,
43
+ docsUrl: this.docsUrl
44
+ };
45
+ }
46
+ /**
47
+ * Type guard to check if an error is a CliStructuredError.
48
+ * Uses duck-typing to work across module boundaries where instanceof may fail.
49
+ */
50
+ static is(error) {
51
+ if (!(error instanceof Error)) return false;
52
+ const candidate = error;
53
+ return candidate.name === "CliStructuredError" && typeof candidate.code === "string" && (candidate.domain === "CLI" || candidate.domain === "RTM") && typeof candidate.toEnvelope === "function";
54
+ }
55
+ };
56
+ /**
57
+ * Config file not found or missing.
58
+ */
59
+ function errorConfigFileNotFound(configPath, options) {
60
+ return new CliStructuredError("4001", "Config file not found", {
61
+ domain: "CLI",
62
+ ...options?.why ? { why: options.why } : { why: "Config file not found" },
63
+ fix: "Run 'prisma-next init' to create a config file",
64
+ docsUrl: "https://prisma-next.dev/docs/cli/config",
65
+ ...configPath ? { where: { path: configPath } } : {}
66
+ });
67
+ }
68
+ /**
69
+ * Contract configuration missing from config.
70
+ */
71
+ function errorContractConfigMissing(options) {
72
+ return new CliStructuredError("4002", "Contract configuration missing", {
73
+ domain: "CLI",
74
+ why: options?.why ?? "The contract configuration is required for emit",
75
+ fix: "Add contract configuration to your prisma-next.config.ts",
76
+ docsUrl: "https://prisma-next.dev/docs/cli/contract-emit"
77
+ });
78
+ }
79
+ /**
80
+ * Contract validation failed.
81
+ */
82
+ function errorContractValidationFailed(reason, options) {
83
+ return new CliStructuredError("4003", "Contract validation failed", {
84
+ domain: "CLI",
85
+ why: reason,
86
+ fix: "Re-run `prisma-next contract emit`, or fix the contract file and try again",
87
+ docsUrl: "https://prisma-next.dev/docs/contracts",
88
+ ...options?.where ? { where: options.where } : {}
89
+ });
90
+ }
91
+ /**
92
+ * File not found.
93
+ */
94
+ function errorFileNotFound(filePath, options) {
95
+ return new CliStructuredError("4004", "File not found", {
96
+ domain: "CLI",
97
+ why: options?.why ?? `File not found: ${filePath}`,
98
+ fix: options?.fix ?? "Check that the file path is correct",
99
+ where: { path: filePath },
100
+ ...options?.docsUrl ? { docsUrl: options.docsUrl } : {}
101
+ });
102
+ }
103
+ /**
104
+ * Database connection is required but not provided.
105
+ */
106
+ function errorDatabaseConnectionRequired(options) {
107
+ return new CliStructuredError("4005", "Database connection is required", {
108
+ domain: "CLI",
109
+ why: options?.why ?? "Database connection is required for this command",
110
+ fix: "Provide `--db <url>` or set `db: { connection: \"postgres://…\" }` in prisma-next.config.ts"
111
+ });
112
+ }
113
+ /**
114
+ * Query runner factory is required but not provided in config.
115
+ */
116
+ function errorQueryRunnerFactoryRequired(options) {
117
+ return new CliStructuredError("4006", "Query runner factory is required", {
118
+ domain: "CLI",
119
+ why: options?.why ?? "Config.db.queryRunnerFactory is required for db verify",
120
+ fix: "Add db.queryRunnerFactory to prisma-next.config.ts",
121
+ docsUrl: "https://prisma-next.dev/docs/cli/db-verify"
122
+ });
123
+ }
124
+ /**
125
+ * Family verify.readMarker is required but not provided.
126
+ */
127
+ function errorFamilyReadMarkerSqlRequired(options) {
128
+ return new CliStructuredError("4007", "Family readMarker() is required", {
129
+ domain: "CLI",
130
+ why: options?.why ?? "Family verify.readMarker is required for db verify",
131
+ fix: "Ensure family.verify.readMarker() is exported by your family package",
132
+ docsUrl: "https://prisma-next.dev/docs/cli/db-verify"
133
+ });
134
+ }
135
+ /**
136
+ * JSON output format not supported.
137
+ */
138
+ function errorJsonFormatNotSupported(options) {
139
+ return new CliStructuredError("4008", "Unsupported JSON format", {
140
+ domain: "CLI",
141
+ why: `The ${options.command} command does not support --json ${options.format}`,
142
+ fix: `Use --json ${options.supportedFormats.join(" or ")}, or omit --json for human output`,
143
+ meta: {
144
+ command: options.command,
145
+ format: options.format,
146
+ supportedFormats: options.supportedFormats
147
+ }
148
+ });
149
+ }
150
+ /**
151
+ * Driver is required for DB-connected commands but not provided.
152
+ */
153
+ function errorDriverRequired(options) {
154
+ return new CliStructuredError("4010", "Driver is required for DB-connected commands", {
155
+ domain: "CLI",
156
+ why: options?.why ?? "Config.driver is required for DB-connected commands",
157
+ fix: "Add a control-plane driver to prisma-next.config.ts (e.g. import a driver descriptor and set `driver: postgresDriver`)",
158
+ docsUrl: "https://prisma-next.dev/docs/cli/config"
159
+ });
160
+ }
161
+ /**
162
+ * Contract requires extension packs that are not provided by config descriptors.
163
+ */
164
+ function errorContractMissingExtensionPacks(options) {
165
+ const missing = [...options.missingExtensionPacks].sort();
166
+ return new CliStructuredError("4011", "Missing extension packs in config", {
167
+ domain: "CLI",
168
+ why: missing.length === 1 ? `Contract requires extension pack '${missing[0]}', but CLI config does not provide a matching descriptor.` : `Contract requires extension packs ${missing.map((p) => `'${p}'`).join(", ")}, but CLI config does not provide matching descriptors.`,
169
+ fix: "Add the missing extension descriptors to `extensions` in prisma-next.config.ts",
170
+ docsUrl: "https://prisma-next.dev/docs/cli/config",
171
+ meta: {
172
+ missingExtensionPacks: missing,
173
+ providedComponentIds: [...options.providedComponentIds].sort()
174
+ }
175
+ });
176
+ }
177
+ /**
178
+ * Migration planning failed due to conflicts.
179
+ */
180
+ function errorMigrationPlanningFailed(options) {
181
+ const conflictSummaries = options.conflicts.map((c) => c.summary);
182
+ const computedWhy = options.why ?? conflictSummaries.join("\n");
183
+ const conflictFixes = options.conflicts.map((c) => c.why).filter((why) => typeof why === "string");
184
+ return new CliStructuredError("4020", "Migration planning failed", {
185
+ domain: "CLI",
186
+ why: computedWhy,
187
+ fix: conflictFixes.length > 0 ? conflictFixes.join("\n") : "Use `db schema-verify` to inspect conflicts, or ensure the database is empty",
188
+ meta: { conflicts: options.conflicts },
189
+ docsUrl: "https://prisma-next.dev/docs/cli/db-init"
190
+ });
191
+ }
192
+ /**
193
+ * Target does not support migrations (missing createPlanner/createRunner).
194
+ */
195
+ function errorTargetMigrationNotSupported(options) {
196
+ return new CliStructuredError("4021", "Target does not support migrations", {
197
+ domain: "CLI",
198
+ why: options?.why ?? "The configured target does not provide migration planner/runner",
199
+ fix: "Select a target that provides migrations (it must export `target.migrations` for db init)",
200
+ docsUrl: "https://prisma-next.dev/docs/cli/db-init"
201
+ });
202
+ }
203
+ /**
204
+ * Config validation error (missing required fields).
205
+ */
206
+ function errorConfigValidation(field, options) {
207
+ return new CliStructuredError("4001", "Config file not found", {
208
+ domain: "CLI",
209
+ why: options?.why ?? `Config must have a "${field}" field`,
210
+ fix: "Run 'prisma-next init' to create a config file",
211
+ docsUrl: "https://prisma-next.dev/docs/cli/config"
212
+ });
213
+ }
214
+ /**
215
+ * Contract marker not found in database.
216
+ */
217
+ function errorMarkerMissing(options) {
218
+ return new CliStructuredError("3001", "Marker missing", {
219
+ domain: "RTM",
220
+ why: options?.why ?? "Contract marker not found in database",
221
+ fix: "Run `prisma-next db sign --db <url>` to create marker"
222
+ });
223
+ }
224
+ /**
225
+ * Contract hash does not match database marker.
226
+ */
227
+ function errorHashMismatch(options) {
228
+ return new CliStructuredError("3002", "Hash mismatch", {
229
+ domain: "RTM",
230
+ why: options?.why ?? "Contract hash does not match database marker",
231
+ fix: "Migrate database or re-sign if intentional",
232
+ ...options?.expected || options?.actual ? { meta: {
233
+ ...options.expected ? { expected: options.expected } : {},
234
+ ...options.actual ? { actual: options.actual } : {}
235
+ } } : {}
236
+ });
237
+ }
238
+ /**
239
+ * Contract target does not match config target.
240
+ */
241
+ function errorTargetMismatch(expected, actual, options) {
242
+ return new CliStructuredError("3003", "Target mismatch", {
243
+ domain: "RTM",
244
+ why: options?.why ?? `Contract target does not match config target (expected: ${expected}, actual: ${actual})`,
245
+ fix: "Align contract target and config target",
246
+ meta: {
247
+ expected,
248
+ actual
249
+ }
250
+ });
251
+ }
252
+ /**
253
+ * Generic runtime error.
254
+ */
255
+ function errorRuntime(summary, options) {
256
+ return new CliStructuredError("3000", summary, {
257
+ domain: "RTM",
258
+ ...options?.why ? { why: options.why } : { why: "Verification failed" },
259
+ ...options?.fix ? { fix: options.fix } : { fix: "Check contract and database state" },
260
+ ...options?.meta ? { meta: options.meta } : {}
261
+ });
262
+ }
263
+ /**
264
+ * Generic unexpected error.
265
+ */
266
+ function errorUnexpected(message, options) {
267
+ return new CliStructuredError("4999", "Unexpected error", {
268
+ domain: "CLI",
269
+ why: options?.why ?? message,
270
+ fix: options?.fix ?? "Check the error message and try again"
271
+ });
272
+ }
273
+
274
+ //#endregion
275
+ export { errorTargetMigrationNotSupported as _, errorContractMissingExtensionPacks as a, errorDriverRequired as c, errorHashMismatch as d, errorJsonFormatNotSupported as f, errorRuntime as g, errorQueryRunnerFactoryRequired as h, errorContractConfigMissing as i, errorFamilyReadMarkerSqlRequired as l, errorMigrationPlanningFailed as m, errorConfigFileNotFound as n, errorContractValidationFailed as o, errorMarkerMissing as p, errorConfigValidation as r, errorDatabaseConnectionRequired as s, CliStructuredError as t, errorFileNotFound as u, errorTargetMismatch as v, errorUnexpected as y };
276
+ //# sourceMappingURL=errors-Qlh0sdcb.mjs.map