@prisma-next/mongo-contract-psl 0.11.0 → 0.12.0

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.
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.mts","names":[],"sources":["../../src/provider.ts"],"mappings":";;;UAOiB,oBAAA;EAAA,SACN,MAAA;AAAA;AAAA,iBAGK,aAAA,CAAc,UAAA,UAAoB,OAAA,GAAU,oBAAA,GAAuB,cAAA"}
1
+ {"version":3,"file":"provider.d.mts","names":[],"sources":["../../src/provider.ts"],"mappings":";;;UAOiB,oBAAA;EAAA,SACN,MAAM;AAAA;AAAA,iBAGD,aAAA,CAAc,UAAA,UAAoB,OAAA,GAAU,oBAAA,GAAuB,cAAc"}
@@ -1,4 +1,4 @@
1
- import { t as interpretPslDocumentToMongoContract } from "../interpreter-COTnSq1Y.mjs";
1
+ import { t as interpretPslDocumentToMongoContract } from "../interpreter-CSiej-EK.mjs";
2
2
  import { notOk, ok } from "@prisma-next/utils/result";
3
3
  import { parsePslDocument } from "@prisma-next/psl-parser";
4
4
  import { readFile } from "node:fs/promises";
@@ -1 +1 @@
1
- {"version":3,"file":"provider.mjs","names":[],"sources":["../../src/provider.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { ContractConfig } from '@prisma-next/config/config-types';\nimport { parsePslDocument } from '@prisma-next/psl-parser';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { interpretPslDocumentToMongoContract } from './interpreter';\n\nexport interface MongoContractOptions {\n readonly output?: string;\n}\n\nexport function mongoContract(schemaPath: string, options?: MongoContractOptions): ContractConfig {\n return {\n source: {\n inputs: [schemaPath],\n load: async (context) => {\n const [absoluteSchemaPath] = context.resolvedInputs;\n if (absoluteSchemaPath === undefined) {\n throw new Error(\n 'mongoContract: context.resolvedInputs is empty. The CLI config loader should populate it positional-matched with source.inputs.',\n );\n }\n let schema: string;\n try {\n schema = await readFile(absoluteSchemaPath, 'utf-8');\n } catch (error) {\n const message = String(error);\n return notOk({\n summary: `Failed to read Prisma schema at \"${schemaPath}\"`,\n diagnostics: [\n {\n code: 'PSL_SCHEMA_READ_FAILED',\n message,\n sourceId: schemaPath,\n },\n ],\n meta: { schemaPath, absoluteSchemaPath, cause: message },\n });\n }\n\n const document = parsePslDocument({\n schema,\n sourceId: schemaPath,\n });\n\n const interpreted = interpretPslDocumentToMongoContract({\n document,\n scalarTypeDescriptors: context.scalarTypeDescriptors,\n codecLookup: context.codecLookup,\n });\n if (!interpreted.ok) {\n return interpreted;\n }\n\n return ok(interpreted.value);\n },\n },\n ...ifDefined('output', options?.output),\n };\n}\n"],"mappings":";;;;;;AAWA,SAAgB,cAAc,YAAoB,SAAgD;CAChG,OAAO;EACL,QAAQ;GACN,QAAQ,CAAC,WAAW;GACpB,MAAM,OAAO,YAAY;IACvB,MAAM,CAAC,sBAAsB,QAAQ;IACrC,IAAI,uBAAuB,KAAA,GACzB,MAAM,IAAI,MACR,kIACD;IAEH,IAAI;IACJ,IAAI;KACF,SAAS,MAAM,SAAS,oBAAoB,QAAQ;aAC7C,OAAO;KACd,MAAM,UAAU,OAAO,MAAM;KAC7B,OAAO,MAAM;MACX,SAAS,oCAAoC,WAAW;MACxD,aAAa,CACX;OACE,MAAM;OACN;OACA,UAAU;OACX,CACF;MACD,MAAM;OAAE;OAAY;OAAoB,OAAO;OAAS;MACzD,CAAC;;IAQJ,MAAM,cAAc,oCAAoC;KACtD,UANe,iBAAiB;MAChC;MACA,UAAU;MACX,CAGS;KACR,uBAAuB,QAAQ;KAC/B,aAAa,QAAQ;KACtB,CAAC;IACF,IAAI,CAAC,YAAY,IACf,OAAO;IAGT,OAAO,GAAG,YAAY,MAAM;;GAE/B;EACD,GAAG,UAAU,UAAU,SAAS,OAAO;EACxC"}
1
+ {"version":3,"file":"provider.mjs","names":[],"sources":["../../src/provider.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { ContractConfig } from '@prisma-next/config/config-types';\nimport { parsePslDocument } from '@prisma-next/psl-parser';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { interpretPslDocumentToMongoContract } from './interpreter';\n\nexport interface MongoContractOptions {\n readonly output?: string;\n}\n\nexport function mongoContract(schemaPath: string, options?: MongoContractOptions): ContractConfig {\n return {\n source: {\n inputs: [schemaPath],\n load: async (context) => {\n const [absoluteSchemaPath] = context.resolvedInputs;\n if (absoluteSchemaPath === undefined) {\n throw new Error(\n 'mongoContract: context.resolvedInputs is empty. The CLI config loader should populate it positional-matched with source.inputs.',\n );\n }\n let schema: string;\n try {\n schema = await readFile(absoluteSchemaPath, 'utf-8');\n } catch (error) {\n const message = String(error);\n return notOk({\n summary: `Failed to read Prisma schema at \"${schemaPath}\"`,\n diagnostics: [\n {\n code: 'PSL_SCHEMA_READ_FAILED',\n message,\n sourceId: schemaPath,\n },\n ],\n meta: { schemaPath, absoluteSchemaPath, cause: message },\n });\n }\n\n const document = parsePslDocument({\n schema,\n sourceId: schemaPath,\n });\n\n const interpreted = interpretPslDocumentToMongoContract({\n document,\n scalarTypeDescriptors: context.scalarTypeDescriptors,\n codecLookup: context.codecLookup,\n });\n if (!interpreted.ok) {\n return interpreted;\n }\n\n return ok(interpreted.value);\n },\n },\n ...ifDefined('output', options?.output),\n };\n}\n"],"mappings":";;;;;;AAWA,SAAgB,cAAc,YAAoB,SAAgD;CAChG,OAAO;EACL,QAAQ;GACN,QAAQ,CAAC,UAAU;GACnB,MAAM,OAAO,YAAY;IACvB,MAAM,CAAC,sBAAsB,QAAQ;IACrC,IAAI,uBAAuB,KAAA,GACzB,MAAM,IAAI,MACR,iIACF;IAEF,IAAI;IACJ,IAAI;KACF,SAAS,MAAM,SAAS,oBAAoB,OAAO;IACrD,SAAS,OAAO;KACd,MAAM,UAAU,OAAO,KAAK;KAC5B,OAAO,MAAM;MACX,SAAS,oCAAoC,WAAW;MACxD,aAAa,CACX;OACE,MAAM;OACN;OACA,UAAU;MACZ,CACF;MACA,MAAM;OAAE;OAAY;OAAoB,OAAO;MAAQ;KACzD,CAAC;IACH;IAOA,MAAM,cAAc,oCAAoC;KACtD,UANe,iBAAiB;MAChC;MACA,UAAU;KACZ,CAGS;KACP,uBAAuB,QAAQ;KAC/B,aAAa,QAAQ;IACvB,CAAC;IACD,IAAI,CAAC,YAAY,IACf,OAAO;IAGT,OAAO,GAAG,YAAY,KAAK;GAC7B;EACF;EACA,GAAG,UAAU,UAAU,SAAS,MAAM;CACxC;AACF"}
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
+ import { Contract } from "@prisma-next/contract/types";
1
2
  import { Result } from "@prisma-next/utils/result";
2
3
  import { ParsePslDocumentResult } from "@prisma-next/psl-parser";
3
4
  import { ContractSourceDiagnostics } from "@prisma-next/config/config-types";
4
- import { Contract } from "@prisma-next/contract/types";
5
5
  import { CodecLookup } from "@prisma-next/framework-components/codec";
6
6
 
7
7
  //#region src/interpreter.d.ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/interpreter.ts"],"mappings":";;;;;;;UAwCiB,wCAAA;EAAA,SACN,QAAA,EAAU,sBAAA;EAAA,SACV,qBAAA,EAAuB,WAAA;EAAA,SACvB,WAAA,GAAc,WAAA;AAAA;AAAA,iBA0xBT,mCAAA,CACd,KAAA,EAAO,wCAAA,GACN,MAAA,CAAO,QAAA,EAAU,yBAAA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/interpreter.ts"],"mappings":";;;;;;;UA4CiB,wCAAA;EAAA,SACN,QAAA,EAAU,sBAAA;EAAA,SACV,qBAAA,EAAuB,WAAA;EAAA,SACvB,WAAA,GAAc,WAAA;AAAA;AAAA,iBAiyBT,mCAAA,CACd,KAAA,EAAO,wCAAA,GACN,MAAA,CAAO,QAAA,EAAU,yBAAA"}
package/dist/index.mjs CHANGED
@@ -1,2 +1,2 @@
1
- import { t as interpretPslDocumentToMongoContract } from "./interpreter-COTnSq1Y.mjs";
1
+ import { t as interpretPslDocumentToMongoContract } from "./interpreter-CSiej-EK.mjs";
2
2
  export { interpretPslDocumentToMongoContract };
@@ -1,6 +1,8 @@
1
1
  import { computeProfileHash, computeStorageHash } from "@prisma-next/contract/hashing";
2
+ import { crossRef } from "@prisma-next/contract/types";
2
3
  import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
3
- import { MongoCollection, MongoIndex, MongoStorage, MongoValidator, applyPolymorphicScopeToMongoIndex } from "@prisma-next/mongo-contract";
4
+ import { MongoCollection, MongoIndex, MongoStorage, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace } from "@prisma-next/mongo-contract";
5
+ import { mongoContractCanonicalizationHooks } from "@prisma-next/mongo-contract/canonicalization-hooks";
4
6
  import { notOk, ok } from "@prisma-next/utils/result";
5
7
  import { getPositionalArgument, parseQuotedStringLiteral } from "@prisma-next/psl-parser";
6
8
  //#region src/derive-json-schema.ts
@@ -42,11 +44,15 @@ function deriveObjectSchema(fields, valueObjects, codecLookup) {
42
44
  }
43
45
  const result = {
44
46
  bsonType: "object",
45
- properties
47
+ properties,
48
+ additionalProperties: false
46
49
  };
47
50
  if (required.length > 0) result["required"] = required.sort();
48
51
  return result;
49
52
  }
