@prisma-next/sql-contract-psl 0.8.0 → 0.9.0-dev.2
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/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{interpreter-ijCjxhaU.mjs → interpreter-D_zkd14G.mjs} +63 -14
- package/dist/interpreter-D_zkd14G.mjs.map +1 -0
- package/dist/provider.mjs +1 -1
- package/package.json +12 -14
- package/src/interpreter.ts +64 -29
- package/src/psl-column-resolution.ts +29 -0
- package/dist/interpreter-ijCjxhaU.mjs.map +0 -1
package/src/interpreter.ts
CHANGED
|
@@ -11,9 +11,10 @@ import type {
|
|
|
11
11
|
} from '@prisma-next/contract/types';
|
|
12
12
|
import type {
|
|
13
13
|
AuthoringContributions,
|
|
14
|
-
|
|
14
|
+
AuthoringEntityContext,
|
|
15
|
+
AuthoringEntityTypeDescriptor,
|
|
15
16
|
} from '@prisma-next/framework-components/authoring';
|
|
16
|
-
import {
|
|
17
|
+
import { instantiateAuthoringEntityType } from '@prisma-next/framework-components/authoring';
|
|
17
18
|
import type { ExtensionPackRef, TargetPackRef } from '@prisma-next/framework-components/components';
|
|
18
19
|
import type {
|
|
19
20
|
ControlMutationDefaultRegistry,
|
|
@@ -29,7 +30,11 @@ import type {
|
|
|
29
30
|
PslModel,
|
|
30
31
|
PslNamedTypeDeclaration,
|
|
31
32
|
} from '@prisma-next/psl-parser';
|
|
32
|
-
import
|
|
33
|
+
import {
|
|
34
|
+
isPostgresEnumStorageEntry,
|
|
35
|
+
type PostgresEnumStorageEntry,
|
|
36
|
+
type StorageTypeInstance,
|
|
37
|
+
} from '@prisma-next/sql-contract/types';
|
|
33
38
|
import {
|
|
34
39
|
buildSqlContractFromDefinition,
|
|
35
40
|
type ForeignKeyNode,
|
|
@@ -55,7 +60,7 @@ import {
|
|
|
55
60
|
import type { ColumnDescriptor } from './psl-column-resolution';
|
|
56
61
|
import {
|
|
57
62
|
checkUncomposedNamespace,
|
|
58
|
-
|
|
63
|
+
getAuthoringEntity,
|
|
59
64
|
instantiatePslTypeConstructor,
|
|
60
65
|
reportUncomposedNamespace,
|
|
61
66
|
resolveDbNativeTypeAttribute,
|
|
@@ -158,17 +163,40 @@ function mapParserDiagnostics(document: ParsePslDocumentResult): ContractSourceD
|
|
|
158
163
|
interface ProcessEnumDeclarationsInput {
|
|
159
164
|
readonly enums: readonly PslEnum[];
|
|
160
165
|
readonly sourceId: string;
|
|
161
|
-
readonly
|
|
166
|
+
readonly enumEntityDescriptor: AuthoringEntityTypeDescriptor | undefined;
|
|
167
|
+
readonly entityContext: AuthoringEntityContext;
|
|
162
168
|
readonly diagnostics: ContractSourceDiagnostic[];
|
|
163
169
|
}
|
|
164
170
|
|
|
165
171
|
function processEnumDeclarations(input: ProcessEnumDeclarationsInput): {
|
|
166
|
-
readonly storageTypes: Record<string, StorageTypeInstance>;
|
|
172
|
+
readonly storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
|
|
167
173
|
readonly enumTypeDescriptors: Map<string, ColumnDescriptor>;
|
|
168
174
|
} {
|
|
169
|
-
const storageTypes: Record<string, StorageTypeInstance> = {};
|
|
175
|
+
const storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {};
|
|
170
176
|
const enumTypeDescriptors = new Map<string, ColumnDescriptor>();
|
|
171
177
|
|
|
178
|
+
if (input.enums.length === 0) {
|
|
179
|
+
return { storageTypes, enumTypeDescriptors };
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (!input.enumEntityDescriptor) {
|
|
183
|
+
// The PSL `enum X { … }` syntax only resolves when the active
|
|
184
|
+
// pack composition contributes an `enum` entity-type factory (the
|
|
185
|
+
// Postgres target pack does so today via
|
|
186
|
+
// `authoring.entityTypes.enum`). Without the contribution we
|
|
187
|
+
// surface a diagnostic per declaration rather than silently
|
|
188
|
+
// swallowing the syntax.
|
|
189
|
+
for (const enumDeclaration of input.enums) {
|
|
190
|
+
input.diagnostics.push({
|
|
191
|
+
code: 'PSL_UNSUPPORTED_NAMED_TYPE_BASE',
|
|
192
|
+
message: `Enum "${enumDeclaration.name}" requires the active target pack to contribute an enum entity-type helper`,
|
|
193
|
+
sourceId: input.sourceId,
|
|
194
|
+
span: enumDeclaration.span,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
return { storageTypes, enumTypeDescriptors };
|
|
198
|
+
}
|
|
199
|
+
|
|
172
200
|
for (const enumDeclaration of input.enums) {
|
|
173
201
|
const nativeType = parseMapName({
|
|
174
202
|
attribute: getAttribute(enumDeclaration.attributes, 'map'),
|
|
@@ -178,29 +206,29 @@ function processEnumDeclarations(input: ProcessEnumDeclarationsInput): {
|
|
|
178
206
|
entityLabel: `Enum "${enumDeclaration.name}"`,
|
|
179
207
|
span: enumDeclaration.span,
|
|
180
208
|
});
|
|
181
|
-
const
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
209
|
+
const values = enumDeclaration.values.map((value) => value.name);
|
|
210
|
+
const constructed = instantiateAuthoringEntityType(
|
|
211
|
+
'enum',
|
|
212
|
+
input.enumEntityDescriptor,
|
|
213
|
+
[{ name: enumDeclaration.name, nativeType, values }],
|
|
214
|
+
input.entityContext,
|
|
215
|
+
);
|
|
216
|
+
if (!isPostgresEnumStorageEntry(constructed)) {
|
|
217
|
+
input.diagnostics.push({
|
|
218
|
+
code: 'PSL_UNSUPPORTED_NAMED_TYPE_BASE',
|
|
219
|
+
message: `Enum "${enumDeclaration.name}": enum entity-type factory must return a PostgresEnumStorageEntry-shaped value (kind: 'postgres-enum')`,
|
|
220
|
+
sourceId: input.sourceId,
|
|
221
|
+
span: enumDeclaration.span,
|
|
222
|
+
});
|
|
223
|
+
continue;
|
|
224
|
+
}
|
|
191
225
|
const descriptor: ColumnDescriptor = {
|
|
192
|
-
codecId:
|
|
193
|
-
nativeType:
|
|
226
|
+
codecId: constructed.codecId,
|
|
227
|
+
nativeType: constructed.nativeType,
|
|
194
228
|
typeRef: enumDeclaration.name,
|
|
195
229
|
};
|
|
196
230
|
enumTypeDescriptors.set(enumDeclaration.name, descriptor);
|
|
197
|
-
storageTypes[enumDeclaration.name] =
|
|
198
|
-
codecId: enumStorageType.codecId,
|
|
199
|
-
nativeType: enumStorageType.nativeType,
|
|
200
|
-
typeParams: enumStorageType.typeParams ?? {
|
|
201
|
-
values: enumDeclaration.values.map((value) => value.name),
|
|
202
|
-
},
|
|
203
|
-
};
|
|
231
|
+
storageTypes[enumDeclaration.name] = constructed;
|
|
204
232
|
}
|
|
205
233
|
|
|
206
234
|
return { storageTypes, enumTypeDescriptors };
|
|
@@ -282,10 +310,10 @@ function validateNamedTypeAttributes(input: {
|
|
|
282
310
|
}
|
|
283
311
|
|
|
284
312
|
function resolveNamedTypeDeclarations(input: ResolveNamedTypeDeclarationsInput): {
|
|
285
|
-
readonly storageTypes: Record<string, StorageTypeInstance>;
|
|
313
|
+
readonly storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry>;
|
|
286
314
|
readonly namedTypeDescriptors: Map<string, ColumnDescriptor>;
|
|
287
315
|
} {
|
|
288
|
-
const storageTypes: Record<string, StorageTypeInstance> = {};
|
|
316
|
+
const storageTypes: Record<string, StorageTypeInstance | PostgresEnumStorageEntry> = {};
|
|
289
317
|
const namedTypeDescriptors = new Map<string, ColumnDescriptor>();
|
|
290
318
|
|
|
291
319
|
for (const declaration of input.declarations) {
|
|
@@ -336,6 +364,7 @@ function resolveNamedTypeDeclarations(input: ResolveNamedTypeDeclarationsInput):
|
|
|
336
364
|
toNamedTypeFieldDescriptor(declaration.name, storageType),
|
|
337
365
|
);
|
|
338
366
|
storageTypes[declaration.name] = {
|
|
367
|
+
kind: 'codec-instance',
|
|
339
368
|
codecId: storageType.codecId,
|
|
340
369
|
nativeType: storageType.nativeType,
|
|
341
370
|
typeParams: storageType.typeParams ?? {},
|
|
@@ -401,6 +430,7 @@ function resolveNamedTypeDeclarations(input: ResolveNamedTypeDeclarationsInput):
|
|
|
401
430
|
toNamedTypeFieldDescriptor(declaration.name, descriptor),
|
|
402
431
|
);
|
|
403
432
|
storageTypes[declaration.name] = {
|
|
433
|
+
kind: 'codec-instance',
|
|
404
434
|
codecId: descriptor.codecId,
|
|
405
435
|
nativeType: descriptor.nativeType,
|
|
406
436
|
typeParams: descriptor.typeParams ?? {},
|
|
@@ -411,6 +441,7 @@ function resolveNamedTypeDeclarations(input: ResolveNamedTypeDeclarationsInput):
|
|
|
411
441
|
const descriptor = toNamedTypeFieldDescriptor(declaration.name, baseDescriptor);
|
|
412
442
|
namedTypeDescriptors.set(declaration.name, descriptor);
|
|
413
443
|
storageTypes[declaration.name] = {
|
|
444
|
+
kind: 'codec-instance',
|
|
414
445
|
codecId: baseDescriptor.codecId,
|
|
415
446
|
nativeType: baseDescriptor.nativeType,
|
|
416
447
|
typeParams: {},
|
|
@@ -1284,7 +1315,11 @@ export function interpretPslDocumentToSqlContract(
|
|
|
1284
1315
|
const enumResult = processEnumDeclarations({
|
|
1285
1316
|
enums,
|
|
1286
1317
|
sourceId,
|
|
1287
|
-
|
|
1318
|
+
enumEntityDescriptor: getAuthoringEntity(input.authoringContributions, ['enum']),
|
|
1319
|
+
entityContext: {
|
|
1320
|
+
family: input.target.familyId,
|
|
1321
|
+
target: input.target.targetId,
|
|
1322
|
+
},
|
|
1288
1323
|
diagnostics,
|
|
1289
1324
|
});
|
|
1290
1325
|
|
|
@@ -2,6 +2,7 @@ import type { ContractSourceDiagnostic } from '@prisma-next/config/config-types'
|
|
|
2
2
|
import type { ColumnDefault, ExecutionMutationDefaultPhases } from '@prisma-next/contract/types';
|
|
3
3
|
import type {
|
|
4
4
|
AuthoringContributions,
|
|
5
|
+
AuthoringEntityTypeDescriptor,
|
|
5
6
|
AuthoringFieldPresetDescriptor,
|
|
6
7
|
AuthoringTypeConstructorDescriptor,
|
|
7
8
|
} from '@prisma-next/framework-components/authoring';
|
|
@@ -9,6 +10,7 @@ import {
|
|
|
9
10
|
hasRegisteredFieldNamespace,
|
|
10
11
|
instantiateAuthoringFieldPreset,
|
|
11
12
|
instantiateAuthoringTypeConstructor,
|
|
13
|
+
isAuthoringEntityTypeDescriptor,
|
|
12
14
|
isAuthoringFieldPresetDescriptor,
|
|
13
15
|
isAuthoringTypeConstructorDescriptor,
|
|
14
16
|
validateAuthoringHelperArguments,
|
|
@@ -71,6 +73,33 @@ export function getAuthoringTypeConstructor(
|
|
|
71
73
|
return isAuthoringTypeConstructorDescriptor(current) ? current : undefined;
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Walks `authoringContributions.entityTypes` segment-by-segment and returns
|
|
78
|
+
* the entity type descriptor at the resolved path, or `undefined` if no
|
|
79
|
+
* descriptor is registered.
|
|
80
|
+
*
|
|
81
|
+
* Used by the PSL interpreter to dispatch declarative entity-shaped
|
|
82
|
+
* declarations (`enum`, future `namespace { … }`, …) through the
|
|
83
|
+
* pack entity-type mechanism — the descriptor's `factory` (or
|
|
84
|
+
* `template`) materialises the IR-class instance without the
|
|
85
|
+
* interpreter knowing target-specific construction.
|
|
86
|
+
*/
|
|
87
|
+
export function getAuthoringEntity(
|
|
88
|
+
contributions: AuthoringContributions | undefined,
|
|
89
|
+
path: readonly string[],
|
|
90
|
+
): AuthoringEntityTypeDescriptor | undefined {
|
|
91
|
+
let current: unknown = contributions?.entityTypes;
|
|
92
|
+
|
|
93
|
+
for (const segment of path) {
|
|
94
|
+
if (typeof current !== 'object' || current === null || Array.isArray(current)) {
|
|
95
|
+
return undefined;
|
|
96
|
+
}
|
|
97
|
+
current = (current as Record<string, unknown>)[segment];
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return isAuthoringEntityTypeDescriptor(current) ? current : undefined;
|
|
101
|
+
}
|
|
102
|
+
|
|
74
103
|
/**
|
|
75
104
|
* Walks `authoringContributions.field` segment-by-segment and returns the field-preset descriptor at the resolved path, or `undefined` if no descriptor is registered.
|
|
76
105
|
*
|