@prisma/orm-family-sql 8.0.0-rc.14-dev.16 → 8.0.0-rc.14-dev.18

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 (31) hide show
  1. package/dist/contract-prisma7__provider.mjs +15 -25
  2. package/dist/contract-prisma7__provider.mjs.map +1 -1
  3. package/dist/contract-psl.d.mts +6 -24
  4. package/dist/contract-psl.d.mts.map +1 -1
  5. package/dist/contract-psl.mjs +1 -1
  6. package/dist/contract-psl__attribute-specs.d.mts +11 -3
  7. package/dist/contract-psl__attribute-specs.d.mts.map +1 -1
  8. package/dist/contract-psl__attribute-specs.mjs +2 -2
  9. package/dist/contract-psl__provider.mjs +12 -5
  10. package/dist/contract-psl__provider.mjs.map +1 -1
  11. package/dist/{control-B8LE0HRq.mjs → control-DIVsNXHK.mjs} +4 -2
  12. package/dist/control-DIVsNXHK.mjs.map +1 -0
  13. package/dist/{control--13SHD7X.d.mts → control-nLCfcNhb.d.mts} +4 -1
  14. package/dist/control-nLCfcNhb.d.mts.map +1 -0
  15. package/dist/family.d.mts +1 -1
  16. package/dist/family.mjs +1 -1
  17. package/dist/family__control.d.mts +1 -1
  18. package/dist/family__control.mjs +1 -1
  19. package/dist/family__pack.mjs +1 -1
  20. package/dist/{interpreter-CkCfPqup-DF7bZvNM.mjs → interpreter-C8cP92FD-Co9RsuUU.mjs} +58 -1549
  21. package/dist/interpreter-C8cP92FD-Co9RsuUU.mjs.map +1 -0
  22. package/dist/psl-column-resolution-sNpXQygQ-BQr15EoR.d.mts +28 -0
  23. package/dist/psl-column-resolution-sNpXQygQ-BQr15EoR.d.mts.map +1 -0
  24. package/dist/psl-field-resolution-_o74AUE4-CKYNRnzL.mjs +1868 -0
  25. package/dist/psl-field-resolution-_o74AUE4-CKYNRnzL.mjs.map +1 -0
  26. package/package.json +18 -18
  27. package/dist/control--13SHD7X.d.mts.map +0 -1
  28. package/dist/control-B8LE0HRq.mjs.map +0 -1
  29. package/dist/interpreter-CkCfPqup-DF7bZvNM.mjs.map +0 -1
  30. package/dist/sql-attribute-specs-DxpHr9Fk-CeWmMP7y.mjs +0 -543
  31. package/dist/sql-attribute-specs-DxpHr9Fk-CeWmMP7y.mjs.map +0 -1
@@ -1,1426 +1,28 @@
1
1
  import { n as isAuthoredIndexInput } from "./index-naming-Cj1Anq-T-C9TevpPR.mjs";
2
2
  import { n as providesPslEntityPlacement } from "./entity-handle-lowering-hook-B3atrRKX.mjs";
3
- import { s as sqlTextFromCanonical, t as SQL_EXPRESSION_DATA_TYPE_ID } from "./sql-expression-BXx0Ilj-.mjs";
4
3
  import { d as resolvedTypeParams } from "./types-jFnALKoT.mjs";
5
- import { n as checkSqlDefaultBody, o as reservedSqlDefaultBody } from "./validators-DvzOZLel.mjs";
6
4
  import { t as deriveValueSetFromEntity } from "./value-set-derivation-hook-Di9JZ0X7.mjs";
7
- import { a as storedAsListColumn, i as isValueObjectMember, n as buildSqlContractFromDefinition } from "./derived-checks-C_y1rk6O-DdqjzGNy.mjs";
8
- import { a as getAttribute, c as interpretModelAttribute, d as modelAttributeSpecsFrom, f as sqlAttributeSpecs, i as formatDbAttributeMigrationMessage, l as lowerDefaultFunctionWithRegistry, n as createSqlBinder, o as getNamedArgument, p as storageName, r as fieldSpecContext, s as interpretFieldAttribute, t as PSL_CHECK_ON_STI_VARIANT, u as mapFieldNamesToColumns } from "./sql-attribute-specs-DxpHr9Fk-CeWmMP7y.mjs";
5
+ import { n as buildSqlContractFromDefinition } from "./derived-checks-C_y1rk6O-DdqjzGNy.mjs";
6
+ import { S as toNamedTypeFieldDescriptor, _ as modelCoordinateKey, b as sqlAttributeSpecs, c as getAttribute, f as instantiatePslTypeConstructor, g as modelAttributeSpecsFrom, h as mapFieldNamesToColumns, i as contractError, l as getAuthoringEntity, m as interpretModelAttribute, n as bareTypeConstructorOf, p as interpretFieldAttribute, r as collectResolvedFields, s as formatDbAttributeMigrationMessage, t as PSL_CHECK_ON_STI_VARIANT, u as getNamedArgument, x as storageName, y as resolveFieldTypeDescriptor } from "./psl-field-resolution-_o74AUE4-CKYNRnzL.mjs";
9
7
  import { t as defaultTableName } from "./default-table-name-BfFY8qYR-lHNcVmY5.mjs";
10
- import { structuredError } from "@prisma/orm-framework/utils/structured-error";
11
- import { checkUncomposedNamespace, getAuthoringFieldPreset, getAuthoringTypeConstructor, hasRegisteredFieldNamespace, instantiateAuthoringEntityType, instantiateAuthoringTypeConstructor, isAuthoringEntityTypeDescriptor, isAuthoringModelAttributeDescriptor, validateAuthoringHelperArguments } from "@prisma/orm-framework/components/authoring";
8
+ import { instantiateAuthoringEntityType, instantiateAuthoringTypeConstructor, isAuthoringEntityTypeDescriptor, isAuthoringModelAttributeDescriptor } from "@prisma/orm-framework/components/authoring";
12
9
  import { UNBOUND_NAMESPACE_ID } from "@prisma/orm-framework/components/ir";
13
- import { InternalError, isInternalError } from "@prisma/orm-framework/utils/internal-error";
10
+ import { InternalError } from "@prisma/orm-framework/utils/internal-error";
14
11
  import { crossRef } from "@prisma/orm-framework/contract/types";
15
12
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
16
- import { codecForRef } from "@prisma/orm-framework/components/codec";
17
13
  import { blindCast } from "@prisma/orm-framework/utils/casts";
18
- import { ArrayLiteralAst, IdentifierAst, NamespaceDeclarationAst } from "@prisma/orm-framework/psl-parser/syntax";
14
+ import { NamespaceDeclarationAst } from "@prisma/orm-framework/psl-parser/syntax";
19
15
  import { resolveToOneRelationNullable } from "@prisma/orm-framework/contract-authoring";
20
16
  import { assertDefined, invariant } from "@prisma/orm-framework/utils/assertions";
21
- import { describeTaggedLiteralFailure } from "@prisma/orm-framework/components/control";
22
17
  import { notOk, ok } from "@prisma/orm-framework/utils/result";
23
- import { createPslDiagnosticCollector, diagnosticSource, findBlockDescriptor, interpretExtensionBlocks, nodePslSpan, typeReferenceNode } from "@prisma/orm-framework/psl-parser";
18
+ import { contributedTypeOf, createPslDiagnosticCollector, diagnosticSource, findBlockDescriptor, interpretExtensionBlocks, nodePslSpan, typeReferenceNode } from "@prisma/orm-framework/psl-parser";
19
+ import { claimedBlockKeywords, enumMemberAttributeDiagnostics, fkRelationPairKey, requiredOneToOneBackrelationDiagnostic, unsupportedBlockDiagnostic } from "@prisma/orm-framework/psl-parser/interpret";
24
20
  import { UNBOUND_PSL_NAMESPACE_NAME, UNSPECIFIED_PSL_NAMESPACE_ID } from "@prisma/orm-framework/components/psl-ast";
