@prisma-next/sql-contract-psl 0.12.0-dev.30 → 0.12.0-dev.32
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/README.md +10 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{interpreter-o0m3OC4P.mjs → interpreter-B75uZQde.mjs} +74 -2
- package/dist/interpreter-B75uZQde.mjs.map +1 -0
- package/dist/provider.d.mts +2 -0
- package/dist/provider.d.mts.map +1 -1
- package/dist/provider.mjs +3 -2
- package/dist/provider.mjs.map +1 -1
- package/package.json +12 -12
- package/src/interpreter.ts +26 -0
- package/src/provider.ts +6 -1
- package/src/psl-attribute-parsing.ts +66 -0
- package/dist/interpreter-o0m3OC4P.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -14,7 +14,7 @@ This keeps core/CLI source-agnostic while giving PSL-first SQL users a one-line
|
|
|
14
14
|
## Responsibilities
|
|
15
15
|
|
|
16
16
|
- Interpret `ParsePslDocumentResult` into SQL `Contract`
|
|
17
|
-
- Interpret generic PSL attributes into SQL contract semantics (`@id`, `@unique`, `@default`, `@relation`, `@map`, `@@map`)
|
|
17
|
+
- Interpret generic PSL attributes into SQL contract semantics (`@id`, `@unique`, `@default`, `@relation`, `@map`, `@@map`, `@@control`)
|
|
18
18
|
- Interpret SQL timestamp semantics: `DateTime @default(now())` (or the equivalent `temporal.createdAt()` field-preset call) as a storage default, and `temporal.updatedAt()` as an execution mutation default
|
|
19
19
|
- Lower shared constructor expressions in both `types {}` blocks and inline field positions (for example `ShortName = sql.String(length: 35)` and `embedding pgvector.Vector(length: 1536)?`)
|
|
20
20
|
- Lower supported default functions through composed registry inputs
|
|
@@ -71,12 +71,20 @@ Supported timestamp authoring surface:
|
|
|
71
71
|
- The Prisma-flavored `@updatedAt` attribute is not supported; references produce `PSL_UNSUPPORTED_FIELD_ATTRIBUTE` with a migration hint pointing at `temporal.updatedAt()`. The hint is suppressed when the field already declares any `temporal.*` preset.
|
|
72
72
|
- `@createdAt` is not supported as a PSL alias.
|
|
73
73
|
|
|
74
|
+
Model-level control policy:
|
|
75
|
+
|
|
76
|
+
- `@@control(<policy>)` lowers to the storage table's `control` field. The argument is one positional lowercase literal: `managed`, `tolerated`, `external`, or `observed`. Omit `@@control` to leave per-table control unset (the framework default applies at runtime).
|
|
77
|
+
|
|
78
|
+
Contract-level default (specifier options bag):
|
|
79
|
+
|
|
80
|
+
- `defaultControlPolicy` on `prismaContract(...)` sets `Contract.defaultControlPolicy` at load time when the interpreted contract does not already define one (source wins when both are present).
|
|
81
|
+
|
|
74
82
|
## Public API
|
|
75
83
|
|
|
76
84
|
- `@prisma-next/sql-contract-psl`
|
|
77
85
|
- `interpretPslDocumentToSqlContract({ document, target, scalarTypeDescriptors, authoringContributions?, controlMutationDefaults?, composedExtensionPacks? })`
|
|
78
86
|
- `@prisma-next/sql-contract-psl/provider`
|
|
79
|
-
- `prismaContract(schemaPath, { output?, target, scalarTypeDescriptors, authoringContributions?, controlMutationDefaults?, composedExtensionPacks? })`
|
|
87
|
+
- `prismaContract(schemaPath, { output?, target, defaultControlPolicy?, scalarTypeDescriptors, authoringContributions?, controlMutationDefaults?, composedExtensionPacks? })`
|
|
80
88
|
- Provider input is fully preassembled by composition layers (for example `@prisma-next/family-sql/control` helpers).
|
|
81
89
|
|
|
82
90
|
## Dependencies
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/psl-column-resolution.ts","../src/interpreter.ts"],"mappings":";;;;;;;;;;;KAyCY,gBAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA,GAAa,MAAM;AAAA;;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/psl-column-resolution.ts","../src/interpreter.ts"],"mappings":";;;;;;;;;;;KAyCY,gBAAA;EAAA,SACD,OAAA;EAAA,SACA,UAAA;EAAA,SACA,OAAA;EAAA,SACA,UAAA,GAAa,MAAM;AAAA;;;UC+Cb,sCAAA;EAAA,SACN,QAAA,EAAU,sBAAA;EAAA,SACV,MAAA,EAAQ,aAAA;EAAA,SACR,qBAAA,EAAuB,WAAA,SAAoB,gBAAA;EAAA,SAC3C,sBAAA;EAAA,SACA,yBAAA,YAAqC,gBAAA;EAAA,SACrC,uBAAA,GAA0B,yBAAA;EAAA,SAC1B,sBAAA,GAAyB,sBAAA;EDtDzB;;;AAAmB;;;;AC+C9B;;ED/CW,SCgEA,eAAA,IAAmB,KAAA,EAAO,uBAAA,KAA4B,SAAA;AAAA;AAAA,iBA4zCjD,iCAAA,CACd,KAAA,EAAO,sCAAA,GACN,MAAA,CAAO,QAAA,EAAU,yBAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as interpretPslDocumentToSqlContract } from "./interpreter-
|
|
1
|
+
import { t as interpretPslDocumentToSqlContract } from "./interpreter-B75uZQde.mjs";
|
|
2
2
|
export { interpretPslDocumentToSqlContract };
|
|
@@ -278,6 +278,56 @@ function findDuplicateFieldName(fieldNames) {
|
|
|
278
278
|
seen.add(name);
|
|
279
279
|
}
|
|
280
280
|
}
|
|
281
|
+
const CONTROL_POLICY_LITERAL_SET = new Set([
|
|
282
|
+
"managed",
|
|
283
|
+
"tolerated",
|
|
284
|
+
"external",
|
|
285
|
+
"observed"
|
|
286
|
+
]);
|
|
287
|
+
function isControlPolicyLiteral(value) {
|
|
288
|
+
return CONTROL_POLICY_LITERAL_SET.has(value);
|
|
289
|
+
}
|
|
290
|
+
function parseControlPolicyAttribute(input) {
|
|
291
|
+
if (input.attribute.args.filter((arg) => arg.kind === "named").length > 0) {
|
|
292
|
+
input.diagnostics.push({
|
|
293
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
294
|
+
message: "`@@control` does not accept named arguments; pass the policy positionally as `@@control(external)`.",
|
|
295
|
+
sourceId: input.sourceId,
|
|
296
|
+
span: input.attribute.span
|
|
297
|
+
});
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
const positionalArgs = getPositionalArguments(input.attribute);
|
|
301
|
+
if (positionalArgs.length === 0) {
|
|
302
|
+
input.diagnostics.push({
|
|
303
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
304
|
+
message: "`@@control` requires exactly one positional argument: `managed`, `tolerated`, `external`, or `observed`.",
|
|
305
|
+
sourceId: input.sourceId,
|
|
306
|
+
span: input.attribute.span
|
|
307
|
+
});
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (positionalArgs.length > 1) {
|
|
311
|
+
input.diagnostics.push({
|
|
312
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
313
|
+
message: `\`@@control\` accepts exactly one positional argument; got ${positionalArgs.length}.`,
|
|
314
|
+
sourceId: input.sourceId,
|
|
315
|
+
span: input.attribute.span
|
|
316
|
+
});
|
|
317
|
+
return;
|
|
318
|
+
}
|
|
319
|
+
const token = unquoteStringLiteral(positionalArgs[0] ?? "").trim();
|
|
320
|
+
if (!isControlPolicyLiteral(token)) {
|
|
321
|
+
input.diagnostics.push({
|
|
322
|
+
code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
|
|
323
|
+
message: `\`@@control\` argument \`${token}\` is not a known policy. Allowed: \`managed\`, \`tolerated\`, \`external\`, \`observed\`.`,
|
|
324
|
+
sourceId: input.sourceId,
|
|
325
|
+
span: input.attribute.span
|
|
326
|
+
});
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
return token;
|
|
330
|
+
}
|
|
281
331
|
function mapFieldNamesToColumns(input) {
|
|
282
332
|
const columns = [];
|
|
283
333
|
for (const fieldName of input.fieldNames) {
|
|
@@ -2128,6 +2178,8 @@ function buildModelNodeFromPsl(input) {
|
|
|
2128
2178
|
} : void 0;
|
|
2129
2179
|
const hasInlinePrimaryKey = primaryKey !== void 0;
|
|
2130
2180
|
let blockPrimaryKeyDeclared = false;
|
|
2181
|
+
let controlPolicyDeclared = false;
|
|
2182
|
+
let controlPolicy;
|
|
2131
2183
|
const resultBackrelationCandidates = [];
|
|
2132
2184
|
for (const field of model.fields) {
|
|
2133
2185
|
if (!field.list || !input.modelNames.has(field.typeName)) continue;
|
|
@@ -2194,6 +2246,25 @@ function buildModelNodeFromPsl(input) {
|
|
|
2194
2246
|
for (const modelAttribute of model.attributes) {
|
|
2195
2247
|
if (modelAttribute.name === "map") continue;
|
|
2196
2248
|
if (modelAttribute.name === "discriminator" || modelAttribute.name === "base") continue;
|
|
2249
|
+
if (modelAttribute.name === "control") {
|
|
2250
|
+
if (controlPolicyDeclared) {
|
|
2251
|
+
diagnostics.push({
|
|
2252
|
+
code: "PSL_DUPLICATE_ATTRIBUTE",
|
|
2253
|
+
message: `\`@@control\` declared more than once on model "${model.name}".`,
|
|
2254
|
+
sourceId,
|
|
2255
|
+
span: modelAttribute.span
|
|
2256
|
+
});
|
|
2257
|
+
continue;
|
|
2258
|
+
}
|
|
2259
|
+
controlPolicyDeclared = true;
|
|
2260
|
+
const parsed = parseControlPolicyAttribute({
|
|
2261
|
+
attribute: modelAttribute,
|
|
2262
|
+
sourceId,
|
|
2263
|
+
diagnostics
|
|
2264
|
+
});
|
|
2265
|
+
if (parsed !== void 0) controlPolicy = parsed;
|
|
2266
|
+
continue;
|
|
2267
|
+
}
|
|
2197
2268
|
const attributeLabel = `Model "${model.name}" @@${modelAttribute.name}`;
|
|
2198
2269
|
if (modelAttribute.name === "id") {
|
|
2199
2270
|
if (blockPrimaryKeyDeclared) {
|
|
@@ -2516,7 +2587,8 @@ function buildModelNodeFromPsl(input) {
|
|
|
2516
2587
|
...ifDefined("id", primaryKey),
|
|
2517
2588
|
...uniqueConstraints.length > 0 ? { uniques: uniqueConstraints } : {},
|
|
2518
2589
|
...indexNodes.length > 0 ? { indexes: indexNodes } : {},
|
|
2519
|
-
...foreignKeyNodes.length > 0 ? { foreignKeys: foreignKeyNodes } : {}
|
|
2590
|
+
...foreignKeyNodes.length > 0 ? { foreignKeys: foreignKeyNodes } : {},
|
|
2591
|
+
...ifDefined("control", controlPolicy)
|
|
2520
2592
|
},
|
|
2521
2593
|
fkRelationMetadata: resultFkRelationMetadata,
|
|
2522
2594
|
backrelationCandidates: resultBackrelationCandidates,
|
|
@@ -2979,4 +3051,4 @@ function interpretPslDocumentToSqlContract(input) {
|
|
|
2979
3051
|
//#endregion
|
|
2980
3052
|
export { interpretPslDocumentToSqlContract as t };
|
|
2981
3053
|
|
|
2982
|
-
//# sourceMappingURL=interpreter-
|
|
3054
|
+
//# sourceMappingURL=interpreter-B75uZQde.mjs.map
|