@prisma-next/target-mongo 0.6.0-dev.13 → 0.6.0-dev.15

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.
@@ -29,14 +29,33 @@ declare class FilterEvaluator implements MongoFilterVisitor<boolean> {
29
29
  }
30
30
  //#endregion
31
31
  //#region src/core/marker-ledger.d.ts
32
- declare function readMarker(db: Db): Promise<ContractMarkerRecord | null>;
33
- declare function initMarker(db: Db, destination: {
32
+ /**
33
+ * Reads the marker document for the given contract space, or returns
34
+ * `null` if no marker has been written for that space yet. Each space
35
+ * owns one row keyed by `_id: <space>` — see ADR 212 for the per-space
36
+ * mechanism this enables.
37
+ */
38
+ declare function readMarker(db: Db, space: string): Promise<ContractMarkerRecord | null>;
39
+ /**
40
+ * Reads every marker doc in the collection (one per contract space)
41
+ * and returns them keyed by `space`. Used by the per-space verifier
42
+ * to detect marker-vs-on-disk drift and orphan marker rows. Returns
43
+ * an empty map when no marker docs have been written yet.
44
+ *
45
+ * Marker docs are keyed by `_id: <space>` (string); ledger entries
46
+ * live in the same collection but use a driver-generated `ObjectId`
47
+ * `_id` plus `type: 'ledger'`. The filter selects string-keyed docs
48
+ * with a `space` field, which excludes ledger entries by construction.
49
+ */
50
+ declare function readAllMarkers(db: Db): Promise<ReadonlyMap<string, ContractMarkerRecord>>;
51
+ declare function initMarker(db: Db, space: string, destination: {
34
52
  readonly storageHash: string;
35
53
  readonly profileHash: string;
36
54
  readonly invariants?: readonly string[];
37
55
  }): Promise<void>;
38
56
  /**
39
- * Updates the marker doc atomically (CAS on `expectedFrom`).
57
+ * Updates the marker doc for the given space atomically (CAS on
58
+ * `expectedFrom`).
40
59
  *
41
60
  * `destination.invariants`:
42
61
  * - `undefined` → existing field left untouched.
@@ -44,12 +63,22 @@ declare function initMarker(db: Db, destination: {
44
63
  * aggregation pipeline (`$setUnion + $sortArray`), atomic at the
45
64
  * document level. `[]` is a no-op merge.
46
65
  */
47
- declare function updateMarker(db: Db, expectedFrom: string, destination: {
66
+ declare function updateMarker(db: Db, space: string, expectedFrom: string, destination: {
48
67
  readonly storageHash: string;
49
68
  readonly profileHash: string;
50
69
  readonly invariants?: readonly string[];
51
70
  }): Promise<boolean>;
52
- declare function writeLedgerEntry(db: Db, entry: {
71
+ /**
72
+ * Appends a ledger entry for the given space. Ledger entries co-exist
73
+ * with marker docs in the same collection; marker docs use `_id: <space>`
74
+ * (string), ledger entries use `type: 'ledger'` plus a driver-generated
75
+ * ObjectId. Reads partition the two by filter shape.
76
+ *
77
+ * The same `edgeId` may legitimately recur across different spaces (e.g.
78
+ * a synthetic ∅→head edge on first apply), so the ledger key is
79
+ * `(space, edgeId)` — the doc carries `space` for partitioned reads.
80
+ */
81
+ declare function writeLedgerEntry(db: Db, space: string, entry: {
53
82
  readonly edgeId: string;
54
83
  readonly from: string;
55
84
  readonly to: string;
@@ -100,19 +129,25 @@ declare class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'
100
129
  }
101
130
  //#endregion
102
131
  //#region src/core/mongo-runner.d.ts
132
+ /**
133
+ * Marker / ledger operations the Mongo runner depends on. Every method
134
+ * takes a `space` parameter so each loaded contract space addresses its
135
+ * own marker row independently — see ADR 212 for the per-space
136
+ * mechanism.
137
+ */
103
138
  interface MarkerOperations {
104
- readMarker(): Promise<ContractMarkerRecord | null>;
105
- initMarker(destination: {
139
+ readMarker(space: string): Promise<ContractMarkerRecord | null>;
140
+ initMarker(space: string, destination: {
106
141
  readonly storageHash: string;
107
142
  readonly profileHash: string;
108
143
  readonly invariants?: readonly string[];
109
144
  }): Promise<void>;
110
- updateMarker(expectedFrom: string, destination: {
145
+ updateMarker(space: string, expectedFrom: string, destination: {
111
146
  readonly storageHash: string;
112
147
  readonly profileHash: string;
113
148
  readonly invariants?: readonly string[];
114
149
  }): Promise<boolean>;
115
- writeLedgerEntry(entry: {
150
+ writeLedgerEntry(space: string, entry: {
116
151
  readonly edgeId: string;
117
152
  readonly from: string;
118
153
  readonly to: string;
@@ -138,6 +173,18 @@ interface MongoMigrationRunnerExecuteOptions {
138
173
  readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;
139
174
  readonly strictVerification?: boolean;
140
175
  readonly context?: OperationContext;
176
+ /**
177
+ * Per-space schema projection. When set, the runner applies this
178
+ * function to the introspected schema before invoking
179
+ * `verifyMongoSchema`, so per-space verification only sees the slice
180
+ * the destination contract actually claims.
181
+ *
182
+ * The descriptor's `executeAcrossSpaces` injects this callback,
183
+ * derived from the sibling spaces in the aggregate. Single-space
184
+ * callers leave it unset and verify against the whole introspected
185
+ * schema (the pre-aggregate behaviour).
186
+ */
187
+ readonly projectSchema?: (schema: MongoSchemaIR) => MongoSchemaIR;
141
188
  }
142
189
  declare class MongoMigrationRunner {
143
190
  private readonly deps;
@@ -206,5 +253,5 @@ interface RenderMigrationMeta {
206
253
  */
207
254
  declare function renderCallsToTypeScript(calls: ReadonlyArray<OpFactoryCall>, meta: RenderMigrationMeta): string;
208
255
  //#endregion
209
- export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoRunnerDependencies, type OpFactoryCall, type PlanCallsResult, PlannerProducedMongoMigration, type RenderMigrationMeta, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
256
+ export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoMigrationRunnerExecuteOptions, type MongoRunnerDependencies, type OpFactoryCall, type PlanCallsResult, PlannerProducedMongoMigration, type RenderMigrationMeta, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readAllMarkers, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
210
257
  //# sourceMappingURL=control.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"mappings":"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"}
1
+ {"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"mappings":"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"}
package/dist/control.mjs CHANGED
@@ -9,6 +9,7 @@ import { TsExpression, jsonToTsSource, renderImports } from "@prisma-next/ts-ren
9
9
  import { Migration } from "@prisma-next/migration-tools/migration";
10
10
  import { detectScaffoldRuntime, shebangLineFor } from "@prisma-next/migration-tools/migration-ts";
11
11
  import { errorRunnerFailed } from "@prisma-next/errors/execution";
12
+ import { APP_SPACE_ID } from "@prisma-next/framework-components/control";
12
13
  import { notOk, ok } from "@prisma-next/utils/result";
13
14
  //#region src/core/ddl-formatter.ts
14
15
  function formatKeySpec(keys) {
@@ -134,8 +135,19 @@ var FilterEvaluator = class {
134
135
  //#endregion
135
136
  //#region src/core/marker-ledger.ts
136
137
  const COLLECTION = "_prisma_migrations";
137
- const MARKER_ID = "marker";
138
+ /**
139
+ * Marker doc shape.
140
+ *
141
+ * Same fields as the SQL marker row but camelCase + Mongo-native types:
142
+ * `Date` is BSON-hydrated, `meta` is a native object (not JSON-stringified),
143
+ * `_id` and any extension fields are tolerated. `invariants?` is optional —
144
+ * absent reads as `[]` (schemaless default); present-but-malformed throws.
145
+ *
146
+ * `space` is required: every marker doc is keyed by its space id (`_id`)
147
+ * and stamped with a matching `space` field for partitioned reads.
148
+ */
138
149
  const MongoMarkerDocSchema = type({
150
+ space: "string",
139
151
  storageHash: "string",
140
152
  profileHash: "string",
141
153
  "contractJson?": "unknown | null",
@@ -169,14 +181,50 @@ async function executeInsertOne(db, cmd) {
169
181
  async function executeFindOneAndUpdate(db, cmd) {
170
182
  return db.collection(cmd.collection).findOneAndUpdate(cmd.filter, cmd.update, { upsert: cmd.upsert });
171
183
  }
172
- async function readMarker(db) {
173
- const doc = (await executeAggregate(db, new RawAggregateCommand(COLLECTION, [{ $match: { _id: MARKER_ID } }, { $limit: 1 }])))[0];
184
+ /**
185
+ * Reads the marker document for the given contract space, or returns
186
+ * `null` if no marker has been written for that space yet. Each space
187
+ * owns one row keyed by `_id: <space>` — see ADR 212 for the per-space
188
+ * mechanism this enables.
189
+ */
190
+ async function readMarker(db, space) {
191
+ const doc = (await executeAggregate(db, new RawAggregateCommand(COLLECTION, [{ $match: {
192
+ _id: space,
193
+ space
194
+ } }, { $limit: 1 }])))[0];
174
195
  if (!doc) return null;
175
196
  return parseMongoMarkerDoc(doc);
176
197
  }
177
- async function initMarker(db, destination) {
198
+ /**
199
+ * Reads every marker doc in the collection (one per contract space)
200
+ * and returns them keyed by `space`. Used by the per-space verifier
201
+ * to detect marker-vs-on-disk drift and orphan marker rows. Returns
202
+ * an empty map when no marker docs have been written yet.
203
+ *
204
+ * Marker docs are keyed by `_id: <space>` (string); ledger entries
205
+ * live in the same collection but use a driver-generated `ObjectId`
206
+ * `_id` plus `type: 'ledger'`. The filter selects string-keyed docs
207
+ * with a `space` field, which excludes ledger entries by construction.
208
+ */
209
+ async function readAllMarkers(db) {
210
+ const docs = await executeAggregate(db, new RawAggregateCommand(COLLECTION, [{ $match: {
211
+ _id: { $type: "string" },
212
+ space: { $type: "string" },
213
+ $expr: { $eq: ["$_id", "$space"] }
214
+ } }]));
215
+ const out = /* @__PURE__ */ new Map();
216
+ for (const doc of docs) {
217
+ const space = doc["space"];
218
+ /* v8 ignore next -- @preserve type-narrowing guard: the $match stage above filters on `space: { $type: 'string' }`, so this branch is unreachable at runtime. The check exists so the `out.set(space, ...)` call below can accept `string`. */
219
+ if (typeof space !== "string") continue;
220
+ out.set(space, parseMongoMarkerDoc(doc));
221
+ }
222
+ return out;
223
+ }
224
+ async function initMarker(db, space, destination) {
178
225
  await executeInsertOne(db, new RawInsertOneCommand(COLLECTION, {
179
- _id: MARKER_ID,
226
+ _id: space,
227
+ space,
180
228
  storageHash: destination.storageHash,
181
229
  profileHash: destination.profileHash,
182
230
  contractJson: null,
@@ -188,7 +236,8 @@ async function initMarker(db, destination) {
188
236
  }));
189
237
  }
190
238
  /**
191
- * Updates the marker doc atomically (CAS on `expectedFrom`).
239
+ * Updates the marker doc for the given space atomically (CAS on
240
+ * `expectedFrom`).
192
241
  *
193
242
  * `destination.invariants`:
194
243
  * - `undefined` → existing field left untouched.
@@ -196,7 +245,7 @@ async function initMarker(db, destination) {
196
245
  * aggregation pipeline (`$setUnion + $sortArray`), atomic at the
197
246
  * document level. `[]` is a no-op merge.
198
247
  */
199
- async function updateMarker(db, expectedFrom, destination) {
248
+ async function updateMarker(db, space, expectedFrom, destination) {
200
249
  const setBase = {
201
250
  storageHash: destination.storageHash,
202
251
  profileHash: destination.profileHash,
@@ -210,13 +259,25 @@ async function updateMarker(db, expectedFrom, destination) {
210
259
  } }
211
260
  } }];
212
261
  return await executeFindOneAndUpdate(db, new RawFindOneAndUpdateCommand(COLLECTION, {
213
- _id: MARKER_ID,
262
+ _id: space,
263
+ space,
214
264
  storageHash: expectedFrom
215
265
  }, update, false)) !== null;
216
266
  }
217
- async function writeLedgerEntry(db, entry) {
267
+ /**
268
+ * Appends a ledger entry for the given space. Ledger entries co-exist
269
+ * with marker docs in the same collection; marker docs use `_id: <space>`
270
+ * (string), ledger entries use `type: 'ledger'` plus a driver-generated
271
+ * ObjectId. Reads partition the two by filter shape.
272
+ *
273
+ * The same `edgeId` may legitimately recur across different spaces (e.g.
274
+ * a synthetic ∅→head edge on first apply), so the ledger key is
275
+ * `(space, edgeId)` — the doc carries `space` for partitioned reads.
276
+ */
277
+ async function writeLedgerEntry(db, space, entry) {
218
278
  await executeInsertOne(db, new RawInsertOneCommand(COLLECTION, {
219
279
  type: "ledger",
280
+ space,
220
281
  edgeId: entry.edgeId,
221
282
  from: entry.from,
222
283
  to: entry.to,
@@ -1167,9 +1228,10 @@ var MongoMigrationRunner = class {
1167
1228
  async execute(options) {
1168
1229
  const { commandExecutor, inspectionExecutor, adapter, driver, markerOps } = this.deps;
1169
1230
  const operations = deserializeMongoOps(options.plan.operations);
1231
+ const space = options.plan.spaceId ?? APP_SPACE_ID;
1170
1232
  const policyCheck = this.enforcePolicyCompatibility(options.policy, operations);
1171
1233
  if (policyCheck) return policyCheck;
1172
- const existingMarker = await markerOps.readMarker();
1234
+ const existingMarker = await markerOps.readMarker(space);
1173
1235
  const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
1174
1236
  if (markerCheck) return markerCheck;
1175
1237
  const checks = options.executionChecks;
@@ -1211,9 +1273,10 @@ var MongoMigrationRunner = class {
1211
1273
  const markerAlreadyAtDestination = existingMarker !== null && existingMarker.storageHash === destination.storageHash && existingMarker.profileHash === profileHash;
1212
1274
  if (!(operationsExecuted === 0 && markerAlreadyAtDestination && incomingIsSubsetOfExisting)) {
1213
1275
  const liveSchema = await this.deps.introspectSchema();
1276
+ const verifySchema = options.projectSchema ? options.projectSchema(liveSchema) : liveSchema;
1214
1277
  const verifyResult = verifyMongoSchema({
1215
1278
  contract: options.destinationContract,
1216
- schema: liveSchema,
1279
+ schema: verifySchema,
1217
1280
  strict: options.strictVerification ?? true,
1218
1281
  frameworkComponents: options.frameworkComponents,
1219
1282
  ...options.context ? { context: options.context } : {}
@@ -1223,21 +1286,22 @@ var MongoMigrationRunner = class {
1223
1286
  meta: { issues: verifyResult.schema.issues }
1224
1287
  });
1225
1288
  if (existingMarker) {
1226
- if (!await markerOps.updateMarker(existingMarker.storageHash, {
1289
+ if (!await markerOps.updateMarker(space, existingMarker.storageHash, {
1227
1290
  storageHash: destination.storageHash,
1228
1291
  profileHash,
1229
1292
  invariants: incomingInvariants
1230
1293
  })) return runnerFailure("MARKER_CAS_FAILURE", "Marker was modified by another process during migration execution.", { meta: {
1294
+ space,
1231
1295
  expectedStorageHash: existingMarker.storageHash,
1232
1296
  destinationStorageHash: destination.storageHash
1233
1297
  } });
1234
- } else await markerOps.initMarker({
1298
+ } else await markerOps.initMarker(space, {
1235
1299
  storageHash: destination.storageHash,
1236
1300
  profileHash,
1237
1301
  invariants: incomingInvariants
1238
1302
  });
1239
1303
  const originHash = existingMarker?.storageHash ?? "";
1240
- await markerOps.writeLedgerEntry({
1304
+ await markerOps.writeLedgerEntry(space, {
1241
1305
  edgeId: `${originHash}->${destination.storageHash}`,
1242
1306
  from: originHash,
1243
1307
  to: destination.storageHash
@@ -1330,6 +1394,6 @@ var MongoMigrationRunner = class {
1330
1394
  }
1331
1395
  };
1332
1396
  //#endregion
1333
- export { CollModCall, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, MongoMigrationPlanner, MongoMigrationRunner, PlannerProducedMongoMigration, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
1397
+ export { CollModCall, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, MongoMigrationPlanner, MongoMigrationRunner, PlannerProducedMongoMigration, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readAllMarkers, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
1334
1398
 
1335
1399
  //# sourceMappingURL=control.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"control.mjs","names":["record"],"sources":["../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/op-factory-call.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts","../src/core/planner-produced-migration.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts"],"sourcesContent":["import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport type {\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n MongoDdlCommandVisitor,\n MongoIndexKey,\n} from '@prisma-next/mongo-query-ast/control';\n\nfunction formatKeySpec(keys: ReadonlyArray<MongoIndexKey>): string {\n const entries = keys.map((k) => `${JSON.stringify(k.field)}: ${JSON.stringify(k.direction)}`);\n return `{ ${entries.join(', ')} }`;\n}\n\nfunction formatOptions(cmd: CreateIndexCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.unique) parts.push('unique: true');\n if (cmd.sparse) parts.push('sparse: true');\n if (cmd.expireAfterSeconds !== undefined)\n parts.push(`expireAfterSeconds: ${cmd.expireAfterSeconds}`);\n if (cmd.name) parts.push(`name: ${JSON.stringify(cmd.name)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.weights) parts.push(`weights: ${JSON.stringify(cmd.weights)}`);\n if (cmd.default_language) parts.push(`default_language: ${JSON.stringify(cmd.default_language)}`);\n if (cmd.language_override)\n parts.push(`language_override: ${JSON.stringify(cmd.language_override)}`);\n if (cmd.wildcardProjection)\n parts.push(`wildcardProjection: ${JSON.stringify(cmd.wildcardProjection)}`);\n if (cmd.partialFilterExpression)\n parts.push(`partialFilterExpression: ${JSON.stringify(cmd.partialFilterExpression)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nfunction formatCreateCollectionOptions(cmd: CreateCollectionCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.capped) parts.push('capped: true');\n if (cmd.size !== undefined) parts.push(`size: ${cmd.size}`);\n if (cmd.max !== undefined) parts.push(`max: ${cmd.max}`);\n if (cmd.timeseries) parts.push(`timeseries: ${JSON.stringify(cmd.timeseries)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.clusteredIndex) parts.push(`clusteredIndex: ${JSON.stringify(cmd.clusteredIndex)}`);\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction) parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(`changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nclass MongoDdlCommandFormatter implements MongoDdlCommandVisitor<string> {\n createIndex(cmd: CreateIndexCommand): string {\n const keySpec = formatKeySpec(cmd.keys);\n const opts = formatOptions(cmd);\n return opts\n ? `db.${cmd.collection}.createIndex(${keySpec}, ${opts})`\n : `db.${cmd.collection}.createIndex(${keySpec})`;\n }\n\n dropIndex(cmd: DropIndexCommand): string {\n return `db.${cmd.collection}.dropIndex(${JSON.stringify(cmd.name)})`;\n }\n\n createCollection(cmd: CreateCollectionCommand): string {\n const opts = formatCreateCollectionOptions(cmd);\n return opts\n ? `db.createCollection(${JSON.stringify(cmd.collection)}, ${opts})`\n : `db.createCollection(${JSON.stringify(cmd.collection)})`;\n }\n\n dropCollection(cmd: DropCollectionCommand): string {\n return `db.${cmd.collection}.drop()`;\n }\n\n collMod(cmd: CollModCommand): string {\n const parts: string[] = [`collMod: ${JSON.stringify(cmd.collection)}`];\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction)\n parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(\n `changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`,\n );\n return `db.runCommand({ ${parts.join(', ')} })`;\n }\n}\n\nconst formatter = new MongoDdlCommandFormatter();\n\ninterface MongoExecuteStep {\n readonly command: { readonly accept: <R>(visitor: MongoDdlCommandVisitor<R>) => R };\n}\n\nexport function formatMongoOperations(operations: readonly MigrationPlanOperation[]): string[] {\n const statements: string[] = [];\n for (const operation of operations) {\n const candidate = operation as unknown as Record<string, unknown>;\n if (!('execute' in candidate) || !Array.isArray(candidate['execute'])) {\n continue;\n }\n for (const step of candidate['execute'] as MongoExecuteStep[]) {\n if (step.command && typeof step.command.accept === 'function') {\n statements.push(step.command.accept(formatter));\n }\n }\n }\n return statements;\n}\n","import type {\n MongoAndExpr,\n MongoExistsExpr,\n MongoExprFilter,\n MongoFieldFilter,\n MongoFilterExpr,\n MongoFilterVisitor,\n MongoNotExpr,\n MongoOrExpr,\n} from '@prisma-next/mongo-query-ast/control';\nimport { deepEqual } from '@prisma-next/mongo-schema-ir';\nimport type { MongoValue } from '@prisma-next/mongo-value';\n\nfunction getNestedField(doc: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = doc;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n const record = current as Record<string, unknown>;\n if (!Object.hasOwn(record, part)) {\n return undefined;\n }\n current = record[part];\n }\n return current;\n}\n\nfunction evaluateFieldOp(op: string, actual: unknown, expected: MongoValue): boolean {\n switch (op) {\n case '$eq':\n return deepEqual(actual, expected);\n case '$ne':\n return !deepEqual(actual, expected);\n case '$gt':\n return typeof actual === typeof expected && (actual as number) > (expected as number);\n case '$gte':\n return typeof actual === typeof expected && (actual as number) >= (expected as number);\n case '$lt':\n return typeof actual === typeof expected && (actual as number) < (expected as number);\n case '$lte':\n return typeof actual === typeof expected && (actual as number) <= (expected as number);\n case '$in':\n return Array.isArray(expected) && expected.some((v) => deepEqual(actual, v));\n default:\n throw new Error(`Unsupported filter operator in migration check: ${op}`);\n }\n}\n\nexport class FilterEvaluator implements MongoFilterVisitor<boolean> {\n private doc: Record<string, unknown> = {};\n\n evaluate(filter: MongoFilterExpr, doc: Record<string, unknown>): boolean {\n this.doc = doc;\n return filter.accept(this);\n }\n\n field(expr: MongoFieldFilter): boolean {\n const value = getNestedField(this.doc, expr.field);\n return evaluateFieldOp(expr.op, value, expr.value);\n }\n\n and(expr: MongoAndExpr): boolean {\n return expr.exprs.every((child) => child.accept(this));\n }\n\n or(expr: MongoOrExpr): boolean {\n return expr.exprs.some((child) => child.accept(this));\n }\n\n not(expr: MongoNotExpr): boolean {\n return !expr.expr.accept(this);\n }\n\n exists(expr: MongoExistsExpr): boolean {\n const has = getNestedField(this.doc, expr.field) !== undefined;\n return expr.exists ? has : !has;\n }\n\n expr(_expr: MongoExprFilter): boolean {\n throw new Error('Aggregation expression filters are not supported in migration checks');\n }\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport {\n RawAggregateCommand,\n RawFindOneAndUpdateCommand,\n RawInsertOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport { type } from 'arktype';\nimport type { Db, Document, UpdateFilter } from 'mongodb';\n\nconst COLLECTION = '_prisma_migrations';\nconst MARKER_ID = 'marker';\n\n// Same shape as the SQL marker row but camelCase + Mongo-native types:\n// `Date` is BSON-hydrated, `meta` is a native object (not JSON-stringified),\n// `_id` and any extension fields are tolerated. `invariants?` is optional —\n// absent reads as `[]` (schemaless default); present-but-malformed throws.\nconst MongoMarkerDocSchema = type({\n storageHash: 'string',\n profileHash: 'string',\n 'contractJson?': 'unknown | null',\n 'canonicalVersion?': 'number | null',\n 'updatedAt?': 'Date',\n 'appTag?': 'string | null',\n 'meta?': type({ '[string]': 'unknown' }).or('null'),\n 'invariants?': type('string').array(),\n '+': 'delete',\n});\n\nfunction parseMongoMarkerDoc(doc: unknown): ContractMarkerRecord {\n const result = MongoMarkerDocSchema(doc);\n if (result instanceof type.errors) {\n throw new Error(`Invalid marker doc on ${COLLECTION}: ${result.summary}`);\n }\n return {\n storageHash: result.storageHash,\n profileHash: result.profileHash,\n contractJson: result.contractJson ?? null,\n canonicalVersion: result.canonicalVersion ?? null,\n updatedAt: result.updatedAt ?? new Date(),\n appTag: result.appTag ?? null,\n meta: (result.meta as Record<string, unknown> | null) ?? {},\n invariants: result.invariants ?? [],\n };\n}\n\nasync function executeAggregate(db: Db, cmd: RawAggregateCommand): Promise<Document[]> {\n return db\n .collection(cmd.collection)\n .aggregate(cmd.pipeline as Record<string, unknown>[])\n .toArray();\n}\n\nasync function executeInsertOne(db: Db, cmd: RawInsertOneCommand): Promise<void> {\n await db.collection(cmd.collection).insertOne(cmd.document);\n}\n\nasync function executeFindOneAndUpdate(\n db: Db,\n cmd: RawFindOneAndUpdateCommand,\n): Promise<Document | null> {\n // `cmd.update` is `Document | ReadonlyArray<Document>` per the AST. The\n // MongoDB driver's `findOneAndUpdate` accepts the same shape under the\n // type `UpdateFilter<T> | Document[]`. The driver's runtime path handles\n // both forms identically — pipelines (array) and update docs (object).\n // One cast to that union keeps the call single-arm.\n return db\n .collection(cmd.collection)\n .findOneAndUpdate(cmd.filter, cmd.update as UpdateFilter<Document> | Document[], {\n upsert: cmd.upsert,\n });\n}\n\nexport async function readMarker(db: Db): Promise<ContractMarkerRecord | null> {\n const cmd = new RawAggregateCommand(COLLECTION, [{ $match: { _id: MARKER_ID } }, { $limit: 1 }]);\n const docs = await executeAggregate(db, cmd);\n const doc = docs[0];\n if (!doc) return null;\n return parseMongoMarkerDoc(doc);\n}\n\nexport async function initMarker(\n db: Db,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n _id: MARKER_ID,\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n contractJson: null,\n canonicalVersion: null,\n updatedAt: new Date(),\n appTag: null,\n meta: {},\n invariants: destination.invariants ?? [],\n });\n await executeInsertOne(db, cmd);\n}\n\n/**\n * Updates the marker doc atomically (CAS on `expectedFrom`).\n *\n * `destination.invariants`:\n * - `undefined` → existing field left untouched.\n * - explicit value → merged into the existing field server-side via an\n * aggregation pipeline (`$setUnion + $sortArray`), atomic at the\n * document level. `[]` is a no-op merge.\n */\nexport async function updateMarker(\n db: Db,\n expectedFrom: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n): Promise<boolean> {\n const setBase: Record<string, unknown> = {\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n updatedAt: new Date(),\n };\n // When invariants is supplied, use an aggregation pipeline so the\n // merge runs server-side against the doc's current value (atomic, no\n // read-then-write window). When omitted, a regular update doc keeps\n // the field untouched.\n const update: Document | Document[] =\n destination.invariants === undefined\n ? { $set: setBase }\n : [\n {\n $set: {\n ...setBase,\n invariants: {\n $sortArray: {\n input: { $setUnion: [{ $ifNull: ['$invariants', []] }, destination.invariants] },\n sortBy: 1,\n },\n },\n },\n },\n ];\n const cmd = new RawFindOneAndUpdateCommand(\n COLLECTION,\n { _id: MARKER_ID, storageHash: expectedFrom },\n update,\n false,\n );\n const result = await executeFindOneAndUpdate(db, cmd);\n return result !== null;\n}\n\nexport async function writeLedgerEntry(\n db: Db,\n entry: { readonly edgeId: string; readonly from: string; readonly to: string },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n type: 'ledger',\n edgeId: entry.edgeId,\n from: entry.from,\n to: entry.to,\n appliedAt: new Date(),\n });\n await executeInsertOne(db, cmd);\n}\n","import type { PlanMeta } from '@prisma-next/contract/types';\nimport type { MigrationOperationClass } from '@prisma-next/framework-components/control';\nimport {\n type AnyMongoDdlCommand,\n type AnyMongoInspectionCommand,\n type AnyMongoMigrationOperation,\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n ListCollectionsCommand,\n ListIndexesCommand,\n MongoAndExpr,\n type MongoDataTransformCheck,\n type MongoDataTransformOperation,\n MongoExistsExpr,\n MongoFieldFilter,\n type MongoFilterExpr,\n type MongoMigrationCheck,\n type MongoMigrationPlanOperation,\n type MongoMigrationStep,\n MongoNotExpr,\n MongoOrExpr,\n} from '@prisma-next/mongo-query-ast/control';\nimport {\n AggregateCommand,\n type AnyMongoCommand,\n MongoAddFieldsStage,\n MongoLimitStage,\n MongoLookupStage,\n MongoMatchStage,\n MongoMergeStage,\n type MongoPipelineStage,\n MongoProjectStage,\n type MongoQueryPlan,\n MongoSortStage,\n type MongoUpdatePipelineStage,\n RawAggregateCommand,\n RawDeleteManyCommand,\n RawDeleteOneCommand,\n RawFindOneAndDeleteCommand,\n RawFindOneAndUpdateCommand,\n RawInsertManyCommand,\n RawInsertOneCommand,\n RawUpdateManyCommand,\n RawUpdateOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { type } from 'arktype';\n\nconst IndexKeyDirection = type('1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\"');\nconst IndexKeyJson = type({ field: 'string', direction: IndexKeyDirection });\n\nconst CreateIndexJson = type({\n kind: '\"createIndex\"',\n collection: 'string',\n keys: IndexKeyJson.array().atLeastLength(1),\n 'unique?': 'boolean',\n 'sparse?': 'boolean',\n 'expireAfterSeconds?': 'number',\n 'partialFilterExpression?': 'Record<string, unknown>',\n 'name?': 'string',\n 'wildcardProjection?': 'Record<string, unknown>',\n 'collation?': 'Record<string, unknown>',\n 'weights?': 'Record<string, unknown>',\n 'default_language?': 'string',\n 'language_override?': 'string',\n});\n\nconst DropIndexJson = type({\n kind: '\"dropIndex\"',\n collection: 'string',\n name: 'string',\n});\n\nconst CreateCollectionJson = type({\n kind: '\"createCollection\"',\n collection: 'string',\n 'validator?': 'Record<string, unknown>',\n 'validationLevel?': '\"strict\" | \"moderate\"',\n 'validationAction?': '\"error\" | \"warn\"',\n 'capped?': 'boolean',\n 'size?': 'number',\n 'max?': 'number',\n 'timeseries?': 'Record<string, unknown>',\n 'collation?': 'Record<string, unknown>',\n 'changeStreamPreAndPostImages?': 'Record<string, unknown>',\n 'clusteredIndex?': 'Record<string, unknown>',\n});\n\nconst DropCollectionJson = type({\n kind: '\"dropCollection\"',\n collection: 'string',\n});\n\nconst CollModJson = type({\n kind: '\"collMod\"',\n collection: 'string',\n 'validator?': 'Record<string, unknown>',\n 'validationLevel?': '\"strict\" | \"moderate\"',\n 'validationAction?': '\"error\" | \"warn\"',\n 'changeStreamPreAndPostImages?': 'Record<string, unknown>',\n});\n\nconst ListIndexesJson = type({\n kind: '\"listIndexes\"',\n collection: 'string',\n});\n\nconst ListCollectionsJson = type({\n kind: '\"listCollections\"',\n});\n\nconst FieldFilterJson = type({\n kind: '\"field\"',\n field: 'string',\n op: 'string',\n value: 'unknown',\n});\n\nconst ExistsFilterJson = type({\n kind: '\"exists\"',\n field: 'string',\n exists: 'boolean',\n});\n\n// ============================================================================\n// DML command schemas\n// ============================================================================\n\nconst RawInsertOneJson = type({\n kind: '\"rawInsertOne\"',\n collection: 'string',\n document: 'Record<string, unknown>',\n});\n\nconst RawInsertManyJson = type({\n kind: '\"rawInsertMany\"',\n collection: 'string',\n documents: 'Record<string, unknown>[]',\n});\n\nconst RawUpdateOneJson = type({\n kind: '\"rawUpdateOne\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n update: 'Record<string, unknown> | Record<string, unknown>[]',\n});\n\nconst RawUpdateManyJson = type({\n kind: '\"rawUpdateMany\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n update: 'Record<string, unknown> | Record<string, unknown>[]',\n});\n\nconst RawDeleteOneJson = type({\n kind: '\"rawDeleteOne\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n});\n\nconst RawDeleteManyJson = type({\n kind: '\"rawDeleteMany\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n});\n\nconst RawAggregateJson = type({\n kind: '\"rawAggregate\"',\n collection: 'string',\n pipeline: 'Record<string, unknown>[]',\n});\n\nconst RawFindOneAndUpdateJson = type({\n kind: '\"rawFindOneAndUpdate\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n update: 'Record<string, unknown> | Record<string, unknown>[]',\n upsert: 'boolean',\n});\n\nconst RawFindOneAndDeleteJson = type({\n kind: '\"rawFindOneAndDelete\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n});\n\nconst TypedAggregateJson = type({\n kind: '\"aggregate\"',\n collection: 'string',\n pipeline: 'Record<string, unknown>[]',\n});\n\nconst PlanMetaJson = type({\n target: 'string',\n storageHash: 'string',\n lane: 'string',\n 'targetFamily?': 'string',\n 'profileHash?': 'string',\n 'annotations?': 'Record<string, unknown>',\n});\n\nconst QueryPlanJson = type({\n collection: 'string',\n command: 'Record<string, unknown>',\n meta: PlanMetaJson,\n});\n\n// ============================================================================\n// DDL check/step schemas\n// ============================================================================\n\nconst CheckJson = type({\n description: 'string',\n source: 'Record<string, unknown>',\n filter: 'Record<string, unknown>',\n expect: '\"exists\" | \"notExists\"',\n});\n\nconst StepJson = type({\n description: 'string',\n command: 'Record<string, unknown>',\n});\n\nconst DdlOperationJson = type({\n id: 'string',\n label: 'string',\n operationClass: '\"additive\" | \"widening\" | \"destructive\"',\n precheck: 'Record<string, unknown>[]',\n execute: 'Record<string, unknown>[]',\n postcheck: 'Record<string, unknown>[]',\n});\n\nconst DataTransformCheckJson = type({\n description: 'string',\n source: 'Record<string, unknown>',\n filter: 'Record<string, unknown>',\n expect: '\"exists\" | \"notExists\"',\n});\n\nconst DataTransformOperationJson = type({\n id: 'string',\n label: 'string',\n operationClass: '\"data\"',\n name: 'string',\n precheck: 'Record<string, unknown>[]',\n run: 'Record<string, unknown>[]',\n postcheck: 'Record<string, unknown>[]',\n});\n\nfunction validate<T>(schema: { assert: (data: unknown) => T }, data: unknown, context: string): T {\n try {\n return schema.assert(stripUndefinedDeep(data));\n } catch (error) {\n /* v8 ignore start -- assertion libraries always throw Error instances */\n const message = error instanceof Error ? error.message : String(error);\n /* v8 ignore stop */\n throw new Error(`Invalid ${context}: ${message}`);\n }\n}\n\n/**\n * Strip `undefined`-valued properties before they reach arktype's optional-key\n * assertions.\n *\n * Op IRs (e.g. `CreateCollectionCommand`) assign every optional field on\n * every instance — fields the caller did not provide land as\n * `undefined`-valued properties. arktype treats `{ foo?: 'boolean' }` as\n * \"key may be absent, but if present must be boolean\", so the bare instance\n * fails validation when it crosses the deserialize boundary in-process\n * (no JSON round-trip happens between planner → runner). This helper\n * recovers the JSON-round-tripped shape (undefined keys absent) without\n * forcing every caller to round-trip.\n *\n * Returns the original value reference whenever no change is needed.\n * That preserves prototype-bound payload values such as BSON wrappers\n * (`ObjectId`, `Decimal128`, `Binary`, …) which embed no `undefined`\n * own-enumerable properties and therefore never trigger a rebuild.\n * Top-level op IRs (class instances with `undefined` optional fields)\n * still get flattened to plain records as required by arktype.\n */\nfunction stripUndefinedDeep(value: unknown): unknown {\n if (Array.isArray(value)) {\n let changed = false;\n const next = value.map((item) => {\n const stripped = stripUndefinedDeep(item);\n if (stripped !== item) changed = true;\n return stripped;\n });\n return changed ? next : value;\n }\n if (value === null || typeof value !== 'object') {\n return value;\n }\n const entries = Object.entries(value as Record<string, unknown>);\n const out: Record<string, unknown> = {};\n let changed = false;\n for (const [key, val] of entries) {\n if (val === undefined) {\n changed = true;\n continue;\n }\n const stripped = stripUndefinedDeep(val);\n if (stripped !== val) changed = true;\n out[key] = stripped;\n }\n return changed ? out : value;\n}\n\nfunction deserializeFilterExpr(json: unknown): MongoFilterExpr {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'field': {\n const data = validate(FieldFilterJson, json, 'field filter');\n return MongoFieldFilter.of(data.field, data.op, data.value as never);\n }\n case 'and': {\n const exprs = record['exprs'];\n if (!Array.isArray(exprs)) throw new Error('Invalid and filter: missing exprs array');\n return MongoAndExpr.of(exprs.map(deserializeFilterExpr));\n }\n case 'or': {\n const exprs = record['exprs'];\n if (!Array.isArray(exprs)) throw new Error('Invalid or filter: missing exprs array');\n return MongoOrExpr.of(exprs.map(deserializeFilterExpr));\n }\n case 'not': {\n const expr = record['expr'];\n if (!expr || typeof expr !== 'object') throw new Error('Invalid not filter: missing expr');\n return new MongoNotExpr(deserializeFilterExpr(expr));\n }\n case 'exists': {\n const data = validate(ExistsFilterJson, json, 'exists filter');\n return new MongoExistsExpr(data.field, data.exists);\n }\n default:\n throw new Error(`Unknown filter expression kind: ${kind}`);\n }\n}\n\n// ============================================================================\n// Pipeline stage deserialization\n// ============================================================================\n\nexport function deserializePipelineStage(json: unknown): MongoPipelineStage {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'match':\n return new MongoMatchStage(deserializeFilterExpr(record['filter']));\n case 'limit':\n return new MongoLimitStage(record['limit'] as number);\n case 'sort':\n return new MongoSortStage(record['sort'] as Record<string, 1 | -1>);\n case 'project':\n return new MongoProjectStage(record['projection'] as Record<string, 0 | 1>);\n case 'addFields':\n return new MongoAddFieldsStage(record['fields'] as Record<string, never>);\n case 'lookup': {\n const opts: {\n from: string;\n as: string;\n localField?: string;\n foreignField?: string;\n pipeline?: ReadonlyArray<MongoPipelineStage>;\n let_?: Record<string, never>;\n } = {\n from: record['from'] as string,\n as: record['as'] as string,\n };\n if (record['localField'] !== undefined) opts.localField = record['localField'] as string;\n if (record['foreignField'] !== undefined)\n opts.foreignField = record['foreignField'] as string;\n if (record['pipeline'] !== undefined)\n opts.pipeline = (record['pipeline'] as unknown[]).map(deserializePipelineStage);\n if (record['let_'] !== undefined) opts.let_ = record['let_'] as Record<string, never>;\n return new MongoLookupStage(opts);\n }\n case 'merge': {\n const opts: {\n into: string | { db: string; coll: string };\n on?: string | ReadonlyArray<string>;\n whenMatched?: string | ReadonlyArray<MongoUpdatePipelineStage>;\n whenNotMatched?: string;\n } = {\n into: record['into'] as string | { db: string; coll: string },\n };\n if (record['on'] !== undefined) opts.on = record['on'] as string | string[];\n if (record['whenMatched'] !== undefined) {\n const wm = record['whenMatched'];\n opts.whenMatched =\n typeof wm === 'string'\n ? wm\n : ((wm as unknown[]).map(deserializePipelineStage) as MongoUpdatePipelineStage[]);\n }\n if (record['whenNotMatched'] !== undefined)\n opts.whenNotMatched = record['whenNotMatched'] as string;\n return new MongoMergeStage(opts);\n }\n default:\n throw new Error(`Unknown pipeline stage kind: ${kind}`);\n }\n}\n\n// ============================================================================\n// DML command deserialization\n// ============================================================================\n\nexport function deserializeDmlCommand(json: unknown): AnyMongoCommand {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'rawInsertOne': {\n const data = validate(RawInsertOneJson, json, 'rawInsertOne command');\n return new RawInsertOneCommand(data.collection, data.document);\n }\n case 'rawInsertMany': {\n const data = validate(RawInsertManyJson, json, 'rawInsertMany command');\n return new RawInsertManyCommand(data.collection, data.documents);\n }\n case 'rawUpdateOne': {\n const data = validate(RawUpdateOneJson, json, 'rawUpdateOne command');\n return new RawUpdateOneCommand(data.collection, data.filter, data.update);\n }\n case 'rawUpdateMany': {\n const data = validate(RawUpdateManyJson, json, 'rawUpdateMany command');\n return new RawUpdateManyCommand(data.collection, data.filter, data.update);\n }\n case 'rawDeleteOne': {\n const data = validate(RawDeleteOneJson, json, 'rawDeleteOne command');\n return new RawDeleteOneCommand(data.collection, data.filter);\n }\n case 'rawDeleteMany': {\n const data = validate(RawDeleteManyJson, json, 'rawDeleteMany command');\n return new RawDeleteManyCommand(data.collection, data.filter);\n }\n case 'rawAggregate': {\n const data = validate(RawAggregateJson, json, 'rawAggregate command');\n return new RawAggregateCommand(data.collection, data.pipeline);\n }\n case 'rawFindOneAndUpdate': {\n const data = validate(RawFindOneAndUpdateJson, json, 'rawFindOneAndUpdate command');\n return new RawFindOneAndUpdateCommand(data.collection, data.filter, data.update, data.upsert);\n }\n case 'rawFindOneAndDelete': {\n const data = validate(RawFindOneAndDeleteJson, json, 'rawFindOneAndDelete command');\n return new RawFindOneAndDeleteCommand(data.collection, data.filter);\n }\n case 'aggregate': {\n const data = validate(TypedAggregateJson, json, 'aggregate command');\n const pipeline = data.pipeline.map(deserializePipelineStage);\n return new AggregateCommand(data.collection, pipeline);\n }\n default:\n throw new Error(`Unknown DML command kind: ${kind}`);\n }\n}\n\n// ============================================================================\n// MongoQueryPlan deserialization\n// ============================================================================\n\nexport function deserializeMongoQueryPlan(json: unknown): MongoQueryPlan {\n const data = validate(QueryPlanJson, json, 'Mongo query plan');\n const command = deserializeDmlCommand(data.command);\n const m = data.meta;\n const meta: PlanMeta = {\n target: m.target,\n storageHash: m.storageHash,\n lane: m.lane,\n ...ifDefined('targetFamily', m.targetFamily),\n ...ifDefined('profileHash', m.profileHash),\n ...ifDefined('annotations', m.annotations),\n };\n return { collection: data.collection, command, meta };\n}\n\n// ============================================================================\n// DDL command deserialization\n// ============================================================================\n\nfunction deserializeDdlCommand(json: unknown): AnyMongoDdlCommand {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'createIndex': {\n const data = validate(CreateIndexJson, json, 'createIndex command');\n return new CreateIndexCommand(data.collection, data.keys, {\n unique: data.unique,\n sparse: data.sparse,\n expireAfterSeconds: data.expireAfterSeconds,\n partialFilterExpression: data.partialFilterExpression,\n name: data.name,\n wildcardProjection: data.wildcardProjection as Record<string, 0 | 1> | undefined,\n collation: data.collation,\n weights: data.weights as Record<string, number> | undefined,\n default_language: data.default_language,\n language_override: data.language_override,\n });\n }\n case 'dropIndex': {\n const data = validate(DropIndexJson, json, 'dropIndex command');\n return new DropIndexCommand(data.collection, data.name);\n }\n case 'createCollection': {\n const data = validate(CreateCollectionJson, json, 'createCollection command');\n return new CreateCollectionCommand(data.collection, {\n validator: data.validator,\n validationLevel: data.validationLevel,\n validationAction: data.validationAction,\n capped: data.capped,\n size: data.size,\n max: data.max,\n timeseries: data.timeseries as CreateCollectionCommand['timeseries'],\n collation: data.collation,\n changeStreamPreAndPostImages: data.changeStreamPreAndPostImages as\n | { enabled: boolean }\n | undefined,\n clusteredIndex: data.clusteredIndex as CreateCollectionCommand['clusteredIndex'],\n });\n }\n case 'dropCollection': {\n const data = validate(DropCollectionJson, json, 'dropCollection command');\n return new DropCollectionCommand(data.collection);\n }\n case 'collMod': {\n const data = validate(CollModJson, json, 'collMod command');\n return new CollModCommand(data.collection, {\n validator: data.validator,\n validationLevel: data.validationLevel,\n validationAction: data.validationAction,\n changeStreamPreAndPostImages: data.changeStreamPreAndPostImages as\n | { enabled: boolean }\n | undefined,\n });\n }\n default:\n throw new Error(`Unknown DDL command kind: ${kind}`);\n }\n}\n\nfunction deserializeInspectionCommand(json: unknown): AnyMongoInspectionCommand {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'listIndexes': {\n const data = validate(ListIndexesJson, json, 'listIndexes command');\n return new ListIndexesCommand(data.collection);\n }\n case 'listCollections': {\n validate(ListCollectionsJson, json, 'listCollections command');\n return new ListCollectionsCommand();\n }\n default:\n throw new Error(`Unknown inspection command kind: ${kind}`);\n }\n}\n\nfunction deserializeCheck(json: unknown): MongoMigrationCheck {\n const data = validate(CheckJson, json, 'migration check');\n return {\n description: data.description,\n source: deserializeInspectionCommand(data.source),\n filter: deserializeFilterExpr(data.filter),\n expect: data.expect,\n };\n}\n\nfunction deserializeStep(json: unknown): MongoMigrationStep {\n const data = validate(StepJson, json, 'migration step');\n return {\n description: data.description,\n command: deserializeDdlCommand(data.command),\n };\n}\n\nfunction isDataTransformJson(json: unknown): boolean {\n return (\n typeof json === 'object' &&\n json !== null &&\n (json as Record<string, unknown>)['operationClass'] === 'data'\n );\n}\n\nfunction deserializeDdlOp(json: unknown): MongoMigrationPlanOperation {\n const data = validate(DdlOperationJson, json, 'migration operation');\n return {\n id: data.id,\n label: data.label,\n operationClass: data.operationClass as MigrationOperationClass,\n precheck: data.precheck.map(deserializeCheck),\n execute: data.execute.map(deserializeStep),\n postcheck: data.postcheck.map(deserializeCheck),\n };\n}\n\nfunction deserializeDataTransformCheck(json: unknown): MongoDataTransformCheck {\n const data = validate(DataTransformCheckJson, json, 'data transform check');\n return {\n description: data.description,\n source: deserializeMongoQueryPlan(data.source),\n filter: deserializeFilterExpr(data.filter),\n expect: data.expect,\n };\n}\n\nfunction deserializeDataTransformOp(json: unknown): MongoDataTransformOperation {\n const data = validate(DataTransformOperationJson, json, 'data transform operation');\n return {\n id: data.id,\n label: data.label,\n operationClass: 'data',\n name: data.name,\n precheck: data.precheck.map(deserializeDataTransformCheck),\n run: data.run.map(deserializeMongoQueryPlan),\n postcheck: data.postcheck.map(deserializeDataTransformCheck),\n };\n}\n\nexport function deserializeMongoOp(json: unknown): AnyMongoMigrationOperation {\n if (isDataTransformJson(json)) {\n return deserializeDataTransformOp(json);\n }\n return deserializeDdlOp(json);\n}\n\nexport function deserializeMongoOps(json: readonly unknown[]): AnyMongoMigrationOperation[] {\n return json.map(deserializeMongoOp);\n}\n\nexport function serializeMongoOps(ops: readonly AnyMongoMigrationOperation[]): string {\n return JSON.stringify(ops, null, 2);\n}\n","/**\n * Mongo migration IR: one concrete `*Call` class per pure factory under\n * `migration-factories.ts`, plus a shared `OpFactoryCallNode` abstract\n * base. Every call class carries the literal arguments its backing\n * factory would receive, computes a human-readable `label` in its\n * constructor, and implements two polymorphic hooks:\n *\n * - `toOp()` — converts the IR node to a runtime\n * `MongoMigrationPlanOperation` by delegating to the matching pure\n * factory in `migration-factories.ts`.\n * - `renderTypeScript()` / `importRequirements()` — inherited from\n * `TsExpression`. Used by `renderCallsToTypeScript` to emit the call\n * as a TypeScript expression inside the scaffolded `migration.ts`.\n *\n * The abstract base and all concrete classes are package-private.\n * External consumers see only the framework-level `OpFactoryCall`\n * interface and the `OpFactoryCall` union.\n */\n\nimport type {\n OpFactoryCall as FrameworkOpFactoryCall,\n MigrationOperationClass,\n} from '@prisma-next/framework-components/control';\nimport type {\n CollModOptions,\n CreateCollectionOptions,\n CreateIndexOptions,\n MongoIndexKey,\n MongoMigrationPlanOperation,\n} from '@prisma-next/mongo-query-ast/control';\nimport type {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\nimport { type ImportRequirement, jsonToTsSource, TsExpression } from '@prisma-next/ts-render';\nimport {\n collMod,\n createCollection,\n createIndex,\n dropCollection,\n dropIndex,\n} from './migration-factories';\n\nexport interface CollModMeta {\n readonly id?: string;\n readonly label?: string;\n readonly operationClass?: MigrationOperationClass;\n}\n\nconst TARGET_MIGRATION_MODULE = '@prisma-next/target-mongo/migration';\n\nabstract class OpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {\n abstract readonly factoryName: string;\n abstract readonly operationClass: MigrationOperationClass;\n abstract readonly label: string;\n abstract toOp(): MongoMigrationPlanOperation;\n\n importRequirements(): readonly ImportRequirement[] {\n return [{ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: this.factoryName }];\n }\n\n protected freeze(): void {\n Object.freeze(this);\n }\n}\n\nfunction formatKeys(keys: ReadonlyArray<MongoIndexKey>): string {\n return keys.map((k) => `${k.field}:${k.direction}`).join(', ');\n}\n\nexport class CreateIndexCall extends OpFactoryCallNode {\n readonly factoryName = 'createIndex' as const;\n readonly operationClass = 'additive' as const;\n readonly collection: string;\n readonly keys: ReadonlyArray<MongoIndexKey>;\n readonly options: CreateIndexOptions | undefined;\n readonly label: string;\n\n constructor(\n collection: string,\n keys: ReadonlyArray<MongoIndexKey>,\n options?: CreateIndexOptions,\n ) {\n super();\n this.collection = collection;\n this.keys = keys;\n this.options = options;\n this.label = `Create index on ${collection} (${formatKeys(keys)})`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return createIndex(this.collection, this.keys, this.options);\n }\n\n renderTypeScript(): string {\n return this.options\n ? `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)}, ${jsonToTsSource(this.options)})`\n : `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;\n }\n}\n\nexport class DropIndexCall extends OpFactoryCallNode {\n readonly factoryName = 'dropIndex' as const;\n readonly operationClass = 'destructive' as const;\n readonly collection: string;\n readonly keys: ReadonlyArray<MongoIndexKey>;\n readonly label: string;\n\n constructor(collection: string, keys: ReadonlyArray<MongoIndexKey>) {\n super();\n this.collection = collection;\n this.keys = keys;\n this.label = `Drop index on ${collection} (${formatKeys(keys)})`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return dropIndex(this.collection, this.keys);\n }\n\n renderTypeScript(): string {\n return `dropIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;\n }\n}\n\nexport class CreateCollectionCall extends OpFactoryCallNode {\n readonly factoryName = 'createCollection' as const;\n readonly operationClass = 'additive' as const;\n readonly collection: string;\n readonly options: CreateCollectionOptions | undefined;\n readonly label: string;\n\n constructor(collection: string, options?: CreateCollectionOptions) {\n super();\n this.collection = collection;\n this.options = options;\n this.label = `Create collection ${collection}`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return createCollection(this.collection, this.options);\n }\n\n renderTypeScript(): string {\n return this.options\n ? `createCollection(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})`\n : `createCollection(${jsonToTsSource(this.collection)})`;\n }\n}\n\nexport class DropCollectionCall extends OpFactoryCallNode {\n readonly factoryName = 'dropCollection' as const;\n readonly operationClass = 'destructive' as const;\n readonly collection: string;\n readonly label: string;\n\n constructor(collection: string) {\n super();\n this.collection = collection;\n this.label = `Drop collection ${collection}`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return dropCollection(this.collection);\n }\n\n renderTypeScript(): string {\n return `dropCollection(${jsonToTsSource(this.collection)})`;\n }\n}\n\nexport class CollModCall extends OpFactoryCallNode {\n readonly factoryName = 'collMod' as const;\n readonly collection: string;\n readonly options: CollModOptions;\n readonly meta: CollModMeta | undefined;\n readonly operationClass: MigrationOperationClass;\n readonly label: string;\n\n constructor(collection: string, options: CollModOptions, meta?: CollModMeta) {\n super();\n this.collection = collection;\n this.options = options;\n this.meta = meta;\n this.operationClass = meta?.operationClass ?? 'destructive';\n this.label = meta?.label ?? `Modify collection ${collection}`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return collMod(this.collection, this.options, this.meta);\n }\n\n renderTypeScript(): string {\n return this.meta\n ? `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)}, ${jsonToTsSource(this.meta)})`\n : `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})`;\n }\n}\n\nexport type OpFactoryCall =\n | CreateIndexCall\n | DropIndexCall\n | CreateCollectionCall\n | DropCollectionCall\n | CollModCall;\n\nexport function schemaIndexToCreateIndexOptions(index: MongoSchemaIndex): CreateIndexOptions {\n return {\n unique: index.unique || undefined,\n sparse: index.sparse,\n expireAfterSeconds: index.expireAfterSeconds,\n partialFilterExpression: index.partialFilterExpression,\n wildcardProjection: index.wildcardProjection,\n collation: index.collation,\n weights: index.weights,\n default_language: index.default_language,\n language_override: index.language_override,\n };\n}\n\nexport function schemaCollectionToCreateCollectionOptions(\n coll: MongoSchemaCollection,\n): CreateCollectionOptions | undefined {\n const opts: MongoSchemaCollectionOptions | undefined = coll.options;\n const validator: MongoSchemaValidator | undefined = coll.validator;\n if (!opts && !validator) return undefined;\n return {\n capped: opts?.capped ? true : undefined,\n size: opts?.capped?.size,\n max: opts?.capped?.max,\n timeseries: opts?.timeseries,\n collation: opts?.collation,\n clusteredIndex: opts?.clusteredIndex\n ? {\n key: { _id: 1 } as Record<string, number>,\n unique: true as boolean,\n ...(opts.clusteredIndex.name != null ? { name: opts.clusteredIndex.name } : {}),\n }\n : undefined,\n validator: validator ? { $jsonSchema: validator.jsonSchema } : undefined,\n validationLevel: validator?.validationLevel,\n validationAction: validator?.validationAction,\n changeStreamPreAndPostImages: opts?.changeStreamPreAndPostImages,\n };\n}\n","import type { MongoMigrationPlanOperation } from '@prisma-next/mongo-query-ast/control';\nimport type { OpFactoryCall } from './op-factory-call';\n\nexport function renderOps(calls: ReadonlyArray<OpFactoryCall>): MongoMigrationPlanOperation[] {\n return calls.map((call) => call.toOp());\n}\n","import { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';\nimport { type ImportRequirement, jsonToTsSource, renderImports } from '@prisma-next/ts-render';\nimport type { OpFactoryCall } from './op-factory-call';\n\nexport interface RenderMigrationMeta {\n readonly from: string | null;\n readonly to: string;\n readonly labels?: readonly string[];\n}\n\n/**\n * Always-present base imports for the rendered scaffold:\n *\n * - `Migration` from `@prisma-next/family-mongo/migration` — the\n * user-facing Mongo `Migration` base; subclasses don't need to\n * redeclare `targetId` or thread family/target generics.\n * - `MigrationCLI` from `@prisma-next/cli/migration-cli` — the\n * migration-file CLI entrypoint that loads `prisma-next.config.ts`,\n * assembles a `ControlStack`, and instantiates the migration class.\n * The migration file owns this dependency directly: pulling CLI\n * machinery in at script run time is acceptable because the script's\n * whole purpose is to be invoked from the project that owns the\n * config. (Mirrors the postgres facade pattern; pulling `MigrationCLI`\n * into `@prisma-next/family-mongo/migration` so a Mongo migration only\n * needs one import is tracked separately as a follow-up.)\n */\nconst BASE_IMPORTS: readonly ImportRequirement[] = [\n { moduleSpecifier: '@prisma-next/family-mongo/migration', symbol: 'Migration' },\n { moduleSpecifier: '@prisma-next/cli/migration-cli', symbol: 'MigrationCLI' },\n];\n\n/**\n * Render a list of Mongo `OpFactoryCall`s as a `migration.ts`\n * source string. The result is shebanged, extends the user-facing\n * `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and\n * implements the abstract `operations` and `describe` members. `meta` is\n * always rendered — `describe()` is part of the `Migration` contract, so\n * even an empty stub must satisfy it; callers pass `from: null` for a\n * baseline `migration-new` scaffold (and a real `to` hash either way).\n *\n * The walk is polymorphic: each call node contributes its own\n * `renderTypeScript()` expression and declares its own\n * `importRequirements()`. The top-level renderer aggregates imports\n * across all nodes and emits one `import { … } from \"…\"` line per module.\n * The `Migration` and `MigrationCLI` imports are always emitted — they're\n * structural to the rendered scaffold (extends `Migration`, calls\n * `MigrationCLI.run`), not driven by any node.\n */\nexport function renderCallsToTypeScript(\n calls: ReadonlyArray<OpFactoryCall>,\n meta: RenderMigrationMeta,\n): string {\n const imports = buildImports(calls);\n const operationsBody = calls.map((c) => c.renderTypeScript()).join(',\\n');\n\n return [\n shebangLineFor(detectScaffoldRuntime()),\n imports,\n '',\n 'class M extends Migration {',\n buildDescribeMethod(meta),\n ' override get operations() {',\n ' return [',\n indent(operationsBody, 6),\n ' ];',\n ' }',\n '}',\n '',\n 'export default M;',\n 'MigrationCLI.run(import.meta.url, M);',\n '',\n ].join('\\n');\n}\n\nfunction buildImports(calls: ReadonlyArray<OpFactoryCall>): string {\n const requirements: ImportRequirement[] = [...BASE_IMPORTS];\n for (const call of calls) {\n for (const req of call.importRequirements()) {\n requirements.push(req);\n }\n }\n return renderImports(requirements);\n}\n\nfunction buildDescribeMethod(meta: RenderMigrationMeta): string {\n const lines: string[] = [];\n lines.push(' override describe() {');\n lines.push(' return {');\n lines.push(` from: ${JSON.stringify(meta.from)},`);\n lines.push(` to: ${JSON.stringify(meta.to)},`);\n if (meta.labels && meta.labels.length > 0) {\n lines.push(` labels: ${jsonToTsSource(meta.labels)},`);\n }\n lines.push(' };');\n lines.push(' }');\n lines.push('');\n return lines.join('\\n');\n}\n\nfunction indent(text: string, spaces: number): string {\n const pad = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : line))\n .join('\\n');\n}\n","import type { MigrationPlanWithAuthoringSurface } from '@prisma-next/framework-components/control';\nimport { Migration, type MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport type { AnyMongoMigrationOperation } from '@prisma-next/mongo-query-ast/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { OpFactoryCall } from './op-factory-call';\nimport { renderOps } from './render-ops';\nimport { renderCallsToTypeScript } from './render-typescript';\n\n/**\n * Planner-produced Mongo migration, returned by `MongoMigrationPlanner.plan(...)`\n * and `MongoMigrationPlanner.emptyMigration(...)`.\n *\n * Unlike user-authored migrations (which extend `MongoMigration` from\n * `@prisma-next/family-mongo/migration`), this class lives inside the target\n * and holds the richer authoring IR (`OpFactoryCall[]`) needed to render\n * itself back to TypeScript source. It implements\n * `MigrationPlanWithAuthoringSurface` so that the CLI can uniformly ask any\n * planner result to serialize itself to a `migration.ts`.\n *\n * Extends the framework `Migration` base class directly (not\n * `MongoMigration`) because `MongoMigration` lives in `@prisma-next/family-mongo`,\n * which depends on this package — extending it here would create a dependency\n * cycle.\n */\nexport class PlannerProducedMongoMigration\n extends Migration<AnyMongoMigrationOperation>\n implements MigrationPlanWithAuthoringSurface\n{\n readonly targetId = 'mongo' as const;\n\n constructor(\n private readonly calls: readonly OpFactoryCall[],\n private readonly meta: MigrationMeta,\n ) {\n super();\n }\n\n override get operations(): readonly AnyMongoMigrationOperation[] {\n return renderOps(this.calls);\n }\n\n override describe(): MigrationMeta {\n return this.meta;\n }\n\n renderTypeScript(): string {\n return renderCallsToTypeScript(this.calls, {\n from: this.meta.from,\n to: this.meta.to,\n ...ifDefined('labels', this.meta.labels),\n });\n }\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationOperationClass,\n MigrationOperationPolicy,\n MigrationPlanner,\n MigrationPlannerConflict,\n MigrationPlannerResult,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaIR,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\nimport { canonicalize, deepEqual } from '@prisma-next/mongo-schema-ir';\nimport { contractToMongoSchemaIR } from './contract-to-schema';\nimport type { OpFactoryCall } from './op-factory-call';\nimport {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n schemaCollectionToCreateCollectionOptions,\n schemaIndexToCreateIndexOptions,\n} from './op-factory-call';\nimport { PlannerProducedMongoMigration } from './planner-produced-migration';\n\nfunction buildIndexLookupKey(index: MongoSchemaIndex): string {\n const keys = index.keys.map((k) => `${k.field}:${k.direction}`).join(',');\n const opts = [\n index.unique ? 'unique' : '',\n index.sparse ? 'sparse' : '',\n index.expireAfterSeconds != null ? `ttl:${index.expireAfterSeconds}` : '',\n index.partialFilterExpression ? `pfe:${canonicalize(index.partialFilterExpression)}` : '',\n index.wildcardProjection ? `wp:${canonicalize(index.wildcardProjection)}` : '',\n index.collation ? `col:${canonicalize(index.collation)}` : '',\n index.weights ? `wt:${canonicalize(index.weights)}` : '',\n index.default_language ? `dl:${index.default_language}` : '',\n index.language_override ? `lo:${index.language_override}` : '',\n ]\n .filter(Boolean)\n .join(';');\n return opts ? `${keys}|${opts}` : keys;\n}\n\nfunction validatorsEqual(\n a: MongoSchemaValidator | undefined,\n b: MongoSchemaValidator | undefined,\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return (\n a.validationLevel === b.validationLevel &&\n a.validationAction === b.validationAction &&\n canonicalize(a.jsonSchema) === canonicalize(b.jsonSchema)\n );\n}\n\nfunction classifyValidatorUpdate(\n origin: MongoSchemaValidator,\n dest: MongoSchemaValidator,\n): 'widening' | 'destructive' {\n let hasDestructive = false;\n\n if (canonicalize(origin.jsonSchema) !== canonicalize(dest.jsonSchema)) {\n hasDestructive = true;\n }\n\n if (origin.validationAction !== dest.validationAction) {\n if (dest.validationAction === 'error') hasDestructive = true;\n }\n\n if (origin.validationLevel !== dest.validationLevel) {\n if (dest.validationLevel === 'strict') hasDestructive = true;\n }\n\n return hasDestructive ? 'destructive' : 'widening';\n}\n\nfunction hasImmutableOptionChange(\n origin: MongoSchemaCollectionOptions | undefined,\n dest: MongoSchemaCollectionOptions | undefined,\n): string | undefined {\n if (canonicalize(origin?.capped) !== canonicalize(dest?.capped)) return 'capped';\n if (canonicalize(origin?.timeseries) !== canonicalize(dest?.timeseries)) return 'timeseries';\n if (canonicalize(origin?.collation) !== canonicalize(dest?.collation)) return 'collation';\n if (canonicalize(origin?.clusteredIndex) !== canonicalize(dest?.clusteredIndex))\n return 'clusteredIndex';\n return undefined;\n}\n\nfunction collectionHasOptions(coll: MongoSchemaCollection): boolean {\n return !!(coll.options || coll.validator);\n}\n\nexport type PlanCallsResult =\n | { readonly kind: 'success'; readonly calls: OpFactoryCall[] }\n | { readonly kind: 'failure'; readonly conflicts: MigrationPlannerConflict[] };\n\nexport class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'> {\n planCalls(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;\n }): PlanCallsResult {\n const contract = options.contract as MongoContract;\n const originIR = options.schema as MongoSchemaIR;\n const destinationIR = contractToMongoSchemaIR(contract);\n\n const collCreates: OpFactoryCall[] = [];\n const drops: OpFactoryCall[] = [];\n const creates: OpFactoryCall[] = [];\n const validatorOps: OpFactoryCall[] = [];\n const mutableOptionOps: OpFactoryCall[] = [];\n const collDrops: OpFactoryCall[] = [];\n const conflicts: MigrationPlannerConflict[] = [];\n\n const allCollectionNames = new Set([\n ...originIR.collectionNames,\n ...destinationIR.collectionNames,\n ]);\n\n for (const collName of [...allCollectionNames].sort()) {\n const originColl = originIR.collection(collName);\n const destColl = destinationIR.collection(collName);\n\n if (!originColl) {\n // Provision contract-declared collections that are absent from\n // the live database. MongoDB lazily materialises a collection\n // on first write, so subsequent `createIndex` calls in the same\n // plan would create the collection for us implicitly — but the\n // schema verifier treats an unmaterialised contract collection\n // as a `missing_table` issue, so a plan that lacks both options\n // and indexes (e.g. a plain `users` collection from the init\n // scaffold) ends up provisioning nothing and failing verify.\n // The planner therefore emits an explicit createCollection for\n // any contract collection that has options/validator OR no\n // indexes to ride along on. Collections that have indexes\n // continue to rely on createIndex for materialisation, keeping\n // existing plans byte-stable.\n if (destColl && (collectionHasOptions(destColl) || destColl.indexes.length === 0)) {\n const opts = collectionHasOptions(destColl)\n ? schemaCollectionToCreateCollectionOptions(destColl)\n : undefined;\n collCreates.push(new CreateCollectionCall(collName, opts));\n }\n } else if (!destColl) {\n collDrops.push(new DropCollectionCall(collName));\n } else {\n const immutableChange = hasImmutableOptionChange(originColl.options, destColl.options);\n if (immutableChange) {\n conflicts.push({\n kind: 'policy-violation',\n summary: `Cannot change immutable collection option '${immutableChange}' on ${collName}`,\n why: `MongoDB does not support modifying the '${immutableChange}' option after collection creation`,\n });\n }\n\n const mutableCall = planMutableOptionsDiffCall(\n collName,\n originColl.options,\n destColl.options,\n );\n if (mutableCall) mutableOptionOps.push(mutableCall);\n\n const validatorCall = planValidatorDiffCall(\n collName,\n originColl.validator,\n destColl.validator,\n );\n if (validatorCall) validatorOps.push(validatorCall);\n }\n\n const originLookup = new Map<string, MongoSchemaIndex>();\n if (originColl) {\n for (const idx of originColl.indexes) {\n originLookup.set(buildIndexLookupKey(idx), idx);\n }\n }\n\n const destLookup = new Map<string, MongoSchemaIndex>();\n if (destColl) {\n for (const idx of destColl.indexes) {\n destLookup.set(buildIndexLookupKey(idx), idx);\n }\n }\n\n for (const [lookupKey, idx] of originLookup) {\n if (!destLookup.has(lookupKey)) {\n drops.push(new DropIndexCall(collName, idx.keys));\n }\n }\n\n for (const [lookupKey, idx] of destLookup) {\n if (!originLookup.has(lookupKey)) {\n creates.push(\n new CreateIndexCall(collName, idx.keys, schemaIndexToCreateIndexOptions(idx)),\n );\n }\n }\n }\n\n if (conflicts.length > 0) {\n return { kind: 'failure', conflicts };\n }\n\n const allCalls = [\n ...collCreates,\n ...drops,\n ...creates,\n ...validatorOps,\n ...mutableOptionOps,\n ...collDrops,\n ];\n\n for (const call of allCalls) {\n if (!options.policy.allowedOperationClasses.includes(call.operationClass)) {\n conflicts.push({\n kind: 'policy-violation',\n summary: `${call.operationClass} operation disallowed: ${call.label}`,\n why: `Policy does not allow '${call.operationClass}' operations`,\n });\n }\n }\n\n if (conflicts.length > 0) {\n return { kind: 'failure', conflicts };\n }\n\n return { kind: 'success', calls: allCalls };\n }\n\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n /**\n * The \"from\" contract (state the planner assumes the database starts at),\n * or `null` for reconciliation flows. Used to populate `describe().from`\n * on the produced plan as `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract | null;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;\n }): MigrationPlannerResult {\n const contract = options.contract as MongoContract;\n const result = this.planCalls(options);\n if (result.kind === 'failure') return result;\n return {\n kind: 'success',\n plan: new PlannerProducedMongoMigration(result.calls, {\n from: options.fromContract?.storage.storageHash ?? null,\n to: contract.storage.storageHash,\n }),\n };\n }\n\n /**\n * Produce an empty `migration.ts` authoring surface for `migration new`.\n *\n * The \"empty migration\" is a `PlannerProducedMongoMigration` with no\n * operations; `renderTypeScript()` emits a stub class with the correct\n * `from`/`to` metadata that the user then fills in with operations. The\n * contract path on the context is unused — Mongo's emitted source does\n * not import from the generated contract `.d.ts`.\n */\n emptyMigration(context: MigrationScaffoldContext): MigrationPlanWithAuthoringSurface {\n return new PlannerProducedMongoMigration([], {\n from: context.fromHash,\n to: context.toHash,\n });\n }\n}\n\nfunction planValidatorDiffCall(\n collName: string,\n originValidator: MongoSchemaValidator | undefined,\n destValidator: MongoSchemaValidator | undefined,\n): OpFactoryCall | undefined {\n if (validatorsEqual(originValidator, destValidator)) return undefined;\n\n if (destValidator) {\n const operationClass: MigrationOperationClass = originValidator\n ? classifyValidatorUpdate(originValidator, destValidator)\n : 'destructive';\n return new CollModCall(\n collName,\n {\n validator: { $jsonSchema: destValidator.jsonSchema },\n validationLevel: destValidator.validationLevel,\n validationAction: destValidator.validationAction,\n },\n {\n id: `validator.${collName}.${originValidator ? 'update' : 'add'}`,\n label: `${originValidator ? 'Update' : 'Add'} validator on ${collName}`,\n operationClass,\n },\n );\n }\n\n return new CollModCall(\n collName,\n {\n validator: {},\n validationLevel: 'strict',\n validationAction: 'error',\n },\n {\n id: `validator.${collName}.remove`,\n label: `Remove validator on ${collName}`,\n operationClass: 'widening',\n },\n );\n}\n\nfunction planMutableOptionsDiffCall(\n collName: string,\n origin: MongoSchemaCollectionOptions | undefined,\n dest: MongoSchemaCollectionOptions | undefined,\n): OpFactoryCall | undefined {\n const originCSPPI = origin?.changeStreamPreAndPostImages;\n const destCSPPI = dest?.changeStreamPreAndPostImages;\n if (deepEqual(originCSPPI, destCSPPI)) return undefined;\n\n const desiredCSPPI = destCSPPI ?? { enabled: false };\n return new CollModCall(\n collName,\n {\n changeStreamPreAndPostImages: desiredCSPPI,\n },\n {\n id: `options.${collName}.update`,\n label: `Update mutable options on ${collName}`,\n operationClass: desiredCSPPI.enabled ? 'widening' : 'destructive',\n },\n );\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { errorRunnerFailed } from '@prisma-next/errors/execution';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlanOperation,\n MigrationRunnerExecutionChecks,\n MigrationRunnerFailure,\n MigrationRunnerResult,\n OperationContext,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type { MongoAdapter, MongoDriver } from '@prisma-next/mongo-lowering';\nimport type {\n AnyMongoMigrationOperation,\n MongoDataTransformCheck,\n MongoDataTransformOperation,\n MongoDdlCommandVisitor,\n MongoInspectionCommandVisitor,\n MongoMigrationCheck,\n MongoMigrationPlanOperation,\n} from '@prisma-next/mongo-query-ast/control';\nimport type { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { FilterEvaluator } from './filter-evaluator';\nimport { deserializeMongoOps } from './mongo-ops-serializer';\nimport { verifyMongoSchema } from './schema-verify/verify-mongo-schema';\n\nconst READ_ONLY_CHECK_COMMAND_KINDS: ReadonlySet<string> = new Set(['aggregate', 'rawAggregate']);\n\nexport interface MarkerOperations {\n readMarker(): Promise<ContractMarkerRecord | null>;\n initMarker(destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n }): Promise<void>;\n updateMarker(\n expectedFrom: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<boolean>;\n writeLedgerEntry(entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n }): Promise<void>;\n}\n\nexport interface MongoRunnerDependencies {\n readonly commandExecutor: MongoDdlCommandVisitor<Promise<void>>;\n readonly inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>;\n readonly adapter: MongoAdapter;\n readonly driver: MongoDriver;\n readonly markerOps: MarkerOperations;\n readonly introspectSchema: () => Promise<MongoSchemaIR>;\n}\n\nexport interface MongoMigrationRunnerExecuteOptions {\n readonly plan: MigrationPlan;\n readonly destinationContract: MongoContract;\n readonly policy: MigrationOperationPolicy;\n readonly callbacks?: {\n onOperationStart?(op: MigrationPlanOperation): void;\n onOperationComplete?(op: MigrationPlanOperation): void;\n };\n readonly executionChecks?: MigrationRunnerExecutionChecks;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;\n readonly strictVerification?: boolean;\n readonly context?: OperationContext;\n}\n\nfunction runnerFailure(\n code: string,\n summary: string,\n opts?: { why?: string; meta?: Record<string, unknown> },\n): MigrationRunnerResult {\n return notOk<MigrationRunnerFailure>({\n code,\n summary,\n ...opts,\n });\n}\n\nexport class MongoMigrationRunner {\n constructor(private readonly deps: MongoRunnerDependencies) {}\n\n async execute(options: MongoMigrationRunnerExecuteOptions): Promise<MigrationRunnerResult> {\n const { commandExecutor, inspectionExecutor, adapter, driver, markerOps } = this.deps;\n const operations = deserializeMongoOps(options.plan.operations as readonly unknown[]);\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, operations);\n if (policyCheck) return policyCheck;\n\n const existingMarker = await markerOps.readMarker();\n\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (markerCheck) return markerCheck;\n\n const checks = options.executionChecks;\n const runPrechecks = checks?.prechecks !== false;\n const runPostchecks = checks?.postchecks !== false;\n const runIdempotency = checks?.idempotencyChecks !== false;\n\n const filterEvaluator = new FilterEvaluator();\n\n let operationsExecuted = 0;\n\n for (const operation of operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n if (operation.operationClass === 'data') {\n const result = await this.executeDataTransform(\n operation as MongoDataTransformOperation,\n adapter,\n driver,\n filterEvaluator,\n runIdempotency,\n runPrechecks,\n runPostchecks,\n );\n if (result.failure) return result.failure;\n if (result.executed) operationsExecuted += 1;\n continue;\n }\n\n const ddlOp = operation as MongoMigrationPlanOperation;\n\n if (runPostchecks && runIdempotency) {\n const allSatisfied = await this.allChecksSatisfied(\n ddlOp.postcheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (allSatisfied) continue;\n }\n\n if (runPrechecks) {\n const precheckResult = await this.evaluateChecks(\n ddlOp.precheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (!precheckResult) {\n return runnerFailure(\n 'PRECHECK_FAILED',\n `Operation ${operation.id} failed during precheck`,\n { meta: { operationId: operation.id } },\n );\n }\n }\n\n for (const step of ddlOp.execute) {\n await step.command.accept(commandExecutor);\n }\n\n if (runPostchecks) {\n const postcheckResult = await this.evaluateChecks(\n ddlOp.postcheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (!postcheckResult) {\n return runnerFailure(\n 'POSTCHECK_FAILED',\n `Operation ${operation.id} failed during postcheck`,\n { meta: { operationId: operation.id } },\n );\n }\n }\n\n operationsExecuted += 1;\n } finally {\n options.callbacks?.onOperationComplete?.(operation);\n }\n }\n\n const destination = options.plan.destination;\n const profileHash = options.destinationContract.profileHash ?? destination.storageHash;\n\n const incomingInvariants = options.plan.providedInvariants ?? [];\n const existingInvariantSet = new Set(existingMarker?.invariants ?? []);\n const incomingIsSubsetOfExisting = incomingInvariants.every((id) =>\n existingInvariantSet.has(id),\n );\n const markerAlreadyAtDestination =\n existingMarker !== null &&\n existingMarker.storageHash === destination.storageHash &&\n existingMarker.profileHash === profileHash;\n\n // Skip marker/ledger writes (and schema verification) only when the apply\n // is a true no-op: no operations executed, marker already at destination,\n // and every incoming invariant is already in the stored set.\n //\n // Divergence from the SQL runners (postgres/sqlite): those runners gate\n // the no-op skip on `isSelfEdge` (origin === destination) only, so a\n // non-self-edge `db update` that introspects-as-no-op still writes a\n // ledger entry. Mongo skips even those because the runner has no\n // structural distinction between self-edge and re-apply — invariant-\n // aware routing here does not yet differentiate between the two\n // ledger semantics. If the SQL audit-trail behavior should hold for\n // Mongo too, gate this `isNoOp` on a self-edge check (or, conversely,\n // align the SQL runners to skip non-self-edge no-ops uniformly).\n const isNoOp =\n operationsExecuted === 0 && markerAlreadyAtDestination && incomingIsSubsetOfExisting;\n\n if (!isNoOp) {\n const liveSchema = await this.deps.introspectSchema();\n const verifyResult = verifyMongoSchema({\n contract: options.destinationContract,\n schema: liveSchema,\n strict: options.strictVerification ?? true,\n frameworkComponents: options.frameworkComponents,\n ...(options.context ? { context: options.context } : {}),\n });\n if (!verifyResult.ok) {\n return runnerFailure('SCHEMA_VERIFY_FAILED', verifyResult.summary, {\n why: 'The resulting database schema does not satisfy the destination contract.',\n meta: { issues: verifyResult.schema.issues },\n });\n }\n\n if (existingMarker) {\n const updated = await markerOps.updateMarker(existingMarker.storageHash, {\n storageHash: destination.storageHash,\n profileHash,\n invariants: incomingInvariants,\n });\n if (!updated) {\n return runnerFailure(\n 'MARKER_CAS_FAILURE',\n 'Marker was modified by another process during migration execution.',\n {\n meta: {\n expectedStorageHash: existingMarker.storageHash,\n destinationStorageHash: destination.storageHash,\n },\n },\n );\n }\n } else {\n await markerOps.initMarker({\n storageHash: destination.storageHash,\n profileHash,\n invariants: incomingInvariants,\n });\n }\n\n const originHash = existingMarker?.storageHash ?? '';\n await markerOps.writeLedgerEntry({\n edgeId: `${originHash}->${destination.storageHash}`,\n from: originHash,\n to: destination.storageHash,\n });\n }\n\n return ok({ operationsPlanned: operations.length, operationsExecuted });\n }\n\n private async executeDataTransform(\n op: MongoDataTransformOperation,\n adapter: MongoAdapter,\n driver: MongoDriver,\n filterEvaluator: FilterEvaluator,\n runIdempotency: boolean,\n runPrechecks: boolean,\n runPostchecks: boolean,\n ): Promise<{ executed: boolean; failure?: MigrationRunnerResult }> {\n if (runPostchecks && runIdempotency && op.postcheck.length > 0) {\n const allSatisfied = await this.evaluateDataTransformChecks(\n op.postcheck,\n adapter,\n driver,\n filterEvaluator,\n );\n if (allSatisfied) return { executed: false };\n }\n\n if (runPrechecks && op.precheck.length > 0) {\n const passed = await this.evaluateDataTransformChecks(\n op.precheck,\n adapter,\n driver,\n filterEvaluator,\n );\n if (!passed) {\n return {\n executed: false,\n failure: runnerFailure('PRECHECK_FAILED', `Operation ${op.id} failed during precheck`, {\n meta: { operationId: op.id, name: op.name },\n }),\n };\n }\n }\n\n for (const plan of op.run) {\n const wireCommand = await adapter.lower(plan, {});\n for await (const _ of driver.execute(wireCommand)) {\n /* consume */\n }\n }\n\n if (runPostchecks && op.postcheck.length > 0) {\n const passed = await this.evaluateDataTransformChecks(\n op.postcheck,\n adapter,\n driver,\n filterEvaluator,\n );\n if (!passed) {\n return {\n executed: false,\n failure: runnerFailure('POSTCHECK_FAILED', `Operation ${op.id} failed during postcheck`, {\n meta: { operationId: op.id, name: op.name },\n }),\n };\n }\n }\n\n return { executed: true };\n }\n\n private async evaluateDataTransformChecks(\n checks: readonly MongoDataTransformCheck[],\n adapter: MongoAdapter,\n driver: MongoDriver,\n filterEvaluator: FilterEvaluator,\n ): Promise<boolean> {\n for (const check of checks) {\n const commandKind = check.source.command.kind;\n if (!READ_ONLY_CHECK_COMMAND_KINDS.has(commandKind)) {\n throw errorRunnerFailed(\n `Data-transform check rejected: command kind \"${commandKind}\" is not read-only`,\n {\n why: 'Data-transform checks must use aggregate or rawAggregate commands so the pre/postcheck path cannot mutate the database.',\n fix: 'Author the check.source as an aggregate pipeline (or rawAggregate) rather than a DML write command.',\n meta: {\n checkDescription: check.description,\n commandKind,\n collection: check.source.collection,\n },\n },\n );\n }\n const wireCommand = await adapter.lower(check.source, {});\n let matchFound = false;\n for await (const row of driver.execute<Record<string, unknown>>(wireCommand)) {\n if (filterEvaluator.evaluate(check.filter, row)) {\n matchFound = true;\n break;\n }\n }\n const passed = check.expect === 'exists' ? matchFound : !matchFound;\n if (!passed) return false;\n }\n return true;\n }\n\n private async evaluateChecks(\n checks: readonly MongoMigrationCheck[],\n inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>,\n filterEvaluator: FilterEvaluator,\n ): Promise<boolean> {\n for (const check of checks) {\n const documents = await check.source.accept(inspectionExecutor);\n const matchFound = documents.some((doc) =>\n filterEvaluator.evaluate(check.filter, doc as Record<string, unknown>),\n );\n const passed = check.expect === 'exists' ? matchFound : !matchFound;\n if (!passed) return false;\n }\n return true;\n }\n\n private async allChecksSatisfied(\n checks: readonly MongoMigrationCheck[],\n inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>,\n filterEvaluator: FilterEvaluator,\n ): Promise<boolean> {\n if (checks.length === 0) return false;\n return this.evaluateChecks(checks, inspectionExecutor, filterEvaluator);\n }\n\n private enforcePolicyCompatibility(\n policy: MigrationOperationPolicy,\n operations: readonly AnyMongoMigrationOperation[],\n ): MigrationRunnerResult | undefined {\n const allowedClasses = new Set(policy.allowedOperationClasses);\n for (const operation of operations) {\n if (!allowedClasses.has(operation.operationClass)) {\n return runnerFailure(\n 'POLICY_VIOLATION',\n `Operation ${operation.id} has class \"${operation.operationClass}\" which is not allowed by policy.`,\n {\n why: `Policy only allows: ${[...allowedClasses].join(', ')}.`,\n meta: {\n operationId: operation.id,\n operationClass: operation.operationClass,\n },\n },\n );\n }\n }\n return undefined;\n }\n\n private ensureMarkerCompatibility(\n marker: ContractMarkerRecord | null,\n plan: MigrationPlan,\n ): MigrationRunnerResult | undefined {\n const origin = plan.origin ?? null;\n if (!origin) {\n // No origin assertion on the plan — the caller has done its own\n // correctness check (typically `db update` via live-schema\n // introspection) and does not rely on marker continuity.\n return undefined;\n }\n\n if (!marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Missing contract marker: expected origin storage hash ${origin.storageHash}.`,\n { meta: { expectedOriginStorageHash: origin.storageHash } },\n );\n }\n\n if (marker.storageHash !== origin.storageHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`,\n {\n meta: {\n markerStorageHash: marker.storageHash,\n expectedOriginStorageHash: origin.storageHash,\n },\n },\n );\n }\n\n return undefined;\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"control.mjs","names":["record"],"sources":["../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/op-factory-call.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts","../src/core/planner-produced-migration.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts"],"sourcesContent":["import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport type {\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n MongoDdlCommandVisitor,\n MongoIndexKey,\n} from '@prisma-next/mongo-query-ast/control';\n\nfunction formatKeySpec(keys: ReadonlyArray<MongoIndexKey>): string {\n const entries = keys.map((k) => `${JSON.stringify(k.field)}: ${JSON.stringify(k.direction)}`);\n return `{ ${entries.join(', ')} }`;\n}\n\nfunction formatOptions(cmd: CreateIndexCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.unique) parts.push('unique: true');\n if (cmd.sparse) parts.push('sparse: true');\n if (cmd.expireAfterSeconds !== undefined)\n parts.push(`expireAfterSeconds: ${cmd.expireAfterSeconds}`);\n if (cmd.name) parts.push(`name: ${JSON.stringify(cmd.name)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.weights) parts.push(`weights: ${JSON.stringify(cmd.weights)}`);\n if (cmd.default_language) parts.push(`default_language: ${JSON.stringify(cmd.default_language)}`);\n if (cmd.language_override)\n parts.push(`language_override: ${JSON.stringify(cmd.language_override)}`);\n if (cmd.wildcardProjection)\n parts.push(`wildcardProjection: ${JSON.stringify(cmd.wildcardProjection)}`);\n if (cmd.partialFilterExpression)\n parts.push(`partialFilterExpression: ${JSON.stringify(cmd.partialFilterExpression)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nfunction formatCreateCollectionOptions(cmd: CreateCollectionCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.capped) parts.push('capped: true');\n if (cmd.size !== undefined) parts.push(`size: ${cmd.size}`);\n if (cmd.max !== undefined) parts.push(`max: ${cmd.max}`);\n if (cmd.timeseries) parts.push(`timeseries: ${JSON.stringify(cmd.timeseries)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.clusteredIndex) parts.push(`clusteredIndex: ${JSON.stringify(cmd.clusteredIndex)}`);\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction) parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(`changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nclass MongoDdlCommandFormatter implements MongoDdlCommandVisitor<string> {\n createIndex(cmd: CreateIndexCommand): string {\n const keySpec = formatKeySpec(cmd.keys);\n const opts = formatOptions(cmd);\n return opts\n ? `db.${cmd.collection}.createIndex(${keySpec}, ${opts})`\n : `db.${cmd.collection}.createIndex(${keySpec})`;\n }\n\n dropIndex(cmd: DropIndexCommand): string {\n return `db.${cmd.collection}.dropIndex(${JSON.stringify(cmd.name)})`;\n }\n\n createCollection(cmd: CreateCollectionCommand): string {\n const opts = formatCreateCollectionOptions(cmd);\n return opts\n ? `db.createCollection(${JSON.stringify(cmd.collection)}, ${opts})`\n : `db.createCollection(${JSON.stringify(cmd.collection)})`;\n }\n\n dropCollection(cmd: DropCollectionCommand): string {\n return `db.${cmd.collection}.drop()`;\n }\n\n collMod(cmd: CollModCommand): string {\n const parts: string[] = [`collMod: ${JSON.stringify(cmd.collection)}`];\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction)\n parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(\n `changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`,\n );\n return `db.runCommand({ ${parts.join(', ')} })`;\n }\n}\n\nconst formatter = new MongoDdlCommandFormatter();\n\ninterface MongoExecuteStep {\n readonly command: { readonly accept: <R>(visitor: MongoDdlCommandVisitor<R>) => R };\n}\n\nexport function formatMongoOperations(operations: readonly MigrationPlanOperation[]): string[] {\n const statements: string[] = [];\n for (const operation of operations) {\n const candidate = operation as unknown as Record<string, unknown>;\n if (!('execute' in candidate) || !Array.isArray(candidate['execute'])) {\n continue;\n }\n for (const step of candidate['execute'] as MongoExecuteStep[]) {\n if (step.command && typeof step.command.accept === 'function') {\n statements.push(step.command.accept(formatter));\n }\n }\n }\n return statements;\n}\n","import type {\n MongoAndExpr,\n MongoExistsExpr,\n MongoExprFilter,\n MongoFieldFilter,\n MongoFilterExpr,\n MongoFilterVisitor,\n MongoNotExpr,\n MongoOrExpr,\n} from '@prisma-next/mongo-query-ast/control';\nimport { deepEqual } from '@prisma-next/mongo-schema-ir';\nimport type { MongoValue } from '@prisma-next/mongo-value';\n\nfunction getNestedField(doc: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = doc;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n const record = current as Record<string, unknown>;\n if (!Object.hasOwn(record, part)) {\n return undefined;\n }\n current = record[part];\n }\n return current;\n}\n\nfunction evaluateFieldOp(op: string, actual: unknown, expected: MongoValue): boolean {\n switch (op) {\n case '$eq':\n return deepEqual(actual, expected);\n case '$ne':\n return !deepEqual(actual, expected);\n case '$gt':\n return typeof actual === typeof expected && (actual as number) > (expected as number);\n case '$gte':\n return typeof actual === typeof expected && (actual as number) >= (expected as number);\n case '$lt':\n return typeof actual === typeof expected && (actual as number) < (expected as number);\n case '$lte':\n return typeof actual === typeof expected && (actual as number) <= (expected as number);\n case '$in':\n return Array.isArray(expected) && expected.some((v) => deepEqual(actual, v));\n default:\n throw new Error(`Unsupported filter operator in migration check: ${op}`);\n }\n}\n\nexport class FilterEvaluator implements MongoFilterVisitor<boolean> {\n private doc: Record<string, unknown> = {};\n\n evaluate(filter: MongoFilterExpr, doc: Record<string, unknown>): boolean {\n this.doc = doc;\n return filter.accept(this);\n }\n\n field(expr: MongoFieldFilter): boolean {\n const value = getNestedField(this.doc, expr.field);\n return evaluateFieldOp(expr.op, value, expr.value);\n }\n\n and(expr: MongoAndExpr): boolean {\n return expr.exprs.every((child) => child.accept(this));\n }\n\n or(expr: MongoOrExpr): boolean {\n return expr.exprs.some((child) => child.accept(this));\n }\n\n not(expr: MongoNotExpr): boolean {\n return !expr.expr.accept(this);\n }\n\n exists(expr: MongoExistsExpr): boolean {\n const has = getNestedField(this.doc, expr.field) !== undefined;\n return expr.exists ? has : !has;\n }\n\n expr(_expr: MongoExprFilter): boolean {\n throw new Error('Aggregation expression filters are not supported in migration checks');\n }\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport {\n RawAggregateCommand,\n RawFindOneAndUpdateCommand,\n RawInsertOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport { type } from 'arktype';\nimport type { Db, Document, UpdateFilter } from 'mongodb';\n\nconst COLLECTION = '_prisma_migrations';\n\n/**\n * Marker doc shape.\n *\n * Same fields as the SQL marker row but camelCase + Mongo-native types:\n * `Date` is BSON-hydrated, `meta` is a native object (not JSON-stringified),\n * `_id` and any extension fields are tolerated. `invariants?` is optional —\n * absent reads as `[]` (schemaless default); present-but-malformed throws.\n *\n * `space` is required: every marker doc is keyed by its space id (`_id`)\n * and stamped with a matching `space` field for partitioned reads.\n */\nconst MongoMarkerDocSchema = type({\n space: 'string',\n storageHash: 'string',\n profileHash: 'string',\n 'contractJson?': 'unknown | null',\n 'canonicalVersion?': 'number | null',\n 'updatedAt?': 'Date',\n 'appTag?': 'string | null',\n 'meta?': type({ '[string]': 'unknown' }).or('null'),\n 'invariants?': type('string').array(),\n '+': 'delete',\n});\n\nfunction parseMongoMarkerDoc(doc: unknown): ContractMarkerRecord {\n const result = MongoMarkerDocSchema(doc);\n if (result instanceof type.errors) {\n throw new Error(`Invalid marker doc on ${COLLECTION}: ${result.summary}`);\n }\n return {\n storageHash: result.storageHash,\n profileHash: result.profileHash,\n contractJson: result.contractJson ?? null,\n canonicalVersion: result.canonicalVersion ?? null,\n updatedAt: result.updatedAt ?? new Date(),\n appTag: result.appTag ?? null,\n meta: (result.meta as Record<string, unknown> | null) ?? {},\n invariants: result.invariants ?? [],\n };\n}\n\nasync function executeAggregate(db: Db, cmd: RawAggregateCommand): Promise<Document[]> {\n return db\n .collection(cmd.collection)\n .aggregate(cmd.pipeline as Record<string, unknown>[])\n .toArray();\n}\n\nasync function executeInsertOne(db: Db, cmd: RawInsertOneCommand): Promise<void> {\n await db.collection(cmd.collection).insertOne(cmd.document);\n}\n\nasync function executeFindOneAndUpdate(\n db: Db,\n cmd: RawFindOneAndUpdateCommand,\n): Promise<Document | null> {\n // `cmd.update` is `Document | ReadonlyArray<Document>` per the AST. The\n // MongoDB driver's `findOneAndUpdate` accepts the same shape under the\n // type `UpdateFilter<T> | Document[]`. The driver's runtime path handles\n // both forms identically — pipelines (array) and update docs (object).\n // One cast to that union keeps the call single-arm.\n return db\n .collection(cmd.collection)\n .findOneAndUpdate(cmd.filter, cmd.update as UpdateFilter<Document> | Document[], {\n upsert: cmd.upsert,\n });\n}\n\n/**\n * Reads the marker document for the given contract space, or returns\n * `null` if no marker has been written for that space yet. Each space\n * owns one row keyed by `_id: <space>` — see ADR 212 for the per-space\n * mechanism this enables.\n */\nexport async function readMarker(db: Db, space: string): Promise<ContractMarkerRecord | null> {\n const cmd = new RawAggregateCommand(COLLECTION, [\n { $match: { _id: space, space } },\n { $limit: 1 },\n ]);\n const docs = await executeAggregate(db, cmd);\n const doc = docs[0];\n if (!doc) return null;\n return parseMongoMarkerDoc(doc);\n}\n\n/**\n * Reads every marker doc in the collection (one per contract space)\n * and returns them keyed by `space`. Used by the per-space verifier\n * to detect marker-vs-on-disk drift and orphan marker rows. Returns\n * an empty map when no marker docs have been written yet.\n *\n * Marker docs are keyed by `_id: <space>` (string); ledger entries\n * live in the same collection but use a driver-generated `ObjectId`\n * `_id` plus `type: 'ledger'`. The filter selects string-keyed docs\n * with a `space` field, which excludes ledger entries by construction.\n */\nexport async function readAllMarkers(db: Db): Promise<ReadonlyMap<string, ContractMarkerRecord>> {\n const cmd = new RawAggregateCommand(COLLECTION, [\n {\n $match: {\n _id: { $type: 'string' },\n space: { $type: 'string' },\n $expr: { $eq: ['$_id', '$space'] },\n },\n },\n ]);\n const docs = await executeAggregate(db, cmd);\n const out = new Map<string, ContractMarkerRecord>();\n for (const doc of docs) {\n const space = doc['space'];\n /* v8 ignore next -- @preserve type-narrowing guard: the $match stage above filters on `space: { $type: 'string' }`, so this branch is unreachable at runtime. The check exists so the `out.set(space, ...)` call below can accept `string`. */\n if (typeof space !== 'string') continue;\n out.set(space, parseMongoMarkerDoc(doc));\n }\n return out;\n}\n\nexport async function initMarker(\n db: Db,\n space: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n _id: space,\n space,\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n contractJson: null,\n canonicalVersion: null,\n updatedAt: new Date(),\n appTag: null,\n meta: {},\n invariants: destination.invariants ?? [],\n });\n await executeInsertOne(db, cmd);\n}\n\n/**\n * Updates the marker doc for the given space atomically (CAS on\n * `expectedFrom`).\n *\n * `destination.invariants`:\n * - `undefined` → existing field left untouched.\n * - explicit value → merged into the existing field server-side via an\n * aggregation pipeline (`$setUnion + $sortArray`), atomic at the\n * document level. `[]` is a no-op merge.\n */\nexport async function updateMarker(\n db: Db,\n space: string,\n expectedFrom: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n): Promise<boolean> {\n const setBase: Record<string, unknown> = {\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n updatedAt: new Date(),\n };\n // When invariants is supplied, use an aggregation pipeline so the\n // merge runs server-side against the doc's current value (atomic, no\n // read-then-write window). When omitted, a regular update doc keeps\n // the field untouched.\n const update: Document | Document[] =\n destination.invariants === undefined\n ? { $set: setBase }\n : [\n {\n $set: {\n ...setBase,\n invariants: {\n $sortArray: {\n input: { $setUnion: [{ $ifNull: ['$invariants', []] }, destination.invariants] },\n sortBy: 1,\n },\n },\n },\n },\n ];\n const cmd = new RawFindOneAndUpdateCommand(\n COLLECTION,\n { _id: space, space, storageHash: expectedFrom },\n update,\n false,\n );\n const result = await executeFindOneAndUpdate(db, cmd);\n return result !== null;\n}\n\n/**\n * Appends a ledger entry for the given space. Ledger entries co-exist\n * with marker docs in the same collection; marker docs use `_id: <space>`\n * (string), ledger entries use `type: 'ledger'` plus a driver-generated\n * ObjectId. Reads partition the two by filter shape.\n *\n * The same `edgeId` may legitimately recur across different spaces (e.g.\n * a synthetic ∅→head edge on first apply), so the ledger key is\n * `(space, edgeId)` — the doc carries `space` for partitioned reads.\n */\nexport async function writeLedgerEntry(\n db: Db,\n space: string,\n entry: { readonly edgeId: string; readonly from: string; readonly to: string },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n type: 'ledger',\n space,\n edgeId: entry.edgeId,\n from: entry.from,\n to: entry.to,\n appliedAt: new Date(),\n });\n await executeInsertOne(db, cmd);\n}\n","import type { PlanMeta } from '@prisma-next/contract/types';\nimport type { MigrationOperationClass } from '@prisma-next/framework-components/control';\nimport {\n type AnyMongoDdlCommand,\n type AnyMongoInspectionCommand,\n type AnyMongoMigrationOperation,\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n ListCollectionsCommand,\n ListIndexesCommand,\n MongoAndExpr,\n type MongoDataTransformCheck,\n type MongoDataTransformOperation,\n MongoExistsExpr,\n MongoFieldFilter,\n type MongoFilterExpr,\n type MongoMigrationCheck,\n type MongoMigrationPlanOperation,\n type MongoMigrationStep,\n MongoNotExpr,\n MongoOrExpr,\n} from '@prisma-next/mongo-query-ast/control';\nimport {\n AggregateCommand,\n type AnyMongoCommand,\n MongoAddFieldsStage,\n MongoLimitStage,\n MongoLookupStage,\n MongoMatchStage,\n MongoMergeStage,\n type MongoPipelineStage,\n MongoProjectStage,\n type MongoQueryPlan,\n MongoSortStage,\n type MongoUpdatePipelineStage,\n RawAggregateCommand,\n RawDeleteManyCommand,\n RawDeleteOneCommand,\n RawFindOneAndDeleteCommand,\n RawFindOneAndUpdateCommand,\n RawInsertManyCommand,\n RawInsertOneCommand,\n RawUpdateManyCommand,\n RawUpdateOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport { type } from 'arktype';\n\nconst IndexKeyDirection = type('1 | -1 | \"text\" | \"2dsphere\" | \"2d\" | \"hashed\"');\nconst IndexKeyJson = type({ field: 'string', direction: IndexKeyDirection });\n\nconst CreateIndexJson = type({\n kind: '\"createIndex\"',\n collection: 'string',\n keys: IndexKeyJson.array().atLeastLength(1),\n 'unique?': 'boolean',\n 'sparse?': 'boolean',\n 'expireAfterSeconds?': 'number',\n 'partialFilterExpression?': 'Record<string, unknown>',\n 'name?': 'string',\n 'wildcardProjection?': 'Record<string, unknown>',\n 'collation?': 'Record<string, unknown>',\n 'weights?': 'Record<string, unknown>',\n 'default_language?': 'string',\n 'language_override?': 'string',\n});\n\nconst DropIndexJson = type({\n kind: '\"dropIndex\"',\n collection: 'string',\n name: 'string',\n});\n\nconst CreateCollectionJson = type({\n kind: '\"createCollection\"',\n collection: 'string',\n 'validator?': 'Record<string, unknown>',\n 'validationLevel?': '\"strict\" | \"moderate\"',\n 'validationAction?': '\"error\" | \"warn\"',\n 'capped?': 'boolean',\n 'size?': 'number',\n 'max?': 'number',\n 'timeseries?': 'Record<string, unknown>',\n 'collation?': 'Record<string, unknown>',\n 'changeStreamPreAndPostImages?': 'Record<string, unknown>',\n 'clusteredIndex?': 'Record<string, unknown>',\n});\n\nconst DropCollectionJson = type({\n kind: '\"dropCollection\"',\n collection: 'string',\n});\n\nconst CollModJson = type({\n kind: '\"collMod\"',\n collection: 'string',\n 'validator?': 'Record<string, unknown>',\n 'validationLevel?': '\"strict\" | \"moderate\"',\n 'validationAction?': '\"error\" | \"warn\"',\n 'changeStreamPreAndPostImages?': 'Record<string, unknown>',\n});\n\nconst ListIndexesJson = type({\n kind: '\"listIndexes\"',\n collection: 'string',\n});\n\nconst ListCollectionsJson = type({\n kind: '\"listCollections\"',\n});\n\nconst FieldFilterJson = type({\n kind: '\"field\"',\n field: 'string',\n op: 'string',\n value: 'unknown',\n});\n\nconst ExistsFilterJson = type({\n kind: '\"exists\"',\n field: 'string',\n exists: 'boolean',\n});\n\n// ============================================================================\n// DML command schemas\n// ============================================================================\n\nconst RawInsertOneJson = type({\n kind: '\"rawInsertOne\"',\n collection: 'string',\n document: 'Record<string, unknown>',\n});\n\nconst RawInsertManyJson = type({\n kind: '\"rawInsertMany\"',\n collection: 'string',\n documents: 'Record<string, unknown>[]',\n});\n\nconst RawUpdateOneJson = type({\n kind: '\"rawUpdateOne\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n update: 'Record<string, unknown> | Record<string, unknown>[]',\n});\n\nconst RawUpdateManyJson = type({\n kind: '\"rawUpdateMany\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n update: 'Record<string, unknown> | Record<string, unknown>[]',\n});\n\nconst RawDeleteOneJson = type({\n kind: '\"rawDeleteOne\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n});\n\nconst RawDeleteManyJson = type({\n kind: '\"rawDeleteMany\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n});\n\nconst RawAggregateJson = type({\n kind: '\"rawAggregate\"',\n collection: 'string',\n pipeline: 'Record<string, unknown>[]',\n});\n\nconst RawFindOneAndUpdateJson = type({\n kind: '\"rawFindOneAndUpdate\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n update: 'Record<string, unknown> | Record<string, unknown>[]',\n upsert: 'boolean',\n});\n\nconst RawFindOneAndDeleteJson = type({\n kind: '\"rawFindOneAndDelete\"',\n collection: 'string',\n filter: 'Record<string, unknown>',\n});\n\nconst TypedAggregateJson = type({\n kind: '\"aggregate\"',\n collection: 'string',\n pipeline: 'Record<string, unknown>[]',\n});\n\nconst PlanMetaJson = type({\n target: 'string',\n storageHash: 'string',\n lane: 'string',\n 'targetFamily?': 'string',\n 'profileHash?': 'string',\n 'annotations?': 'Record<string, unknown>',\n});\n\nconst QueryPlanJson = type({\n collection: 'string',\n command: 'Record<string, unknown>',\n meta: PlanMetaJson,\n});\n\n// ============================================================================\n// DDL check/step schemas\n// ============================================================================\n\nconst CheckJson = type({\n description: 'string',\n source: 'Record<string, unknown>',\n filter: 'Record<string, unknown>',\n expect: '\"exists\" | \"notExists\"',\n});\n\nconst StepJson = type({\n description: 'string',\n command: 'Record<string, unknown>',\n});\n\nconst DdlOperationJson = type({\n id: 'string',\n label: 'string',\n operationClass: '\"additive\" | \"widening\" | \"destructive\"',\n precheck: 'Record<string, unknown>[]',\n execute: 'Record<string, unknown>[]',\n postcheck: 'Record<string, unknown>[]',\n});\n\nconst DataTransformCheckJson = type({\n description: 'string',\n source: 'Record<string, unknown>',\n filter: 'Record<string, unknown>',\n expect: '\"exists\" | \"notExists\"',\n});\n\nconst DataTransformOperationJson = type({\n id: 'string',\n label: 'string',\n operationClass: '\"data\"',\n name: 'string',\n precheck: 'Record<string, unknown>[]',\n run: 'Record<string, unknown>[]',\n postcheck: 'Record<string, unknown>[]',\n});\n\nfunction validate<T>(schema: { assert: (data: unknown) => T }, data: unknown, context: string): T {\n try {\n return schema.assert(stripUndefinedDeep(data));\n } catch (error) {\n /* v8 ignore start -- assertion libraries always throw Error instances */\n const message = error instanceof Error ? error.message : String(error);\n /* v8 ignore stop */\n throw new Error(`Invalid ${context}: ${message}`);\n }\n}\n\n/**\n * Strip `undefined`-valued properties before they reach arktype's optional-key\n * assertions.\n *\n * Op IRs (e.g. `CreateCollectionCommand`) assign every optional field on\n * every instance — fields the caller did not provide land as\n * `undefined`-valued properties. arktype treats `{ foo?: 'boolean' }` as\n * \"key may be absent, but if present must be boolean\", so the bare instance\n * fails validation when it crosses the deserialize boundary in-process\n * (no JSON round-trip happens between planner → runner). This helper\n * recovers the JSON-round-tripped shape (undefined keys absent) without\n * forcing every caller to round-trip.\n *\n * Returns the original value reference whenever no change is needed.\n * That preserves prototype-bound payload values such as BSON wrappers\n * (`ObjectId`, `Decimal128`, `Binary`, …) which embed no `undefined`\n * own-enumerable properties and therefore never trigger a rebuild.\n * Top-level op IRs (class instances with `undefined` optional fields)\n * still get flattened to plain records as required by arktype.\n */\nfunction stripUndefinedDeep(value: unknown): unknown {\n if (Array.isArray(value)) {\n let changed = false;\n const next = value.map((item) => {\n const stripped = stripUndefinedDeep(item);\n if (stripped !== item) changed = true;\n return stripped;\n });\n return changed ? next : value;\n }\n if (value === null || typeof value !== 'object') {\n return value;\n }\n const entries = Object.entries(value as Record<string, unknown>);\n const out: Record<string, unknown> = {};\n let changed = false;\n for (const [key, val] of entries) {\n if (val === undefined) {\n changed = true;\n continue;\n }\n const stripped = stripUndefinedDeep(val);\n if (stripped !== val) changed = true;\n out[key] = stripped;\n }\n return changed ? out : value;\n}\n\nfunction deserializeFilterExpr(json: unknown): MongoFilterExpr {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'field': {\n const data = validate(FieldFilterJson, json, 'field filter');\n return MongoFieldFilter.of(data.field, data.op, data.value as never);\n }\n case 'and': {\n const exprs = record['exprs'];\n if (!Array.isArray(exprs)) throw new Error('Invalid and filter: missing exprs array');\n return MongoAndExpr.of(exprs.map(deserializeFilterExpr));\n }\n case 'or': {\n const exprs = record['exprs'];\n if (!Array.isArray(exprs)) throw new Error('Invalid or filter: missing exprs array');\n return MongoOrExpr.of(exprs.map(deserializeFilterExpr));\n }\n case 'not': {\n const expr = record['expr'];\n if (!expr || typeof expr !== 'object') throw new Error('Invalid not filter: missing expr');\n return new MongoNotExpr(deserializeFilterExpr(expr));\n }\n case 'exists': {\n const data = validate(ExistsFilterJson, json, 'exists filter');\n return new MongoExistsExpr(data.field, data.exists);\n }\n default:\n throw new Error(`Unknown filter expression kind: ${kind}`);\n }\n}\n\n// ============================================================================\n// Pipeline stage deserialization\n// ============================================================================\n\nexport function deserializePipelineStage(json: unknown): MongoPipelineStage {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'match':\n return new MongoMatchStage(deserializeFilterExpr(record['filter']));\n case 'limit':\n return new MongoLimitStage(record['limit'] as number);\n case 'sort':\n return new MongoSortStage(record['sort'] as Record<string, 1 | -1>);\n case 'project':\n return new MongoProjectStage(record['projection'] as Record<string, 0 | 1>);\n case 'addFields':\n return new MongoAddFieldsStage(record['fields'] as Record<string, never>);\n case 'lookup': {\n const opts: {\n from: string;\n as: string;\n localField?: string;\n foreignField?: string;\n pipeline?: ReadonlyArray<MongoPipelineStage>;\n let_?: Record<string, never>;\n } = {\n from: record['from'] as string,\n as: record['as'] as string,\n };\n if (record['localField'] !== undefined) opts.localField = record['localField'] as string;\n if (record['foreignField'] !== undefined)\n opts.foreignField = record['foreignField'] as string;\n if (record['pipeline'] !== undefined)\n opts.pipeline = (record['pipeline'] as unknown[]).map(deserializePipelineStage);\n if (record['let_'] !== undefined) opts.let_ = record['let_'] as Record<string, never>;\n return new MongoLookupStage(opts);\n }\n case 'merge': {\n const opts: {\n into: string | { db: string; coll: string };\n on?: string | ReadonlyArray<string>;\n whenMatched?: string | ReadonlyArray<MongoUpdatePipelineStage>;\n whenNotMatched?: string;\n } = {\n into: record['into'] as string | { db: string; coll: string },\n };\n if (record['on'] !== undefined) opts.on = record['on'] as string | string[];\n if (record['whenMatched'] !== undefined) {\n const wm = record['whenMatched'];\n opts.whenMatched =\n typeof wm === 'string'\n ? wm\n : ((wm as unknown[]).map(deserializePipelineStage) as MongoUpdatePipelineStage[]);\n }\n if (record['whenNotMatched'] !== undefined)\n opts.whenNotMatched = record['whenNotMatched'] as string;\n return new MongoMergeStage(opts);\n }\n default:\n throw new Error(`Unknown pipeline stage kind: ${kind}`);\n }\n}\n\n// ============================================================================\n// DML command deserialization\n// ============================================================================\n\nexport function deserializeDmlCommand(json: unknown): AnyMongoCommand {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'rawInsertOne': {\n const data = validate(RawInsertOneJson, json, 'rawInsertOne command');\n return new RawInsertOneCommand(data.collection, data.document);\n }\n case 'rawInsertMany': {\n const data = validate(RawInsertManyJson, json, 'rawInsertMany command');\n return new RawInsertManyCommand(data.collection, data.documents);\n }\n case 'rawUpdateOne': {\n const data = validate(RawUpdateOneJson, json, 'rawUpdateOne command');\n return new RawUpdateOneCommand(data.collection, data.filter, data.update);\n }\n case 'rawUpdateMany': {\n const data = validate(RawUpdateManyJson, json, 'rawUpdateMany command');\n return new RawUpdateManyCommand(data.collection, data.filter, data.update);\n }\n case 'rawDeleteOne': {\n const data = validate(RawDeleteOneJson, json, 'rawDeleteOne command');\n return new RawDeleteOneCommand(data.collection, data.filter);\n }\n case 'rawDeleteMany': {\n const data = validate(RawDeleteManyJson, json, 'rawDeleteMany command');\n return new RawDeleteManyCommand(data.collection, data.filter);\n }\n case 'rawAggregate': {\n const data = validate(RawAggregateJson, json, 'rawAggregate command');\n return new RawAggregateCommand(data.collection, data.pipeline);\n }\n case 'rawFindOneAndUpdate': {\n const data = validate(RawFindOneAndUpdateJson, json, 'rawFindOneAndUpdate command');\n return new RawFindOneAndUpdateCommand(data.collection, data.filter, data.update, data.upsert);\n }\n case 'rawFindOneAndDelete': {\n const data = validate(RawFindOneAndDeleteJson, json, 'rawFindOneAndDelete command');\n return new RawFindOneAndDeleteCommand(data.collection, data.filter);\n }\n case 'aggregate': {\n const data = validate(TypedAggregateJson, json, 'aggregate command');\n const pipeline = data.pipeline.map(deserializePipelineStage);\n return new AggregateCommand(data.collection, pipeline);\n }\n default:\n throw new Error(`Unknown DML command kind: ${kind}`);\n }\n}\n\n// ============================================================================\n// MongoQueryPlan deserialization\n// ============================================================================\n\nexport function deserializeMongoQueryPlan(json: unknown): MongoQueryPlan {\n const data = validate(QueryPlanJson, json, 'Mongo query plan');\n const command = deserializeDmlCommand(data.command);\n const m = data.meta;\n const meta: PlanMeta = {\n target: m.target,\n storageHash: m.storageHash,\n lane: m.lane,\n ...ifDefined('targetFamily', m.targetFamily),\n ...ifDefined('profileHash', m.profileHash),\n ...ifDefined('annotations', m.annotations),\n };\n return { collection: data.collection, command, meta };\n}\n\n// ============================================================================\n// DDL command deserialization\n// ============================================================================\n\nfunction deserializeDdlCommand(json: unknown): AnyMongoDdlCommand {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'createIndex': {\n const data = validate(CreateIndexJson, json, 'createIndex command');\n return new CreateIndexCommand(data.collection, data.keys, {\n unique: data.unique,\n sparse: data.sparse,\n expireAfterSeconds: data.expireAfterSeconds,\n partialFilterExpression: data.partialFilterExpression,\n name: data.name,\n wildcardProjection: data.wildcardProjection as Record<string, 0 | 1> | undefined,\n collation: data.collation,\n weights: data.weights as Record<string, number> | undefined,\n default_language: data.default_language,\n language_override: data.language_override,\n });\n }\n case 'dropIndex': {\n const data = validate(DropIndexJson, json, 'dropIndex command');\n return new DropIndexCommand(data.collection, data.name);\n }\n case 'createCollection': {\n const data = validate(CreateCollectionJson, json, 'createCollection command');\n return new CreateCollectionCommand(data.collection, {\n validator: data.validator,\n validationLevel: data.validationLevel,\n validationAction: data.validationAction,\n capped: data.capped,\n size: data.size,\n max: data.max,\n timeseries: data.timeseries as CreateCollectionCommand['timeseries'],\n collation: data.collation,\n changeStreamPreAndPostImages: data.changeStreamPreAndPostImages as\n | { enabled: boolean }\n | undefined,\n clusteredIndex: data.clusteredIndex as CreateCollectionCommand['clusteredIndex'],\n });\n }\n case 'dropCollection': {\n const data = validate(DropCollectionJson, json, 'dropCollection command');\n return new DropCollectionCommand(data.collection);\n }\n case 'collMod': {\n const data = validate(CollModJson, json, 'collMod command');\n return new CollModCommand(data.collection, {\n validator: data.validator,\n validationLevel: data.validationLevel,\n validationAction: data.validationAction,\n changeStreamPreAndPostImages: data.changeStreamPreAndPostImages as\n | { enabled: boolean }\n | undefined,\n });\n }\n default:\n throw new Error(`Unknown DDL command kind: ${kind}`);\n }\n}\n\nfunction deserializeInspectionCommand(json: unknown): AnyMongoInspectionCommand {\n const record = json as Record<string, unknown>;\n const kind = record['kind'] as string;\n switch (kind) {\n case 'listIndexes': {\n const data = validate(ListIndexesJson, json, 'listIndexes command');\n return new ListIndexesCommand(data.collection);\n }\n case 'listCollections': {\n validate(ListCollectionsJson, json, 'listCollections command');\n return new ListCollectionsCommand();\n }\n default:\n throw new Error(`Unknown inspection command kind: ${kind}`);\n }\n}\n\nfunction deserializeCheck(json: unknown): MongoMigrationCheck {\n const data = validate(CheckJson, json, 'migration check');\n return {\n description: data.description,\n source: deserializeInspectionCommand(data.source),\n filter: deserializeFilterExpr(data.filter),\n expect: data.expect,\n };\n}\n\nfunction deserializeStep(json: unknown): MongoMigrationStep {\n const data = validate(StepJson, json, 'migration step');\n return {\n description: data.description,\n command: deserializeDdlCommand(data.command),\n };\n}\n\nfunction isDataTransformJson(json: unknown): boolean {\n return (\n typeof json === 'object' &&\n json !== null &&\n (json as Record<string, unknown>)['operationClass'] === 'data'\n );\n}\n\nfunction deserializeDdlOp(json: unknown): MongoMigrationPlanOperation {\n const data = validate(DdlOperationJson, json, 'migration operation');\n return {\n id: data.id,\n label: data.label,\n operationClass: data.operationClass as MigrationOperationClass,\n precheck: data.precheck.map(deserializeCheck),\n execute: data.execute.map(deserializeStep),\n postcheck: data.postcheck.map(deserializeCheck),\n };\n}\n\nfunction deserializeDataTransformCheck(json: unknown): MongoDataTransformCheck {\n const data = validate(DataTransformCheckJson, json, 'data transform check');\n return {\n description: data.description,\n source: deserializeMongoQueryPlan(data.source),\n filter: deserializeFilterExpr(data.filter),\n expect: data.expect,\n };\n}\n\nfunction deserializeDataTransformOp(json: unknown): MongoDataTransformOperation {\n const data = validate(DataTransformOperationJson, json, 'data transform operation');\n return {\n id: data.id,\n label: data.label,\n operationClass: 'data',\n name: data.name,\n precheck: data.precheck.map(deserializeDataTransformCheck),\n run: data.run.map(deserializeMongoQueryPlan),\n postcheck: data.postcheck.map(deserializeDataTransformCheck),\n };\n}\n\nexport function deserializeMongoOp(json: unknown): AnyMongoMigrationOperation {\n if (isDataTransformJson(json)) {\n return deserializeDataTransformOp(json);\n }\n return deserializeDdlOp(json);\n}\n\nexport function deserializeMongoOps(json: readonly unknown[]): AnyMongoMigrationOperation[] {\n return json.map(deserializeMongoOp);\n}\n\nexport function serializeMongoOps(ops: readonly AnyMongoMigrationOperation[]): string {\n return JSON.stringify(ops, null, 2);\n}\n","/**\n * Mongo migration IR: one concrete `*Call` class per pure factory under\n * `migration-factories.ts`, plus a shared `OpFactoryCallNode` abstract\n * base. Every call class carries the literal arguments its backing\n * factory would receive, computes a human-readable `label` in its\n * constructor, and implements two polymorphic hooks:\n *\n * - `toOp()` — converts the IR node to a runtime\n * `MongoMigrationPlanOperation` by delegating to the matching pure\n * factory in `migration-factories.ts`.\n * - `renderTypeScript()` / `importRequirements()` — inherited from\n * `TsExpression`. Used by `renderCallsToTypeScript` to emit the call\n * as a TypeScript expression inside the scaffolded `migration.ts`.\n *\n * The abstract base and all concrete classes are package-private.\n * External consumers see only the framework-level `OpFactoryCall`\n * interface and the `OpFactoryCall` union.\n */\n\nimport type {\n OpFactoryCall as FrameworkOpFactoryCall,\n MigrationOperationClass,\n} from '@prisma-next/framework-components/control';\nimport type {\n CollModOptions,\n CreateCollectionOptions,\n CreateIndexOptions,\n MongoIndexKey,\n MongoMigrationPlanOperation,\n} from '@prisma-next/mongo-query-ast/control';\nimport type {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\nimport { type ImportRequirement, jsonToTsSource, TsExpression } from '@prisma-next/ts-render';\nimport {\n collMod,\n createCollection,\n createIndex,\n dropCollection,\n dropIndex,\n} from './migration-factories';\n\nexport interface CollModMeta {\n readonly id?: string;\n readonly label?: string;\n readonly operationClass?: MigrationOperationClass;\n}\n\nconst TARGET_MIGRATION_MODULE = '@prisma-next/target-mongo/migration';\n\nabstract class OpFactoryCallNode extends TsExpression implements FrameworkOpFactoryCall {\n abstract readonly factoryName: string;\n abstract readonly operationClass: MigrationOperationClass;\n abstract readonly label: string;\n abstract toOp(): MongoMigrationPlanOperation;\n\n importRequirements(): readonly ImportRequirement[] {\n return [{ moduleSpecifier: TARGET_MIGRATION_MODULE, symbol: this.factoryName }];\n }\n\n protected freeze(): void {\n Object.freeze(this);\n }\n}\n\nfunction formatKeys(keys: ReadonlyArray<MongoIndexKey>): string {\n return keys.map((k) => `${k.field}:${k.direction}`).join(', ');\n}\n\nexport class CreateIndexCall extends OpFactoryCallNode {\n readonly factoryName = 'createIndex' as const;\n readonly operationClass = 'additive' as const;\n readonly collection: string;\n readonly keys: ReadonlyArray<MongoIndexKey>;\n readonly options: CreateIndexOptions | undefined;\n readonly label: string;\n\n constructor(\n collection: string,\n keys: ReadonlyArray<MongoIndexKey>,\n options?: CreateIndexOptions,\n ) {\n super();\n this.collection = collection;\n this.keys = keys;\n this.options = options;\n this.label = `Create index on ${collection} (${formatKeys(keys)})`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return createIndex(this.collection, this.keys, this.options);\n }\n\n renderTypeScript(): string {\n return this.options\n ? `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)}, ${jsonToTsSource(this.options)})`\n : `createIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;\n }\n}\n\nexport class DropIndexCall extends OpFactoryCallNode {\n readonly factoryName = 'dropIndex' as const;\n readonly operationClass = 'destructive' as const;\n readonly collection: string;\n readonly keys: ReadonlyArray<MongoIndexKey>;\n readonly label: string;\n\n constructor(collection: string, keys: ReadonlyArray<MongoIndexKey>) {\n super();\n this.collection = collection;\n this.keys = keys;\n this.label = `Drop index on ${collection} (${formatKeys(keys)})`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return dropIndex(this.collection, this.keys);\n }\n\n renderTypeScript(): string {\n return `dropIndex(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.keys)})`;\n }\n}\n\nexport class CreateCollectionCall extends OpFactoryCallNode {\n readonly factoryName = 'createCollection' as const;\n readonly operationClass = 'additive' as const;\n readonly collection: string;\n readonly options: CreateCollectionOptions | undefined;\n readonly label: string;\n\n constructor(collection: string, options?: CreateCollectionOptions) {\n super();\n this.collection = collection;\n this.options = options;\n this.label = `Create collection ${collection}`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return createCollection(this.collection, this.options);\n }\n\n renderTypeScript(): string {\n return this.options\n ? `createCollection(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})`\n : `createCollection(${jsonToTsSource(this.collection)})`;\n }\n}\n\nexport class DropCollectionCall extends OpFactoryCallNode {\n readonly factoryName = 'dropCollection' as const;\n readonly operationClass = 'destructive' as const;\n readonly collection: string;\n readonly label: string;\n\n constructor(collection: string) {\n super();\n this.collection = collection;\n this.label = `Drop collection ${collection}`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return dropCollection(this.collection);\n }\n\n renderTypeScript(): string {\n return `dropCollection(${jsonToTsSource(this.collection)})`;\n }\n}\n\nexport class CollModCall extends OpFactoryCallNode {\n readonly factoryName = 'collMod' as const;\n readonly collection: string;\n readonly options: CollModOptions;\n readonly meta: CollModMeta | undefined;\n readonly operationClass: MigrationOperationClass;\n readonly label: string;\n\n constructor(collection: string, options: CollModOptions, meta?: CollModMeta) {\n super();\n this.collection = collection;\n this.options = options;\n this.meta = meta;\n this.operationClass = meta?.operationClass ?? 'destructive';\n this.label = meta?.label ?? `Modify collection ${collection}`;\n this.freeze();\n }\n\n toOp(): MongoMigrationPlanOperation {\n return collMod(this.collection, this.options, this.meta);\n }\n\n renderTypeScript(): string {\n return this.meta\n ? `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)}, ${jsonToTsSource(this.meta)})`\n : `collMod(${jsonToTsSource(this.collection)}, ${jsonToTsSource(this.options)})`;\n }\n}\n\nexport type OpFactoryCall =\n | CreateIndexCall\n | DropIndexCall\n | CreateCollectionCall\n | DropCollectionCall\n | CollModCall;\n\nexport function schemaIndexToCreateIndexOptions(index: MongoSchemaIndex): CreateIndexOptions {\n return {\n unique: index.unique || undefined,\n sparse: index.sparse,\n expireAfterSeconds: index.expireAfterSeconds,\n partialFilterExpression: index.partialFilterExpression,\n wildcardProjection: index.wildcardProjection,\n collation: index.collation,\n weights: index.weights,\n default_language: index.default_language,\n language_override: index.language_override,\n };\n}\n\nexport function schemaCollectionToCreateCollectionOptions(\n coll: MongoSchemaCollection,\n): CreateCollectionOptions | undefined {\n const opts: MongoSchemaCollectionOptions | undefined = coll.options;\n const validator: MongoSchemaValidator | undefined = coll.validator;\n if (!opts && !validator) return undefined;\n return {\n capped: opts?.capped ? true : undefined,\n size: opts?.capped?.size,\n max: opts?.capped?.max,\n timeseries: opts?.timeseries,\n collation: opts?.collation,\n clusteredIndex: opts?.clusteredIndex\n ? {\n key: { _id: 1 } as Record<string, number>,\n unique: true as boolean,\n ...(opts.clusteredIndex.name != null ? { name: opts.clusteredIndex.name } : {}),\n }\n : undefined,\n validator: validator ? { $jsonSchema: validator.jsonSchema } : undefined,\n validationLevel: validator?.validationLevel,\n validationAction: validator?.validationAction,\n changeStreamPreAndPostImages: opts?.changeStreamPreAndPostImages,\n };\n}\n","import type { MongoMigrationPlanOperation } from '@prisma-next/mongo-query-ast/control';\nimport type { OpFactoryCall } from './op-factory-call';\n\nexport function renderOps(calls: ReadonlyArray<OpFactoryCall>): MongoMigrationPlanOperation[] {\n return calls.map((call) => call.toOp());\n}\n","import { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';\nimport { type ImportRequirement, jsonToTsSource, renderImports } from '@prisma-next/ts-render';\nimport type { OpFactoryCall } from './op-factory-call';\n\nexport interface RenderMigrationMeta {\n readonly from: string | null;\n readonly to: string;\n readonly labels?: readonly string[];\n}\n\n/**\n * Always-present base imports for the rendered scaffold:\n *\n * - `Migration` from `@prisma-next/family-mongo/migration` — the\n * user-facing Mongo `Migration` base; subclasses don't need to\n * redeclare `targetId` or thread family/target generics.\n * - `MigrationCLI` from `@prisma-next/cli/migration-cli` — the\n * migration-file CLI entrypoint that loads `prisma-next.config.ts`,\n * assembles a `ControlStack`, and instantiates the migration class.\n * The migration file owns this dependency directly: pulling CLI\n * machinery in at script run time is acceptable because the script's\n * whole purpose is to be invoked from the project that owns the\n * config. (Mirrors the postgres facade pattern; pulling `MigrationCLI`\n * into `@prisma-next/family-mongo/migration` so a Mongo migration only\n * needs one import is tracked separately as a follow-up.)\n */\nconst BASE_IMPORTS: readonly ImportRequirement[] = [\n { moduleSpecifier: '@prisma-next/family-mongo/migration', symbol: 'Migration' },\n { moduleSpecifier: '@prisma-next/cli/migration-cli', symbol: 'MigrationCLI' },\n];\n\n/**\n * Render a list of Mongo `OpFactoryCall`s as a `migration.ts`\n * source string. The result is shebanged, extends the user-facing\n * `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and\n * implements the abstract `operations` and `describe` members. `meta` is\n * always rendered — `describe()` is part of the `Migration` contract, so\n * even an empty stub must satisfy it; callers pass `from: null` for a\n * baseline `migration-new` scaffold (and a real `to` hash either way).\n *\n * The walk is polymorphic: each call node contributes its own\n * `renderTypeScript()` expression and declares its own\n * `importRequirements()`. The top-level renderer aggregates imports\n * across all nodes and emits one `import { … } from \"…\"` line per module.\n * The `Migration` and `MigrationCLI` imports are always emitted — they're\n * structural to the rendered scaffold (extends `Migration`, calls\n * `MigrationCLI.run`), not driven by any node.\n */\nexport function renderCallsToTypeScript(\n calls: ReadonlyArray<OpFactoryCall>,\n meta: RenderMigrationMeta,\n): string {\n const imports = buildImports(calls);\n const operationsBody = calls.map((c) => c.renderTypeScript()).join(',\\n');\n\n return [\n shebangLineFor(detectScaffoldRuntime()),\n imports,\n '',\n 'class M extends Migration {',\n buildDescribeMethod(meta),\n ' override get operations() {',\n ' return [',\n indent(operationsBody, 6),\n ' ];',\n ' }',\n '}',\n '',\n 'export default M;',\n 'MigrationCLI.run(import.meta.url, M);',\n '',\n ].join('\\n');\n}\n\nfunction buildImports(calls: ReadonlyArray<OpFactoryCall>): string {\n const requirements: ImportRequirement[] = [...BASE_IMPORTS];\n for (const call of calls) {\n for (const req of call.importRequirements()) {\n requirements.push(req);\n }\n }\n return renderImports(requirements);\n}\n\nfunction buildDescribeMethod(meta: RenderMigrationMeta): string {\n const lines: string[] = [];\n lines.push(' override describe() {');\n lines.push(' return {');\n lines.push(` from: ${JSON.stringify(meta.from)},`);\n lines.push(` to: ${JSON.stringify(meta.to)},`);\n if (meta.labels && meta.labels.length > 0) {\n lines.push(` labels: ${jsonToTsSource(meta.labels)},`);\n }\n lines.push(' };');\n lines.push(' }');\n lines.push('');\n return lines.join('\\n');\n}\n\nfunction indent(text: string, spaces: number): string {\n const pad = ' '.repeat(spaces);\n return text\n .split('\\n')\n .map((line) => (line.trim() ? `${pad}${line}` : line))\n .join('\\n');\n}\n","import type { MigrationPlanWithAuthoringSurface } from '@prisma-next/framework-components/control';\nimport { Migration, type MigrationMeta } from '@prisma-next/migration-tools/migration';\nimport type { AnyMongoMigrationOperation } from '@prisma-next/mongo-query-ast/control';\nimport { ifDefined } from '@prisma-next/utils/defined';\nimport type { OpFactoryCall } from './op-factory-call';\nimport { renderOps } from './render-ops';\nimport { renderCallsToTypeScript } from './render-typescript';\n\n/**\n * Planner-produced Mongo migration, returned by `MongoMigrationPlanner.plan(...)`\n * and `MongoMigrationPlanner.emptyMigration(...)`.\n *\n * Unlike user-authored migrations (which extend `MongoMigration` from\n * `@prisma-next/family-mongo/migration`), this class lives inside the target\n * and holds the richer authoring IR (`OpFactoryCall[]`) needed to render\n * itself back to TypeScript source. It implements\n * `MigrationPlanWithAuthoringSurface` so that the CLI can uniformly ask any\n * planner result to serialize itself to a `migration.ts`.\n *\n * Extends the framework `Migration` base class directly (not\n * `MongoMigration`) because `MongoMigration` lives in `@prisma-next/family-mongo`,\n * which depends on this package — extending it here would create a dependency\n * cycle.\n */\nexport class PlannerProducedMongoMigration\n extends Migration<AnyMongoMigrationOperation>\n implements MigrationPlanWithAuthoringSurface\n{\n readonly targetId = 'mongo' as const;\n\n constructor(\n private readonly calls: readonly OpFactoryCall[],\n private readonly meta: MigrationMeta,\n ) {\n super();\n }\n\n override get operations(): readonly AnyMongoMigrationOperation[] {\n return renderOps(this.calls);\n }\n\n override describe(): MigrationMeta {\n return this.meta;\n }\n\n renderTypeScript(): string {\n return renderCallsToTypeScript(this.calls, {\n from: this.meta.from,\n to: this.meta.to,\n ...ifDefined('labels', this.meta.labels),\n });\n }\n}\n","import type { Contract } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationOperationClass,\n MigrationOperationPolicy,\n MigrationPlanner,\n MigrationPlannerConflict,\n MigrationPlannerResult,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaIR,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\nimport { canonicalize, deepEqual } from '@prisma-next/mongo-schema-ir';\nimport { contractToMongoSchemaIR } from './contract-to-schema';\nimport type { OpFactoryCall } from './op-factory-call';\nimport {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n schemaCollectionToCreateCollectionOptions,\n schemaIndexToCreateIndexOptions,\n} from './op-factory-call';\nimport { PlannerProducedMongoMigration } from './planner-produced-migration';\n\nfunction buildIndexLookupKey(index: MongoSchemaIndex): string {\n const keys = index.keys.map((k) => `${k.field}:${k.direction}`).join(',');\n const opts = [\n index.unique ? 'unique' : '',\n index.sparse ? 'sparse' : '',\n index.expireAfterSeconds != null ? `ttl:${index.expireAfterSeconds}` : '',\n index.partialFilterExpression ? `pfe:${canonicalize(index.partialFilterExpression)}` : '',\n index.wildcardProjection ? `wp:${canonicalize(index.wildcardProjection)}` : '',\n index.collation ? `col:${canonicalize(index.collation)}` : '',\n index.weights ? `wt:${canonicalize(index.weights)}` : '',\n index.default_language ? `dl:${index.default_language}` : '',\n index.language_override ? `lo:${index.language_override}` : '',\n ]\n .filter(Boolean)\n .join(';');\n return opts ? `${keys}|${opts}` : keys;\n}\n\nfunction validatorsEqual(\n a: MongoSchemaValidator | undefined,\n b: MongoSchemaValidator | undefined,\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return (\n a.validationLevel === b.validationLevel &&\n a.validationAction === b.validationAction &&\n canonicalize(a.jsonSchema) === canonicalize(b.jsonSchema)\n );\n}\n\nfunction classifyValidatorUpdate(\n origin: MongoSchemaValidator,\n dest: MongoSchemaValidator,\n): 'widening' | 'destructive' {\n let hasDestructive = false;\n\n if (canonicalize(origin.jsonSchema) !== canonicalize(dest.jsonSchema)) {\n hasDestructive = true;\n }\n\n if (origin.validationAction !== dest.validationAction) {\n if (dest.validationAction === 'error') hasDestructive = true;\n }\n\n if (origin.validationLevel !== dest.validationLevel) {\n if (dest.validationLevel === 'strict') hasDestructive = true;\n }\n\n return hasDestructive ? 'destructive' : 'widening';\n}\n\nfunction hasImmutableOptionChange(\n origin: MongoSchemaCollectionOptions | undefined,\n dest: MongoSchemaCollectionOptions | undefined,\n): string | undefined {\n if (canonicalize(origin?.capped) !== canonicalize(dest?.capped)) return 'capped';\n if (canonicalize(origin?.timeseries) !== canonicalize(dest?.timeseries)) return 'timeseries';\n if (canonicalize(origin?.collation) !== canonicalize(dest?.collation)) return 'collation';\n if (canonicalize(origin?.clusteredIndex) !== canonicalize(dest?.clusteredIndex))\n return 'clusteredIndex';\n return undefined;\n}\n\nfunction collectionHasOptions(coll: MongoSchemaCollection): boolean {\n return !!(coll.options || coll.validator);\n}\n\nexport type PlanCallsResult =\n | { readonly kind: 'success'; readonly calls: OpFactoryCall[] }\n | { readonly kind: 'failure'; readonly conflicts: MigrationPlannerConflict[] };\n\nexport class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'> {\n planCalls(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;\n }): PlanCallsResult {\n const contract = options.contract as MongoContract;\n const originIR = options.schema as MongoSchemaIR;\n const destinationIR = contractToMongoSchemaIR(contract);\n\n const collCreates: OpFactoryCall[] = [];\n const drops: OpFactoryCall[] = [];\n const creates: OpFactoryCall[] = [];\n const validatorOps: OpFactoryCall[] = [];\n const mutableOptionOps: OpFactoryCall[] = [];\n const collDrops: OpFactoryCall[] = [];\n const conflicts: MigrationPlannerConflict[] = [];\n\n const allCollectionNames = new Set([\n ...originIR.collectionNames,\n ...destinationIR.collectionNames,\n ]);\n\n for (const collName of [...allCollectionNames].sort()) {\n const originColl = originIR.collection(collName);\n const destColl = destinationIR.collection(collName);\n\n if (!originColl) {\n // Provision contract-declared collections that are absent from\n // the live database. MongoDB lazily materialises a collection\n // on first write, so subsequent `createIndex` calls in the same\n // plan would create the collection for us implicitly — but the\n // schema verifier treats an unmaterialised contract collection\n // as a `missing_table` issue, so a plan that lacks both options\n // and indexes (e.g. a plain `users` collection from the init\n // scaffold) ends up provisioning nothing and failing verify.\n // The planner therefore emits an explicit createCollection for\n // any contract collection that has options/validator OR no\n // indexes to ride along on. Collections that have indexes\n // continue to rely on createIndex for materialisation, keeping\n // existing plans byte-stable.\n if (destColl && (collectionHasOptions(destColl) || destColl.indexes.length === 0)) {\n const opts = collectionHasOptions(destColl)\n ? schemaCollectionToCreateCollectionOptions(destColl)\n : undefined;\n collCreates.push(new CreateCollectionCall(collName, opts));\n }\n } else if (!destColl) {\n collDrops.push(new DropCollectionCall(collName));\n } else {\n const immutableChange = hasImmutableOptionChange(originColl.options, destColl.options);\n if (immutableChange) {\n conflicts.push({\n kind: 'policy-violation',\n summary: `Cannot change immutable collection option '${immutableChange}' on ${collName}`,\n why: `MongoDB does not support modifying the '${immutableChange}' option after collection creation`,\n });\n }\n\n const mutableCall = planMutableOptionsDiffCall(\n collName,\n originColl.options,\n destColl.options,\n );\n if (mutableCall) mutableOptionOps.push(mutableCall);\n\n const validatorCall = planValidatorDiffCall(\n collName,\n originColl.validator,\n destColl.validator,\n );\n if (validatorCall) validatorOps.push(validatorCall);\n }\n\n const originLookup = new Map<string, MongoSchemaIndex>();\n if (originColl) {\n for (const idx of originColl.indexes) {\n originLookup.set(buildIndexLookupKey(idx), idx);\n }\n }\n\n const destLookup = new Map<string, MongoSchemaIndex>();\n if (destColl) {\n for (const idx of destColl.indexes) {\n destLookup.set(buildIndexLookupKey(idx), idx);\n }\n }\n\n for (const [lookupKey, idx] of originLookup) {\n if (!destLookup.has(lookupKey)) {\n drops.push(new DropIndexCall(collName, idx.keys));\n }\n }\n\n for (const [lookupKey, idx] of destLookup) {\n if (!originLookup.has(lookupKey)) {\n creates.push(\n new CreateIndexCall(collName, idx.keys, schemaIndexToCreateIndexOptions(idx)),\n );\n }\n }\n }\n\n if (conflicts.length > 0) {\n return { kind: 'failure', conflicts };\n }\n\n const allCalls = [\n ...collCreates,\n ...drops,\n ...creates,\n ...validatorOps,\n ...mutableOptionOps,\n ...collDrops,\n ];\n\n for (const call of allCalls) {\n if (!options.policy.allowedOperationClasses.includes(call.operationClass)) {\n conflicts.push({\n kind: 'policy-violation',\n summary: `${call.operationClass} operation disallowed: ${call.label}`,\n why: `Policy does not allow '${call.operationClass}' operations`,\n });\n }\n }\n\n if (conflicts.length > 0) {\n return { kind: 'failure', conflicts };\n }\n\n return { kind: 'success', calls: allCalls };\n }\n\n plan(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n /**\n * The \"from\" contract (state the planner assumes the database starts at),\n * or `null` for reconciliation flows. Used to populate `describe().from`\n * on the produced plan as `fromContract?.storage.storageHash ?? null`.\n */\n readonly fromContract: Contract | null;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;\n }): MigrationPlannerResult {\n const contract = options.contract as MongoContract;\n const result = this.planCalls(options);\n if (result.kind === 'failure') return result;\n return {\n kind: 'success',\n plan: new PlannerProducedMongoMigration(result.calls, {\n from: options.fromContract?.storage.storageHash ?? null,\n to: contract.storage.storageHash,\n }),\n };\n }\n\n /**\n * Produce an empty `migration.ts` authoring surface for `migration new`.\n *\n * The \"empty migration\" is a `PlannerProducedMongoMigration` with no\n * operations; `renderTypeScript()` emits a stub class with the correct\n * `from`/`to` metadata that the user then fills in with operations. The\n * contract path on the context is unused — Mongo's emitted source does\n * not import from the generated contract `.d.ts`.\n */\n emptyMigration(context: MigrationScaffoldContext): MigrationPlanWithAuthoringSurface {\n return new PlannerProducedMongoMigration([], {\n from: context.fromHash,\n to: context.toHash,\n });\n }\n}\n\nfunction planValidatorDiffCall(\n collName: string,\n originValidator: MongoSchemaValidator | undefined,\n destValidator: MongoSchemaValidator | undefined,\n): OpFactoryCall | undefined {\n if (validatorsEqual(originValidator, destValidator)) return undefined;\n\n if (destValidator) {\n const operationClass: MigrationOperationClass = originValidator\n ? classifyValidatorUpdate(originValidator, destValidator)\n : 'destructive';\n return new CollModCall(\n collName,\n {\n validator: { $jsonSchema: destValidator.jsonSchema },\n validationLevel: destValidator.validationLevel,\n validationAction: destValidator.validationAction,\n },\n {\n id: `validator.${collName}.${originValidator ? 'update' : 'add'}`,\n label: `${originValidator ? 'Update' : 'Add'} validator on ${collName}`,\n operationClass,\n },\n );\n }\n\n return new CollModCall(\n collName,\n {\n validator: {},\n validationLevel: 'strict',\n validationAction: 'error',\n },\n {\n id: `validator.${collName}.remove`,\n label: `Remove validator on ${collName}`,\n operationClass: 'widening',\n },\n );\n}\n\nfunction planMutableOptionsDiffCall(\n collName: string,\n origin: MongoSchemaCollectionOptions | undefined,\n dest: MongoSchemaCollectionOptions | undefined,\n): OpFactoryCall | undefined {\n const originCSPPI = origin?.changeStreamPreAndPostImages;\n const destCSPPI = dest?.changeStreamPreAndPostImages;\n if (deepEqual(originCSPPI, destCSPPI)) return undefined;\n\n const desiredCSPPI = destCSPPI ?? { enabled: false };\n return new CollModCall(\n collName,\n {\n changeStreamPreAndPostImages: desiredCSPPI,\n },\n {\n id: `options.${collName}.update`,\n label: `Update mutable options on ${collName}`,\n operationClass: desiredCSPPI.enabled ? 'widening' : 'destructive',\n },\n );\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { errorRunnerFailed } from '@prisma-next/errors/execution';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport {\n APP_SPACE_ID,\n type MigrationOperationPolicy,\n type MigrationPlan,\n type MigrationPlanOperation,\n type MigrationRunnerExecutionChecks,\n type MigrationRunnerFailure,\n type MigrationRunnerResult,\n type OperationContext,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type { MongoAdapter, MongoDriver } from '@prisma-next/mongo-lowering';\nimport type {\n AnyMongoMigrationOperation,\n MongoDataTransformCheck,\n MongoDataTransformOperation,\n MongoDdlCommandVisitor,\n MongoInspectionCommandVisitor,\n MongoMigrationCheck,\n MongoMigrationPlanOperation,\n} from '@prisma-next/mongo-query-ast/control';\nimport type { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { FilterEvaluator } from './filter-evaluator';\nimport { deserializeMongoOps } from './mongo-ops-serializer';\nimport { verifyMongoSchema } from './schema-verify/verify-mongo-schema';\n\nconst READ_ONLY_CHECK_COMMAND_KINDS: ReadonlySet<string> = new Set(['aggregate', 'rawAggregate']);\n\n/**\n * Marker / ledger operations the Mongo runner depends on. Every method\n * takes a `space` parameter so each loaded contract space addresses its\n * own marker row independently — see ADR 212 for the per-space\n * mechanism.\n */\nexport interface MarkerOperations {\n readMarker(space: string): Promise<ContractMarkerRecord | null>;\n initMarker(\n space: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<void>;\n updateMarker(\n space: string,\n expectedFrom: string,\n destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n readonly invariants?: readonly string[];\n },\n ): Promise<boolean>;\n writeLedgerEntry(\n space: string,\n entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n },\n ): Promise<void>;\n}\n\nexport interface MongoRunnerDependencies {\n readonly commandExecutor: MongoDdlCommandVisitor<Promise<void>>;\n readonly inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>;\n readonly adapter: MongoAdapter;\n readonly driver: MongoDriver;\n readonly markerOps: MarkerOperations;\n readonly introspectSchema: () => Promise<MongoSchemaIR>;\n}\n\nexport interface MongoMigrationRunnerExecuteOptions {\n readonly plan: MigrationPlan;\n readonly destinationContract: MongoContract;\n readonly policy: MigrationOperationPolicy;\n readonly callbacks?: {\n onOperationStart?(op: MigrationPlanOperation): void;\n onOperationComplete?(op: MigrationPlanOperation): void;\n };\n readonly executionChecks?: MigrationRunnerExecutionChecks;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;\n readonly strictVerification?: boolean;\n readonly context?: OperationContext;\n /**\n * Per-space schema projection. When set, the runner applies this\n * function to the introspected schema before invoking\n * `verifyMongoSchema`, so per-space verification only sees the slice\n * the destination contract actually claims.\n *\n * The descriptor's `executeAcrossSpaces` injects this callback,\n * derived from the sibling spaces in the aggregate. Single-space\n * callers leave it unset and verify against the whole introspected\n * schema (the pre-aggregate behaviour).\n */\n readonly projectSchema?: (schema: MongoSchemaIR) => MongoSchemaIR;\n}\n\nfunction runnerFailure(\n code: string,\n summary: string,\n opts?: { why?: string; meta?: Record<string, unknown> },\n): MigrationRunnerResult {\n return notOk<MigrationRunnerFailure>({\n code,\n summary,\n ...opts,\n });\n}\n\nexport class MongoMigrationRunner {\n constructor(private readonly deps: MongoRunnerDependencies) {}\n\n async execute(options: MongoMigrationRunnerExecuteOptions): Promise<MigrationRunnerResult> {\n const { commandExecutor, inspectionExecutor, adapter, driver, markerOps } = this.deps;\n const operations = deserializeMongoOps(options.plan.operations as readonly unknown[]);\n // Plans produced by the contract-space-aware planner stamp `spaceId`\n // onto the plan; pre-port single-space callers leave it absent and\n // fall through to the application's well-known space.\n const space = options.plan.spaceId ?? APP_SPACE_ID;\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, operations);\n if (policyCheck) return policyCheck;\n\n const existingMarker = await markerOps.readMarker(space);\n\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (markerCheck) return markerCheck;\n\n const checks = options.executionChecks;\n const runPrechecks = checks?.prechecks !== false;\n const runPostchecks = checks?.postchecks !== false;\n const runIdempotency = checks?.idempotencyChecks !== false;\n\n const filterEvaluator = new FilterEvaluator();\n\n let operationsExecuted = 0;\n\n for (const operation of operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n if (operation.operationClass === 'data') {\n const result = await this.executeDataTransform(\n operation as MongoDataTransformOperation,\n adapter,\n driver,\n filterEvaluator,\n runIdempotency,\n runPrechecks,\n runPostchecks,\n );\n if (result.failure) return result.failure;\n if (result.executed) operationsExecuted += 1;\n continue;\n }\n\n const ddlOp = operation as MongoMigrationPlanOperation;\n\n if (runPostchecks && runIdempotency) {\n const allSatisfied = await this.allChecksSatisfied(\n ddlOp.postcheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (allSatisfied) continue;\n }\n\n if (runPrechecks) {\n const precheckResult = await this.evaluateChecks(\n ddlOp.precheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (!precheckResult) {\n return runnerFailure(\n 'PRECHECK_FAILED',\n `Operation ${operation.id} failed during precheck`,\n { meta: { operationId: operation.id } },\n );\n }\n }\n\n for (const step of ddlOp.execute) {\n await step.command.accept(commandExecutor);\n }\n\n if (runPostchecks) {\n const postcheckResult = await this.evaluateChecks(\n ddlOp.postcheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (!postcheckResult) {\n return runnerFailure(\n 'POSTCHECK_FAILED',\n `Operation ${operation.id} failed during postcheck`,\n { meta: { operationId: operation.id } },\n );\n }\n }\n\n operationsExecuted += 1;\n } finally {\n options.callbacks?.onOperationComplete?.(operation);\n }\n }\n\n const destination = options.plan.destination;\n const profileHash = options.destinationContract.profileHash ?? destination.storageHash;\n\n const incomingInvariants = options.plan.providedInvariants ?? [];\n const existingInvariantSet = new Set(existingMarker?.invariants ?? []);\n const incomingIsSubsetOfExisting = incomingInvariants.every((id) =>\n existingInvariantSet.has(id),\n );\n const markerAlreadyAtDestination =\n existingMarker !== null &&\n existingMarker.storageHash === destination.storageHash &&\n existingMarker.profileHash === profileHash;\n\n // Skip marker/ledger writes (and schema verification) only when the apply\n // is a true no-op: no operations executed, marker already at destination,\n // and every incoming invariant is already in the stored set.\n //\n // Divergence from the SQL runners (postgres/sqlite): those runners gate\n // the no-op skip on `isSelfEdge` (origin === destination) only, so a\n // non-self-edge `db update` that introspects-as-no-op still writes a\n // ledger entry. Mongo skips even those because the runner has no\n // structural distinction between self-edge and re-apply — invariant-\n // aware routing here does not yet differentiate between the two\n // ledger semantics. If the SQL audit-trail behavior should hold for\n // Mongo too, gate this `isNoOp` on a self-edge check (or, conversely,\n // align the SQL runners to skip non-self-edge no-ops uniformly).\n const isNoOp =\n operationsExecuted === 0 && markerAlreadyAtDestination && incomingIsSubsetOfExisting;\n\n if (!isNoOp) {\n const liveSchema = await this.deps.introspectSchema();\n // In a multi-space aggregate the live database holds collections\n // owned by sibling spaces; the descriptor's `executeAcrossSpaces`\n // injects a `projectSchema` that strips them so per-space verify\n // only checks the slice this contract claims. Single-space\n // callers leave the projection identity (no-op).\n const verifySchema = options.projectSchema ? options.projectSchema(liveSchema) : liveSchema;\n const verifyResult = verifyMongoSchema({\n contract: options.destinationContract,\n schema: verifySchema,\n strict: options.strictVerification ?? true,\n frameworkComponents: options.frameworkComponents,\n ...(options.context ? { context: options.context } : {}),\n });\n if (!verifyResult.ok) {\n return runnerFailure('SCHEMA_VERIFY_FAILED', verifyResult.summary, {\n why: 'The resulting database schema does not satisfy the destination contract.',\n meta: { issues: verifyResult.schema.issues },\n });\n }\n\n if (existingMarker) {\n const updated = await markerOps.updateMarker(space, existingMarker.storageHash, {\n storageHash: destination.storageHash,\n profileHash,\n invariants: incomingInvariants,\n });\n if (!updated) {\n return runnerFailure(\n 'MARKER_CAS_FAILURE',\n 'Marker was modified by another process during migration execution.',\n {\n meta: {\n space,\n expectedStorageHash: existingMarker.storageHash,\n destinationStorageHash: destination.storageHash,\n },\n },\n );\n }\n } else {\n await markerOps.initMarker(space, {\n storageHash: destination.storageHash,\n profileHash,\n invariants: incomingInvariants,\n });\n }\n\n const originHash = existingMarker?.storageHash ?? '';\n await markerOps.writeLedgerEntry(space, {\n edgeId: `${originHash}->${destination.storageHash}`,\n from: originHash,\n to: destination.storageHash,\n });\n }\n\n return ok({ operationsPlanned: operations.length, operationsExecuted });\n }\n\n private async executeDataTransform(\n op: MongoDataTransformOperation,\n adapter: MongoAdapter,\n driver: MongoDriver,\n filterEvaluator: FilterEvaluator,\n runIdempotency: boolean,\n runPrechecks: boolean,\n runPostchecks: boolean,\n ): Promise<{ executed: boolean; failure?: MigrationRunnerResult }> {\n if (runPostchecks && runIdempotency && op.postcheck.length > 0) {\n const allSatisfied = await this.evaluateDataTransformChecks(\n op.postcheck,\n adapter,\n driver,\n filterEvaluator,\n );\n if (allSatisfied) return { executed: false };\n }\n\n if (runPrechecks && op.precheck.length > 0) {\n const passed = await this.evaluateDataTransformChecks(\n op.precheck,\n adapter,\n driver,\n filterEvaluator,\n );\n if (!passed) {\n return {\n executed: false,\n failure: runnerFailure('PRECHECK_FAILED', `Operation ${op.id} failed during precheck`, {\n meta: { operationId: op.id, name: op.name },\n }),\n };\n }\n }\n\n for (const plan of op.run) {\n const wireCommand = await adapter.lower(plan, {});\n for await (const _ of driver.execute(wireCommand)) {\n /* consume */\n }\n }\n\n if (runPostchecks && op.postcheck.length > 0) {\n const passed = await this.evaluateDataTransformChecks(\n op.postcheck,\n adapter,\n driver,\n filterEvaluator,\n );\n if (!passed) {\n return {\n executed: false,\n failure: runnerFailure('POSTCHECK_FAILED', `Operation ${op.id} failed during postcheck`, {\n meta: { operationId: op.id, name: op.name },\n }),\n };\n }\n }\n\n return { executed: true };\n }\n\n private async evaluateDataTransformChecks(\n checks: readonly MongoDataTransformCheck[],\n adapter: MongoAdapter,\n driver: MongoDriver,\n filterEvaluator: FilterEvaluator,\n ): Promise<boolean> {\n for (const check of checks) {\n const commandKind = check.source.command.kind;\n if (!READ_ONLY_CHECK_COMMAND_KINDS.has(commandKind)) {\n throw errorRunnerFailed(\n `Data-transform check rejected: command kind \"${commandKind}\" is not read-only`,\n {\n why: 'Data-transform checks must use aggregate or rawAggregate commands so the pre/postcheck path cannot mutate the database.',\n fix: 'Author the check.source as an aggregate pipeline (or rawAggregate) rather than a DML write command.',\n meta: {\n checkDescription: check.description,\n commandKind,\n collection: check.source.collection,\n },\n },\n );\n }\n const wireCommand = await adapter.lower(check.source, {});\n let matchFound = false;\n for await (const row of driver.execute<Record<string, unknown>>(wireCommand)) {\n if (filterEvaluator.evaluate(check.filter, row)) {\n matchFound = true;\n break;\n }\n }\n const passed = check.expect === 'exists' ? matchFound : !matchFound;\n if (!passed) return false;\n }\n return true;\n }\n\n private async evaluateChecks(\n checks: readonly MongoMigrationCheck[],\n inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>,\n filterEvaluator: FilterEvaluator,\n ): Promise<boolean> {\n for (const check of checks) {\n const documents = await check.source.accept(inspectionExecutor);\n const matchFound = documents.some((doc) =>\n filterEvaluator.evaluate(check.filter, doc as Record<string, unknown>),\n );\n const passed = check.expect === 'exists' ? matchFound : !matchFound;\n if (!passed) return false;\n }\n return true;\n }\n\n private async allChecksSatisfied(\n checks: readonly MongoMigrationCheck[],\n inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>,\n filterEvaluator: FilterEvaluator,\n ): Promise<boolean> {\n if (checks.length === 0) return false;\n return this.evaluateChecks(checks, inspectionExecutor, filterEvaluator);\n }\n\n private enforcePolicyCompatibility(\n policy: MigrationOperationPolicy,\n operations: readonly AnyMongoMigrationOperation[],\n ): MigrationRunnerResult | undefined {\n const allowedClasses = new Set(policy.allowedOperationClasses);\n for (const operation of operations) {\n if (!allowedClasses.has(operation.operationClass)) {\n return runnerFailure(\n 'POLICY_VIOLATION',\n `Operation ${operation.id} has class \"${operation.operationClass}\" which is not allowed by policy.`,\n {\n why: `Policy only allows: ${[...allowedClasses].join(', ')}.`,\n meta: {\n operationId: operation.id,\n operationClass: operation.operationClass,\n },\n },\n );\n }\n }\n return undefined;\n }\n\n private ensureMarkerCompatibility(\n marker: ContractMarkerRecord | null,\n plan: MigrationPlan,\n ): MigrationRunnerResult | undefined {\n const origin = plan.origin ?? null;\n if (!origin) {\n // No origin assertion on the plan — the caller has done its own\n // correctness check (typically `db update` via live-schema\n // introspection) and does not rely on marker continuity.\n return undefined;\n }\n\n if (!marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Missing contract marker: expected origin storage hash ${origin.storageHash}.`,\n { meta: { expectedOriginStorageHash: origin.storageHash } },\n );\n }\n\n if (marker.storageHash !== origin.storageHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`,\n {\n meta: {\n markerStorageHash: marker.storageHash,\n expectedOriginStorageHash: origin.storageHash,\n },\n },\n );\n }\n\n return undefined;\n }\n}\n"],"mappings":";;;;;;;;;;;;;;AAWA,SAAS,cAAc,MAA4C;CAEjE,OAAO,KADS,KAAK,KAAK,MAAM,GAAG,KAAK,UAAU,EAAE,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,UAAU,GACvE,CAAC,KAAK,KAAK,CAAC;;AAGjC,SAAS,cAAc,KAA6C;CAClE,MAAM,QAAkB,EAAE;CAC1B,IAAI,IAAI,QAAQ,MAAM,KAAK,eAAe;CAC1C,IAAI,IAAI,QAAQ,MAAM,KAAK,eAAe;CAC1C,IAAI,IAAI,uBAAuB,KAAA,GAC7B,MAAM,KAAK,uBAAuB,IAAI,qBAAqB;CAC7D,IAAI,IAAI,MAAM,MAAM,KAAK,SAAS,KAAK,UAAU,IAAI,KAAK,GAAG;CAC7D,IAAI,IAAI,WAAW,MAAM,KAAK,cAAc,KAAK,UAAU,IAAI,UAAU,GAAG;CAC5E,IAAI,IAAI,SAAS,MAAM,KAAK,YAAY,KAAK,UAAU,IAAI,QAAQ,GAAG;CACtE,IAAI,IAAI,kBAAkB,MAAM,KAAK,qBAAqB,KAAK,UAAU,IAAI,iBAAiB,GAAG;CACjG,IAAI,IAAI,mBACN,MAAM,KAAK,sBAAsB,KAAK,UAAU,IAAI,kBAAkB,GAAG;CAC3E,IAAI,IAAI,oBACN,MAAM,KAAK,uBAAuB,KAAK,UAAU,IAAI,mBAAmB,GAAG;CAC7E,IAAI,IAAI,yBACN,MAAM,KAAK,4BAA4B,KAAK,UAAU,IAAI,wBAAwB,GAAG;CACvF,IAAI,MAAM,WAAW,GAAG,OAAO,KAAA;CAC/B,OAAO,KAAK,MAAM,KAAK,KAAK,CAAC;;AAG/B,SAAS,8BAA8B,KAAkD;CACvF,MAAM,QAAkB,EAAE;CAC1B,IAAI,IAAI,QAAQ,MAAM,KAAK,eAAe;CAC1C,IAAI,IAAI,SAAS,KAAA,GAAW,MAAM,KAAK,SAAS,IAAI,OAAO;CAC3D,IAAI,IAAI,QAAQ,KAAA,GAAW,MAAM,KAAK,QAAQ,IAAI,MAAM;CACxD,IAAI,IAAI,YAAY,MAAM,KAAK,eAAe,KAAK,UAAU,IAAI,WAAW,GAAG;CAC/E,IAAI,IAAI,WAAW,MAAM,KAAK,cAAc,KAAK,UAAU,IAAI,UAAU,GAAG;CAC5E,IAAI,IAAI,gBAAgB,MAAM,KAAK,mBAAmB,KAAK,UAAU,IAAI,eAAe,GAAG;CAC3F,IAAI,IAAI,WAAW,MAAM,KAAK,cAAc,KAAK,UAAU,IAAI,UAAU,GAAG;CAC5E,IAAI,IAAI,iBAAiB,MAAM,KAAK,oBAAoB,KAAK,UAAU,IAAI,gBAAgB,GAAG;CAC9F,IAAI,IAAI,kBAAkB,MAAM,KAAK,qBAAqB,KAAK,UAAU,IAAI,iBAAiB,GAAG;CACjG,IAAI,IAAI,8BACN,MAAM,KAAK,iCAAiC,KAAK,UAAU,IAAI,6BAA6B,GAAG;CACjG,IAAI,MAAM,WAAW,GAAG,OAAO,KAAA;CAC/B,OAAO,KAAK,MAAM,KAAK,KAAK,CAAC;;AAG/B,IAAM,2BAAN,MAAyE;CACvE,YAAY,KAAiC;EAC3C,MAAM,UAAU,cAAc,IAAI,KAAK;EACvC,MAAM,OAAO,cAAc,IAAI;EAC/B,OAAO,OACH,MAAM,IAAI,WAAW,eAAe,QAAQ,IAAI,KAAK,KACrD,MAAM,IAAI,WAAW,eAAe,QAAQ;;CAGlD,UAAU,KAA+B;EACvC,OAAO,MAAM,IAAI,WAAW,aAAa,KAAK,UAAU,IAAI,KAAK,CAAC;;CAGpE,iBAAiB,KAAsC;EACrD,MAAM,OAAO,8BAA8B,IAAI;EAC/C,OAAO,OACH,uBAAuB,KAAK,UAAU,IAAI,WAAW,CAAC,IAAI,KAAK,KAC/D,uBAAuB,KAAK,UAAU,IAAI,WAAW,CAAC;;CAG5D,eAAe,KAAoC;EACjD,OAAO,MAAM,IAAI,WAAW;;CAG9B,QAAQ,KAA6B;EACnC,MAAM,QAAkB,CAAC,YAAY,KAAK,UAAU,IAAI,WAAW,GAAG;EACtE,IAAI,IAAI,WAAW,MAAM,KAAK,cAAc,KAAK,UAAU,IAAI,UAAU,GAAG;EAC5E,IAAI,IAAI,iBAAiB,MAAM,KAAK,oBAAoB,KAAK,UAAU,IAAI,gBAAgB,GAAG;EAC9F,IAAI,IAAI,kBACN,MAAM,KAAK,qBAAqB,KAAK,UAAU,IAAI,iBAAiB,GAAG;EACzE,IAAI,IAAI,8BACN,MAAM,KACJ,iCAAiC,KAAK,UAAU,IAAI,6BAA6B,GAClF;EACH,OAAO,mBAAmB,MAAM,KAAK,KAAK,CAAC;;;AAI/C,MAAM,YAAY,IAAI,0BAA0B;AAMhD,SAAgB,sBAAsB,YAAyD;CAC7F,MAAM,aAAuB,EAAE;CAC/B,KAAK,MAAM,aAAa,YAAY;EAClC,MAAM,YAAY;EAClB,IAAI,EAAE,aAAa,cAAc,CAAC,MAAM,QAAQ,UAAU,WAAW,EACnE;EAEF,KAAK,MAAM,QAAQ,UAAU,YAC3B,IAAI,KAAK,WAAW,OAAO,KAAK,QAAQ,WAAW,YACjD,WAAW,KAAK,KAAK,QAAQ,OAAO,UAAU,CAAC;;CAIrD,OAAO;;;;ACjGT,SAAS,eAAe,KAA8B,MAAuB;CAC3E,MAAM,QAAQ,KAAK,MAAM,IAAI;CAC7B,IAAI,UAAmB;CACvB,KAAK,MAAM,QAAQ,OAAO;EACxB,IAAI,YAAY,QAAQ,YAAY,KAAA,KAAa,OAAO,YAAY,UAClE;EAEF,MAAM,SAAS;EACf,IAAI,CAAC,OAAO,OAAO,QAAQ,KAAK,EAC9B;EAEF,UAAU,OAAO;;CAEnB,OAAO;;AAGT,SAAS,gBAAgB,IAAY,QAAiB,UAA+B;CACnF,QAAQ,IAAR;EACE,KAAK,OACH,OAAO,UAAU,QAAQ,SAAS;EACpC,KAAK,OACH,OAAO,CAAC,UAAU,QAAQ,SAAS;EACrC,KAAK,OACH,OAAO,OAAO,WAAW,OAAO,YAAa,SAAqB;EACpE,KAAK,QACH,OAAO,OAAO,WAAW,OAAO,YAAa,UAAsB;EACrE,KAAK,OACH,OAAO,OAAO,WAAW,OAAO,YAAa,SAAqB;EACpE,KAAK,QACH,OAAO,OAAO,WAAW,OAAO,YAAa,UAAsB;EACrE,KAAK,OACH,OAAO,MAAM,QAAQ,SAAS,IAAI,SAAS,MAAM,MAAM,UAAU,QAAQ,EAAE,CAAC;EAC9E,SACE,MAAM,IAAI,MAAM,mDAAmD,KAAK;;;AAI9E,IAAa,kBAAb,MAAoE;CAClE,MAAuC,EAAE;CAEzC,SAAS,QAAyB,KAAuC;EACvE,KAAK,MAAM;EACX,OAAO,OAAO,OAAO,KAAK;;CAG5B,MAAM,MAAiC;EACrC,MAAM,QAAQ,eAAe,KAAK,KAAK,KAAK,MAAM;EAClD,OAAO,gBAAgB,KAAK,IAAI,OAAO,KAAK,MAAM;;CAGpD,IAAI,MAA6B;EAC/B,OAAO,KAAK,MAAM,OAAO,UAAU,MAAM,OAAO,KAAK,CAAC;;CAGxD,GAAG,MAA4B;EAC7B,OAAO,KAAK,MAAM,MAAM,UAAU,MAAM,OAAO,KAAK,CAAC;;CAGvD,IAAI,MAA6B;EAC/B,OAAO,CAAC,KAAK,KAAK,OAAO,KAAK;;CAGhC,OAAO,MAAgC;EACrC,MAAM,MAAM,eAAe,KAAK,KAAK,KAAK,MAAM,KAAK,KAAA;EACrD,OAAO,KAAK,SAAS,MAAM,CAAC;;CAG9B,KAAK,OAAiC;EACpC,MAAM,IAAI,MAAM,uEAAuE;;;;;ACxE3F,MAAM,aAAa;;;;;;;;;;;;AAanB,MAAM,uBAAuB,KAAK;CAChC,OAAO;CACP,aAAa;CACb,aAAa;CACb,iBAAiB;CACjB,qBAAqB;CACrB,cAAc;CACd,WAAW;CACX,SAAS,KAAK,EAAE,YAAY,WAAW,CAAC,CAAC,GAAG,OAAO;CACnD,eAAe,KAAK,SAAS,CAAC,OAAO;CACrC,KAAK;CACN,CAAC;AAEF,SAAS,oBAAoB,KAAoC;CAC/D,MAAM,SAAS,qBAAqB,IAAI;CACxC,IAAI,kBAAkB,KAAK,QACzB,MAAM,IAAI,MAAM,yBAAyB,WAAW,IAAI,OAAO,UAAU;CAE3E,OAAO;EACL,aAAa,OAAO;EACpB,aAAa,OAAO;EACpB,cAAc,OAAO,gBAAgB;EACrC,kBAAkB,OAAO,oBAAoB;EAC7C,WAAW,OAAO,6BAAa,IAAI,MAAM;EACzC,QAAQ,OAAO,UAAU;EACzB,MAAO,OAAO,QAA2C,EAAE;EAC3D,YAAY,OAAO,cAAc,EAAE;EACpC;;AAGH,eAAe,iBAAiB,IAAQ,KAA+C;CACrF,OAAO,GACJ,WAAW,IAAI,WAAW,CAC1B,UAAU,IAAI,SAAsC,CACpD,SAAS;;AAGd,eAAe,iBAAiB,IAAQ,KAAyC;CAC/E,MAAM,GAAG,WAAW,IAAI,WAAW,CAAC,UAAU,IAAI,SAAS;;AAG7D,eAAe,wBACb,IACA,KAC0B;CAM1B,OAAO,GACJ,WAAW,IAAI,WAAW,CAC1B,iBAAiB,IAAI,QAAQ,IAAI,QAA+C,EAC/E,QAAQ,IAAI,QACb,CAAC;;;;;;;;AASN,eAAsB,WAAW,IAAQ,OAAqD;CAM5F,MAAM,OAAM,MADO,iBAAiB,IAAI,IAJxB,oBAAoB,YAAY,CAC9C,EAAE,QAAQ;EAAE,KAAK;EAAO;EAAO,EAAE,EACjC,EAAE,QAAQ,GAAG,CACd,CAC0C,CAAC,EAC3B;CACjB,IAAI,CAAC,KAAK,OAAO;CACjB,OAAO,oBAAoB,IAAI;;;;;;;;;;;;;AAcjC,eAAsB,eAAe,IAA4D;CAU/F,MAAM,OAAO,MAAM,iBAAiB,IAAI,IATxB,oBAAoB,YAAY,CAC9C,EACE,QAAQ;EACN,KAAK,EAAE,OAAO,UAAU;EACxB,OAAO,EAAE,OAAO,UAAU;EAC1B,OAAO,EAAE,KAAK,CAAC,QAAQ,SAAS,EAAE;EACnC,EACF,CACF,CAC0C,CAAC;CAC5C,MAAM,sBAAM,IAAI,KAAmC;CACnD,KAAK,MAAM,OAAO,MAAM;EACtB,MAAM,QAAQ,IAAI;;EAElB,IAAI,OAAO,UAAU,UAAU;EAC/B,IAAI,IAAI,OAAO,oBAAoB,IAAI,CAAC;;CAE1C,OAAO;;AAGT,eAAsB,WACpB,IACA,OACA,aAKe;CAaf,MAAM,iBAAiB,IAAI,IAZX,oBAAoB,YAAY;EAC9C,KAAK;EACL;EACA,aAAa,YAAY;EACzB,aAAa,YAAY;EACzB,cAAc;EACd,kBAAkB;EAClB,2BAAW,IAAI,MAAM;EACrB,QAAQ;EACR,MAAM,EAAE;EACR,YAAY,YAAY,cAAc,EAAE;EACzC,CAC6B,CAAC;;;;;;;;;;;;AAajC,eAAsB,aACpB,IACA,OACA,cACA,aAKkB;CAClB,MAAM,UAAmC;EACvC,aAAa,YAAY;EACzB,aAAa,YAAY;EACzB,2BAAW,IAAI,MAAM;EACtB;CAKD,MAAM,SACJ,YAAY,eAAe,KAAA,IACvB,EAAE,MAAM,SAAS,GACjB,CACE,EACE,MAAM;EACJ,GAAG;EACH,YAAY,EACV,YAAY;GACV,OAAO,EAAE,WAAW,CAAC,EAAE,SAAS,CAAC,eAAe,EAAE,CAAC,EAAE,EAAE,YAAY,WAAW,EAAE;GAChF,QAAQ;GACT,EACF;EACF,EACF,CACF;CAQP,OAAO,MADc,wBAAwB,IAAI,IANjC,2BACd,YACA;EAAE,KAAK;EAAO;EAAO,aAAa;EAAc,EAChD,QACA,MAEkD,CAAC,KACnC;;;;;;;;;;;;AAapB,eAAsB,iBACpB,IACA,OACA,OACe;CASf,MAAM,iBAAiB,IAAI,IARX,oBAAoB,YAAY;EAC9C,MAAM;EACN;EACA,QAAQ,MAAM;EACd,MAAM,MAAM;EACZ,IAAI,MAAM;EACV,2BAAW,IAAI,MAAM;EACtB,CAC6B,CAAC;;;;AChLjC,MAAM,kBAAkB,KAAK;CAC3B,MAAM;CACN,YAAY;CACZ,MALmB,KAAK;EAAE,OAAO;EAAU,WADnB,KAAK,yDAC0C;EAAE,CAKvD,CAAC,OAAO,CAAC,cAAc,EAAE;CAC3C,WAAW;CACX,WAAW;CACX,uBAAuB;CACvB,4BAA4B;CAC5B,SAAS;CACT,uBAAuB;CACvB,cAAc;CACd,YAAY;CACZ,qBAAqB;CACrB,sBAAsB;CACvB,CAAC;AAEF,MAAM,gBAAgB,KAAK;CACzB,MAAM;CACN,YAAY;CACZ,MAAM;CACP,CAAC;AAEF,MAAM,uBAAuB,KAAK;CAChC,MAAM;CACN,YAAY;CACZ,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,WAAW;CACX,SAAS;CACT,QAAQ;CACR,eAAe;CACf,cAAc;CACd,iCAAiC;CACjC,mBAAmB;CACpB,CAAC;AAEF,MAAM,qBAAqB,KAAK;CAC9B,MAAM;CACN,YAAY;CACb,CAAC;AAEF,MAAM,cAAc,KAAK;CACvB,MAAM;CACN,YAAY;CACZ,cAAc;CACd,oBAAoB;CACpB,qBAAqB;CACrB,iCAAiC;CAClC,CAAC;AAEF,MAAM,kBAAkB,KAAK;CAC3B,MAAM;CACN,YAAY;CACb,CAAC;AAEF,MAAM,sBAAsB,KAAK,EAC/B,MAAM,uBACP,CAAC;AAEF,MAAM,kBAAkB,KAAK;CAC3B,MAAM;CACN,OAAO;CACP,IAAI;CACJ,OAAO;CACR,CAAC;AAEF,MAAM,mBAAmB,KAAK;CAC5B,MAAM;CACN,OAAO;CACP,QAAQ;CACT,CAAC;AAMF,MAAM,mBAAmB,KAAK;CAC5B,MAAM;CACN,YAAY;CACZ,UAAU;CACX,CAAC;AAEF,MAAM,oBAAoB,KAAK;CAC7B,MAAM;CACN,YAAY;CACZ,WAAW;CACZ,CAAC;AAEF,MAAM,mBAAmB,KAAK;CAC5B,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,QAAQ;CACT,CAAC;AAEF,MAAM,oBAAoB,KAAK;CAC7B,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,QAAQ;CACT,CAAC;AAEF,MAAM,mBAAmB,KAAK;CAC5B,MAAM;CACN,YAAY;CACZ,QAAQ;CACT,CAAC;AAEF,MAAM,oBAAoB,KAAK;CAC7B,MAAM;CACN,YAAY;CACZ,QAAQ;CACT,CAAC;AAEF,MAAM,mBAAmB,KAAK;CAC5B,MAAM;CACN,YAAY;CACZ,UAAU;CACX,CAAC;AAEF,MAAM,0BAA0B,KAAK;CACnC,MAAM;CACN,YAAY;CACZ,QAAQ;CACR,QAAQ;CACR,QAAQ;CACT,CAAC;AAEF,MAAM,0BAA0B,KAAK;CACnC,MAAM;CACN,YAAY;CACZ,QAAQ;CACT,CAAC;AAEF,MAAM,qBAAqB,KAAK;CAC9B,MAAM;CACN,YAAY;CACZ,UAAU;CACX,CAAC;AAWF,MAAM,gBAAgB,KAAK;CACzB,YAAY;CACZ,SAAS;CACT,MAZmB,KAAK;EACxB,QAAQ;EACR,aAAa;EACb,MAAM;EACN,iBAAiB;EACjB,gBAAgB;EAChB,gBAAgB;EACjB,CAKmB;CACnB,CAAC;AAMF,MAAM,YAAY,KAAK;CACrB,aAAa;CACb,QAAQ;CACR,QAAQ;CACR,QAAQ;CACT,CAAC;AAEF,MAAM,WAAW,KAAK;CACpB,aAAa;CACb,SAAS;CACV,CAAC;AAEF,MAAM,mBAAmB,KAAK;CAC5B,IAAI;CACJ,OAAO;CACP,gBAAgB;CAChB,UAAU;CACV,SAAS;CACT,WAAW;CACZ,CAAC;AAEF,MAAM,yBAAyB,KAAK;CAClC,aAAa;CACb,QAAQ;CACR,QAAQ;CACR,QAAQ;CACT,CAAC;AAEF,MAAM,6BAA6B,KAAK;CACtC,IAAI;CACJ,OAAO;CACP,gBAAgB;CAChB,MAAM;CACN,UAAU;CACV,KAAK;CACL,WAAW;CACZ,CAAC;AAEF,SAAS,SAAY,QAA0C,MAAe,SAAoB;CAChG,IAAI;EACF,OAAO,OAAO,OAAO,mBAAmB,KAAK,CAAC;UACvC,OAAO;;EAEd,MAAM,UAAU,iBAAiB,QAAQ,MAAM,UAAU,OAAO,MAAM;;EAEtE,MAAM,IAAI,MAAM,WAAW,QAAQ,IAAI,UAAU;;;;;;;;;;;;;;;;;;;;;;;AAwBrD,SAAS,mBAAmB,OAAyB;CACnD,IAAI,MAAM,QAAQ,MAAM,EAAE;EACxB,IAAI,UAAU;EACd,MAAM,OAAO,MAAM,KAAK,SAAS;GAC/B,MAAM,WAAW,mBAAmB,KAAK;GACzC,IAAI,aAAa,MAAM,UAAU;GACjC,OAAO;IACP;EACF,OAAO,UAAU,OAAO;;CAE1B,IAAI,UAAU,QAAQ,OAAO,UAAU,UACrC,OAAO;CAET,MAAM,UAAU,OAAO,QAAQ,MAAiC;CAChE,MAAM,MAA+B,EAAE;CACvC,IAAI,UAAU;CACd,KAAK,MAAM,CAAC,KAAK,QAAQ,SAAS;EAChC,IAAI,QAAQ,KAAA,GAAW;GACrB,UAAU;GACV;;EAEF,MAAM,WAAW,mBAAmB,IAAI;EACxC,IAAI,aAAa,KAAK,UAAU;EAChC,IAAI,OAAO;;CAEb,OAAO,UAAU,MAAM;;AAGzB,SAAS,sBAAsB,MAAgC;CAC7D,MAAM,SAAS;CACf,MAAM,OAAO,OAAO;CACpB,QAAQ,MAAR;EACE,KAAK,SAAS;GACZ,MAAM,OAAO,SAAS,iBAAiB,MAAM,eAAe;GAC5D,OAAO,iBAAiB,GAAG,KAAK,OAAO,KAAK,IAAI,KAAK,MAAe;;EAEtE,KAAK,OAAO;GACV,MAAM,QAAQ,OAAO;GACrB,IAAI,CAAC,MAAM,QAAQ,MAAM,EAAE,MAAM,IAAI,MAAM,0CAA0C;GACrF,OAAO,aAAa,GAAG,MAAM,IAAI,sBAAsB,CAAC;;EAE1D,KAAK,MAAM;GACT,MAAM,QAAQ,OAAO;GACrB,IAAI,CAAC,MAAM,QAAQ,MAAM,EAAE,MAAM,IAAI,MAAM,yCAAyC;GACpF,OAAO,YAAY,GAAG,MAAM,IAAI,sBAAsB,CAAC;;EAEzD,KAAK,OAAO;GACV,MAAM,OAAO,OAAO;GACpB,IAAI,CAAC,QAAQ,OAAO,SAAS,UAAU,MAAM,IAAI,MAAM,mCAAmC;GAC1F,OAAO,IAAI,aAAa,sBAAsB,KAAK,CAAC;;EAEtD,KAAK,UAAU;GACb,MAAM,OAAO,SAAS,kBAAkB,MAAM,gBAAgB;GAC9D,OAAO,IAAI,gBAAgB,KAAK,OAAO,KAAK,OAAO;;EAErD,SACE,MAAM,IAAI,MAAM,mCAAmC,OAAO;;;AAQhE,SAAgB,yBAAyB,MAAmC;CAC1E,MAAM,SAAS;CACf,MAAM,OAAO,OAAO;CACpB,QAAQ,MAAR;EACE,KAAK,SACH,OAAO,IAAI,gBAAgB,sBAAsB,OAAO,UAAU,CAAC;EACrE,KAAK,SACH,OAAO,IAAI,gBAAgB,OAAO,SAAmB;EACvD,KAAK,QACH,OAAO,IAAI,eAAe,OAAO,QAAkC;EACrE,KAAK,WACH,OAAO,IAAI,kBAAkB,OAAO,cAAuC;EAC7E,KAAK,aACH,OAAO,IAAI,oBAAoB,OAAO,UAAmC;EAC3E,KAAK,UAAU;GACb,MAAM,OAOF;IACF,MAAM,OAAO;IACb,IAAI,OAAO;IACZ;GACD,IAAI,OAAO,kBAAkB,KAAA,GAAW,KAAK,aAAa,OAAO;GACjE,IAAI,OAAO,oBAAoB,KAAA,GAC7B,KAAK,eAAe,OAAO;GAC7B,IAAI,OAAO,gBAAgB,KAAA,GACzB,KAAK,WAAY,OAAO,YAA0B,IAAI,yBAAyB;GACjF,IAAI,OAAO,YAAY,KAAA,GAAW,KAAK,OAAO,OAAO;GACrD,OAAO,IAAI,iBAAiB,KAAK;;EAEnC,KAAK,SAAS;GACZ,MAAM,OAKF,EACF,MAAM,OAAO,SACd;GACD,IAAI,OAAO,UAAU,KAAA,GAAW,KAAK,KAAK,OAAO;GACjD,IAAI,OAAO,mBAAmB,KAAA,GAAW;IACvC,MAAM,KAAK,OAAO;IAClB,KAAK,cACH,OAAO,OAAO,WACV,KACE,GAAiB,IAAI,yBAAyB;;GAExD,IAAI,OAAO,sBAAsB,KAAA,GAC/B,KAAK,iBAAiB,OAAO;GAC/B,OAAO,IAAI,gBAAgB,KAAK;;EAElC,SACE,MAAM,IAAI,MAAM,gCAAgC,OAAO;;;AAQ7D,SAAgB,sBAAsB,MAAgC;CAEpE,MAAM,OAAOA,KAAO;CACpB,QAAQ,MAAR;EACE,KAAK,gBAAgB;GACnB,MAAM,OAAO,SAAS,kBAAkB,MAAM,uBAAuB;GACrE,OAAO,IAAI,oBAAoB,KAAK,YAAY,KAAK,SAAS;;EAEhE,KAAK,iBAAiB;GACpB,MAAM,OAAO,SAAS,mBAAmB,MAAM,wBAAwB;GACvE,OAAO,IAAI,qBAAqB,KAAK,YAAY,KAAK,UAAU;;EAElE,KAAK,gBAAgB;GACnB,MAAM,OAAO,SAAS,kBAAkB,MAAM,uBAAuB;GACrE,OAAO,IAAI,oBAAoB,KAAK,YAAY,KAAK,QAAQ,KAAK,OAAO;;EAE3E,KAAK,iBAAiB;GACpB,MAAM,OAAO,SAAS,mBAAmB,MAAM,wBAAwB;GACvE,OAAO,IAAI,qBAAqB,KAAK,YAAY,KAAK,QAAQ,KAAK,OAAO;;EAE5E,KAAK,gBAAgB;GACnB,MAAM,OAAO,SAAS,kBAAkB,MAAM,uBAAuB;GACrE,OAAO,IAAI,oBAAoB,KAAK,YAAY,KAAK,OAAO;;EAE9D,KAAK,iBAAiB;GACpB,MAAM,OAAO,SAAS,mBAAmB,MAAM,wBAAwB;GACvE,OAAO,IAAI,qBAAqB,KAAK,YAAY,KAAK,OAAO;;EAE/D,KAAK,gBAAgB;GACnB,MAAM,OAAO,SAAS,kBAAkB,MAAM,uBAAuB;GACrE,OAAO,IAAI,oBAAoB,KAAK,YAAY,KAAK,SAAS;;EAEhE,KAAK,uBAAuB;GAC1B,MAAM,OAAO,SAAS,yBAAyB,MAAM,8BAA8B;GACnF,OAAO,IAAI,2BAA2B,KAAK,YAAY,KAAK,QAAQ,KAAK,QAAQ,KAAK,OAAO;;EAE/F,KAAK,uBAAuB;GAC1B,MAAM,OAAO,SAAS,yBAAyB,MAAM,8BAA8B;GACnF,OAAO,IAAI,2BAA2B,KAAK,YAAY,KAAK,OAAO;;EAErE,KAAK,aAAa;GAChB,MAAM,OAAO,SAAS,oBAAoB,MAAM,oBAAoB;GACpE,MAAM,WAAW,KAAK,SAAS,IAAI,yBAAyB;GAC5D,OAAO,IAAI,iBAAiB,KAAK,YAAY,SAAS;;EAExD,SACE,MAAM,IAAI,MAAM,6BAA6B,OAAO;;;AAQ1D,SAAgB,0BAA0B,MAA+B;CACvE,MAAM,OAAO,SAAS,eAAe,MAAM,mBAAmB;CAC9D,MAAM,UAAU,sBAAsB,KAAK,QAAQ;CACnD,MAAM,IAAI,KAAK;CACf,MAAM,OAAiB;EACrB,QAAQ,EAAE;EACV,aAAa,EAAE;EACf,MAAM,EAAE;EACR,GAAG,UAAU,gBAAgB,EAAE,aAAa;EAC5C,GAAG,UAAU,eAAe,EAAE,YAAY;EAC1C,GAAG,UAAU,eAAe,EAAE,YAAY;EAC3C;CACD,OAAO;EAAE,YAAY,KAAK;EAAY;EAAS;EAAM;;AAOvD,SAAS,sBAAsB,MAAmC;CAEhE,MAAM,OAAOA,KAAO;CACpB,QAAQ,MAAR;EACE,KAAK,eAAe;GAClB,MAAM,OAAO,SAAS,iBAAiB,MAAM,sBAAsB;GACnE,OAAO,IAAI,mBAAmB,KAAK,YAAY,KAAK,MAAM;IACxD,QAAQ,KAAK;IACb,QAAQ,KAAK;IACb,oBAAoB,KAAK;IACzB,yBAAyB,KAAK;IAC9B,MAAM,KAAK;IACX,oBAAoB,KAAK;IACzB,WAAW,KAAK;IAChB,SAAS,KAAK;IACd,kBAAkB,KAAK;IACvB,mBAAmB,KAAK;IACzB,CAAC;;EAEJ,KAAK,aAAa;GAChB,MAAM,OAAO,SAAS,eAAe,MAAM,oBAAoB;GAC/D,OAAO,IAAI,iBAAiB,KAAK,YAAY,KAAK,KAAK;;EAEzD,KAAK,oBAAoB;GACvB,MAAM,OAAO,SAAS,sBAAsB,MAAM,2BAA2B;GAC7E,OAAO,IAAI,wBAAwB,KAAK,YAAY;IAClD,WAAW,KAAK;IAChB,iBAAiB,KAAK;IACtB,kBAAkB,KAAK;IACvB,QAAQ,KAAK;IACb,MAAM,KAAK;IACX,KAAK,KAAK;IACV,YAAY,KAAK;IACjB,WAAW,KAAK;IAChB,8BAA8B,KAAK;IAGnC,gBAAgB,KAAK;IACtB,CAAC;;EAEJ,KAAK,kBAEH,OAAO,IAAI,sBADE,SAAS,oBAAoB,MAAM,yBACX,CAAC,WAAW;EAEnD,KAAK,WAAW;GACd,MAAM,OAAO,SAAS,aAAa,MAAM,kBAAkB;GAC3D,OAAO,IAAI,eAAe,KAAK,YAAY;IACzC,WAAW,KAAK;IAChB,iBAAiB,KAAK;IACtB,kBAAkB,KAAK;IACvB,8BAA8B,KAAK;IAGpC,CAAC;;EAEJ,SACE,MAAM,IAAI,MAAM,6BAA6B,OAAO;;;AAI1D,SAAS,6BAA6B,MAA0C;CAE9E,MAAM,OAAOA,KAAO;CACpB,QAAQ,MAAR;EACE,KAAK,eAEH,OAAO,IAAI,mBADE,SAAS,iBAAiB,MAAM,sBACX,CAAC,WAAW;EAEhD,KAAK;GACH,SAAS,qBAAqB,MAAM,0BAA0B;GAC9D,OAAO,IAAI,wBAAwB;EAErC,SACE,MAAM,IAAI,MAAM,oCAAoC,OAAO;;;AAIjE,SAAS,iBAAiB,MAAoC;CAC5D,MAAM,OAAO,SAAS,WAAW,MAAM,kBAAkB;CACzD,OAAO;EACL,aAAa,KAAK;EAClB,QAAQ,6BAA6B,KAAK,OAAO;EACjD,QAAQ,sBAAsB,KAAK,OAAO;EAC1C,QAAQ,KAAK;EACd;;AAGH,SAAS,gBAAgB,MAAmC;CAC1D,MAAM,OAAO,SAAS,UAAU,MAAM,iBAAiB;CACvD,OAAO;EACL,aAAa,KAAK;EAClB,SAAS,sBAAsB,KAAK,QAAQ;EAC7C;;AAGH,SAAS,oBAAoB,MAAwB;CACnD,OACE,OAAO,SAAS,YAChB,SAAS,QACR,KAAiC,sBAAsB;;AAI5D,SAAS,iBAAiB,MAA4C;CACpE,MAAM,OAAO,SAAS,kBAAkB,MAAM,sBAAsB;CACpE,OAAO;EACL,IAAI,KAAK;EACT,OAAO,KAAK;EACZ,gBAAgB,KAAK;EACrB,UAAU,KAAK,SAAS,IAAI,iBAAiB;EAC7C,SAAS,KAAK,QAAQ,IAAI,gBAAgB;EAC1C,WAAW,KAAK,UAAU,IAAI,iBAAiB;EAChD;;AAGH,SAAS,8BAA8B,MAAwC;CAC7E,MAAM,OAAO,SAAS,wBAAwB,MAAM,uBAAuB;CAC3E,OAAO;EACL,aAAa,KAAK;EAClB,QAAQ,0BAA0B,KAAK,OAAO;EAC9C,QAAQ,sBAAsB,KAAK,OAAO;EAC1C,QAAQ,KAAK;EACd;;AAGH,SAAS,2BAA2B,MAA4C;CAC9E,MAAM,OAAO,SAAS,4BAA4B,MAAM,2BAA2B;CACnF,OAAO;EACL,IAAI,KAAK;EACT,OAAO,KAAK;EACZ,gBAAgB;EAChB,MAAM,KAAK;EACX,UAAU,KAAK,SAAS,IAAI,8BAA8B;EAC1D,KAAK,KAAK,IAAI,IAAI,0BAA0B;EAC5C,WAAW,KAAK,UAAU,IAAI,8BAA8B;EAC7D;;AAGH,SAAgB,mBAAmB,MAA2C;CAC5E,IAAI,oBAAoB,KAAK,EAC3B,OAAO,2BAA2B,KAAK;CAEzC,OAAO,iBAAiB,KAAK;;AAG/B,SAAgB,oBAAoB,MAAwD;CAC1F,OAAO,KAAK,IAAI,mBAAmB;;AAGrC,SAAgB,kBAAkB,KAAoD;CACpF,OAAO,KAAK,UAAU,KAAK,MAAM,EAAE;;;;ACvkBrC,MAAM,0BAA0B;AAEhC,IAAe,oBAAf,cAAyC,aAA+C;CAMtF,qBAAmD;EACjD,OAAO,CAAC;GAAE,iBAAiB;GAAyB,QAAQ,KAAK;GAAa,CAAC;;CAGjF,SAAyB;EACvB,OAAO,OAAO,KAAK;;;AAIvB,SAAS,WAAW,MAA4C;CAC9D,OAAO,KAAK,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,YAAY,CAAC,KAAK,KAAK;;AAGhE,IAAa,kBAAb,cAAqC,kBAAkB;CACrD,cAAuB;CACvB,iBAA0B;CAC1B;CACA;CACA;CACA;CAEA,YACE,YACA,MACA,SACA;EACA,OAAO;EACP,KAAK,aAAa;EAClB,KAAK,OAAO;EACZ,KAAK,UAAU;EACf,KAAK,QAAQ,mBAAmB,WAAW,IAAI,WAAW,KAAK,CAAC;EAChE,KAAK,QAAQ;;CAGf,OAAoC;EAClC,OAAO,YAAY,KAAK,YAAY,KAAK,MAAM,KAAK,QAAQ;;CAG9D,mBAA2B;EACzB,OAAO,KAAK,UACR,eAAe,eAAe,KAAK,WAAW,CAAC,IAAI,eAAe,KAAK,KAAK,CAAC,IAAI,eAAe,KAAK,QAAQ,CAAC,KAC9G,eAAe,eAAe,KAAK,WAAW,CAAC,IAAI,eAAe,KAAK,KAAK,CAAC;;;AAIrF,IAAa,gBAAb,cAAmC,kBAAkB;CACnD,cAAuB;CACvB,iBAA0B;CAC1B;CACA;CACA;CAEA,YAAY,YAAoB,MAAoC;EAClE,OAAO;EACP,KAAK,aAAa;EAClB,KAAK,OAAO;EACZ,KAAK,QAAQ,iBAAiB,WAAW,IAAI,WAAW,KAAK,CAAC;EAC9D,KAAK,QAAQ;;CAGf,OAAoC;EAClC,OAAO,UAAU,KAAK,YAAY,KAAK,KAAK;;CAG9C,mBAA2B;EACzB,OAAO,aAAa,eAAe,KAAK,WAAW,CAAC,IAAI,eAAe,KAAK,KAAK,CAAC;;;AAItF,IAAa,uBAAb,cAA0C,kBAAkB;CAC1D,cAAuB;CACvB,iBAA0B;CAC1B;CACA;CACA;CAEA,YAAY,YAAoB,SAAmC;EACjE,OAAO;EACP,KAAK,aAAa;EAClB,KAAK,UAAU;EACf,KAAK,QAAQ,qBAAqB;EAClC,KAAK,QAAQ;;CAGf,OAAoC;EAClC,OAAO,iBAAiB,KAAK,YAAY,KAAK,QAAQ;;CAGxD,mBAA2B;EACzB,OAAO,KAAK,UACR,oBAAoB,eAAe,KAAK,WAAW,CAAC,IAAI,eAAe,KAAK,QAAQ,CAAC,KACrF,oBAAoB,eAAe,KAAK,WAAW,CAAC;;;AAI5D,IAAa,qBAAb,cAAwC,kBAAkB;CACxD,cAAuB;CACvB,iBAA0B;CAC1B;CACA;CAEA,YAAY,YAAoB;EAC9B,OAAO;EACP,KAAK,aAAa;EAClB,KAAK,QAAQ,mBAAmB;EAChC,KAAK,QAAQ;;CAGf,OAAoC;EAClC,OAAO,eAAe,KAAK,WAAW;;CAGxC,mBAA2B;EACzB,OAAO,kBAAkB,eAAe,KAAK,WAAW,CAAC;;;AAI7D,IAAa,cAAb,cAAiC,kBAAkB;CACjD,cAAuB;CACvB;CACA;CACA;CACA;CACA;CAEA,YAAY,YAAoB,SAAyB,MAAoB;EAC3E,OAAO;EACP,KAAK,aAAa;EAClB,KAAK,UAAU;EACf,KAAK,OAAO;EACZ,KAAK,iBAAiB,MAAM,kBAAkB;EAC9C,KAAK,QAAQ,MAAM,SAAS,qBAAqB;EACjD,KAAK,QAAQ;;CAGf,OAAoC;EAClC,OAAO,QAAQ,KAAK,YAAY,KAAK,SAAS,KAAK,KAAK;;CAG1D,mBAA2B;EACzB,OAAO,KAAK,OACR,WAAW,eAAe,KAAK,WAAW,CAAC,IAAI,eAAe,KAAK,QAAQ,CAAC,IAAI,eAAe,KAAK,KAAK,CAAC,KAC1G,WAAW,eAAe,KAAK,WAAW,CAAC,IAAI,eAAe,KAAK,QAAQ,CAAC;;;AAWpF,SAAgB,gCAAgC,OAA6C;CAC3F,OAAO;EACL,QAAQ,MAAM,UAAU,KAAA;EACxB,QAAQ,MAAM;EACd,oBAAoB,MAAM;EAC1B,yBAAyB,MAAM;EAC/B,oBAAoB,MAAM;EAC1B,WAAW,MAAM;EACjB,SAAS,MAAM;EACf,kBAAkB,MAAM;EACxB,mBAAmB,MAAM;EAC1B;;AAGH,SAAgB,0CACd,MACqC;CACrC,MAAM,OAAiD,KAAK;CAC5D,MAAM,YAA8C,KAAK;CACzD,IAAI,CAAC,QAAQ,CAAC,WAAW,OAAO,KAAA;CAChC,OAAO;EACL,QAAQ,MAAM,SAAS,OAAO,KAAA;EAC9B,MAAM,MAAM,QAAQ;EACpB,KAAK,MAAM,QAAQ;EACnB,YAAY,MAAM;EAClB,WAAW,MAAM;EACjB,gBAAgB,MAAM,iBAClB;GACE,KAAK,EAAE,KAAK,GAAG;GACf,QAAQ;GACR,GAAI,KAAK,eAAe,QAAQ,OAAO,EAAE,MAAM,KAAK,eAAe,MAAM,GAAG,EAAE;GAC/E,GACD,KAAA;EACJ,WAAW,YAAY,EAAE,aAAa,UAAU,YAAY,GAAG,KAAA;EAC/D,iBAAiB,WAAW;EAC5B,kBAAkB,WAAW;EAC7B,8BAA8B,MAAM;EACrC;;;;ACtPH,SAAgB,UAAU,OAAoE;CAC5F,OAAO,MAAM,KAAK,SAAS,KAAK,MAAM,CAAC;;;;;;;;;;;;;;;;;;;;ACsBzC,MAAM,eAA6C,CACjD;CAAE,iBAAiB;CAAuC,QAAQ;CAAa,EAC/E;CAAE,iBAAiB;CAAkC,QAAQ;CAAgB,CAC9E;;;;;;;;;;;;;;;;;;AAmBD,SAAgB,wBACd,OACA,MACQ;CACR,MAAM,UAAU,aAAa,MAAM;CACnC,MAAM,iBAAiB,MAAM,KAAK,MAAM,EAAE,kBAAkB,CAAC,CAAC,KAAK,MAAM;CAEzE,OAAO;EACL,eAAe,uBAAuB,CAAC;EACvC;EACA;EACA;EACA,oBAAoB,KAAK;EACzB;EACA;EACA,OAAO,gBAAgB,EAAE;EACzB;EACA;EACA;EACA;EACA;EACA;EACA;EACD,CAAC,KAAK,KAAK;;AAGd,SAAS,aAAa,OAA6C;CACjE,MAAM,eAAoC,CAAC,GAAG,aAAa;CAC3D,KAAK,MAAM,QAAQ,OACjB,KAAK,MAAM,OAAO,KAAK,oBAAoB,EACzC,aAAa,KAAK,IAAI;CAG1B,OAAO,cAAc,aAAa;;AAGpC,SAAS,oBAAoB,MAAmC;CAC9D,MAAM,QAAkB,EAAE;CAC1B,MAAM,KAAK,0BAA0B;CACrC,MAAM,KAAK,eAAe;CAC1B,MAAM,KAAK,eAAe,KAAK,UAAU,KAAK,KAAK,CAAC,GAAG;CACvD,MAAM,KAAK,aAAa,KAAK,UAAU,KAAK,GAAG,CAAC,GAAG;CACnD,IAAI,KAAK,UAAU,KAAK,OAAO,SAAS,GACtC,MAAM,KAAK,iBAAiB,eAAe,KAAK,OAAO,CAAC,GAAG;CAE7D,MAAM,KAAK,SAAS;CACpB,MAAM,KAAK,MAAM;CACjB,MAAM,KAAK,GAAG;CACd,OAAO,MAAM,KAAK,KAAK;;AAGzB,SAAS,OAAO,MAAc,QAAwB;CACpD,MAAM,MAAM,IAAI,OAAO,OAAO;CAC9B,OAAO,KACJ,MAAM,KAAK,CACX,KAAK,SAAU,KAAK,MAAM,GAAG,GAAG,MAAM,SAAS,KAAM,CACrD,KAAK,KAAK;;;;;;;;;;;;;;;;;;;;AChFf,IAAa,gCAAb,cACU,UAEV;CAIqB;CACA;CAJnB,WAAoB;CAEpB,YACE,OACA,MACA;EACA,OAAO;EAHU,KAAA,QAAA;EACA,KAAA,OAAA;;CAKnB,IAAa,aAAoD;EAC/D,OAAO,UAAU,KAAK,MAAM;;CAG9B,WAAmC;EACjC,OAAO,KAAK;;CAGd,mBAA2B;EACzB,OAAO,wBAAwB,KAAK,OAAO;GACzC,MAAM,KAAK,KAAK;GAChB,IAAI,KAAK,KAAK;GACd,GAAG,UAAU,UAAU,KAAK,KAAK,OAAO;GACzC,CAAC;;;;;ACjBN,SAAS,oBAAoB,OAAiC;CAC5D,MAAM,OAAO,MAAM,KAAK,KAAK,MAAM,GAAG,EAAE,MAAM,GAAG,EAAE,YAAY,CAAC,KAAK,IAAI;CACzE,MAAM,OAAO;EACX,MAAM,SAAS,WAAW;EAC1B,MAAM,SAAS,WAAW;EAC1B,MAAM,sBAAsB,OAAO,OAAO,MAAM,uBAAuB;EACvE,MAAM,0BAA0B,OAAO,aAAa,MAAM,wBAAwB,KAAK;EACvF,MAAM,qBAAqB,MAAM,aAAa,MAAM,mBAAmB,KAAK;EAC5E,MAAM,YAAY,OAAO,aAAa,MAAM,UAAU,KAAK;EAC3D,MAAM,UAAU,MAAM,aAAa,MAAM,QAAQ,KAAK;EACtD,MAAM,mBAAmB,MAAM,MAAM,qBAAqB;EAC1D,MAAM,oBAAoB,MAAM,MAAM,sBAAsB;EAC7D,CACE,OAAO,QAAQ,CACf,KAAK,IAAI;CACZ,OAAO,OAAO,GAAG,KAAK,GAAG,SAAS;;AAGpC,SAAS,gBACP,GACA,GACS;CACT,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;CACrB,IAAI,CAAC,KAAK,CAAC,GAAG,OAAO;CACrB,OACE,EAAE,oBAAoB,EAAE,mBACxB,EAAE,qBAAqB,EAAE,oBACzB,aAAa,EAAE,WAAW,KAAK,aAAa,EAAE,WAAW;;AAI7D,SAAS,wBACP,QACA,MAC4B;CAC5B,IAAI,iBAAiB;CAErB,IAAI,aAAa,OAAO,WAAW,KAAK,aAAa,KAAK,WAAW,EACnE,iBAAiB;CAGnB,IAAI,OAAO,qBAAqB,KAAK;MAC/B,KAAK,qBAAqB,SAAS,iBAAiB;;CAG1D,IAAI,OAAO,oBAAoB,KAAK;MAC9B,KAAK,oBAAoB,UAAU,iBAAiB;;CAG1D,OAAO,iBAAiB,gBAAgB;;AAG1C,SAAS,yBACP,QACA,MACoB;CACpB,IAAI,aAAa,QAAQ,OAAO,KAAK,aAAa,MAAM,OAAO,EAAE,OAAO;CACxE,IAAI,aAAa,QAAQ,WAAW,KAAK,aAAa,MAAM,WAAW,EAAE,OAAO;CAChF,IAAI,aAAa,QAAQ,UAAU,KAAK,aAAa,MAAM,UAAU,EAAE,OAAO;CAC9E,IAAI,aAAa,QAAQ,eAAe,KAAK,aAAa,MAAM,eAAe,EAC7E,OAAO;;AAIX,SAAS,qBAAqB,MAAsC;CAClE,OAAO,CAAC,EAAE,KAAK,WAAW,KAAK;;AAOjC,IAAa,wBAAb,MAAiF;CAC/E,UAAU,SAKU;EAClB,MAAM,WAAW,QAAQ;EACzB,MAAM,WAAW,QAAQ;EACzB,MAAM,gBAAgB,wBAAwB,SAAS;EAEvD,MAAM,cAA+B,EAAE;EACvC,MAAM,QAAyB,EAAE;EACjC,MAAM,UAA2B,EAAE;EACnC,MAAM,eAAgC,EAAE;EACxC,MAAM,mBAAoC,EAAE;EAC5C,MAAM,YAA6B,EAAE;EACrC,MAAM,YAAwC,EAAE;EAEhD,MAAM,qBAAqB,IAAI,IAAI,CACjC,GAAG,SAAS,iBACZ,GAAG,cAAc,gBAClB,CAAC;EAEF,KAAK,MAAM,YAAY,CAAC,GAAG,mBAAmB,CAAC,MAAM,EAAE;GACrD,MAAM,aAAa,SAAS,WAAW,SAAS;GAChD,MAAM,WAAW,cAAc,WAAW,SAAS;GAEnD,IAAI,CAAC;QAcC,aAAa,qBAAqB,SAAS,IAAI,SAAS,QAAQ,WAAW,IAAI;KACjF,MAAM,OAAO,qBAAqB,SAAS,GACvC,0CAA0C,SAAS,GACnD,KAAA;KACJ,YAAY,KAAK,IAAI,qBAAqB,UAAU,KAAK,CAAC;;UAEvD,IAAI,CAAC,UACV,UAAU,KAAK,IAAI,mBAAmB,SAAS,CAAC;QAC3C;IACL,MAAM,kBAAkB,yBAAyB,WAAW,SAAS,SAAS,QAAQ;IACtF,IAAI,iBACF,UAAU,KAAK;KACb,MAAM;KACN,SAAS,8CAA8C,gBAAgB,OAAO;KAC9E,KAAK,2CAA2C,gBAAgB;KACjE,CAAC;IAGJ,MAAM,cAAc,2BAClB,UACA,WAAW,SACX,SAAS,QACV;IACD,IAAI,aAAa,iBAAiB,KAAK,YAAY;IAEnD,MAAM,gBAAgB,sBACpB,UACA,WAAW,WACX,SAAS,UACV;IACD,IAAI,eAAe,aAAa,KAAK,cAAc;;GAGrD,MAAM,+BAAe,IAAI,KAA+B;GACxD,IAAI,YACF,KAAK,MAAM,OAAO,WAAW,SAC3B,aAAa,IAAI,oBAAoB,IAAI,EAAE,IAAI;GAInD,MAAM,6BAAa,IAAI,KAA+B;GACtD,IAAI,UACF,KAAK,MAAM,OAAO,SAAS,SACzB,WAAW,IAAI,oBAAoB,IAAI,EAAE,IAAI;GAIjD,KAAK,MAAM,CAAC,WAAW,QAAQ,cAC7B,IAAI,CAAC,WAAW,IAAI,UAAU,EAC5B,MAAM,KAAK,IAAI,cAAc,UAAU,IAAI,KAAK,CAAC;GAIrD,KAAK,MAAM,CAAC,WAAW,QAAQ,YAC7B,IAAI,CAAC,aAAa,IAAI,UAAU,EAC9B,QAAQ,KACN,IAAI,gBAAgB,UAAU,IAAI,MAAM,gCAAgC,IAAI,CAAC,CAC9E;;EAKP,IAAI,UAAU,SAAS,GACrB,OAAO;GAAE,MAAM;GAAW;GAAW;EAGvC,MAAM,WAAW;GACf,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACH,GAAG;GACJ;EAED,KAAK,MAAM,QAAQ,UACjB,IAAI,CAAC,QAAQ,OAAO,wBAAwB,SAAS,KAAK,eAAe,EACvE,UAAU,KAAK;GACb,MAAM;GACN,SAAS,GAAG,KAAK,eAAe,yBAAyB,KAAK;GAC9D,KAAK,0BAA0B,KAAK,eAAe;GACpD,CAAC;EAIN,IAAI,UAAU,SAAS,GACrB,OAAO;GAAE,MAAM;GAAW;GAAW;EAGvC,OAAO;GAAE,MAAM;GAAW,OAAO;GAAU;;CAG7C,KAAK,SAWsB;EACzB,MAAM,WAAW,QAAQ;EACzB,MAAM,SAAS,KAAK,UAAU,QAAQ;EACtC,IAAI,OAAO,SAAS,WAAW,OAAO;EACtC,OAAO;GACL,MAAM;GACN,MAAM,IAAI,8BAA8B,OAAO,OAAO;IACpD,MAAM,QAAQ,cAAc,QAAQ,eAAe;IACnD,IAAI,SAAS,QAAQ;IACtB,CAAC;GACH;;;;;;;;;;;CAYH,eAAe,SAAsE;EACnF,OAAO,IAAI,8BAA8B,EAAE,EAAE;GAC3C,MAAM,QAAQ;GACd,IAAI,QAAQ;GACb,CAAC;;;AAIN,SAAS,sBACP,UACA,iBACA,eAC2B;CAC3B,IAAI,gBAAgB,iBAAiB,cAAc,EAAE,OAAO,KAAA;CAE5D,IAAI,eAAe;EACjB,MAAM,iBAA0C,kBAC5C,wBAAwB,iBAAiB,cAAc,GACvD;EACJ,OAAO,IAAI,YACT,UACA;GACE,WAAW,EAAE,aAAa,cAAc,YAAY;GACpD,iBAAiB,cAAc;GAC/B,kBAAkB,cAAc;GACjC,EACD;GACE,IAAI,aAAa,SAAS,GAAG,kBAAkB,WAAW;GAC1D,OAAO,GAAG,kBAAkB,WAAW,MAAM,gBAAgB;GAC7D;GACD,CACF;;CAGH,OAAO,IAAI,YACT,UACA;EACE,WAAW,EAAE;EACb,iBAAiB;EACjB,kBAAkB;EACnB,EACD;EACE,IAAI,aAAa,SAAS;EAC1B,OAAO,uBAAuB;EAC9B,gBAAgB;EACjB,CACF;;AAGH,SAAS,2BACP,UACA,QACA,MAC2B;CAC3B,MAAM,cAAc,QAAQ;CAC5B,MAAM,YAAY,MAAM;CACxB,IAAI,UAAU,aAAa,UAAU,EAAE,OAAO,KAAA;CAE9C,MAAM,eAAe,aAAa,EAAE,SAAS,OAAO;CACpD,OAAO,IAAI,YACT,UACA,EACE,8BAA8B,cAC/B,EACD;EACE,IAAI,WAAW,SAAS;EACxB,OAAO,6BAA6B;EACpC,gBAAgB,aAAa,UAAU,aAAa;EACrD,CACF;;;;ACvTH,MAAM,gCAAqD,IAAI,IAAI,CAAC,aAAa,eAAe,CAAC;AAwEjG,SAAS,cACP,MACA,SACA,MACuB;CACvB,OAAO,MAA8B;EACnC;EACA;EACA,GAAG;EACJ,CAAC;;AAGJ,IAAa,uBAAb,MAAkC;CACH;CAA7B,YAAY,MAAgD;EAA/B,KAAA,OAAA;;CAE7B,MAAM,QAAQ,SAA6E;EACzF,MAAM,EAAE,iBAAiB,oBAAoB,SAAS,QAAQ,cAAc,KAAK;EACjF,MAAM,aAAa,oBAAoB,QAAQ,KAAK,WAAiC;EAIrF,MAAM,QAAQ,QAAQ,KAAK,WAAW;EAEtC,MAAM,cAAc,KAAK,2BAA2B,QAAQ,QAAQ,WAAW;EAC/E,IAAI,aAAa,OAAO;EAExB,MAAM,iBAAiB,MAAM,UAAU,WAAW,MAAM;EAExD,MAAM,cAAc,KAAK,0BAA0B,gBAAgB,QAAQ,KAAK;EAChF,IAAI,aAAa,OAAO;EAExB,MAAM,SAAS,QAAQ;EACvB,MAAM,eAAe,QAAQ,cAAc;EAC3C,MAAM,gBAAgB,QAAQ,eAAe;EAC7C,MAAM,iBAAiB,QAAQ,sBAAsB;EAErD,MAAM,kBAAkB,IAAI,iBAAiB;EAE7C,IAAI,qBAAqB;EAEzB,KAAK,MAAM,aAAa,YAAY;GAClC,QAAQ,WAAW,mBAAmB,UAAU;GAChD,IAAI;IACF,IAAI,UAAU,mBAAmB,QAAQ;KACvC,MAAM,SAAS,MAAM,KAAK,qBACxB,WACA,SACA,QACA,iBACA,gBACA,cACA,cACD;KACD,IAAI,OAAO,SAAS,OAAO,OAAO;KAClC,IAAI,OAAO,UAAU,sBAAsB;KAC3C;;IAGF,MAAM,QAAQ;IAEd,IAAI,iBAAiB;SAMf,MALuB,KAAK,mBAC9B,MAAM,WACN,oBACA,gBACD,EACiB;;IAGpB,IAAI;SAME,CAAC,MALwB,KAAK,eAChC,MAAM,UACN,oBACA,gBACD,EAEC,OAAO,cACL,mBACA,aAAa,UAAU,GAAG,0BAC1B,EAAE,MAAM,EAAE,aAAa,UAAU,IAAI,EAAE,CACxC;;IAIL,KAAK,MAAM,QAAQ,MAAM,SACvB,MAAM,KAAK,QAAQ,OAAO,gBAAgB;IAG5C,IAAI;SAME,CAAC,MALyB,KAAK,eACjC,MAAM,WACN,oBACA,gBACD,EAEC,OAAO,cACL,oBACA,aAAa,UAAU,GAAG,2BAC1B,EAAE,MAAM,EAAE,aAAa,UAAU,IAAI,EAAE,CACxC;;IAIL,sBAAsB;aACd;IACR,QAAQ,WAAW,sBAAsB,UAAU;;;EAIvD,MAAM,cAAc,QAAQ,KAAK;EACjC,MAAM,cAAc,QAAQ,oBAAoB,eAAe,YAAY;EAE3E,MAAM,qBAAqB,QAAQ,KAAK,sBAAsB,EAAE;EAChE,MAAM,uBAAuB,IAAI,IAAI,gBAAgB,cAAc,EAAE,CAAC;EACtE,MAAM,6BAA6B,mBAAmB,OAAO,OAC3D,qBAAqB,IAAI,GAAG,CAC7B;EACD,MAAM,6BACJ,mBAAmB,QACnB,eAAe,gBAAgB,YAAY,eAC3C,eAAe,gBAAgB;EAkBjC,IAAI,EAFF,uBAAuB,KAAK,8BAA8B,6BAE/C;GACX,MAAM,aAAa,MAAM,KAAK,KAAK,kBAAkB;GAMrD,MAAM,eAAe,QAAQ,gBAAgB,QAAQ,cAAc,WAAW,GAAG;GACjF,MAAM,eAAe,kBAAkB;IACrC,UAAU,QAAQ;IAClB,QAAQ;IACR,QAAQ,QAAQ,sBAAsB;IACtC,qBAAqB,QAAQ;IAC7B,GAAI,QAAQ,UAAU,EAAE,SAAS,QAAQ,SAAS,GAAG,EAAE;IACxD,CAAC;GACF,IAAI,CAAC,aAAa,IAChB,OAAO,cAAc,wBAAwB,aAAa,SAAS;IACjE,KAAK;IACL,MAAM,EAAE,QAAQ,aAAa,OAAO,QAAQ;IAC7C,CAAC;GAGJ,IAAI;QAME,CAAC,MALiB,UAAU,aAAa,OAAO,eAAe,aAAa;KAC9E,aAAa,YAAY;KACzB;KACA,YAAY;KACb,CAAC,EAEA,OAAO,cACL,sBACA,sEACA,EACE,MAAM;KACJ;KACA,qBAAqB,eAAe;KACpC,wBAAwB,YAAY;KACrC,EACF,CACF;UAGH,MAAM,UAAU,WAAW,OAAO;IAChC,aAAa,YAAY;IACzB;IACA,YAAY;IACb,CAAC;GAGJ,MAAM,aAAa,gBAAgB,eAAe;GAClD,MAAM,UAAU,iBAAiB,OAAO;IACtC,QAAQ,GAAG,WAAW,IAAI,YAAY;IACtC,MAAM;IACN,IAAI,YAAY;IACjB,CAAC;;EAGJ,OAAO,GAAG;GAAE,mBAAmB,WAAW;GAAQ;GAAoB,CAAC;;CAGzE,MAAc,qBACZ,IACA,SACA,QACA,iBACA,gBACA,cACA,eACiE;EACjE,IAAI,iBAAiB,kBAAkB,GAAG,UAAU,SAAS;OAOvD,MANuB,KAAK,4BAC9B,GAAG,WACH,SACA,QACA,gBACD,EACiB,OAAO,EAAE,UAAU,OAAO;;EAG9C,IAAI,gBAAgB,GAAG,SAAS,SAAS;OAOnC,CAAC,MANgB,KAAK,4BACxB,GAAG,UACH,SACA,QACA,gBACD,EAEC,OAAO;IACL,UAAU;IACV,SAAS,cAAc,mBAAmB,aAAa,GAAG,GAAG,0BAA0B,EACrF,MAAM;KAAE,aAAa,GAAG;KAAI,MAAM,GAAG;KAAM,EAC5C,CAAC;IACH;;EAIL,KAAK,MAAM,QAAQ,GAAG,KAAK;GACzB,MAAM,cAAc,MAAM,QAAQ,MAAM,MAAM,EAAE,CAAC;GACjD,WAAW,MAAM,KAAK,OAAO,QAAQ,YAAY;;EAKnD,IAAI,iBAAiB,GAAG,UAAU,SAAS;OAOrC,CAAC,MANgB,KAAK,4BACxB,GAAG,WACH,SACA,QACA,gBACD,EAEC,OAAO;IACL,UAAU;IACV,SAAS,cAAc,oBAAoB,aAAa,GAAG,GAAG,2BAA2B,EACvF,MAAM;KAAE,aAAa,GAAG;KAAI,MAAM,GAAG;KAAM,EAC5C,CAAC;IACH;;EAIL,OAAO,EAAE,UAAU,MAAM;;CAG3B,MAAc,4BACZ,QACA,SACA,QACA,iBACkB;EAClB,KAAK,MAAM,SAAS,QAAQ;GAC1B,MAAM,cAAc,MAAM,OAAO,QAAQ;GACzC,IAAI,CAAC,8BAA8B,IAAI,YAAY,EACjD,MAAM,kBACJ,gDAAgD,YAAY,qBAC5D;IACE,KAAK;IACL,KAAK;IACL,MAAM;KACJ,kBAAkB,MAAM;KACxB;KACA,YAAY,MAAM,OAAO;KAC1B;IACF,CACF;GAEH,MAAM,cAAc,MAAM,QAAQ,MAAM,MAAM,QAAQ,EAAE,CAAC;GACzD,IAAI,aAAa;GACjB,WAAW,MAAM,OAAO,OAAO,QAAiC,YAAY,EAC1E,IAAI,gBAAgB,SAAS,MAAM,QAAQ,IAAI,EAAE;IAC/C,aAAa;IACb;;GAIJ,IAAI,EADW,MAAM,WAAW,WAAW,aAAa,CAAC,aAC5C,OAAO;;EAEtB,OAAO;;CAGT,MAAc,eACZ,QACA,oBACA,iBACkB;EAClB,KAAK,MAAM,SAAS,QAAQ;GAE1B,MAAM,cAAa,MADK,MAAM,OAAO,OAAO,mBAAmB,EAClC,MAAM,QACjC,gBAAgB,SAAS,MAAM,QAAQ,IAA+B,CACvE;GAED,IAAI,EADW,MAAM,WAAW,WAAW,aAAa,CAAC,aAC5C,OAAO;;EAEtB,OAAO;;CAGT,MAAc,mBACZ,QACA,oBACA,iBACkB;EAClB,IAAI,OAAO,WAAW,GAAG,OAAO;EAChC,OAAO,KAAK,eAAe,QAAQ,oBAAoB,gBAAgB;;CAGzE,2BACE,QACA,YACmC;EACnC,MAAM,iBAAiB,IAAI,IAAI,OAAO,wBAAwB;EAC9D,KAAK,MAAM,aAAa,YACtB,IAAI,CAAC,eAAe,IAAI,UAAU,eAAe,EAC/C,OAAO,cACL,oBACA,aAAa,UAAU,GAAG,cAAc,UAAU,eAAe,oCACjE;GACE,KAAK,uBAAuB,CAAC,GAAG,eAAe,CAAC,KAAK,KAAK,CAAC;GAC3D,MAAM;IACJ,aAAa,UAAU;IACvB,gBAAgB,UAAU;IAC3B;GACF,CACF;;CAMP,0BACE,QACA,MACmC;EACnC,MAAM,SAAS,KAAK,UAAU;EAC9B,IAAI,CAAC,QAIH;EAGF,IAAI,CAAC,QACH,OAAO,cACL,0BACA,yDAAyD,OAAO,YAAY,IAC5E,EAAE,MAAM,EAAE,2BAA2B,OAAO,aAAa,EAAE,CAC5D;EAGH,IAAI,OAAO,gBAAgB,OAAO,aAChC,OAAO,cACL,0BACA,6BAA6B,OAAO,YAAY,gCAAgC,OAAO,YAAY,KACnG,EACE,MAAM;GACJ,mBAAmB,OAAO;GAC1B,2BAA2B,OAAO;GACnC,EACF,CACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@prisma-next/target-mongo",
3
- "version": "0.6.0-dev.13",
3
+ "version": "0.6.0-dev.15",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -8,18 +8,18 @@
8
8
  "dependencies": {
9
9
  "arktype": "^2.1.29",
10
10
  "mongodb": "^6.16.0",
11
- "@prisma-next/contract": "0.6.0-dev.13",
12
- "@prisma-next/framework-components": "0.6.0-dev.13",
13
- "@prisma-next/errors": "0.6.0-dev.13",
14
- "@prisma-next/mongo-codec": "0.6.0-dev.13",
15
- "@prisma-next/migration-tools": "0.6.0-dev.13",
16
- "@prisma-next/ts-render": "0.6.0-dev.13",
17
- "@prisma-next/mongo-lowering": "0.6.0-dev.13",
18
- "@prisma-next/mongo-contract": "0.6.0-dev.13",
19
- "@prisma-next/mongo-query-ast": "0.6.0-dev.13",
20
- "@prisma-next/mongo-schema-ir": "0.6.0-dev.13",
21
- "@prisma-next/mongo-value": "0.6.0-dev.13",
22
- "@prisma-next/utils": "0.6.0-dev.13"
11
+ "@prisma-next/contract": "0.6.0-dev.15",
12
+ "@prisma-next/errors": "0.6.0-dev.15",
13
+ "@prisma-next/migration-tools": "0.6.0-dev.15",
14
+ "@prisma-next/framework-components": "0.6.0-dev.15",
15
+ "@prisma-next/mongo-codec": "0.6.0-dev.15",
16
+ "@prisma-next/mongo-contract": "0.6.0-dev.15",
17
+ "@prisma-next/ts-render": "0.6.0-dev.15",
18
+ "@prisma-next/mongo-query-ast": "0.6.0-dev.15",
19
+ "@prisma-next/mongo-schema-ir": "0.6.0-dev.15",
20
+ "@prisma-next/mongo-lowering": "0.6.0-dev.15",
21
+ "@prisma-next/mongo-value": "0.6.0-dev.15",
22
+ "@prisma-next/utils": "0.6.0-dev.15"
23
23
  },
24
24
  "devDependencies": {
25
25
  "mongodb-memory-server": "11.0.1",
@@ -27,8 +27,8 @@
27
27
  "tsdown": "0.22.0",
28
28
  "typescript": "5.9.3",
29
29
  "vitest": "4.1.5",
30
- "@prisma-next/tsconfig": "0.0.0",
31
30
  "@prisma-next/test-utils": "0.0.1",
31
+ "@prisma-next/tsconfig": "0.0.0",
32
32
  "@prisma-next/tsdown": "0.0.0"
33
33
  },
34
34
  "files": [
@@ -8,13 +8,20 @@ import { type } from 'arktype';
8
8
  import type { Db, Document, UpdateFilter } from 'mongodb';
9
9
 
10
10
  const COLLECTION = '_prisma_migrations';
11
- const MARKER_ID = 'marker';
12
11
 
13
- // Same shape as the SQL marker row but camelCase + Mongo-native types:
14
- // `Date` is BSON-hydrated, `meta` is a native object (not JSON-stringified),
15
- // `_id` and any extension fields are tolerated. `invariants?` is optional —
16
- // absent reads as `[]` (schemaless default); present-but-malformed throws.
12
+ /**
13
+ * Marker doc shape.
14
+ *
15
+ * Same fields as the SQL marker row but camelCase + Mongo-native types:
16
+ * `Date` is BSON-hydrated, `meta` is a native object (not JSON-stringified),
17
+ * `_id` and any extension fields are tolerated. `invariants?` is optional —
18
+ * absent reads as `[]` (schemaless default); present-but-malformed throws.
19
+ *
20
+ * `space` is required: every marker doc is keyed by its space id (`_id`)
21
+ * and stamped with a matching `space` field for partitioned reads.
22
+ */
17
23
  const MongoMarkerDocSchema = type({
24
+ space: 'string',
18
25
  storageHash: 'string',
19
26
  profileHash: 'string',
20
27
  'contractJson?': 'unknown | null',
@@ -70,16 +77,58 @@ async function executeFindOneAndUpdate(
70
77
  });
71
78
  }
72
79
 
73
- export async function readMarker(db: Db): Promise<ContractMarkerRecord | null> {
74
- const cmd = new RawAggregateCommand(COLLECTION, [{ $match: { _id: MARKER_ID } }, { $limit: 1 }]);
80
+ /**
81
+ * Reads the marker document for the given contract space, or returns
82
+ * `null` if no marker has been written for that space yet. Each space
83
+ * owns one row keyed by `_id: <space>` — see ADR 212 for the per-space
84
+ * mechanism this enables.
85
+ */
86
+ export async function readMarker(db: Db, space: string): Promise<ContractMarkerRecord | null> {
87
+ const cmd = new RawAggregateCommand(COLLECTION, [
88
+ { $match: { _id: space, space } },
89
+ { $limit: 1 },
90
+ ]);
75
91
  const docs = await executeAggregate(db, cmd);
76
92
  const doc = docs[0];
77
93
  if (!doc) return null;
78
94
  return parseMongoMarkerDoc(doc);
79
95
  }
80
96
 
97
+ /**
98
+ * Reads every marker doc in the collection (one per contract space)
99
+ * and returns them keyed by `space`. Used by the per-space verifier
100
+ * to detect marker-vs-on-disk drift and orphan marker rows. Returns
101
+ * an empty map when no marker docs have been written yet.
102
+ *
103
+ * Marker docs are keyed by `_id: <space>` (string); ledger entries
104
+ * live in the same collection but use a driver-generated `ObjectId`
105
+ * `_id` plus `type: 'ledger'`. The filter selects string-keyed docs
106
+ * with a `space` field, which excludes ledger entries by construction.
107
+ */
108
+ export async function readAllMarkers(db: Db): Promise<ReadonlyMap<string, ContractMarkerRecord>> {
109
+ const cmd = new RawAggregateCommand(COLLECTION, [
110
+ {
111
+ $match: {
112
+ _id: { $type: 'string' },
113
+ space: { $type: 'string' },
114
+ $expr: { $eq: ['$_id', '$space'] },
115
+ },
116
+ },
117
+ ]);
118
+ const docs = await executeAggregate(db, cmd);
119
+ const out = new Map<string, ContractMarkerRecord>();
120
+ for (const doc of docs) {
121
+ const space = doc['space'];
122
+ /* v8 ignore next -- @preserve type-narrowing guard: the $match stage above filters on `space: { $type: 'string' }`, so this branch is unreachable at runtime. The check exists so the `out.set(space, ...)` call below can accept `string`. */
123
+ if (typeof space !== 'string') continue;
124
+ out.set(space, parseMongoMarkerDoc(doc));
125
+ }
126
+ return out;
127
+ }
128
+
81
129
  export async function initMarker(
82
130
  db: Db,
131
+ space: string,
83
132
  destination: {
84
133
  readonly storageHash: string;
85
134
  readonly profileHash: string;
@@ -87,7 +136,8 @@ export async function initMarker(
87
136
  },
88
137
  ): Promise<void> {
89
138
  const cmd = new RawInsertOneCommand(COLLECTION, {
90
- _id: MARKER_ID,
139
+ _id: space,
140
+ space,
91
141
  storageHash: destination.storageHash,
92
142
  profileHash: destination.profileHash,
93
143
  contractJson: null,
@@ -101,7 +151,8 @@ export async function initMarker(
101
151
  }
102
152
 
103
153
  /**
104
- * Updates the marker doc atomically (CAS on `expectedFrom`).
154
+ * Updates the marker doc for the given space atomically (CAS on
155
+ * `expectedFrom`).
105
156
  *
106
157
  * `destination.invariants`:
107
158
  * - `undefined` → existing field left untouched.
@@ -111,6 +162,7 @@ export async function initMarker(
111
162
  */
112
163
  export async function updateMarker(
113
164
  db: Db,
165
+ space: string,
114
166
  expectedFrom: string,
115
167
  destination: {
116
168
  readonly storageHash: string;
@@ -145,7 +197,7 @@ export async function updateMarker(
145
197
  ];
146
198
  const cmd = new RawFindOneAndUpdateCommand(
147
199
  COLLECTION,
148
- { _id: MARKER_ID, storageHash: expectedFrom },
200
+ { _id: space, space, storageHash: expectedFrom },
149
201
  update,
150
202
  false,
151
203
  );
@@ -153,12 +205,24 @@ export async function updateMarker(
153
205
  return result !== null;
154
206
  }
155
207
 
208
+ /**
209
+ * Appends a ledger entry for the given space. Ledger entries co-exist
210
+ * with marker docs in the same collection; marker docs use `_id: <space>`
211
+ * (string), ledger entries use `type: 'ledger'` plus a driver-generated
212
+ * ObjectId. Reads partition the two by filter shape.
213
+ *
214
+ * The same `edgeId` may legitimately recur across different spaces (e.g.
215
+ * a synthetic ∅→head edge on first apply), so the ledger key is
216
+ * `(space, edgeId)` — the doc carries `space` for partitioned reads.
217
+ */
156
218
  export async function writeLedgerEntry(
157
219
  db: Db,
220
+ space: string,
158
221
  entry: { readonly edgeId: string; readonly from: string; readonly to: string },
159
222
  ): Promise<void> {
160
223
  const cmd = new RawInsertOneCommand(COLLECTION, {
161
224
  type: 'ledger',
225
+ space,
162
226
  edgeId: entry.edgeId,
163
227
  from: entry.from,
164
228
  to: entry.to,
@@ -1,14 +1,15 @@
1
1
  import type { ContractMarkerRecord } from '@prisma-next/contract/types';
2
2
  import { errorRunnerFailed } from '@prisma-next/errors/execution';
3
3
  import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';
4
- import type {
5
- MigrationOperationPolicy,
6
- MigrationPlan,
7
- MigrationPlanOperation,
8
- MigrationRunnerExecutionChecks,
9
- MigrationRunnerFailure,
10
- MigrationRunnerResult,
11
- OperationContext,
4
+ import {
5
+ APP_SPACE_ID,
6
+ type MigrationOperationPolicy,
7
+ type MigrationPlan,
8
+ type MigrationPlanOperation,
9
+ type MigrationRunnerExecutionChecks,
10
+ type MigrationRunnerFailure,
11
+ type MigrationRunnerResult,
12
+ type OperationContext,
12
13
  } from '@prisma-next/framework-components/control';
13
14
  import type { MongoContract } from '@prisma-next/mongo-contract';
14
15
  import type { MongoAdapter, MongoDriver } from '@prisma-next/mongo-lowering';
@@ -29,14 +30,24 @@ import { verifyMongoSchema } from './schema-verify/verify-mongo-schema';
29
30
 
30
31
  const READ_ONLY_CHECK_COMMAND_KINDS: ReadonlySet<string> = new Set(['aggregate', 'rawAggregate']);
31
32
 
33
+ /**
34
+ * Marker / ledger operations the Mongo runner depends on. Every method
35
+ * takes a `space` parameter so each loaded contract space addresses its
36
+ * own marker row independently — see ADR 212 for the per-space
37
+ * mechanism.
38
+ */
32
39
  export interface MarkerOperations {
33
- readMarker(): Promise<ContractMarkerRecord | null>;
34
- initMarker(destination: {
35
- readonly storageHash: string;
36
- readonly profileHash: string;
37
- readonly invariants?: readonly string[];
38
- }): Promise<void>;
40
+ readMarker(space: string): Promise<ContractMarkerRecord | null>;
41
+ initMarker(
42
+ space: string,
43
+ destination: {
44
+ readonly storageHash: string;
45
+ readonly profileHash: string;
46
+ readonly invariants?: readonly string[];
47
+ },
48
+ ): Promise<void>;
39
49
  updateMarker(
50
+ space: string,
40
51
  expectedFrom: string,
41
52
  destination: {
42
53
  readonly storageHash: string;
@@ -44,11 +55,14 @@ export interface MarkerOperations {
44
55
  readonly invariants?: readonly string[];
45
56
  },
46
57
  ): Promise<boolean>;
47
- writeLedgerEntry(entry: {
48
- readonly edgeId: string;
49
- readonly from: string;
50
- readonly to: string;
51
- }): Promise<void>;
58
+ writeLedgerEntry(
59
+ space: string,
60
+ entry: {
61
+ readonly edgeId: string;
62
+ readonly from: string;
63
+ readonly to: string;
64
+ },
65
+ ): Promise<void>;
52
66
  }
53
67
 
54
68
  export interface MongoRunnerDependencies {
@@ -72,6 +86,18 @@ export interface MongoMigrationRunnerExecuteOptions {
72
86
  readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;
73
87
  readonly strictVerification?: boolean;
74
88
  readonly context?: OperationContext;
89
+ /**
90
+ * Per-space schema projection. When set, the runner applies this
91
+ * function to the introspected schema before invoking
92
+ * `verifyMongoSchema`, so per-space verification only sees the slice
93
+ * the destination contract actually claims.
94
+ *
95
+ * The descriptor's `executeAcrossSpaces` injects this callback,
96
+ * derived from the sibling spaces in the aggregate. Single-space
97
+ * callers leave it unset and verify against the whole introspected
98
+ * schema (the pre-aggregate behaviour).
99
+ */
100
+ readonly projectSchema?: (schema: MongoSchemaIR) => MongoSchemaIR;
75
101
  }
76
102
 
77
103
  function runnerFailure(
@@ -92,11 +118,15 @@ export class MongoMigrationRunner {
92
118
  async execute(options: MongoMigrationRunnerExecuteOptions): Promise<MigrationRunnerResult> {
93
119
  const { commandExecutor, inspectionExecutor, adapter, driver, markerOps } = this.deps;
94
120
  const operations = deserializeMongoOps(options.plan.operations as readonly unknown[]);
121
+ // Plans produced by the contract-space-aware planner stamp `spaceId`
122
+ // onto the plan; pre-port single-space callers leave it absent and
123
+ // fall through to the application's well-known space.
124
+ const space = options.plan.spaceId ?? APP_SPACE_ID;
95
125
 
96
126
  const policyCheck = this.enforcePolicyCompatibility(options.policy, operations);
97
127
  if (policyCheck) return policyCheck;
98
128
 
99
- const existingMarker = await markerOps.readMarker();
129
+ const existingMarker = await markerOps.readMarker(space);
100
130
 
101
131
  const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);
102
132
  if (markerCheck) return markerCheck;
@@ -210,9 +240,15 @@ export class MongoMigrationRunner {
210
240
 
211
241
  if (!isNoOp) {
212
242
  const liveSchema = await this.deps.introspectSchema();
243
+ // In a multi-space aggregate the live database holds collections
244
+ // owned by sibling spaces; the descriptor's `executeAcrossSpaces`
245
+ // injects a `projectSchema` that strips them so per-space verify
246
+ // only checks the slice this contract claims. Single-space
247
+ // callers leave the projection identity (no-op).
248
+ const verifySchema = options.projectSchema ? options.projectSchema(liveSchema) : liveSchema;
213
249
  const verifyResult = verifyMongoSchema({
214
250
  contract: options.destinationContract,
215
- schema: liveSchema,
251
+ schema: verifySchema,
216
252
  strict: options.strictVerification ?? true,
217
253
  frameworkComponents: options.frameworkComponents,
218
254
  ...(options.context ? { context: options.context } : {}),
@@ -225,7 +261,7 @@ export class MongoMigrationRunner {
225
261
  }
226
262
 
227
263
  if (existingMarker) {
228
- const updated = await markerOps.updateMarker(existingMarker.storageHash, {
264
+ const updated = await markerOps.updateMarker(space, existingMarker.storageHash, {
229
265
  storageHash: destination.storageHash,
230
266
  profileHash,
231
267
  invariants: incomingInvariants,
@@ -236,6 +272,7 @@ export class MongoMigrationRunner {
236
272
  'Marker was modified by another process during migration execution.',
237
273
  {
238
274
  meta: {
275
+ space,
239
276
  expectedStorageHash: existingMarker.storageHash,
240
277
  destinationStorageHash: destination.storageHash,
241
278
  },
@@ -243,7 +280,7 @@ export class MongoMigrationRunner {
243
280
  );
244
281
  }
245
282
  } else {
246
- await markerOps.initMarker({
283
+ await markerOps.initMarker(space, {
247
284
  storageHash: destination.storageHash,
248
285
  profileHash,
249
286
  invariants: incomingInvariants,
@@ -251,7 +288,7 @@ export class MongoMigrationRunner {
251
288
  }
252
289
 
253
290
  const originHash = existingMarker?.storageHash ?? '';
254
- await markerOps.writeLedgerEntry({
291
+ await markerOps.writeLedgerEntry(space, {
255
292
  edgeId: `${originHash}->${destination.storageHash}`,
256
293
  from: originHash,
257
294
  to: destination.storageHash,
@@ -1,7 +1,13 @@
1
1
  export { contractToMongoSchemaIR } from '../core/contract-to-schema';
2
2
  export { formatMongoOperations } from '../core/ddl-formatter';
3
3
  export { FilterEvaluator } from '../core/filter-evaluator';
4
- export { initMarker, readMarker, updateMarker, writeLedgerEntry } from '../core/marker-ledger';
4
+ export {
5
+ initMarker,
6
+ readAllMarkers,
7
+ readMarker,
8
+ updateMarker,
9
+ writeLedgerEntry,
10
+ } from '../core/marker-ledger';
5
11
  export {
6
12
  deserializeMongoOp,
7
13
  deserializeMongoOps,
@@ -10,7 +16,10 @@ export {
10
16
  export type { PlanCallsResult } from '../core/mongo-planner';
11
17
  export { MongoMigrationPlanner } from '../core/mongo-planner';
12
18
  export type { MarkerOperations, MongoRunnerDependencies } from '../core/mongo-runner';
13
- export { MongoMigrationRunner } from '../core/mongo-runner';
19
+ export {
20
+ MongoMigrationRunner,
21
+ type MongoMigrationRunnerExecuteOptions,
22
+ } from '../core/mongo-runner';
14
23
  export type { CollModMeta, OpFactoryCall } from '../core/op-factory-call';
15
24
  export {
16
25
  CollModCall,