@prisma/orm-family-sql 8.0.0-rc.8-dev.17 → 8.0.0-rc.8-dev.18

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/dist/contract-psl.mjs +1 -1
  2. package/dist/contract-psl__attribute-specs.d.mts +77 -0
  3. package/dist/contract-psl__attribute-specs.d.mts.map +1 -0
  4. package/dist/contract-psl__attribute-specs.mjs +2 -0
  5. package/dist/contract-psl__provider.mjs +1 -1
  6. package/dist/contract-psl__provider.mjs.map +1 -1
  7. package/dist/{control-CyOPr5No.d.mts → control-CCQP4VFK.d.mts} +69 -1
  8. package/dist/control-CCQP4VFK.d.mts.map +1 -0
  9. package/dist/{control-CK4QOli_.mjs → control-DheONC4E.mjs} +4 -2
  10. package/dist/control-DheONC4E.mjs.map +1 -0
  11. package/dist/family.d.mts +2 -1
  12. package/dist/family.mjs +1 -1
  13. package/dist/family__control.d.mts +1 -1
  14. package/dist/family__control.mjs +1 -1
  15. package/dist/family__pack.d.mts +2 -249
  16. package/dist/family__pack.mjs +3 -1
  17. package/dist/family__pack.mjs.map +1 -1
  18. package/dist/index-DrcrDbOI-BlARY_6q.d.mts +536 -0
  19. package/dist/index-DrcrDbOI-BlARY_6q.d.mts.map +1 -0
  20. package/dist/{interpreter-RTglKUpM-B-iOLic9.mjs → interpreter-DQIdQxL1-DyNYhhep.mjs} +67 -296
  21. package/dist/interpreter-DQIdQxL1-DyNYhhep.mjs.map +1 -0
  22. package/dist/pack-Chia4J0l.d.mts +317 -0
  23. package/dist/pack-Chia4J0l.d.mts.map +1 -0
  24. package/dist/sql-attribute-specs-Cr8_u9ma-ENY2C_np.mjs +281 -0
  25. package/dist/sql-attribute-specs-Cr8_u9ma-ENY2C_np.mjs.map +1 -0
  26. package/package.json +18 -17
  27. package/dist/control-CK4QOli_.mjs.map +0 -1
  28. package/dist/control-CyOPr5No.d.mts.map +0 -1
  29. package/dist/family__pack.d.mts.map +0 -1
  30. package/dist/interpreter-RTglKUpM-B-iOLic9.mjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  import { t as deriveValueSetFromEntity } from "./value-set-derivation-hook-Di9JZ0X7.mjs";
2
+ import { a as interpretFieldAttribute, i as findModelAttributeNode, n as fieldSpecContext, o as interpretModelAttribute, r as findFieldAttributeNode, s as sqlAttributeSpecs, t as PSL_CHECK_ON_STI_VARIANT } from "./sql-attribute-specs-Cr8_u9ma-ENY2C_np.mjs";
2
3
  import { n as buildSqlContractFromDefinition } from "./derived-checks-BzL102Q0-0nIMlEux.mjs";
3
4
  import { structuredError } from "@prisma/orm-framework/utils/structured-error";
4
5
  import { hasRegisteredFieldNamespace, instantiateAuthoringEntityType, instantiateAuthoringFieldPreset, instantiateAuthoringTypeConstructor, isAuthoringEntityTypeDescriptor, isAuthoringFieldPresetDescriptor, isAuthoringModelAttributeDescriptor, isAuthoringPslBlockDescriptor, isAuthoringTypeConstructorDescriptor, validateAuthoringHelperArguments } from "@prisma/orm-framework/components/authoring";
@@ -7,10 +8,10 @@ import { InternalError } from "@prisma/orm-framework/utils/internal-error";
7
8
  import { crossRef } from "@prisma/orm-framework/contract/types";
8
9
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
9
10
  import { blindCast } from "@prisma/orm-framework/utils/casts";
10
- import { bool, entityRef, fieldAttribute, fieldRef, findBlockDescriptor, funcCall, identifier, interpretAttribute, keywordPslSpan, leafDiagnostic, list, modelAttribute, nodePslSpan, num, oneOf, optional, record, str } from "@prisma/orm-framework/psl-parser";
11
- import { assertDefined, invariant } from "@prisma/orm-framework/utils/assertions";
11
+ import { findBlockDescriptor, keywordPslSpan, nodePslSpan } from "@prisma/orm-framework/psl-parser";
12
12
  import { notOk, ok } from "@prisma/orm-framework/utils/result";
