@prisma-next/mongo-contract-psl 0.13.0 → 0.14.0-dev.10

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,MAAM;AAAA;AAAA,iBAGD,aAAA,CAAc,UAAA,UAAoB,OAAA,GAAU,oBAAA,GAAuB,cAAc"}
1
+ {"version":3,"file":"provider.d.mts","names":[],"sources":["../../src/provider.ts"],"mappings":";;;UAUiB,oBAAA;EAAA,SACN,MAAM;AAAA;AAAA,iBAgBD,aAAA,CAAc,UAAA,UAAoB,OAAA,GAAU,oBAAA,GAAuB,cAAc"}
@@ -1,12 +1,22 @@
1
- import { t as interpretPslDocumentToMongoContract } from "../interpreter-CNVgUGau.mjs";
1
+ import { t as interpretPslDocumentToMongoContract } from "../interpreter-DCiVHDlW.mjs";
2
+ import { buildSymbolTable, rangeToPslSpan } from "@prisma-next/psl-parser";
2
3
  import { notOk, ok } from "@prisma-next/utils/result";
3
- import { parsePslDocument } from "@prisma-next/psl-parser";
4
- import { readFile } from "node:fs/promises";
5
4
  import { ifDefined } from "@prisma-next/utils/defined";
5
+ import { readFile } from "node:fs/promises";
6
+ import { parse } from "@prisma-next/psl-parser/syntax";
6
7
  //#region src/provider.ts
