@prisma/orm-family-mongo 8.0.0-rc.14-dev.12 → 8.0.0-rc.14-dev.13

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.
@@ -8,11 +8,11 @@ import { ArrayLiteralAst, FunctionCallAst, PathExprAst } from "@prisma/orm-frame
8
8
  import { notOk, ok } from "@prisma/orm-framework/utils/result";
9
9
  import { resolveToOneRelationNullable } from "@prisma/orm-framework/contract-authoring";
10
10
  import { checkUncomposedNamespace, getAuthoringFieldPreset, hasRegisteredFieldNamespace, instantiateAuthoringEntityType, isAuthoringEntityTypeDescriptor, isAuthoringTypeConstructorDescriptor } from "@prisma/orm-framework/components/authoring";
11
- import { bool, createBinder, createPslDiagnosticCollector, diagnosticSource, entityRef, fieldAttribute, fieldRef, funcCall, identifier, int, interpretAttribute, interpretExtensionBlocks, json, list, mapPslDiagnostics, modelAttribute, nodePslSpan, num, oneOf, optional, record, referencedFieldRef, str } from "@prisma/orm-framework/psl-parser";
11
+ import { bool, createBinder, createPslDiagnosticCollector, diagnosticSource, entityRef, fieldAttribute, fieldRef, funcCall, identifier, int, interpretAttribute, interpretExtensionBlocks, json, list, mapPslDiagnostics, modelAttribute, nodePslSpan, num, oneOf, optional, record, referencedFieldRef, str, typeReferenceNode } from "@prisma/orm-framework/psl-parser";
12
12
  import { claimedBlockKeywords, consumeInvalidFkPairing, enumMemberAttributeDiagnostics, fkRelationPairKey, instantiatePslFieldPreset, reportUncomposedNamespace, reportUnknownFieldPreset, requiredOneToOneBackrelationDiagnostic, unsupportedBlockDiagnostic } from "@prisma/orm-framework/psl-parser/interpret";
13
13
  import { assertDefined } from "@prisma/orm-framework/utils/assertions";
14
14
  import { ifDefined } from "@prisma/orm-framework/utils/defined";
15
- //#region ../../../2-mongo-family/2-authoring/contract-psl/dist/interpreter-Da0fGDSM.mjs
15
+ //#region ../../../2-mongo-family/2-authoring/contract-psl/dist/interpreter-DSD7dXPk.mjs
16
16
  /**
17
17
  * The `bsonType` keyword for a list of BSON type names: the name itself for one entry, the list for several.
18
18
  */
@@ -258,12 +258,6 @@ function resolveFieldPreset(input) {
258
258
  ...ifDefined("executionDefaults", instantiated.executionDefaults)
259
259
  };
260
260
  }
