@prisma/orm-family-sql 8.0.0-rc.13-dev.9 → 8.0.0-rc.13-dev.11

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.
@@ -2,7 +2,7 @@ import { n as isAuthoredIndexInput } from "./index-naming-Cj1Anq-T-w1JL7-EM.mjs"
2
2
  import { n as providesPslEntityPlacement } from "./entity-handle-lowering-hook-B3atrRKX.mjs";
3
3
  import { t as deriveValueSetFromEntity } from "./value-set-derivation-hook-Di9JZ0X7.mjs";
4
4
  import { n as buildSqlContractFromDefinition } from "./derived-checks-Bsrdb2Wk-D4UfM06W.mjs";
5
- import { a as findModelAttributeNode, c as lowerDefaultFunctionWithRegistry, i as findFieldAttributeNode, l as modelAttributeSpecsFrom, n as createSqlBinder, o as interpretFieldAttribute, r as fieldSpecContext, s as interpretModelAttribute, t as PSL_CHECK_ON_STI_VARIANT, u as sqlAttributeSpecs } from "./sql-attribute-specs-4YqT9Gt_-DkPyYEaE.mjs";
5
+ import { a as getAttribute, c as interpretModelAttribute, d as modelAttributeSpecsFrom, f as sqlAttributeSpecs, i as formatDbAttributeMigrationMessage, l as lowerDefaultFunctionWithRegistry, n as createSqlBinder, o as getNamedArgument, p as storageName, r as fieldSpecContext, s as interpretFieldAttribute, t as PSL_CHECK_ON_STI_VARIANT, u as mapFieldNamesToColumns } from "./sql-attribute-specs-Bs9QDuS7-DmIRJUz9.mjs";
6
6
  import { t as defaultTableName } from "./default-table-name-BfFY8qYR-lHNcVmY5.mjs";
7
7
  import { isStructuredError, structuredError } from "@prisma/orm-framework/utils/structured-error";
8
8
  import { checkUncomposedNamespace, getAuthoringFieldPreset, hasRegisteredFieldNamespace, instantiateAuthoringEntityType, instantiateAuthoringTypeConstructor, isAuthoringEntityTypeDescriptor, isAuthoringModelAttributeDescriptor, isAuthoringTypeConstructorDescriptor, isDataTypeLoweringEntry, loweringEntryKey, validateAuthoringHelperArguments } from "@prisma/orm-framework/components/authoring";
@@ -11,48 +11,19 @@ import { InternalError } from "@prisma/orm-framework/utils/internal-error";
11
11
  import { crossRef } from "@prisma/orm-framework/contract/types";
12
12
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
13
13
  import { blindCast } from "@prisma/orm-framework/utils/casts";
14
+ import { NamespaceDeclarationAst } from "@prisma/orm-framework/psl-parser/syntax";
14
15
  import { resolveToOneRelationNullable } from "@prisma/orm-framework/contract-authoring";
15
16
  import { materializeCodec } from "@prisma/orm-framework/components/codec";
16
17
  import { assertDefined, invariant } from "@prisma/orm-framework/utils/assertions";
17
18
  import { describeTaggedLiteralFailure } from "@prisma/orm-framework/components/control";
18
19
  import { notOk, ok } from "@prisma/orm-framework/utils/result";
19
- import { createPslDiagnosticCollector, diagnosticSource, findBlockDescriptor, interpretExtensionBlocks, nodePslSpan } from "@prisma/orm-framework/psl-parser";
20
+ import { createPslDiagnosticCollector, diagnosticSource, findBlockDescriptor, interpretExtensionBlocks, nodePslSpan, typeReferenceNode } from "@prisma/orm-framework/psl-parser";
20
21
  import { UNBOUND_PSL_NAMESPACE_NAME, UNSPECIFIED_PSL_NAMESPACE_ID } from "@prisma/orm-framework/components/psl-ast";
21
- import { claimedBlockKeywords, consumeInvalidFkPairing, enumMemberAttributeDiagnostics, fkRelationPairKey, instantiatePslFieldPreset, mapPslHelperArgs, reportUncomposedNamespace, reportUnknownFieldPreset, requiredOneToOneBackrelationDiagnostic, uncomposedNamespaceDiagnostic, unsupportedBlockDiagnostic } from "@prisma/orm-framework/psl-parser/interpret";
22
- //#region ../../../2-sql/2-authoring/contract-psl/dist/interpreter-BMMGMTBa.mjs
22
+ import { claimedBlockKeywords, enumMemberAttributeDiagnostics, fkRelationPairKey, instantiatePslFieldPreset, mapPslHelperArgs, reportUncomposedNamespace, reportUnknownFieldPreset, requiredOneToOneBackrelationDiagnostic, uncomposedNamespaceDiagnostic, unsupportedBlockDiagnostic } from "@prisma/orm-framework/psl-parser/interpret";
23
+ //#region ../../../2-sql/2-authoring/contract-psl/dist/interpreter-gs7fSAIb.mjs
23
24
  function contractError(code, message, options) {
24
25
  return structuredError(code, message, options);
25
26
  }
26
- function getAttribute(attributes, name) {
27
- return attributes?.find((attribute) => attribute.name === name);
28
- }
29
- function formatDbAttributeMigrationMessage(attribute) {
30
- const renderedArguments = attribute.args.map((argument) => argument.kind === "named" && argument.name !== void 0 ? `${argument.name}: ${argument.value}` : argument.value).join(", ");
31
- const argumentList = attribute.args.length === 0 ? "" : `(${renderedArguments})`;
32
- const constructorName = attribute.name.slice(3);
33
- return `@${attribute.name}${argumentList} is no longer supported; use ${constructorName}${argumentList} in type position`;
34
- }
35
- function getNamedArgument(attribute, name) {
36
- const entry = attribute.args.find((arg) => arg.kind === "named" && arg.name === name);
37
- if (entry?.kind !== "named") return;
38
- return entry.value;
39
- }
40
- function mapFieldNamesToColumns(input) {
41
- const columns = [];
42
- for (const fieldName of input.fieldNames) {
43
- const columnName = input.mapping.fieldColumns.get(fieldName);
44
- if (!columnName) {
45
- input.diagnostics.push({
46
- code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
47
- message: `${input.entityLabel} references unknown field "${input.modelName}.${fieldName}"`,
48
- ...input.source.at(input.span)
49
- });
50
- return;
51
- }
52
- columns.push(columnName);
53
- }
54
- return columns;
55
- }
56
27
  /** A `` json`...` `` body that is not a JSON document. */
57
28
  const PSL_INVALID_JSON_LITERAL = "PSL_INVALID_JSON_LITERAL";
58
29
  /** A written value the entry, a cast, or the column's codec refuses. */
@@ -397,6 +368,12 @@ function getAuthoringEntity(contributions, path) {
397
368
  }
398
369
  return current !== void 0 && isAuthoringEntityTypeDescriptor(current) ? current : void 0;
399
370
  }