53
+ function isRecord(value) {
54
+ return typeof value === "object" && value !== null && !Array.isArray(value);
55
+ }
50
56
  function deriveJsonSchema(fields, valueObjects, codecLookup) {
51
57
  return new MongoValidator({
52
58
  jsonSchema: deriveObjectSchema(fields, valueObjects, codecLookup),
@@ -56,11 +62,11 @@ function deriveJsonSchema(fields, valueObjects, codecLookup) {
56
62
  }
57
63
  function derivePolymorphicJsonSchema(baseFields, discriminatorField, variants, valueObjects, codecLookup) {
58
64
  const baseSchema = deriveObjectSchema(baseFields, valueObjects, codecLookup);
65
+ const baseProperties = isRecord(baseSchema["properties"]) ? baseSchema["properties"] : {};
59
66
  const oneOf = [];
60
67
  for (const variant of variants) {
61
68
  const variantOnlyFields = {};
62
69
  for (const [name, field] of Object.entries(variant.fields)) if (!(name in baseFields)) variantOnlyFields[name] = field;
63
- const entry = { properties: { [discriminatorField]: { enum: [variant.discriminatorValue] } } };
64
70
  const variantProperties = {};
65
71
  const variantRequired = [discriminatorField];
66
72
  for (const [name, field] of Object.entries(variantOnlyFields)) {
@@ -70,14 +76,19 @@ function derivePolymorphicJsonSchema(baseFields, discriminatorField, variants, v
70
76
  if (!field.nullable) variantRequired.push(name);
71
77
  }
72
78
  }
73
- if (Object.keys(variantProperties).length > 0) entry["properties"] = {
74
- ...entry["properties"],
75
- ...variantProperties
79
+ const entry = {
80
+ properties: {
81
+ ...baseProperties,
82
+ [discriminatorField]: { enum: [variant.discriminatorValue] },
83
+ ...variantProperties
84
+ },
85
+ required: variantRequired.sort(),
86
+ additionalProperties: false
76
87
  };
77
- entry["required"] = variantRequired.sort();
78
88
  oneOf.push(entry);
79
89
  }
80
90
  const jsonSchema = { ...baseSchema };
91
+ delete jsonSchema["additionalProperties"];
81
92
  if (oneOf.length > 0) jsonSchema["oneOf"] = oneOf;
82
93
  return new MongoValidator({
83
94
  jsonSchema,
@@ -212,6 +223,9 @@ function resolveFieldMappings(model) {
212
223
  function resolveCollectionName(model) {
213
224
  return getMapName(model.attributes) ?? lowerFirst(model.name);
214
225
  }
226
+ function mongoCrossRef(modelName) {
227
+ return crossRef(modelName, UNBOUND_NAMESPACE_ID);
228
+ }
215
229
  function collectPolymorphismDeclarations(document, sourceId, diagnostics) {
216
230
  const discriminatorDeclarations = /* @__PURE__ */ new Map();
217
231
  const baseDeclarations = /* @__PURE__ */ new Map();
@@ -370,14 +384,14 @@ function resolvePolymorphism(input) {
370
384
  ...patched,
371
385
  [variantName]: {
372
386
  ...variantModel,
373
- base: baseDecl.baseName,
387
+ base: mongoCrossRef(baseDecl.baseName),
374
388
  storage: { collection: baseCollection }
375
389
  }
376
390
  };
377
391
  const variantCollectionName = resolveCollectionName(variantPslModel);
378
- if (roots[variantCollectionName] === variantName) if (variantCollectionName === baseCollection && baseModel) roots = {
392
+ if (roots[variantCollectionName]?.model === variantName) if (variantCollectionName === baseCollection && baseModel) roots = {
379
393
  ...roots,
380
- [variantCollectionName]: baseDecl.baseName
394
+ [variantCollectionName]: mongoCrossRef(baseDecl.baseName)
381
395
  };
382
396
  else roots = Object.fromEntries(Object.entries(roots).filter(([key]) => key !== variantCollectionName));
383
397
  const variantOwnIndexes = modelIndexesByName.get(variantName) ?? [];
@@ -710,6 +724,7 @@ function collectIndexes(pslModel, fieldMappings, modelNames, sourceId, diagnosti
710
724
  function isRelationField(field, modelNames) {
711
725
  return modelNames.has(field.typeName);
712
726
  }
727
+ const MONGO_OBJECT_ID_PSL_TYPE = "ObjectId";
713
728
  function resolveFieldCodecId(field, scalarTypeDescriptors) {
714
729
  return scalarTypeDescriptors.get(field.typeName);
715
730
  }
@@ -794,7 +809,7 @@ function interpretPslDocumentToMongoContract(input) {
794
809
  const targetFieldMappings = targetModel ? resolveFieldMappings(targetModel) : void 0;
795
810
  const targetMapped = relation.references.map((f) => targetFieldMappings?.pslNameToMapped.get(f) ?? f);
796
811
  relations[field.name] = {
797
- to: field.typeName,
812
+ to: mongoCrossRef(field.typeName),
798
813
  cardinality: "N:1",
799
814
  on: {
800
815
  localFields: localMapped,
@@ -818,11 +833,21 @@ function interpretPslDocumentToMongoContract(input) {
818
833
  fields[mappedName] = resolved;
819
834
  }
820
835
  const isVariantModel = pslModel.attributes.some((attr) => attr.name === "base");
821
- if (!pslModel.fields.some((f) => getAttribute(f.attributes, "id") !== void 0) && !isVariantModel) diagnostics.push({
836
+ const hasIdField = pslModel.fields.some((f) => getAttribute(f.attributes, "id") !== void 0);
837
+ if (!isVariantModel) if (!hasIdField) diagnostics.push({
822
838
  code: "PSL_MISSING_ID_FIELD",
823
839
  message: `Model "${pslModel.name}" has no field with @id attribute. Every model must have exactly one @id field.`,
824
840
  sourceId
825
841
  });
842
+ else {
843
+ const objectIdCodecId = scalarTypeDescriptors.get(MONGO_OBJECT_ID_PSL_TYPE);
844
+ const idField = fields["_id"];
845
+ if (!(idField !== void 0 && idField.type.kind === "scalar" && objectIdCodecId !== void 0 && idField.type.codecId === objectIdCodecId)) diagnostics.push({
846
+ code: "PSL_MONGO_ID_REQUIRED",
847
+ message: `Model "${pslModel.name}" must declare an _id field of type ObjectId (e.g. \`id ObjectId @id @map("_id")\`).`,
848
+ sourceId
849
+ });
850
+ }
826
851
  models[pslModel.name] = {
827
852
  fields,
828
853
  relations,
@@ -833,7 +858,7 @@ function interpretPslDocumentToMongoContract(input) {
833
858
  const existingColl = collections[collectionName];
834
859
  if (existingColl && modelIndexes.length > 0) collections[collectionName] = { indexes: [...existingColl["indexes"] ?? [], ...modelIndexes] };
835
860
  else if (!existingColl) collections[collectionName] = modelIndexes.length > 0 ? { indexes: modelIndexes } : {};
836
- roots[collectionName] = pslModel.name;
861
+ roots[collectionName] = mongoCrossRef(pslModel.name);
837
862
  }
838
863
  const valueObjects = {};
839
864
  for (const compositeType of allCompositeTypes) {
@@ -879,7 +904,7 @@ function interpretPslDocumentToMongoContract(input) {
879
904
  const modelEntry = models[candidate.modelName];
880
905
  if (!modelEntry) continue;
881
906
  modelEntry.relations[candidate.fieldName] = {
882
- to: candidate.targetModelName,
907
+ to: mongoCrossRef(candidate.targetModelName),
883
908
  cardinality: candidate.cardinality,
884
909
  on: {
885
910
  localFields: fk.targetFields,
@@ -928,25 +953,30 @@ function interpretPslDocumentToMongoContract(input) {
928
953
  if (coll["options"] !== void 0) input.options = coll["options"];
929
954
  collectionsAsClasses[name] = new MongoCollection(input);
930
955
  }
931
- const storageWithoutHash = { namespaces: { [UNBOUND_NAMESPACE_ID]: {
932
- id: UNBOUND_NAMESPACE_ID,
933
- collections: collectionsAsClasses
934
- } } };
935
956
  const storage = new MongoStorage({
936
957
  storageHash: computeStorageHash({
937
958
  target,
938
959
  targetFamily,
939
- storage: storageWithoutHash
960
+ storage: { namespaces: { [UNBOUND_NAMESPACE_ID]: {
961
+ id: UNBOUND_NAMESPACE_ID,
962
+ collections: collectionsAsClasses
963
+ } } },
964
+ ...mongoContractCanonicalizationHooks
940
965
  }),
941
- ...storageWithoutHash
966
+ namespaces: { [UNBOUND_NAMESPACE_ID]: buildMongoNamespace({
967
+ id: UNBOUND_NAMESPACE_ID,
968
+ collections: collectionsAsClasses
969
+ }) }
942
970
  });
943
971
  const capabilities = {};
944
972
  return ok({
945
973
  targetFamily,
946
974
  target,
947
975
  roots: polyResult.roots,
948
- models: polyResult.models,
949
- ...Object.keys(valueObjects).length > 0 ? { valueObjects } : {},
976
+ domain: { namespaces: { [UNBOUND_NAMESPACE_ID]: {
977
+ models: polyResult.models,
978
+ ...Object.keys(valueObjects).length > 0 ? { valueObjects } : {}
979
+ } } },
950
980
  storage,
951
981
  extensionPacks: {},
952
982
  capabilities,
@@ -961,4 +991,4 @@ function interpretPslDocumentToMongoContract(input) {
961
991
  //#endregion
962
992
  export { interpretPslDocumentToMongoContract as t };
963
993
 
964
- //# sourceMappingURL=interpreter-COTnSq1Y.mjs.map
994
+ //# sourceMappingURL=interpreter-CSiej-EK.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"interpreter-CSiej-EK.mjs","names":[],"sources":["../src/derive-json-schema.ts","../src/psl-helpers.ts","../src/interpreter.ts"],"sourcesContent":["import type { ContractField, ContractValueObject } from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { MongoValidator } from '@prisma-next/mongo-contract';\n\nfunction resolveBsonType(\n codecId: string,\n codecLookup: CodecLookup | undefined,\n): string | undefined {\n return codecLookup?.targetTypesFor(codecId)?.[0];\n}\n\nfunction fieldToBsonSchema(\n field: ContractField,\n valueObjects: Record<string, ContractValueObject> | undefined,\n codecLookup: CodecLookup | undefined,\n): Record<string, unknown> | undefined {\n if (field.type.kind === 'scalar') {\n const bsonType = resolveBsonType(field.type.codecId, codecLookup);\n if (!bsonType) return undefined;\n\n if ('many' in field && field.many) {\n return { bsonType: 'array', items: { bsonType } };\n }\n\n if (field.nullable) {\n return { bsonType: ['null', bsonType] };\n }\n\n return { bsonType };\n }\n\n if (field.type.kind === 'valueObject') {\n const vo = valueObjects?.[field.type.name];\n if (!vo) return undefined;\n const voSchema = deriveObjectSchema(vo.fields, valueObjects, codecLookup);\n if ('many' in field && field.many) {\n return { bsonType: 'array', items: voSchema };\n }\n if (field.nullable) {\n return { oneOf: [{ bsonType: 'null' }, voSchema] };\n }\n return voSchema;\n }\n\n return undefined;\n}\n\nfunction deriveObjectSchema(\n fields: Record<string, ContractField>,\n valueObjects: Record<string, ContractValueObject> | undefined,\n codecLookup: CodecLookup | undefined,\n): Record<string, unknown> {\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [fieldName, field] of Object.entries(fields)) {\n const schema = fieldToBsonSchema(field, valueObjects, codecLookup);\n if (schema) {\n properties[fieldName] = schema;\n if (!field.nullable) {\n required.push(fieldName);\n }\n }\n }\n\n const result: Record<string, unknown> = {\n bsonType: 'object',\n properties,\n // Closed by default: documents carrying fields not declared in `properties`\n // are rejected at every level (top-level collections and nested value objects).\n additionalProperties: false,\n };\n if (required.length > 0) {\n result['required'] = required.sort();\n }\n return result;\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nexport function deriveJsonSchema(\n fields: Record<string, ContractField>,\n valueObjects?: Record<string, ContractValueObject>,\n codecLookup?: CodecLookup,\n): MongoValidator {\n return new MongoValidator({\n jsonSchema: deriveObjectSchema(fields, valueObjects, codecLookup),\n validationLevel: 'strict',\n validationAction: 'error',\n });\n}\n\nexport interface PolymorphicVariant {\n readonly discriminatorValue: string;\n readonly fields: Record<string, ContractField>;\n}\n\nexport function derivePolymorphicJsonSchema(\n baseFields: Record<string, ContractField>,\n discriminatorField: string,\n variants: readonly PolymorphicVariant[],\n valueObjects?: Record<string, ContractValueObject>,\n codecLookup?: CodecLookup,\n): MongoValidator {\n const baseSchema = deriveObjectSchema(baseFields, valueObjects, codecLookup);\n const baseProperties = isRecord(baseSchema['properties']) ? baseSchema['properties'] : {};\n\n const oneOf: Record<string, unknown>[] = [];\n for (const variant of variants) {\n const variantOnlyFields: Record<string, ContractField> = {};\n for (const [name, field] of Object.entries(variant.fields)) {\n if (!(name in baseFields)) {\n variantOnlyFields[name] = field;\n }\n }\n\n const variantProperties: Record<string, unknown> = {};\n const variantRequired: string[] = [discriminatorField];\n for (const [name, field] of Object.entries(variantOnlyFields)) {\n const schema = fieldToBsonSchema(field, valueObjects, codecLookup);\n if (schema) {\n variantProperties[name] = schema;\n if (!field.nullable) {\n variantRequired.push(name);\n }\n }\n }\n\n // `additionalProperties: false` only sees the `properties` of the schema\n // object it sits on — it does not look into sibling `oneOf` branches. Each\n // branch is validated independently, so a closed branch must list the base\n // properties too; otherwise it would reject the base fields. The\n // discriminator is constrained to this variant's value.\n const entry: Record<string, unknown> = {\n properties: {\n ...baseProperties,\n [discriminatorField]: { enum: [variant.discriminatorValue] },\n ...variantProperties,\n },\n required: variantRequired.sort(),\n additionalProperties: false,\n };\n\n oneOf.push(entry);\n }\n\n // The top-level schema stays open: closure is enforced by the closed branches.\n // Keeping `additionalProperties: false` here would reject every variant-only\n // field, since the top-level `properties` only lists base fields.\n const jsonSchema = { ...baseSchema };\n delete jsonSchema['additionalProperties'];\n if (oneOf.length > 0) {\n jsonSchema['oneOf'] = oneOf;\n }\n\n return new MongoValidator({\n jsonSchema,\n validationLevel: 'strict',\n validationAction: 'error',\n });\n}\n","import type { PslAttribute, PslAttributeArgument } from '@prisma-next/psl-parser';\nimport { getPositionalArgument, parseQuotedStringLiteral } from '@prisma-next/psl-parser';\n\nexport { getPositionalArgument, parseQuotedStringLiteral };\n\nexport function getNamedArgument(attr: PslAttribute, name: string): string | undefined {\n const arg = attr.args.find((a) => a.kind === 'named' && a.name === name);\n return arg?.value;\n}\n\nexport function parseFieldList(value: string): readonly string[] {\n const inner = value.replace(/^\\[/, '').replace(/\\]$/, '').trim();\n if (inner.length === 0) return [];\n return splitTopLevel(inner).map((s) => s.trim());\n}\n\nexport interface ParsedIndexField {\n readonly name: string;\n readonly isWildcard: boolean;\n readonly direction?: number;\n}\n\nexport function parseIndexFieldList(value: string): readonly ParsedIndexField[] {\n const segments = parseFieldList(value);\n return segments.map(parseIndexFieldSegment);\n}\n\nfunction parseIndexFieldSegment(segment: string): ParsedIndexField {\n const wildcardMatch = segment.match(/^wildcard\\(\\s*(.*?)\\s*\\)$/);\n if (wildcardMatch) {\n const scope = wildcardMatch[1] ?? '';\n return {\n name: scope.length > 0 ? `${scope}.$**` : '$**',\n isWildcard: true,\n };\n }\n\n const modifierMatch = segment.match(/^(\\w+)\\(\\s*sort:\\s*(\\w+)\\s*\\)$/);\n if (modifierMatch) {\n const fieldName = modifierMatch[1] ?? segment;\n const sortValue = modifierMatch[2];\n return {\n name: fieldName,\n isWildcard: false,\n direction: sortValue === 'Desc' ? -1 : 1,\n };\n }\n\n return { name: segment, isWildcard: false };\n}\n\nfunction splitTopLevel(input: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < input.length; i++) {\n const ch = input[i];\n if (ch === '(' || ch === '[' || ch === '{') depth++;\n else if (ch === ')' || ch === ']' || ch === '}') depth = Math.max(0, depth - 1);\n else if (ch === ',' && depth === 0) {\n parts.push(input.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(input.slice(start));\n return parts;\n}\n\nexport function lowerFirst(value: string): string {\n if (value.length === 0) return value;\n return value[0]?.toLowerCase() + value.slice(1);\n}\n\nexport function getAttribute(\n attributes: readonly PslAttribute[],\n name: string,\n): PslAttribute | undefined {\n return attributes.find((attr) => attr.name === name);\n}\n\nexport function getMapName(attributes: readonly PslAttribute[]): string | undefined {\n const mapAttr = getAttribute(attributes, 'map');\n if (!mapAttr) return undefined;\n const arg = mapAttr.args[0];\n if (!arg) return undefined;\n return stripQuotes(arg.value);\n}\n\nexport interface ParsedRelationAttribute {\n readonly relationName?: string;\n readonly fields?: readonly string[];\n readonly references?: readonly string[];\n}\n\nexport function parseRelationAttribute(\n attributes: readonly PslAttribute[],\n): ParsedRelationAttribute | undefined {\n const relationAttr = getAttribute(attributes, 'relation');\n if (!relationAttr) return undefined;\n\n let relationName: string | undefined;\n let fieldsArg: PslAttributeArgument | undefined;\n let referencesArg: PslAttributeArgument | undefined;\n\n for (const arg of relationAttr.args) {\n if (arg.kind === 'positional') {\n relationName = stripQuotes(arg.value);\n } else if (arg.name === 'name') {\n relationName = stripQuotes(arg.value);\n } else if (arg.name === 'fields') {\n fieldsArg = arg;\n } else if (arg.name === 'references') {\n referencesArg = arg;\n }\n }\n\n const fields = fieldsArg ? parseFieldList(fieldsArg.value) : undefined;\n const references = referencesArg ? parseFieldList(referencesArg.value) : undefined;\n\n return {\n ...(relationName !== undefined ? { relationName } : {}),\n ...(fields !== undefined ? { fields } : {}),\n ...(references !== undefined ? { references } : {}),\n };\n}\n\nfunction stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n","import type {\n ContractSourceDiagnostic,\n ContractSourceDiagnostics,\n} from '@prisma-next/config/config-types';\nimport { computeProfileHash, computeStorageHash } from '@prisma-next/contract/hashing';\nimport {\n type Contract,\n type ContractField,\n type ContractReferenceRelation,\n type ContractValueObject,\n type CrossReference,\n crossRef,\n} from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport {\n applyPolymorphicScopeToMongoIndex,\n buildMongoNamespace,\n MongoCollection,\n MongoIndex,\n type MongoIndexKeyDirection,\n MongoStorage,\n} from '@prisma-next/mongo-contract';\nimport { mongoContractCanonicalizationHooks } from '@prisma-next/mongo-contract/canonicalization-hooks';\nimport type {\n ParsePslDocumentResult,\n PslField,\n PslModel,\n PslNamespace,\n PslSpan,\n} from '@prisma-next/psl-parser';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { deriveJsonSchema, derivePolymorphicJsonSchema } from './derive-json-schema';\nimport {\n getAttribute,\n getMapName,\n getNamedArgument,\n getPositionalArgument,\n lowerFirst,\n parseIndexFieldList,\n parseQuotedStringLiteral,\n parseRelationAttribute,\n} from './psl-helpers';\n\nexport interface InterpretPslDocumentToMongoContractInput {\n readonly document: ParsePslDocumentResult;\n readonly scalarTypeDescriptors: ReadonlyMap<string, string>;\n readonly codecLookup?: CodecLookup;\n}\n\n/**\n * Name of the framework-parser synthesised bucket for top-level\n * declarations. Re-declared locally so the interpreter does not have to\n * import from `@prisma-next/framework-components/psl-ast`.\n */\nconst UNSPECIFIED_PSL_NAMESPACE_NAME = '__unspecified__';\n\n/**\n * Mongo FR16c validation: Mongo's authoring DSL exposes the connection's\n * database as the only namespace surface today, so the PSL interpreter\n * rejects every explicit `namespace { … }` block. The implicit\n * `__unspecified__` bucket (top-level declarations) is the only\n * namespace Mongo accepts. `namespace unbound { … }` is rejected too —\n * Mongo has no late-binding namespace concept on the PSL surface (the\n * database name comes from the connection string, not from PSL).\n */\nfunction validateNamespaceBlocksForMongoTarget(input: {\n readonly namespaces: readonly PslNamespace[];\n readonly sourceId: string;\n readonly diagnostics: ContractSourceDiagnostic[];\n}): void {\n for (const namespace of input.namespaces) {\n if (namespace.name === UNSPECIFIED_PSL_NAMESPACE_NAME) {\n continue;\n }\n input.diagnostics.push({\n code: 'PSL_UNSUPPORTED_NAMESPACE_BLOCK',\n message: `Mongo does not support \\`namespace ${namespace.name} { … }\\` blocks (the database is bound by the connection string; declare models at the document top level instead).`,\n sourceId: input.sourceId,\n span: namespace.span,\n });\n }\n}\n\ninterface FieldMappings {\n readonly pslNameToMapped: Map<string, string>;\n}\n\ninterface FkRelation {\n readonly declaringModel: string;\n readonly fieldName: string;\n readonly targetModel: string;\n readonly relationName?: string;\n readonly localFields: readonly string[];\n readonly targetFields: readonly string[];\n}\n\nfunction fkRelationPairKey(declaringModel: string, targetModel: string): string {\n return `${declaringModel}::${targetModel}`;\n}\n\nfunction resolveFieldMappings(model: PslModel): FieldMappings {\n const pslNameToMapped = new Map<string, string>();\n for (const field of model.fields) {\n const mapped = getMapName(field.attributes) ?? field.name;\n pslNameToMapped.set(field.name, mapped);\n }\n return { pslNameToMapped };\n}\n\nfunction resolveCollectionName(model: PslModel): string {\n return getMapName(model.attributes) ?? lowerFirst(model.name);\n}\n\ninterface MongoModelEntry {\n readonly fields: Record<string, ContractField>;\n readonly relations: Record<string, ContractReferenceRelation>;\n readonly storage: { readonly collection: string };\n readonly discriminator?: { readonly field: string };\n readonly variants?: Record<string, { readonly value: string }>;\n readonly base?: CrossReference;\n}\n\ntype DiscriminatorDeclaration = { readonly fieldName: string; readonly span: PslModel['span'] };\ntype BaseDeclaration = {\n readonly baseName: string;\n readonly value: string;\n readonly collectionName: string;\n readonly span: PslModel['span'];\n};\n\nfunction mongoCrossRef(modelName: string): CrossReference {\n return crossRef(modelName, UNBOUND_NAMESPACE_ID);\n}\n\nfunction collectPolymorphismDeclarations(\n document: ParsePslDocumentResult,\n sourceId: string,\n diagnostics: ContractSourceDiagnostic[],\n): {\n discriminatorDeclarations: Map<string, DiscriminatorDeclaration>;\n baseDeclarations: Map<string, BaseDeclaration>;\n} {\n const discriminatorDeclarations = new Map<string, DiscriminatorDeclaration>();\n const baseDeclarations = new Map<string, BaseDeclaration>();\n const allPslModels = document.ast.namespaces.flatMap((ns) => ns.models);\n\n for (const pslModel of allPslModels) {\n for (const attr of pslModel.attributes) {\n if (attr.name === 'discriminator') {\n const fieldName = getPositionalArgument(attr);\n if (!fieldName) {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Model \"${pslModel.name}\" @@discriminator requires a field name argument`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n const discField = pslModel.fields.find((f) => f.name === fieldName);\n if (discField && discField.typeName !== 'String') {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Discriminator field \"${fieldName}\" on model \"${pslModel.name}\" must be of type String, but is \"${discField.typeName}\"`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n discriminatorDeclarations.set(pslModel.name, { fieldName, span: attr.span });\n }\n if (attr.name === 'base') {\n const baseName = getPositionalArgument(attr, 0);\n const rawValue = getPositionalArgument(attr, 1);\n if (!baseName || !rawValue) {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Model \"${pslModel.name}\" @@base requires two arguments: base model name and discriminator value`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n const value = parseQuotedStringLiteral(rawValue);\n if (value === undefined) {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Model \"${pslModel.name}\" @@base discriminator value must be a quoted string literal`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n const collectionName = resolveCollectionName(pslModel);\n baseDeclarations.set(pslModel.name, { baseName, value, collectionName, span: attr.span });\n }\n }\n }\n\n return { discriminatorDeclarations, baseDeclarations };\n}\n\nfunction resolvePolymorphism(input: {\n models: Record<string, MongoModelEntry>;\n roots: Record<string, CrossReference>;\n collections: Record<string, Record<string, unknown>>;\n document: ParsePslDocumentResult;\n discriminatorDeclarations: Map<string, DiscriminatorDeclaration>;\n baseDeclarations: Map<string, BaseDeclaration>;\n modelNames: ReadonlySet<string>;\n indexSpans: Map<MongoIndex, PslSpan>;\n modelIndexesByName: Map<string, readonly MongoIndex[]>;\n sourceId: string;\n}): {\n models: Record<string, MongoModelEntry>;\n roots: Record<string, CrossReference>;\n collections: Record<string, Record<string, unknown>>;\n diagnostics: ContractSourceDiagnostic[];\n} {\n const {\n discriminatorDeclarations,\n baseDeclarations,\n modelNames,\n sourceId,\n document,\n indexSpans,\n modelIndexesByName,\n } = input;\n const allPslModels = document.ast.namespaces.flatMap((ns) => ns.models);\n let patched = input.models;\n let roots = input.roots;\n let collections = input.collections;\n const diagnostics: ContractSourceDiagnostic[] = [];\n\n for (const [modelName, decl] of discriminatorDeclarations) {\n if (baseDeclarations.has(modelName)) {\n diagnostics.push({\n code: 'PSL_DISCRIMINATOR_AND_BASE',\n message: `Model \"${modelName}\" cannot have both @@discriminator and @@base`,\n sourceId,\n span: decl.span,\n });\n continue;\n }\n\n const model = patched[modelName];\n if (!model) continue;\n\n const pslModel = allPslModels.find((m) => m.name === modelName);\n const mappedDiscriminatorField = pslModel\n ? (resolveFieldMappings(pslModel).pslNameToMapped.get(decl.fieldName) ?? decl.fieldName)\n : decl.fieldName;\n\n if (!Object.hasOwn(model.fields, mappedDiscriminatorField)) {\n diagnostics.push({\n code: 'PSL_DISCRIMINATOR_FIELD_NOT_FOUND',\n message: `Discriminator field \"${decl.fieldName}\" is not a field on model \"${modelName}\"`,\n sourceId,\n span: decl.span,\n });\n continue;\n }\n\n const variants: Record<string, { readonly value: string }> = {};\n for (const [variantName, baseDecl] of baseDeclarations) {\n if (baseDecl.baseName !== modelName) continue;\n variants[variantName] = { value: baseDecl.value };\n }\n\n if (Object.keys(variants).length === 0) {\n diagnostics.push({\n code: 'PSL_ORPHANED_DISCRIMINATOR',\n message: `Model \"${modelName}\" has @@discriminator but no variant models declare @@base(${modelName}, ...)`,\n sourceId,\n span: decl.span,\n });\n continue;\n }\n\n patched = {\n ...patched,\n [modelName]: { ...model, discriminator: { field: mappedDiscriminatorField }, variants },\n };\n }\n\n for (const [variantName, baseDecl] of baseDeclarations) {\n if (!modelNames.has(baseDecl.baseName)) {\n diagnostics.push({\n code: 'PSL_BASE_TARGET_NOT_FOUND',\n message: `Model \"${variantName}\" @@base references non-existent model \"${baseDecl.baseName}\"`,\n sourceId,\n span: baseDecl.span,\n });\n continue;\n }\n\n if (!discriminatorDeclarations.has(baseDecl.baseName)) {\n diagnostics.push({\n code: 'PSL_ORPHANED_BASE',\n message: `Model \"${variantName}\" declares @@base(${baseDecl.baseName}, ...) but \"${baseDecl.baseName}\" has no @@discriminator`,\n sourceId,\n span: baseDecl.span,\n });\n continue;\n }\n\n if (discriminatorDeclarations.has(variantName)) {\n continue;\n }\n\n const baseModel = patched[baseDecl.baseName];\n const variantPslModel = allPslModels.find((m) => m.name === variantName);\n if (!variantPslModel) continue;\n const hasExplicitMap = getMapName(variantPslModel.attributes) !== undefined;\n\n if (hasExplicitMap && baseModel && baseDecl.collectionName !== baseModel.storage.collection) {\n diagnostics.push({\n code: 'PSL_MONGO_VARIANT_SEPARATE_COLLECTION',\n message: `Mongo variant \"${variantName}\" cannot use a different collection than its base \"${baseDecl.baseName}\". Mongo only supports single-collection polymorphism.`,\n sourceId,\n span: baseDecl.span,\n });\n continue;\n }\n\n const baseCollection = baseModel?.storage.collection ?? baseDecl.collectionName;\n const variantModel = patched[variantName];\n if (variantModel) {\n patched = {\n ...patched,\n [variantName]: {\n ...variantModel,\n base: mongoCrossRef(baseDecl.baseName),\n storage: { collection: baseCollection },\n },\n };\n }\n\n const variantCollectionName = resolveCollectionName(variantPslModel);\n if (roots[variantCollectionName]?.model === variantName) {\n if (variantCollectionName === baseCollection && baseModel) {\n roots = { ...roots, [variantCollectionName]: mongoCrossRef(baseDecl.baseName) };\n } else {\n roots = Object.fromEntries(\n Object.entries(roots).filter(([key]) => key !== variantCollectionName),\n );\n }\n }\n\n const variantOwnIndexes = modelIndexesByName.get(variantName) ?? [];\n const baseColl = collections[baseCollection];\n\n const baseModelEntry = patched[baseDecl.baseName];\n const discriminatorField = baseModelEntry?.discriminator?.field;\n const scopedVariantIndexes: MongoIndex[] = [];\n if (discriminatorField) {\n for (const idx of variantOwnIndexes) {\n const result = applyPolymorphicScopeToMongoIndex(idx, {\n discriminatorField,\n discriminatorValue: baseDecl.value,\n });\n if (result.kind === 'conflict') {\n const span = indexSpans.get(idx) ?? baseDecl.span;\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: `Variant \"${variantName}\" index conflicts with discriminator scope: ${result.reason}`,\n sourceId,\n span,\n });\n continue;\n }\n if (result.index !== idx) {\n indexSpans.set(result.index, indexSpans.get(idx) ?? baseDecl.span);\n }\n scopedVariantIndexes.push(result.index);\n }\n } else {\n scopedVariantIndexes.push(...variantOwnIndexes);\n }\n\n if (variantCollectionName !== baseCollection) {\n const filtered = Object.fromEntries(\n Object.entries(collections).filter(([key]) => key !== variantCollectionName),\n );\n if (scopedVariantIndexes.length > 0 && baseColl) {\n const baseIndexes = (baseColl['indexes'] ?? []) as MongoIndex[];\n collections = {\n ...filtered,\n [baseCollection]: {\n ...baseColl,\n indexes: [...baseIndexes, ...scopedVariantIndexes],\n },\n };\n } else {\n collections = filtered;\n }\n } else if (baseColl) {\n const existingIndexes = (baseColl['indexes'] ?? []) as MongoIndex[];\n const variantIndexSet = new Set<MongoIndex>(variantOwnIndexes);\n const withoutUnscopedVariants = existingIndexes.filter((idx) => !variantIndexSet.has(idx));\n const mergedIndexes = [...withoutUnscopedVariants];\n for (const idx of scopedVariantIndexes) {\n const idxKey = canonicalJson(idx);\n const isDuplicate = withoutUnscopedVariants.some(\n (existing) => canonicalJson(existing) === idxKey,\n );\n if (!isDuplicate) {\n mergedIndexes.push(idx);\n }\n }\n if (\n mergedIndexes.length !== existingIndexes.length ||\n mergedIndexes.some((idx, i) => idx !== existingIndexes[i])\n ) {\n const next: Record<string, unknown> = { ...baseColl };\n if (mergedIndexes.length > 0) {\n next['indexes'] = mergedIndexes;\n } else {\n delete next['indexes'];\n }\n collections = { ...collections, [baseCollection]: next };\n }\n }\n }\n\n return { models: patched, roots, collections, diagnostics };\n}\n\n// Property-order-stable serialization for structural equality of plain\n// JSON-compatible values. Used for comparing MongoIndex shapes in\n// the variant-merge dedup path where a future change to the spread order\n// would otherwise produce JSON-stringify mismatches even though the\n// indexes are structurally identical.\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map(canonicalJson).join(',')}]`;\n }\n if (value && typeof value === 'object') {\n return `{${Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`)\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction parseIndexDirection(raw: string | undefined): MongoIndexKeyDirection {\n if (!raw) return 1;\n const stripped = raw.replace(/^[\"']/, '').replace(/[\"']$/, '');\n const num = Number(stripped);\n if (num === 1 || num === -1) return num;\n if (['text', '2dsphere', '2d', 'hashed'].includes(stripped))\n return stripped as MongoIndexKeyDirection;\n return 1;\n}\n\nfunction parseNumericArg(raw: string | undefined): number | undefined {\n if (!raw) return undefined;\n const n = Number(raw);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction parseBooleanArg(raw: string | undefined): boolean | undefined {\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n return undefined;\n}\n\nfunction parseJsonArg(raw: string | undefined): Record<string, unknown> | undefined {\n if (!raw) return undefined;\n const stripped = raw.replace(/^[\"']/, '').replace(/[\"']$/, '').replace(/\\\\\"/g, '\"');\n try {\n const parsed = JSON.parse(stripped);\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // not valid JSON\n }\n return undefined;\n}\n\nfunction parseCollation(\n attr: import('@prisma-next/psl-parser').PslAttribute,\n): Record<string, unknown> | null | undefined {\n const locale = stripQuotesHelper(getNamedArgument(attr, 'collationLocale'));\n if (!locale) {\n const hasAnyCollationArg =\n getNamedArgument(attr, 'collationStrength') != null ||\n getNamedArgument(attr, 'collationCaseLevel') != null ||\n getNamedArgument(attr, 'collationCaseFirst') != null ||\n getNamedArgument(attr, 'collationNumericOrdering') != null ||\n getNamedArgument(attr, 'collationAlternate') != null ||\n getNamedArgument(attr, 'collationMaxVariable') != null ||\n getNamedArgument(attr, 'collationBackwards') != null ||\n getNamedArgument(attr, 'collationNormalization') != null;\n return hasAnyCollationArg ? null : undefined;\n }\n\n const collation: Record<string, unknown> = { locale };\n const strength = parseNumericArg(getNamedArgument(attr, 'collationStrength'));\n if (strength != null) collation['strength'] = strength;\n const caseLevel = parseBooleanArg(getNamedArgument(attr, 'collationCaseLevel'));\n if (caseLevel != null) collation['caseLevel'] = caseLevel;\n const caseFirst = stripQuotesHelper(getNamedArgument(attr, 'collationCaseFirst'));\n if (caseFirst != null) collation['caseFirst'] = caseFirst;\n const numericOrdering = parseBooleanArg(getNamedArgument(attr, 'collationNumericOrdering'));\n if (numericOrdering != null) collation['numericOrdering'] = numericOrdering;\n const alternate = stripQuotesHelper(getNamedArgument(attr, 'collationAlternate'));\n if (alternate != null) collation['alternate'] = alternate;\n const maxVariable = stripQuotesHelper(getNamedArgument(attr, 'collationMaxVariable'));\n if (maxVariable != null) collation['maxVariable'] = maxVariable;\n const backwards = parseBooleanArg(getNamedArgument(attr, 'collationBackwards'));\n if (backwards != null) collation['backwards'] = backwards;\n const normalization = parseBooleanArg(getNamedArgument(attr, 'collationNormalization'));\n if (normalization != null) collation['normalization'] = normalization;\n return collation;\n}\n\nfunction stripQuotesHelper(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n return raw.replace(/^[\"']/, '').replace(/[\"']$/, '');\n}\n\nfunction parseProjectionList(\n raw: string | undefined,\n value: 0 | 1,\n): Record<string, 0 | 1> | undefined {\n if (!raw) return undefined;\n const stripped = raw.replace(/^[\"']/, '').replace(/[\"']$/, '');\n const inner = stripped.replace(/^\\[/, '').replace(/\\]$/, '').trim();\n if (inner.length === 0) return undefined;\n const fields = inner\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n const result: Record<string, 0 | 1> = {};\n for (const f of fields) {\n result[f] = value;\n }\n return result;\n}\n\nfunction collectIndexes(\n pslModel: PslModel,\n fieldMappings: FieldMappings,\n modelNames: ReadonlySet<string>,\n sourceId: string,\n diagnostics: ContractSourceDiagnostic[],\n indexSpans: Map<MongoIndex, PslSpan>,\n): MongoIndex[] {\n const indexes: MongoIndex[] = [];\n let textIndexCount = 0;\n\n // Storage-indexable PSL field names — i.e. all declared fields except\n // relation fields (which don't materialize a column on this model). The\n // index field-existence check (PSL_INDEX_FIELD_NOT_FOUND) consults this\n // rather than fieldMappings.pslNameToMapped because the latter contains\n // every PSL field including relation fields.\n const indexableFieldNames = new Set<string>();\n for (const f of pslModel.fields) {\n if (modelNames.has(f.typeName)) continue;\n indexableFieldNames.add(f.name);\n }\n\n for (const field of pslModel.fields) {\n if (modelNames.has(field.typeName)) continue;\n const uniqueAttr = getAttribute(field.attributes, 'unique');\n if (!uniqueAttr) continue;\n const mappedName = fieldMappings.pslNameToMapped.get(field.name) ?? field.name;\n const fieldUniqueIndex = new MongoIndex({\n keys: [{ field: mappedName, direction: 1 }],\n unique: true,\n });\n indexes.push(fieldUniqueIndex);\n indexSpans.set(fieldUniqueIndex, uniqueAttr.span);\n }\n\n for (const attr of pslModel.attributes) {\n const isIndex = attr.name === 'index';\n const isUnique = attr.name === 'unique';\n const isTextIndex = attr.name === 'textIndex';\n if (!isIndex && !isUnique && !isTextIndex) continue;\n\n const fieldsArg = getPositionalArgument(attr, 0);\n if (!fieldsArg) continue;\n const parsedFields = parseIndexFieldList(fieldsArg);\n if (parsedFields.length === 0) continue;\n\n const hasWildcard = parsedFields.some((f) => f.isWildcard);\n const wildcardCount = parsedFields.filter((f) => f.isWildcard).length;\n\n if (wildcardCount > 1) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'An index can contain at most one wildcard() field',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (isUnique && hasWildcard) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'Unique indexes cannot use wildcard() fields',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (isTextIndex) {\n textIndexCount++;\n if (textIndexCount > 1) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: `Only one @@textIndex is allowed per collection (model \"${pslModel.name}\")`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (hasWildcard) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message:\n 'wildcard() fields cannot be combined with type: hashed/2dsphere/2d or @@textIndex',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n }\n\n const typeArg = getNamedArgument(attr, 'type');\n const defaultDirection: MongoIndexKeyDirection = isTextIndex\n ? 'text'\n : parseIndexDirection(typeArg);\n\n if (\n hasWildcard &&\n typeof defaultDirection === 'string' &&\n ['hashed', '2dsphere', '2d'].includes(defaultDirection)\n ) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: `wildcard() fields cannot be combined with type: ${defaultDirection}`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (defaultDirection === 'hashed' && parsedFields.length > 1) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'Hashed indexes must have exactly one field',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n let missingField: string | undefined;\n for (const pf of parsedFields) {\n let fieldNameForLookup: string | undefined;\n if (pf.isWildcard) {\n const wildcardMatch = pf.name.match(/^(.+)\\.\\$\\*\\*$/);\n fieldNameForLookup = wildcardMatch ? wildcardMatch[1] : undefined;\n } else {\n fieldNameForLookup = pf.name;\n }\n if (fieldNameForLookup === undefined || fieldNameForLookup.length === 0) continue;\n if (!indexableFieldNames.has(fieldNameForLookup)) {\n missingField = fieldNameForLookup;\n break;\n }\n }\n if (missingField !== undefined) {\n diagnostics.push({\n code: 'PSL_INDEX_FIELD_NOT_FOUND',\n message: `Index on model \"${pslModel.name}\" references unknown field \"${missingField}\"`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const keys = parsedFields.map((pf) => {\n const mappedName = pf.isWildcard\n ? pf.name.replace(/^(.+)\\.\\$\\*\\*$/, (_, prefix: string) => {\n const mapped = fieldMappings.pslNameToMapped.get(prefix);\n return mapped ? `${mapped}.$**` : `${prefix}.$**`;\n })\n : (fieldMappings.pslNameToMapped.get(pf.name) ?? pf.name);\n const direction: MongoIndexKeyDirection =\n pf.direction != null ? (pf.direction as MongoIndexKeyDirection) : defaultDirection;\n return { field: mappedName, direction };\n });\n\n const unique = isUnique ? true : undefined;\n const sparse = isTextIndex ? undefined : parseBooleanArg(getNamedArgument(attr, 'sparse'));\n const expireAfterSeconds = isTextIndex\n ? undefined\n : parseNumericArg(getNamedArgument(attr, 'expireAfterSeconds'));\n\n if (hasWildcard && expireAfterSeconds != null) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'expireAfterSeconds cannot be combined with wildcard() fields',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const partialFilterExpression = parseJsonArg(getNamedArgument(attr, 'filter'));\n\n const includeArg = getNamedArgument(attr, 'include');\n const excludeArg = getNamedArgument(attr, 'exclude');\n\n if (includeArg != null && excludeArg != null) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'Cannot specify both include and exclude on the same index',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if ((includeArg != null || excludeArg != null) && !hasWildcard) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message:\n 'include/exclude options are only valid when the index contains a wildcard() field',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const wildcardProjection =\n includeArg != null\n ? parseProjectionList(includeArg, 1)\n : excludeArg != null\n ? parseProjectionList(excludeArg, 0)\n : undefined;\n\n const collation = parseCollation(attr);\n if (collation === null) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'collationLocale is required when using collation options',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const rawWeights = parseJsonArg(getNamedArgument(attr, 'weights'));\n let weights: Record<string, number> | undefined;\n if (rawWeights) {\n weights = {};\n for (const [k, v] of Object.entries(rawWeights)) {\n if (typeof v === 'number') weights[k] = v;\n }\n }\n\n const rawDefaultLang = isTextIndex\n ? getNamedArgument(attr, 'language')\n : getNamedArgument(attr, 'default_language');\n const default_language = stripQuotesHelper(rawDefaultLang);\n\n const rawLangOverride = getNamedArgument(attr, 'languageOverride');\n const language_override = stripQuotesHelper(rawLangOverride);\n\n const index = new MongoIndex({\n keys,\n ...(unique != null && { unique }),\n ...(sparse != null && { sparse }),\n ...(expireAfterSeconds != null && { expireAfterSeconds }),\n ...(partialFilterExpression != null && { partialFilterExpression }),\n ...(wildcardProjection != null && { wildcardProjection }),\n ...(collation != null && { collation }),\n ...(weights != null && { weights }),\n ...(default_language != null && { default_language }),\n ...(language_override != null && { language_override }),\n });\n\n indexes.push(index);\n indexSpans.set(index, attr.span);\n }\n\n return indexes;\n}\n\nfunction isRelationField(field: PslField, modelNames: ReadonlySet<string>): boolean {\n return modelNames.has(field.typeName);\n}\n\n// PSL scalar type name whose codec is mandated for a Mongo model's `_id`.\nconst MONGO_OBJECT_ID_PSL_TYPE = 'ObjectId';\n\nfunction resolveFieldCodecId(\n field: PslField,\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n): string | undefined {\n return scalarTypeDescriptors.get(field.typeName);\n}\n\nfunction resolveNonRelationField(\n field: PslField,\n ownerName: string,\n compositeTypeNames: ReadonlySet<string>,\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n sourceId: string,\n diagnostics: ContractSourceDiagnostic[],\n): ContractField | undefined {\n if (compositeTypeNames.has(field.typeName)) {\n const result: ContractField = {\n type: { kind: 'valueObject', name: field.typeName },\n nullable: field.optional,\n };\n return field.list ? { ...result, many: true } : result;\n }\n\n const codecId = resolveFieldCodecId(field, scalarTypeDescriptors);\n if (!codecId) {\n diagnostics.push({\n code: 'PSL_UNSUPPORTED_FIELD_TYPE',\n message: `Field \"${ownerName}.${field.name}\" type \"${field.typeName}\" is not supported in Mongo PSL interpreter`,\n sourceId,\n span: field.span,\n });\n return undefined;\n }\n\n const result: ContractField = {\n type: { kind: 'scalar', codecId },\n nullable: field.optional,\n };\n return field.list ? { ...result, many: true } : result;\n}\n\nexport function interpretPslDocumentToMongoContract(\n input: InterpretPslDocumentToMongoContractInput,\n): Result<Contract, ContractSourceDiagnostics> {\n const { document, scalarTypeDescriptors, codecLookup } = input;\n const sourceId = document.ast.sourceId;\n const diagnostics: ContractSourceDiagnostic[] = [];\n validateNamespaceBlocksForMongoTarget({\n namespaces: document.ast.namespaces,\n sourceId,\n diagnostics,\n });\n // Mongo lowers only the implicit `__unspecified__` bucket today —\n // explicit `namespace { … }` blocks were rejected above. The IR\n // collection map remains flat (and the Mongo target represents\n // databases via `MongoTargetDatabase`, populated at compose time by\n // the connection string rather than authoring-time PSL).\n const allModels = document.ast.namespaces.flatMap((ns) => ns.models);\n const allCompositeTypes = document.ast.namespaces.flatMap((ns) => ns.compositeTypes);\n const modelNames = new Set(allModels.map((m) => m.name));\n const compositeTypeNames = new Set(allCompositeTypes.map((ct) => ct.name));\n\n const models: Record<string, MongoModelEntry> = {};\n const collections: Record<string, Record<string, unknown>> = {};\n const roots: Record<string, CrossReference> = {};\n const allFkRelations: FkRelation[] = [];\n const indexSpans = new Map<MongoIndex, PslSpan>();\n const modelIndexesByName = new Map<string, readonly MongoIndex[]>();\n\n interface BackrelationCandidate {\n readonly modelName: string;\n readonly fieldName: string;\n readonly targetModelName: string;\n readonly relationName?: string;\n readonly cardinality: '1:1' | '1:N';\n readonly field: PslField;\n }\n const backrelationCandidates: BackrelationCandidate[] = [];\n\n for (const pslModel of allModels) {\n const collectionName = resolveCollectionName(pslModel);\n const fieldMappings = resolveFieldMappings(pslModel);\n\n const fields: Record<string, ContractField> = {};\n const relations: Record<string, ContractReferenceRelation> = {};\n\n for (const field of pslModel.fields) {\n if (isRelationField(field, modelNames)) {\n const relation = parseRelationAttribute(field.attributes);\n\n if (field.list || !(relation?.fields && relation?.references)) {\n backrelationCandidates.push({\n modelName: pslModel.name,\n fieldName: field.name,\n targetModelName: field.typeName,\n ...(relation?.relationName !== undefined\n ? { relationName: relation.relationName }\n : {}),\n cardinality: field.list ? '1:N' : '1:1',\n field,\n });\n continue;\n }\n\n if (relation?.fields && relation?.references) {\n const localMapped = relation.fields.map((f) => fieldMappings.pslNameToMapped.get(f) ?? f);\n\n const targetModel = allModels.find((m) => m.name === field.typeName);\n const targetFieldMappings = targetModel ? resolveFieldMappings(targetModel) : undefined;\n const targetMapped = relation.references.map(\n (f) => targetFieldMappings?.pslNameToMapped.get(f) ?? f,\n );\n\n relations[field.name] = {\n to: mongoCrossRef(field.typeName),\n cardinality: 'N:1' as const,\n on: {\n localFields: localMapped,\n targetFields: targetMapped,\n },\n };\n\n allFkRelations.push({\n declaringModel: pslModel.name,\n fieldName: field.name,\n targetModel: field.typeName,\n ...(relation.relationName !== undefined ? { relationName: relation.relationName } : {}),\n localFields: localMapped,\n targetFields: targetMapped,\n });\n }\n continue;\n }\n\n const resolved = resolveNonRelationField(\n field,\n pslModel.name,\n compositeTypeNames,\n scalarTypeDescriptors,\n sourceId,\n diagnostics,\n );\n if (!resolved) continue;\n\n const mappedName = fieldMappings.pslNameToMapped.get(field.name) ?? field.name;\n fields[mappedName] = resolved;\n }\n\n const isVariantModel = pslModel.attributes.some((attr) => attr.name === 'base');\n const hasIdField = pslModel.fields.some((f) => getAttribute(f.attributes, 'id') !== undefined);\n // Variant models inherit the base's identity and are validated through their base.\n if (!isVariantModel) {\n if (!hasIdField) {\n diagnostics.push({\n code: 'PSL_MISSING_ID_FIELD',\n message: `Model \"${pslModel.name}\" has no field with @id attribute. Every model must have exactly one @id field.`,\n sourceId,\n });\n } else {\n // The resulting document must carry an `_id` of BSON type objectId. We\n // assert on the emitted shape (the mapped-name-keyed field record), not\n // on how the user spelled it — `id ObjectId @id @map(\"_id\")` and a field\n // literally named `_id` both satisfy it; a non-objectId or unmapped id\n // does not.\n const objectIdCodecId = scalarTypeDescriptors.get(MONGO_OBJECT_ID_PSL_TYPE);\n const idField = fields['_id'];\n const idIsObjectId =\n idField !== undefined &&\n idField.type.kind === 'scalar' &&\n objectIdCodecId !== undefined &&\n idField.type.codecId === objectIdCodecId;\n if (!idIsObjectId) {\n diagnostics.push({\n code: 'PSL_MONGO_ID_REQUIRED',\n message: `Model \"${pslModel.name}\" must declare an _id field of type ObjectId (e.g. \\`id ObjectId @id @map(\"_id\")\\`).`,\n sourceId,\n });\n }\n }\n }\n\n models[pslModel.name] = { fields, relations, storage: { collection: collectionName } };\n const modelIndexes = collectIndexes(\n pslModel,\n fieldMappings,\n modelNames,\n sourceId,\n diagnostics,\n indexSpans,\n );\n modelIndexesByName.set(pslModel.name, modelIndexes);\n const existingColl = collections[collectionName];\n if (existingColl && modelIndexes.length > 0) {\n const existingIndexes = (existingColl['indexes'] ?? []) as MongoIndex[];\n collections[collectionName] = { indexes: [...existingIndexes, ...modelIndexes] };\n } else if (!existingColl) {\n collections[collectionName] = modelIndexes.length > 0 ? { indexes: modelIndexes } : {};\n }\n roots[collectionName] = mongoCrossRef(pslModel.name);\n }\n\n const valueObjects: Record<string, ContractValueObject> = {};\n for (const compositeType of allCompositeTypes) {\n const fields: Record<string, ContractField> = {};\n for (const field of compositeType.fields) {\n const resolved = resolveNonRelationField(\n field,\n compositeType.name,\n compositeTypeNames,\n scalarTypeDescriptors,\n sourceId,\n diagnostics,\n );\n if (!resolved) continue;\n fields[field.name] = resolved;\n }\n valueObjects[compositeType.name] = { fields };\n }\n\n const fkRelationsByPair = new Map<string, FkRelation[]>();\n for (const fk of allFkRelations) {\n const key = fkRelationPairKey(fk.declaringModel, fk.targetModel);\n const existing = fkRelationsByPair.get(key);\n if (existing) {\n existing.push(fk);\n } else {\n fkRelationsByPair.set(key, [fk]);\n }\n }\n\n for (const candidate of backrelationCandidates) {\n const pairKey = fkRelationPairKey(candidate.targetModelName, candidate.modelName);\n const pairMatches = fkRelationsByPair.get(pairKey) ?? [];\n const matches = candidate.relationName\n ? pairMatches.filter((r) => r.relationName === candidate.relationName)\n : [...pairMatches];\n\n if (matches.length === 0) {\n diagnostics.push({\n code: 'PSL_ORPHANED_BACKRELATION',\n message: `Backrelation list field \"${candidate.modelName}.${candidate.fieldName}\" has no matching FK-side relation on model \"${candidate.targetModelName}\". Add @relation(fields: [...], references: [...]) on the FK-side relation or use an explicit join model for many-to-many.`,\n sourceId,\n span: candidate.field.span,\n });\n continue;\n }\n if (matches.length > 1) {\n diagnostics.push({\n code: 'PSL_AMBIGUOUS_BACKRELATION',\n message: `Backrelation list field \"${candidate.modelName}.${candidate.fieldName}\" matches multiple FK-side relations on model \"${candidate.targetModelName}\". Add @relation(\"...\") to both sides to disambiguate.`,\n sourceId,\n span: candidate.field.span,\n });\n continue;\n }\n\n const fk = matches[0];\n if (!fk) continue;\n const modelEntry = models[candidate.modelName];\n if (!modelEntry) continue;\n modelEntry.relations[candidate.fieldName] = {\n to: mongoCrossRef(candidate.targetModelName),\n cardinality: candidate.cardinality,\n on: {\n localFields: fk.targetFields,\n targetFields: fk.localFields,\n },\n };\n }\n\n const { discriminatorDeclarations, baseDeclarations } = collectPolymorphismDeclarations(\n document,\n sourceId,\n diagnostics,\n );\n const polyResult = resolvePolymorphism({\n models,\n roots,\n collections,\n document,\n discriminatorDeclarations,\n baseDeclarations,\n modelNames,\n indexSpans,\n modelIndexesByName,\n sourceId,\n });\n\n if (diagnostics.length > 0 || polyResult.diagnostics.length > 0) {\n return notOk({\n summary: 'PSL to Mongo contract interpretation failed',\n diagnostics: [...diagnostics, ...polyResult.diagnostics],\n });\n }\n\n const resolvedModels = polyResult.models;\n const resolvedCollections = polyResult.collections;\n\n for (const [, modelEntry] of Object.entries(resolvedModels)) {\n if (modelEntry.base) continue;\n\n const collectionName = modelEntry.storage.collection;\n const coll = resolvedCollections[collectionName];\n if (!coll) continue;\n\n if (modelEntry.discriminator && modelEntry.variants) {\n const variantEntries = Object.entries(modelEntry.variants).map(\n ([variantName, { value }]) => ({\n discriminatorValue: value,\n fields: resolvedModels[variantName]?.fields ?? {},\n }),\n );\n coll['validator'] = derivePolymorphicJsonSchema(\n modelEntry.fields,\n modelEntry.discriminator.field,\n variantEntries,\n valueObjects,\n codecLookup,\n );\n } else {\n coll['validator'] = deriveJsonSchema(modelEntry.fields, valueObjects, codecLookup);\n }\n }\n\n const target = 'mongo';\n const targetFamily = 'mongo';\n const collectionsAsClasses: Record<string, MongoCollection> = {};\n for (const [name, coll] of Object.entries(resolvedCollections)) {\n const input: {\n indexes?: ReadonlyArray<MongoIndex>;\n validator?: unknown;\n options?: unknown;\n } = {};\n if (coll['indexes'] !== undefined) {\n input.indexes = coll['indexes'] as ReadonlyArray<MongoIndex>;\n }\n if (coll['validator'] !== undefined) {\n input.validator = coll['validator'];\n }\n if (coll['options'] !== undefined) {\n input.options = coll['options'];\n }\n // input.validator/options are arktype-validated JSON shapes; MongoCollection\n // constructor normalises them into MongoValidator / MongoCollectionOptions\n // instances. The narrow cast is bounded to the field-typed input record.\n collectionsAsClasses[name] = new MongoCollection(\n input as ConstructorParameters<typeof MongoCollection>[0],\n );\n }\n const storageWithoutHash = {\n namespaces: {\n [UNBOUND_NAMESPACE_ID]: {\n id: UNBOUND_NAMESPACE_ID,\n collections: collectionsAsClasses,\n },\n },\n };\n const storageHash = computeStorageHash({\n target,\n targetFamily,\n storage: storageWithoutHash,\n ...mongoContractCanonicalizationHooks,\n });\n const storage = new MongoStorage({\n storageHash,\n namespaces: {\n [UNBOUND_NAMESPACE_ID]: buildMongoNamespace({\n id: UNBOUND_NAMESPACE_ID,\n collections: collectionsAsClasses,\n }),\n },\n }) as Contract['storage'];\n const capabilities: Record<string, Record<string, boolean>> = {};\n\n return ok({\n targetFamily,\n target,\n roots: polyResult.roots,\n domain: {\n namespaces: {\n [UNBOUND_NAMESPACE_ID]: {\n models: polyResult.models,\n ...(Object.keys(valueObjects).length > 0 ? { valueObjects } : {}),\n },\n },\n },\n storage,\n extensionPacks: {},\n capabilities,\n profileHash: computeProfileHash({ target, targetFamily, capabilities }),\n meta: {},\n });\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,36 +1,47 @@
1
1
  {
2
2
  "name": "@prisma-next/mongo-contract-psl",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "description": "PSL-to-Mongo ContractIR interpreter for Prisma Next",
8
8
  "dependencies": {
9
- "@prisma-next/config": "0.11.0",
10
- "@prisma-next/contract": "0.11.0",
11
- "@prisma-next/framework-components": "0.11.0",
12
- "@prisma-next/mongo-contract": "0.11.0",
13
- "@prisma-next/psl-parser": "0.11.0",
14
- "@prisma-next/utils": "0.11.0",
9
+ "@prisma-next/config": "0.12.0",
10
+ "@prisma-next/contract": "0.12.0",
11
+ "@prisma-next/framework-components": "0.12.0",
12
+ "@prisma-next/mongo-contract": "0.12.0",
13
+ "@prisma-next/psl-parser": "0.12.0",
14
+ "@prisma-next/utils": "0.12.0",
15
15
  "pathe": "^2.0.3"
16
16
  },
17
17
  "devDependencies": {
18
- "@prisma-next/tsconfig": "0.11.0",
19
- "@prisma-next/tsdown": "0.11.0",
18
+ "@prisma-next/tsconfig": "0.12.0",
19
+ "@prisma-next/tsdown": "0.12.0",
20
20
  "tsdown": "0.22.0",
21
21
  "typescript": "5.9.3",
22
22
  "vitest": "4.1.6"
23
23
  },
24
+ "peerDependencies": {
25
+ "typescript": ">=5.9"
26
+ },
27
+ "peerDependenciesMeta": {
28
+ "typescript": {
29
+ "optional": true
30
+ }
31
+ },
24
32
  "files": [
25
33
  "dist",
26
34
  "src"
27
35
  ],
36
+ "types": "./dist/index.d.mts",
28
37
  "exports": {
29
38
  ".": "./dist/index.mjs",
30
39
  "./provider": "./dist/exports/provider.mjs",
31
40
  "./package.json": "./package.json"
32
41
  },
33
- "types": "./dist/index.d.mts",
42
+ "engines": {
43
+ "node": ">=24"
44
+ },
34
45
  "repository": {
35
46
  "type": "git",
36
47
  "url": "https://github.com/prisma/prisma-next.git",
@@ -66,6 +66,9 @@ function deriveObjectSchema(
66
66
  const result: Record<string, unknown> = {
67
67
  bsonType: 'object',
68
68
  properties,
69
+ // Closed by default: documents carrying fields not declared in `properties`
70
+ // are rejected at every level (top-level collections and nested value objects).
71
+ additionalProperties: false,
69
72
  };
70
73
  if (required.length > 0) {
71
74
  result['required'] = required.sort();
@@ -73,6 +76,10 @@ function deriveObjectSchema(
73
76
  return result;
74
77
  }
75
78
 
79
+ function isRecord(value: unknown): value is Record<string, unknown> {
80
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
81
+ }
82
+
76
83
  export function deriveJsonSchema(
77
84
  fields: Record<string, ContractField>,
78
85
  valueObjects?: Record<string, ContractValueObject>,
@@ -98,6 +105,7 @@ export function derivePolymorphicJsonSchema(
98
105
  codecLookup?: CodecLookup,
99
106
  ): MongoValidator {
100
107
  const baseSchema = deriveObjectSchema(baseFields, valueObjects, codecLookup);
108
+ const baseProperties = isRecord(baseSchema['properties']) ? baseSchema['properties'] : {};
101
109
 
102
110
  const oneOf: Record<string, unknown>[] = [];
103
111
  for (const variant of variants) {
@@ -108,12 +116,6 @@ export function derivePolymorphicJsonSchema(
108
116
  }
109
117
  }
110
118
 
111
- const entry: Record<string, unknown> = {
112
- properties: {
113
- [discriminatorField]: { enum: [variant.discriminatorValue] },
114
- },
115
- };
116
-
117
119
  const variantProperties: Record<string, unknown> = {};
118
120
  const variantRequired: string[] = [discriminatorField];
119
121
  for (const [name, field] of Object.entries(variantOnlyFields)) {
@@ -126,18 +128,29 @@ export function derivePolymorphicJsonSchema(
126
128
  }
127
129
  }
128
130
 
129
- if (Object.keys(variantProperties).length > 0) {
130
- (entry['properties'] as Record<string, unknown>) = {
131
- ...(entry['properties'] as Record<string, unknown>),
131
+ // `additionalProperties: false` only sees the `properties` of the schema
132
+ // object it sits on — it does not look into sibling `oneOf` branches. Each
133
+ // branch is validated independently, so a closed branch must list the base
134
+ // properties too; otherwise it would reject the base fields. The
135
+ // discriminator is constrained to this variant's value.
136
+ const entry: Record<string, unknown> = {
137
+ properties: {
138
+ ...baseProperties,
139
+ [discriminatorField]: { enum: [variant.discriminatorValue] },
132
140
  ...variantProperties,
133
- };
134
- }
135
- entry['required'] = variantRequired.sort();
141
+ },
142
+ required: variantRequired.sort(),
143
+ additionalProperties: false,
144
+ };
136
145
 
137
146
  oneOf.push(entry);
138
147
  }
139
148
 
149
+ // The top-level schema stays open: closure is enforced by the closed branches.
150
+ // Keeping `additionalProperties: false` here would reject every variant-only
151
+ // field, since the top-level `properties` only lists base fields.
140
152
  const jsonSchema = { ...baseSchema };
153
+ delete jsonSchema['additionalProperties'];
141
154
  if (oneOf.length > 0) {
142
155
  jsonSchema['oneOf'] = oneOf;
143
156
  }
@@ -3,21 +3,25 @@ import type {
3
3
  ContractSourceDiagnostics,
4
4
  } from '@prisma-next/config/config-types';
5
5
  import { computeProfileHash, computeStorageHash } from '@prisma-next/contract/hashing';
6
- import type {
7
- Contract,
8
- ContractField,
9
- ContractReferenceRelation,
10
- ContractValueObject,
6
+ import {
7
+ type Contract,
8
+ type ContractField,
9
+ type ContractReferenceRelation,
10
+ type ContractValueObject,
11
+ type CrossReference,
12
+ crossRef,
11
13
  } from '@prisma-next/contract/types';
12
14
  import type { CodecLookup } from '@prisma-next/framework-components/codec';
13
15
  import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
14
16
  import {
15
17
  applyPolymorphicScopeToMongoIndex,
18
+ buildMongoNamespace,
16
19
  MongoCollection,
17
20
  MongoIndex,
18
21
  type MongoIndexKeyDirection,
19
22
  MongoStorage,
20
23
  } from '@prisma-next/mongo-contract';
24
+ import { mongoContractCanonicalizationHooks } from '@prisma-next/mongo-contract/canonicalization-hooks';
21
25
  import type {
22
26
  ParsePslDocumentResult,
23
27
  PslField,
@@ -114,7 +118,7 @@ interface MongoModelEntry {
114
118
  readonly storage: { readonly collection: string };
115
119
  readonly discriminator?: { readonly field: string };
116
120
  readonly variants?: Record<string, { readonly value: string }>;
117
- readonly base?: string;
121
+ readonly base?: CrossReference;
118
122
  }
119
123
 
120
124
  type DiscriminatorDeclaration = { readonly fieldName: string; readonly span: PslModel['span'] };
@@ -125,6 +129,10 @@ type BaseDeclaration = {
125
129
  readonly span: PslModel['span'];
126
130
  };
127
131
 
132
+ function mongoCrossRef(modelName: string): CrossReference {
133
+ return crossRef(modelName, UNBOUND_NAMESPACE_ID);
134
+ }
135
+
128
136
  function collectPolymorphismDeclarations(
129
137
  document: ParsePslDocumentResult,
130
138
  sourceId: string,
@@ -195,7 +203,7 @@ function collectPolymorphismDeclarations(
195
203
 
196
204
  function resolvePolymorphism(input: {
197
205
  models: Record<string, MongoModelEntry>;
198
- roots: Record<string, string>;
206
+ roots: Record<string, CrossReference>;
199
207
  collections: Record<string, Record<string, unknown>>;
200
208
  document: ParsePslDocumentResult;
201
209
  discriminatorDeclarations: Map<string, DiscriminatorDeclaration>;
@@ -206,7 +214,7 @@ function resolvePolymorphism(input: {
206
214
  sourceId: string;
207
215
  }): {
208
216
  models: Record<string, MongoModelEntry>;
209
- roots: Record<string, string>;
217
+ roots: Record<string, CrossReference>;
210
218
  collections: Record<string, Record<string, unknown>>;
211
219
  diagnostics: ContractSourceDiagnostic[];
212
220
  } {
@@ -323,16 +331,16 @@ function resolvePolymorphism(input: {
323
331
  ...patched,
324
332
  [variantName]: {
325
333
  ...variantModel,
326
- base: baseDecl.baseName,
334
+ base: mongoCrossRef(baseDecl.baseName),
327
335
  storage: { collection: baseCollection },
328
336
  },
329
337
  };
330
338
  }
331
339
 
332
340
  const variantCollectionName = resolveCollectionName(variantPslModel);
333
- if (roots[variantCollectionName] === variantName) {
341
+ if (roots[variantCollectionName]?.model === variantName) {
334
342
  if (variantCollectionName === baseCollection && baseModel) {
335
- roots = { ...roots, [variantCollectionName]: baseDecl.baseName };
343
+ roots = { ...roots, [variantCollectionName]: mongoCrossRef(baseDecl.baseName) };
336
344
  } else {
337
345
  roots = Object.fromEntries(
338
346
  Object.entries(roots).filter(([key]) => key !== variantCollectionName),
@@ -794,6 +802,9 @@ function isRelationField(field: PslField, modelNames: ReadonlySet<string>): bool
794
802
  return modelNames.has(field.typeName);
795
803
  }
796
804
 
805
+ // PSL scalar type name whose codec is mandated for a Mongo model's `_id`.
806
+ const MONGO_OBJECT_ID_PSL_TYPE = 'ObjectId';
807
+
797
808
  function resolveFieldCodecId(
798
809
  field: PslField,
799
810
  scalarTypeDescriptors: ReadonlyMap<string, string>,
@@ -858,7 +869,7 @@ export function interpretPslDocumentToMongoContract(
858
869
 
859
870
  const models: Record<string, MongoModelEntry> = {};
860
871
  const collections: Record<string, Record<string, unknown>> = {};
861
- const roots: Record<string, string> = {};
872
+ const roots: Record<string, CrossReference> = {};
862
873
  const allFkRelations: FkRelation[] = [];
863
874
  const indexSpans = new Map<MongoIndex, PslSpan>();
864
875
  const modelIndexesByName = new Map<string, readonly MongoIndex[]>();
@@ -908,7 +919,7 @@ export function interpretPslDocumentToMongoContract(
908
919
  );
909
920
 
910
921
  relations[field.name] = {
911
- to: field.typeName,
922
+ to: mongoCrossRef(field.typeName),
912
923
  cardinality: 'N:1' as const,
913
924
  on: {
914
925
  localFields: localMapped,
@@ -944,12 +955,35 @@ export function interpretPslDocumentToMongoContract(
944
955
 
945
956
  const isVariantModel = pslModel.attributes.some((attr) => attr.name === 'base');
946
957
  const hasIdField = pslModel.fields.some((f) => getAttribute(f.attributes, 'id') !== undefined);
947
- if (!hasIdField && !isVariantModel) {
948
- diagnostics.push({
949
- code: 'PSL_MISSING_ID_FIELD',
950
- message: `Model "${pslModel.name}" has no field with @id attribute. Every model must have exactly one @id field.`,
951
- sourceId,
952
- });
958
+ // Variant models inherit the base's identity and are validated through their base.
959
+ if (!isVariantModel) {
960
+ if (!hasIdField) {
961
+ diagnostics.push({
962
+ code: 'PSL_MISSING_ID_FIELD',
963
+ message: `Model "${pslModel.name}" has no field with @id attribute. Every model must have exactly one @id field.`,
964
+ sourceId,
965
+ });
966
+ } else {
967
+ // The resulting document must carry an `_id` of BSON type objectId. We
968
+ // assert on the emitted shape (the mapped-name-keyed field record), not
969
+ // on how the user spelled it — `id ObjectId @id @map("_id")` and a field
970
+ // literally named `_id` both satisfy it; a non-objectId or unmapped id
971
+ // does not.
972
+ const objectIdCodecId = scalarTypeDescriptors.get(MONGO_OBJECT_ID_PSL_TYPE);
973
+ const idField = fields['_id'];
974
+ const idIsObjectId =
975
+ idField !== undefined &&
976
+ idField.type.kind === 'scalar' &&
977
+ objectIdCodecId !== undefined &&
978
+ idField.type.codecId === objectIdCodecId;
979
+ if (!idIsObjectId) {
980
+ diagnostics.push({
981
+ code: 'PSL_MONGO_ID_REQUIRED',
982
+ message: `Model "${pslModel.name}" must declare an _id field of type ObjectId (e.g. \`id ObjectId @id @map("_id")\`).`,
983
+ sourceId,
984
+ });
985
+ }
986
+ }
953
987
  }
954
988
 
955
989
  models[pslModel.name] = { fields, relations, storage: { collection: collectionName } };
@@ -969,7 +1003,7 @@ export function interpretPslDocumentToMongoContract(
969
1003
  } else if (!existingColl) {
970
1004
  collections[collectionName] = modelIndexes.length > 0 ? { indexes: modelIndexes } : {};
971
1005
  }
972
- roots[collectionName] = pslModel.name;
1006
+ roots[collectionName] = mongoCrossRef(pslModel.name);
973
1007
  }
974
1008
 
975
1009
  const valueObjects: Record<string, ContractValueObject> = {};
@@ -1032,7 +1066,7 @@ export function interpretPslDocumentToMongoContract(
1032
1066
  const modelEntry = models[candidate.modelName];
1033
1067
  if (!modelEntry) continue;
1034
1068
  modelEntry.relations[candidate.fieldName] = {
1035
- to: candidate.targetModelName,
1069
+ to: mongoCrossRef(candidate.targetModelName),
1036
1070
  cardinality: candidate.cardinality,
1037
1071
  on: {
1038
1072
  localFields: fk.targetFields,
@@ -1128,10 +1162,20 @@ export function interpretPslDocumentToMongoContract(
1128
1162
  },
1129
1163
  },
1130
1164
  };
1131
- const storageHash = computeStorageHash({ target, targetFamily, storage: storageWithoutHash });
1165
+ const storageHash = computeStorageHash({
1166
+ target,
1167
+ targetFamily,
1168
+ storage: storageWithoutHash,
1169
+ ...mongoContractCanonicalizationHooks,
1170
+ });
1132
1171
  const storage = new MongoStorage({
1133
1172
  storageHash,
1134
- ...storageWithoutHash,
1173
+ namespaces: {
1174
+ [UNBOUND_NAMESPACE_ID]: buildMongoNamespace({
1175
+ id: UNBOUND_NAMESPACE_ID,
1176
+ collections: collectionsAsClasses,
1177
+ }),
1178
+ },
1135
1179
  }) as Contract['storage'];
1136
1180
  const capabilities: Record<string, Record<string, boolean>> = {};
1137
1181
 
@@ -1139,8 +1183,14 @@ export function interpretPslDocumentToMongoContract(
1139
1183
  targetFamily,
1140
1184
  target,
1141
1185
  roots: polyResult.roots,
1142
- models: polyResult.models,
1143
- ...(Object.keys(valueObjects).length > 0 ? { valueObjects } : {}),
1186
+ domain: {
1187
+ namespaces: {
1188
+ [UNBOUND_NAMESPACE_ID]: {
1189
+ models: polyResult.models,
1190
+ ...(Object.keys(valueObjects).length > 0 ? { valueObjects } : {}),
1191
+ },
1192
+ },
1193
+ },
1144
1194
  storage,
1145
1195
  extensionPacks: {},
1146
1196
  capabilities,
@@ -1 +0,0 @@
1
- {"version":3,"file":"interpreter-COTnSq1Y.mjs","names":[],"sources":["../src/derive-json-schema.ts","../src/psl-helpers.ts","../src/interpreter.ts"],"sourcesContent":["import type { ContractField, ContractValueObject } from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { MongoValidator } from '@prisma-next/mongo-contract';\n\nfunction resolveBsonType(\n codecId: string,\n codecLookup: CodecLookup | undefined,\n): string | undefined {\n return codecLookup?.targetTypesFor(codecId)?.[0];\n}\n\nfunction fieldToBsonSchema(\n field: ContractField,\n valueObjects: Record<string, ContractValueObject> | undefined,\n codecLookup: CodecLookup | undefined,\n): Record<string, unknown> | undefined {\n if (field.type.kind === 'scalar') {\n const bsonType = resolveBsonType(field.type.codecId, codecLookup);\n if (!bsonType) return undefined;\n\n if ('many' in field && field.many) {\n return { bsonType: 'array', items: { bsonType } };\n }\n\n if (field.nullable) {\n return { bsonType: ['null', bsonType] };\n }\n\n return { bsonType };\n }\n\n if (field.type.kind === 'valueObject') {\n const vo = valueObjects?.[field.type.name];\n if (!vo) return undefined;\n const voSchema = deriveObjectSchema(vo.fields, valueObjects, codecLookup);\n if ('many' in field && field.many) {\n return { bsonType: 'array', items: voSchema };\n }\n if (field.nullable) {\n return { oneOf: [{ bsonType: 'null' }, voSchema] };\n }\n return voSchema;\n }\n\n return undefined;\n}\n\nfunction deriveObjectSchema(\n fields: Record<string, ContractField>,\n valueObjects: Record<string, ContractValueObject> | undefined,\n codecLookup: CodecLookup | undefined,\n): Record<string, unknown> {\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n for (const [fieldName, field] of Object.entries(fields)) {\n const schema = fieldToBsonSchema(field, valueObjects, codecLookup);\n if (schema) {\n properties[fieldName] = schema;\n if (!field.nullable) {\n required.push(fieldName);\n }\n }\n }\n\n const result: Record<string, unknown> = {\n bsonType: 'object',\n properties,\n };\n if (required.length > 0) {\n result['required'] = required.sort();\n }\n return result;\n}\n\nexport function deriveJsonSchema(\n fields: Record<string, ContractField>,\n valueObjects?: Record<string, ContractValueObject>,\n codecLookup?: CodecLookup,\n): MongoValidator {\n return new MongoValidator({\n jsonSchema: deriveObjectSchema(fields, valueObjects, codecLookup),\n validationLevel: 'strict',\n validationAction: 'error',\n });\n}\n\nexport interface PolymorphicVariant {\n readonly discriminatorValue: string;\n readonly fields: Record<string, ContractField>;\n}\n\nexport function derivePolymorphicJsonSchema(\n baseFields: Record<string, ContractField>,\n discriminatorField: string,\n variants: readonly PolymorphicVariant[],\n valueObjects?: Record<string, ContractValueObject>,\n codecLookup?: CodecLookup,\n): MongoValidator {\n const baseSchema = deriveObjectSchema(baseFields, valueObjects, codecLookup);\n\n const oneOf: Record<string, unknown>[] = [];\n for (const variant of variants) {\n const variantOnlyFields: Record<string, ContractField> = {};\n for (const [name, field] of Object.entries(variant.fields)) {\n if (!(name in baseFields)) {\n variantOnlyFields[name] = field;\n }\n }\n\n const entry: Record<string, unknown> = {\n properties: {\n [discriminatorField]: { enum: [variant.discriminatorValue] },\n },\n };\n\n const variantProperties: Record<string, unknown> = {};\n const variantRequired: string[] = [discriminatorField];\n for (const [name, field] of Object.entries(variantOnlyFields)) {\n const schema = fieldToBsonSchema(field, valueObjects, codecLookup);\n if (schema) {\n variantProperties[name] = schema;\n if (!field.nullable) {\n variantRequired.push(name);\n }\n }\n }\n\n if (Object.keys(variantProperties).length > 0) {\n (entry['properties'] as Record<string, unknown>) = {\n ...(entry['properties'] as Record<string, unknown>),\n ...variantProperties,\n };\n }\n entry['required'] = variantRequired.sort();\n\n oneOf.push(entry);\n }\n\n const jsonSchema = { ...baseSchema };\n if (oneOf.length > 0) {\n jsonSchema['oneOf'] = oneOf;\n }\n\n return new MongoValidator({\n jsonSchema,\n validationLevel: 'strict',\n validationAction: 'error',\n });\n}\n","import type { PslAttribute, PslAttributeArgument } from '@prisma-next/psl-parser';\nimport { getPositionalArgument, parseQuotedStringLiteral } from '@prisma-next/psl-parser';\n\nexport { getPositionalArgument, parseQuotedStringLiteral };\n\nexport function getNamedArgument(attr: PslAttribute, name: string): string | undefined {\n const arg = attr.args.find((a) => a.kind === 'named' && a.name === name);\n return arg?.value;\n}\n\nexport function parseFieldList(value: string): readonly string[] {\n const inner = value.replace(/^\\[/, '').replace(/\\]$/, '').trim();\n if (inner.length === 0) return [];\n return splitTopLevel(inner).map((s) => s.trim());\n}\n\nexport interface ParsedIndexField {\n readonly name: string;\n readonly isWildcard: boolean;\n readonly direction?: number;\n}\n\nexport function parseIndexFieldList(value: string): readonly ParsedIndexField[] {\n const segments = parseFieldList(value);\n return segments.map(parseIndexFieldSegment);\n}\n\nfunction parseIndexFieldSegment(segment: string): ParsedIndexField {\n const wildcardMatch = segment.match(/^wildcard\\(\\s*(.*?)\\s*\\)$/);\n if (wildcardMatch) {\n const scope = wildcardMatch[1] ?? '';\n return {\n name: scope.length > 0 ? `${scope}.$**` : '$**',\n isWildcard: true,\n };\n }\n\n const modifierMatch = segment.match(/^(\\w+)\\(\\s*sort:\\s*(\\w+)\\s*\\)$/);\n if (modifierMatch) {\n const fieldName = modifierMatch[1] ?? segment;\n const sortValue = modifierMatch[2];\n return {\n name: fieldName,\n isWildcard: false,\n direction: sortValue === 'Desc' ? -1 : 1,\n };\n }\n\n return { name: segment, isWildcard: false };\n}\n\nfunction splitTopLevel(input: string): string[] {\n const parts: string[] = [];\n let depth = 0;\n let start = 0;\n for (let i = 0; i < input.length; i++) {\n const ch = input[i];\n if (ch === '(' || ch === '[' || ch === '{') depth++;\n else if (ch === ')' || ch === ']' || ch === '}') depth = Math.max(0, depth - 1);\n else if (ch === ',' && depth === 0) {\n parts.push(input.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(input.slice(start));\n return parts;\n}\n\nexport function lowerFirst(value: string): string {\n if (value.length === 0) return value;\n return value[0]?.toLowerCase() + value.slice(1);\n}\n\nexport function getAttribute(\n attributes: readonly PslAttribute[],\n name: string,\n): PslAttribute | undefined {\n return attributes.find((attr) => attr.name === name);\n}\n\nexport function getMapName(attributes: readonly PslAttribute[]): string | undefined {\n const mapAttr = getAttribute(attributes, 'map');\n if (!mapAttr) return undefined;\n const arg = mapAttr.args[0];\n if (!arg) return undefined;\n return stripQuotes(arg.value);\n}\n\nexport interface ParsedRelationAttribute {\n readonly relationName?: string;\n readonly fields?: readonly string[];\n readonly references?: readonly string[];\n}\n\nexport function parseRelationAttribute(\n attributes: readonly PslAttribute[],\n): ParsedRelationAttribute | undefined {\n const relationAttr = getAttribute(attributes, 'relation');\n if (!relationAttr) return undefined;\n\n let relationName: string | undefined;\n let fieldsArg: PslAttributeArgument | undefined;\n let referencesArg: PslAttributeArgument | undefined;\n\n for (const arg of relationAttr.args) {\n if (arg.kind === 'positional') {\n relationName = stripQuotes(arg.value);\n } else if (arg.name === 'name') {\n relationName = stripQuotes(arg.value);\n } else if (arg.name === 'fields') {\n fieldsArg = arg;\n } else if (arg.name === 'references') {\n referencesArg = arg;\n }\n }\n\n const fields = fieldsArg ? parseFieldList(fieldsArg.value) : undefined;\n const references = referencesArg ? parseFieldList(referencesArg.value) : undefined;\n\n return {\n ...(relationName !== undefined ? { relationName } : {}),\n ...(fields !== undefined ? { fields } : {}),\n ...(references !== undefined ? { references } : {}),\n };\n}\n\nfunction stripQuotes(value: string): string {\n if (value.startsWith('\"') && value.endsWith('\"')) {\n return value.slice(1, -1);\n }\n return value;\n}\n","import type {\n ContractSourceDiagnostic,\n ContractSourceDiagnostics,\n} from '@prisma-next/config/config-types';\nimport { computeProfileHash, computeStorageHash } from '@prisma-next/contract/hashing';\nimport type {\n Contract,\n ContractField,\n ContractReferenceRelation,\n ContractValueObject,\n} from '@prisma-next/contract/types';\nimport type { CodecLookup } from '@prisma-next/framework-components/codec';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport {\n applyPolymorphicScopeToMongoIndex,\n MongoCollection,\n MongoIndex,\n type MongoIndexKeyDirection,\n MongoStorage,\n} from '@prisma-next/mongo-contract';\nimport type {\n ParsePslDocumentResult,\n PslField,\n PslModel,\n PslNamespace,\n PslSpan,\n} from '@prisma-next/psl-parser';\nimport { notOk, ok, type Result } from '@prisma-next/utils/result';\nimport { deriveJsonSchema, derivePolymorphicJsonSchema } from './derive-json-schema';\nimport {\n getAttribute,\n getMapName,\n getNamedArgument,\n getPositionalArgument,\n lowerFirst,\n parseIndexFieldList,\n parseQuotedStringLiteral,\n parseRelationAttribute,\n} from './psl-helpers';\n\nexport interface InterpretPslDocumentToMongoContractInput {\n readonly document: ParsePslDocumentResult;\n readonly scalarTypeDescriptors: ReadonlyMap<string, string>;\n readonly codecLookup?: CodecLookup;\n}\n\n/**\n * Name of the framework-parser synthesised bucket for top-level\n * declarations. Re-declared locally so the interpreter does not have to\n * import from `@prisma-next/framework-components/psl-ast`.\n */\nconst UNSPECIFIED_PSL_NAMESPACE_NAME = '__unspecified__';\n\n/**\n * Mongo FR16c validation: Mongo's authoring DSL exposes the connection's\n * database as the only namespace surface today, so the PSL interpreter\n * rejects every explicit `namespace { … }` block. The implicit\n * `__unspecified__` bucket (top-level declarations) is the only\n * namespace Mongo accepts. `namespace unbound { … }` is rejected too —\n * Mongo has no late-binding namespace concept on the PSL surface (the\n * database name comes from the connection string, not from PSL).\n */\nfunction validateNamespaceBlocksForMongoTarget(input: {\n readonly namespaces: readonly PslNamespace[];\n readonly sourceId: string;\n readonly diagnostics: ContractSourceDiagnostic[];\n}): void {\n for (const namespace of input.namespaces) {\n if (namespace.name === UNSPECIFIED_PSL_NAMESPACE_NAME) {\n continue;\n }\n input.diagnostics.push({\n code: 'PSL_UNSUPPORTED_NAMESPACE_BLOCK',\n message: `Mongo does not support \\`namespace ${namespace.name} { … }\\` blocks (the database is bound by the connection string; declare models at the document top level instead).`,\n sourceId: input.sourceId,\n span: namespace.span,\n });\n }\n}\n\ninterface FieldMappings {\n readonly pslNameToMapped: Map<string, string>;\n}\n\ninterface FkRelation {\n readonly declaringModel: string;\n readonly fieldName: string;\n readonly targetModel: string;\n readonly relationName?: string;\n readonly localFields: readonly string[];\n readonly targetFields: readonly string[];\n}\n\nfunction fkRelationPairKey(declaringModel: string, targetModel: string): string {\n return `${declaringModel}::${targetModel}`;\n}\n\nfunction resolveFieldMappings(model: PslModel): FieldMappings {\n const pslNameToMapped = new Map<string, string>();\n for (const field of model.fields) {\n const mapped = getMapName(field.attributes) ?? field.name;\n pslNameToMapped.set(field.name, mapped);\n }\n return { pslNameToMapped };\n}\n\nfunction resolveCollectionName(model: PslModel): string {\n return getMapName(model.attributes) ?? lowerFirst(model.name);\n}\n\ninterface MongoModelEntry {\n readonly fields: Record<string, ContractField>;\n readonly relations: Record<string, ContractReferenceRelation>;\n readonly storage: { readonly collection: string };\n readonly discriminator?: { readonly field: string };\n readonly variants?: Record<string, { readonly value: string }>;\n readonly base?: string;\n}\n\ntype DiscriminatorDeclaration = { readonly fieldName: string; readonly span: PslModel['span'] };\ntype BaseDeclaration = {\n readonly baseName: string;\n readonly value: string;\n readonly collectionName: string;\n readonly span: PslModel['span'];\n};\n\nfunction collectPolymorphismDeclarations(\n document: ParsePslDocumentResult,\n sourceId: string,\n diagnostics: ContractSourceDiagnostic[],\n): {\n discriminatorDeclarations: Map<string, DiscriminatorDeclaration>;\n baseDeclarations: Map<string, BaseDeclaration>;\n} {\n const discriminatorDeclarations = new Map<string, DiscriminatorDeclaration>();\n const baseDeclarations = new Map<string, BaseDeclaration>();\n const allPslModels = document.ast.namespaces.flatMap((ns) => ns.models);\n\n for (const pslModel of allPslModels) {\n for (const attr of pslModel.attributes) {\n if (attr.name === 'discriminator') {\n const fieldName = getPositionalArgument(attr);\n if (!fieldName) {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Model \"${pslModel.name}\" @@discriminator requires a field name argument`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n const discField = pslModel.fields.find((f) => f.name === fieldName);\n if (discField && discField.typeName !== 'String') {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Discriminator field \"${fieldName}\" on model \"${pslModel.name}\" must be of type String, but is \"${discField.typeName}\"`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n discriminatorDeclarations.set(pslModel.name, { fieldName, span: attr.span });\n }\n if (attr.name === 'base') {\n const baseName = getPositionalArgument(attr, 0);\n const rawValue = getPositionalArgument(attr, 1);\n if (!baseName || !rawValue) {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Model \"${pslModel.name}\" @@base requires two arguments: base model name and discriminator value`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n const value = parseQuotedStringLiteral(rawValue);\n if (value === undefined) {\n diagnostics.push({\n code: 'PSL_INVALID_ATTRIBUTE_ARGUMENT',\n message: `Model \"${pslModel.name}\" @@base discriminator value must be a quoted string literal`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n const collectionName = resolveCollectionName(pslModel);\n baseDeclarations.set(pslModel.name, { baseName, value, collectionName, span: attr.span });\n }\n }\n }\n\n return { discriminatorDeclarations, baseDeclarations };\n}\n\nfunction resolvePolymorphism(input: {\n models: Record<string, MongoModelEntry>;\n roots: Record<string, string>;\n collections: Record<string, Record<string, unknown>>;\n document: ParsePslDocumentResult;\n discriminatorDeclarations: Map<string, DiscriminatorDeclaration>;\n baseDeclarations: Map<string, BaseDeclaration>;\n modelNames: ReadonlySet<string>;\n indexSpans: Map<MongoIndex, PslSpan>;\n modelIndexesByName: Map<string, readonly MongoIndex[]>;\n sourceId: string;\n}): {\n models: Record<string, MongoModelEntry>;\n roots: Record<string, string>;\n collections: Record<string, Record<string, unknown>>;\n diagnostics: ContractSourceDiagnostic[];\n} {\n const {\n discriminatorDeclarations,\n baseDeclarations,\n modelNames,\n sourceId,\n document,\n indexSpans,\n modelIndexesByName,\n } = input;\n const allPslModels = document.ast.namespaces.flatMap((ns) => ns.models);\n let patched = input.models;\n let roots = input.roots;\n let collections = input.collections;\n const diagnostics: ContractSourceDiagnostic[] = [];\n\n for (const [modelName, decl] of discriminatorDeclarations) {\n if (baseDeclarations.has(modelName)) {\n diagnostics.push({\n code: 'PSL_DISCRIMINATOR_AND_BASE',\n message: `Model \"${modelName}\" cannot have both @@discriminator and @@base`,\n sourceId,\n span: decl.span,\n });\n continue;\n }\n\n const model = patched[modelName];\n if (!model) continue;\n\n const pslModel = allPslModels.find((m) => m.name === modelName);\n const mappedDiscriminatorField = pslModel\n ? (resolveFieldMappings(pslModel).pslNameToMapped.get(decl.fieldName) ?? decl.fieldName)\n : decl.fieldName;\n\n if (!Object.hasOwn(model.fields, mappedDiscriminatorField)) {\n diagnostics.push({\n code: 'PSL_DISCRIMINATOR_FIELD_NOT_FOUND',\n message: `Discriminator field \"${decl.fieldName}\" is not a field on model \"${modelName}\"`,\n sourceId,\n span: decl.span,\n });\n continue;\n }\n\n const variants: Record<string, { readonly value: string }> = {};\n for (const [variantName, baseDecl] of baseDeclarations) {\n if (baseDecl.baseName !== modelName) continue;\n variants[variantName] = { value: baseDecl.value };\n }\n\n if (Object.keys(variants).length === 0) {\n diagnostics.push({\n code: 'PSL_ORPHANED_DISCRIMINATOR',\n message: `Model \"${modelName}\" has @@discriminator but no variant models declare @@base(${modelName}, ...)`,\n sourceId,\n span: decl.span,\n });\n continue;\n }\n\n patched = {\n ...patched,\n [modelName]: { ...model, discriminator: { field: mappedDiscriminatorField }, variants },\n };\n }\n\n for (const [variantName, baseDecl] of baseDeclarations) {\n if (!modelNames.has(baseDecl.baseName)) {\n diagnostics.push({\n code: 'PSL_BASE_TARGET_NOT_FOUND',\n message: `Model \"${variantName}\" @@base references non-existent model \"${baseDecl.baseName}\"`,\n sourceId,\n span: baseDecl.span,\n });\n continue;\n }\n\n if (!discriminatorDeclarations.has(baseDecl.baseName)) {\n diagnostics.push({\n code: 'PSL_ORPHANED_BASE',\n message: `Model \"${variantName}\" declares @@base(${baseDecl.baseName}, ...) but \"${baseDecl.baseName}\" has no @@discriminator`,\n sourceId,\n span: baseDecl.span,\n });\n continue;\n }\n\n if (discriminatorDeclarations.has(variantName)) {\n continue;\n }\n\n const baseModel = patched[baseDecl.baseName];\n const variantPslModel = allPslModels.find((m) => m.name === variantName);\n if (!variantPslModel) continue;\n const hasExplicitMap = getMapName(variantPslModel.attributes) !== undefined;\n\n if (hasExplicitMap && baseModel && baseDecl.collectionName !== baseModel.storage.collection) {\n diagnostics.push({\n code: 'PSL_MONGO_VARIANT_SEPARATE_COLLECTION',\n message: `Mongo variant \"${variantName}\" cannot use a different collection than its base \"${baseDecl.baseName}\". Mongo only supports single-collection polymorphism.`,\n sourceId,\n span: baseDecl.span,\n });\n continue;\n }\n\n const baseCollection = baseModel?.storage.collection ?? baseDecl.collectionName;\n const variantModel = patched[variantName];\n if (variantModel) {\n patched = {\n ...patched,\n [variantName]: {\n ...variantModel,\n base: baseDecl.baseName,\n storage: { collection: baseCollection },\n },\n };\n }\n\n const variantCollectionName = resolveCollectionName(variantPslModel);\n if (roots[variantCollectionName] === variantName) {\n if (variantCollectionName === baseCollection && baseModel) {\n roots = { ...roots, [variantCollectionName]: baseDecl.baseName };\n } else {\n roots = Object.fromEntries(\n Object.entries(roots).filter(([key]) => key !== variantCollectionName),\n );\n }\n }\n\n const variantOwnIndexes = modelIndexesByName.get(variantName) ?? [];\n const baseColl = collections[baseCollection];\n\n const baseModelEntry = patched[baseDecl.baseName];\n const discriminatorField = baseModelEntry?.discriminator?.field;\n const scopedVariantIndexes: MongoIndex[] = [];\n if (discriminatorField) {\n for (const idx of variantOwnIndexes) {\n const result = applyPolymorphicScopeToMongoIndex(idx, {\n discriminatorField,\n discriminatorValue: baseDecl.value,\n });\n if (result.kind === 'conflict') {\n const span = indexSpans.get(idx) ?? baseDecl.span;\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: `Variant \"${variantName}\" index conflicts with discriminator scope: ${result.reason}`,\n sourceId,\n span,\n });\n continue;\n }\n if (result.index !== idx) {\n indexSpans.set(result.index, indexSpans.get(idx) ?? baseDecl.span);\n }\n scopedVariantIndexes.push(result.index);\n }\n } else {\n scopedVariantIndexes.push(...variantOwnIndexes);\n }\n\n if (variantCollectionName !== baseCollection) {\n const filtered = Object.fromEntries(\n Object.entries(collections).filter(([key]) => key !== variantCollectionName),\n );\n if (scopedVariantIndexes.length > 0 && baseColl) {\n const baseIndexes = (baseColl['indexes'] ?? []) as MongoIndex[];\n collections = {\n ...filtered,\n [baseCollection]: {\n ...baseColl,\n indexes: [...baseIndexes, ...scopedVariantIndexes],\n },\n };\n } else {\n collections = filtered;\n }\n } else if (baseColl) {\n const existingIndexes = (baseColl['indexes'] ?? []) as MongoIndex[];\n const variantIndexSet = new Set<MongoIndex>(variantOwnIndexes);\n const withoutUnscopedVariants = existingIndexes.filter((idx) => !variantIndexSet.has(idx));\n const mergedIndexes = [...withoutUnscopedVariants];\n for (const idx of scopedVariantIndexes) {\n const idxKey = canonicalJson(idx);\n const isDuplicate = withoutUnscopedVariants.some(\n (existing) => canonicalJson(existing) === idxKey,\n );\n if (!isDuplicate) {\n mergedIndexes.push(idx);\n }\n }\n if (\n mergedIndexes.length !== existingIndexes.length ||\n mergedIndexes.some((idx, i) => idx !== existingIndexes[i])\n ) {\n const next: Record<string, unknown> = { ...baseColl };\n if (mergedIndexes.length > 0) {\n next['indexes'] = mergedIndexes;\n } else {\n delete next['indexes'];\n }\n collections = { ...collections, [baseCollection]: next };\n }\n }\n }\n\n return { models: patched, roots, collections, diagnostics };\n}\n\n// Property-order-stable serialization for structural equality of plain\n// JSON-compatible values. Used for comparing MongoIndex shapes in\n// the variant-merge dedup path where a future change to the spread order\n// would otherwise produce JSON-stringify mismatches even though the\n// indexes are structurally identical.\nfunction canonicalJson(value: unknown): string {\n if (Array.isArray(value)) {\n return `[${value.map(canonicalJson).join(',')}]`;\n }\n if (value && typeof value === 'object') {\n return `{${Object.entries(value as Record<string, unknown>)\n .sort(([left], [right]) => left.localeCompare(right))\n .map(([key, entry]) => `${JSON.stringify(key)}:${canonicalJson(entry)}`)\n .join(',')}}`;\n }\n return JSON.stringify(value);\n}\n\nfunction parseIndexDirection(raw: string | undefined): MongoIndexKeyDirection {\n if (!raw) return 1;\n const stripped = raw.replace(/^[\"']/, '').replace(/[\"']$/, '');\n const num = Number(stripped);\n if (num === 1 || num === -1) return num;\n if (['text', '2dsphere', '2d', 'hashed'].includes(stripped))\n return stripped as MongoIndexKeyDirection;\n return 1;\n}\n\nfunction parseNumericArg(raw: string | undefined): number | undefined {\n if (!raw) return undefined;\n const n = Number(raw);\n return Number.isFinite(n) ? n : undefined;\n}\n\nfunction parseBooleanArg(raw: string | undefined): boolean | undefined {\n if (raw === 'true') return true;\n if (raw === 'false') return false;\n return undefined;\n}\n\nfunction parseJsonArg(raw: string | undefined): Record<string, unknown> | undefined {\n if (!raw) return undefined;\n const stripped = raw.replace(/^[\"']/, '').replace(/[\"']$/, '').replace(/\\\\\"/g, '\"');\n try {\n const parsed = JSON.parse(stripped);\n if (typeof parsed === 'object' && parsed !== null && !Array.isArray(parsed)) {\n return parsed as Record<string, unknown>;\n }\n } catch {\n // not valid JSON\n }\n return undefined;\n}\n\nfunction parseCollation(\n attr: import('@prisma-next/psl-parser').PslAttribute,\n): Record<string, unknown> | null | undefined {\n const locale = stripQuotesHelper(getNamedArgument(attr, 'collationLocale'));\n if (!locale) {\n const hasAnyCollationArg =\n getNamedArgument(attr, 'collationStrength') != null ||\n getNamedArgument(attr, 'collationCaseLevel') != null ||\n getNamedArgument(attr, 'collationCaseFirst') != null ||\n getNamedArgument(attr, 'collationNumericOrdering') != null ||\n getNamedArgument(attr, 'collationAlternate') != null ||\n getNamedArgument(attr, 'collationMaxVariable') != null ||\n getNamedArgument(attr, 'collationBackwards') != null ||\n getNamedArgument(attr, 'collationNormalization') != null;\n return hasAnyCollationArg ? null : undefined;\n }\n\n const collation: Record<string, unknown> = { locale };\n const strength = parseNumericArg(getNamedArgument(attr, 'collationStrength'));\n if (strength != null) collation['strength'] = strength;\n const caseLevel = parseBooleanArg(getNamedArgument(attr, 'collationCaseLevel'));\n if (caseLevel != null) collation['caseLevel'] = caseLevel;\n const caseFirst = stripQuotesHelper(getNamedArgument(attr, 'collationCaseFirst'));\n if (caseFirst != null) collation['caseFirst'] = caseFirst;\n const numericOrdering = parseBooleanArg(getNamedArgument(attr, 'collationNumericOrdering'));\n if (numericOrdering != null) collation['numericOrdering'] = numericOrdering;\n const alternate = stripQuotesHelper(getNamedArgument(attr, 'collationAlternate'));\n if (alternate != null) collation['alternate'] = alternate;\n const maxVariable = stripQuotesHelper(getNamedArgument(attr, 'collationMaxVariable'));\n if (maxVariable != null) collation['maxVariable'] = maxVariable;\n const backwards = parseBooleanArg(getNamedArgument(attr, 'collationBackwards'));\n if (backwards != null) collation['backwards'] = backwards;\n const normalization = parseBooleanArg(getNamedArgument(attr, 'collationNormalization'));\n if (normalization != null) collation['normalization'] = normalization;\n return collation;\n}\n\nfunction stripQuotesHelper(raw: string | undefined): string | undefined {\n if (!raw) return undefined;\n return raw.replace(/^[\"']/, '').replace(/[\"']$/, '');\n}\n\nfunction parseProjectionList(\n raw: string | undefined,\n value: 0 | 1,\n): Record<string, 0 | 1> | undefined {\n if (!raw) return undefined;\n const stripped = raw.replace(/^[\"']/, '').replace(/[\"']$/, '');\n const inner = stripped.replace(/^\\[/, '').replace(/\\]$/, '').trim();\n if (inner.length === 0) return undefined;\n const fields = inner\n .split(',')\n .map((s) => s.trim())\n .filter((s) => s.length > 0);\n const result: Record<string, 0 | 1> = {};\n for (const f of fields) {\n result[f] = value;\n }\n return result;\n}\n\nfunction collectIndexes(\n pslModel: PslModel,\n fieldMappings: FieldMappings,\n modelNames: ReadonlySet<string>,\n sourceId: string,\n diagnostics: ContractSourceDiagnostic[],\n indexSpans: Map<MongoIndex, PslSpan>,\n): MongoIndex[] {\n const indexes: MongoIndex[] = [];\n let textIndexCount = 0;\n\n // Storage-indexable PSL field names — i.e. all declared fields except\n // relation fields (which don't materialize a column on this model). The\n // index field-existence check (PSL_INDEX_FIELD_NOT_FOUND) consults this\n // rather than fieldMappings.pslNameToMapped because the latter contains\n // every PSL field including relation fields.\n const indexableFieldNames = new Set<string>();\n for (const f of pslModel.fields) {\n if (modelNames.has(f.typeName)) continue;\n indexableFieldNames.add(f.name);\n }\n\n for (const field of pslModel.fields) {\n if (modelNames.has(field.typeName)) continue;\n const uniqueAttr = getAttribute(field.attributes, 'unique');\n if (!uniqueAttr) continue;\n const mappedName = fieldMappings.pslNameToMapped.get(field.name) ?? field.name;\n const fieldUniqueIndex = new MongoIndex({\n keys: [{ field: mappedName, direction: 1 }],\n unique: true,\n });\n indexes.push(fieldUniqueIndex);\n indexSpans.set(fieldUniqueIndex, uniqueAttr.span);\n }\n\n for (const attr of pslModel.attributes) {\n const isIndex = attr.name === 'index';\n const isUnique = attr.name === 'unique';\n const isTextIndex = attr.name === 'textIndex';\n if (!isIndex && !isUnique && !isTextIndex) continue;\n\n const fieldsArg = getPositionalArgument(attr, 0);\n if (!fieldsArg) continue;\n const parsedFields = parseIndexFieldList(fieldsArg);\n if (parsedFields.length === 0) continue;\n\n const hasWildcard = parsedFields.some((f) => f.isWildcard);\n const wildcardCount = parsedFields.filter((f) => f.isWildcard).length;\n\n if (wildcardCount > 1) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'An index can contain at most one wildcard() field',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (isUnique && hasWildcard) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'Unique indexes cannot use wildcard() fields',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (isTextIndex) {\n textIndexCount++;\n if (textIndexCount > 1) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: `Only one @@textIndex is allowed per collection (model \"${pslModel.name}\")`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (hasWildcard) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message:\n 'wildcard() fields cannot be combined with type: hashed/2dsphere/2d or @@textIndex',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n }\n\n const typeArg = getNamedArgument(attr, 'type');\n const defaultDirection: MongoIndexKeyDirection = isTextIndex\n ? 'text'\n : parseIndexDirection(typeArg);\n\n if (\n hasWildcard &&\n typeof defaultDirection === 'string' &&\n ['hashed', '2dsphere', '2d'].includes(defaultDirection)\n ) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: `wildcard() fields cannot be combined with type: ${defaultDirection}`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if (defaultDirection === 'hashed' && parsedFields.length > 1) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'Hashed indexes must have exactly one field',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n let missingField: string | undefined;\n for (const pf of parsedFields) {\n let fieldNameForLookup: string | undefined;\n if (pf.isWildcard) {\n const wildcardMatch = pf.name.match(/^(.+)\\.\\$\\*\\*$/);\n fieldNameForLookup = wildcardMatch ? wildcardMatch[1] : undefined;\n } else {\n fieldNameForLookup = pf.name;\n }\n if (fieldNameForLookup === undefined || fieldNameForLookup.length === 0) continue;\n if (!indexableFieldNames.has(fieldNameForLookup)) {\n missingField = fieldNameForLookup;\n break;\n }\n }\n if (missingField !== undefined) {\n diagnostics.push({\n code: 'PSL_INDEX_FIELD_NOT_FOUND',\n message: `Index on model \"${pslModel.name}\" references unknown field \"${missingField}\"`,\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const keys = parsedFields.map((pf) => {\n const mappedName = pf.isWildcard\n ? pf.name.replace(/^(.+)\\.\\$\\*\\*$/, (_, prefix: string) => {\n const mapped = fieldMappings.pslNameToMapped.get(prefix);\n return mapped ? `${mapped}.$**` : `${prefix}.$**`;\n })\n : (fieldMappings.pslNameToMapped.get(pf.name) ?? pf.name);\n const direction: MongoIndexKeyDirection =\n pf.direction != null ? (pf.direction as MongoIndexKeyDirection) : defaultDirection;\n return { field: mappedName, direction };\n });\n\n const unique = isUnique ? true : undefined;\n const sparse = isTextIndex ? undefined : parseBooleanArg(getNamedArgument(attr, 'sparse'));\n const expireAfterSeconds = isTextIndex\n ? undefined\n : parseNumericArg(getNamedArgument(attr, 'expireAfterSeconds'));\n\n if (hasWildcard && expireAfterSeconds != null) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'expireAfterSeconds cannot be combined with wildcard() fields',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const partialFilterExpression = parseJsonArg(getNamedArgument(attr, 'filter'));\n\n const includeArg = getNamedArgument(attr, 'include');\n const excludeArg = getNamedArgument(attr, 'exclude');\n\n if (includeArg != null && excludeArg != null) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'Cannot specify both include and exclude on the same index',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n if ((includeArg != null || excludeArg != null) && !hasWildcard) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message:\n 'include/exclude options are only valid when the index contains a wildcard() field',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const wildcardProjection =\n includeArg != null\n ? parseProjectionList(includeArg, 1)\n : excludeArg != null\n ? parseProjectionList(excludeArg, 0)\n : undefined;\n\n const collation = parseCollation(attr);\n if (collation === null) {\n diagnostics.push({\n code: 'PSL_INVALID_INDEX',\n message: 'collationLocale is required when using collation options',\n sourceId,\n span: attr.span,\n });\n continue;\n }\n\n const rawWeights = parseJsonArg(getNamedArgument(attr, 'weights'));\n let weights: Record<string, number> | undefined;\n if (rawWeights) {\n weights = {};\n for (const [k, v] of Object.entries(rawWeights)) {\n if (typeof v === 'number') weights[k] = v;\n }\n }\n\n const rawDefaultLang = isTextIndex\n ? getNamedArgument(attr, 'language')\n : getNamedArgument(attr, 'default_language');\n const default_language = stripQuotesHelper(rawDefaultLang);\n\n const rawLangOverride = getNamedArgument(attr, 'languageOverride');\n const language_override = stripQuotesHelper(rawLangOverride);\n\n const index = new MongoIndex({\n keys,\n ...(unique != null && { unique }),\n ...(sparse != null && { sparse }),\n ...(expireAfterSeconds != null && { expireAfterSeconds }),\n ...(partialFilterExpression != null && { partialFilterExpression }),\n ...(wildcardProjection != null && { wildcardProjection }),\n ...(collation != null && { collation }),\n ...(weights != null && { weights }),\n ...(default_language != null && { default_language }),\n ...(language_override != null && { language_override }),\n });\n\n indexes.push(index);\n indexSpans.set(index, attr.span);\n }\n\n return indexes;\n}\n\nfunction isRelationField(field: PslField, modelNames: ReadonlySet<string>): boolean {\n return modelNames.has(field.typeName);\n}\n\nfunction resolveFieldCodecId(\n field: PslField,\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n): string | undefined {\n return scalarTypeDescriptors.get(field.typeName);\n}\n\nfunction resolveNonRelationField(\n field: PslField,\n ownerName: string,\n compositeTypeNames: ReadonlySet<string>,\n scalarTypeDescriptors: ReadonlyMap<string, string>,\n sourceId: string,\n diagnostics: ContractSourceDiagnostic[],\n): ContractField | undefined {\n if (compositeTypeNames.has(field.typeName)) {\n const result: ContractField = {\n type: { kind: 'valueObject', name: field.typeName },\n nullable: field.optional,\n };\n return field.list ? { ...result, many: true } : result;\n }\n\n const codecId = resolveFieldCodecId(field, scalarTypeDescriptors);\n if (!codecId) {\n diagnostics.push({\n code: 'PSL_UNSUPPORTED_FIELD_TYPE',\n message: `Field \"${ownerName}.${field.name}\" type \"${field.typeName}\" is not supported in Mongo PSL interpreter`,\n sourceId,\n span: field.span,\n });\n return undefined;\n }\n\n const result: ContractField = {\n type: { kind: 'scalar', codecId },\n nullable: field.optional,\n };\n return field.list ? { ...result, many: true } : result;\n}\n\nexport function interpretPslDocumentToMongoContract(\n input: InterpretPslDocumentToMongoContractInput,\n): Result<Contract, ContractSourceDiagnostics> {\n const { document, scalarTypeDescriptors, codecLookup } = input;\n const sourceId = document.ast.sourceId;\n const diagnostics: ContractSourceDiagnostic[] = [];\n validateNamespaceBlocksForMongoTarget({\n namespaces: document.ast.namespaces,\n sourceId,\n diagnostics,\n });\n // Mongo lowers only the implicit `__unspecified__` bucket today —\n // explicit `namespace { … }` blocks were rejected above. The IR\n // collection map remains flat (and the Mongo target represents\n // databases via `MongoTargetDatabase`, populated at compose time by\n // the connection string rather than authoring-time PSL).\n const allModels = document.ast.namespaces.flatMap((ns) => ns.models);\n const allCompositeTypes = document.ast.namespaces.flatMap((ns) => ns.compositeTypes);\n const modelNames = new Set(allModels.map((m) => m.name));\n const compositeTypeNames = new Set(allCompositeTypes.map((ct) => ct.name));\n\n const models: Record<string, MongoModelEntry> = {};\n const collections: Record<string, Record<string, unknown>> = {};\n const roots: Record<string, string> = {};\n const allFkRelations: FkRelation[] = [];\n const indexSpans = new Map<MongoIndex, PslSpan>();\n const modelIndexesByName = new Map<string, readonly MongoIndex[]>();\n\n interface BackrelationCandidate {\n readonly modelName: string;\n readonly fieldName: string;\n readonly targetModelName: string;\n readonly relationName?: string;\n readonly cardinality: '1:1' | '1:N';\n readonly field: PslField;\n }\n const backrelationCandidates: BackrelationCandidate[] = [];\n\n for (const pslModel of allModels) {\n const collectionName = resolveCollectionName(pslModel);\n const fieldMappings = resolveFieldMappings(pslModel);\n\n const fields: Record<string, ContractField> = {};\n const relations: Record<string, ContractReferenceRelation> = {};\n\n for (const field of pslModel.fields) {\n if (isRelationField(field, modelNames)) {\n const relation = parseRelationAttribute(field.attributes);\n\n if (field.list || !(relation?.fields && relation?.references)) {\n backrelationCandidates.push({\n modelName: pslModel.name,\n fieldName: field.name,\n targetModelName: field.typeName,\n ...(relation?.relationName !== undefined\n ? { relationName: relation.relationName }\n : {}),\n cardinality: field.list ? '1:N' : '1:1',\n field,\n });\n continue;\n }\n\n if (relation?.fields && relation?.references) {\n const localMapped = relation.fields.map((f) => fieldMappings.pslNameToMapped.get(f) ?? f);\n\n const targetModel = allModels.find((m) => m.name === field.typeName);\n const targetFieldMappings = targetModel ? resolveFieldMappings(targetModel) : undefined;\n const targetMapped = relation.references.map(\n (f) => targetFieldMappings?.pslNameToMapped.get(f) ?? f,\n );\n\n relations[field.name] = {\n to: field.typeName,\n cardinality: 'N:1' as const,\n on: {\n localFields: localMapped,\n targetFields: targetMapped,\n },\n };\n\n allFkRelations.push({\n declaringModel: pslModel.name,\n fieldName: field.name,\n targetModel: field.typeName,\n ...(relation.relationName !== undefined ? { relationName: relation.relationName } : {}),\n localFields: localMapped,\n targetFields: targetMapped,\n });\n }\n continue;\n }\n\n const resolved = resolveNonRelationField(\n field,\n pslModel.name,\n compositeTypeNames,\n scalarTypeDescriptors,\n sourceId,\n diagnostics,\n );\n if (!resolved) continue;\n\n const mappedName = fieldMappings.pslNameToMapped.get(field.name) ?? field.name;\n fields[mappedName] = resolved;\n }\n\n const isVariantModel = pslModel.attributes.some((attr) => attr.name === 'base');\n const hasIdField = pslModel.fields.some((f) => getAttribute(f.attributes, 'id') !== undefined);\n if (!hasIdField && !isVariantModel) {\n diagnostics.push({\n code: 'PSL_MISSING_ID_FIELD',\n message: `Model \"${pslModel.name}\" has no field with @id attribute. Every model must have exactly one @id field.`,\n sourceId,\n });\n }\n\n models[pslModel.name] = { fields, relations, storage: { collection: collectionName } };\n const modelIndexes = collectIndexes(\n pslModel,\n fieldMappings,\n modelNames,\n sourceId,\n diagnostics,\n indexSpans,\n );\n modelIndexesByName.set(pslModel.name, modelIndexes);\n const existingColl = collections[collectionName];\n if (existingColl && modelIndexes.length > 0) {\n const existingIndexes = (existingColl['indexes'] ?? []) as MongoIndex[];\n collections[collectionName] = { indexes: [...existingIndexes, ...modelIndexes] };\n } else if (!existingColl) {\n collections[collectionName] = modelIndexes.length > 0 ? { indexes: modelIndexes } : {};\n }\n roots[collectionName] = pslModel.name;\n }\n\n const valueObjects: Record<string, ContractValueObject> = {};\n for (const compositeType of allCompositeTypes) {\n const fields: Record<string, ContractField> = {};\n for (const field of compositeType.fields) {\n const resolved = resolveNonRelationField(\n field,\n compositeType.name,\n compositeTypeNames,\n scalarTypeDescriptors,\n sourceId,\n diagnostics,\n );\n if (!resolved) continue;\n fields[field.name] = resolved;\n }\n valueObjects[compositeType.name] = { fields };\n }\n\n const fkRelationsByPair = new Map<string, FkRelation[]>();\n for (const fk of allFkRelations) {\n const key = fkRelationPairKey(fk.declaringModel, fk.targetModel);\n const existing = fkRelationsByPair.get(key);\n if (existing) {\n existing.push(fk);\n } else {\n fkRelationsByPair.set(key, [fk]);\n }\n }\n\n for (const candidate of backrelationCandidates) {\n const pairKey = fkRelationPairKey(candidate.targetModelName, candidate.modelName);\n const pairMatches = fkRelationsByPair.get(pairKey) ?? [];\n const matches = candidate.relationName\n ? pairMatches.filter((r) => r.relationName === candidate.relationName)\n : [...pairMatches];\n\n if (matches.length === 0) {\n diagnostics.push({\n code: 'PSL_ORPHANED_BACKRELATION',\n message: `Backrelation list field \"${candidate.modelName}.${candidate.fieldName}\" has no matching FK-side relation on model \"${candidate.targetModelName}\". Add @relation(fields: [...], references: [...]) on the FK-side relation or use an explicit join model for many-to-many.`,\n sourceId,\n span: candidate.field.span,\n });\n continue;\n }\n if (matches.length > 1) {\n diagnostics.push({\n code: 'PSL_AMBIGUOUS_BACKRELATION',\n message: `Backrelation list field \"${candidate.modelName}.${candidate.fieldName}\" matches multiple FK-side relations on model \"${candidate.targetModelName}\". Add @relation(\"...\") to both sides to disambiguate.`,\n sourceId,\n span: candidate.field.span,\n });\n continue;\n }\n\n const fk = matches[0];\n if (!fk) continue;\n const modelEntry = models[candidate.modelName];\n if (!modelEntry) continue;\n modelEntry.relations[candidate.fieldName] = {\n to: candidate.targetModelName,\n cardinality: candidate.cardinality,\n on: {\n localFields: fk.targetFields,\n targetFields: fk.localFields,\n },\n };\n }\n\n const { discriminatorDeclarations, baseDeclarations } = collectPolymorphismDeclarations(\n document,\n sourceId,\n diagnostics,\n );\n const polyResult = resolvePolymorphism({\n models,\n roots,\n collections,\n document,\n discriminatorDeclarations,\n baseDeclarations,\n modelNames,\n indexSpans,\n modelIndexesByName,\n sourceId,\n });\n\n if (diagnostics.length > 0 || polyResult.diagnostics.length > 0) {\n return notOk({\n summary: 'PSL to Mongo contract interpretation failed',\n diagnostics: [...diagnostics, ...polyResult.diagnostics],\n });\n }\n\n const resolvedModels = polyResult.models;\n const resolvedCollections = polyResult.collections;\n\n for (const [, modelEntry] of Object.entries(resolvedModels)) {\n if (modelEntry.base) continue;\n\n const collectionName = modelEntry.storage.collection;\n const coll = resolvedCollections[collectionName];\n if (!coll) continue;\n\n if (modelEntry.discriminator && modelEntry.variants) {\n const variantEntries = Object.entries(modelEntry.variants).map(\n ([variantName, { value }]) => ({\n discriminatorValue: value,\n fields: resolvedModels[variantName]?.fields ?? {},\n }),\n );\n coll['validator'] = derivePolymorphicJsonSchema(\n modelEntry.fields,\n modelEntry.discriminator.field,\n variantEntries,\n valueObjects,\n codecLookup,\n );\n } else {\n coll['validator'] = deriveJsonSchema(modelEntry.fields, valueObjects, codecLookup);\n }\n }\n\n const target = 'mongo';\n const targetFamily = 'mongo';\n const collectionsAsClasses: Record<string, MongoCollection> = {};\n for (const [name, coll] of Object.entries(resolvedCollections)) {\n const input: {\n indexes?: ReadonlyArray<MongoIndex>;\n validator?: unknown;\n options?: unknown;\n } = {};\n if (coll['indexes'] !== undefined) {\n input.indexes = coll['indexes'] as ReadonlyArray<MongoIndex>;\n }\n if (coll['validator'] !== undefined) {\n input.validator = coll['validator'];\n }\n if (coll['options'] !== undefined) {\n input.options = coll['options'];\n }\n // input.validator/options are arktype-validated JSON shapes; MongoCollection\n // constructor normalises them into MongoValidator / MongoCollectionOptions\n // instances. The narrow cast is bounded to the field-typed input record.\n collectionsAsClasses[name] = new MongoCollection(\n input as ConstructorParameters<typeof MongoCollection>[0],\n );\n }\n const storageWithoutHash = {\n namespaces: {\n [UNBOUND_NAMESPACE_ID]: {\n id: UNBOUND_NAMESPACE_ID,\n collections: collectionsAsClasses,\n },\n },\n };\n const storageHash = computeStorageHash({ target, targetFamily, storage: storageWithoutHash });\n const storage = new MongoStorage({\n storageHash,\n ...storageWithoutHash,\n }) as Contract['storage'];\n const capabilities: Record<string, Record<string, boolean>> = {};\n\n return ok({\n targetFamily,\n target,\n roots: polyResult.roots,\n models: polyResult.models,\n ...(Object.keys(valueObjects).length > 0 ? { valueObjects } : {}),\n storage,\n extensionPacks: {},\n capabilities,\n profileHash: computeProfileHash({ target, targetFamily, capabilities }),\n meta: {},\n });\n}\n"],"mappings":"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"}