261
- function findModelAttributeNode(model, name) {
262
- for (const attribute of model.node.attributes()) if (attribute.name()?.isSimpleName(name) === true) return attribute;
263
- }
264
- function findFieldAttributeNode(field, name) {
265
- for (const attribute of field.node.attributes()) if (attribute.name()?.isSimpleName(name) === true) return attribute;
266
- }
267
261
  function buildModelAttributeCtx(input) {
268
262
  return {
269
263
  sources: input.sources,
@@ -736,14 +730,24 @@ function relationNullabilityMismatchDiagnostic(modelName, field, sources) {
736
730
  ...source.at(field.span)
737
731
  };
738
732
  }
739
- function resolveFieldMappings(input) {
740
- const { model, specContext, sources, binder, diagnostics } = input;
741
- const pslNameToMapped = /* @__PURE__ */ new Map();
733
+ function resolvePhysicalNames(input) {
734
+ const { model, physicalNames, specContext, sources, binder, diagnostics } = input;
735
+ const modelMap = model.attributes.find((attr) => attr.name === "map");
736
+ const collectionName = modelMap ? interpretModelAttribute({
737
+ symbols: specContext.symbols,
738
+ node: modelMap.node,
739
+ spec: mongoAttributeSpecs.model.map(specContext),
740
+ model,
741
+ sources,
742
+ binder,
743
+ diagnostics
744
+ })?.name : void 0;
745
+ physicalNames.set(model, collectionName ?? defaultCollectionName(model.name));
742
746
  for (const field of Object.values(model.fields)) {
743
- const mapNode = findFieldAttributeNode(field, "map");
744
- const mapped = (mapNode ? interpretFieldAttribute({
747
+ const fieldMap = field.attributes.find((attr) => attr.name === "map");
748
+ const mapped = fieldMap ? interpretFieldAttribute({
745
749
  symbols: specContext.symbols,
746
- node: mapNode,
750
+ node: fieldMap.node,
747
751
  spec: mongoAttributeSpecs.field.map({
748
752
  ...specContext,
749
753
  field
@@ -753,33 +757,25 @@ function resolveFieldMappings(input) {
753
757
  sources,
754
758
  binder,
755
759
  diagnostics
756
- })?.name : void 0) ?? field.name;
757
- pslNameToMapped.set(field.name, mapped);
760
+ })?.name : void 0;
761
+ physicalNames.set(field, mapped ?? field.name);
758
762
  }
759
- return { pslNameToMapped };
760
763
  }
761
- function resolveCollectionName(input) {
762
- const { model, specContext, sources, binder, diagnostics } = input;
763
- const mapNode = findModelAttributeNode(model, "map");
764
- return (mapNode ? interpretModelAttribute({
765
- symbols: specContext.symbols,
766
- node: mapNode,
767
- spec: mongoAttributeSpecs.model.map(specContext),
768
- model,
769
- sources,
770
- binder,
771
- diagnostics
772
- })?.name : void 0) ?? defaultCollectionName(model.name);
764
+ function physicalName(physicalNames, symbol) {
765
+ assertDefined(symbol, "Physical names require a bound declaration");
766
+ const name = physicalNames.get(symbol);
767
+ assertDefined(name, "Physical names must be populated before lowering");
768
+ return name;
773
769
  }
774
770
  function mongoCrossRef(modelName) {
775
771
  return crossRef(modelName, UNBOUND_NAMESPACE_ID);
776
772
  }
777
- function collectPolymorphismDeclarations(models, specContextFor, modelMetadataByName, sources, binder, diagnostics) {
773
+ function collectPolymorphismDeclarations(models, specContextFor, physicalNames, sources, binder, diagnostics) {
778
774
  const discriminatorDeclarations = /* @__PURE__ */ new Map();
779
775
  const baseDeclarations = /* @__PURE__ */ new Map();
780
776
  for (const model of models) {
781
777
  const specContext = specContextFor(model);
782
- const discNode = findModelAttributeNode(model, "discriminator");
778
+ const discNode = model.attributes.find((attr) => attr.name === "discriminator")?.node;
783
779
  if (discNode) {
784
780
  const parsed = interpretModelAttribute({
785
781
  symbols: specContext.symbols,
@@ -805,7 +801,7 @@ function collectPolymorphismDeclarations(models, specContextFor, modelMetadataBy
805
801
  });
806
802
  }
807
803
  }
808
- const baseNode = findModelAttributeNode(model, "base");
804
+ const baseNode = model.attributes.find((attr) => attr.name === "base")?.node;
809
805
  if (baseNode) {
810
806
  const parsed = interpretModelAttribute({
811
807
  symbols: specContext.symbols,
@@ -817,7 +813,7 @@ function collectPolymorphismDeclarations(models, specContextFor, modelMetadataBy
817
813
  diagnostics
818
814
  });
819
815
  if (parsed) {
820
- const collectionName = modelMetadataByName.get(model.name)?.collectionName ?? defaultCollectionName(model.name);
816
+ const collectionName = physicalName(physicalNames, model);
821
817
  baseDeclarations.set(model, {
822
818
  base: parsed.base.declaration,
823
819
  value: parsed.value,
@@ -834,7 +830,7 @@ function collectPolymorphismDeclarations(models, specContextFor, modelMetadataBy
834
830
  };
835
831
  }
836
832
  function resolvePolymorphism(input) {
837
- const { discriminatorDeclarations, baseDeclarations, modelMetadataByName, indexSpans, modelIndexesByName, indexSources } = input;
833
+ const { discriminatorDeclarations, baseDeclarations, physicalNames, indexSpans, modelIndexesByName, indexSources } = input;
838
834
  let patched = input.models;
839
835
  let roots = input.roots;
840
836
  let collections = input.collections;
@@ -851,7 +847,7 @@ function resolvePolymorphism(input) {
851
847
  }
852
848
  const model = patched[modelName];
853
849
  if (!model) continue;
854
- const mappedDiscriminatorField = modelMetadataByName.get(modelName)?.fieldMappings.pslNameToMapped.get(decl.fieldName) ?? decl.fieldName;
850
+ const mappedDiscriminatorField = physicalName(physicalNames, declaration.fields[decl.fieldName]);
855
851
  if (!Object.hasOwn(model.fields, mappedDiscriminatorField)) {
856
852
  diagnostics.push({
857
853
  code: "PSL_DISCRIMINATOR_FIELD_NOT_FOUND",
@@ -913,7 +909,7 @@ function resolvePolymorphism(input) {
913
909
  storage: { collection: baseCollection }
914
910
  }
915
911
  };
916
- const variantCollectionName = modelMetadataByName.get(variantName)?.collectionName ?? defaultCollectionName(variantName);
912
+ const variantCollectionName = physicalName(physicalNames, variant);
917
913
  if (roots[variantCollectionName]?.model === variantName) if (variantCollectionName === baseCollection && baseModel) roots = {
918
914
  ...roots,
919
915
  [variantCollectionName]: mongoCrossRef(baseName)
@@ -1050,12 +1046,12 @@ function resolveIndexKeys(parsedFields, defaultDirection, ctx) {
1050
1046
  direction: defaultDirection
1051
1047
  };
1052
1048
  return {
1053
- field: `${ctx.fieldMappings.pslNameToMapped.get(field.scope) ?? field.scope}.$**`,
1049
+ field: `${physicalName(ctx.physicalNames, ctx.pslModel.fields[field.scope])}.$**`,
1054
1050
  direction: defaultDirection
1055
1051
  };
1056
1052
  }
1057
1053
  return {
1058
- field: ctx.fieldMappings.pslNameToMapped.get(field.name) ?? field.name,
1054
+ field: physicalName(ctx.physicalNames, ctx.pslModel.fields[field.name]),
1059
1055
  direction: field.direction ?? defaultDirection
1060
1056
  };
1061
1057
  }),
@@ -1198,20 +1194,20 @@ function nestedIndexPath(node) {
1198
1194
  }
1199
1195
  }
1200
1196
  }
1201
- function nestedIndexPathMessage(path, pslModel, compositeTypeNames) {
1197
+ function nestedIndexPathMessage(path, pslModel, binder) {
1202
1198
  const [root = ""] = path;
1203
1199
  const label = `Index field "${path.join(".")}" on model "${pslModel.name}"`;
1204
- const rootType = Object.hasOwn(pslModel.fields, root) ? pslModel.fields[root]?.typeName : void 0;
1205
- return rootType !== void 0 && compositeTypeNames.has(rootType) ? `${label} is a path into a composite type; indexes on fields of a composite type are not supported yet. Index a top-level field of "${pslModel.name}" or remove the index.` : `${label} is a dotted path, but "${root}" is not a field of "${pslModel.name}" whose type is a composite type, so the path names no field. List fields of "${pslModel.name}" by name.`;
1200
+ const rootField = Object.hasOwn(pslModel.fields, root) ? pslModel.fields[root] : void 0;
1201
+ return rootField !== void 0 && fieldTypeResolution(rootField, binder)?.kind === "compositeType" ? `${label} is a path into a composite type; indexes on fields of a composite type are not supported yet. Index a top-level field of "${pslModel.name}" or remove the index.` : `${label} is a dotted path, but "${root}" is not a field of "${pslModel.name}" whose type is a composite type, so the path names no field. List fields of "${pslModel.name}" by name.`;
1206
1202
  }
1207
- function collectIndexes(pslModel, specContext, fieldMappings, modelNames, compositeTypeNames, sources, binder, diagnostics, indexSpans, indexSources) {
1203
+ function collectIndexes(pslModel, specContext, physicalNames, sources, binder, diagnostics, indexSpans, indexSources) {
1208
1204
  const indexes = [];
1209
1205
  let textIndexCount = 0;
1210
1206
  const indexableFieldNames = /* @__PURE__ */ new Set();
1211
- for (const field of Object.values(pslModel.fields)) if (!modelNames.has(field.typeName)) indexableFieldNames.add(field.name);
1207
+ for (const field of Object.values(pslModel.fields)) if (fieldTypeResolution(field, binder)?.kind !== "model") indexableFieldNames.add(field.name);
1212
1208
  for (const field of Object.values(pslModel.fields)) {
1213
- if (modelNames.has(field.typeName)) continue;
1214
- const uniqueNode = findFieldAttributeNode(field, "unique");
1209
+ if (fieldTypeResolution(field, binder)?.kind === "model") continue;
1210
+ const uniqueNode = field.attributes.find((attr) => attr.name === "unique")?.node;
1215
1211
  if (!uniqueNode) continue;
1216
1212
  if (interpretFieldAttribute({
1217
1213
  symbols: specContext.symbols,
@@ -1228,7 +1224,7 @@ function collectIndexes(pslModel, specContext, fieldMappings, modelNames, compos
1228
1224
  }) === void 0) continue;
1229
1225
  const fieldUniqueIndex = new MongoIndex({
1230
1226
  keys: [{
1231
- field: fieldMappings.pslNameToMapped.get(field.name) ?? field.name,
1227
+ field: physicalName(physicalNames, field),
1232
1228
  direction: 1
1233
1229
  }],
1234
1230
  unique: true
@@ -1237,15 +1233,13 @@ function collectIndexes(pslModel, specContext, fieldMappings, modelNames, compos
1237
1233
  indexSpans.set(fieldUniqueIndex, nodePslSpan(uniqueNode.syntax, sources));
1238
1234
  indexSources.set(fieldUniqueIndex, diagnosticSource(sources, uniqueNode.syntax));
1239
1235
  }
1240
- const attributeNodes = Array.from(pslModel.node.attributes());
1241
- for (const [attrIndex, attr] of pslModel.attributes.entries()) {
1236
+ for (const attr of pslModel.attributes) {
1242
1237
  if (attr.name !== "index" && attr.name !== "unique" && attr.name !== "textIndex") continue;
1243
- const node = attributeNodes[attrIndex];
1244
- if (!node) continue;
1238
+ const node = attr.node;
1245
1239
  const source = diagnosticSource(sources, node.syntax);
1246
1240
  const ctx = {
1247
1241
  pslModel,
1248
- fieldMappings,
1242
+ physicalNames,
1249
1243
  indexableFieldNames,
1250
1244
  source,
1251
1245
  span: attr.span,
@@ -1255,7 +1249,7 @@ function collectIndexes(pslModel, specContext, fieldMappings, modelNames, compos
1255
1249
  if (nested !== void 0) {
1256
1250
  diagnostics.push({
1257
1251
  code: "PSL_INVALID_INDEX",
1258
- message: nestedIndexPathMessage(nested.path, pslModel, compositeTypeNames),
1252
+ message: nestedIndexPathMessage(nested.path, pslModel, binder),
1259
1253
  ...source.at(nodePslSpan(nested.syntax, sources))
1260
1254
  });
1261
1255
  continue;
@@ -1303,13 +1297,11 @@ function collectIndexes(pslModel, specContext, fieldMappings, modelNames, compos
1303
1297
  }
1304
1298
  return indexes;
1305
1299
  }
1306
- function isRelationField(field, modelNames) {
1307
- return modelNames.has(field.typeName);
1300
+ function fieldTypeResolution(field, binder) {
1301
+ const node = typeReferenceNode(field);
1302
+ return node === void 0 ? void 0 : binder.symbolForNode(node);
1308
1303
  }
1309
1304
  const MONGO_OBJECT_ID_PSL_TYPE = "ObjectId";
1310
- function resolveFieldCodecId(field, scalarTypeCodecIds) {
1311
- return scalarTypeCodecIds.get(field.typeName);
1312
- }
1313
1305
  /**
1314
1306
  * Keys each preset's execution defaults by collection and stored field. Rejects presets on variant fields, since a default keyed by collection applies to every document in it, and merges identical defaults that two models declare for the same collection field.
1315
1307
  */
@@ -1357,14 +1349,13 @@ function resolvePresetExecutionDefaults(input) {
1357
1349
  }
1358
1350
  return resolved;
1359
1351
  }
1360
- function resolveNonRelationField(field, owner, compositeTypeNames, scalarTypeCodecIds, codecIdByEnumName, presetContext, scalarNames) {
1361
- const { sources, diagnostics } = presetContext;
1352
+ function resolveNonRelationField(field, owner, resolution, codecIdByEnumName, presetContext, scalarNames, onPresetHandled, onUnresolvedType) {
1362
1353
  const ownerName = owner.name;
1363
- if (compositeTypeNames.has(field.typeName)) {
1354
+ if (resolution?.kind === "compositeType") {
1364
1355
  const result = {
1365
1356
  type: {
1366
1357
  kind: "valueObject",
1367
- name: field.typeName
1358
+ name: resolution.symbol.name
1368
1359
  },
1369
1360
  nullable: field.optional
1370
1361
  };
@@ -1373,13 +1364,14 @@ function resolveNonRelationField(field, owner, compositeTypeNames, scalarTypeCod
1373
1364
  many: true
1374
1365
  } : result };
1375
1366
  }
1376
- const enumCodecId = codecIdByEnumName.get(field.typeName);
1377
- if (enumCodecId !== void 0) {
1367
+ if (resolution?.kind === "block" && resolution.symbol.keyword === "enum") {
1368
+ const enumCodecId = codecIdByEnumName.get(resolution.symbol.name);
1369
+ if (enumCodecId === void 0) return void 0;
1378
1370
  const valueSet = {
1379
1371
  plane: "domain",
1380
1372
  entityKind: "enum",
1381
1373
  namespaceId: UNBOUND_NAMESPACE_ID,
1382
- entityName: field.typeName
1374
+ entityName: resolution.symbol.name
1383
1375
  };
1384
1376
  const result = {
1385
1377
  type: {
@@ -1394,30 +1386,36 @@ function resolveNonRelationField(field, owner, compositeTypeNames, scalarTypeCod
1394
1386
  many: true
1395
1387
  } : result };
1396
1388
  }
1397
- if (field.malformedType) return;
1398
- const preset = resolveFieldPreset({
1399
- field,
1400
- ownerName,
1401
- ownerKind: owner.kind,
1402
- context: presetContext
1403
- });
1404
- if (preset.kind === "invalid") return;
1405
- if (preset.kind === "preset") return {
1406
- field: preset.field,
1407
- ...ifDefined("executionDefaults", preset.executionDefaults)
1408
- };
1409
- const codecId = resolveFieldCodecId(field, scalarTypeCodecIds);
1410
- if (!codecId && scalarNames.declaredEnums.has(field.typeName)) return;
1411
- if (!codecId) {
1412
- const typeNode = field.node.typeAnnotation()?.name()?.syntax;
1413
- const source = diagnosticSource(sources, field.node.syntax);
1414
- diagnostics.push({
1389
+ if (resolution?.kind === "model" || resolution?.kind === "namedType" || resolution?.kind === "block" || resolution?.kind === "crossSpace") {
1390
+ presetContext.diagnostics.push({
1415
1391
  code: "PSL_UNSUPPORTED_FIELD_TYPE",
1416
- message: scalarNames.unknownTypeMessage(field, ownerName),
1417
- ...typeNode === void 0 ? source.at(field.span) : diagnosticSource(sources, typeNode).at()
1392
+ message: `Field "${ownerName}.${field.name}" type "${field.typeName}" is not supported in Mongo PSL interpreter`,
1393
+ ...diagnosticSource(presetContext.sources, field.node.syntax).at(field.span)
1418
1394
  });
1419
1395
  return;
1420
1396
  }
1397
+ if (resolution?.kind !== "contributedType" && resolution?.kind !== "unresolved") return;
1398
+ if (resolution.kind === "unresolved") {
1399
+ if (field.typeConstructor === void 0) {
1400
+ if (resolution.name === field.typeName) onUnresolvedType(field, ownerName);
1401
+ return;
1402
+ }
1403
+ if (resolution.name !== field.typeConstructor.path.join(".")) return void 0;
1404
+ const preset = resolveFieldPreset({
1405
+ field,
1406
+ ownerName,
1407
+ ownerKind: owner.kind,
1408
+ context: presetContext
1409
+ });
1410
+ if (preset.kind === "none") return void 0;
1411
+ onPresetHandled(field);
1412
+ if (preset.kind === "invalid") return void 0;
1413
+ return {
1414
+ field: preset.field,
1415
+ ...ifDefined("executionDefaults", preset.executionDefaults)
1416
+ };
1417
+ }
1418
+ const codecId = resolution.symbol.descriptor.output.codecId;
1421
1419
  scalarNames.warnDeprecated(field);
1422
1420
  const result = {
1423
1421
  type: {
@@ -1492,8 +1490,7 @@ function interpretPslDocumentToMongoContract(input) {
1492
1490
  types: input.authoringContributions?.type,
1493
1491
  scalarTypeCodecIds,
1494
1492
  formerScalarCodecIds: input.formerScalarCodecIds ?? /* @__PURE__ */ new Map()
1495
- }),
1496
- declaredEnums: new Set(Object.values(symbolTable.topLevel.blocks).filter((block) => block.keyword === "enum").map((block) => block.name))
1493
+ })
1497
1494
  };
1498
1495
  const { binder, diagnostics: binderDiagnostics } = createMongoBinder({
1499
1496
  symbolTable,
@@ -1502,7 +1499,20 @@ function interpretPslDocumentToMongoContract(input) {
1502
1499
  controlMutationDefaults: input.controlMutationDefaults,
1503
1500
  authoringContributions: input.authoringContributions
1504
1501
  });
1505
- diagnostics.push(...binderDiagnostics.filter((diagnostic) => diagnostic.data?.["reference"] !== "type"));
1502
+ const replacedTypeDiagnostics = /* @__PURE__ */ new Set();
1503
+ const unresolvedTypeMessages = /* @__PURE__ */ new Map();
1504
+ const typeDiagnosticsFor = (field) => {
1505
+ const node = typeReferenceNode(field);
1506
+ if (node === void 0) return [];
1507
+ const { filename, range } = diagnosticSource(sources, node).at();
1508
+ return binderDiagnostics.filter((diagnostic) => diagnostic.code === "PSL_UNRESOLVED_REFERENCE" && diagnostic.filename === filename && diagnostic.range.start.line === range.start.line && diagnostic.range.start.character === range.start.character && diagnostic.range.end.line === range.end.line && diagnostic.range.end.character === range.end.character);
1509
+ };
1510
+ const onPresetHandled = (field) => {
1511
+ for (const diagnostic of typeDiagnosticsFor(field)) replacedTypeDiagnostics.add(diagnostic);
1512
+ };
1513
+ const onUnresolvedType = (field, ownerName) => {
1514
+ for (const diagnostic of typeDiagnosticsFor(field)) unresolvedTypeMessages.set(diagnostic, scalarNames.unknownTypeMessage(field, ownerName));
1515
+ };
1506
1516
  const { parsedBlocks, diagnostics: blockDiagnostics } = interpretExtensionBlocks({
1507
1517
  symbolTable,
1508
1518
  sources,
@@ -1519,33 +1529,20 @@ function interpretPslDocumentToMongoContract(input) {
1519
1529
  });
1520
1530
  const allModels = Object.values(topLevel.models);
1521
1531
  const allCompositeTypes = Object.values(topLevel.compositeTypes);
1522
- const modelNames = new Set(allModels.map((m) => m.name));
1523
- const compositeTypeNames = new Set(allCompositeTypes.map((ct) => ct.name));
1524
1532
  const specContextFor = (model) => ({
1525
1533
  symbols: symbolTable,
1526
1534
  model,
1527
1535
  controlMutationDefaults: input.controlMutationDefaults
1528
1536
  });
1529
- const modelMetadataByName = /* @__PURE__ */ new Map();
1530
- for (const model of allModels) {
1531
- const specContext = specContextFor(model);
1532
- modelMetadataByName.set(model.name, {
1533
- collectionName: resolveCollectionName({
1534
- model,
1535
- specContext,
1536
- sources,
1537
- binder,
1538
- diagnostics
1539
- }),
1540
- fieldMappings: resolveFieldMappings({
1541
- model,
1542
- specContext,
1543
- sources,
1544
- binder,
1545
- diagnostics
1546
- })
1547
- });
1548
- }
1537
+ const physicalNames = /* @__PURE__ */ new Map();
1538
+ for (const model of allModels) resolvePhysicalNames({
1539
+ model,
1540
+ physicalNames,
1541
+ specContext: specContextFor(model),
1542
+ sources,
1543
+ binder,
1544
+ diagnostics
1545
+ });
1549
1546
  const blockKeywords = /* @__PURE__ */ new Set(["enum", ...claimedBlockKeywords(input.authoringContributions?.pslBlockDescriptors)]);
1550
1547
  for (const block of Object.values(topLevel.blocks)) if (!blockKeywords.has(block.keyword)) diagnostics.push(unsupportedBlockDiagnostic(block, sources));
1551
1548
  const builtEnums = processEnumDeclarations({
@@ -1577,15 +1574,15 @@ function interpretPslDocumentToMongoContract(input) {
1577
1574
  const invalidFkPairings = [];
1578
1575
  for (const pslModel of allModels) {
1579
1576
  const modelSource = diagnosticSource(sources, pslModel.node.syntax);
1580
- const metadata = modelMetadataByName.get(pslModel.name);
1581
- if (!metadata) continue;
1582
- const { collectionName, fieldMappings } = metadata;
1577
+ const collectionName = physicalName(physicalNames, pslModel);
1583
1578
  const specContext = specContextFor(pslModel);
1584
1579
  const fields = {};
1585
1580
  const relations = {};
1586
1581
  for (const field of Object.values(pslModel.fields)) {
1587
- if (isRelationField(field, modelNames)) {
1588
- const relationNode = findFieldAttributeNode(field, "relation");
1582
+ const resolution = fieldTypeResolution(field, binder);
1583
+ if (resolution?.kind === "model") {
1584
+ const target = resolution.symbol;
1585
+ const relationNode = field.attributes.find((attr) => attr.name === "relation")?.node;
1589
1586
  const relation = relationNode ? interpretFieldAttribute({
1590
1587
  symbols: specContext.symbols,
1591
1588
  node: relationNode,
@@ -1602,7 +1599,7 @@ function interpretPslDocumentToMongoContract(input) {
1602
1599
  if (field.list || !(relation?.fields && relation?.references)) {
1603
1600
  backrelationCandidates.push({
1604
1601
  modelName: pslModel.name,
1605
- targetModelName: field.typeName,
1602
+ targetModelName: target.name,
1606
1603
  ...ifDefined("relationName", relation?.name),
1607
1604
  cardinality: field.list ? "1:N" : "1:1",
1608
1605
  field,
@@ -1618,16 +1615,16 @@ function interpretPslDocumentToMongoContract(input) {
1618
1615
  }).contradiction !== void 0) {
1619
1616
  diagnostics.push(relationNullabilityMismatchDiagnostic(pslModel.name, field, sources));
1620
1617
  invalidFkPairings.push({
1621
- pairKey: fkRelationPairKey(pslModel.name, field.typeName),
1618
+ pairKey: fkRelationPairKey(pslModel.name, target.name),
1622
1619
  ...ifDefined("relationName", relation.name)
1623
1620
  });
1624
1621
  continue;
1625
1622
  }
1626
- const localMapped = relation.fields.map((f) => fieldMappings.pslNameToMapped.get(f) ?? f);
1627
- const targetFieldMappings = modelMetadataByName.get(field.typeName)?.fieldMappings;
1628
- const targetMapped = relation.references.map((f) => targetFieldMappings?.pslNameToMapped.get(f) ?? f);
1623
+ if (!physicalNames.has(target)) continue;
1624
+ const localMapped = relation.fields.map((name) => physicalName(physicalNames, pslModel.fields[name]));
1625
+ const targetMapped = relation.references.map((name) => physicalName(physicalNames, target.fields[name]));
1629
1626
  relations[field.name] = {
1630
- to: mongoCrossRef(field.typeName),
1627
+ to: mongoCrossRef(target.name),
1631
1628
  cardinality: "N:1",
1632
1629
  nullable: field.optional,
1633
1630
  on: {
@@ -1637,7 +1634,7 @@ function interpretPslDocumentToMongoContract(input) {
1637
1634
  };
1638
1635
  allFkRelations.push({
1639
1636
  declaringModel: pslModel.name,
1640
- targetModel: field.typeName,
1637
+ targetModel: target.name,
1641
1638
  ...ifDefined("relationName", relation.name),
1642
1639
  localFields: localMapped,
1643
1640
  targetFields: targetMapped
@@ -1648,9 +1645,9 @@ function interpretPslDocumentToMongoContract(input) {
1648
1645
  const resolved = resolveNonRelationField(field, {
1649
1646
  name: pslModel.name,
1650
1647
  kind: "model"
1651
- }, compositeTypeNames, scalarTypeCodecIds, codecIdByEnumName, presetContext, scalarNames);
1648
+ }, resolution, codecIdByEnumName, presetContext, scalarNames, onPresetHandled, onUnresolvedType);
1652
1649
  if (!resolved) continue;
1653
- const mappedName = fieldMappings.pslNameToMapped.get(field.name) ?? field.name;
1650
+ const mappedName = physicalName(physicalNames, field);
1654
1651
  fields[mappedName] = resolved.field;
1655
1652
  if (resolved.executionDefaults) presetExecutionDefaults.push({
1656
1653
  modelName: pslModel.name,
@@ -1661,7 +1658,7 @@ function interpretPslDocumentToMongoContract(input) {
1661
1658
  }
1662
1659
  const isVariantModel = pslModel.attributes.some((attr) => attr.name === "base");
1663
1660
  const hasIdField = Object.values(pslModel.fields).filter((field) => {
1664
- const idNode = findFieldAttributeNode(field, "id");
1661
+ const idNode = field.attributes.find((attr) => attr.name === "id")?.node;
1665
1662
  if (!idNode) return false;
1666
1663
  return interpretFieldAttribute({
1667
1664
  symbols: specContext.symbols,
@@ -1696,7 +1693,7 @@ function interpretPslDocumentToMongoContract(input) {
1696
1693
  relations,
1697
1694
  storage: { collection: collectionName }
1698
1695
  };
1699
- const modelIndexes = collectIndexes(pslModel, specContext, fieldMappings, modelNames, compositeTypeNames, sources, binder, diagnostics, indexSpans, indexSources);
1696
+ const modelIndexes = collectIndexes(pslModel, specContext, physicalNames, sources, binder, diagnostics, indexSpans, indexSources);
1700
1697
  modelIndexesByName.set(pslModel.name, modelIndexes);
1701
1698
  const existingColl = collections[collectionName];
1702
1699
  if (existingColl && modelIndexes.length > 0) collections[collectionName] = { indexes: [...collectionIndexes(existingColl), ...modelIndexes] };
@@ -1710,7 +1707,7 @@ function interpretPslDocumentToMongoContract(input) {
1710
1707
  const resolved = resolveNonRelationField(field, {
1711
1708
  name: compositeType.name,
1712
1709
  kind: "compositeType"
1713
- }, compositeTypeNames, scalarTypeCodecIds, codecIdByEnumName, presetContext, scalarNames);
1710
+ }, fieldTypeResolution(field, binder), codecIdByEnumName, presetContext, scalarNames, onPresetHandled, onUnresolvedType);
1714
1711
  if (!resolved) continue;
1715
1712
  fields[field.name] = resolved.field;
1716
1713
  }
@@ -1726,7 +1723,7 @@ function interpretPslDocumentToMongoContract(input) {
1726
1723
  const modelEntry = models[modelName];
1727
1724
  if (modelEntry) modelEntry.relations[fieldName] = relation;
1728
1725
  }
1729
- const { discriminatorDeclarations, baseDeclarations } = collectPolymorphismDeclarations(allModels, specContextFor, modelMetadataByName, sources, binder, diagnostics);
1726
+ const { discriminatorDeclarations, baseDeclarations } = collectPolymorphismDeclarations(allModels, specContextFor, physicalNames, sources, binder, diagnostics);
1730
1727
  const polyResult = resolvePolymorphism({
1731
1728
  sources,
1732
1729
  models,
@@ -1736,7 +1733,7 @@ function interpretPslDocumentToMongoContract(input) {
1736
1733
  baseDeclarations,
1737
1734
  indexSpans,
1738
1735
  modelIndexesByName,
1739
- modelMetadataByName,
1736
+ physicalNames,
1740
1737
  indexSources
1741
1738
  });
1742
1739
  const executionDefaults = resolvePresetExecutionDefaults({
@@ -1745,10 +1742,18 @@ function interpretPslDocumentToMongoContract(input) {
1745
1742
  sources,
1746
1743
  diagnostics
1747
1744
  });
1748
- if (diagnostics.length > 0 || polyResult.diagnostics.length > 0 || (input.seedDiagnostics?.length ?? 0) > 0) return notOk({
1745
+ const remainingBinderDiagnostics = binderDiagnostics.filter((diagnostic) => !replacedTypeDiagnostics.has(diagnostic)).map((diagnostic) => {
1746
+ const message = unresolvedTypeMessages.get(diagnostic);
1747
+ return message === void 0 ? diagnostic : {
1748
+ ...diagnostic,
1749
+ message
1750
+ };
1751
+ });
1752
+ if (remainingBinderDiagnostics.length > 0 || diagnostics.length > 0 || polyResult.diagnostics.length > 0 || (input.seedDiagnostics?.length ?? 0) > 0) return notOk({
1749
1753
  summary: "PSL to Mongo contract interpretation failed",
1750
1754
  diagnostics: [
1751
1755
  ...input.seedDiagnostics ?? [],
1756
+ ...mapPslDiagnostics(remainingBinderDiagnostics, sources),
1752
1757
  ...diagnostics.toExternal(),
1753
1758
  ...polyResult.diagnostics.toExternal()
1754
1759
  ]
@@ -1817,4 +1822,4 @@ function interpretPslDocumentToMongoContract(input) {
1817
1822
  //#endregion
1818
1823
  export { pairMongoBackRelations as a, mongoAttributeSpecs as i, derivePolymorphicJsonSchema as n, interpretPslDocumentToMongoContract as r, deriveJsonSchema as t };
1819
1824
 
1820
- //# sourceMappingURL=interpreter-Da0fGDSM-DGCJEzeI.mjs.map
1825
+ //# sourceMappingURL=interpreter-DSD7dXPk-D37QHryH.mjs.map