371
+ function replacesUnresolvedTypeVoice(typeName, composedExtensions, context) {
372
+ if (checkUncomposedNamespace(typeName, composedExtensions, context) !== void 0) return true;
373
+ const dotIndex = typeName.indexOf(".");
374
+ if (dotIndex <= 0 || dotIndex === typeName.length - 1) return false;
375
+ return hasRegisteredFieldNamespace(context.authoringContributions, typeName.slice(0, dotIndex));
376
+ }
400
377
  function instantiatePslTypeConstructor(input) {
401
378
  const helperPath = input.call.path.join(".");
402
379
  const args = mapPslHelperArgs({
@@ -685,7 +662,7 @@ function lowerTaggedLiteral(literal, support, context, source) {
685
662
  };
686
663
  }
687
664
  function lowerDefaultForField(input) {
688
- const node = findFieldAttributeNode(input.field, "default");
665
+ const node = getAttribute(input.field.attributes, "default")?.node;
689
666
  if (node === void 0) return {};
690
667
  const source = diagnosticSource(input.sources, node.syntax);
691
668
  const spec = sqlAttributeSpecs.field.default(fieldSpecContext({
@@ -860,7 +837,7 @@ function resolveColumnDescriptor(field, enumTypeDescriptors, namedTypeDescriptor
860
837
  }
861
838
  function lowerEnumDefaultForField(input) {
862
839
  const { field, model, enumHandle, diagnostics } = input;
863
- const node = findFieldAttributeNode(field, "default");
840
+ const node = getAttribute(field.attributes, "default")?.node;
864
841
  if (node === void 0) return {};
865
842
  if (enumHandle.enumMembers.length === 0) return {};
866
843
  const interpreted = interpretFieldAttribute({
@@ -951,7 +928,7 @@ function describeUnsupportedSqlAttribute(input) {
951
928
  function extractFieldConstraintNames(input) {
952
929
  const idAttribute = getAttribute(input.field.attributes, "id");
953
930
  const uniqueAttribute = getAttribute(input.field.attributes, "unique");
954
- const idNode = findFieldAttributeNode(input.field, "id");
931
+ const idNode = getAttribute(input.field.attributes, "id")?.node;
955
932
  const idName = idNode === void 0 ? void 0 : interpretFieldAttribute({
956
933
  node: idNode,
957
934
  symbols: input.symbolTable,
@@ -962,7 +939,7 @@ function extractFieldConstraintNames(input) {
962
939
  binder: input.binder,
963
940
  diagnostics: input.diagnostics
964
941
  })?.map;
965
- const uniqueNode = findFieldAttributeNode(input.field, "unique");
942
+ const uniqueNode = getAttribute(input.field.attributes, "unique")?.node;
966
943
  return {
967
944
  idAttribute,
968
945
  uniqueAttribute,
@@ -987,7 +964,7 @@ function extractFieldConstraintNames(input) {
987
964
  * the only form the definition tree carries.
988
965
  */
989
966
  function lowerNoCheckForField(input) {
990
- const node = findFieldAttributeNode(input.field, "noCheck");
967
+ const node = getAttribute(input.field.attributes, "noCheck")?.node;
991
968
  if (node === void 0) return void 0;
992
969
  const interpreted = interpretFieldAttribute({
993
970
  node,
@@ -1029,20 +1006,22 @@ function lowerNoCheckForField(input) {
1029
1006
  return [...authored].sort();
1030
1007
  }
1031
1008
  function collectResolvedFields(input) {
1032
- const { model, symbolTable, mapping, enumTypeDescriptors, namedTypeDescriptors, modelNames, compositeTypeNames, composedExtensions, authoringContributions, binder, familyId, targetId, defaultFunctionRegistry, dataTypeSupport, generatorDescriptorById, diagnostics, sources, scalarColumnDescriptors, enumHandles, capabilities, namespaceId, namespaceExtensionEntities, codecLookup } = input;
1009
+ const { model, symbolTable, enumTypeDescriptors, namedTypeDescriptors, composedExtensions, authoringContributions, binder, familyId, targetId, defaultFunctionRegistry, dataTypeSupport, generatorDescriptorById, diagnostics, sources, scalarColumnDescriptors, enumHandles, capabilities, namespaceId, namespaceExtensionEntities, codecLookup } = input;
1033
1010
  const resolvedFields = [];
1034
1011
  const valueObjectStorageTypeName = authoringContributions?.valueObjectStorageType;
1035
1012
  const declaredControlPolicy = getAttribute(model.attributes, "control")?.args.find((arg) => arg.kind === "positional")?.value.trim();
1036
1013
  const modelDerivesChecks = declaredControlPolicy === void 0 || declaredControlPolicy === "managed";
1037
1014
  for (const field of Object.values(model.fields)) {
1038
1015
  const source = diagnosticSource(sources, field.node.syntax);
1039
- const isModelField = modelNames.has(field.typeName);
1016
+ const fieldTypeReference = typeReferenceNode(field);
1017
+ const fieldTypeResolution = fieldTypeReference === void 0 ? void 0 : binder.symbolForNode(fieldTypeReference);
1018
+ const isModelField = fieldTypeResolution?.kind === "model";
1040
1019
  if (field.list && isModelField) continue;
1041
1020
  const relationAttribute = getAttribute(field.attributes, "relation");
1042
1021
  if (isModelField && relationAttribute) continue;
1043
1022
  if (field.typeContractSpaceId !== void 0 && relationAttribute) continue;
1044
1023
  if (isModelField) continue;
1045
- const isValueObjectField = compositeTypeNames.has(field.typeName);
1024
+ const isValueObjectField = fieldTypeResolution?.kind === "compositeType";
1046
1025
  const isListField = field.list;
1047
1026
  let descriptor;
1048
1027
  let scalarCodecId;
@@ -1076,7 +1055,7 @@ function collectResolvedFields(input) {
1076
1055
  }
1077
1056
  const resolved = resolveFieldTypeDescriptor(resolveInput);
1078
1057
  if (!resolved.ok) {
1079
- if (!resolved.alreadyReported) diagnostics.push({
1058
+ if (!resolved.alreadyReported && fieldTypeResolution?.kind !== "unresolved") diagnostics.push({
1080
1059
  code: "PSL_UNSUPPORTED_FIELD_TYPE",
1081
1060
  message: `Field "${model.name}.${field.name}" type "${field.typeName}" is not supported in SQL PSL provider v1`,
1082
1061
  ...source.at(field.span)
@@ -1096,7 +1075,7 @@ function collectResolvedFields(input) {
1096
1075
  } else {
1097
1076
  const resolved = resolveFieldTypeDescriptor(resolveInput);
1098
1077
  if (!resolved.ok) {
1099
- if (!resolved.alreadyReported) diagnostics.push({
1078
+ if (!resolved.alreadyReported && fieldTypeResolution?.kind !== "unresolved") diagnostics.push({
1100
1079
  code: "PSL_UNSUPPORTED_FIELD_TYPE",
1101
1080
  message: `Field "${model.name}.${field.name}" type "${field.typeName}" is not supported in SQL PSL provider v1`,
1102
1081
  ...source.at(field.span)
@@ -1179,7 +1158,7 @@ function collectResolvedFields(input) {
1179
1158
  });
1180
1159
  continue;
1181
1160
  }
1182
- const mappedColumnName = mapping.fieldColumns.get(field.name) ?? field.name;
1161
+ const mappedColumnName = storageName(field, input.physicalNames);
1183
1162
  const { idAttribute, uniqueAttribute, idName, uniqueName } = extractFieldConstraintNames({
1184
1163
  symbolTable: input.symbolTable,
1185
1164
  model,
@@ -1244,42 +1223,6 @@ function collectResolvedFields(input) {
1244
1223
  }
1245
1224
  return resolvedFields;
1246
1225
  }
1247
- function buildModelMappings(symbols, modelEntries, defaultNamespaceId, diagnostics, sources, binder) {
1248
- const result = /* @__PURE__ */ new Map();
1249
- for (const { model, namespaceId } of modelEntries) {
1250
- const mapNode = findModelAttributeNode(model, "map");
1251
- const tableName = mapNode === void 0 ? defaultTableName(model.name) : interpretModelAttribute({
1252
- node: mapNode,
1253
- symbols,
1254
- spec: sqlAttributeSpecs.model.map(),
1255
- model,
1256
- sources,
1257
- binder,
1258
- diagnostics
1259
- })?.name ?? defaultTableName(model.name);
1260
- const fieldColumns = /* @__PURE__ */ new Map();
1261
- for (const field of Object.values(model.fields)) {
1262
- const fieldMapNode = findFieldAttributeNode(field, "map");
1263
- const columnName = fieldMapNode === void 0 ? field.name : interpretFieldAttribute({
1264
- node: fieldMapNode,
1265
- symbols,
1266
- spec: sqlAttributeSpecs.field.map(),
1267
- model,
1268
- field,
1269
- binder,
1270
- sources,
1271
- diagnostics
1272
- })?.name ?? field.name;
1273
- fieldColumns.set(field.name, columnName);
1274
- }
1275
- result.set(modelCoordinateKey(namespaceId ?? defaultNamespaceId, model.name), {
1276
- model,
1277
- tableName,
1278
- fieldColumns
1279
- });
1280
- }
1281
- return result;
1282
- }
1283
1226
  function validateNamedTypeAttributes(input) {
1284
1227
  let hasUnsupportedNamedTypeAttribute = false;
1285
1228
  for (const attribute of input.declaration.attributes) {
@@ -1424,11 +1367,14 @@ const REFERENTIAL_ACTION_MAP = {
1424
1367
  setNull: "setNull",
1425
1368
  setDefault: "setDefault"
1426
1369
  };
1370
+ function modelName(key) {
1371
+ return typeof key === "string" ? key : key.name;
1372
+ }
1427
1373
  function normalizeReferentialAction(actionToken) {
1428
1374
  return REFERENTIAL_ACTION_MAP[actionToken];
1429
1375
  }
1430
1376
  function interpretRelationAttribute(input) {
1431
- const node = findFieldAttributeNode(input.field, "relation");
1377
+ const node = getAttribute(input.field.attributes, "relation")?.node;
1432
1378
  if (node === void 0) return void 0;
1433
1379
  return interpretFieldAttribute({
1434
1380
  symbols: input.symbols,
@@ -1454,7 +1400,7 @@ function indexFkRelations(input) {
1454
1400
  if (!existing) modelRelations.set(relation.declaringModelName, current);
1455
1401
  current.push({
1456
1402
  fieldName: relation.declaringFieldName,
1457
- toModel: relation.targetModelName,
1403
+ toModel: modelName(relation.targetModelName),
1458
1404
  toTable: relation.targetTableName,
1459
1405
  ...ifDefined("toNamespaceId", relation.targetNamespaceId),
1460
1406
  cardinality: "N:1",
@@ -1466,13 +1412,14 @@ function indexFkRelations(input) {
1466
1412
  childColumns: relation.referencedColumns
1467
1413
  }
1468
1414
  });
1469
- const pairKey = fkRelationPairKey(relation.declaringModelName, relation.targetModelName);
1470
- const pairRelations = fkRelationsByPair.get(pairKey);
1471
- if (!pairRelations) {
1472
- fkRelationsByPair.set(pairKey, [relation]);
1473
- continue;
1474
- }
1475
- pairRelations.push(relation);
1415
+ let targets = fkRelationsByPair.get(relation.declaringModelName);
1416
+ if (!targets) {
1417
+ targets = /* @__PURE__ */ new Map();
1418
+ fkRelationsByPair.set(relation.declaringModelName, targets);
1419
+ }
1420
+ const pairRelations = targets.get(relation.targetModelName);
1421
+ if (pairRelations) pairRelations.push(relation);
1422
+ else targets.set(relation.targetModelName, [relation]);
1476
1423
  }
1477
1424
  return {
1478
1425
  modelRelations,
@@ -1541,7 +1488,7 @@ function findJunctionFkPairs(input) {
1541
1488
  if (childFk === parentFk || childFk.targetModelName !== input.candidate.targetModelName) continue;
1542
1489
  if (!idColumns || !idColumnsAreExactlyFkPair(idColumns, parentFk.localColumns, childFk.localColumns)) {
1543
1490
  nearMisses.push({
1544
- junctionModelName,
1491
+ junctionModelName: modelName(junctionModelName),
1545
1492
  reason: "id-not-fk-covering"
1546
1493
  });
1547
1494
  continue;
@@ -1549,7 +1496,7 @@ function findJunctionFkPairs(input) {
1549
1496
  const orderedChildColumns = childColumnsInTargetIdOrder(childFk, targetIdColumns);
1550
1497
  if (!orderedChildColumns) {
1551
1498
  nearMisses.push({
1552
- junctionModelName,
1499
+ junctionModelName: modelName(junctionModelName),
1553
1500
  reason: "target-fk-not-id"
1554
1501
  });
1555
1502
  continue;
@@ -1569,21 +1516,22 @@ function findJunctionFkPairs(input) {
1569
1516
  }
1570
1517
  function junctionNearMissDiagnostic(candidate, nearMiss, sources) {
1571
1518
  const source = diagnosticSource(sources, candidate.field.node.syntax);
1572
- const listField = `${candidate.modelName}.${candidate.field.name}`;
1519
+ const listField = `${modelName(candidate.modelName)}.${candidate.field.name}`;
1520
+ const targetModelName = modelName(candidate.targetModelName);
1573
1521
  const data = {
1574
1522
  listField,
1575
1523
  junctionModel: nearMiss.junctionModelName,
1576
- targetModel: candidate.targetModelName
1524
+ targetModel: targetModelName
1577
1525
  };
1578
1526
  if (nearMiss.reason === "target-fk-not-id") return {
1579
1527
  code: "PSL_JUNCTION_TARGET_FK_NOT_ID",
1580
- message: `Backrelation list field "${listField}" found junction model "${nearMiss.junctionModelName}", but its foreign key to "${candidate.targetModelName}" does not reference "${candidate.targetModelName}"'s @id. The junction's target-side foreign key must reference "${candidate.targetModelName}"'s full @id columns for many-to-many recognition.`,
1528
+ message: `Backrelation list field "${listField}" found junction model "${nearMiss.junctionModelName}", but its foreign key to "${targetModelName}" does not reference "${targetModelName}"'s @id. The junction's target-side foreign key must reference "${targetModelName}"'s full @id columns for many-to-many recognition.`,
1581
1529
  ...source.at(candidate.field.span),
1582
1530
  data
1583
1531
  };
1584
1532
  return {
1585
1533
  code: "PSL_JUNCTION_ID_NOT_FK_COVERING",
1586
- message: `Backrelation list field "${listField}" found junction-shaped model "${nearMiss.junctionModelName}" linking "${candidate.modelName}" and "${candidate.targetModelName}", but its id does not cover exactly its foreign-key columns. Declare @@id([...]) on "${nearMiss.junctionModelName}" listing exactly the two foreign-key columns for many-to-many recognition.`,
1534
+ message: `Backrelation list field "${listField}" found junction-shaped model "${nearMiss.junctionModelName}" linking "${modelName(candidate.modelName)}" and "${targetModelName}", but its id does not cover exactly its foreign-key columns. Declare @@id([...]) on "${nearMiss.junctionModelName}" listing exactly the two foreign-key columns for many-to-many recognition.`,
1587
1535
  ...source.at(candidate.field.span),
1588
1536
  data
1589
1537
  };
@@ -1591,7 +1539,7 @@ function junctionNearMissDiagnostic(candidate, nearMiss, sources) {
1591
1539
  function manyToManyRelationNode(candidate, pair) {
1592
1540
  return {
1593
1541
  fieldName: candidate.field.name,
1594
- toModel: pair.childFk.targetModelName,
1542
+ toModel: modelName(pair.childFk.targetModelName),
1595
1543
  toTable: pair.childFk.targetTableName,
1596
1544
  ...ifDefined("toNamespaceId", pair.childFk.targetNamespaceId),
1597
1545
  cardinality: "N:M",
@@ -1631,11 +1579,18 @@ function fkColumnsAreUnique(localColumns, uniqueColumnSets) {
1631
1579
  function applyBackrelationCandidates(input) {
1632
1580
  for (const candidate of input.backrelationCandidates) {
1633
1581
  const source = diagnosticSource(input.sources, candidate.field.node.syntax);
1634
- const pairKey = fkRelationPairKey(candidate.targetModelName, candidate.modelName);
1635
- const pairMatches = input.fkRelationsByPair.get(pairKey) ?? [];
1582
+ const pairMatches = input.fkRelationsByPair.get(candidate.targetModelName)?.get(candidate.modelName) ?? [];
1636
1583
  const matches = candidate.relationName ? pairMatches.filter((relation) => relation.relationName === candidate.relationName) : [...pairMatches];
1637
1584
  if (matches.length === 0) {
1638
- if (consumeInvalidFkPairing(candidate, pairKey, input.invalidFkPairings)) continue;
1585
+ const invalidIndex = input.invalidFkPairings.findIndex((pairing) => {
1586
+ if (pairing.relationName !== candidate.relationName) return false;
1587
+ if ("pairKey" in pairing) return typeof candidate.targetModelName === "string" && typeof candidate.modelName === "string" && pairing.pairKey === fkRelationPairKey(candidate.targetModelName, candidate.modelName);
1588
+ return pairing.declaringModel === candidate.targetModelName && pairing.targetModel === candidate.modelName;
1589
+ });
1590
+ if (invalidIndex !== -1) {
1591
+ input.invalidFkPairings.splice(invalidIndex, 1);
1592
+ continue;
1593
+ }
1639
1594
  if (candidate.isList) {
1640
1595
  const { pairs: junctionPairs, nearMisses } = findJunctionFkPairs({
1641
1596
  candidate,
@@ -1650,7 +1605,7 @@ function applyBackrelationCandidates(input) {
1650
1605
  if (junctionPairs.length > 1) {
1651
1606
  input.diagnostics.push({
1652
1607
  code: "PSL_AMBIGUOUS_BACKRELATION",
1653
- message: `Backrelation list field "${candidate.modelName}.${candidate.field.name}" matches multiple junction FK pairs for a many-to-many relation. Add @relation(name: "...") (or @relation("...")) to the list field and the junction FK-side relation pointing back at "${candidate.modelName}" to disambiguate.`,
1608
+ message: `Backrelation list field "${modelName(candidate.modelName)}.${candidate.field.name}" matches multiple junction FK pairs for a many-to-many relation. Add @relation(name: "...") (or @relation("...")) to the list field and the junction FK-side relation pointing back at "${modelName(candidate.modelName)}" to disambiguate.`,
1654
1609
  ...source.at(candidate.field.span)
1655
1610
  });
1656
1611
  continue;
@@ -1663,7 +1618,7 @@ function applyBackrelationCandidates(input) {
1663
1618
  }
1664
1619
  input.diagnostics.push({
1665
1620
  code: "PSL_ORPHANED_BACKRELATION",
1666
- message: `Backrelation field "${candidate.modelName}.${candidate.field.name}" has no matching FK-side relation on model "${candidate.targetModelName}". Add @relation(fields: [...], references: [...]) on the FK-side relation${candidate.isList ? " or use an explicit join model for many-to-many" : ""}.`,
1621
+ message: `Backrelation field "${modelName(candidate.modelName)}.${candidate.field.name}" has no matching FK-side relation on model "${modelName(candidate.targetModelName)}". Add @relation(fields: [...], references: [...]) on the FK-side relation${candidate.isList ? " or use an explicit join model for many-to-many" : ""}.`,
1667
1622
  ...source.at(candidate.field.span)
1668
1623
  });
1669
1624
  continue;
@@ -1671,7 +1626,7 @@ function applyBackrelationCandidates(input) {
1671
1626
  if (matches.length > 1) {
1672
1627
  input.diagnostics.push({
1673
1628
  code: "PSL_AMBIGUOUS_BACKRELATION",
1674
- message: `Backrelation field "${candidate.modelName}.${candidate.field.name}" matches multiple FK-side relations on model "${candidate.targetModelName}". Add @relation(name: "...") (or @relation("...")) to both sides to disambiguate.`,
1629
+ message: `Backrelation field "${modelName(candidate.modelName)}.${candidate.field.name}" matches multiple FK-side relations on model "${modelName(candidate.targetModelName)}". Add @relation(name: "...") (or @relation("...")) to both sides to disambiguate.`,
1675
1630
  ...source.at(candidate.field.span)
1676
1631
  });
1677
1632
  continue;
@@ -1684,22 +1639,22 @@ function applyBackrelationCandidates(input) {
1684
1639
  if (!fkColumnsAreUnique(matched.localColumns, uniqueColumnSets)) {
1685
1640
  input.diagnostics.push({
1686
1641
  code: "PSL_NON_UNIQUE_BACKRELATION",
1687
- message: `Backrelation field "${candidate.modelName}.${candidate.field.name}" is singular, but the matching FK on "${matched.declaringModelName}" (fields ${matched.localColumns.map((column) => `"${column}"`).join(", ")}) is not unique. A singular back-relation implies at most one related row; add @unique (or @@unique([...])) to the FK fields, or make "${candidate.field.name}" a list.`,
1642
+ message: `Backrelation field "${modelName(candidate.modelName)}.${candidate.field.name}" is singular, but the matching FK on "${modelName(matched.declaringModelName)}" (fields ${matched.localColumns.map((column) => `"${column}"`).join(", ")}) is not unique. A singular back-relation implies at most one related row; add @unique (or @@unique([...])) to the FK fields, or make "${candidate.field.name}" a list.`,
1688
1643
  ...source.at(candidate.field.span)
1689
1644
  });
1690
1645
  continue;
1691
1646
  }
1692
1647
  }
1693
1648
  if (!candidate.isList && !candidate.field.optional) input.diagnostics.push(requiredOneToOneBackrelationDiagnostic({
1694
- modelName: candidate.modelName,
1649
+ modelName: modelName(candidate.modelName),
1695
1650
  field: candidate.field,
1696
- targetModelName: candidate.targetModelName,
1651
+ targetModelName: modelName(candidate.targetModelName),
1697
1652
  sources: input.sources,
1698
1653
  recordNoun: "row"
1699
1654
  }));
1700
1655
  relationsForModel(input.modelRelations, candidate.modelName).push({
1701
1656
  fieldName: candidate.field.name,
1702
- toModel: matched.declaringModelName,
1657
+ toModel: modelName(matched.declaringModelName),
1703
1658
  toTable: matched.declaringTableName,
1704
1659
  ...ifDefined("toNamespaceId", matched.declaringNamespaceId),
1705
1660
  ...candidate.isList ? { cardinality: "1:N" } : {
@@ -2023,19 +1978,17 @@ function relationNullabilityMismatchDiagnostic(modelName, relationAttribute, sou
2023
1978
  };
2024
1979
  }
2025
1980
  function buildModelNodeFromPsl(input) {
2026
- const { model, mapping, diagnostics } = input;
1981
+ const { model, diagnostics } = input;
2027
1982
  const source = diagnosticSource(input.sources, model.node.syntax);
2028
- const tableName = mapping.tableName;
2029
- const modelNamespaceId = input.modelNamespaceIds.get(model.name);
1983
+ const tableName = storageName(model, input.physicalNames);
1984
+ const modelNamespaceId = input.namespaceId;
2030
1985
  const namespaceExtensionEntitiesForModel = modelNamespaceId !== void 0 ? input.namespaceExtensionEntities?.get(modelNamespaceId) : void 0;
2031
1986
  const resolvedFields = collectResolvedFields({
2032
1987
  model,
1988
+ physicalNames: input.physicalNames,
2033
1989
  symbolTable: input.symbolTable,
2034
- mapping,
2035
1990
  enumTypeDescriptors: input.enumTypeDescriptors,
2036
1991
  namedTypeDescriptors: input.namedTypeDescriptors,
2037
- modelNames: input.modelNames,
2038
- compositeTypeNames: input.compositeTypeNames,
2039
1992
  composedExtensions: input.composedExtensions,
2040
1993
  authoringContributions: input.authoringContributions,
2041
1994
  familyId: input.familyId,
@@ -2072,7 +2025,8 @@ function buildModelNodeFromPsl(input) {
2072
2025
  const modelAttributeEntities = {};
2073
2026
  const resultBackrelationCandidates = [];
2074
2027
  for (const field of Object.values(model.fields)) {
2075
- if (!input.modelNames.has(field.typeName)) continue;
2028
+ const backrelationTarget = backrelationTargetSymbol(field, input.binder);
2029
+ if (backrelationTarget === void 0) continue;
2076
2030
  const relationAttribute = getAttribute(field.attributes, "relation");
2077
2031
  if (!field.list && relationAttribute && relationAttributeDeclaresOwningSide(relationAttribute)) continue;
2078
2032
  const attributesValid = validateBackrelationFieldAttributes({
@@ -2117,10 +2071,10 @@ function buildModelNodeFromPsl(input) {
2117
2071
  }
2118
2072
  if (!attributesValid) continue;
2119
2073
  resultBackrelationCandidates.push({
2120
- modelName: model.name,
2074
+ modelName: model,
2121
2075
  tableName,
2122
2076
  field,
2123
- targetModelName: field.typeName,
2077
+ targetModelName: backrelationTarget,
2124
2078
  isList: field.list,
2125
2079
  ...ifDefined("relationName", relationName)
2126
2080
  });
@@ -2208,9 +2162,9 @@ function buildModelNodeFromPsl(input) {
2208
2162
  continue;
2209
2163
  }
2210
2164
  const columnNames = mapFieldNamesToColumns({
2211
- modelName: model.name,
2165
+ model,
2166
+ physicalNames: input.physicalNames,
2212
2167
  fieldNames,
2213
- mapping,
2214
2168
  source,
2215
2169
  diagnostics,
2216
2170
  span: modelAttribute.span,
@@ -2238,9 +2192,9 @@ function buildModelNodeFromPsl(input) {
2238
2192
  });
2239
2193
  if (parsed === void 0) continue;
2240
2194
  const columnNames = mapFieldNamesToColumns({
2241
- modelName: model.name,
2195
+ model,
2196
+ physicalNames: input.physicalNames,
2242
2197
  fieldNames: parsed.fields,
2243
- mapping,
2244
2198
  source,
2245
2199
  diagnostics,
2246
2200
  span: modelAttribute.span,
@@ -2269,9 +2223,9 @@ function buildModelNodeFromPsl(input) {
2269
2223
  let columnNames;
2270
2224
  if (parsed.fields !== void 0) {
2271
2225
  const mapped = mapFieldNamesToColumns({
2272
- modelName: model.name,
2226
+ model,
2227
+ physicalNames: input.physicalNames,
2273
2228
  fieldNames: parsed.fields,
2274
- mapping,
2275
2229
  source,
2276
2230
  diagnostics,
2277
2231
  span: modelAttribute.span,
@@ -2358,7 +2312,10 @@ function buildModelNodeFromPsl(input) {
2358
2312
  target: input.targetId,
2359
2313
  modelName: model.name,
2360
2314
  storageName: tableName,
2361
- fieldStorageName: (fieldName) => mapping.fieldColumns.get(fieldName),
2315
+ fieldStorageName: (fieldName) => {
2316
+ const field = model.fields[fieldName];
2317
+ return field === void 0 ? void 0 : storageName(field, input.physicalNames);
2318
+ },
2362
2319
  fieldCodecId: (fieldName) => resolvedFields.find((resolved) => resolved.field.name === fieldName)?.descriptor.codecId,
2363
2320
  namespaceId: modelNamespaceId ?? input.defaultNamespaceId,
2364
2321
  sourceId: source.sources.sourceFileFor(source.node).filename,
@@ -2428,9 +2385,9 @@ function buildModelNodeFromPsl(input) {
2428
2385
  continue;
2429
2386
  }
2430
2387
  const localColumns = mapFieldNamesToColumns({
2431
- modelName: model.name,
2388
+ model,
2389
+ physicalNames: input.physicalNames,
2432
2390
  fieldNames: parsedRelation.fields,
2433
- mapping,
2434
2391
  source,
2435
2392
  diagnostics,
2436
2393
  span: relationAttribute.relation.span,
@@ -2502,19 +2459,15 @@ function buildModelNodeFromPsl(input) {
2502
2459
  continue;
2503
2460
  }
2504
2461
  const qualifiedTypeName = fieldTypeNamespaceId ? `${fieldTypeNamespaceId}.${fieldTypeName}` : fieldTypeName;
2505
- if (!input.modelNames.has(fieldTypeName)) {
2462
+ const typeReference = typeReferenceNode(relationAttribute.field);
2463
+ const targetResolution = typeReference === void 0 ? void 0 : input.binder.symbolForNode(typeReference);
2464
+ if (targetResolution?.kind === "unresolved") continue;
2465
+ const targetModel = targetResolution?.kind === "model" ? targetResolution.symbol : void 0;
2466
+ if (targetModel === void 0) {
2467
+ const foundKind = targetResolution === void 0 ? void 0 : relationTargetKindLabel(targetResolution);
2506
2468
  diagnostics.push({
2507
2469
  code: "PSL_INVALID_RELATION_TARGET",
2508
- message: `Relation field "${model.name}.${relationAttribute.field.name}" references unknown model "${qualifiedTypeName}"`,
2509
- ...source.at(relationAttribute.field.span)
2510
- });
2511
- continue;
2512
- }
2513
- const normalizedQualifier = fieldTypeNamespaceId === void 0 ? void 0 : fieldTypeNamespaceId === UNBOUND_PSL_NAMESPACE_NAME ? UNBOUND_NAMESPACE_ID : fieldTypeNamespaceId;
2514
- if (normalizedQualifier !== void 0 && !input.modelMappingsByCoordinate.has(modelCoordinateKey(normalizedQualifier, fieldTypeName))) {
2515
- diagnostics.push({
2516
- code: "PSL_INVALID_RELATION_TARGET",
2517
- message: `Relation field "${model.name}.${relationAttribute.field.name}" references unknown model "${qualifiedTypeName}"`,
2470
+ message: foundKind === void 0 ? `Relation field "${model.name}.${relationAttribute.field.name}" references unknown model "${qualifiedTypeName}"` : `Relation field "${model.name}.${relationAttribute.field.name}" references ${foundKind} "${qualifiedTypeName}"; a relation target must be a model`,
2518
2471
  ...source.at(relationAttribute.field.span)
2519
2472
  });
2520
2473
  continue;
@@ -2536,19 +2489,10 @@ function buildModelNodeFromPsl(input) {
2536
2489
  });
2537
2490
  continue;
2538
2491
  }
2539
- const targetMapping = normalizedQualifier !== void 0 ? input.modelMappingsByCoordinate.get(modelCoordinateKey(normalizedQualifier, fieldTypeName)) : input.modelMappings.get(fieldTypeName);
2540
- if (!targetMapping) {
2541
- diagnostics.push({
2542
- code: "PSL_INVALID_RELATION_TARGET",
2543
- message: `Relation field "${model.name}.${relationAttribute.field.name}" references unknown model "${qualifiedTypeName}"`,
2544
- ...source.at(relationAttribute.field.span)
2545
- });
2546
- continue;
2547
- }
2548
2492
  const localColumns = mapFieldNamesToColumns({
2549
- modelName: model.name,
2493
+ model,
2494
+ physicalNames: input.physicalNames,
2550
2495
  fieldNames: parsedRelation.fields,
2551
- mapping,
2552
2496
  source,
2553
2497
  diagnostics,
2554
2498
  span: relationAttribute.relation.span,
@@ -2558,15 +2502,16 @@ function buildModelNodeFromPsl(input) {
2558
2502
  if (relationNullabilityMismatch(relationAttribute.field, localColumns, resolvedFields)) {
2559
2503
  diagnostics.push(relationNullabilityMismatchDiagnostic(model.name, relationAttribute, source));
2560
2504
  resultInvalidFkPairings.push({
2561
- pairKey: fkRelationPairKey(model.name, targetMapping.model.name),
2505
+ declaringModel: model,
2506
+ targetModel,
2562
2507
  ...ifDefined("relationName", parsedRelation.name)
2563
2508
  });
2564
2509
  continue;
2565
2510
  }
2566
2511
  const referencedColumns = mapFieldNamesToColumns({
2567
- modelName: targetMapping.model.name,
2512
+ model: targetModel,
2513
+ physicalNames: input.physicalNames,
2568
2514
  fieldNames: parsedRelation.references,
2569
- mapping: targetMapping,
2570
2515
  source,
2571
2516
  diagnostics,
2572
2517
  span: relationAttribute.relation.span,
@@ -2583,12 +2528,16 @@ function buildModelNodeFromPsl(input) {
2583
2528
  }
2584
2529
  const onDelete = parsedRelation.onDelete ? normalizeReferentialAction(parsedRelation.onDelete) : void 0;
2585
2530
  const onUpdate = parsedRelation.onUpdate ? normalizeReferentialAction(parsedRelation.onUpdate) : void 0;
2586
- const targetNamespaceId = normalizedQualifier !== void 0 ? normalizedQualifier : input.modelNamespaceIds.get(targetMapping.model.name);
2531
+ const targetNamespaceId = resolveNamespaceIdForSqlTarget({
2532
+ bucketName: targetModel.node.syntax.findAncestor(NamespaceDeclarationAst.cast)?.name()?.name() ?? UNSPECIFIED_PSL_NAMESPACE_ID,
2533
+ targetId: input.targetId
2534
+ });
2535
+ const targetTableName = storageName(targetModel, input.physicalNames);
2587
2536
  foreignKeyNodes.push({
2588
2537
  columns: localColumns,
2589
2538
  references: {
2590
- model: targetMapping.model.name,
2591
- table: targetMapping.tableName,
2539
+ model: targetModel.name,
2540
+ table: targetTableName,
2592
2541
  columns: referencedColumns,
2593
2542
  ...ifDefined("namespaceId", targetNamespaceId)
2594
2543
  },
@@ -2598,12 +2547,12 @@ function buildModelNodeFromPsl(input) {
2598
2547
  ...ifDefined("index", parsedRelation.index)
2599
2548
  });
2600
2549
  resultFkRelationMetadata.push({
2601
- declaringModelName: model.name,
2550
+ declaringModelName: model,
2602
2551
  declaringFieldName: relationAttribute.field.name,
2603
2552
  declaringTableName: tableName,
2604
- ...ifDefined("declaringNamespaceId", input.modelNamespaceIds.get(model.name)),
2605
- targetModelName: targetMapping.model.name,
2606
- targetTableName: targetMapping.tableName,
2553
+ ...ifDefined("declaringNamespaceId", modelNamespaceId),
2554
+ targetModelName: targetModel,
2555
+ targetTableName,
2607
2556
  ...ifDefined("targetNamespaceId", targetNamespaceId),
2608
2557
  ...ifDefined("relationName", parsedRelation.name),
2609
2558
  nullable: relationAttribute.field.optional,
@@ -2645,17 +2594,18 @@ function buildModelNodeFromPsl(input) {
2645
2594
  };
2646
2595
  }
2647
2596
  function buildValueObjects(input) {
2648
- const { compositeTypes, enumTypeDescriptors, namedTypeDescriptors, scalarColumnDescriptors, composedExtensions, familyId, targetId, authoringContributions, diagnostics, sources } = input;
2597
+ const { compositeTypes, enumTypeDescriptors, namedTypeDescriptors, scalarColumnDescriptors, composedExtensions, familyId, targetId, authoringContributions, diagnostics, sources, binder } = input;
2649
2598
  const valueObjects = {};
2650
- const compositeTypeNames = new Set(compositeTypes.map((ct) => ct.name));
2651
2599
  for (const compositeType of compositeTypes) {
2652
2600
  const fields = {};
2653
2601
  for (const field of Object.values(compositeType.fields)) {
2654
- if (compositeTypeNames.has(field.typeName)) {
2602
+ const fieldTypeReference = typeReferenceNode(field);
2603
+ const fieldTypeResolution = fieldTypeReference === void 0 ? void 0 : binder.symbolForNode(fieldTypeReference);
2604
+ if (fieldTypeResolution?.kind === "compositeType") {
2655
2605
  const result = {
2656
2606
  type: {
2657
2607
  kind: "valueObject",
2658
- name: field.typeName
2608
+ name: fieldTypeResolution.symbol.name
2659
2609
  },
2660
2610
  nullable: field.optional
2661
2611
  };
@@ -2679,7 +2629,7 @@ function buildValueObjects(input) {
2679
2629
  entityLabel: `Field "${compositeType.name}.${field.name}"`
2680
2630
  });
2681
2631
  if (!resolved.ok) {
2682
- if (!resolved.alreadyReported) diagnostics.push({
2632
+ if (!resolved.alreadyReported && fieldTypeResolution?.kind !== "unresolved") diagnostics.push({
2683
2633
  code: "PSL_UNSUPPORTED_FIELD_TYPE",
2684
2634
  message: `Field "${compositeType.name}.${field.name}" type "${field.typeName}" is not supported`,
2685
2635
  ...diagnosticSource(sources, field.node.syntax).at(field.span)
@@ -2748,7 +2698,7 @@ function collectPolymorphismDeclarations(identities, symbols, sources, binder, d
2748
2698
  const baseDeclarations = /* @__PURE__ */ new Map();
2749
2699
  for (const { model, key } of identities.values()) {
2750
2700
  const source = diagnosticSource(sources, model.node.syntax);
2751
- const discriminatorNode = findModelAttributeNode(model, "discriminator");
2701
+ const discriminatorNode = getAttribute(model.attributes, "discriminator")?.node;
2752
2702
  if (discriminatorNode !== void 0) {
2753
2703
  const parsed = interpretModelAttribute({
2754
2704
  node: discriminatorNode,
@@ -2768,13 +2718,14 @@ function collectPolymorphismDeclarations(identities, symbols, sources, binder, d
2768
2718
  ...source.at(span)
2769
2719
  });
2770
2720
  else discriminatorDeclarations.set(key, {
2721
+ model,
2771
2722
  fieldName: parsed.field,
2772
2723
  span,
2773
2724
  source
2774
2725
  });
2775
2726
  }
2776
2727
  }
2777
- const baseNode = findModelAttributeNode(model, "base");
2728
+ const baseNode = getAttribute(model.attributes, "base")?.node;
2778
2729
  if (baseNode !== void 0) {
2779
2730
  const parsed = interpretModelAttribute({
2780
2731
  node: baseNode,
@@ -2789,6 +2740,7 @@ function collectPolymorphismDeclarations(identities, symbols, sources, binder, d
2789
2740
  const base = identities.get(parsed.base.declaration);
2790
2741
  invariant(base !== void 0, `Resolved base model "${parsed.base.declaration.name}" is missing from the collected model identities`);
2791
2742
  baseDeclarations.set(key, {
2743
+ model,
2792
2744
  source,
2793
2745
  base,
2794
2746
  value: parsed.value,
@@ -2802,7 +2754,7 @@ function collectPolymorphismDeclarations(identities, symbols, sources, binder, d
2802
2754
  baseDeclarations
2803
2755
  };
2804
2756
  }
2805
- function resolvePolymorphism(models, discriminatorDeclarations, baseDeclarations, modelMappings, syntheticPkFieldsByVariant, stiBaseFieldsByBase, diagnostics) {
2757
+ function resolvePolymorphism(models, physicalNames, discriminatorDeclarations, baseDeclarations, syntheticPkFieldsByVariant, stiBaseFieldsByBase, diagnostics) {
2806
2758
  let patched = models;
2807
2759
  for (const [baseKey, fieldNames] of stiBaseFieldsByBase) {
2808
2760
  const baseModel = patched[baseKey];
@@ -2813,7 +2765,7 @@ function resolvePolymorphism(models, discriminatorDeclarations, baseDeclarations
2813
2765
  };
2814
2766
  }
2815
2767
  for (const [modelKey, decl] of discriminatorDeclarations) {
2816
- const modelName = modelMappings.get(modelKey)?.model.name;
2768
+ const modelName = decl.model.name;
2817
2769
  if (baseDeclarations.has(modelKey)) {
2818
2770
  diagnostics.push({
2819
2771
  code: "PSL_DISCRIMINATOR_AND_BASE",
@@ -2826,10 +2778,9 @@ function resolvePolymorphism(models, discriminatorDeclarations, baseDeclarations
2826
2778
  if (!model) continue;
2827
2779
  const variants = {};
2828
2780
  const seenValues = /* @__PURE__ */ new Map();
2829
- for (const [variantKey, baseDecl] of baseDeclarations) {
2781
+ for (const baseDecl of baseDeclarations.values()) {
2830
2782
  if (baseDecl.base.key !== modelKey) continue;
2831
- const variantName = modelMappings.get(variantKey)?.model.name;
2832
- invariant(variantName !== void 0, `Variant "${variantKey}" is missing from the model mappings`);
2783
+ const variantName = baseDecl.model.name;
2833
2784
  const existingVariant = seenValues.get(baseDecl.value);
2834
2785
  if (existingVariant) {
2835
2786
  diagnostics.push({
@@ -2860,8 +2811,7 @@ function resolvePolymorphism(models, discriminatorDeclarations, baseDeclarations
2860
2811
  };
2861
2812
  }
2862
2813
  for (const [variantKey, baseDecl] of baseDeclarations) {
2863
- const variantMapping = modelMappings.get(variantKey);
2864
- const variantName = variantMapping?.model.name;
2814
+ const variantName = baseDecl.model.name;
2865
2815
  const baseName = baseDecl.base.model.name;
2866
2816
  if (!discriminatorDeclarations.has(baseDecl.base.key)) {
2867
2817
  diagnostics.push({
@@ -2874,8 +2824,7 @@ function resolvePolymorphism(models, discriminatorDeclarations, baseDeclarations
2874
2824
  if (discriminatorDeclarations.has(variantKey)) continue;
2875
2825
  const variantModel = patched[variantKey];
2876
2826
  if (!variantModel) continue;
2877
- const baseMapping = modelMappings.get(baseDecl.base.key);
2878
- const resolvedTable = variantMapping?.model.attributes.some((attr) => attr.name === "map") ?? false ? variantMapping?.tableName : baseMapping?.tableName;
2827
+ const resolvedTable = storageName(getAttribute(baseDecl.model.attributes, "map") !== void 0 ? baseDecl.model : baseDecl.base.model, physicalNames);
2879
2828
  const patchedVariant = {
2880
2829
  ...variantModel,
2881
2830
  base: crossRef(baseName, baseDecl.base.namespaceId),
@@ -3041,12 +2990,30 @@ function stripStorageOnlyDomainFields(model, fieldNames) {
3041
2990
  }
3042
2991
  };
3043
2992
  }
3044
- function voicedAsUncomposedNamespace(diagnostic, composedExtensions, context) {
2993
+ function backrelationTargetSymbol(field, binder) {
2994
+ const typeReference = typeReferenceNode(field);
2995
+ if (typeReference === void 0) return void 0;
2996
+ const resolution = binder.symbolForNode(typeReference);
2997
+ return resolution?.kind === "model" ? resolution.symbol : void 0;
2998
+ }
2999
+ function relationTargetKindLabel(resolution) {
3000
+ switch (resolution.kind) {
3001
+ case "compositeType": return "composite type";
3002
+ case "namedType": return "named type";
3003
+ case "block": return resolution.symbol.keyword;
3004
+ case "namespace":
3005
+ case "contributedNamespace": return "namespace";
3006
+ case "contributedType": return "type";
3007
+ default: return;
3008
+ }
3009
+ }
3010
+ function replacedBySqlTypeVoice(diagnostic, composedExtensions, context) {
3045
3011
  const data = diagnostic.data;
3046
3012
  if (data?.["reference"] !== "type") return false;
3013
+ if (data["constructorCall"] !== true) return false;
3047
3014
  const name = data["name"];
3048
3015
  if (typeof name !== "string") return false;
3049
- return checkUncomposedNamespace(name, composedExtensions, context) !== void 0;
3016
+ return replacesUnresolvedTypeVoice(name, composedExtensions, context);
3050
3017
  }
3051
3018
  function interpretPslDocumentToSqlContract(input) {
3052
3019
  if (!input.target) throw new InternalError("PSL interpretation requires an explicit target context from composition.");
@@ -3078,7 +3045,7 @@ function interpretPslDocumentToSqlContract(input) {
3078
3045
  targetId: input.target.targetId
3079
3046
  })
3080
3047
  });
3081
- diagnostics.push(...binderDiagnostics.filter((diagnostic) => !voicedAsUncomposedNamespace(diagnostic, composedExtensionNames, {
3048
+ diagnostics.push(...binderDiagnostics.filter((diagnostic) => !replacedBySqlTypeVoice(diagnostic, composedExtensionNames, {
3082
3049
  familyId: "sql",
3083
3050
  targetId: input.target.targetId,
3084
3051
  authoringContributions: input.authoringContributions
@@ -3108,7 +3075,6 @@ function interpretPslDocumentToSqlContract(input) {
3108
3075
  });
3109
3076
  const models = [];
3110
3077
  const modelEntries = [];
3111
- const modelNamespaceIds = /* @__PURE__ */ new Map();
3112
3078
  const compositeTypes = [];
3113
3079
  const collectScope = (bucketName, scopeModels, scopeCompositeTypes) => {
3114
3080
  const resolvedNamespaceId = resolveNamespaceIdForSqlTarget({
@@ -3121,15 +3087,40 @@ function interpretPslDocumentToSqlContract(input) {
3121
3087
  model,
3122
3088
  namespaceId: resolvedNamespaceId
3123
3089
  });
3124
- if (resolvedNamespaceId !== void 0) modelNamespaceIds.set(model.name, resolvedNamespaceId);
3125
3090
  }
3126
3091
  for (const compositeType of scopeCompositeTypes) compositeTypes.push(compositeType);
3127
3092
  };
3128
3093
  collectScope(UNSPECIFIED_PSL_NAMESPACE_ID, Object.values(topLevel.models), Object.values(topLevel.compositeTypes));
3129
3094
  for (const namespace of namespaceSymbols) collectScope(namespace.name, Object.values(namespace.models), Object.values(namespace.compositeTypes));
3095
+ const physicalNames = /* @__PURE__ */ new Map();
3096
+ for (const model of models) {
3097
+ const mapNode = getAttribute(model.attributes, "map")?.node;
3098
+ const mapped = mapNode === void 0 ? void 0 : interpretModelAttribute({
3099
+ node: mapNode,
3100
+ symbols: input.symbolTable,
3101
+ spec: sqlAttributeSpecs.model.map(),
3102
+ model,
3103
+ sources: input.sources,
3104
+ binder,
3105
+ diagnostics
3106
+ });
3107
+ physicalNames.set(model, mapped?.name ?? defaultTableName(model.name));
3108
+ for (const field of Object.values(model.fields)) {
3109
+ const mapNode = getAttribute(field.attributes, "map")?.node;
3110
+ const mapped = mapNode === void 0 ? void 0 : interpretFieldAttribute({
3111
+ node: mapNode,
3112
+ symbols: input.symbolTable,
3113
+ spec: sqlAttributeSpecs.field.map(),
3114
+ model,
3115
+ field,
3116
+ sources: input.sources,
3117
+ binder,
3118
+ diagnostics
3119
+ });
3120
+ physicalNames.set(field, mapped?.name ?? field.name);
3121
+ }
3122
+ }
3130
3123
  const defaultNamespaceId = input.target.defaultNamespaceId;
3131
- const modelNames = new Set(models.map((model) => model.name));
3132
- const compositeTypeNames = new Set(compositeTypes.map((ct) => ct.name));
3133
3124
  const composedExtensions = new Set(input.composedExtensions ?? []);
3134
3125
  const composedExtensionContracts = input.composedExtensionContracts;
3135
3126
  const defaultFunctionRegistry = input.controlMutationDefaults?.defaultFunctionRegistry ?? /* @__PURE__ */ new Map();
@@ -3199,17 +3190,15 @@ function interpretPslDocumentToSqlContract(input) {
3199
3190
  } },
3200
3191
  warnings: authoringWarnings
3201
3192
  };
3202
- const earlyModelMappingsByCoordinate = buildModelMappings(input.symbolTable, modelEntries, defaultNamespaceId, createPslDiagnosticCollector(input.sources), input.sources, binder);
3203
- const modelCoordinates = /* @__PURE__ */ new Map();
3204
- for (const entry of modelEntries) {
3205
- const nsId = entry.namespaceId ?? defaultNamespaceId;
3206
- const mapping = earlyModelMappingsByCoordinate.get(modelCoordinateKey(nsId, entry.model.name));
3207
- if (mapping !== void 0) modelCoordinates.set(entry.model, {
3208
- namespaceId: nsId,
3209
- tableName: mapping.tableName
3210
- });
3211
- }
3212
- const modelCoordinateOf = (model) => modelCoordinates.get(model);
3193
+ const modelCoordinateOf = (model) => {
3194
+ return {
3195
+ namespaceId: resolveNamespaceIdForSqlTarget({
3196
+ bucketName: model.node.syntax.findAncestor(NamespaceDeclarationAst.cast)?.name()?.name() ?? UNSPECIFIED_PSL_NAMESPACE_ID,
3197
+ targetId: input.target.targetId
3198
+ }) ?? defaultNamespaceId,
3199
+ tableName: storageName(model, physicalNames)
3200
+ };
3201
+ };
3213
3202
  const namespaceExtensionEntities = /* @__PURE__ */ new Map();
3214
3203
  const fileExtensionEntityRows = (rows, blocks) => {
3215
3204
  for (const row of rows) {
@@ -3272,10 +3261,7 @@ function interpretPslDocumentToSqlContract(input) {
3272
3261
  diagnostics
3273
3262
  });
3274
3263
  const storageTypes = { ...namedTypeResult.storageTypes };
3275
- const modelMappingsByCoordinate = buildModelMappings(input.symbolTable, modelEntries, defaultNamespaceId, diagnostics, input.sources, binder);
3276
- const modelMappings = /* @__PURE__ */ new Map();
3277
- for (const mapping of modelMappingsByCoordinate.values()) modelMappings.set(mapping.model.name, mapping);
3278
- const modelNodes = [];
3264
+ const modelNodes = /* @__PURE__ */ new Map();
3279
3265
  const fkRelationMetadata = [];
3280
3266
  const invalidFkPairings = [];
3281
3267
  const backrelationCandidates = [];
@@ -3284,15 +3270,10 @@ function interpretPslDocumentToSqlContract(input) {
3284
3270
  const modelAttributeEntitiesByNamespace = /* @__PURE__ */ new Map();
3285
3271
  for (const { model, namespaceId } of modelEntries) {
3286
3272
  const coordinate = modelCoordinateKey(namespaceId ?? defaultNamespaceId, model.name);
3287
- const mapping = modelMappingsByCoordinate.get(coordinate);
3288
- if (!mapping) continue;
3289
3273
  const result = buildModelNodeFromPsl({
3290
3274
  model,
3291
- mapping,
3292
- modelMappings,
3293
- modelMappingsByCoordinate,
3294
- modelNames,
3295
- compositeTypeNames,
3275
+ physicalNames,
3276
+ namespaceId,
3296
3277
  enumTypeDescriptors: allEnumTypeDescriptors,
3297
3278
  namedTypeDescriptors: namedTypeResult.namedTypeDescriptors,
3298
3279
  composedExtensions,
@@ -3308,7 +3289,6 @@ function interpretPslDocumentToSqlContract(input) {
3308
3289
  binder,
3309
3290
  symbolTable: input.symbolTable,
3310
3291
  diagnostics,
3311
- modelNamespaceIds,
3312
3292
  ...enumHandlesByName.size > 0 ? { enumHandles: enumHandlesByName } : {},
3313
3293
  capabilities: input.capabilities,
3314
3294
  ...namespaceExtensionEntities.size > 0 ? { namespaceExtensionEntities } : {},
@@ -3318,7 +3298,7 @@ function interpretPslDocumentToSqlContract(input) {
3318
3298
  defaultNamespaceId,
3319
3299
  parsedBlocks
3320
3300
  });
3321
- modelNodes.push(namespaceId !== void 0 ? {
3301
+ modelNodes.set(model, namespaceId !== void 0 ? {
3322
3302
  ...result.modelNode,
3323
3303
  namespaceId
3324
3304
  } : result.modelNode);
@@ -3327,8 +3307,8 @@ function interpretPslDocumentToSqlContract(input) {
3327
3307
  backrelationCandidates.push(...result.backrelationCandidates);
3328
3308
  modelResolvedFields.set(coordinate, result.resolvedFields);
3329
3309
  if (result.crossSpaceRelations.length > 0) {
3330
- const existing = crossSpaceRelationsByModel.get(model.name) ?? [];
3331
- crossSpaceRelationsByModel.set(model.name, [...existing, ...result.crossSpaceRelations]);
3310
+ const existing = crossSpaceRelationsByModel.get(model) ?? [];
3311
+ crossSpaceRelationsByModel.set(model, [...existing, ...result.crossSpaceRelations]);
3332
3312
  }
3333
3313
  if (Object.keys(result.modelAttributeEntities).length > 0) {
3334
3314
  const nsKey = namespaceId ?? defaultNamespaceId;
@@ -3343,13 +3323,13 @@ function interpretPslDocumentToSqlContract(input) {
3343
3323
  const { modelRelations, fkRelationsByPair, fkRelationsByDeclaringModel } = indexFkRelations({ fkRelationMetadata });
3344
3324
  const modelIdColumns = /* @__PURE__ */ new Map();
3345
3325
  const modelUniqueColumnSets = /* @__PURE__ */ new Map();
3346
- for (const modelNode of modelNodes) {
3347
- if (modelNode.id) modelIdColumns.set(modelNode.modelName, modelNode.id.columns);
3326
+ for (const [model, modelNode] of modelNodes) {
3327
+ if (modelNode.id) modelIdColumns.set(model, modelNode.id.columns);
3348
3328
  const uniqueColumnSets = [];
3349
3329
  if (modelNode.id) uniqueColumnSets.push(modelNode.id.columns);
3350
3330
  for (const unique of modelNode.uniques ?? []) uniqueColumnSets.push(unique.columns);
3351
3331
  for (const index of modelNode.indexes ?? []) if (index.unique === true && index.columns !== void 0 && index.where === void 0) uniqueColumnSets.push(index.columns);
3352
- modelUniqueColumnSets.set(modelNode.modelName, uniqueColumnSets);
3332
+ modelUniqueColumnSets.set(model, uniqueColumnSets);
3353
3333
  }
3354
3334
  applyBackrelationCandidates({
3355
3335
  backrelationCandidates,
@@ -3376,14 +3356,12 @@ function interpretPslDocumentToSqlContract(input) {
3376
3356
  }];
3377
3357
  })), input.symbolTable, input.sources, binder, diagnostics);
3378
3358
  const stiVariantKeys = /* @__PURE__ */ new Set();
3379
- for (const variantKey of baseDeclarations.keys()) if (!(modelMappingsByCoordinate.get(variantKey)?.model.attributes.some((attr) => attr.name === "map") ?? false)) stiVariantKeys.add(variantKey);
3359
+ for (const [variantKey, declaration] of baseDeclarations) if (!(getAttribute(declaration.model.attributes, "map") !== void 0)) stiVariantKeys.add(variantKey);
3380
3360
  for (const variantKey of stiVariantKeys) {
3381
- const variantMapping = modelMappingsByCoordinate.get(variantKey);
3382
- if (variantMapping === void 0) continue;
3383
- const variantName = variantMapping.model.name;
3384
3361
  const baseDecl = baseDeclarations.get(variantKey);
3385
- invariant(baseDecl !== void 0, `stiVariantKeys is derived from baseDeclarations.keys(), so "${variantName}" must have a base declaration`);
3386
- for (const attribute of variantMapping.model.node.attributes()) {
3362
+ invariant(baseDecl !== void 0, `stiVariantKeys is derived from baseDeclarations.keys(), so "${variantKey}" must have a base declaration`);
3363
+ const variantName = baseDecl.model.name;
3364
+ for (const attribute of baseDecl.model.node.attributes()) {
3387
3365
  if (attribute.name()?.isSimpleName("check") !== true) continue;
3388
3366
  diagnostics.push({
3389
3367
  code: PSL_CHECK_ON_STI_VARIANT,
@@ -3392,7 +3370,10 @@ function interpretPslDocumentToSqlContract(input) {
3392
3370
  });
3393
3371
  }
3394
3372
  }
3395
- const { modelNodes: mtiLinkedModelNodes, syntheticPkFieldsByVariant } = materializeMtiVariantStorageLinks(modelNodes, baseDeclarations, stiVariantKeys, defaultNamespaceId);
3373
+ const { modelNodes: mtiLinkedModelNodes, syntheticPkFieldsByVariant } = materializeMtiVariantStorageLinks(Array.from(modelNodes, ([symbol, model]) => ({
3374
+ ...model,
3375
+ ...modelRelations.has(symbol) ? { relations: [...modelRelations.get(symbol) ?? []].sort((left, right) => compareStrings(left.fieldName, right.fieldName)) } : {}
3376
+ })), baseDeclarations, stiVariantKeys, defaultNamespaceId);
3396
3377
  const { modelNodes: stiColumnModelNodes, stiBaseFieldsByBase } = materializeStiVariantStorageColumns(mtiLinkedModelNodes, baseDeclarations, stiVariantKeys, defaultNamespaceId);
3397
3378
  const valueObjects = buildValueObjects({
3398
3379
  compositeTypes,
@@ -3445,10 +3426,7 @@ function interpretPslDocumentToSqlContract(input) {
3445
3426
  ...Object.keys(validEnumHandles).length > 0 ? { enums: validEnumHandles } : {},
3446
3427
  ...namespaceExtensionEntities.size > 0 ? { namespaces: [...namespaceExtensionEntities.keys()] } : {},
3447
3428
  createNamespace: createNamespaceWithExtensions,
3448
- models: stiColumnModelNodes.map((model) => ({
3449
- ...model,
3450
- ...modelRelations.has(model.modelName) ? { relations: [...modelRelations.get(model.modelName) ?? []].sort((left, right) => compareStrings(left.fieldName, right.fieldName)) } : {}
3451
- }))
3429
+ models: stiColumnModelNodes
3452
3430
  }, input.codecLookup);
3453
3431
  const modelsForPatch = {};
3454
3432
  for (const [namespaceId, namespaceSlice] of Object.entries(contract.domain.namespaces)) for (const [modelName, model] of Object.entries(namespaceSlice.models)) {
@@ -3458,7 +3436,7 @@ function interpretPslDocumentToSqlContract(input) {
3458
3436
  }
3459
3437
  let patchedModels = patchModelDomainFields(modelsForPatch, modelResolvedFields);
3460
3438
  const polyDiagnostics = createPslDiagnosticCollector(input.sources);
3461
- patchedModels = resolvePolymorphism(patchedModels, discriminatorDeclarations, baseDeclarations, modelMappingsByCoordinate, syntheticPkFieldsByVariant, stiBaseFieldsByBase, polyDiagnostics);
3439
+ patchedModels = resolvePolymorphism(patchedModels, physicalNames, discriminatorDeclarations, baseDeclarations, syntheticPkFieldsByVariant, stiBaseFieldsByBase, polyDiagnostics);
3462
3440
  if (polyDiagnostics.length > 0) return notOk({
3463
3441
  summary: "PSL to SQL contract interpretation failed",
3464
3442
  diagnostics: polyDiagnostics.toExternal()
@@ -3478,4 +3456,4 @@ function interpretPslDocumentToSqlContract(input) {
3478
3456
  //#endregion
3479
3457
  export { interpretPslDocumentToSqlContract as a, resolveFieldTypeDescriptor as c, indexFkRelations as i, buildEntityTypesByDiscriminator as n, normalizeReferentialAction as o, entryForTag as r, readDataTypeDefault as s, applyBackrelationCandidates as t };
3480
3458
 
3481
- //# sourceMappingURL=interpreter-BMMGMTBa-CT5iKl13.mjs.map
3459
+ //# sourceMappingURL=interpreter-gs7fSAIb-DuqyTGAB.mjs.map