@prisma/orm-family-sql 8.0.0-rc.14-dev.15 → 8.0.0-rc.14-dev.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/contract-prisma7__provider.mjs +15 -25
- package/dist/contract-prisma7__provider.mjs.map +1 -1
- package/dist/contract-psl.d.mts +6 -24
- package/dist/contract-psl.d.mts.map +1 -1
- package/dist/contract-psl.mjs +1 -1
- package/dist/contract-psl__attribute-specs.d.mts +11 -3
- package/dist/contract-psl__attribute-specs.d.mts.map +1 -1
- package/dist/contract-psl__attribute-specs.mjs +2 -2
- package/dist/contract-psl__provider.mjs +12 -5
- package/dist/contract-psl__provider.mjs.map +1 -1
- package/dist/{control-B8LE0HRq.mjs → control-DIVsNXHK.mjs} +4 -2
- package/dist/control-DIVsNXHK.mjs.map +1 -0
- package/dist/{control--13SHD7X.d.mts → control-nLCfcNhb.d.mts} +4 -1
- package/dist/control-nLCfcNhb.d.mts.map +1 -0
- package/dist/family.d.mts +1 -1
- package/dist/family.mjs +1 -1
- package/dist/family__control.d.mts +1 -1
- package/dist/family__control.mjs +1 -1
- package/dist/family__pack.mjs +1 -1
- package/dist/{interpreter-CkCfPqup-DF7bZvNM.mjs → interpreter-C8cP92FD-Co9RsuUU.mjs} +58 -1549
- package/dist/interpreter-C8cP92FD-Co9RsuUU.mjs.map +1 -0
- package/dist/psl-column-resolution-sNpXQygQ-BQr15EoR.d.mts +28 -0
- package/dist/psl-column-resolution-sNpXQygQ-BQr15EoR.d.mts.map +1 -0
- package/dist/psl-field-resolution-_o74AUE4-CKYNRnzL.mjs +1868 -0
- package/dist/psl-field-resolution-_o74AUE4-CKYNRnzL.mjs.map +1 -0
- package/package.json +18 -18
- package/dist/control--13SHD7X.d.mts.map +0 -1
- package/dist/control-B8LE0HRq.mjs.map +0 -1
- package/dist/interpreter-CkCfPqup-DF7bZvNM.mjs.map +0 -1
- package/dist/sql-attribute-specs-DxpHr9Fk-CeWmMP7y.mjs +0 -543
- 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 {
|
|
8
|
-
import {
|
|
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 {
|
|
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
|
|
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 {
|
|
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
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
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
|
|
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 =
|
|
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
|
|
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
|
|
2143
|
-
enumTypeDescriptors.set(
|
|
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
|
-
|
|
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
|
-
|
|
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",
|
|
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(
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
3363
|
-
const
|
|
3364
|
-
const
|
|
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) =>
|
|
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
|
|
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
|
-
|
|
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 {
|
|
2157
|
+
export { normalizeReferentialAction as a, interpretPslDocumentToSqlContract as i, buildEntityTypesByDiscriminator as n, indexFkRelations as r, applyBackrelationCandidates as t };
|
|
3649
2158
|
|
|
3650
|
-
//# sourceMappingURL=interpreter-
|
|
2159
|
+
//# sourceMappingURL=interpreter-C8cP92FD-Co9RsuUU.mjs.map
|