8
+ function mapParseDiagnostics(diagnostics, sourceFile, sourceId) {
9
+ return diagnostics.map((diagnostic) => ({
10
+ code: diagnostic.code,
11
+ message: diagnostic.message,
12
+ sourceId,
13
+ span: rangeToPslSpan(diagnostic.range, sourceFile)
14
+ }));
15
+ }
7
16
  function mongoContract(schemaPath, options) {
8
17
  return {
9
18
  source: {
19
+ sourceFormat: "psl",
10
20
  inputs: [schemaPath],
11
21
  load: async (context) => {
12
22
  const [absoluteSchemaPath] = context.resolvedInputs;
@@ -30,11 +40,18 @@ function mongoContract(schemaPath, options) {
30
40
  }
31
41
  });
32
42
  }
43
+ const { document, sourceFile, diagnostics: parseDiagnostics } = parse(schema);
44
+ const { table: symbolTable, diagnostics: symbolTableDiagnostics } = buildSymbolTable({
45
+ document,
46
+ sourceFile,
47
+ scalarTypes: [...context.scalarTypeDescriptors.keys()],
48
+ pslBlockDescriptors: context.authoringContributions.pslBlockDescriptors
49
+ });
33
50
  const interpreted = interpretPslDocumentToMongoContract({
34
- document: parsePslDocument({
35
- schema,
36
- sourceId: schemaPath
37
- }),
51
+ symbolTable,
52
+ sourceFile,
53
+ sourceId: schemaPath,
54
+ seedDiagnostics: [...mapParseDiagnostics(parseDiagnostics, sourceFile, schemaPath), ...mapParseDiagnostics(symbolTableDiagnostics, sourceFile, schemaPath)],
38
55
  scalarTypeDescriptors: context.scalarTypeDescriptors,
39
56
  codecLookup: context.codecLookup
40
57
  });
@@ -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,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"}
1
+ {"version":3,"file":"provider.mjs","names":[],"sources":["../../src/provider.ts"],"sourcesContent":["import { readFile } from 'node:fs/promises';\nimport type { ContractConfig, ContractSourceDiagnostic } from '@prisma-next/config/config-types';\nimport { buildSymbolTable, rangeToPslSpan } from '@prisma-next/psl-parser';\nimport type { ParseDiagnostic, SourceFile } from '@prisma-next/psl-parser/syntax';\nimport { parse } from '@prisma-next/psl-parser/syntax';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { notOk, ok } from '@prisma-next/utils/result';\n\nimport { interpretPslDocumentToMongoContract } from './interpreter';\n\nexport interface MongoContractOptions {\n readonly output?: string;\n}\n\nfunction mapParseDiagnostics(\n diagnostics: readonly ParseDiagnostic[],\n sourceFile: SourceFile,\n sourceId: string,\n): ContractSourceDiagnostic[] {\n return diagnostics.map((diagnostic) => ({\n code: diagnostic.code,\n message: diagnostic.message,\n sourceId,\n span: rangeToPslSpan(diagnostic.range, sourceFile),\n }));\n}\n\nexport function mongoContract(schemaPath: string, options?: MongoContractOptions): ContractConfig {\n return {\n source: {\n sourceFormat: 'psl',\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, sourceFile, diagnostics: parseDiagnostics } = parse(schema);\n const { table: symbolTable, diagnostics: symbolTableDiagnostics } = buildSymbolTable({\n document,\n sourceFile,\n scalarTypes: [...context.scalarTypeDescriptors.keys()],\n pslBlockDescriptors: context.authoringContributions.pslBlockDescriptors,\n });\n\n // Do not short-circuit on provider-level diagnostics; recovered CST can\n // still produce interpreter diagnostics in the same response.\n const seedDiagnostics = [\n ...mapParseDiagnostics(parseDiagnostics, sourceFile, schemaPath),\n ...mapParseDiagnostics(symbolTableDiagnostics, sourceFile, schemaPath),\n ];\n\n const interpreted = interpretPslDocumentToMongoContract({\n symbolTable,\n sourceFile,\n sourceId: schemaPath,\n seedDiagnostics,\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":";;;;;;;AAcA,SAAS,oBACP,aACA,YACA,UAC4B;CAC5B,OAAO,YAAY,KAAK,gBAAgB;EACtC,MAAM,WAAW;EACjB,SAAS,WAAW;EACpB;EACA,MAAM,eAAe,WAAW,OAAO,UAAU;CACnD,EAAE;AACJ;AAEA,SAAgB,cAAc,YAAoB,SAAgD;CAChG,OAAO;EACL,QAAQ;GACN,cAAc;GACd,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;IAEA,MAAM,EAAE,UAAU,YAAY,aAAa,qBAAqB,MAAM,MAAM;IAC5E,MAAM,EAAE,OAAO,aAAa,aAAa,2BAA2B,iBAAiB;KACnF;KACA;KACA,aAAa,CAAC,GAAG,QAAQ,sBAAsB,KAAK,CAAC;KACrD,qBAAqB,QAAQ,uBAAuB;IACtD,CAAC;IASD,MAAM,cAAc,oCAAoC;KACtD;KACA;KACA,UAAU;KACV,iBAAA,CARA,GAAG,oBAAoB,kBAAkB,YAAY,UAAU,GAC/D,GAAG,oBAAoB,wBAAwB,YAAY,UAAU,CAOvD;KACd,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,14 +1,18 @@
1
1
  import { Contract } from "@prisma-next/contract/types";
2
+ import { SymbolTable } from "@prisma-next/psl-parser";
2
3
  import { Result } from "@prisma-next/utils/result";
3
- import { ParsePslDocumentResult } from "@prisma-next/psl-parser";
4
- import { ContractSourceDiagnostics } from "@prisma-next/config/config-types";
4
+ import { SourceFile } from "@prisma-next/psl-parser/syntax";
5
+ import { ContractSourceDiagnostic, ContractSourceDiagnostics } from "@prisma-next/config/config-types";
5
6
  import { CodecLookup } from "@prisma-next/framework-components/codec";
6
7
 
7
8
  //#region src/interpreter.d.ts
8
9
  interface InterpretPslDocumentToMongoContractInput {
9
- readonly document: ParsePslDocumentResult;
10
+ readonly symbolTable: SymbolTable;
11
+ readonly sourceFile: SourceFile;
12
+ readonly sourceId: string;
10
13
  readonly scalarTypeDescriptors: ReadonlyMap<string, string>;
11
14
  readonly codecLookup?: CodecLookup;
15
+ readonly seedDiagnostics?: readonly ContractSourceDiagnostic[];
12
16
  }
13
17
  declare function interpretPslDocumentToMongoContract(input: InterpretPslDocumentToMongoContractInput): Result<Contract, ContractSourceDiagnostics>;
14
18
  //#endregion
@@ -1 +1 @@
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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/interpreter.ts"],"mappings":";;;;;;;;UAkDiB,wCAAA;EAAA,SACN,WAAA,EAAa,WAAA;EAAA,SACb,UAAA,EAAY,UAAA;EAAA,SACZ,QAAA;EAAA,SACA,qBAAA,EAAuB,WAAA;EAAA,SACvB,WAAA,GAAc,WAAA;EAAA,SACd,eAAA,YAA2B,wBAAA;AAAA;AAAA,iBAoxBtB,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-CNVgUGau.mjs";
1
+ import { t as interpretPslDocumentToMongoContract } from "./interpreter-DCiVHDlW.mjs";
2
2
  export { interpretPslDocumentToMongoContract };
@@ -1,10 +1,12 @@
1
1
  import { computeProfileHash, computeStorageHash } from "@prisma-next/contract/hashing";
2
2
  import { crossRef } from "@prisma-next/contract/types";
3
3
  import { UNBOUND_NAMESPACE_ID } from "@prisma-next/framework-components/ir";
4
- import { MongoCollection, MongoIndex, MongoStorage, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace } from "@prisma-next/mongo-contract";
4
+ import { MongoIndex, MongoStorage, MongoValidator, applyPolymorphicScopeToMongoIndex, buildMongoNamespace } from "@prisma-next/mongo-contract";
5
5
  import { mongoContractCanonicalizationHooks } from "@prisma-next/mongo-contract/canonicalization-hooks";
6
+ import { nodePslSpan, parseQuotedStringLiteral } from "@prisma-next/psl-parser";
7
+ import { blindCast } from "@prisma-next/utils/casts";
6
8
  import { notOk, ok } from "@prisma-next/utils/result";
7
- import { getPositionalArgument, parseQuotedStringLiteral } from "@prisma-next/psl-parser";
9
+ import { ifDefined } from "@prisma-next/utils/defined";
8
10
  //#region src/derive-json-schema.ts
9
11
  function resolveBsonType(codecId, codecLookup) {
10
12
  return codecLookup?.targetTypesFor(codecId)?.[0];
@@ -98,6 +100,9 @@ function derivePolymorphicJsonSchema(baseFields, discriminatorField, variants, v
98
100
  }
99
101
  //#endregion
100
102
  //#region src/psl-helpers.ts
103
+ function getPositionalArgument(attr, index = 0) {
104
+ return attr.args.filter((arg) => arg.kind === "positional")[index]?.value;
105
+ }
101
106
  function getNamedArgument(attr, name) {
102
107
  return attr.args.find((a) => a.kind === "named" && a.name === name)?.value;
103
108
  }
@@ -172,9 +177,9 @@ function parseRelationAttribute(attributes) {
172
177
  const fields = fieldsArg ? parseFieldList(fieldsArg.value) : void 0;
173
178
  const references = referencesArg ? parseFieldList(referencesArg.value) : void 0;
174
179
  return {
175
- ...relationName !== void 0 ? { relationName } : {},
176
- ...fields !== void 0 ? { fields } : {},
177
- ...references !== void 0 ? { references } : {}
180
+ ...ifDefined("relationName", relationName),
181
+ ...ifDefined("fields", fields),
182
+ ...ifDefined("references", references)
178
183
  };
179
184
  }
180
185
  function stripQuotes(value) {
@@ -184,37 +189,23 @@ function stripQuotes(value) {
184
189
  //#endregion
185
190
  //#region src/interpreter.ts
186
191
  /**
187
- * Name of the framework-parser synthesised bucket for top-level
188
- * declarations. Re-declared locally so the interpreter does not have to
189
- * import from `@prisma-next/framework-components/psl-ast`.
190
- */
191
- const UNSPECIFIED_PSL_NAMESPACE_NAME = "__unspecified__";
192
- /**
193
- * Mongo FR16c validation: Mongo's authoring DSL exposes the connection's
194
- * database as the only namespace surface today, so the PSL interpreter
195
- * rejects every explicit `namespace { … }` block. The implicit
196
- * `__unspecified__` bucket (top-level declarations) is the only
197
- * namespace Mongo accepts. `namespace unbound { … }` is rejected too —
198
- * Mongo has no late-binding namespace concept on the PSL surface (the
199
- * database name comes from the connection string, not from PSL).
192
+ * Mongo's PSL surface binds the database from the connection string, so every
193
+ * explicit namespace block is invalid, including `namespace unbound { … }`.
200
194
  */
201
195
  function validateNamespaceBlocksForMongoTarget(input) {
202
- for (const namespace of input.namespaces) {
203
- if (namespace.name === UNSPECIFIED_PSL_NAMESPACE_NAME) continue;
204
- input.diagnostics.push({
205
- code: "PSL_UNSUPPORTED_NAMESPACE_BLOCK",
206
- 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).`,
207
- sourceId: input.sourceId,
208
- span: namespace.span
209
- });
210
- }
196
+ for (const namespace of input.namespaces) input.diagnostics.push({
197
+ code: "PSL_UNSUPPORTED_NAMESPACE_BLOCK",
198
+ 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).`,
199
+ sourceId: input.sourceId,
200
+ span: nodePslSpan(namespace.node.syntax, input.sourceFile)
201
+ });
211
202
  }
212
203
  function fkRelationPairKey(declaringModel, targetModel) {
213
204
  return `${declaringModel}::${targetModel}`;
214
205
  }
215
206
  function resolveFieldMappings(model) {
216
207
  const pslNameToMapped = /* @__PURE__ */ new Map();
217
- for (const field of model.fields) {
208
+ for (const field of Object.values(model.fields)) {
218
209
  const mapped = getMapName(field.attributes) ?? field.name;
219
210
  pslNameToMapped.set(field.name, mapped);
220
211
  }
@@ -226,33 +217,32 @@ function resolveCollectionName(model) {
226
217
  function mongoCrossRef(modelName) {
227
218
  return crossRef(modelName, UNBOUND_NAMESPACE_ID);
228
219
  }
229
- function collectPolymorphismDeclarations(document, sourceId, diagnostics) {
220
+ function collectPolymorphismDeclarations(models, sourceId, diagnostics) {
230
221
  const discriminatorDeclarations = /* @__PURE__ */ new Map();
231
222
  const baseDeclarations = /* @__PURE__ */ new Map();
232
- const allPslModels = document.ast.namespaces.flatMap((ns) => ns.models);
233
- for (const pslModel of allPslModels) for (const attr of pslModel.attributes) {
223
+ for (const model of models) for (const attr of model.attributes) {
234
224
  if (attr.name === "discriminator") {
235
225
  const fieldName = getPositionalArgument(attr);
236
226
  if (!fieldName) {
237
227
  diagnostics.push({
238
228
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
239
- message: `Model "${pslModel.name}" @@discriminator requires a field name argument`,
229
+ message: `Model "${model.name}" @@discriminator requires a field name argument`,
240
230
  sourceId,
241
231
  span: attr.span
242
232
  });
243
233
  continue;
244
234
  }
245
- const discField = pslModel.fields.find((f) => f.name === fieldName);
235
+ const discField = model.fields[fieldName];
246
236
  if (discField && discField.typeName !== "String") {
247
237
  diagnostics.push({
248
238
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
249
- message: `Discriminator field "${fieldName}" on model "${pslModel.name}" must be of type String, but is "${discField.typeName}"`,
239
+ message: `Discriminator field "${fieldName}" on model "${model.name}" must be of type String, but is "${discField.typeName}"`,
250
240
  sourceId,
251
241
  span: attr.span
252
242
  });
253
243
  continue;
254
244
  }
255
- discriminatorDeclarations.set(pslModel.name, {
245
+ discriminatorDeclarations.set(model.name, {
256
246
  fieldName,
257
247
  span: attr.span
258
248
  });
@@ -263,7 +253,7 @@ function collectPolymorphismDeclarations(document, sourceId, diagnostics) {
263
253
  if (!baseName || !rawValue) {
264
254
  diagnostics.push({
265
255
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
266
- message: `Model "${pslModel.name}" @@base requires two arguments: base model name and discriminator value`,
256
+ message: `Model "${model.name}" @@base requires two arguments: base model name and discriminator value`,
267
257
  sourceId,
268
258
  span: attr.span
269
259
  });
@@ -273,14 +263,14 @@ function collectPolymorphismDeclarations(document, sourceId, diagnostics) {
273
263
  if (value === void 0) {
274
264
  diagnostics.push({
275
265
  code: "PSL_INVALID_ATTRIBUTE_ARGUMENT",
276
- message: `Model "${pslModel.name}" @@base discriminator value must be a quoted string literal`,
266
+ message: `Model "${model.name}" @@base discriminator value must be a quoted string literal`,
277
267
  sourceId,
278
268
  span: attr.span
279
269
  });
280
270
  continue;
281
271
  }
282
- const collectionName = resolveCollectionName(pslModel);
283
- baseDeclarations.set(pslModel.name, {
272
+ const collectionName = resolveCollectionName(model);
273
+ baseDeclarations.set(model.name, {
284
274
  baseName,
285
275
  value,
286
276
  collectionName,
@@ -294,8 +284,7 @@ function collectPolymorphismDeclarations(document, sourceId, diagnostics) {
294
284
  };
295
285
  }
296
286
  function resolvePolymorphism(input) {
297
- const { discriminatorDeclarations, baseDeclarations, modelNames, sourceId, document, indexSpans, modelIndexesByName } = input;
298
- const allPslModels = document.ast.namespaces.flatMap((ns) => ns.models);
287
+ const { discriminatorDeclarations, baseDeclarations, modelNames, sourceId, allModels: allModelViews, indexSpans, modelIndexesByName } = input;
299
288
  let patched = input.models;
300
289
  let roots = input.roots;
301
290
  let collections = input.collections;
@@ -312,8 +301,8 @@ function resolvePolymorphism(input) {
312
301
  }
313
302
  const model = patched[modelName];
314
303
  if (!model) continue;
315
- const pslModel = allPslModels.find((m) => m.name === modelName);
316
- const mappedDiscriminatorField = pslModel ? resolveFieldMappings(pslModel).pslNameToMapped.get(decl.fieldName) ?? decl.fieldName : decl.fieldName;
304
+ const modelView = allModelViews.find((m) => m.name === modelName);
305
+ const mappedDiscriminatorField = modelView ? resolveFieldMappings(modelView).pslNameToMapped.get(decl.fieldName) ?? decl.fieldName : decl.fieldName;
317
306
  if (!Object.hasOwn(model.fields, mappedDiscriminatorField)) {
318
307
  diagnostics.push({
319
308
  code: "PSL_DISCRIMINATOR_FIELD_NOT_FOUND",
@@ -367,9 +356,9 @@ function resolvePolymorphism(input) {
367
356
  }
368
357
  if (discriminatorDeclarations.has(variantName)) continue;
369
358
  const baseModel = patched[baseDecl.baseName];
370
- const variantPslModel = allPslModels.find((m) => m.name === variantName);
371
- if (!variantPslModel) continue;
372
- if (getMapName(variantPslModel.attributes) !== void 0 && baseModel && baseDecl.collectionName !== baseModel.storage.collection) {
359
+ const variantModelView = allModelViews.find((m) => m.name === variantName);
360
+ if (!variantModelView) continue;
361
+ if (getMapName(variantModelView.attributes) !== void 0 && baseModel && baseDecl.collectionName !== baseModel.storage.collection) {
373
362
  diagnostics.push({
374
363
  code: "PSL_MONGO_VARIANT_SEPARATE_COLLECTION",
375
364
  message: `Mongo variant "${variantName}" cannot use a different collection than its base "${baseDecl.baseName}". Mongo only supports single-collection polymorphism.`,
@@ -388,7 +377,7 @@ function resolvePolymorphism(input) {
388
377
  storage: { collection: baseCollection }
389
378
  }
390
379
  };
391
- const variantCollectionName = resolveCollectionName(variantPslModel);
380
+ const variantCollectionName = resolveCollectionName(variantModelView);
392
381
  if (roots[variantCollectionName]?.model === variantName) if (variantCollectionName === baseCollection && baseModel) roots = {
393
382
  ...roots,
394
383
  [variantCollectionName]: mongoCrossRef(baseDecl.baseName)
@@ -496,21 +485,21 @@ function parseCollation(attr) {
496
485
  if (!locale) return getNamedArgument(attr, "collationStrength") != null || getNamedArgument(attr, "collationCaseLevel") != null || getNamedArgument(attr, "collationCaseFirst") != null || getNamedArgument(attr, "collationNumericOrdering") != null || getNamedArgument(attr, "collationAlternate") != null || getNamedArgument(attr, "collationMaxVariable") != null || getNamedArgument(attr, "collationBackwards") != null || getNamedArgument(attr, "collationNormalization") != null ? null : void 0;
497
486
  const collation = { locale };
498
487
  const strength = parseNumericArg(getNamedArgument(attr, "collationStrength"));
499
- if (strength != null) collation["strength"] = strength;
488
+ if (strength != null) collation.strength = strength;
500
489
  const caseLevel = parseBooleanArg(getNamedArgument(attr, "collationCaseLevel"));
501
- if (caseLevel != null) collation["caseLevel"] = caseLevel;
490
+ if (caseLevel != null) collation.caseLevel = caseLevel;
502
491
  const caseFirst = stripQuotesHelper(getNamedArgument(attr, "collationCaseFirst"));
503
- if (caseFirst != null) collation["caseFirst"] = caseFirst;
492
+ if (caseFirst != null) collation.caseFirst = caseFirst;
504
493
  const numericOrdering = parseBooleanArg(getNamedArgument(attr, "collationNumericOrdering"));
505
- if (numericOrdering != null) collation["numericOrdering"] = numericOrdering;
494
+ if (numericOrdering != null) collation.numericOrdering = numericOrdering;
506
495
  const alternate = stripQuotesHelper(getNamedArgument(attr, "collationAlternate"));
507
- if (alternate != null) collation["alternate"] = alternate;
496
+ if (alternate != null) collation.alternate = alternate;
508
497
  const maxVariable = stripQuotesHelper(getNamedArgument(attr, "collationMaxVariable"));
509
- if (maxVariable != null) collation["maxVariable"] = maxVariable;
498
+ if (maxVariable != null) collation.maxVariable = maxVariable;
510
499
  const backwards = parseBooleanArg(getNamedArgument(attr, "collationBackwards"));
511
- if (backwards != null) collation["backwards"] = backwards;
500
+ if (backwards != null) collation.backwards = backwards;
512
501
  const normalization = parseBooleanArg(getNamedArgument(attr, "collationNormalization"));
513
- if (normalization != null) collation["normalization"] = normalization;
502
+ if (normalization != null) collation.normalization = normalization;
514
503
  return collation;
515
504
  }
516
505
  function stripQuotesHelper(raw) {
@@ -530,11 +519,11 @@ function collectIndexes(pslModel, fieldMappings, modelNames, sourceId, diagnosti
530
519
  const indexes = [];
531
520
  let textIndexCount = 0;
532
521
  const indexableFieldNames = /* @__PURE__ */ new Set();
533
- for (const f of pslModel.fields) {
522
+ for (const f of Object.values(pslModel.fields)) {
534
523
  if (modelNames.has(f.typeName)) continue;
535
524
  indexableFieldNames.add(f.name);
536
525
  }
537
- for (const field of pslModel.fields) {
526
+ for (const field of Object.values(pslModel.fields)) {
538
527
  if (modelNames.has(field.typeName)) continue;
539
528
  const uniqueAttr = getAttribute(field.attributes, "unique");
540
529
  if (!uniqueAttr) continue;
@@ -742,6 +731,7 @@ function resolveNonRelationField(field, ownerName, compositeTypeNames, scalarTyp
742
731
  many: true
743
732
  } : result;
744
733
  }
734
+ if (field.malformedType) return;
745
735
  const codecId = resolveFieldCodecId(field, scalarTypeDescriptors);
746
736
  if (!codecId) {
747
737
  diagnostics.push({
@@ -765,16 +755,18 @@ function resolveNonRelationField(field, ownerName, compositeTypeNames, scalarTyp
765
755
  } : result;
766
756
  }
767
757
  function interpretPslDocumentToMongoContract(input) {
768
- const { document, scalarTypeDescriptors, codecLookup } = input;
769
- const sourceId = document.ast.sourceId;
770
- const diagnostics = [];
758
+ const { symbolTable, sourceFile, scalarTypeDescriptors, codecLookup } = input;
759
+ const sourceId = input.sourceId;
760
+ const diagnostics = [...input.seedDiagnostics ?? []];
761
+ const topLevel = symbolTable.topLevel;
771
762
  validateNamespaceBlocksForMongoTarget({
772
- namespaces: document.ast.namespaces,
763
+ namespaces: Object.values(topLevel.namespaces),
773
764
  sourceId,
765
+ sourceFile,
774
766
  diagnostics
775
767
  });
776
- const allModels = document.ast.namespaces.flatMap((ns) => ns.models);
777
- const allCompositeTypes = document.ast.namespaces.flatMap((ns) => ns.compositeTypes);
768
+ const allModels = Object.values(topLevel.models);
769
+ const allCompositeTypes = Object.values(topLevel.compositeTypes);
778
770
  const modelNames = new Set(allModels.map((m) => m.name));
779
771
  const compositeTypeNames = new Set(allCompositeTypes.map((ct) => ct.name));
780
772
  const models = {};
@@ -789,7 +781,7 @@ function interpretPslDocumentToMongoContract(input) {
789
781
  const fieldMappings = resolveFieldMappings(pslModel);
790
782
  const fields = {};
791
783
  const relations = {};
792
- for (const field of pslModel.fields) {
784
+ for (const field of Object.values(pslModel.fields)) {
793
785
  if (isRelationField(field, modelNames)) {
794
786
  const relation = parseRelationAttribute(field.attributes);
795
787
  if (field.list || !(relation?.fields && relation?.references)) {
@@ -833,7 +825,7 @@ function interpretPslDocumentToMongoContract(input) {
833
825
  fields[mappedName] = resolved;
834
826
  }
835
827
  const isVariantModel = pslModel.attributes.some((attr) => attr.name === "base");
836
- const hasIdField = pslModel.fields.some((f) => getAttribute(f.attributes, "id") !== void 0);
828
+ const hasIdField = Object.values(pslModel.fields).some((f) => getAttribute(f.attributes, "id") !== void 0);
837
829
  if (!isVariantModel) if (!hasIdField) diagnostics.push({
838
830
  code: "PSL_MISSING_ID_FIELD",
839
831
  message: `Model "${pslModel.name}" has no field with @id attribute. Every model must have exactly one @id field.`,
@@ -863,7 +855,7 @@ function interpretPslDocumentToMongoContract(input) {
863
855
  const valueObjects = {};
864
856
  for (const compositeType of allCompositeTypes) {
865
857
  const fields = {};
866
- for (const field of compositeType.fields) {
858
+ for (const field of Object.values(compositeType.fields)) {
867
859
  const resolved = resolveNonRelationField(field, compositeType.name, compositeTypeNames, scalarTypeDescriptors, sourceId, diagnostics);
868
860
  if (!resolved) continue;
869
861
  fields[field.name] = resolved;
@@ -912,12 +904,12 @@ function interpretPslDocumentToMongoContract(input) {
912
904
  }
913
905
  };
914
906
  }
915
- const { discriminatorDeclarations, baseDeclarations } = collectPolymorphismDeclarations(document, sourceId, diagnostics);
907
+ const { discriminatorDeclarations, baseDeclarations } = collectPolymorphismDeclarations(allModels, sourceId, diagnostics);
916
908
  const polyResult = resolvePolymorphism({
917
909
  models,
918
910
  roots,
919
911
  collections,
920
- document,
912
+ allModels,
921
913
  discriminatorDeclarations,
922
914
  baseDeclarations,
923
915
  modelNames,
@@ -945,28 +937,29 @@ function interpretPslDocumentToMongoContract(input) {
945
937
  }
946
938
  const target = "mongo";
947
939
  const targetFamily = "mongo";
948
- const collectionsAsClasses = {};
940
+ const collectionInputs = {};
949
941
  for (const [name, coll] of Object.entries(resolvedCollections)) {
950
- const input = {};
951
- if (coll["indexes"] !== void 0) input.indexes = coll["indexes"];
952
- if (coll["validator"] !== void 0) input.validator = coll["validator"];
953
- if (coll["options"] !== void 0) input.options = coll["options"];
954
- collectionsAsClasses[name] = new MongoCollection(input);
942
+ const raw = {};
943
+ if (coll["indexes"] != null) raw["indexes"] = coll["indexes"];
944
+ if (coll["validator"] != null) raw["validator"] = coll["validator"];
945
+ if (coll["options"] != null) raw["options"] = coll["options"];
946
+ collectionInputs[name] = blindCast(raw);
955
947
  }
948
+ const unboundNamespace = buildMongoNamespace({
949
+ id: UNBOUND_NAMESPACE_ID,
950
+ entries: { collection: collectionInputs }
951
+ });
956
952
  const storage = new MongoStorage({
957
953
  storageHash: computeStorageHash({
958
954
  target,
959
955
  targetFamily,
960
956
  storage: { namespaces: { [UNBOUND_NAMESPACE_ID]: {
961
957
  id: UNBOUND_NAMESPACE_ID,
962
- entries: { collection: collectionsAsClasses }
958
+ entries: { collection: unboundNamespace.entries.collection }
963
959
  } } },
964
960
  ...mongoContractCanonicalizationHooks
965
961
  }),
966
- namespaces: { [UNBOUND_NAMESPACE_ID]: buildMongoNamespace({
967
- id: UNBOUND_NAMESPACE_ID,
968
- entries: { collection: collectionsAsClasses }
969
- }) }
962
+ namespaces: { [UNBOUND_NAMESPACE_ID]: unboundNamespace }
970
963
  });
971
964
  const capabilities = {};
972
965
  return ok({
@@ -991,4 +984,4 @@ function interpretPslDocumentToMongoContract(input) {
991
984
  //#endregion
992
985
  export { interpretPslDocumentToMongoContract as t };
993
986
 
994
- //# sourceMappingURL=interpreter-CNVgUGau.mjs.map
987
+ //# sourceMappingURL=interpreter-DCiVHDlW.mjs.map