13
- //#region ../../../2-sql/2-authoring/contract-psl/dist/interpreter-RTglKUpM.mjs
13
+ import { assertDefined, invariant } from "@prisma/orm-framework/utils/assertions";
14
+ //#region ../../../2-sql/2-authoring/contract-psl/dist/interpreter-DQIdQxL1.mjs
14
15
  function contractError(code, message, options) {
15
16
  return structuredError(code, message, options);
16
17
  }
@@ -364,196 +365,6 @@ function mapPslHelperArgs(input) {
364
365
  }
365
366
  return mappedArgs;
366
367
  }
367
- function findModelAttributeNode(model, name) {
368
- for (const attribute of model.node.attributes()) if (attribute.name()?.isSimpleName(name) === true) return attribute;
369
- }
370
- function findFieldAttributeNode(field, name) {
371
- for (const attribute of field.node.attributes()) if (attribute.name()?.isSimpleName(name) === true) return attribute;
372
- }
373
- function buildModelInterpretCtx(input) {
374
- return {
375
- level: "model",
376
- sourceId: input.sourceId,
377
- sourceFile: input.sourceFile,
378
- selfModel: input.selfModel,
379
- resolveReferencedModel: () => void 0
380
- };
381
- }
382
- function buildFieldInterpretCtx(input) {
383
- return {
384
- level: "field",
385
- sourceId: input.sourceId,
386
- sourceFile: input.sourceFile,
387
- selfModel: input.selfModel,
388
- resolveReferencedModel: input.resolveReferencedModel ?? (() => void 0),
389
- field: input.field
390
- };
391
- }
392
- function interpretModelAttribute(input) {
393
- const result = interpretAttribute(input.node, input.spec, buildModelInterpretCtx({
394
- selfModel: input.model,
395
- sourceFile: input.sourceFile,
396
- sourceId: input.sourceId
397
- }));
398
- if (!result.ok) {
399
- for (const failure of result.failure) input.diagnostics.push(failure);
400
- return;
401
- }
402
- return result.value;
403
- }
404
- function interpretFieldAttribute(input) {
405
- const result = interpretAttribute(input.node, input.spec, buildFieldInterpretCtx({
406
- selfModel: input.model,
407
- field: input.field,
408
- sourceFile: input.sourceFile,
409
- sourceId: input.sourceId,
410
- resolveReferencedModel: input.resolveReferencedModel
411
- }));
412
- if (!result.ok) {
413
- for (const failure of result.failure) input.diagnostics.push(failure);
414
- return;
415
- }
416
- return result.value;
417
- }
418
- const mapModelSpec = modelAttribute("map", { positional: [{
419
- key: "name",
420
- type: str()
421
- }] });
422
- const mapFieldSpec = fieldAttribute("map", { positional: [{
423
- key: "name",
424
- type: str()
425
- }] });
426
- function buildDefaultSpec(input) {
427
- const literal = () => oneOf(str(), num(), bool());
428
- const funcArms = [...input.registry.entries()].map(([name, entry]) => funcCall(name, blindCast(entry.signature)));
429
- return fieldAttribute("default", { positional: [{
430
- key: "value",
431
- type: oneOf(...input.isList ? [list(literal()), ...funcArms] : [
432
- str(),
433
- num(),
434
- bool(),
435
- ...funcArms
436
- ])
437
- }] });
438
- }
439
- function buildEnumDefaultSpec(memberNames) {
440
- const [first, ...rest] = memberNames;
441
- return fieldAttribute("default", { positional: [{
442
- key: "member",
443
- type: oneOf(...[identifier(first), ...rest.map((name) => identifier(name))])
444
- }] });
445
- }
446
- const idFieldSpec = fieldAttribute("id", { named: { map: optional(str()) } });
447
- const uniqueFieldSpec = fieldAttribute("unique", { named: { map: optional(str()) } });
448
- const noCheckKindArgument = () => oneOf(identifier("membership"), identifier("elementNotNull"));
449
- /**
450
- * `@noCheck` waives generated CHECK constraints on one column: bare for every
451
- * kind the column's shape derives, or naming concrete kinds. Two optional
452
- * positional slots cover the whole kind vocabulary; a third argument is
453
- * necessarily a duplicate and fails as excess arity.
454
- */
455
- const noCheckFieldSpec = fieldAttribute("noCheck", {
456
- positional: [{
457
- key: "first",
458
- type: optional(noCheckKindArgument())
459
- }, {
460
- key: "second",
461
- type: optional(noCheckKindArgument())
462
- }],
463
- refine: (value, ctx, attributeNode) => {
464
- if (value.first !== void 0 && value.first === value.second) return [leafDiagnostic(ctx, attributeNode, "`@noCheck` names the same kind twice")];
465
- return [];
466
- }
467
- });
468
- const idModelSpec = modelAttribute("id", {
469
- positional: [{
470
- key: "fields",
471
- type: list(fieldRef("self"), {
472
- nonEmpty: true,
473
- unique: true
474
- })
475
- }],
476
- named: { map: optional(str()) }
477
- });
478
- const uniqueModelSpec = modelAttribute("unique", {
479
- positional: [{
480
- key: "fields",
481
- type: list(fieldRef("self"), {
482
- nonEmpty: true,
483
- unique: true
484
- })
485
- }],
486
- named: { map: optional(str()) }
487
- });
488
- const PSL_INDEX_FIELDS_XOR_EXPRESSION = "PSL_INDEX_FIELDS_XOR_EXPRESSION";
489
- const PSL_INDEX_EXPRESSION_REQUIRES_NAME = "PSL_INDEX_EXPRESSION_REQUIRES_NAME";
490
- const PSL_INDEX_NAME_XOR_MAP = "PSL_INDEX_NAME_XOR_MAP";
491
- const indexModelSpec = modelAttribute("index", {
492
- positional: [{
493
- key: "fields",
494
- type: optional(list(fieldRef("self"), {
495
- nonEmpty: true,
496
- unique: true
497
- }))
498
- }],
499
- named: {
500
- expression: optional(str()),
501
- where: optional(str()),
502
- unique: optional(bool()),
503
- name: optional(str()),
504
- map: optional(str()),
505
- type: optional(str()),
506
- options: optional(record(str()))
507
- },
508
- refine: (value, ctx, attributeNode) => {
509
- const diagnostics = [];
510
- if (value.fields === void 0 === (value.expression === void 0)) diagnostics.push(leafDiagnostic(ctx, attributeNode, "`@@index` requires exactly one of a fields list or an `expression` argument", PSL_INDEX_FIELDS_XOR_EXPRESSION));
511
- if (value.expression !== void 0 && value.name === void 0 && value.map === void 0) diagnostics.push(leafDiagnostic(ctx, attributeNode, "`@@index` with an `expression` argument requires a `name` or `map` argument (a default name cannot be derived from an expression)", PSL_INDEX_EXPRESSION_REQUIRES_NAME));
512
- if (value.name !== void 0 && value.map !== void 0) diagnostics.push(leafDiagnostic(ctx, attributeNode, "`@@index` takes at most one of `name` and `map`", PSL_INDEX_NAME_XOR_MAP));
513
- if (value.options !== void 0 && value.type === void 0) diagnostics.push(leafDiagnostic(ctx, attributeNode, "`@@index` options argument requires a type argument"));
514
- return diagnostics;
515
- }
516
- });
517
- const PSL_CHECK_REQUIRES_NAME_OR_MAP = "PSL_CHECK_REQUIRES_NAME_OR_MAP";
518
- const PSL_CHECK_NAME_XOR_MAP = "PSL_CHECK_NAME_XOR_MAP";
519
- const PSL_CHECK_EXPRESSION_EMPTY = "PSL_CHECK_EXPRESSION_EMPTY";
520
- /**
521
- * A single-table-inheritance variant (`@@base` with no own `@@map`) shares
522
- * its base model's storage table and has no table of its own to declare a
523
- * check on — raised from {@link interpretPslDocumentToSqlContract}, not from
524
- * this spec's own `refine`, because the rule needs the model's `@@base`
525
- * declaration, which a single attribute's `refine` cannot see.
526
- */
527
- const PSL_CHECK_ON_STI_VARIANT = "PSL_CHECK_ON_STI_VARIANT";
528
- const checkModelSpec = modelAttribute("check", {
529
- named: {
530
- expression: str(),
531
- name: optional(str()),
532
- map: optional(str())
533
- },
534
- refine: (value, ctx, attributeNode) => {
535
- const diagnostics = [];
536
- if (value.expression.trim().length === 0) diagnostics.push(leafDiagnostic(ctx, attributeNode, "`@@check` expression must not be empty — an empty predicate is not a constraint", PSL_CHECK_EXPRESSION_EMPTY));
537
- if (value.name === void 0 && value.map === void 0) diagnostics.push(leafDiagnostic(ctx, attributeNode, "`@@check` requires a `name` or `map` argument (a default name cannot be derived — a check has no column tuple to name itself after)", PSL_CHECK_REQUIRES_NAME_OR_MAP));
538
- if (value.name !== void 0 && value.map !== void 0) diagnostics.push(leafDiagnostic(ctx, attributeNode, "`@@check` takes at most one of `name` and `map`", PSL_CHECK_NAME_XOR_MAP));
539
- return diagnostics;
540
- }
541
- });
542
- const controlModelSpec = modelAttribute("control", { positional: [{
543
- key: "policy",
544
- type: oneOf(identifier("managed"), identifier("tolerated"), identifier("external"), identifier("observed"))
545
- }] });
546
- const discriminatorModelSpec = modelAttribute("discriminator", { positional: [{
547
- key: "field",
548
- type: fieldRef("self")
549
- }] });
550
- const baseModelSpec = modelAttribute("base", { positional: [{
551
- key: "base",
552
- type: entityRef()
553
- }, {
554
- key: "value",
555
- type: str()
556
- }] });
557
368
  function toNamedTypeFieldDescriptor(typeRef, descriptor) {
558
369
  return {
559
370
  codecId: descriptor.codecId,
@@ -951,10 +762,12 @@ function lowerDefaultForField(input) {
951
762
  if (node === void 0) return {};
952
763
  const interpreted = interpretFieldAttribute({
953
764
  node,
954
- spec: buildDefaultSpec({
955
- isList: input.isList ?? false,
956
- registry: input.defaultFunctionRegistry
957
- }),
765
+ spec: sqlAttributeSpecs.field.default(fieldSpecContext({
766
+ symbols: input.symbolTable,
767
+ model: input.model,
768
+ field: input.field,
769
+ controlMutationDefaults: input.defaultFunctionRegistry
770
+ })),
958
771
  model: input.model,
959
772
  field: input.field,
960
773
  sourceFile: input.sourceFile,
@@ -1027,11 +840,15 @@ function lowerEnumDefaultForField(input) {
1027
840
  const { field, model, sourceFile, enumHandle, sourceId, diagnostics } = input;
1028
841
  const node = findFieldAttributeNode(field, "default");
1029
842
  if (node === void 0) return {};
1030
- const [firstMember, ...restMembers] = enumHandle.enumMembers.map((m) => m.name);
1031
- if (firstMember === void 0) return {};
843
+ if (enumHandle.enumMembers.length === 0) return {};
1032
844
  const interpreted = interpretFieldAttribute({
1033
845
  node,
1034
- spec: buildEnumDefaultSpec([firstMember, ...restMembers]),
846
+ spec: sqlAttributeSpecs.field.default(fieldSpecContext({
847
+ symbols: input.symbolTable,
848
+ model,
849
+ field,
850
+ controlMutationDefaults: input.defaultFunctionRegistry
851
+ })),
1035
852
  model,
1036
853
  field,
1037
854
  sourceFile,
@@ -1039,7 +856,8 @@ function lowerEnumDefaultForField(input) {
1039
856
  diagnostics
1040
857
  });
1041
858
  if (interpreted === void 0) return {};
1042
- const member = interpreted.member;
859
+ const member = interpreted.value;
860
+ invariant(typeof member === "string", "the enum @default grammar admits only member identifiers, so the parsed value is a string");
1043
861
  const match = enumHandle.enumMembers.find((m) => m.name === member);
1044
862
  if (!match) return {};
1045
863
  return { defaultValue: {
@@ -1051,25 +869,17 @@ const MODEL_COORDINATE_SEPARATOR = "\0";
1051
869
  function modelCoordinateKey(namespaceId, modelName) {
1052
870
  return `${namespaceId}${MODEL_COORDINATE_SEPARATOR}${modelName}`;
1053
871
  }
1054
- const BUILTIN_FIELD_ATTRIBUTE_NAMES = /* @__PURE__ */ new Set([
1055
- "id",
1056
- "unique",
1057
- "default",
1058
- "relation",
1059
- "map",
1060
- "noCheck"
1061
- ]);
1062
872
  const REMOVED_ATTRIBUTE_RULES = /* @__PURE__ */ new Map([["updatedAt", {
1063
873
  hint: "Use `temporal.updatedAt()` as a field-preset call instead.",
1064
874
  suppressWhen: (field) => field.typeConstructor?.path[0] === "temporal"
1065
875
  }]]);
1066
876
  {
1067
- const overlap = [...REMOVED_ATTRIBUTE_RULES.keys()].filter((name) => BUILTIN_FIELD_ATTRIBUTE_NAMES.has(name));
1068
- if (overlap.length > 0) throw new InternalError(`BUILTIN_FIELD_ATTRIBUTE_NAMES and REMOVED_ATTRIBUTE_RULES must not overlap. Names in both: ${overlap.join(", ")}`);
877
+ const overlap = [...REMOVED_ATTRIBUTE_RULES.keys()].filter((name) => Object.hasOwn(sqlAttributeSpecs.field, name));
878
+ if (overlap.length > 0) throw new InternalError(`Registered SQL field attributes and REMOVED_ATTRIBUTE_RULES must not overlap. Names in both: ${overlap.join(", ")}`);
1069
879
  }
1070
880
  function validateFieldAttributes(input) {
1071
881
  for (const attribute of input.field.attributes) {
1072
- if (BUILTIN_FIELD_ATTRIBUTE_NAMES.has(attribute.name)) continue;
882
+ if (Object.hasOwn(sqlAttributeSpecs.field, attribute.name)) continue;
1073
883
  if (attribute.name.startsWith("db.")) {
1074
884
  input.diagnostics.push({
1075
885
  code: "PSL_UNSUPPORTED_FIELD_ATTRIBUTE",
@@ -1111,7 +921,7 @@ function extractFieldConstraintNames(input) {
1111
921
  const idNode = findFieldAttributeNode(input.field, "id");
1112
922
  const idName = idNode === void 0 ? void 0 : interpretFieldAttribute({
1113
923
  node: idNode,
1114
- spec: idFieldSpec,
924
+ spec: sqlAttributeSpecs.field.id(),
1115
925
  model: input.model,
1116
926
  field: input.field,
1117
927
  sourceFile: input.sourceFile,
@@ -1125,7 +935,7 @@ function extractFieldConstraintNames(input) {
1125
935
  idName,
1126
936
  uniqueName: uniqueNode === void 0 ? void 0 : interpretFieldAttribute({
1127
937
  node: uniqueNode,
1128
- spec: uniqueFieldSpec,
938
+ spec: sqlAttributeSpecs.field.unique(),
1129
939
  model: input.model,
1130
940
  field: input.field,
1131
941
  sourceFile: input.sourceFile,
@@ -1146,7 +956,7 @@ function lowerNoCheckForField(input) {
1146
956
  if (node === void 0) return void 0;
1147
957
  const interpreted = interpretFieldAttribute({
1148
958
  node,
1149
- spec: noCheckFieldSpec,
959
+ spec: sqlAttributeSpecs.field.noCheck(),
1150
960
  model: input.model,
1151
961
  field: input.field,
1152
962
  sourceFile: input.sourceFile,
@@ -1185,7 +995,7 @@ function lowerNoCheckForField(input) {
1185
995
  return [...authored].sort();
1186
996
  }
1187
997
  function collectResolvedFields(input) {
1188
- const { model, mapping, enumTypeDescriptors, namedTypeDescriptors, modelNames, compositeTypeNames, composedExtensions, authoringContributions, familyId, targetId, defaultFunctionRegistry, generatorDescriptorById, diagnostics, sourceId, scalarColumnDescriptors, enumHandles, capabilities, namespaceId, namespaceExtensionEntities, codecLookup } = input;
998
+ const { model, symbolTable, mapping, enumTypeDescriptors, namedTypeDescriptors, modelNames, compositeTypeNames, composedExtensions, authoringContributions, familyId, targetId, defaultFunctionRegistry, generatorDescriptorById, diagnostics, sourceId, scalarColumnDescriptors, enumHandles, capabilities, namespaceId, namespaceExtensionEntities, codecLookup } = input;
1189
999
  const resolvedFields = [];
1190
1000
  const valueObjectStorageTypeName = authoringContributions?.valueObjectStorageType;
1191
1001
  const declaredControlPolicy = getAttribute(model.attributes, "control")?.args.find((arg) => arg.kind === "positional")?.value.trim();
@@ -1300,22 +1110,24 @@ function collectResolvedFields(input) {
1300
1110
  fieldName: field.name,
1301
1111
  field,
1302
1112
  model,
1113
+ symbolTable,
1303
1114
  sourceFile: input.sourceFile,
1304
1115
  enumHandle,
1305
1116
  sourceId,
1117
+ defaultFunctionRegistry,
1306
1118
  diagnostics
1307
1119
  }) : lowerDefaultForField({
1308
1120
  modelName: model.name,
1309
1121
  fieldName: field.name,
1310
1122
  field,
1311
1123
  model,
1124
+ symbolTable,
1312
1125
  sourceFile: input.sourceFile,
1313
1126
  columnDescriptor: descriptor,
1314
1127
  generatorDescriptorById,
1315
1128
  sourceId,
1316
1129
  defaultFunctionRegistry,
1317
- diagnostics,
1318
- isList: isListField
1130
+ diagnostics
1319
1131
  }) : {};
1320
1132
  const loweredOnCreate = loweredDefault.executionDefaults?.onCreate;
1321
1133
  const loweredFunctionDefault = loweredDefault.defaultValue?.kind === "function";
@@ -1411,7 +1223,7 @@ function buildModelMappings(modelEntries, defaultNamespaceId, diagnostics, sourc
1411
1223
  const mapNode = findModelAttributeNode(model, "map");
1412
1224
  const tableName = mapNode === void 0 ? lowerFirst(model.name) : interpretModelAttribute({
1413
1225
  node: mapNode,
1414
- spec: mapModelSpec,
1226
+ spec: sqlAttributeSpecs.model.map(),
1415
1227
  model,
1416
1228
  sourceFile,
1417
1229
  sourceId,
@@ -1422,7 +1234,7 @@ function buildModelMappings(modelEntries, defaultNamespaceId, diagnostics, sourc
1422
1234
  const fieldMapNode = findFieldAttributeNode(field, "map");
1423
1235
  const columnName = fieldMapNode === void 0 ? field.name : interpretFieldAttribute({
1424
1236
  node: fieldMapNode,
1425
- spec: mapFieldSpec,
1237
+ spec: sqlAttributeSpecs.field.map(),
1426
1238
  model,
1427
1239
  field,
1428
1240
  sourceFile,
@@ -1593,52 +1405,6 @@ function fkRelationPairKey(declaringModelName, targetModelName) {
1593
1405
  function normalizeReferentialAction(actionToken) {
1594
1406
  return REFERENTIAL_ACTION_MAP[actionToken];
1595
1407
  }
1596
- function relationInvariants(parsed, ctx) {
1597
- if (parsed.fields !== void 0 !== (parsed.references !== void 0)) return [{
1598
- code: "PSL_INVALID_ATTRIBUTE_SYNTAX",
1599
- message: `Relation field "${ctx.selfModel.name}.${ctx.field?.name ?? ""}" requires fields and references arguments`,
1600
- sourceId: ctx.sourceId,
1601
- span: relationAttributeSpan(ctx)
1602
- }];
1603
- return [];
1604
- }
1605
- const sqlRelation = fieldAttribute("relation", {
1606
- positional: [{
1607
- key: "name",
1608
- type: optional(str())
1609
- }],
1610
- named: {
1611
- name: optional(str()),
1612
- fields: optional(list(fieldRef("self"), {
1613
- nonEmpty: true,
1614
- unique: true
1615
- })),
1616
- references: optional(list(fieldRef("referenced"), {
1617
- nonEmpty: true,
1618
- unique: true
1619
- })),
1620
- map: optional(str()),
1621
- onDelete: optional(oneOf(identifier("NoAction"), identifier("Restrict"), identifier("Cascade"), identifier("SetNull"), identifier("SetDefault"))),
1622
- onUpdate: optional(oneOf(identifier("NoAction"), identifier("Restrict"), identifier("Cascade"), identifier("SetNull"), identifier("SetDefault"))),
1623
- /**
1624
- * Opts a foreign key out of its default backing index
1625
- * (`index: false`). Omitted (the default) keeps the FK's derived
1626
- * backing-index expectation; only `false` is meaningful — there is no
1627
- * `index: true` spelling since that is already the default.
1628
- */
1629
- index: optional(bool())
1630
- },
1631
- refine: relationInvariants
1632
- });
1633
- function relationAttributeSpan(ctx) {
1634
- const field = ctx.field;
1635
- if (field !== void 0) {
1636
- const node = findFieldAttributeNode(field, "relation");
1637
- if (node !== void 0) return nodePslSpan(node.syntax, ctx.sourceFile);
1638
- return field.span;
1639
- }
1640
- return ctx.selfModel.span;
1641
- }
1642
1408
  function resolveReferencedModel(symbols, field) {
1643
1409
  const topLevel = symbols.topLevel.models[field.typeName];
1644
1410
  if (topLevel !== void 0) return topLevel;
@@ -1652,7 +1418,7 @@ function interpretRelationAttribute(input) {
1652
1418
  if (node === void 0) return void 0;
1653
1419
  return interpretFieldAttribute({
1654
1420
  node,
1655
- spec: sqlRelation,
1421
+ spec: sqlAttributeSpecs.field.relation(),
1656
1422
  model: input.selfModel,
1657
1423
  field: input.field,
1658
1424
  sourceFile: input.sourceFile,
@@ -2290,6 +2056,7 @@ function buildModelNodeFromPsl(input) {
2290
2056
  const namespaceExtensionEntitiesForModel = modelNamespaceId !== void 0 ? input.namespaceExtensionEntities?.get(modelNamespaceId) : void 0;
2291
2057
  const resolvedFields = collectResolvedFields({
2292
2058
  model,
2059
+ symbolTable: input.symbolTable,
2293
2060
  mapping,
2294
2061
  enumTypeDescriptors: input.enumTypeDescriptors,
2295
2062
  namedTypeDescriptors: input.namedTypeDescriptors,
@@ -2398,6 +2165,30 @@ function buildModelNodeFromPsl(input) {
2398
2165
  const foreignKeyNodes = [];
2399
2166
  const modelAttributeNodes = Array.from(model.node.attributes());
2400
2167
  for (const [attributeIndex, modelAttribute] of model.attributes.entries()) {
2168
+ if (!Object.hasOwn(sqlAttributeSpecs.model, modelAttribute.name) && !input.modelAttributesByName.has(modelAttribute.name)) {
2169
+ const uncomposedNamespace = checkUncomposedNamespace(modelAttribute.name, input.composedExtensions, {
2170
+ familyId: input.familyId,
2171
+ targetId: input.targetId,
2172
+ authoringContributions: input.authoringContributions
2173
+ });
2174
+ if (uncomposedNamespace) {
2175
+ reportUncomposedNamespace({
2176
+ subjectLabel: `Attribute "@@${modelAttribute.name}"`,
2177
+ namespace: uncomposedNamespace,
2178
+ sourceId,
2179
+ span: modelAttribute.span,
2180
+ diagnostics
2181
+ });
2182
+ continue;
2183
+ }
2184
+ diagnostics.push({
2185
+ code: "PSL_UNSUPPORTED_MODEL_ATTRIBUTE",
2186
+ message: `Model "${model.name}" uses unsupported attribute "@@${modelAttribute.name}"`,
2187
+ sourceId,
2188
+ span: modelAttribute.span
2189
+ });
2190
+ continue;
2191
+ }
2401
2192
  if (modelAttribute.name === "map") continue;
2402
2193
  if (modelAttribute.name === "discriminator" || modelAttribute.name === "base") continue;
2403
2194
  if (modelAttribute.name === "control") {
@@ -2415,7 +2206,7 @@ function buildModelNodeFromPsl(input) {
2415
2206
  if (node === void 0) continue;
2416
2207
  const parsed = interpretModelAttribute({
2417
2208
  node,
2418
- spec: controlModelSpec,
2209
+ spec: sqlAttributeSpecs.model.control(),
2419
2210
  model,
2420
2211
  sourceFile: input.sourceFile,
2421
2212
  sourceId,
@@ -2449,7 +2240,7 @@ function buildModelNodeFromPsl(input) {
2449
2240
  if (node === void 0) continue;
2450
2241
  const parsed = interpretModelAttribute({
2451
2242
  node,
2452
- spec: idModelSpec,
2243
+ spec: sqlAttributeSpecs.model.id(),
2453
2244
  model,
2454
2245
  sourceFile: input.sourceFile,
2455
2246
  sourceId,
@@ -2489,7 +2280,7 @@ function buildModelNodeFromPsl(input) {
2489
2280
  if (node === void 0) continue;
2490
2281
  const parsed = interpretModelAttribute({
2491
2282
  node,
2492
- spec: uniqueModelSpec,
2283
+ spec: sqlAttributeSpecs.model.unique(),
2493
2284
  model,
2494
2285
  sourceFile: input.sourceFile,
2495
2286
  sourceId,
@@ -2517,7 +2308,7 @@ function buildModelNodeFromPsl(input) {
2517
2308
  if (node === void 0) continue;
2518
2309
  const parsed = interpretModelAttribute({
2519
2310
  node,
2520
- spec: indexModelSpec,
2311
+ spec: sqlAttributeSpecs.model.index(),
2521
2312
  model,
2522
2313
  sourceFile: input.sourceFile,
2523
2314
  sourceId,
@@ -2564,7 +2355,7 @@ function buildModelNodeFromPsl(input) {
2564
2355
  }
2565
2356
  const parsed = interpretModelAttribute({
2566
2357
  node,
2567
- spec: checkModelSpec,
2358
+ spec: sqlAttributeSpecs.model.check(),
2568
2359
  model,
2569
2360
  sourceFile: input.sourceFile,
2570
2361
  sourceId,
@@ -2622,27 +2413,7 @@ function buildModelNodeFromPsl(input) {
2622
2413
  slot[lowered.key] = lowered.entity;
2623
2414
  continue;
2624
2415
  }
2625
- const uncomposedNamespace = checkUncomposedNamespace(modelAttribute.name, input.composedExtensions, {
2626
- familyId: input.familyId,
2627
- targetId: input.targetId,
2628
- authoringContributions: input.authoringContributions
2629
- });
2630
- if (uncomposedNamespace) {
2631
- reportUncomposedNamespace({
2632
- subjectLabel: `Attribute "@@${modelAttribute.name}"`,
2633
- namespace: uncomposedNamespace,
2634
- sourceId,
2635
- span: modelAttribute.span,
2636
- diagnostics
2637
- });
2638
- continue;
2639
- }
2640
- diagnostics.push({
2641
- code: "PSL_UNSUPPORTED_MODEL_ATTRIBUTE",
2642
- message: `Model "${model.name}" uses unsupported attribute "@@${modelAttribute.name}"`,
2643
- sourceId,
2644
- span: modelAttribute.span
2645
- });
2416
+ throw new InternalError(`Model attribute "@@${modelAttribute.name}" is registered but has no interpreter branch`);
2646
2417
  }
2647
2418
  const resultFkRelationMetadata = [];
2648
2419
  const resultCrossSpaceRelations = [];
@@ -3005,7 +2776,7 @@ function collectPolymorphismDeclarations(models, sourceFile, sourceId, diagnosti
3005
2776
  if (discriminatorNode !== void 0) {
3006
2777
  const parsed = interpretModelAttribute({
3007
2778
  node: discriminatorNode,
3008
- spec: discriminatorModelSpec,
2779
+ spec: sqlAttributeSpecs.model.discriminator(),
3009
2780
  model,
3010
2781
  sourceFile,
3011
2782
  sourceId,
@@ -3030,7 +2801,7 @@ function collectPolymorphismDeclarations(models, sourceFile, sourceId, diagnosti
3030
2801
  if (baseNode !== void 0) {
3031
2802
  const parsed = interpretModelAttribute({
3032
2803
  node: baseNode,
3033
- spec: baseModelSpec,
2804
+ spec: sqlAttributeSpecs.model.base(),
3034
2805
  model,
3035
2806
  sourceFile,
3036
2807
  sourceId,
@@ -3681,4 +3452,4 @@ function interpretPslDocumentToSqlContract(input) {
3681
3452
  //#endregion
3682
3453
  export { interpretPslDocumentToSqlContract as t };
3683
3454
 
3684
- //# sourceMappingURL=interpreter-RTglKUpM-B-iOLic9.mjs.map
3455
+ //# sourceMappingURL=interpreter-DQIdQxL1-DyNYhhep.mjs.map