25
- import { claimedBlockKeywords, enumMemberAttributeDiagnostics, fkRelationPairKey, instantiatePslFieldPreset, mapPslHelperArgs, reportUncomposedNamespace, reportUnknownFieldPreset, requiredOneToOneBackrelationDiagnostic, uncomposedNamespaceDiagnostic, unsupportedBlockDiagnostic } from "@prisma/orm-framework/psl-parser/interpret";
26
- //#region ../../../2-sql/2-authoring/contract-psl/dist/interpreter-CkCfPqup.mjs
27
- function contractError(code, message, options) {
28
- return structuredError(code, message, options);
29
- }
30
- /** A written value the column's codec refuses. */
31
- const PSL_INVALID_DEFAULT_LITERAL = "PSL_INVALID_DEFAULT_LITERAL";
32
- /** A written value whose data type the receiving type neither is nor casts from. */
33
- const PSL_VALUE_TYPE_INCOMPATIBLE = "PSL_VALUE_TYPE_INCOMPATIBLE";
34
- /** A single value written as the default of a column that holds a list. */
35
- const PSL_DEFAULT_LIST_EXPECTED = "PSL_DEFAULT_LIST_EXPECTED";
36
- /** The entry a tag names, or `undefined` when no pack registered that tag. */
37
- function entryForTag(support, tag) {
38
- for (const [key, entry] of Object.entries(support.entries)) if (entry.written.kind === "tag" && entry.written.tag === tag) return {
39
- key,
40
- entry
41
- };
42
- }
43
- /** Every tag a stack registers, in the order the entries were merged, for a diagnostic. */
44
- function knownTags(support) {
45
- return Object.values(support.entries).flatMap((entry) => entry.written.kind === "tag" ? [entry.written.tag] : []);
46
- }
47
- function entryForPlain(support, syntax) {
48
- for (const [key, entry] of Object.entries(support.entries)) if (entry.written.kind === "plain" && entry.written.syntax === syntax) return {
49
- key,
50
- entry
51
- };
52
- }
53
- /** The text an entry reads: a tag's text, a string's value, or the word a boolean is written as. */
54
- function plainText(written) {
55
- switch (written.kind) {
56
- case "tag": return written.text;
57
- case "string": return written.text;
58
- case "boolean": return String(written.value);
59
- case "number": return written.text;
60
- }
61
- }
62
- function messageOf(error) {
63
- return error instanceof Error ? error.message : String(error);
64
- }
65
- /** Read one written value through the entry for its syntax. */
66
- function readValue(support, written, elementIndex) {
67
- const refuse = (refusal) => ({
68
- ok: false,
69
- refusal: blindCast({
70
- ...refusal,
71
- elementIndex
72
- })
73
- });
74
- const found = written.kind === "tag" ? entryForTag(support, written.tag) : entryForPlain(support, written.kind);
75
- if (found === void 0) return written.kind === "tag" ? refuse({
76
- kind: "unknown-tag",
77
- tag: written.tag,
78
- known: knownTags(support)
79
- }) : refuse({
80
- kind: "unwritable",
81
- syntax: written.kind
82
- });
83
- const form = found.entry.written;
84
- if (form.kind === "plain" && form.syntax === "number") {
85
- const text = plainText(written);
86
- const classified = form.classify(text);
87
- if (classified === void 0) return refuse({
88
- kind: "unreadable",
89
- message: `no data type of this target holds the number ${text}`
90
- });
91
- return {
92
- ok: true,
93
- typed: classified
94
- };
95
- }
96
- const text = plainText(written);
97
- try {
98
- return {
99
- ok: true,
100
- typed: {
101
- type: blindCast(found.key),
102
- value: form.parse(text)
103
- }
104
- };
105
- } catch (error) {
106
- if (isInternalError(error)) throw error;
107
- return refuse({
108
- kind: "unreadable",
109
- message: messageOf(error)
110
- });
111
- }
112
- }
113
- /** Convert a value of one data type into the form another stores, when that type takes it. */
114
- function castInto(support, columnType, typed, elementIndex) {
115
- if (typed.type === columnType) return {
116
- ok: true,
117
- value: typed.value
118
- };
119
- const declaration = support.lookup.get(columnType);
120
- const cast = declaration?.casts[typed.type];
121
- if (cast === void 0) return {
122
- ok: false,
123
- refusal: {
124
- kind: "no-cast",
125
- columnType,
126
- valueType: typed.type,
127
- casts: Object.keys(declaration?.casts ?? {}),
128
- elementIndex
129
- }
130
- };
131
- try {
132
- return {
133
- ok: true,
134
- value: cast(typed.value)
135
- };
136
- } catch (error) {
137
- if (isInternalError(error)) throw error;
138
- return {
139
- ok: false,
140
- refusal: {
141
- kind: "unreadable",
142
- message: messageOf(error),
143
- elementIndex
144
- }
145
- };
146
- }
147
- }
148
- /** The column's `typeParams` as the codec reference carries them, so `vector(3)` checks its length. */
149
- function codecRefTypeParams(typeParams) {
150
- return typeParams === void 0 ? void 0 : blindCast(typeParams);
151
- }
152
- /**
153
- * The column's codec descriptor, and `read`, which reads a value in its stored JSON form with the column's codec, built with the column's type parameters.
154
- */
155
- function storedValueReader(input) {
156
- if (input.codecLookup === void 0) throw new InternalError(`Field "${input.fieldPath}": no codec lookup was given, but the column was resolved from a codec descriptor.`);
157
- const descriptor = input.codecLookup.descriptorFor(input.column.codecId);
158
- const codec = codecForRef(input.codecLookup, {
159
- codecId: input.column.codecId,
160
- ...ifDefined("typeParams", codecRefTypeParams(input.column.typeParams))
161
- });
162
- if (codec === void 0 || descriptor === void 0) throw new InternalError(`Field "${input.fieldPath}": no codec descriptor is registered for "${input.column.codecId}", but the column was resolved from one.`);
163
- const read = (value, elementIndex) => {
164
- try {
165
- codec.decodeJson(value);
166
- return {
167
- ok: true,
168
- value
169
- };
170
- } catch (error) {
171
- if (isInternalError(error)) throw error;
172
- return {
173
- ok: false,
174
- refusal: {
175
- kind: "refused-by-codec",
176
- codecId: input.column.codecId,
177
- message: messageOf(error),
178
- elementIndex
179
- }
180
- };
181
- }
182
- };
183
- return {
184
- descriptor,
185
- read
186
- };
187
- }
188
- /**
189
- * Reads a value already in its stored JSON form, such as one member of a JSON document default, with the column's codec. Worded as {@link lowerDataTypeDefault} words a codec refusal.
190
- */
191
- function readStoredValue(input) {
192
- const reading = storedValueReader(input).read(input.value, void 0);
193
- return reading.ok ? reading : refusalDiagnostic(reading.refusal, input.fieldPath);
194
- }
195
- /**
196
- * Read one `@default(...)` value for a column, refusing in parts so each contract source words its
197
- * own diagnostic. `isList` selects the check: a list column's elements are each read and cast
198
- * against the element codec's data type, while a scalar column takes a written list only through
199
- * its type's list cast — which is how `pgvector.Vector(3) @default([0.1, 0.2])` is read.
200
- */
201
- function readDataTypeDefault(input) {
202
- const { descriptor, read: readStored } = storedValueReader(input);
203
- const columnType = descriptor.dataType;
204
- const readOne = (written, elementIndex) => {
205
- const read = readValue(input.support, written, elementIndex);
206
- if (!read.ok) return read;
207
- const cast = castInto(input.support, columnType, read.typed, elementIndex);
208
- if (!cast.ok) return cast;
209
- return readStored(cast.value, elementIndex);
210
- };
211
- if (input.written.kind !== "list") {
212
- if (input.isList) return {
213
- ok: false,
214
- refusal: {
215
- kind: "not-a-list",
216
- elementIndex: void 0
217
- }
218
- };
219
- return readOne(input.written, void 0);
220
- }
221
- if (input.isList) {
222
- const elements = [];
223
- for (const [elementIndex, written] of input.written.elements.entries()) {
224
- if (written.kind === "list") return {
225
- ok: false,
226
- refusal: {
227
- kind: "unreadable",
228
- message: "a list holds values, not other lists",
229
- elementIndex
230
- }
231
- };
232
- const element = readOne(written, elementIndex);
233
- if (!element.ok) return element;
234
- elements.push(element.value);
235
- }
236
- return {
237
- ok: true,
238
- value: elements
239
- };
240
- }
241
- return readListIntoScalar({
242
- ...input,
243
- written: input.written,
244
- columnType,
245
- readStored
246
- });
247
- }
248
- /** A written list on a column that is not a list: the column's type takes it through its list cast. */
249
- function readListIntoScalar(input) {
250
- const listCast = input.support.lookup.get(input.columnType)?.listCast;
251
- if (listCast === void 0) return {
252
- ok: false,
253
- refusal: {
254
- kind: "no-cast",
255
- columnType: input.columnType,
256
- valueType: "a list",
257
- casts: Object.keys(input.support.lookup.get(input.columnType)?.casts ?? {}),
258
- elementIndex: void 0
259
- }
260
- };
261
- const elements = [];
262
- for (const [elementIndex, written] of input.written.elements.entries()) {
263
- if (written.kind === "list") return {
264
- ok: false,
265
- refusal: {
266
- kind: "unreadable",
267
- message: "a list holds values, not other lists",
268
- elementIndex
269
- }
270
- };
271
- const read = readValue(input.support, written, elementIndex);
272
- if (!read.ok) return read;
273
- if (!listCast.of.includes(read.typed.type)) return {
274
- ok: false,
275
- refusal: {
276
- kind: "no-cast",
277
- columnType: input.columnType,
278
- valueType: read.typed.type,
279
- casts: [...listCast.of],
280
- elementIndex
281
- }
282
- };
283
- elements.push(read.typed.value);
284
- }
285
- try {
286
- return input.readStored(listCast.cast(elements), void 0);
287
- } catch (error) {
288
- if (isInternalError(error)) throw error;
289
- return {
290
- ok: false,
291
- refusal: {
292
- kind: "unreadable",
293
- message: messageOf(error),
294
- elementIndex: void 0
295
- }
296
- };
297
- }
298
- }
299
- /** Where in a written list a diagnostic is about, for a message: ` at element 2`. */
300
- function at(elementIndex) {
301
- return elementIndex === void 0 ? "" : ` at element ${elementIndex + 1}`;
302
- }
303
- /** {@link readDataTypeDefault} worded as a PSL diagnostic's code and message. */
304
- function lowerDataTypeDefault(input) {
305
- const read = readDataTypeDefault(input);
306
- return read.ok ? read : refusalDiagnostic(read.refusal, input.fieldPath);
307
- }
308
- /** A refusal worded as a PSL diagnostic's code and message. */
309
- function refusalDiagnostic(refusal, fieldPath) {
310
- const where = `Field "${fieldPath}"${at(refusal.elementIndex)}`;
311
- switch (refusal.kind) {
312
- case "unreadable": return {
313
- ok: false,
314
- code: "PSL_INVALID_LITERAL",
315
- message: `${where}: ${refusal.message}`
316
- };
317
- case "unknown-tag": return {
318
- ok: false,
319
- code: "PSL_UNKNOWN_LITERAL_TAG",
320
- message: `Unknown literal tag "${refusal.tag}". Known tags: ${refusal.known.join(", ")}.`
321
- };
322
- case "unwritable": return {
323
- ok: false,
324
- code: PSL_VALUE_TYPE_INCOMPATIBLE,
325
- message: `${where}: this target has no data type for a ${refusal.syntax} value`
326
- };
327
- case "not-a-list": return {
328
- ok: false,
329
- code: PSL_DEFAULT_LIST_EXPECTED,
330
- message: `${where}: this column holds a list, so its default is a list literal, as in [1, 2]`
331
- };
332
- case "no-cast": return {
333
- ok: false,
334
- code: PSL_VALUE_TYPE_INCOMPATIBLE,
335
- message: `${where}: ${refusal.columnType} has no cast from ${refusal.valueType}; ${describeCasts(refusal.casts)}`
336
- };
337
- case "refused-by-codec": return {
338
- ok: false,
339
- code: PSL_INVALID_DEFAULT_LITERAL,
340
- message: `${where}: ${refusal.message}`
341
- };
342
- }
343
- }
344
- function describeCasts(casts) {
345
- return casts.length === 0 ? "it casts from nothing" : `it casts from ${casts.join(", ")}`;
346
- }
347
- /** Each way the default does not match the composite type. */
348
- function valueObjectDefaultMismatches(input) {
349
- const mismatches = [];
350
- const shape = (path, message) => mismatches.push({
351
- code: PSL_VALUE_TYPE_INCOMPATIBLE,
352
- message: `Field "${path}": ${message}`
353
- });
354
- const checkObject = (value, valueObjectName, path) => {
355
- const valueObject = input.types.nodes.get(valueObjectName);
356
- const declared = input.types.declaredMembers.get(valueObjectName);
357
- if (valueObject === void 0 || declared === void 0) throw new InternalError(`Field "${path}" is typed by the value object "${valueObjectName}", which the contract does not declare.`);
358
- if (!isJsonObject(value)) {
359
- shape(path, `a value of "${valueObjectName}" is a JSON object, not ${jsonKind(value)}`);
360
- return;
361
- }
362
- for (const key of Object.keys(value)) if (!declared.has(key)) shape(path, `"${key}" is not a member of "${valueObjectName}"`);
363
- for (const member of valueObject.fields) checkMember(value[member.fieldName], member, `${path}.${member.fieldName}`);
364
- };
365
- const checkMember = (value, member, path) => {
366
- if (value === void 0) {
367
- if (!member.nullable) shape(path, "the member is required, and the default has no value for it");
368
- return;
369
- }
370
- if (value === null && member.nullable) return;
371
- if (member.many === true) {
372
- if (!Array.isArray(value)) {
373
- shape(path, `the member is a list, so its value is a JSON array, not ${jsonKind(value)}`);
374
- return;
375
- }
376
- for (const [index, element] of value.entries()) {
377
- if (element === null && member.elementNullable) continue;
378
- checkOne(element, member, `${path}[${index}]`, "an element of the member is not null");
379
- }
380
- return;
381
- }
382
- checkOne(value, member, path, "the member is not optional, so its value is not null");
383
- };
384
- const checkOne = (value, member, path, notNull) => {
385
- if (isValueObjectMember(member)) {
386
- if (value === null) shape(path, notNull);
387
- else checkObject(value, member.valueObjectName, path);
388
- return;
389
- }
390
- const reading = readStoredValue({
391
- value,
392
- column: member.descriptor,
393
- codecLookup: input.codecLookup,
394
- fieldPath: path
395
- });
396
- if (!reading.ok) {
397
- if (value === null) shape(path, notNull);
398
- else mismatches.push({
399
- code: reading.code,
400
- message: reading.message
401
- });
402
- return;
403
- }
404
- const enumMismatch = enumValueMismatch(value, member, path, input.codecLookup);
405
- if (enumMismatch !== void 0) mismatches.push(enumMismatch);
406
- };
407
- if (input.value === null) {
408
- if (input.nullable) return mismatches;
409
- shape(input.fieldPath, input.list ? "the default of a list of value objects is a JSON array, not null" : "the default of a value object is a JSON object, not null");
410
- return mismatches;
411
- }
412
- if (input.list) {
413
- if (!Array.isArray(input.value)) {
414
- shape(input.fieldPath, `the default of a list of value objects is a JSON array, not ${jsonKind(input.value)}`);
415
- return mismatches;
416
- }
417
- for (const [index, element] of input.value.entries()) {
418
- if (element === null && input.elementNullable) continue;
419
- checkObject(element, input.valueObjectName, `${input.fieldPath}[${index}]`);
420
- }
421
- return mismatches;
422
- }
423
- if (!isJsonObject(input.value)) {
424
- shape(input.fieldPath, `the default of a value object is a JSON object, not ${jsonKind(input.value)}`);
425
- return mismatches;
426
- }
427
- checkObject(input.value, input.valueObjectName, input.fieldPath);
428
- return mismatches;
429
- }
430
- /**
431
- * A member typed by an enum takes only the enum's values, in the form its codec stores them, as a model field of that enum takes only its members.
432
- */
433
- function enumValueMismatch(value, member, path, codecLookup) {
434
- const handle = member.enumTypeHandle;
435
- if (handle === void 0) return void 0;
436
- const codec = codecLookup?.get(handle.codecId);
437
- const stored = handle.values.map((enumValue) => codec === void 0 ? enumValue : codec.encodeJson(enumValue));
438
- if (stored.some((storedValue) => storedValue === value)) return void 0;
439
- return {
440
- code: PSL_INVALID_DEFAULT_LITERAL,
441
- message: `Field "${path}": Expected one of: ${stored.map((storedValue) => JSON.stringify(storedValue)).join(" | ")}`
442
- };
443
- }
444
- function isJsonObject(value) {
445
- return typeof value === "object" && value !== null && !Array.isArray(value);
446
- }
447
- function jsonKind(value) {
448
- if (value === null) return "null";
449
- if (Array.isArray(value)) return "a JSON array";
450
- if (typeof value === "object") return "a JSON object";
451
- return `a JSON ${typeof value}`;
452
- }
453
- function toNamedTypeFieldDescriptor(typeRef, descriptor) {
454
- return {
455
- codecId: descriptor.codecId,
456
- nativeType: descriptor.nativeType,
457
- typeRef
458
- };
459
- }
460
- /**
461
- * Walks `authoringContributions.entityTypes` segment-by-segment and returns
462
- * the entity type descriptor at the resolved path, or `undefined` if no
463
- * descriptor is registered.
464
- *
465
- * Used by the PSL interpreter to dispatch declarative entity-shaped
466
- * declarations (`enum`, future `namespace { … }`, …) through the
467
- * pack entity-type mechanism — the descriptor's `factory` (or
468
- * `template`) materialises the IR-class instance without the
469
- * interpreter knowing target-specific construction.
470
- */
471
- function getAuthoringEntity(contributions, path) {
472
- let current = contributions?.entityTypes;
473
- for (const segment of path) {
474
- if (typeof current !== "object" || current === null || "kind" in current) return;
475
- current = current[segment];
476
- }
477
- return current !== void 0 && isAuthoringEntityTypeDescriptor(current) ? current : void 0;
478
- }
479
- function replacesUnresolvedTypeVoice(typeName, composedExtensions, context) {
480
- if (checkUncomposedNamespace(typeName, composedExtensions, context) !== void 0) return true;
481
- const dotIndex = typeName.indexOf(".");
482
- if (dotIndex <= 0 || dotIndex === typeName.length - 1) return false;
483
- return hasRegisteredFieldNamespace(context.authoringContributions, typeName.slice(0, dotIndex));
484
- }
485
- function instantiatePslTypeConstructor(input) {
486
- const helperPath = input.call.path.join(".");
487
- const args = mapPslHelperArgs({
488
- args: input.call.args,
489
- descriptors: input.descriptor.args ?? [],
490
- helperLabel: `constructor "${helperPath}"`,
491
- span: input.call.span,
492
- diagnostics: input.diagnostics,
493
- source: input.source,
494
- entityLabel: input.entityLabel
495
- });
496
- if (!args) return;
497
- try {
498
- validateAuthoringHelperArguments(helperPath, input.descriptor.args, args);
499
- return instantiateAuthoringTypeConstructor(input.descriptor, args);
500
- } catch (error) {
501
- if (isInternalError(error)) throw error;
502
- const message = error instanceof Error ? error.message : String(error);
503
- input.diagnostics.push({
504
- code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
505
- message: `${input.entityLabel} constructor "${helperPath}" ${message}`,
506
- ...input.source.at(input.call.span)
507
- });
508
- return;
509
- }
510
- }
511
- function pushUnsupportedTypeConstructorDiagnostic(input) {
512
- input.diagnostics.push({
513
- code: input.code,
514
- message: input.message,
515
- ...input.source.at(input.span)
516
- });
517
- }
518
- function resolvePslTypeConstructorDescriptor(input) {
519
- const descriptor = getAuthoringTypeConstructor(input.authoringContributions, input.call.path);
520
- if (descriptor) return descriptor;
521
- const uncomposedNamespace = checkUncomposedNamespace(input.call.path.join("."), input.composedExtensions, {
522
- familyId: input.familyId,
523
- targetId: input.targetId,
524
- authoringContributions: input.authoringContributions
525
- });
526
- if (uncomposedNamespace) {
527
- reportUncomposedNamespace({
528
- subjectLabel: `Type constructor "${input.call.path.join(".")}"`,
529
- namespace: uncomposedNamespace,
530
- source: input.source,
531
- span: input.call.span,
532
- diagnostics: input.diagnostics
533
- });
534
- return;
535
- }
536
- return pushUnsupportedTypeConstructorDiagnostic({
537
- diagnostics: input.diagnostics,
538
- source: input.source,
539
- span: input.call.span,
540
- code: input.unsupportedCode,
541
- message: input.unsupportedMessage
542
- });
543
- }
544
- /**
545
- * Structural check for a codec descriptor exposing the authoring-time
546
- * `columnFromEntity` hook a type constructor's `entityRefArg` resolves
547
- * through (e.g. the `pg/enum@1` codec descriptor). No casts.
548
- */
549
- function hasColumnFromEntityHook(descriptor) {
550
- return "columnFromEntity" in descriptor && typeof descriptor.columnFromEntity === "function";
551
- }
552
- /**
553
- * Resolves a type-constructor call whose descriptor declares an
554
- * `entityRefArg` (e.g. `pg.enum(AalLevel)`): extracts the call's sole
555
- * positional-argument ref string, resolves it against the field's
556
- * namespace's already-lowered extension entities (keyed by the declared
557
- * `entityRefArg.entityKind`, then block name), and converts the resolved
558
- * entity to column params via the `columnFromEntity` authoring hook on the
559
- * codec descriptor registered for `descriptor.output.codecId`. The `nativeType`
560
- * / `typeParams.typeName` `columnFromEntity` returns are bare — schema
561
- * qualification (e.g. `auth.aal_level`) is a target concern, applied later
562
- * when the target builds the field's namespace. A `valueSet` ref is
563
- * attached when the same namespace derived a value-set under the same block
564
- * name (the generic `deriveValueSet` mechanism), scoped to the field's own
565
- * namespace.
566
- */
567
- function resolveEntityRefTypeConstructorCall(input) {
568
- const entityRefArg = input.descriptor.entityRefArg;
569
- if (entityRefArg === void 0) throw new InternalError("resolveEntityRefTypeConstructorCall called with a descriptor that does not declare an entityRefArg. This is an interpreter bug.");
570
- const helperPath = input.call.path.join(".");
571
- const positionalArgs = input.call.args.filter((arg) => arg.kind === "positional");
572
- const ref = positionalArgs[entityRefArg.index]?.value;
573
- if (input.call.args.length !== 1 || positionalArgs.length !== 1 || ref === void 0) {
574
- input.diagnostics.push({
575
- code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
576
- message: `${input.entityLabel} type constructor "${helperPath}" expects exactly one positional argument naming the referenced entity`,
577
- ...input.source.at(input.call.span)
578
- });
579
- return {
580
- ok: false,
581
- alreadyReported: true
582
- };
583
- }
584
- const reportUnknownRef = () => {
585
- input.diagnostics.push({
586
- code: "PSL_UNKNOWN_ENTITY_REF",
587
- message: `${input.entityLabel} type constructor "${helperPath}(${ref})" does not resolve — no entity named "${ref}" was found in namespace "${input.namespaceId ?? "(unspecified)"}"`,
588
- ...input.source.at(input.call.span)
589
- });
590
- return {
591
- ok: false,
592
- alreadyReported: true
593
- };
594
- };
595
- const entity = input.namespaceExtensionEntities?.[entityRefArg.entityKind]?.[ref];
596
- if (entity === void 0) return reportUnknownRef();
597
- const codecId = input.descriptor.output.codecId;
598
- const codecDescriptor = input.codecLookup?.descriptorFor(codecId);
599
- if (codecDescriptor === void 0 || !hasColumnFromEntityHook(codecDescriptor)) throw contractError("CONTRACT.PACK_CONTRIBUTION_INVALID", `Type constructor "${helperPath}" registers codecId "${codecId}" with an entity-ref argument, but its codec descriptor has no "columnFromEntity" authoring hook. This is a contributor bug in the pack registering "${helperPath}", not a user-schema error.`, { meta: {
600
- helperPath,
601
- codecId
602
- } });
603
- const resolved = codecDescriptor.columnFromEntity(entity);
604
- if (resolved === void 0) return reportUnknownRef();
605
- const derivedValueSet = input.namespaceExtensionEntities?.["valueSet"]?.[ref];
606
- if (derivedValueSet !== void 0 && input.namespaceId === void 0) {
607
- input.diagnostics.push({
608
- code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
609
- message: `${input.entityLabel} type constructor "${helperPath}(${ref})" resolves to a value-set-typed entity, but the field has no resolvable namespace to scope the value-set ref to`,
610
- ...input.source.at(input.call.span)
611
- });
612
- return {
613
- ok: false,
614
- alreadyReported: true
615
- };
616
- }
617
- const valueSet = derivedValueSet !== void 0 && input.namespaceId !== void 0 ? {
618
- plane: "storage",
619
- entityKind: "valueSet",
620
- namespaceId: input.namespaceId,
621
- entityName: ref
622
- } : void 0;
623
- return {
624
- ok: true,
625
- descriptor: {
626
- codecId,
627
- nativeType: resolved.nativeType,
628
- ...resolved.typeParams !== void 0 ? { typeParams: resolved.typeParams } : {},
629
- ...valueSet !== void 0 ? { valueSet } : {}
630
- }
631
- };
632
- }
633
- function resolveFieldTypeDescriptor(input) {
634
- const source = diagnosticSource(input.sources, input.field.node.syntax);
635
- if (input.field.malformedType) return {
636
- ok: false,
637
- alreadyReported: true
638
- };
639
- if (input.field.typeConstructor) {
640
- const presetDescriptor = getAuthoringFieldPreset(input.authoringContributions, input.field.typeConstructor.path);
641
- if (presetDescriptor) {
642
- const instantiated = instantiatePslFieldPreset({
643
- call: input.field.typeConstructor,
644
- descriptor: presetDescriptor,
645
- diagnostics: input.diagnostics,
646
- source,
647
- entityLabel: input.entityLabel
648
- });
649
- if (!instantiated) return {
650
- ok: false,
651
- alreadyReported: true
652
- };
653
- const presetContributions = {
654
- nullable: instantiated.nullable,
655
- id: instantiated.id,
656
- unique: instantiated.unique,
657
- ...instantiated.default !== void 0 ? { default: instantiated.default } : {},
658
- ...instantiated.executionDefaults !== void 0 ? { executionDefaults: instantiated.executionDefaults } : {}
659
- };
660
- return {
661
- ok: true,
662
- descriptor: instantiated.descriptor,
663
- presetContributions
664
- };
665
- }
666
- const helperPath = input.field.typeConstructor.path.join(".");
667
- const namespacePrefix = input.field.typeConstructor.path.length > 1 ? input.field.typeConstructor.path[0] : void 0;
668
- const typeDescriptor = getAuthoringTypeConstructor(input.authoringContributions, input.field.typeConstructor.path);
669
- if (typeDescriptor?.entityRefArg) return resolveEntityRefTypeConstructorCall({
670
- call: input.field.typeConstructor,
671
- descriptor: typeDescriptor,
672
- namespaceId: input.namespaceId,
673
- namespaceExtensionEntities: input.namespaceExtensionEntities,
674
- codecLookup: input.codecLookup,
675
- diagnostics: input.diagnostics,
676
- source,
677
- entityLabel: input.entityLabel
678
- });
679
- if (!typeDescriptor && namespacePrefix && hasRegisteredFieldNamespace(input.authoringContributions, namespacePrefix)) {
680
- reportUnknownFieldPreset({
681
- entityLabel: input.entityLabel,
682
- namespace: namespacePrefix,
683
- helperPath,
684
- authoringContributions: input.authoringContributions,
685
- source,
686
- span: input.field.typeConstructor.span,
687
- diagnostics: input.diagnostics
688
- });
689
- return {
690
- ok: false,
691
- alreadyReported: true
692
- };
693
- }
694
- const descriptor = typeDescriptor ?? resolvePslTypeConstructorDescriptor({
695
- call: input.field.typeConstructor,
696
- authoringContributions: input.authoringContributions,
697
- composedExtensions: input.composedExtensions,
698
- familyId: input.familyId,
699
- targetId: input.targetId,
700
- diagnostics: input.diagnostics,
701
- source,
702
- unsupportedCode: "PSL_UNSUPPORTED_FIELD_TYPE",
703
- unsupportedMessage: `${input.entityLabel} type constructor "${helperPath}" is not supported in SQL PSL provider v1`
704
- });
705
- if (!descriptor) return {
706
- ok: false,
707
- alreadyReported: true
708
- };
709
- const instantiated = instantiatePslTypeConstructor({
710
- call: input.field.typeConstructor,
711
- descriptor,
712
- diagnostics: input.diagnostics,
713
- source,
714
- entityLabel: input.entityLabel
715
- });
716
- if (!instantiated) return {
717
- ok: false,
718
- alreadyReported: true
719
- };
720
- return {
721
- ok: true,
722
- descriptor: instantiated
723
- };
724
- }
725
- const descriptor = resolveColumnDescriptor(input.field, input.enumTypeDescriptors, input.namedTypeDescriptors, input.scalarColumnDescriptors);
726
- if (!descriptor) return {
727
- ok: false,
728
- alreadyReported: false
729
- };
730
- return {
731
- ok: true,
732
- descriptor
733
- };
734
- }
735
- const PSL_INVALID_DEFAULT_SQL = "PSL_INVALID_DEFAULT_SQL";
736
- const TAGGED_LITERAL_CANONICALIZATION_CODES = {
737
- nul: "PSL_TAGGED_LITERAL_NUL",
738
- "too-large": "PSL_TAGGED_LITERAL_TOO_LARGE"
739
- };
740
- function readTaggedLiteral(literal, support, source) {
741
- const reject = (code, message) => ({
742
- ok: false,
743
- diagnostic: {
744
- code,
745
- message,
746
- ...source.at(literal.span)
747
- }
748
- });
749
- if (entryForTag(support, literal.tag) === void 0) return reject("PSL_UNKNOWN_LITERAL_TAG", `Unknown literal tag "${literal.tag}". Known tags: ${knownTags(support).join(", ")}.`);
750
- const { canonicalization } = literal;
751
- if (!canonicalization.ok) return reject(TAGGED_LITERAL_CANONICALIZATION_CODES[canonicalization.reason], describeTaggedLiteralFailure(canonicalization.reason));
752
- return {
753
- ok: true,
754
- written: {
755
- kind: "tag",
756
- tag: literal.tag,
757
- text: canonicalization.body
758
- }
759
- };
760
- }
761
- function rejectStrictListNullDefault(input) {
762
- if (input.field.elementOptional) return false;
763
- for (const arg of input.node.argList()?.args() ?? []) {
764
- const expression = arg.value();
765
- const list = expression ? ArrayLiteralAst.cast(expression.syntax) : void 0;
766
- for (const element of list?.elements() ?? []) {
767
- const identifier = IdentifierAst.cast(element.syntax);
768
- if (identifier?.token()?.text !== "null") continue;
769
- input.diagnostics.push({
770
- code: "PSL_INVALID_DEFAULT_APPLICABILITY",
771
- message: `Field "${input.modelName}.${input.field.name}" has strict list elements and cannot use null in a literal list default. Make the element type nullable or remove null from the default.`,
772
- ...diagnosticSource(input.sources, identifier.syntax).at()
773
- });
774
- return true;
775
- }
776
- }
777
- return false;
778
- }
779
- function lowerDefaultForField(input) {
780
- const node = getAttribute(input.field.attributes, "default")?.node;
781
- if (node === void 0) return {};
782
- const source = diagnosticSource(input.sources, node.syntax);
783
- const spec = sqlAttributeSpecs.field.default(fieldSpecContext({
784
- symbols: input.symbolTable,
785
- model: input.model,
786
- field: input.field,
787
- controlMutationDefaults: {
788
- defaultFunctionRegistry: input.defaultFunctionRegistry,
789
- dataTypeEntries: input.dataTypeSupport.entries
790
- }
791
- }));
792
- const interpreted = interpretFieldAttribute({
793
- symbols: input.symbolTable,
794
- node,
795
- spec,
796
- model: input.model,
797
- field: input.field,
798
- sources: input.sources,
799
- binder: input.binder,
800
- diagnostics: input.diagnostics
801
- });
802
- if (interpreted === void 0) return {};
803
- const value = interpreted.value;
804
- if (Array.isArray(value) && value.includes(null) && rejectStrictListNullDefault({
805
- ...input,
806
- node
807
- })) return {};
808
- if (value === null) {
809
- if (!input.field.optional) {
810
- input.diagnostics.push({
811
- code: "PSL_INVALID_DEFAULT_APPLICABILITY",
812
- message: `Field "${input.modelName}.${input.fieldName}" is non-nullable and cannot use null as its literal default. Make the field nullable or use a non-null default.`,
813
- ...source.at()
814
- });
815
- return {};
816
- }
817
- return { defaultValue: {
818
- kind: "literal",
819
- value: null,
820
- canonical: true
821
- } };
822
- }
823
- const readsListElements = (written) => input.isListColumn || input.field.list && written.kind === "list";
824
- const readAsLiteral = (written) => {
825
- const lowered = lowerDataTypeDefault({
826
- written,
827
- isList: readsListElements(written),
828
- column: input.columnDescriptor,
829
- codecLookup: input.codecLookup,
830
- support: input.dataTypeSupport,
831
- fieldPath: `${input.modelName}.${input.fieldName}`
832
- });
833
- if (!lowered.ok) {
834
- input.diagnostics.push({
835
- code: lowered.code,
836
- message: lowered.message,
837
- ...source.at()
838
- });
839
- return {};
840
- }
841
- let restoredValue = lowered.value;
842
- if (Array.isArray(value) && value.includes(null) && Array.isArray(lowered.value)) {
843
- let index = 0;
844
- const nonNullValues = lowered.value;
845
- restoredValue = value.map((element) => element === null ? null : nonNullValues[index++] ?? null);
846
- }
847
- if (input.valueObjectDefault !== void 0) {
848
- const mismatches = valueObjectDefaultMismatches({
849
- fieldPath: `${input.modelName}.${input.fieldName}`,
850
- value: restoredValue,
851
- list: input.field.list,
852
- nullable: input.field.optional,
853
- elementNullable: input.field.elementOptional,
854
- ...input.valueObjectDefault,
855
- codecLookup: input.codecLookup
856
- });
857
- for (const { code, message } of mismatches) input.diagnostics.push({
858
- code,
859
- message,
860
- ...source.at()
861
- });
862
- if (mismatches.length > 0) return {};
863
- }
864
- return { defaultValue: {
865
- kind: "literal",
866
- value: restoredValue,
867
- canonical: true
868
- } };
869
- };
870
- const writtenElement = (element) => {
871
- if (typeof element === "string") return {
872
- kind: "string",
873
- text: element
874
- };
875
- if (typeof element === "boolean") return {
876
- kind: "boolean",
877
- value: element
878
- };
879
- if ("text" in element) return {
880
- kind: "number",
881
- text: element.text
882
- };
883
- const literal = readTaggedLiteral(element, input.dataTypeSupport, source);
884
- if (!literal.ok) {
885
- input.diagnostics.push(literal.diagnostic);
886
- return { ok: false };
887
- }
888
- return literal.written;
889
- };
890
- const sqlExpressionDefault = (text, span) => {
891
- const reserved = reservedSqlDefaultBody(text);
892
- const refusal = reserved === void 0 ? checkSqlDefaultBody(text) : `Write @default(${reserved}()) instead of sql\`${reserved}()\`; ${reserved}() is a Prisma default function, not raw SQL.`;
893
- if (refusal !== void 0) {
894
- input.diagnostics.push({
895
- code: PSL_INVALID_DEFAULT_SQL,
896
- message: refusal,
897
- ...source.at(span)
898
- });
899
- return {};
900
- }
901
- return { defaultValue: {
902
- kind: "function",
903
- expression: text
904
- } };
905
- };
906
- if (input.columnDescriptor.valueSet !== void 0) {
907
- if (typeof value === "string") return { defaultValue: {
908
- kind: "literal",
909
- value
910
- } };
911
- if (Array.isArray(value)) {
912
- const members = value.filter((element) => element === null || typeof element === "string");
913
- if (members.length === value.length) return { defaultValue: {
914
- kind: "literal",
915
- value: members
916
- } };
917
- }
918
- }
919
- if (Array.isArray(value)) {
920
- const elements = [];
921
- for (const element of value) {
922
- if (element === null) continue;
923
- const written = writtenElement(element);
924
- if ("ok" in written) return {};
925
- elements.push(written);
926
- }
927
- return readAsLiteral({
928
- kind: "list",
929
- elements
930
- });
931
- }
932
- if (typeof value === "string") return readAsLiteral({
933
- kind: "string",
934
- text: value
935
- });
936
- if (typeof value === "boolean") return readAsLiteral({
937
- kind: "boolean",
938
- value
939
- });
940
- if ("text" in value) return readAsLiteral({
941
- kind: "number",
942
- text: value.text
943
- });
944
- if ("tag" in value) {
945
- const literal = readTaggedLiteral(value, input.dataTypeSupport, source);
946
- if (!literal.ok) {
947
- input.diagnostics.push(literal.diagnostic);
948
- return {};
949
- }
950
- const read = readValue(input.dataTypeSupport, literal.written, void 0);
951
- if (read.ok && read.typed.type === SQL_EXPRESSION_DATA_TYPE_ID) return sqlExpressionDefault(sqlTextFromCanonical(read.typed.value), value.span);
952
- return readAsLiteral(literal.written);
953
- }
954
- if (typeof value === "object") {
955
- const context = {
956
- sourceId: input.sources.sourceFileFor(node.syntax).filename,
957
- modelName: input.modelName,
958
- fieldName: input.fieldName,
959
- columnCodecId: input.columnDescriptor.codecId
960
- };
961
- const lowered = lowerDefaultFunctionWithRegistry({
962
- call: value,
963
- registry: input.defaultFunctionRegistry,
964
- context,
965
- source
966
- });
967
- if (!lowered.ok) {
968
- if (lowered.kind === "owned") input.diagnostics.push(lowered.diagnostic);
969
- else input.diagnostics.pushExternal(lowered.diagnostic);
970
- return {};
971
- }
972
- if (lowered.value.kind === "storage") return { defaultValue: lowered.value.defaultValue };
973
- const generatorDescriptor = input.generatorDescriptorById.get(lowered.value.generated.id);
974
- if (!generatorDescriptor) {
975
- input.diagnostics.push({
976
- code: "PSL_INVALID_DEFAULT_APPLICABILITY",
977
- message: `Default generator "${lowered.value.generated.id}" is not available in the composed mutation default registry.`,
978
- ...source.at(value.span)
979
- });
980
- return {};
981
- }
982
- if (generatorDescriptor.applicableCodecIds === void 0) {
983
- input.diagnostics.push({
984
- code: "PSL_INVALID_DEFAULT_APPLICABILITY",
985
- message: `Default generator "${generatorDescriptor.id}" is not applicable to "@default(...)" lowering. Use the corresponding field preset (e.g. \`temporal.${generatorDescriptor.id === "timestampNow" ? "updatedAt" : generatorDescriptor.id}()\`) instead.`,
986
- ...source.at(value.span)
987
- });
988
- return {};
989
- }
990
- if (!generatorDescriptor.applicableCodecIds.includes(input.columnDescriptor.codecId)) {
991
- input.diagnostics.push({
992
- code: "PSL_INVALID_DEFAULT_APPLICABILITY",
993
- message: `Default generator "${generatorDescriptor.id}" is not applicable to "${input.modelName}.${input.fieldName}" with codecId "${input.columnDescriptor.codecId}".`,
994
- ...source.at(value.span)
995
- });
996
- return {};
997
- }
998
- return { executionDefaults: { onCreate: lowered.value.generated } };
999
- }
1000
- return {};
1001
- }
1002
- function resolveColumnDescriptor(field, enumTypeDescriptors, namedTypeDescriptors, scalarColumnDescriptors) {
1003
- if (namedTypeDescriptors.has(field.typeName)) return namedTypeDescriptors.get(field.typeName);
1004
- if (enumTypeDescriptors.has(field.typeName)) return enumTypeDescriptors.get(field.typeName);
1005
- return scalarColumnDescriptors.get(field.typeName);
1006
- }
1007
- function lowerEnumDefaultForField(input) {
1008
- const { field, model, enumHandle, diagnostics } = input;
1009
- const node = getAttribute(field.attributes, "default")?.node;
1010
- if (node === void 0) return {};
1011
- if (enumHandle.enumMembers.length === 0) return {};
1012
- const interpreted = interpretFieldAttribute({
1013
- node,
1014
- spec: sqlAttributeSpecs.field.default(fieldSpecContext({
1015
- symbols: input.symbolTable,
1016
- model,
1017
- field,
1018
- controlMutationDefaults: {
1019
- defaultFunctionRegistry: input.defaultFunctionRegistry,
1020
- dataTypeEntries: input.dataTypeSupport.entries
1021
- }
1022
- })),
1023
- symbols: input.symbolTable,
1024
- model,
1025
- field,
1026
- sources: input.sources,
1027
- binder: input.binder,
1028
- diagnostics
1029
- });
1030
- if (interpreted === void 0) return {};
1031
- const member = interpreted.value;
1032
- if (Array.isArray(member)) {
1033
- if (member.includes(null) && rejectStrictListNullDefault({
1034
- ...input,
1035
- node
1036
- })) return {};
1037
- return { defaultValue: {
1038
- kind: "literal",
1039
- value: blindCast(member.map((entry) => entry === null ? null : enumHandle.enumMembers.find((candidate) => candidate.name === entry)?.value))
1040
- } };
1041
- }
1042
- invariant(typeof member === "string", "the enum @default grammar admits only member identifiers, so the parsed value is a string");
1043
- const match = enumHandle.enumMembers.find((m) => m.name === member);
1044
- if (!match) return {};
1045
- return { defaultValue: {
1046
- kind: "literal",
1047
- value: blindCast(match.value)
1048
- } };
1049
- }
1050
- const MODEL_COORDINATE_SEPARATOR = "\0";
1051
- function modelCoordinateKey(namespaceId, modelName) {
1052
- return `${namespaceId}${MODEL_COORDINATE_SEPARATOR}${modelName}`;
1053
- }
1054
- const REMOVED_ATTRIBUTE_RULES = /* @__PURE__ */ new Map([["updatedAt", {
1055
- hint: "Use `temporal.updatedAt()` as a field-preset call instead.",
1056
- suppressWhen: (field) => field.typeConstructor?.path[0] === "temporal"
1057
- }]]);
1058
- {
1059
- const overlap = [...REMOVED_ATTRIBUTE_RULES.keys()].filter((name) => Object.hasOwn(sqlAttributeSpecs.field, name));
1060
- if (overlap.length > 0) throw new InternalError(`Registered SQL field attributes and REMOVED_ATTRIBUTE_RULES must not overlap. Names in both: ${overlap.join(", ")}`);
1061
- }
1062
- function describeUnsupportedSqlAttribute(input) {
1063
- const namespaceContext = {
1064
- ...ifDefined("familyId", input.familyId),
1065
- ...ifDefined("targetId", input.targetId),
1066
- authoringContributions: input.authoringContributions
1067
- };
1068
- return ({ attribute, level, owner, field }) => {
1069
- if (owner.kind === "compositeType") return void 0;
1070
- if (level === "model") {
1071
- const source = diagnosticSource(input.sources, owner.node.syntax);
1072
- const uncomposedNamespace = checkUncomposedNamespace(attribute.name, input.composedExtensions, namespaceContext);
1073
- if (uncomposedNamespace) return uncomposedNamespaceDiagnostic({
1074
- subjectLabel: `Attribute "@@${attribute.name}"`,
1075
- namespace: uncomposedNamespace,
1076
- source,
1077
- span: attribute.span
1078
- });
1079
- return {
1080
- code: "PSL_UNSUPPORTED_MODEL_ATTRIBUTE",
1081
- message: `Model "${owner.name}" uses unsupported attribute "@@${attribute.name}"`,
1082
- ...source.at(attribute.span)
1083
- };
1084
- }
1085
- if (field === void 0) return void 0;
1086
- const source = diagnosticSource(input.sources, field.node.syntax);
1087
- if (attribute.name.startsWith("db.")) return {
1088
- code: "PSL_UNSUPPORTED_FIELD_ATTRIBUTE",
1089
- message: formatDbAttributeMigrationMessage(attribute),
1090
- ...source.at(attribute.span)
1091
- };
1092
- const uncomposedNamespace = checkUncomposedNamespace(attribute.name, input.composedExtensions, namespaceContext);
1093
- if (uncomposedNamespace) return uncomposedNamespaceDiagnostic({
1094
- subjectLabel: `Attribute "@${attribute.name}"`,
1095
- namespace: uncomposedNamespace,
1096
- source,
1097
- span: attribute.span
1098
- });
1099
- const baseMessage = `Field "${owner.name}.${field.name}" uses unsupported attribute "@${attribute.name}"`;
1100
- const removedRule = REMOVED_ATTRIBUTE_RULES.get(attribute.name);
1101
- return {
1102
- code: "PSL_UNSUPPORTED_FIELD_ATTRIBUTE",
1103
- message: removedRule && !removedRule.suppressWhen(field) ? `${baseMessage}. ${removedRule.hint}` : baseMessage,
1104
- ...source.at(attribute.span)
1105
- };
1106
- };
1107
- }
1108
- function extractFieldConstraintNames(input) {
1109
- const idAttribute = getAttribute(input.field.attributes, "id");
1110
- const uniqueAttribute = getAttribute(input.field.attributes, "unique");
1111
- const idNode = getAttribute(input.field.attributes, "id")?.node;
1112
- const idName = idNode === void 0 ? void 0 : interpretFieldAttribute({
1113
- node: idNode,
1114
- symbols: input.symbolTable,
1115
- spec: sqlAttributeSpecs.field.id(),
1116
- model: input.model,
1117
- field: input.field,
1118
- sources: input.sources,
1119
- binder: input.binder,
1120
- diagnostics: input.diagnostics
1121
- })?.map;
1122
- const uniqueNode = getAttribute(input.field.attributes, "unique")?.node;
1123
- return {
1124
- idAttribute,
1125
- uniqueAttribute,
1126
- idName,
1127
- uniqueName: uniqueNode === void 0 ? void 0 : interpretFieldAttribute({
1128
- node: uniqueNode,
1129
- symbols: input.symbolTable,
1130
- spec: sqlAttributeSpecs.field.unique(),
1131
- model: input.model,
1132
- field: input.field,
1133
- sources: input.sources,
1134
- binder: input.binder,
1135
- diagnostics: input.diagnostics
1136
- })?.map
1137
- };
1138
- }
1139
- /**
1140
- * Interprets a field's `@noCheck` attribute and resolves it against the
1141
- * column's shape: the bare form becomes every kind the shape derives, and a
1142
- * named kind that can never apply is a spec-validation diagnostic on the
1143
- * attribute node. Returns the concrete kinds in canonical ascending order —
1144
- * the only form the definition tree carries.
1145
- */
1146
- function lowerNoCheckForField(input) {
1147
- const node = getAttribute(input.field.attributes, "noCheck")?.node;
1148
- if (node === void 0) return void 0;
1149
- const interpreted = interpretFieldAttribute({
1150
- node,
1151
- spec: sqlAttributeSpecs.field.noCheck(),
1152
- symbols: input.symbolTable,
1153
- model: input.model,
1154
- field: input.field,
1155
- sources: input.sources,
1156
- binder: input.binder,
1157
- diagnostics: input.diagnostics
1158
- });
1159
- if (interpreted === void 0) return void 0;
1160
- const span = getAttribute(input.field.attributes, "noCheck")?.span ?? input.field.span;
1161
- const subject = `Field "${input.model.name}.${input.field.name}"`;
1162
- const derivable = [];
1163
- if (input.isListColumn && !input.elementNullable) derivable.push("elementNotNull");
1164
- if (input.isDomainEnum) derivable.push("membership");
1165
- const authored = [interpreted.first, interpreted.second].filter((kind) => kind === "membership" || kind === "elementNotNull");
1166
- if (authored.length === 0) {
1167
- if (derivable.length === 0) {
1168
- input.diagnostics.push({
1169
- code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
1170
- message: `${subject} @noCheck waives nothing — this column's shape derives no generated checks`,
1171
- ...diagnosticSource(input.sources, input.field.node.syntax).at(span)
1172
- });
1173
- return;
1174
- }
1175
- return derivable;
1176
- }
1177
- for (const kind of authored) if (!derivable.includes(kind)) {
1178
- const explanation = kind === "membership" ? "membership checks are derived only from enum value sets" : "element-non-null checks are derived only for lists whose elements are semantically non-null";
1179
- input.diagnostics.push({
1180
- code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
1181
- message: `${subject} @noCheck(${kind}) does not apply — ${explanation}`,
1182
- ...diagnosticSource(input.sources, input.field.node.syntax).at(span)
1183
- });
1184
- return;
1185
- }
1186
- return [...authored].sort();
1187
- }
1188
- function collectResolvedFields(input) {
1189
- const { model, symbolTable, enumTypeDescriptors, namedTypeDescriptors, valueObjectTypes, composedExtensions, authoringContributions, binder, familyId, targetId, defaultFunctionRegistry, dataTypeSupport, generatorDescriptorById, diagnostics, sources, scalarColumnDescriptors, enumHandles, capabilities, namespaceId, namespaceExtensionEntities, codecLookup } = input;
1190
- const resolvedFields = [];
1191
- const valueObjectStorageTypeName = authoringContributions?.valueObjectStorageType;
1192
- const declaredControlPolicy = getAttribute(model.attributes, "control")?.args.find((arg) => arg.kind === "positional")?.value.trim();
1193
- const modelDerivesChecks = declaredControlPolicy === void 0 || declaredControlPolicy === "managed";
1194
- for (const field of Object.values(model.fields)) {
1195
- const source = diagnosticSource(sources, field.node.syntax);
1196
- const fieldTypeReference = typeReferenceNode(field);
1197
- const fieldTypeResolution = fieldTypeReference === void 0 ? void 0 : binder.symbolForNode(fieldTypeReference);
1198
- const isModelField = fieldTypeResolution?.kind === "model";
1199
- if (field.list && isModelField) continue;
1200
- const relationAttribute = getAttribute(field.attributes, "relation");
1201
- if (isModelField && relationAttribute) continue;
1202
- if (field.typeContractSpaceId !== void 0 && relationAttribute) continue;
1203
- if (isModelField) continue;
1204
- const valueObjectName = fieldTypeResolution?.kind === "compositeType" ? fieldTypeResolution.symbol.name : void 0;
1205
- const isValueObjectField = valueObjectName !== void 0;
1206
- const isListField = field.list;
1207
- const isListColumn = storedAsListColumn({
1208
- list: isListField,
1209
- typedByValueObject: isValueObjectField
1210
- });
1211
- let descriptor;
1212
- let presetContributions;
1213
- const resolveInput = {
1214
- field,
1215
- binder,
1216
- enumTypeDescriptors,
1217
- namedTypeDescriptors,
1218
- scalarColumnDescriptors,
1219
- authoringContributions,
1220
- composedExtensions,
1221
- familyId,
1222
- targetId,
1223
- diagnostics,
1224
- sources,
1225
- entityLabel: `Field "${model.name}.${field.name}"`,
1226
- ...ifDefined("namespaceId", namespaceId),
1227
- ...ifDefined("namespaceExtensionEntities", namespaceExtensionEntities),
1228
- ...ifDefined("codecLookup", codecLookup)
1229
- };
1230
- if (isValueObjectField) {
1231
- if (valueObjectStorageTypeName === void 0) {
1232
- diagnostics.push({
1233
- code: "PSL_UNSUPPORTED_FIELD_TYPE",
1234
- message: `Field "${model.name}.${field.name}" is typed by the composite type "${field.typeName}", but the adapter of the stack declares no storage type for value objects, so the field has no column to be stored in.`,
1235
- ...source.at(field.span)
1236
- });
1237
- continue;
1238
- }
1239
- descriptor = scalarColumnDescriptors.get(valueObjectStorageTypeName);
1240
- if (descriptor === void 0) throw new InternalError(`The stack declares "${valueObjectStorageTypeName}" as its value-object storage type, but it is not one of the stack's scalar types; the control stack checks this when it is assembled.`);
1241
- } else if (isListField) {
1242
- if (capabilities["sql"]?.["scalarList"] !== true) {
1243
- diagnostics.push({
1244
- code: "PSL_SCALAR_LIST_UNSUPPORTED_TARGET",
1245
- message: `Field "${model.name}.${field.name}" is a scalar list, but target "${targetId}" does not support scalar lists (the adapter does not report the "scalarList" capability). Remove the list or author it against a target that supports scalar lists.`,
1246
- ...source.at(field.span)
1247
- });
1248
- continue;
1249
- }
1250
- const resolved = resolveFieldTypeDescriptor(resolveInput);
1251
- if (!resolved.ok) {
1252
- if (!resolved.alreadyReported && fieldTypeResolution?.kind !== "unresolved") diagnostics.push({
1253
- code: "PSL_UNSUPPORTED_FIELD_TYPE",
1254
- message: `Field "${model.name}.${field.name}" type "${field.typeName}" is not supported in SQL PSL provider v1`,
1255
- ...source.at(field.span)
1256
- });
1257
- continue;
1258
- }
1259
- if (resolved.presetContributions) {
1260
- diagnostics.push({
1261
- code: "PSL_PRESET_NOT_LIST",
1262
- message: `Field "${model.name}.${field.name}" uses a field-preset call as a list element type. Presets cannot be list elements; remove "[]" or use a scalar type.`,
1263
- ...source.at(field.span)
1264
- });
1265
- continue;
1266
- }
1267
- descriptor = resolved.descriptor;
1268
- } else {
1269
- const resolved = resolveFieldTypeDescriptor(resolveInput);
1270
- if (!resolved.ok) {
1271
- if (!resolved.alreadyReported && fieldTypeResolution?.kind !== "unresolved") diagnostics.push({
1272
- code: "PSL_UNSUPPORTED_FIELD_TYPE",
1273
- message: `Field "${model.name}.${field.name}" type "${field.typeName}" is not supported in SQL PSL provider v1`,
1274
- ...source.at(field.span)
1275
- });
1276
- continue;
1277
- }
1278
- descriptor = resolved.descriptor;
1279
- presetContributions = resolved.presetContributions;
1280
- }
1281
- if (!descriptor) continue;
1282
- if (presetContributions && field.optional) {
1283
- diagnostics.push({
1284
- code: "PSL_PRESET_NOT_OPTIONAL",
1285
- message: `Field "${model.name}.${field.name}" uses a field-preset call and cannot be optional. Remove "?" or use a different field type.`,
1286
- ...source.at(field.span)
1287
- });
1288
- continue;
1289
- }
1290
- const defaultAttribute = getAttribute(field.attributes, "default");
1291
- if (presetContributions && defaultAttribute) {
1292
- diagnostics.push({
1293
- code: "PSL_PRESET_AND_DEFAULT_CONFLICT",
1294
- message: `Field "${model.name}.${field.name}" uses a field-preset call and cannot also declare @default(...). The preset already specifies the default value.`,
1295
- ...source.at(defaultAttribute.span)
1296
- });
1297
- continue;
1298
- }
1299
- const enumHandle = enumHandles?.get(field.typeName);
1300
- const loweredDefault = defaultAttribute ? enumHandle ? lowerEnumDefaultForField({
1301
- modelName: model.name,
1302
- fieldName: field.name,
1303
- field,
1304
- model,
1305
- symbolTable,
1306
- sources: input.sources,
1307
- binder: input.binder,
1308
- enumHandle,
1309
- defaultFunctionRegistry,
1310
- dataTypeSupport,
1311
- diagnostics
1312
- }) : lowerDefaultForField({
1313
- modelName: model.name,
1314
- fieldName: field.name,
1315
- field,
1316
- model,
1317
- symbolTable,
1318
- sources: input.sources,
1319
- binder: input.binder,
1320
- columnDescriptor: descriptor,
1321
- isListColumn,
1322
- valueObjectDefault: valueObjectName === void 0 ? void 0 : {
1323
- valueObjectName,
1324
- types: valueObjectTypes
1325
- },
1326
- generatorDescriptorById,
1327
- defaultFunctionRegistry,
1328
- dataTypeSupport,
1329
- codecLookup,
1330
- diagnostics
1331
- }) : {};
1332
- const loweredOnCreate = loweredDefault.executionDefaults?.onCreate;
1333
- if (isListField && loweredDefault.defaultValue?.kind === "function" && loweredDefault.defaultValue.expression === "autoincrement()") {
1334
- diagnostics.push({
1335
- code: "PSL_LIST_AUTOINCREMENT_UNSUPPORTED",
1336
- message: `Field "${model.name}.${field.name}" is a list and cannot use autoincrement(); it is a Prisma marker for a sequence-backed scalar column, not SQL.`,
1337
- ...source.at(defaultAttribute?.span ?? field.span)
1338
- });
1339
- continue;
1340
- }
1341
- if (isListField && loweredOnCreate) {
1342
- const defaultExpression = defaultAttribute?.args.find((arg) => arg.kind === "positional")?.value.trim() ?? "this function";
1343
- diagnostics.push({
1344
- code: "PSL_LIST_EXECUTION_DEFAULT_UNSUPPORTED",
1345
- message: `Field "${model.name}.${field.name}" is a list and cannot use an execution default ("${defaultExpression}"). Lists have no per-element execution-default semantics; use a literal list @default or remove the default.`,
1346
- ...source.at(defaultAttribute?.span ?? field.span)
1347
- });
1348
- continue;
1349
- }
1350
- if (field.optional && loweredOnCreate) {
1351
- const generatorDescription = loweredOnCreate.kind === "generator" ? `"${loweredOnCreate.id}"` : "for this field";
1352
- diagnostics.push({
1353
- code: "PSL_INVALID_DEFAULT_FUNCTION_ARGUMENT",
1354
- message: `Field "${model.name}.${field.name}" cannot be optional when using execution default ${generatorDescription}. Remove "?" or use a storage default.`,
1355
- ...source.at(defaultAttribute?.span ?? field.span)
1356
- });
1357
- continue;
1358
- }
1359
- const mappedColumnName = storageName(field, input.physicalNames);
1360
- const { idAttribute, uniqueAttribute, idName, uniqueName } = extractFieldConstraintNames({
1361
- symbolTable: input.symbolTable,
1362
- model,
1363
- field,
1364
- sources: input.sources,
1365
- binder: input.binder,
1366
- diagnostics
1367
- });
1368
- let isIdField = Boolean(idAttribute);
1369
- if (idAttribute && isListField) {
1370
- diagnostics.push({
1371
- code: "PSL_LIST_ID_UNSUPPORTED",
1372
- message: `Field "${model.name}.${field.name}" is a list and cannot be a primary key. Remove @id; a list cannot be an identity column.`,
1373
- ...source.at(idAttribute.span)
1374
- });
1375
- continue;
1376
- }
1377
- if (idAttribute && field.optional) {
1378
- diagnostics.push({
1379
- code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
1380
- message: `Field "${model.name}.${field.name}" @id cannot be optional; primary key columns must be NOT NULL`,
1381
- ...source.at(idAttribute.span)
1382
- });
1383
- isIdField = false;
1384
- }
1385
- if (presetContributions && idAttribute && !presetContributions.id) {
1386
- diagnostics.push({
1387
- code: "PSL_PRESET_AND_ID_CONFLICT",
1388
- message: `Field "${model.name}.${field.name}" uses a field-preset call and cannot also declare @id. Use a preset that contributes id semantics, or drop @id.`,
1389
- ...source.at(idAttribute.span)
1390
- });
1391
- continue;
1392
- }
1393
- const fieldExecutionDefaults = presetContributions?.executionDefaults ?? loweredDefault.executionDefaults;
1394
- const fieldDefaultValue = presetContributions?.default ?? loweredDefault.defaultValue;
1395
- const noCheckKinds = modelDerivesChecks ? lowerNoCheckForField({
1396
- symbolTable: input.symbolTable,
1397
- model,
1398
- field,
1399
- sources: input.sources,
1400
- binder: input.binder,
1401
- isListColumn,
1402
- elementNullable: field.elementOptional,
1403
- isDomainEnum: enumHandle !== void 0,
1404
- diagnostics
1405
- }) : void 0;
1406
- resolvedFields.push({
1407
- field,
1408
- columnName: mappedColumnName,
1409
- descriptor,
1410
- nullable: presetContributions?.nullable ?? field.optional,
1411
- ...ifDefined("defaultValue", fieldDefaultValue),
1412
- ...ifDefined("executionDefaults", fieldExecutionDefaults),
1413
- isId: isIdField || Boolean(presetContributions?.id),
1414
- isUnique: Boolean(uniqueAttribute) || Boolean(presetContributions?.unique),
1415
- ...ifDefined("idName", idName),
1416
- ...ifDefined("uniqueName", uniqueName),
1417
- ...ifDefined("many", isListField ? true : void 0),
1418
- ...ifDefined("noCheck", noCheckKinds),
1419
- ...ifDefined("elementNullable", field.elementOptional ? true : void 0),
1420
- ...ifDefined("valueObjectTypeName", valueObjectName)
1421
- });
1422
- }
1423
- return resolvedFields;
21
+ //#region ../../../2-sql/2-authoring/contract-psl/dist/interpreter-C8cP92FD.mjs
22
+ function baseColumnDescriptor(resolution, enumTypeDescriptors) {
23
+ if (resolution?.kind === "block") return enumTypeDescriptors.get(resolution.symbol);
24
+ const scalar = bareTypeConstructorOf(resolution);
25
+ return scalar === void 0 ? void 0 : instantiateAuthoringTypeConstructor(scalar, []);
1424
26
  }
1425
27
  function validateNamedTypeAttributes(input) {
1426
28
  let hasUnsupportedNamedTypeAttribute = false;
@@ -1434,22 +36,6 @@ function validateNamedTypeAttributes(input) {
1434
36
  hasUnsupportedNamedTypeAttribute = true;
1435
37
  continue;
1436
38
  }
1437
- const uncomposedNamespace = checkUncomposedNamespace(attribute.name, input.composedExtensions, {
1438
- familyId: input.familyId,
1439
- targetId: input.targetId,
1440
- authoringContributions: input.authoringContributions
1441
- });
1442
- if (uncomposedNamespace) {
1443
- reportUncomposedNamespace({
1444
- subjectLabel: `Attribute "@${attribute.name}"`,
1445
- namespace: uncomposedNamespace,
1446
- source: input.source,
1447
- span: attribute.span,
1448
- diagnostics: input.diagnostics
1449
- });
1450
- hasUnsupportedNamedTypeAttribute = true;
1451
- continue;
1452
- }
1453
39
  input.diagnostics.push({
1454
40
  code: "PSL_UNSUPPORTED_NAMED_TYPE_ATTRIBUTE",
1455
41
  message: `Named type "${input.declaration.name}" uses unsupported attribute "${attribute.name}"`,
@@ -1464,6 +50,8 @@ function resolveNamedTypeDeclarations(input) {
1464
50
  const namedTypeDescriptors = /* @__PURE__ */ new Map();
1465
51
  for (const declaration of input.declarations) {
1466
52
  const source = diagnosticSource(input.source.sources, declaration.node.syntax);
53
+ const reference = typeReferenceNode(declaration);
54
+ const resolution = reference === void 0 ? void 0 : input.binder.symbolForNode(reference);
1467
55
  if (declaration.isConstructor) {
1468
56
  const typeConstructor = declaration.typeConstructor;
1469
57
  if (typeConstructor === void 0) {
@@ -1477,25 +65,17 @@ function resolveNamedTypeDeclarations(input) {
1477
65
  if (validateNamedTypeAttributes({
1478
66
  declaration,
1479
67
  source,
1480
- diagnostics: input.diagnostics,
1481
- composedExtensions: input.composedExtensions,
1482
- authoringContributions: input.authoringContributions,
1483
- familyId: input.familyId,
1484
- targetId: input.targetId
68
+ diagnostics: input.diagnostics
1485
69
  })) continue;
1486
- const helperPath = typeConstructor.path.join(".");
1487
- const descriptor = resolvePslTypeConstructorDescriptor({
1488
- call: typeConstructor,
1489
- authoringContributions: input.authoringContributions,
1490
- composedExtensions: input.composedExtensions,
1491
- familyId: input.familyId,
1492
- targetId: input.targetId,
1493
- diagnostics: input.diagnostics,
1494
- source,
1495
- unsupportedCode: "PSL_UNSUPPORTED_NAMED_TYPE_CONSTRUCTOR",
1496
- unsupportedMessage: `Named type "${declaration.name}" references unsupported constructor "${helperPath}"`
1497
- });
1498
- if (!descriptor) continue;
70
+ const descriptor = resolution?.kind === "contributedType" && resolution.symbol.descriptor.kind === "typeConstructor" ? resolution.symbol.descriptor : void 0;
71
+ if (!descriptor) {
72
+ input.diagnostics.push({
73
+ code: "PSL_UNSUPPORTED_NAMED_TYPE_CONSTRUCTOR",
74
+ message: `Named type "${declaration.name}" references unsupported constructor "${typeConstructor.path.join(".")}"`,
75
+ ...source.at(typeConstructor.span)
76
+ });
77
+ continue;
78
+ }
1499
79
  const storageType = instantiatePslTypeConstructor({
1500
80
  call: typeConstructor,
1501
81
  descriptor,
@@ -1504,7 +84,7 @@ function resolveNamedTypeDeclarations(input) {
1504
84
  entityLabel: `Named type "${declaration.name}"`
1505
85
  });
1506
86
  if (!storageType) continue;
1507
- namedTypeDescriptors.set(declaration.name, toNamedTypeFieldDescriptor(declaration.name, storageType));
87
+ namedTypeDescriptors.set(declaration, toNamedTypeFieldDescriptor(declaration.name, storageType));
1508
88
  storageTypeEntries.push([declaration.name, {
1509
89
  kind: "codec-instance",
1510
90
  codecId: storageType.codecId,
@@ -1522,7 +102,7 @@ function resolveNamedTypeDeclarations(input) {
1522
102
  });
1523
103
  continue;
1524
104
  }
1525
- const baseDescriptor = input.enumTypeDescriptors.get(baseType) ?? input.scalarColumnDescriptors.get(baseType);
105
+ const baseDescriptor = baseColumnDescriptor(resolution, input.enumTypeDescriptors);
1526
106
  if (!baseDescriptor) {
1527
107
  input.diagnostics.push({
1528
108
  code: "PSL_UNSUPPORTED_NAMED_TYPE_BASE",
@@ -1534,14 +114,10 @@ function resolveNamedTypeDeclarations(input) {
1534
114
  if (validateNamedTypeAttributes({
1535
115
  declaration,
1536
116
  source,
1537
- diagnostics: input.diagnostics,
1538
- composedExtensions: input.composedExtensions,
1539
- authoringContributions: input.authoringContributions,
1540
- familyId: input.familyId,
1541
- targetId: input.targetId
117
+ diagnostics: input.diagnostics
1542
118
  })) continue;
1543
119
  const descriptor = toNamedTypeFieldDescriptor(declaration.name, baseDescriptor);
1544
- namedTypeDescriptors.set(declaration.name, descriptor);
120
+ namedTypeDescriptors.set(declaration, descriptor);
1545
121
  storageTypeEntries.push([declaration.name, {
1546
122
  kind: "codec-instance",
1547
123
  codecId: baseDescriptor.codecId,
@@ -1874,22 +450,6 @@ function validateBackrelationFieldAttributes(input) {
1874
450
  let valid = true;
1875
451
  for (const attribute of input.field.attributes) {
1876
452
  if (attribute.name === "relation") continue;
1877
- const uncomposedNamespace = checkUncomposedNamespace(attribute.name, input.composedExtensions, {
1878
- familyId: input.familyId,
1879
- targetId: input.targetId,
1880
- authoringContributions: input.authoringContributions
1881
- });
1882
- if (uncomposedNamespace) {
1883
- reportUncomposedNamespace({
1884
- subjectLabel: `Attribute "@${attribute.name}"`,
1885
- namespace: uncomposedNamespace,
1886
- source,
1887
- span: attribute.span,
1888
- diagnostics: input.diagnostics
1889
- });
1890
- valid = false;
1891
- continue;
1892
- }
1893
453
  input.diagnostics.push({
1894
454
  code: "PSL_UNSUPPORTED_FIELD_ATTRIBUTE",
1895
455
  message: `Field "${input.modelName}.${input.field.name}" uses unsupported attribute "@${attribute.name}"`,
@@ -2112,7 +672,7 @@ function lowerExtensionBlocksForNamespace(blocks, ownerNamespaceId, entityTypesB
2112
672
  return rows;
2113
673
  }
2114
674
  function processEnumDeclarations(input) {
2115
- const enumHandles = {};
675
+ const enumHandles = /* @__PURE__ */ new Map();
2116
676
  const enumTypeDescriptors = /* @__PURE__ */ new Map();
2117
677
  if (input.enumBlocks.length === 0) return {
2118
678
  enumHandles,
@@ -2139,8 +699,8 @@ function processEnumDeclarations(input) {
2139
699
  sourceId: input.source.sources.sourceFileFor(symbol.node.syntax).filename
2140
700
  });
2141
701
  if (handle === void 0 || handle === null) continue;
2142
- enumHandles[envelope.name] = handle;
2143
- enumTypeDescriptors.set(envelope.name, {
702
+ enumHandles.set(symbol, handle);
703
+ enumTypeDescriptors.set(symbol, {
2144
704
  codecId: handle.codecId,
2145
705
  nativeType: handle.nativeType
2146
706
  });
@@ -2189,9 +749,7 @@ function buildModelNodeFromPsl(input) {
2189
749
  enumTypeDescriptors: input.enumTypeDescriptors,
2190
750
  namedTypeDescriptors: input.namedTypeDescriptors,
2191
751
  valueObjectTypes: input.valueObjectTypes,
2192
- composedExtensions: input.composedExtensions,
2193
752
  authoringContributions: input.authoringContributions,
2194
- familyId: input.familyId,
2195
753
  targetId: input.targetId,
2196
754
  defaultFunctionRegistry: input.defaultFunctionRegistry,
2197
755
  dataTypeSupport: input.dataTypeSupport,
@@ -2200,7 +758,7 @@ function buildModelNodeFromPsl(input) {
2200
758
  sources: input.sources,
2201
759
  binder: input.binder,
2202
760
  scalarColumnDescriptors: input.scalarColumnDescriptors,
2203
- ...ifDefined("enumHandles", input.enumHandles),
761
+ enumHandles: input.enumHandles,
2204
762
  capabilities: input.capabilities,
2205
763
  ...ifDefined("namespaceId", modelNamespaceId),
2206
764
  ...ifDefined("namespaceExtensionEntities", namespaceExtensionEntitiesForModel),
@@ -2234,11 +792,7 @@ function buildModelNodeFromPsl(input) {
2234
792
  field,
2235
793
  sources: input.sources,
2236
794
  binder: input.binder,
2237
- composedExtensions: input.composedExtensions,
2238
- authoringContributions: input.authoringContributions,
2239
- diagnostics,
2240
- familyId: input.familyId,
2241
- targetId: input.targetId
795
+ diagnostics
2242
796
  });
2243
797
  let relationName;
2244
798
  if (relationAttribute) {
@@ -2782,7 +1336,7 @@ function buildModelNodeFromPsl(input) {
2782
1336
  return {
2783
1337
  ...common,
2784
1338
  ...ifDefined("noCheck", resolvedField.noCheck),
2785
- ...ifDefined("enumTypeHandle", input.enumHandles?.get(resolvedField.field.typeName))
1339
+ ...ifDefined("enumTypeHandle", resolvedField.enumTypeHandle)
2786
1340
  };
2787
1341
  }),
2788
1342
  ...ifDefined("id", primaryKey),
@@ -2831,13 +1385,9 @@ function buildValueObjectNodes(input) {
2831
1385
  }
2832
1386
  const resolved = resolveFieldTypeDescriptor({
2833
1387
  field,
1388
+ resolution: fieldTypeResolution,
2834
1389
  enumTypeDescriptors: input.enumTypeDescriptors,
2835
1390
  namedTypeDescriptors: input.namedTypeDescriptors,
2836
- scalarColumnDescriptors: input.scalarColumnDescriptors,
2837
- authoringContributions: input.authoringContributions,
2838
- composedExtensions: input.composedExtensions,
2839
- familyId: input.familyId,
2840
- targetId: input.targetId,
2841
1391
  diagnostics,
2842
1392
  sources,
2843
1393
  entityLabel: `Field "${compositeType.name}.${field.name}"`,
@@ -2845,14 +1395,7 @@ function buildValueObjectNodes(input) {
2845
1395
  ...ifDefined("namespaceExtensionEntities", input.defaultNamespaceExtensionEntities),
2846
1396
  ...ifDefined("codecLookup", input.codecLookup)
2847
1397
  });
2848
- if (!resolved.ok) {
2849
- if (!resolved.alreadyReported && fieldTypeResolution?.kind !== "unresolved") diagnostics.push({
2850
- code: "PSL_UNSUPPORTED_FIELD_TYPE",
2851
- message: `Field "${compositeType.name}.${field.name}" type "${field.typeName}" is not supported`,
2852
- ...diagnosticSource(sources, field.node.syntax).at(field.span)
2853
- });
2854
- continue;
2855
- }
1398
+ if (!resolved.ok) continue;
2856
1399
  const { descriptor } = resolved;
2857
1400
  if (descriptor.valueSet !== void 0) {
2858
1401
  diagnostics.push({
@@ -2868,7 +1411,7 @@ function buildValueObjectNodes(input) {
2868
1411
  codecId: descriptor.codecId,
2869
1412
  ...ifDefined("typeParams", resolvedTypeParams(descriptor, input.namedTypes))
2870
1413
  },
2871
- ...ifDefined("enumTypeHandle", enumHandles.get(field.typeName))
1414
+ ...ifDefined("enumTypeHandle", fieldTypeResolution?.kind === "block" ? enumHandles.get(fieldTypeResolution.symbol) : void 0)
2872
1415
  });
2873
1416
  }
2874
1417
  return {
@@ -2877,7 +1420,12 @@ function buildValueObjectNodes(input) {
2877
1420
  };
2878
1421
  });
2879
1422
  }
2880
- function collectPolymorphismDeclarations(identities, symbols, sources, binder, diagnostics) {
1423
+ function isStringTyped(field, stringCodecId, binder) {
1424
+ const node = typeReferenceNode(field);
1425
+ const scalar = contributedTypeOf(node === void 0 ? void 0 : binder.symbolForNode(node), binder);
1426
+ return stringCodecId !== void 0 && scalar?.descriptor.kind === "typeConstructor" && scalar.descriptor.output.codecId === stringCodecId;
1427
+ }
1428
+ function collectPolymorphismDeclarations(identities, symbols, sources, binder, stringCodecId, diagnostics) {
2881
1429
  const discriminatorDeclarations = /* @__PURE__ */ new Map();
2882
1430
  const baseDeclarations = /* @__PURE__ */ new Map();
2883
1431
  for (const { model, key } of identities.values()) {
@@ -2896,7 +1444,7 @@ function collectPolymorphismDeclarations(identities, symbols, sources, binder, d
2896
1444
  if (parsed !== void 0) {
2897
1445
  const span = nodePslSpan(discriminatorNode.syntax, sources);
2898
1446
  const discField = model.fields[parsed.field];
2899
- if (discField && discField.typeName !== "String") diagnostics.push({
1447
+ if (discField && !isStringTyped(discField, stringCodecId, binder)) diagnostics.push({
2900
1448
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
2901
1449
  message: `Discriminator field "${parsed.field}" on model "${model.name}" must be of type String, but is "${discField.typeName}"`,
2902
1450
  ...source.at(span)
@@ -3192,14 +1740,6 @@ function relationTargetKindLabel(resolution) {
3192
1740
  default: return;
3193
1741
  }
3194
1742
  }
3195
- function replacedBySqlTypeVoice(diagnostic, composedExtensions, context) {
3196
- const data = diagnostic.data;
3197
- if (data?.["reference"] !== "type") return false;
3198
- if (data["constructorCall"] !== true) return false;
3199
- const name = data["name"];
3200
- if (typeof name !== "string") return false;
3201
- return replacesUnresolvedTypeVoice(name, composedExtensions, context);
3202
- }
3203
1743
  function interpretPslDocumentToSqlContract(input) {
3204
1744
  if (!input.target) throw new InternalError("PSL interpretation requires an explicit target context from composition.");
3205
1745
  if (!input.scalarColumnDescriptors) throw new InternalError("PSL interpretation requires composed scalar type descriptors.");
@@ -3207,34 +1747,10 @@ function interpretPslDocumentToSqlContract(input) {
3207
1747
  assertDefined(anchorDocument, "interpretPslDocumentToSqlContract requires at least one document");
3208
1748
  const source = diagnosticSource(input.sources, anchorDocument.syntax);
3209
1749
  const diagnostics = createPslDiagnosticCollector(input.sources);
3210
- const composedExtensionNames = new Set(input.composedExtensions ?? []);
3211
1750
  const modelAttributesByName = buildModelAttributesByName(input.authoringContributions);
3212
1751
  const contributedModelSpecs = modelAttributeSpecsFrom(modelAttributesByName);
3213
1752
  const composedPslBlockDescriptors = input.authoringContributions?.pslBlockDescriptors ?? {};
3214
- const { binder, diagnostics: binderDiagnostics } = createSqlBinder({
3215
- symbolTable: input.symbolTable,
3216
- sources: input.sources,
3217
- pslBlockDescriptors: composedPslBlockDescriptors,
3218
- authoringContributions: input.authoringContributions,
3219
- controlMutationDefaults: {
3220
- defaultFunctionRegistry: input.controlMutationDefaults?.defaultFunctionRegistry ?? /* @__PURE__ */ new Map(),
3221
- dataTypeEntries: input.authoringContributions?.dataTypes ?? {}
3222
- },
3223
- scalarColumnDescriptors: input.scalarColumnDescriptors,
3224
- contributedModelAttributeSpecs: contributedModelSpecs,
3225
- describeUnsupportedAttribute: describeUnsupportedSqlAttribute({
3226
- composedExtensions: composedExtensionNames,
3227
- authoringContributions: input.authoringContributions,
3228
- sources: input.sources,
3229
- familyId: input.target.familyId,
3230
- targetId: input.target.targetId
3231
- })
3232
- });
3233
- diagnostics.push(...binderDiagnostics.filter((diagnostic) => !replacedBySqlTypeVoice(diagnostic, composedExtensionNames, {
3234
- familyId: "sql",
3235
- targetId: input.target.targetId,
3236
- authoringContributions: input.authoringContributions
3237
- })));
1753
+ const { binder } = input;
3238
1754
  const { topLevel } = input.symbolTable;
3239
1755
  const namespaceSymbols = Object.values(topLevel.namespaces);
3240
1756
  validateNamespaceBlocksForSqlTarget({
@@ -3359,9 +1875,9 @@ function interpretPslDocumentToSqlContract(input) {
3359
1875
  },
3360
1876
  diagnostics
3361
1877
  });
3362
- const allEnumTypeDescriptors = new Map(enumResult.enumTypeDescriptors);
3363
- const validEnumHandles = { ...enumResult.enumHandles };
3364
- const enumHandlesByName = new Map(Object.entries(validEnumHandles));
1878
+ const allEnumTypeDescriptors = enumResult.enumTypeDescriptors;
1879
+ const enumHandles = enumResult.enumHandles;
1880
+ const validEnumHandles = Object.fromEntries(Array.from(enumHandles, ([symbol, handle]) => [symbol.name, handle]));
3365
1881
  const entityTypesByDiscriminator = buildEntityTypesByDiscriminator(input.authoringContributions);
3366
1882
  const authoringWarnings = [];
3367
1883
  const extensionEntityContext = {
@@ -3432,17 +1948,16 @@ function interpretPslDocumentToSqlContract(input) {
3432
1948
  });
3433
1949
  }
3434
1950
  }
3435
- const isScalarRefinement = (symbol) => !symbol.isConstructor && symbol.baseType !== void 0 && input.scalarColumnDescriptors.has(symbol.baseType);
1951
+ const isScalarRefinement = (symbol) => {
1952
+ const reference = typeReferenceNode(symbol);
1953
+ return !symbol.isConstructor && symbol.baseType !== void 0 && reference !== void 0 && bareTypeConstructorOf(binder.symbolForNode(reference)) !== void 0;
1954
+ };
3436
1955
  const allNamedTypes = Object.values(topLevel.namedTypes);
3437
1956
  const namedTypeResult = resolveNamedTypeDeclarations({
3438
1957
  declarations: [...allNamedTypes.filter(isScalarRefinement), ...allNamedTypes.filter((symbol) => !isScalarRefinement(symbol))],
3439
1958
  source,
1959
+ binder,
3440
1960
  enumTypeDescriptors: allEnumTypeDescriptors,
3441
- scalarColumnDescriptors: input.scalarColumnDescriptors,
3442
- composedExtensions,
3443
- familyId: input.target.familyId,
3444
- targetId: input.target.targetId,
3445
- authoringContributions: input.authoringContributions,
3446
1961
  diagnostics
3447
1962
  });
3448
1963
  const storageTypes = { ...namedTypeResult.storageTypes };
@@ -3455,14 +1970,9 @@ function interpretPslDocumentToSqlContract(input) {
3455
1970
  const valueObjects = buildValueObjectNodes({
3456
1971
  compositeTypes,
3457
1972
  enumTypeDescriptors: allEnumTypeDescriptors,
3458
- enumHandles: enumHandlesByName,
1973
+ enumHandles,
3459
1974
  namedTypeDescriptors: namedTypeResult.namedTypeDescriptors,
3460
1975
  namedTypes: namedTypeResult.storageTypes,
3461
- scalarColumnDescriptors: input.scalarColumnDescriptors,
3462
- composedExtensions,
3463
- familyId: input.target.familyId,
3464
- targetId: input.target.targetId,
3465
- authoringContributions: input.authoringContributions,
3466
1976
  diagnostics,
3467
1977
  sources: input.sources,
3468
1978
  defaultNamespaceId,
@@ -3482,7 +1992,6 @@ function interpretPslDocumentToSqlContract(input) {
3482
1992
  valueObjectTypes,
3483
1993
  enumTypeDescriptors: allEnumTypeDescriptors,
3484
1994
  namedTypeDescriptors: namedTypeResult.namedTypeDescriptors,
3485
- composedExtensions,
3486
1995
  composedExtensionContracts,
3487
1996
  familyId: input.target.familyId,
3488
1997
  targetId: input.target.targetId,
@@ -3495,7 +2004,7 @@ function interpretPslDocumentToSqlContract(input) {
3495
2004
  binder,
3496
2005
  symbolTable: input.symbolTable,
3497
2006
  diagnostics,
3498
- ...enumHandlesByName.size > 0 ? { enumHandles: enumHandlesByName } : {},
2007
+ enumHandles,
3499
2008
  capabilities: input.capabilities,
3500
2009
  ...namespaceExtensionEntities.size > 0 ? { namespaceExtensionEntities } : {},
3501
2010
  ...ifDefined("codecLookup", input.codecLookup),
@@ -3559,7 +2068,7 @@ function interpretPslDocumentToSqlContract(input) {
3559
2068
  namespaceId: resolvedNamespaceId,
3560
2069
  key: modelCoordinateKey(resolvedNamespaceId, model.name)
3561
2070
  }];
3562
- })), input.symbolTable, input.sources, binder, diagnostics);
2071
+ })), input.symbolTable, input.sources, binder, input.scalarColumnDescriptors.get("String")?.codecId, diagnostics);
3563
2072
  const stiVariantKeys = /* @__PURE__ */ new Set();
3564
2073
  for (const [variantKey, declaration] of baseDeclarations) if (!(getAttribute(declaration.model.attributes, "map") !== void 0)) stiVariantKeys.add(variantKey);
3565
2074
  for (const variantKey of stiVariantKeys) {
@@ -3645,6 +2154,6 @@ function interpretPslDocumentToSqlContract(input) {
3645
2154
  });
3646
2155
  }
3647
2156
  //#endregion
3648
- export { interpretPslDocumentToSqlContract as a, resolveFieldTypeDescriptor as c, indexFkRelations as i, buildEntityTypesByDiscriminator as n, normalizeReferentialAction as o, entryForTag as r, readDataTypeDefault as s, applyBackrelationCandidates as t };
2157
+ export { normalizeReferentialAction as a, interpretPslDocumentToSqlContract as i, buildEntityTypesByDiscriminator as n, indexFkRelations as r, applyBackrelationCandidates as t };
3649
2158
 
3650
- //# sourceMappingURL=interpreter-CkCfPqup-DF7bZvNM.mjs.map
2159
+ //# sourceMappingURL=interpreter-C8cP92FD-Co9RsuUU.mjs.map