@prisma-next/target-mongo 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/control.d.mts +26 -62
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +48 -69
- package/dist/control.mjs.map +1 -1
- package/package.json +21 -21
- package/src/core/mongo-target-contract-serializer.ts +40 -50
- package/src/core/mongo-target-database.ts +35 -26
- package/src/core/mongo-target-schema-verifier.ts +2 -2
- package/src/exports/control.ts +1 -1
package/dist/control.d.mts
CHANGED
|
@@ -8,7 +8,7 @@ import { MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, Migrat
|
|
|
8
8
|
import { MongoQueryPlan } from "@prisma-next/mongo-query-ast/execution";
|
|
9
9
|
import { MongoContractSerializerBase, MongoSchemaVerifierBase } from "@prisma-next/family-mongo/ir";
|
|
10
10
|
import { Namespace, NamespaceBase } from "@prisma-next/framework-components/ir";
|
|
11
|
-
import { MongoContract, MongoStorage } from "@prisma-next/mongo-contract";
|
|
11
|
+
import { MongoCollection, MongoCollectionInput, MongoContract, MongoStorage } from "@prisma-next/mongo-contract";
|
|
12
12
|
import { Contract } from "@prisma-next/contract/types";
|
|
13
13
|
import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
|
|
14
14
|
import { JsonObject } from "@prisma-next/utils/json";
|
|
@@ -136,79 +136,42 @@ declare class MongoMigrationRunner {
|
|
|
136
136
|
}
|
|
137
137
|
//#endregion
|
|
138
138
|
//#region src/core/mongo-target-contract-serializer.d.ts
|
|
139
|
-
/**
|
|
140
|
-
* Mongo target `ContractSerializer` concretion. Plugs into the
|
|
141
|
-
* family-shared deserialization pipeline at `constructTargetContract`,
|
|
142
|
-
* wrapping the validated flat-data shape in a `MongoStorage` class
|
|
143
|
-
* instance and providing the target's default namespace map.
|
|
144
|
-
*
|
|
145
|
-
* Default namespaces is
|
|
146
|
-
* `{ [UNSPECIFIED_NAMESPACE_ID]: MongoTargetUnspecifiedDatabase.instance }`
|
|
147
|
-
* — supplied at this target-layer call site because the family-layer
|
|
148
|
-
* `MongoStorage` class is target-agnostic (it cannot import the
|
|
149
|
-
* Mongo-target's namespace concretion). Contracts authored before
|
|
150
|
-
* multi-namespace support bind to the unspecified singleton without the
|
|
151
|
-
* call site declaring anything.
|
|
152
|
-
*
|
|
153
|
-
* `validated.storage.collections` already carries `MongoCollection` IR
|
|
154
|
-
* class instances by the time this method runs — the family-base
|
|
155
|
-
* `hydrateMongoContract` walks the arktype-validated tree and
|
|
156
|
-
* constructs class instances before validation. The target serializer
|
|
157
|
-
* just wraps the envelope.
|
|
158
|
-
*/
|
|
159
139
|
declare class MongoTargetContractSerializer extends MongoContractSerializerBase<MongoTargetContract> {
|
|
160
140
|
protected constructTargetContract(validated: MongoContract): MongoTargetContract;
|
|
161
|
-
/**
|
|
162
|
-
* Produce the canonical on-disk JSON shape from an in-memory Mongo
|
|
163
|
-
* contract. Strips runtime-only fields the storage class carries
|
|
164
|
-
* for its live-instance API but that don't belong in the persisted
|
|
165
|
-
* envelope: `MongoStorage.namespaces` is a Namespace-class map the
|
|
166
|
-
* verifier and runtime walk; the persisted shape omits it (today's
|
|
167
|
-
* contracts have a single implicit unspecified namespace; future
|
|
168
|
-
* explicit per-collection assignment will surface in JSON via a
|
|
169
|
-
* different field).
|
|
170
|
-
*
|
|
171
|
-
* Constructing the JsonObject here — rather than relying on
|
|
172
|
-
* non-enumerable property tricks at the storage class — keeps the
|
|
173
|
-
* "what's on disk" decision in the SPI implementer, where it
|
|
174
|
-
* belongs.
|
|
175
|
-
*/
|
|
176
141
|
serializeContract(contract: MongoTargetContract): JsonObject;
|
|
177
142
|
}
|
|
178
143
|
//#endregion
|
|
179
144
|
//#region src/core/mongo-target-database.d.ts
|
|
145
|
+
interface MongoTargetDatabaseInput {
|
|
146
|
+
readonly id: string;
|
|
147
|
+
readonly collections?: Record<string, MongoCollection | MongoCollectionInput>;
|
|
148
|
+
}
|
|
180
149
|
/**
|
|
181
150
|
* Mongo target `Namespace` concretion. In Mongo the "namespace" concept
|
|
182
151
|
* binds to the connection's `db` field — a `MongoTargetDatabase` instance
|
|
183
|
-
* names the database the collections live under.
|
|
152
|
+
* names the database the collections live under. The unbound singleton
|
|
153
|
+
* (below) is the late-bound slot whose binding the connection's `db`
|
|
154
|
+
* resolves at runtime rather than at authoring time.
|
|
184
155
|
*
|
|
185
156
|
* Qualifier emission is the rendering seam: query / DDL emission asks the
|
|
186
157
|
* namespace for its qualifier (e.g. `"<db>.<collection>"`) and consumes
|
|
187
|
-
* the result polymorphically. The
|
|
158
|
+
* the result polymorphically. The unbound singleton overrides these
|
|
188
159
|
* methods to elide the prefix entirely — call sites stay polymorphic and
|
|
189
|
-
* never branch on `id ===
|
|
190
|
-
*
|
|
191
|
-
* **Freeze-trap warning.** The constructor calls `freezeNode(this)` at
|
|
192
|
-
* the end. Direct subclasses MUST NOT add instance fields — the freeze
|
|
193
|
-
* runs in this base constructor and any subclass field assignment will
|
|
194
|
-
* silently fail in non-strict mode or throw in strict mode. The
|
|
195
|
-
* `MongoTargetUnspecifiedDatabase` singleton below is intentionally
|
|
196
|
-
* field-free for this reason; if a future subclass needs to carry
|
|
197
|
-
* additional fields, lift this `freezeNode` to the leaf-class
|
|
198
|
-
* constructors (or to a `seal()` hook each leaf calls explicitly).
|
|
160
|
+
* never branch on `id === UNBOUND_NAMESPACE_ID`.
|
|
199
161
|
*/
|
|
200
162
|
declare class MongoTargetDatabase extends NamespaceBase {
|
|
201
163
|
readonly kind: "database";
|
|
202
164
|
readonly id: string;
|
|
203
|
-
|
|
165
|
+
readonly collections: Readonly<Record<string, MongoCollection>>;
|
|
166
|
+
constructor(input: MongoTargetDatabaseInput);
|
|
204
167
|
/**
|
|
205
168
|
* The bare qualifier as it would appear in a rendered string. The
|
|
206
|
-
*
|
|
169
|
+
* unbound-database singleton overrides this to return `''`.
|
|
207
170
|
*/
|
|
208
171
|
qualifier(): string;
|
|
209
172
|
/**
|
|
210
173
|
* Qualify a collection name with the database prefix. The
|
|
211
|
-
*
|
|
174
|
+
* unbound-database singleton overrides this to emit just the
|
|
212
175
|
* collection name. Used by emission/introspection paths that need a
|
|
213
176
|
* fully-qualified reference.
|
|
214
177
|
*/
|
|
@@ -216,18 +179,19 @@ declare class MongoTargetDatabase extends NamespaceBase {
|
|
|
216
179
|
}
|
|
217
180
|
/**
|
|
218
181
|
* Singleton subclass for the reserved sentinel namespace id
|
|
219
|
-
* (`
|
|
220
|
-
*
|
|
221
|
-
*
|
|
222
|
-
*
|
|
182
|
+
* (`UNBOUND_NAMESPACE_ID`) — the late-bound slot whose binding the
|
|
183
|
+
* connection's `db` resolves at runtime. Overrides qualifier emission
|
|
184
|
+
* to elide the database prefix; call sites that consume `qualifier()`
|
|
185
|
+
* / `qualifyCollection()` get unqualified output without branching on
|
|
186
|
+
* the namespace id.
|
|
223
187
|
*
|
|
224
188
|
* This is the target-side materialization of "the framework provides
|
|
225
189
|
* affordances; targets implement specifics": the framework names the
|
|
226
|
-
* sentinel; Mongo decides what
|
|
227
|
-
*
|
|
190
|
+
* sentinel; Mongo decides what late-bound means here (the collection
|
|
191
|
+
* name, naked — the database is supplied by the live connection).
|
|
228
192
|
*/
|
|
229
|
-
declare class
|
|
230
|
-
static readonly instance:
|
|
193
|
+
declare class MongoTargetUnboundDatabase extends MongoTargetDatabase {
|
|
194
|
+
static readonly instance: MongoTargetUnboundDatabase;
|
|
231
195
|
private constructor();
|
|
232
196
|
qualifier(): string;
|
|
233
197
|
qualifyCollection(collectionName: string): string;
|
|
@@ -242,8 +206,8 @@ declare class MongoTargetUnspecifiedDatabase extends MongoTargetDatabase {
|
|
|
242
206
|
* `diffMongoSchemas`) so production verification behaviour is unchanged.
|
|
243
207
|
*
|
|
244
208
|
* Today's invariant: every Mongo contract carries exactly one
|
|
245
|
-
* namespace (the
|
|
246
|
-
* `
|
|
209
|
+
* namespace (the unbound singleton, materialised as
|
|
210
|
+
* `MongoTargetUnboundDatabase`), so the family-base namespace walk
|
|
247
211
|
* dispatches exactly once and the per-namespace body runs the existing
|
|
248
212
|
* whole-schema diff. Future per-collection namespace assignment will
|
|
249
213
|
* have this hook project the diff to the namespace's owned collections.
|
|
@@ -320,5 +284,5 @@ interface RenderMigrationMeta {
|
|
|
320
284
|
*/
|
|
321
285
|
declare function renderCallsToTypeScript(calls: ReadonlyArray<OpFactoryCall>, meta: RenderMigrationMeta): string;
|
|
322
286
|
//#endregion
|
|
323
|
-
export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoMigrationRunnerExecuteOptions, type MongoRunnerDependencies, type MongoTargetContract, MongoTargetContractSerializer, MongoTargetDatabase, MongoTargetSchemaVerifier,
|
|
287
|
+
export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoMigrationRunnerExecuteOptions, type MongoRunnerDependencies, type MongoTargetContract, MongoTargetContractSerializer, MongoTargetDatabase, MongoTargetSchemaVerifier, MongoTargetUnboundDatabase, type OpFactoryCall, type PlanCallsResult, PlannerProducedMongoMigration, type RenderMigrationMeta, deserializeMongoOp, deserializeMongoOps, mongoTargetDescriptor, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps };
|
|
324
288
|
//# sourceMappingURL=control.d.mts.map
|
package/dist/control.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/mongo-target-contract.ts","../src/core/control-target.ts","../src/core/filter-evaluator.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/mongo-target-contract-serializer.ts","../src/core/mongo-target-database.ts","../src/core/mongo-target-schema-verifier.ts","../src/core/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;KAYY,mBAAA,GAAsB,IAAA,CAAK,aAAA;EAAA,SAC5B,OAAA,EAAS,YAAA;AAAA;;;;;;;;;;;;;cCmCP,qBAAA,EAAuB,4BAAA,CAA6B,mBAAA;;;cCEpD,eAAA,YAA2B,kBAAA;EAAA,QAC9B,GAAA;EAER,QAAA,CAAS,MAAA,EAAQ,eAAA,EAAiB,GAAA,EAAK,MAAA;EAKvC,KAAA,CAAM,IAAA,EAAM,gBAAA;EAKZ,GAAA,CAAI,IAAA,EAAM,YAAA;EAIV,EAAA,CAAG,IAAA,EAAM,WAAA;EAIT,GAAA,CAAI,IAAA,EAAM,YAAA;EAIV,MAAA,CAAO,IAAA,EAAM,eAAA;EAKb,IAAA,CAAK,KAAA,EAAO,eAAA;AAAA;;;iBC8hBE,kBAAA,CAAmB,IAAA,YAAgB,0BAAA;AAAA,iBAOnC,mBAAA,CAAoB,IAAA,uBAA2B,0BAAA;AAAA,iBAI/C,iBAAA,CAAkB,GAAA,WAAc,0BAAA;;;KCphBpC,eAAA;EAAA,SACG,IAAA;EAAA,SAA0B,KAAA,EAAO,aAAA;AAAA;EAAA,SACjC,IAAA;EAAA,SAA0B,SAAA,EAAW,wBAAA;AAAA;AAAA,cAEvC,qBAAA,YAAiC,gBAAA;EAC5C,SAAA,CAAU,OAAA;IAAA,SACC,QAAA;IAAA,SACA,MAAA;IAAA,SACA,MAAA,EAAQ,wBAAA;IAAA,SACR,mBAAA,EAAqB,aAAA,CAAc,8BAAA;EAAA,IAC1C,eAAA;EAgIJ,IAAA,CAAK,OAAA;IAAA,SACM,QAAA;IAAA,SACA,MAAA;IAAA,SACA,MAAA,EAAQ,wBAAA;IJrOW;;;;;IAAA,SI2OnB,YAAA,EAAc,QAAA;IAAA,SACd,mBAAA,EAAqB,aAAA,CAAc,8BAAA;EAAA,IAC1C,sBAAA;;;;AH1MN;;;;;;EGgOE,cAAA,CAAe,OAAA,EAAS,wBAAA,GAA2B,iCAAA;AAAA;;;UC9OpC,kCAAA;EAAA,SACN,IAAA,EAAM,aAAA;EAAA,SACN,mBAAA,EAAqB,aAAA;EAAA,SACrB,MAAA,EAAQ,wBAAA;EAAA,SACR,SAAA;IACP,gBAAA,EAAkB,EAAA,EAAI,sBAAA;IACtB,mBAAA,EAAqB,EAAA,EAAI,sBAAA;EAAA;EAAA,SAElB,eAAA,GAAkB,8BAAA;EAAA,SAClB,mBAAA,EAAqB,aAAA,CAAc,8BAAA;EAAA,SACnC,kBAAA;EAAA,SACA,OAAA,GAAU,gBAAA;;;;;;;;;;;;WAYV,aAAA,IAAiB,MAAA,EAAQ,aAAA,KAAkB,aAAA;AAAA;AAAA,cAezC,oBAAA;EAAA,iBACkB,IAAA;cAAA,IAAA,EAAM,uBAAA;EAE7B,OAAA,CAAQ,OAAA,EAAS,kCAAA,GAAqC,OAAA,CAAQ,qBAAA;EAAA,QAuLtD,oBAAA;EAAA,QA+DA,2BAAA;EAAA,QAoCA,cAAA;EAAA,QAgBA,kBAAA;EAAA,QASN,0BAAA;EAAA,QAuBA,yBAAA;AAAA
|
|
1
|
+
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/mongo-target-contract.ts","../src/core/control-target.ts","../src/core/filter-evaluator.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/mongo-target-contract-serializer.ts","../src/core/mongo-target-database.ts","../src/core/mongo-target-schema-verifier.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
|
@@ -17,8 +17,8 @@ import { APP_SPACE_ID } from "@prisma-next/framework-components/control";
|
|
|
17
17
|
import { AggregateCommand, MongoAddFieldsStage, MongoLimitStage, MongoLookupStage, MongoMatchStage, MongoMergeStage, MongoProjectStage, MongoSortStage, RawAggregateCommand, RawDeleteManyCommand, RawDeleteOneCommand, RawFindOneAndDeleteCommand, RawFindOneAndUpdateCommand, RawInsertManyCommand, RawInsertOneCommand, RawUpdateManyCommand, RawUpdateOneCommand } from "@prisma-next/mongo-query-ast/execution";
|
|
18
18
|
import { type } from "arktype";
|
|
19
19
|
import { MongoContractSerializerBase, MongoSchemaVerifierBase } from "@prisma-next/family-mongo/ir";
|
|
20
|
-
import { NamespaceBase,
|
|
21
|
-
import { MongoStorage } from "@prisma-next/mongo-contract";
|
|
20
|
+
import { NamespaceBase, UNBOUND_NAMESPACE_ID, freezeNode } from "@prisma-next/framework-components/ir";
|
|
21
|
+
import { MongoCollection, MongoStorage } from "@prisma-next/mongo-contract";
|
|
22
22
|
//#region src/core/op-factory-call.ts
|
|
23
23
|
const TARGET_MIGRATION_MODULE = "@prisma-next/target-mongo/migration";
|
|
24
24
|
var OpFactoryCallNode = class extends TsExpression {
|
|
@@ -1184,41 +1184,36 @@ var MongoMigrationRunner = class {
|
|
|
1184
1184
|
/**
|
|
1185
1185
|
* Mongo target `Namespace` concretion. In Mongo the "namespace" concept
|
|
1186
1186
|
* binds to the connection's `db` field — a `MongoTargetDatabase` instance
|
|
1187
|
-
* names the database the collections live under.
|
|
1187
|
+
* names the database the collections live under. The unbound singleton
|
|
1188
|
+
* (below) is the late-bound slot whose binding the connection's `db`
|
|
1189
|
+
* resolves at runtime rather than at authoring time.
|
|
1188
1190
|
*
|
|
1189
1191
|
* Qualifier emission is the rendering seam: query / DDL emission asks the
|
|
1190
1192
|
* namespace for its qualifier (e.g. `"<db>.<collection>"`) and consumes
|
|
1191
|
-
* the result polymorphically. The
|
|
1193
|
+
* the result polymorphically. The unbound singleton overrides these
|
|
1192
1194
|
* methods to elide the prefix entirely — call sites stay polymorphic and
|
|
1193
|
-
* never branch on `id ===
|
|
1194
|
-
*
|
|
1195
|
-
* **Freeze-trap warning.** The constructor calls `freezeNode(this)` at
|
|
1196
|
-
* the end. Direct subclasses MUST NOT add instance fields — the freeze
|
|
1197
|
-
* runs in this base constructor and any subclass field assignment will
|
|
1198
|
-
* silently fail in non-strict mode or throw in strict mode. The
|
|
1199
|
-
* `MongoTargetUnspecifiedDatabase` singleton below is intentionally
|
|
1200
|
-
* field-free for this reason; if a future subclass needs to carry
|
|
1201
|
-
* additional fields, lift this `freezeNode` to the leaf-class
|
|
1202
|
-
* constructors (or to a `seal()` hook each leaf calls explicitly).
|
|
1195
|
+
* never branch on `id === UNBOUND_NAMESPACE_ID`.
|
|
1203
1196
|
*/
|
|
1204
1197
|
var MongoTargetDatabase = class extends NamespaceBase {
|
|
1205
1198
|
kind = "database";
|
|
1206
1199
|
id;
|
|
1207
|
-
|
|
1200
|
+
collections;
|
|
1201
|
+
constructor(input) {
|
|
1208
1202
|
super();
|
|
1209
|
-
this.id = id;
|
|
1203
|
+
this.id = input.id;
|
|
1204
|
+
this.collections = Object.freeze(Object.fromEntries(Object.entries(input.collections ?? {}).map(([name, c]) => [name, c instanceof MongoCollection ? c : new MongoCollection(c)])));
|
|
1210
1205
|
freezeNode(this);
|
|
1211
1206
|
}
|
|
1212
1207
|
/**
|
|
1213
1208
|
* The bare qualifier as it would appear in a rendered string. The
|
|
1214
|
-
*
|
|
1209
|
+
* unbound-database singleton overrides this to return `''`.
|
|
1215
1210
|
*/
|
|
1216
1211
|
qualifier() {
|
|
1217
1212
|
return this.id;
|
|
1218
1213
|
}
|
|
1219
1214
|
/**
|
|
1220
1215
|
* Qualify a collection name with the database prefix. The
|
|
1221
|
-
*
|
|
1216
|
+
* unbound-database singleton overrides this to emit just the
|
|
1222
1217
|
* collection name. Used by emission/introspection paths that need a
|
|
1223
1218
|
* fully-qualified reference.
|
|
1224
1219
|
*/
|
|
@@ -1228,20 +1223,21 @@ var MongoTargetDatabase = class extends NamespaceBase {
|
|
|
1228
1223
|
};
|
|
1229
1224
|
/**
|
|
1230
1225
|
* Singleton subclass for the reserved sentinel namespace id
|
|
1231
|
-
* (`
|
|
1232
|
-
*
|
|
1233
|
-
*
|
|
1234
|
-
*
|
|
1226
|
+
* (`UNBOUND_NAMESPACE_ID`) — the late-bound slot whose binding the
|
|
1227
|
+
* connection's `db` resolves at runtime. Overrides qualifier emission
|
|
1228
|
+
* to elide the database prefix; call sites that consume `qualifier()`
|
|
1229
|
+
* / `qualifyCollection()` get unqualified output without branching on
|
|
1230
|
+
* the namespace id.
|
|
1235
1231
|
*
|
|
1236
1232
|
* This is the target-side materialization of "the framework provides
|
|
1237
1233
|
* affordances; targets implement specifics": the framework names the
|
|
1238
|
-
* sentinel; Mongo decides what
|
|
1239
|
-
*
|
|
1234
|
+
* sentinel; Mongo decides what late-bound means here (the collection
|
|
1235
|
+
* name, naked — the database is supplied by the live connection).
|
|
1240
1236
|
*/
|
|
1241
|
-
var
|
|
1242
|
-
static instance = new
|
|
1237
|
+
var MongoTargetUnboundDatabase = class MongoTargetUnboundDatabase extends MongoTargetDatabase {
|
|
1238
|
+
static instance = new MongoTargetUnboundDatabase();
|
|
1243
1239
|
constructor() {
|
|
1244
|
-
super(
|
|
1240
|
+
super({ id: UNBOUND_NAMESPACE_ID });
|
|
1245
1241
|
}
|
|
1246
1242
|
qualifier() {
|
|
1247
1243
|
return "";
|
|
@@ -1252,61 +1248,44 @@ var MongoTargetUnspecifiedDatabase = class MongoTargetUnspecifiedDatabase extend
|
|
|
1252
1248
|
};
|
|
1253
1249
|
//#endregion
|
|
1254
1250
|
//#region src/core/mongo-target-contract-serializer.ts
|
|
1255
|
-
/**
|
|
1256
|
-
* Mongo target `ContractSerializer` concretion. Plugs into the
|
|
1257
|
-
* family-shared deserialization pipeline at `constructTargetContract`,
|
|
1258
|
-
* wrapping the validated flat-data shape in a `MongoStorage` class
|
|
1259
|
-
* instance and providing the target's default namespace map.
|
|
1260
|
-
*
|
|
1261
|
-
* Default namespaces is
|
|
1262
|
-
* `{ [UNSPECIFIED_NAMESPACE_ID]: MongoTargetUnspecifiedDatabase.instance }`
|
|
1263
|
-
* — supplied at this target-layer call site because the family-layer
|
|
1264
|
-
* `MongoStorage` class is target-agnostic (it cannot import the
|
|
1265
|
-
* Mongo-target's namespace concretion). Contracts authored before
|
|
1266
|
-
* multi-namespace support bind to the unspecified singleton without the
|
|
1267
|
-
* call site declaring anything.
|
|
1268
|
-
*
|
|
1269
|
-
* `validated.storage.collections` already carries `MongoCollection` IR
|
|
1270
|
-
* class instances by the time this method runs — the family-base
|
|
1271
|
-
* `hydrateMongoContract` walks the arktype-validated tree and
|
|
1272
|
-
* constructs class instances before validation. The target serializer
|
|
1273
|
-
* just wraps the envelope.
|
|
1274
|
-
*/
|
|
1275
1251
|
var MongoTargetContractSerializer = class extends MongoContractSerializerBase {
|
|
1276
1252
|
constructTargetContract(validated) {
|
|
1277
1253
|
const { storage, ...rest } = validated;
|
|
1254
|
+
const namespaces = Object.fromEntries(Object.entries(storage.namespaces).map(([nsId, nsData]) => {
|
|
1255
|
+
const collections = nsData.collections;
|
|
1256
|
+
const collectionCount = Object.keys(collections).length;
|
|
1257
|
+
if (nsId === UNBOUND_NAMESPACE_ID && collectionCount === 0) return [nsId, MongoTargetUnboundDatabase.instance];
|
|
1258
|
+
return [nsId, new MongoTargetDatabase({
|
|
1259
|
+
id: nsData.id,
|
|
1260
|
+
collections
|
|
1261
|
+
})];
|
|
1262
|
+
}));
|
|
1278
1263
|
const targetStorage = new MongoStorage({
|
|
1279
1264
|
storageHash: storage.storageHash,
|
|
1280
|
-
|
|
1281
|
-
namespaces: { [UNSPECIFIED_NAMESPACE_ID]: MongoTargetUnspecifiedDatabase.instance }
|
|
1265
|
+
namespaces
|
|
1282
1266
|
});
|
|
1283
1267
|
return {
|
|
1284
1268
|
...rest,
|
|
1285
1269
|
storage: targetStorage
|
|
1286
1270
|
};
|
|
1287
1271
|
}
|
|
1288
|
-
/**
|
|
1289
|
-
* Produce the canonical on-disk JSON shape from an in-memory Mongo
|
|
1290
|
-
* contract. Strips runtime-only fields the storage class carries
|
|
1291
|
-
* for its live-instance API but that don't belong in the persisted
|
|
1292
|
-
* envelope: `MongoStorage.namespaces` is a Namespace-class map the
|
|
1293
|
-
* verifier and runtime walk; the persisted shape omits it (today's
|
|
1294
|
-
* contracts have a single implicit unspecified namespace; future
|
|
1295
|
-
* explicit per-collection assignment will surface in JSON via a
|
|
1296
|
-
* different field).
|
|
1297
|
-
*
|
|
1298
|
-
* Constructing the JsonObject here — rather than relying on
|
|
1299
|
-
* non-enumerable property tricks at the storage class — keeps the
|
|
1300
|
-
* "what's on disk" decision in the SPI implementer, where it
|
|
1301
|
-
* belongs.
|
|
1302
|
-
*/
|
|
1303
1272
|
serializeContract(contract) {
|
|
1304
1273
|
const { storage, ...rest } = contract;
|
|
1274
|
+
const namespacesJson = {};
|
|
1275
|
+
for (const [nsId, ns] of Object.entries(storage.namespaces)) {
|
|
1276
|
+
const collectionsOut = {};
|
|
1277
|
+
for (const [collName, coll] of Object.entries(ns.collections)) collectionsOut[collName] = JSON.parse(JSON.stringify(coll));
|
|
1278
|
+
namespacesJson[nsId] = {
|
|
1279
|
+
id: ns.id,
|
|
1280
|
+
kind: "mongo-database",
|
|
1281
|
+
collections: collectionsOut
|
|
1282
|
+
};
|
|
1283
|
+
}
|
|
1305
1284
|
return {
|
|
1306
1285
|
...rest,
|
|
1307
1286
|
storage: {
|
|
1308
|
-
storageHash: storage.storageHash,
|
|
1309
|
-
|
|
1287
|
+
storageHash: String(storage.storageHash),
|
|
1288
|
+
namespaces: namespacesJson
|
|
1310
1289
|
}
|
|
1311
1290
|
};
|
|
1312
1291
|
}
|
|
@@ -1321,8 +1300,8 @@ var MongoTargetContractSerializer = class extends MongoContractSerializerBase {
|
|
|
1321
1300
|
* `diffMongoSchemas`) so production verification behaviour is unchanged.
|
|
1322
1301
|
*
|
|
1323
1302
|
* Today's invariant: every Mongo contract carries exactly one
|
|
1324
|
-
* namespace (the
|
|
1325
|
-
* `
|
|
1303
|
+
* namespace (the unbound singleton, materialised as
|
|
1304
|
+
* `MongoTargetUnboundDatabase`), so the family-base namespace walk
|
|
1326
1305
|
* dispatches exactly once and the per-namespace body runs the existing
|
|
1327
1306
|
* whole-schema diff. Future per-collection namespace assignment will
|
|
1328
1307
|
* have this hook project the diff to the namespace's owned collections.
|
|
@@ -1450,6 +1429,6 @@ function toSpaceMember(opts) {
|
|
|
1450
1429
|
};
|
|
1451
1430
|
}
|
|
1452
1431
|
//#endregion
|
|
1453
|
-
export { CollModCall, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, MongoMigrationPlanner, MongoMigrationRunner, MongoTargetContractSerializer, MongoTargetDatabase, MongoTargetSchemaVerifier,
|
|
1432
|
+
export { CollModCall, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, MongoMigrationPlanner, MongoMigrationRunner, MongoTargetContractSerializer, MongoTargetDatabase, MongoTargetSchemaVerifier, MongoTargetUnboundDatabase, PlannerProducedMongoMigration, deserializeMongoOp, deserializeMongoOps, mongoTargetDescriptor, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps };
|
|
1454
1433
|
|
|
1455
1434
|
//# sourceMappingURL=control.mjs.map
|
package/dist/control.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.mjs","names":["record"],"sources":["../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/filter-evaluator.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-runner.ts","../src/core/mongo-target-database.ts","../src/core/mongo-target-contract-serializer.ts","../src/core/mongo-target-schema-verifier.ts","../src/core/control-target.ts"],"sourcesContent":["/**\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 { contractToMongoSchemaIR } from '@prisma-next/family-mongo/control';\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 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 {\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 { 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","import type { MarkerOperations, MongoRunnerDependencies } from '@prisma-next/adapter-mongo/control';\nimport type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { errorRunnerFailed } from '@prisma-next/errors/execution';\nimport { verifyMongoSchema } from '@prisma-next/family-mongo/schema-verify';\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 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';\n\nconst READ_ONLY_CHECK_COMMAND_KINDS: ReadonlySet<string> = new Set(['aggregate', 'rawAggregate']);\n\nexport type { MarkerOperations, MongoRunnerDependencies };\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","import {\n freezeNode,\n NamespaceBase,\n UNSPECIFIED_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\n\n/**\n * Mongo target `Namespace` concretion. In Mongo the \"namespace\" concept\n * binds to the connection's `db` field — a `MongoTargetDatabase` instance\n * names the database the collections live under.\n *\n * Qualifier emission is the rendering seam: query / DDL emission asks the\n * namespace for its qualifier (e.g. `\"<db>.<collection>\"`) and consumes\n * the result polymorphically. The unspecified singleton overrides these\n * methods to elide the prefix entirely — call sites stay polymorphic and\n * never branch on `id === UNSPECIFIED_NAMESPACE_ID`.\n *\n * **Freeze-trap warning.** The constructor calls `freezeNode(this)` at\n * the end. Direct subclasses MUST NOT add instance fields — the freeze\n * runs in this base constructor and any subclass field assignment will\n * silently fail in non-strict mode or throw in strict mode. The\n * `MongoTargetUnspecifiedDatabase` singleton below is intentionally\n * field-free for this reason; if a future subclass needs to carry\n * additional fields, lift this `freezeNode` to the leaf-class\n * constructors (or to a `seal()` hook each leaf calls explicitly).\n */\nexport class MongoTargetDatabase extends NamespaceBase {\n readonly kind = 'database' as const;\n readonly id: string;\n\n constructor(id: string) {\n super();\n this.id = id;\n freezeNode(this);\n }\n\n /**\n * The bare qualifier as it would appear in a rendered string. The\n * unspecified-database singleton overrides this to return `''`.\n */\n qualifier(): string {\n return this.id;\n }\n\n /**\n * Qualify a collection name with the database prefix. The\n * unspecified-database singleton overrides this to emit just the\n * collection name. Used by emission/introspection paths that need a\n * fully-qualified reference.\n */\n qualifyCollection(collectionName: string): string {\n return `${this.id}.${collectionName}`;\n }\n}\n\n/**\n * Singleton subclass for the reserved sentinel namespace id\n * (`UNSPECIFIED_NAMESPACE_ID`). Overrides qualifier emission to elide\n * the database prefix — call sites that consume `qualifier()` /\n * `qualifyCollection()` get unqualified output without branching on the\n * namespace id.\n *\n * This is the target-side materialization of \"the framework provides\n * affordances; targets implement specifics\": the framework names the\n * sentinel; Mongo decides what no-database-bound means here (the\n * collection name, naked).\n */\nexport class MongoTargetUnspecifiedDatabase extends MongoTargetDatabase {\n static readonly instance: MongoTargetUnspecifiedDatabase = new MongoTargetUnspecifiedDatabase();\n\n private constructor() {\n super(UNSPECIFIED_NAMESPACE_ID);\n }\n\n override qualifier(): string {\n return '';\n }\n\n override qualifyCollection(collectionName: string): string {\n return collectionName;\n }\n}\n","import { MongoContractSerializerBase } from '@prisma-next/family-mongo/ir';\nimport { UNSPECIFIED_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport { type MongoContract, MongoStorage } from '@prisma-next/mongo-contract';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport type { MongoTargetContract } from './mongo-target-contract';\nimport { MongoTargetUnspecifiedDatabase } from './mongo-target-database';\n\n/**\n * Mongo target `ContractSerializer` concretion. Plugs into the\n * family-shared deserialization pipeline at `constructTargetContract`,\n * wrapping the validated flat-data shape in a `MongoStorage` class\n * instance and providing the target's default namespace map.\n *\n * Default namespaces is\n * `{ [UNSPECIFIED_NAMESPACE_ID]: MongoTargetUnspecifiedDatabase.instance }`\n * — supplied at this target-layer call site because the family-layer\n * `MongoStorage` class is target-agnostic (it cannot import the\n * Mongo-target's namespace concretion). Contracts authored before\n * multi-namespace support bind to the unspecified singleton without the\n * call site declaring anything.\n *\n * `validated.storage.collections` already carries `MongoCollection` IR\n * class instances by the time this method runs — the family-base\n * `hydrateMongoContract` walks the arktype-validated tree and\n * constructs class instances before validation. The target serializer\n * just wraps the envelope.\n */\nexport class MongoTargetContractSerializer extends MongoContractSerializerBase<MongoTargetContract> {\n protected constructTargetContract(validated: MongoContract): MongoTargetContract {\n const { storage, ...rest } = validated;\n const targetStorage = new MongoStorage({\n storageHash: storage.storageHash,\n collections: storage.collections,\n namespaces: {\n [UNSPECIFIED_NAMESPACE_ID]: MongoTargetUnspecifiedDatabase.instance,\n },\n });\n return { ...rest, storage: targetStorage };\n }\n\n /**\n * Produce the canonical on-disk JSON shape from an in-memory Mongo\n * contract. Strips runtime-only fields the storage class carries\n * for its live-instance API but that don't belong in the persisted\n * envelope: `MongoStorage.namespaces` is a Namespace-class map the\n * verifier and runtime walk; the persisted shape omits it (today's\n * contracts have a single implicit unspecified namespace; future\n * explicit per-collection assignment will surface in JSON via a\n * different field).\n *\n * Constructing the JsonObject here — rather than relying on\n * non-enumerable property tricks at the storage class — keeps the\n * \"what's on disk\" decision in the SPI implementer, where it\n * belongs.\n */\n override serializeContract(contract: MongoTargetContract): JsonObject {\n const { storage, ...rest } = contract;\n // `as unknown as JsonObject` because the returned literal mixes\n // `MongoCollection` class instances under `storage.collections` with\n // the JSON-clean remainder of the contract envelope. The class\n // instances are JSON-clean by construction (their `kind` literal is\n // enumerable; nested IR shapes are normalised by the constructor),\n // so the canonical-stringify pass produces correct output, but the\n // structural type system doesn't know `MongoCollection` is JSON-safe.\n return {\n ...rest,\n storage: {\n storageHash: storage.storageHash,\n collections: storage.collections,\n },\n } as unknown as JsonObject;\n }\n}\n","import {\n canonicalizeSchemasForVerification,\n contractToMongoSchemaIR,\n diffMongoSchemas,\n} from '@prisma-next/family-mongo/control';\nimport { MongoSchemaVerifierBase } from '@prisma-next/family-mongo/ir';\nimport type { SchemaIssue, SchemaVerifyOptions } from '@prisma-next/framework-components/control';\nimport type { Namespace } from '@prisma-next/framework-components/ir';\nimport type { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport type { MongoTargetContract } from './mongo-target-contract';\n\n/**\n * Mongo target `SchemaVerifier` concretion. Extends the family base's\n * namespace-walk scaffolding and contributes the per-namespace diff via\n * `verifyNamespace`; the diff body reuses the existing target-side\n * helpers (`contractToMongoSchemaIR`, `canonicalizeSchemasForVerification`,\n * `diffMongoSchemas`) so production verification behaviour is unchanged.\n *\n * Today's invariant: every Mongo contract carries exactly one\n * namespace (the unspecified singleton, materialised as\n * `MongoTargetUnspecifiedDatabase`), so the family-base namespace walk\n * dispatches exactly once and the per-namespace body runs the existing\n * whole-schema diff. Future per-collection namespace assignment will\n * have this hook project the diff to the namespace's owned collections.\n *\n * `verifyTargetExtensions` returns the empty list — Mongo has no\n * target-only kinds today.\n *\n * Strict diff mode is `false` for SPI-routed calls; production\n * verification today still goes through `verifyMongoSchema` which\n * receives strict from the CLI.\n */\nexport class MongoTargetSchemaVerifier extends MongoSchemaVerifierBase<\n MongoTargetContract,\n MongoSchemaIR\n> {\n protected verifyNamespace(options: {\n readonly contract: MongoTargetContract;\n readonly schema: MongoSchemaIR;\n readonly namespaceId: string;\n readonly namespace: Namespace;\n }): readonly SchemaIssue[] {\n const expectedIR = contractToMongoSchemaIR(options.contract);\n const { live, expected } = canonicalizeSchemasForVerification(options.schema, expectedIR);\n const { issues } = diffMongoSchemas(live, expected, false);\n return issues;\n }\n\n protected verifyTargetExtensions(\n _options: SchemaVerifyOptions<MongoTargetContract, MongoSchemaIR>,\n ): readonly SchemaIssue[] {\n return [];\n }\n}\n","import {\n createMongoRunnerDeps,\n extractDb,\n type MongoRunnerDependencies,\n} from '@prisma-next/adapter-mongo/control';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { MongoDriverImpl } from '@prisma-next/driver-mongo';\nimport type {\n MongoControlFamilyInstance,\n MongoControlTargetDescriptor,\n} from '@prisma-next/family-mongo/control';\nimport { contractToMongoSchemaIR } from '@prisma-next/family-mongo/control';\nimport type {\n MigrationRunner,\n MigrationRunnerResult,\n MigrationRunnerSuccessValue,\n MultiSpaceCapableRunner,\n MultiSpaceRunnerFailure,\n MultiSpaceRunnerPerSpaceOptions,\n MultiSpaceRunnerResult,\n} from '@prisma-next/framework-components/control';\nimport {\n type ContractSpaceMember,\n projectSchemaToSpace,\n} from '@prisma-next/migration-tools/aggregate';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type { MongoSchemaCollection } from '@prisma-next/mongo-schema-ir';\nimport { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { mongoTargetDescriptorMeta } from './descriptor-meta';\nimport { MongoMigrationPlanner } from './mongo-planner';\nimport { MongoMigrationRunner, type MongoMigrationRunnerExecuteOptions } from './mongo-runner';\nimport type { MongoTargetContract } from './mongo-target-contract';\nimport { MongoTargetContractSerializer } from './mongo-target-contract-serializer';\nimport { MongoTargetSchemaVerifier } from './mongo-target-schema-verifier';\n\nexport type { MongoControlTargetDescriptor };\n\n/**\n * `migration.ts` default-exports a `Migration` subclass whose `operations`\n * getter returns the ordered list of operations and whose `describe()`\n * returns the manifest identity metadata. `MongoMigrationPlanner.plan()`\n * returns a `MigrationPlanWithAuthoringSurface` that knows how to render\n * itself back to such a file; `MongoMigrationPlanner.emptyMigration()`\n * returns the same shape for `migration new`. Users run the scaffolded\n * `migration.ts` directly (via `node migration.ts`) to self-emit\n * `ops.json` and attest the `migrationHash`.\n */\nexport const mongoTargetDescriptor: MongoControlTargetDescriptor<MongoTargetContract> = {\n ...mongoTargetDescriptorMeta,\n contractSerializer: new MongoTargetContractSerializer(),\n schemaVerifier: new MongoTargetSchemaVerifier(),\n migrations: {\n createPlanner(_family: MongoControlFamilyInstance) {\n return new MongoMigrationPlanner();\n },\n createRunner(family: MongoControlFamilyInstance) {\n // Deps are bound to the first driver passed to execute() and cached for\n // subsequent calls. Callers must not change the driver between calls.\n let cachedDeps: MongoRunnerDependencies | undefined;\n\n const runMongo = async (\n driver: Parameters<MigrationRunner<'mongo', 'mongo'>['execute']>[0]['driver'],\n runnerOptions: Omit<MongoMigrationRunnerExecuteOptions, 'destinationContract'> & {\n readonly destinationContract: unknown;\n },\n ): Promise<MigrationRunnerResult> => {\n cachedDeps ??= createMongoRunnerDeps(\n driver,\n MongoDriverImpl.fromDb(extractDb(driver)),\n family,\n );\n // The framework `MigrationRunner` interface types `destinationContract`\n // as `unknown`; the Mongo runner narrows to `MongoContract`. Validation\n // happens upstream — `migrate` calls\n // `familyInstance.deserializeContract(contract)` on the project-root\n // contract loaded from disk before routing it here, so this cast\n // preserves the framework signature without weakening the runner's\n // typed surface.\n return new MongoMigrationRunner(cachedDeps).execute({\n ...runnerOptions,\n destinationContract: runnerOptions.destinationContract as MongoContract,\n });\n };\n\n const runner: MigrationRunner<'mongo', 'mongo'> & MultiSpaceCapableRunner<'mongo', 'mongo'> =\n {\n async execute(options) {\n const { driver, ...runnerOptions } = options;\n return runMongo(driver, runnerOptions);\n },\n // Mongo cannot wrap DDL ops in a session transaction (createCollection,\n // createIndex, collMod, setValidation all bypass transactions even on\n // replica sets), so the cross-space envelope is *resumable* rather than\n // transactional. Per-space-internal verify-gated marker atomicity\n // already lives in `runner.execute`: ops apply, schema is introspected\n // and verified, and the marker advances only on verify-pass. This loop\n // composes that guarantee across spaces — earlier-advanced markers are\n // not rolled back when a later space fails. Re-running reads each\n // marker, finds spaces 1..N−1 at-head (no-op skip), retries N onward.\n //\n // Per-space verify is sliced via `projectSchemaToSpace`: the live DB\n // holds collections owned by sibling spaces, but each space's verify\n // only sees the slice that space's contract actually claims. Without\n // the projection an aggregate of two spaces could not pass strict\n // verify (every other-space collection would look like an extra).\n //\n // See `docs/architecture docs/subsystems/10. MongoDB Family.md` §\n // Contract spaces and ADR 212 — Contract spaces.\n async executeAcrossSpaces({ driver, perSpaceOptions }): Promise<MultiSpaceRunnerResult> {\n const members = perSpaceOptions.map(toSpaceMember);\n const perSpaceResults: Array<{\n space: string;\n value: MigrationRunnerSuccessValue;\n }> = [];\n for (let i = 0; i < perSpaceOptions.length; i++) {\n const spaceOptions = perSpaceOptions[i];\n if (!spaceOptions) continue;\n const member = members[i];\n if (!member) continue;\n const others = members.filter((_, j) => j !== i);\n const projectSchema = (schema: MongoSchemaIR): MongoSchemaIR => {\n // `projectSchemaToSpace` returns a plain object\n // `{...schemaIR, collections: prunedArray}` (not a\n // `MongoSchemaIR` instance), so the descriptor rewraps\n // the pruned collections into a fresh `MongoSchemaIR`\n // before handing it to `verifyMongoSchema` (which\n // depends on the class's `collectionNames` /\n // `collection(name)` accessors).\n const projected = projectSchemaToSpace(schema, member, others) as {\n readonly collections: ReadonlyArray<MongoSchemaCollection>;\n };\n return new MongoSchemaIR(projected.collections);\n };\n const result = await runMongo(driver, { ...spaceOptions, projectSchema });\n if (!result.ok) {\n return notOk<MultiSpaceRunnerFailure>({\n ...result.failure,\n failingSpace: spaceOptions.space,\n });\n }\n perSpaceResults.push({ space: spaceOptions.space, value: result.value });\n }\n return ok({ perSpaceResults });\n },\n };\n return runner;\n },\n contractToSchema(contract: Contract | null) {\n return contractToMongoSchemaIR(contract as MongoContract | null);\n },\n },\n create() {\n return { familyId: 'mongo' as const, targetId: 'mongo' as const };\n },\n};\n\n/**\n * Synthesise the minimum {@link projectSchemaToSpace}-compatible\n * `ContractSpaceMember` shape from a per-space option entry. The\n * projector only reads `spaceId` and `contract.storage`; the rest of\n * `ContractSpaceMember` (head ref invariants, hydrated migration\n * graph) is irrelevant at runner time and stubbed with sentinels.\n *\n * The `as unknown as ContractSpaceMember` cast is the load-bearing bit\n * — the projector duck-types its members so a sentinel-shaped graph\n * never gets read, but the framework type carries a richer shape.\n */\nfunction toSpaceMember(\n opts: MultiSpaceRunnerPerSpaceOptions<'mongo', 'mongo'>,\n): ContractSpaceMember {\n return {\n spaceId: opts.space,\n // Blind cast: `MultiSpaceRunnerPerSpaceOptions.destinationContract`\n // is intentionally typed `unknown` at the framework boundary\n // (the framework does not know which family's `Contract` shape\n // a runner consumes). The caller is the aggregate runner,\n // which only forwards a value already validated through the\n // family `deserializeContract` seam at the aggregate boundary.\n contract: opts.destinationContract as unknown as Contract,\n headRef: { hash: '', invariants: [] },\n migrations: {\n graph: {\n nodes: new Set<string>(),\n forwardChain: new Map(),\n reverseChain: new Map(),\n migrationByHash: new Map(),\n },\n packagesByMigrationHash: new Map(),\n },\n } as unknown as ContractSpaceMember;\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"control.mjs","names":["record"],"sources":["../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/filter-evaluator.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-runner.ts","../src/core/mongo-target-database.ts","../src/core/mongo-target-contract-serializer.ts","../src/core/mongo-target-schema-verifier.ts","../src/core/control-target.ts"],"sourcesContent":["/**\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 { contractToMongoSchemaIR } from '@prisma-next/family-mongo/control';\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 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 {\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 { 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","import type { MarkerOperations, MongoRunnerDependencies } from '@prisma-next/adapter-mongo/control';\nimport type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport { errorRunnerFailed } from '@prisma-next/errors/execution';\nimport { verifyMongoSchema } from '@prisma-next/family-mongo/schema-verify';\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 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';\n\nconst READ_ONLY_CHECK_COMMAND_KINDS: ReadonlySet<string> = new Set(['aggregate', 'rawAggregate']);\n\nexport type { MarkerOperations, MongoRunnerDependencies };\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","import {\n freezeNode,\n NamespaceBase,\n UNBOUND_NAMESPACE_ID,\n} from '@prisma-next/framework-components/ir';\nimport { MongoCollection, type MongoCollectionInput } from '@prisma-next/mongo-contract';\n\nexport interface MongoTargetDatabaseInput {\n readonly id: string;\n readonly collections?: Record<string, MongoCollection | MongoCollectionInput>;\n}\n\n/**\n * Mongo target `Namespace` concretion. In Mongo the \"namespace\" concept\n * binds to the connection's `db` field — a `MongoTargetDatabase` instance\n * names the database the collections live under. The unbound singleton\n * (below) is the late-bound slot whose binding the connection's `db`\n * resolves at runtime rather than at authoring time.\n *\n * Qualifier emission is the rendering seam: query / DDL emission asks the\n * namespace for its qualifier (e.g. `\"<db>.<collection>\"`) and consumes\n * the result polymorphically. The unbound singleton overrides these\n * methods to elide the prefix entirely — call sites stay polymorphic and\n * never branch on `id === UNBOUND_NAMESPACE_ID`.\n */\nexport class MongoTargetDatabase extends NamespaceBase {\n readonly kind = 'database' as const;\n readonly id: string;\n readonly collections: Readonly<Record<string, MongoCollection>>;\n\n constructor(input: MongoTargetDatabaseInput) {\n super();\n this.id = input.id;\n this.collections = Object.freeze(\n Object.fromEntries(\n Object.entries(input.collections ?? {}).map(([name, c]) => [\n name,\n c instanceof MongoCollection ? c : new MongoCollection(c),\n ]),\n ),\n );\n freezeNode(this);\n }\n\n /**\n * The bare qualifier as it would appear in a rendered string. The\n * unbound-database singleton overrides this to return `''`.\n */\n qualifier(): string {\n return this.id;\n }\n\n /**\n * Qualify a collection name with the database prefix. The\n * unbound-database singleton overrides this to emit just the\n * collection name. Used by emission/introspection paths that need a\n * fully-qualified reference.\n */\n qualifyCollection(collectionName: string): string {\n return `${this.id}.${collectionName}`;\n }\n}\n\n/**\n * Singleton subclass for the reserved sentinel namespace id\n * (`UNBOUND_NAMESPACE_ID`) — the late-bound slot whose binding the\n * connection's `db` resolves at runtime. Overrides qualifier emission\n * to elide the database prefix; call sites that consume `qualifier()`\n * / `qualifyCollection()` get unqualified output without branching on\n * the namespace id.\n *\n * This is the target-side materialization of \"the framework provides\n * affordances; targets implement specifics\": the framework names the\n * sentinel; Mongo decides what late-bound means here (the collection\n * name, naked — the database is supplied by the live connection).\n */\nexport class MongoTargetUnboundDatabase extends MongoTargetDatabase {\n static readonly instance: MongoTargetUnboundDatabase = new MongoTargetUnboundDatabase();\n\n private constructor() {\n super({ id: UNBOUND_NAMESPACE_ID });\n }\n\n override qualifier(): string {\n return '';\n }\n\n override qualifyCollection(collectionName: string): string {\n return collectionName;\n }\n}\n","import { MongoContractSerializerBase } from '@prisma-next/family-mongo/ir';\nimport { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';\nimport { type MongoContract, MongoStorage } from '@prisma-next/mongo-contract';\nimport type { JsonObject } from '@prisma-next/utils/json';\nimport type { MongoTargetContract } from './mongo-target-contract';\nimport { MongoTargetDatabase, MongoTargetUnboundDatabase } from './mongo-target-database';\n\nexport class MongoTargetContractSerializer extends MongoContractSerializerBase<MongoTargetContract> {\n protected constructTargetContract(validated: MongoContract): MongoTargetContract {\n const { storage, ...rest } = validated;\n const namespaces = Object.fromEntries(\n Object.entries(storage.namespaces).map(([nsId, nsData]) => {\n const collections = nsData.collections;\n const collectionCount = Object.keys(collections).length;\n if (nsId === UNBOUND_NAMESPACE_ID && collectionCount === 0) {\n return [nsId, MongoTargetUnboundDatabase.instance];\n }\n return [\n nsId,\n new MongoTargetDatabase({\n id: nsData.id,\n collections,\n }),\n ];\n }),\n );\n const targetStorage = new MongoStorage({\n storageHash: storage.storageHash,\n namespaces,\n });\n return { ...rest, storage: targetStorage };\n }\n\n override serializeContract(contract: MongoTargetContract): JsonObject {\n const { storage, ...rest } = contract;\n const namespacesJson: Record<string, JsonObject> = {};\n for (const [nsId, ns] of Object.entries(storage.namespaces)) {\n const collectionsOut: Record<string, JsonObject> = {};\n for (const [collName, coll] of Object.entries(ns.collections)) {\n collectionsOut[collName] = JSON.parse(JSON.stringify(coll)) as JsonObject;\n }\n namespacesJson[nsId] = {\n id: ns.id,\n kind: 'mongo-database',\n collections: collectionsOut,\n };\n }\n return {\n ...rest,\n storage: {\n storageHash: String(storage.storageHash),\n namespaces: namespacesJson,\n },\n // `rest` carries Contract fields typed against framework interfaces\n // (e.g. `ContractExecutionSection`) that TypeScript can't structurally\n // prove are JSON-compatible without a per-field re-validation pass.\n // The runtime invariant is that an emitted MongoTargetContract has\n // already been through validation and contains only JSON-safe values,\n // so the two-step cast is intentional. Mirrors the pattern in\n // PostgresContractSerializer.serializeContract.\n } as unknown as JsonObject;\n }\n}\n","import {\n canonicalizeSchemasForVerification,\n contractToMongoSchemaIR,\n diffMongoSchemas,\n} from '@prisma-next/family-mongo/control';\nimport { MongoSchemaVerifierBase } from '@prisma-next/family-mongo/ir';\nimport type { SchemaIssue, SchemaVerifyOptions } from '@prisma-next/framework-components/control';\nimport type { Namespace } from '@prisma-next/framework-components/ir';\nimport type { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport type { MongoTargetContract } from './mongo-target-contract';\n\n/**\n * Mongo target `SchemaVerifier` concretion. Extends the family base's\n * namespace-walk scaffolding and contributes the per-namespace diff via\n * `verifyNamespace`; the diff body reuses the existing target-side\n * helpers (`contractToMongoSchemaIR`, `canonicalizeSchemasForVerification`,\n * `diffMongoSchemas`) so production verification behaviour is unchanged.\n *\n * Today's invariant: every Mongo contract carries exactly one\n * namespace (the unbound singleton, materialised as\n * `MongoTargetUnboundDatabase`), so the family-base namespace walk\n * dispatches exactly once and the per-namespace body runs the existing\n * whole-schema diff. Future per-collection namespace assignment will\n * have this hook project the diff to the namespace's owned collections.\n *\n * `verifyTargetExtensions` returns the empty list — Mongo has no\n * target-only kinds today.\n *\n * Strict diff mode is `false` for SPI-routed calls; production\n * verification today still goes through `verifyMongoSchema` which\n * receives strict from the CLI.\n */\nexport class MongoTargetSchemaVerifier extends MongoSchemaVerifierBase<\n MongoTargetContract,\n MongoSchemaIR\n> {\n protected verifyNamespace(options: {\n readonly contract: MongoTargetContract;\n readonly schema: MongoSchemaIR;\n readonly namespaceId: string;\n readonly namespace: Namespace;\n }): readonly SchemaIssue[] {\n const expectedIR = contractToMongoSchemaIR(options.contract);\n const { live, expected } = canonicalizeSchemasForVerification(options.schema, expectedIR);\n const { issues } = diffMongoSchemas(live, expected, false);\n return issues;\n }\n\n protected verifyTargetExtensions(\n _options: SchemaVerifyOptions<MongoTargetContract, MongoSchemaIR>,\n ): readonly SchemaIssue[] {\n return [];\n }\n}\n","import {\n createMongoRunnerDeps,\n extractDb,\n type MongoRunnerDependencies,\n} from '@prisma-next/adapter-mongo/control';\nimport type { Contract } from '@prisma-next/contract/types';\nimport { MongoDriverImpl } from '@prisma-next/driver-mongo';\nimport type {\n MongoControlFamilyInstance,\n MongoControlTargetDescriptor,\n} from '@prisma-next/family-mongo/control';\nimport { contractToMongoSchemaIR } from '@prisma-next/family-mongo/control';\nimport type {\n MigrationRunner,\n MigrationRunnerResult,\n MigrationRunnerSuccessValue,\n MultiSpaceCapableRunner,\n MultiSpaceRunnerFailure,\n MultiSpaceRunnerPerSpaceOptions,\n MultiSpaceRunnerResult,\n} from '@prisma-next/framework-components/control';\nimport {\n type ContractSpaceMember,\n projectSchemaToSpace,\n} from '@prisma-next/migration-tools/aggregate';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type { MongoSchemaCollection } from '@prisma-next/mongo-schema-ir';\nimport { MongoSchemaIR } from '@prisma-next/mongo-schema-ir';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { mongoTargetDescriptorMeta } from './descriptor-meta';\nimport { MongoMigrationPlanner } from './mongo-planner';\nimport { MongoMigrationRunner, type MongoMigrationRunnerExecuteOptions } from './mongo-runner';\nimport type { MongoTargetContract } from './mongo-target-contract';\nimport { MongoTargetContractSerializer } from './mongo-target-contract-serializer';\nimport { MongoTargetSchemaVerifier } from './mongo-target-schema-verifier';\n\nexport type { MongoControlTargetDescriptor };\n\n/**\n * `migration.ts` default-exports a `Migration` subclass whose `operations`\n * getter returns the ordered list of operations and whose `describe()`\n * returns the manifest identity metadata. `MongoMigrationPlanner.plan()`\n * returns a `MigrationPlanWithAuthoringSurface` that knows how to render\n * itself back to such a file; `MongoMigrationPlanner.emptyMigration()`\n * returns the same shape for `migration new`. Users run the scaffolded\n * `migration.ts` directly (via `node migration.ts`) to self-emit\n * `ops.json` and attest the `migrationHash`.\n */\nexport const mongoTargetDescriptor: MongoControlTargetDescriptor<MongoTargetContract> = {\n ...mongoTargetDescriptorMeta,\n contractSerializer: new MongoTargetContractSerializer(),\n schemaVerifier: new MongoTargetSchemaVerifier(),\n migrations: {\n createPlanner(_family: MongoControlFamilyInstance) {\n return new MongoMigrationPlanner();\n },\n createRunner(family: MongoControlFamilyInstance) {\n // Deps are bound to the first driver passed to execute() and cached for\n // subsequent calls. Callers must not change the driver between calls.\n let cachedDeps: MongoRunnerDependencies | undefined;\n\n const runMongo = async (\n driver: Parameters<MigrationRunner<'mongo', 'mongo'>['execute']>[0]['driver'],\n runnerOptions: Omit<MongoMigrationRunnerExecuteOptions, 'destinationContract'> & {\n readonly destinationContract: unknown;\n },\n ): Promise<MigrationRunnerResult> => {\n cachedDeps ??= createMongoRunnerDeps(\n driver,\n MongoDriverImpl.fromDb(extractDb(driver)),\n family,\n );\n // The framework `MigrationRunner` interface types `destinationContract`\n // as `unknown`; the Mongo runner narrows to `MongoContract`. Validation\n // happens upstream — `migrate` calls\n // `familyInstance.deserializeContract(contract)` on the project-root\n // contract loaded from disk before routing it here, so this cast\n // preserves the framework signature without weakening the runner's\n // typed surface.\n return new MongoMigrationRunner(cachedDeps).execute({\n ...runnerOptions,\n destinationContract: runnerOptions.destinationContract as MongoContract,\n });\n };\n\n const runner: MigrationRunner<'mongo', 'mongo'> & MultiSpaceCapableRunner<'mongo', 'mongo'> =\n {\n async execute(options) {\n const { driver, ...runnerOptions } = options;\n return runMongo(driver, runnerOptions);\n },\n // Mongo cannot wrap DDL ops in a session transaction (createCollection,\n // createIndex, collMod, setValidation all bypass transactions even on\n // replica sets), so the cross-space envelope is *resumable* rather than\n // transactional. Per-space-internal verify-gated marker atomicity\n // already lives in `runner.execute`: ops apply, schema is introspected\n // and verified, and the marker advances only on verify-pass. This loop\n // composes that guarantee across spaces — earlier-advanced markers are\n // not rolled back when a later space fails. Re-running reads each\n // marker, finds spaces 1..N−1 at-head (no-op skip), retries N onward.\n //\n // Per-space verify is sliced via `projectSchemaToSpace`: the live DB\n // holds collections owned by sibling spaces, but each space's verify\n // only sees the slice that space's contract actually claims. Without\n // the projection an aggregate of two spaces could not pass strict\n // verify (every other-space collection would look like an extra).\n //\n // See `docs/architecture docs/subsystems/10. MongoDB Family.md` §\n // Contract spaces and ADR 212 — Contract spaces.\n async executeAcrossSpaces({ driver, perSpaceOptions }): Promise<MultiSpaceRunnerResult> {\n const members = perSpaceOptions.map(toSpaceMember);\n const perSpaceResults: Array<{\n space: string;\n value: MigrationRunnerSuccessValue;\n }> = [];\n for (let i = 0; i < perSpaceOptions.length; i++) {\n const spaceOptions = perSpaceOptions[i];\n if (!spaceOptions) continue;\n const member = members[i];\n if (!member) continue;\n const others = members.filter((_, j) => j !== i);\n const projectSchema = (schema: MongoSchemaIR): MongoSchemaIR => {\n // `projectSchemaToSpace` returns a plain object\n // `{...schemaIR, collections: prunedArray}` (not a\n // `MongoSchemaIR` instance), so the descriptor rewraps\n // the pruned collections into a fresh `MongoSchemaIR`\n // before handing it to `verifyMongoSchema` (which\n // depends on the class's `collectionNames` /\n // `collection(name)` accessors).\n const projected = projectSchemaToSpace(schema, member, others) as {\n readonly collections: ReadonlyArray<MongoSchemaCollection>;\n };\n return new MongoSchemaIR(projected.collections);\n };\n const result = await runMongo(driver, { ...spaceOptions, projectSchema });\n if (!result.ok) {\n return notOk<MultiSpaceRunnerFailure>({\n ...result.failure,\n failingSpace: spaceOptions.space,\n });\n }\n perSpaceResults.push({ space: spaceOptions.space, value: result.value });\n }\n return ok({ perSpaceResults });\n },\n };\n return runner;\n },\n contractToSchema(contract: Contract | null) {\n return contractToMongoSchemaIR(contract as MongoContract | null);\n },\n },\n create() {\n return { familyId: 'mongo' as const, targetId: 'mongo' as const };\n },\n};\n\n/**\n * Synthesise the minimum {@link projectSchemaToSpace}-compatible\n * `ContractSpaceMember` shape from a per-space option entry. The\n * projector only reads `spaceId` and `contract.storage`; the rest of\n * `ContractSpaceMember` (head ref invariants, hydrated migration\n * graph) is irrelevant at runner time and stubbed with sentinels.\n *\n * The `as unknown as ContractSpaceMember` cast is the load-bearing bit\n * — the projector duck-types its members so a sentinel-shaped graph\n * never gets read, but the framework type carries a richer shape.\n */\nfunction toSpaceMember(\n opts: MultiSpaceRunnerPerSpaceOptions<'mongo', 'mongo'>,\n): ContractSpaceMember {\n return {\n spaceId: opts.space,\n // Blind cast: `MultiSpaceRunnerPerSpaceOptions.destinationContract`\n // is intentionally typed `unknown` at the framework boundary\n // (the framework does not know which family's `Contract` shape\n // a runner consumes). The caller is the aggregate runner,\n // which only forwards a value already validated through the\n // family `deserializeContract` seam at the aggregate boundary.\n contract: opts.destinationContract as unknown as Contract,\n headRef: { hash: '', invariants: [] },\n migrations: {\n graph: {\n nodes: new Set<string>(),\n forwardChain: new Map(),\n reverseChain: new Map(),\n migrationByHash: new Map(),\n },\n packagesByMigrationHash: new Map(),\n },\n } as unknown as ContractSpaceMember;\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAmDA,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;;;;ACxUH,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;;;;;AC3B3F,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;;;;AC5lBrC,MAAM,gCAAqD,IAAI,IAAI,CAAC,aAAa,eAAe,CAAC;AA8BjG,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;;;;;;;;;;;;;;;;;;AC1ZP,IAAa,sBAAb,cAAyC,cAAc;CACrD,OAAgB;CAChB;CACA;CAEA,YAAY,OAAiC;EAC3C,OAAO;EACP,KAAK,KAAK,MAAM;EAChB,KAAK,cAAc,OAAO,OACxB,OAAO,YACL,OAAO,QAAQ,MAAM,eAAe,EAAE,CAAC,CAAC,KAAK,CAAC,MAAM,OAAO,CACzD,MACA,aAAa,kBAAkB,IAAI,IAAI,gBAAgB,EAAE,CAC1D,CAAC,CACH,CACF;EACD,WAAW,KAAK;;;;;;CAOlB,YAAoB;EAClB,OAAO,KAAK;;;;;;;;CASd,kBAAkB,gBAAgC;EAChD,OAAO,GAAG,KAAK,GAAG,GAAG;;;;;;;;;;;;;;;;AAiBzB,IAAa,6BAAb,MAAa,mCAAmC,oBAAoB;CAClE,OAAgB,WAAuC,IAAI,4BAA4B;CAEvF,cAAsB;EACpB,MAAM,EAAE,IAAI,sBAAsB,CAAC;;CAGrC,YAA6B;EAC3B,OAAO;;CAGT,kBAA2B,gBAAgC;EACzD,OAAO;;;;;ACjFX,IAAa,gCAAb,cAAmD,4BAAiD;CAClG,wBAAkC,WAA+C;EAC/E,MAAM,EAAE,SAAS,GAAG,SAAS;EAC7B,MAAM,aAAa,OAAO,YACxB,OAAO,QAAQ,QAAQ,WAAW,CAAC,KAAK,CAAC,MAAM,YAAY;GACzD,MAAM,cAAc,OAAO;GAC3B,MAAM,kBAAkB,OAAO,KAAK,YAAY,CAAC;GACjD,IAAI,SAAS,wBAAwB,oBAAoB,GACvD,OAAO,CAAC,MAAM,2BAA2B,SAAS;GAEpD,OAAO,CACL,MACA,IAAI,oBAAoB;IACtB,IAAI,OAAO;IACX;IACD,CAAC,CACH;IACD,CACH;EACD,MAAM,gBAAgB,IAAI,aAAa;GACrC,aAAa,QAAQ;GACrB;GACD,CAAC;EACF,OAAO;GAAE,GAAG;GAAM,SAAS;GAAe;;CAG5C,kBAA2B,UAA2C;EACpE,MAAM,EAAE,SAAS,GAAG,SAAS;EAC7B,MAAM,iBAA6C,EAAE;EACrD,KAAK,MAAM,CAAC,MAAM,OAAO,OAAO,QAAQ,QAAQ,WAAW,EAAE;GAC3D,MAAM,iBAA6C,EAAE;GACrD,KAAK,MAAM,CAAC,UAAU,SAAS,OAAO,QAAQ,GAAG,YAAY,EAC3D,eAAe,YAAY,KAAK,MAAM,KAAK,UAAU,KAAK,CAAC;GAE7D,eAAe,QAAQ;IACrB,IAAI,GAAG;IACP,MAAM;IACN,aAAa;IACd;;EAEH,OAAO;GACL,GAAG;GACH,SAAS;IACP,aAAa,OAAO,QAAQ,YAAY;IACxC,YAAY;IACb;GAQF;;;;;;;;;;;;;;;;;;;;;;;;;;AC5BL,IAAa,4BAAb,cAA+C,wBAG7C;CACA,gBAA0B,SAKC;EACzB,MAAM,aAAa,wBAAwB,QAAQ,SAAS;EAC5D,MAAM,EAAE,MAAM,aAAa,mCAAmC,QAAQ,QAAQ,WAAW;EACzF,MAAM,EAAE,WAAW,iBAAiB,MAAM,UAAU,MAAM;EAC1D,OAAO;;CAGT,uBACE,UACwB;EACxB,OAAO,EAAE;;;;;;;;;;;;;;;ACHb,MAAa,wBAA2E;CACtF,GAAG;CACH,oBAAoB,IAAI,+BAA+B;CACvD,gBAAgB,IAAI,2BAA2B;CAC/C,YAAY;EACV,cAAc,SAAqC;GACjD,OAAO,IAAI,uBAAuB;;EAEpC,aAAa,QAAoC;GAG/C,IAAI;GAEJ,MAAM,WAAW,OACf,QACA,kBAGmC;IACnC,eAAe,sBACb,QACA,gBAAgB,OAAO,UAAU,OAAO,CAAC,EACzC,OACD;IAQD,OAAO,IAAI,qBAAqB,WAAW,CAAC,QAAQ;KAClD,GAAG;KACH,qBAAqB,cAAc;KACpC,CAAC;;GAgEJ,OAAO;IA3DH,MAAM,QAAQ,SAAS;KACrB,MAAM,EAAE,QAAQ,GAAG,kBAAkB;KACrC,OAAO,SAAS,QAAQ,cAAc;;IAoBxC,MAAM,oBAAoB,EAAE,QAAQ,mBAAoD;KACtF,MAAM,UAAU,gBAAgB,IAAI,cAAc;KAClD,MAAM,kBAGD,EAAE;KACP,KAAK,IAAI,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK;MAC/C,MAAM,eAAe,gBAAgB;MACrC,IAAI,CAAC,cAAc;MACnB,MAAM,SAAS,QAAQ;MACvB,IAAI,CAAC,QAAQ;MACb,MAAM,SAAS,QAAQ,QAAQ,GAAG,MAAM,MAAM,EAAE;MAChD,MAAM,iBAAiB,WAAyC;OAW9D,OAAO,IAAI,cAHO,qBAAqB,QAAQ,QAAQ,OAGrB,CAAC,YAAY;;MAEjD,MAAM,SAAS,MAAM,SAAS,QAAQ;OAAE,GAAG;OAAc;OAAe,CAAC;MACzE,IAAI,CAAC,OAAO,IACV,OAAO,MAA+B;OACpC,GAAG,OAAO;OACV,cAAc,aAAa;OAC5B,CAAC;MAEJ,gBAAgB,KAAK;OAAE,OAAO,aAAa;OAAO,OAAO,OAAO;OAAO,CAAC;;KAE1E,OAAO,GAAG,EAAE,iBAAiB,CAAC;;IAGvB;;EAEf,iBAAiB,UAA2B;GAC1C,OAAO,wBAAwB,SAAiC;;EAEnE;CACD,SAAS;EACP,OAAO;GAAE,UAAU;GAAkB,UAAU;GAAkB;;CAEpE;;;;;;;;;;;;AAaD,SAAS,cACP,MACqB;CACrB,OAAO;EACL,SAAS,KAAK;EAOd,UAAU,KAAK;EACf,SAAS;GAAE,MAAM;GAAI,YAAY,EAAE;GAAE;EACrC,YAAY;GACV,OAAO;IACL,uBAAO,IAAI,KAAa;IACxB,8BAAc,IAAI,KAAK;IACvB,8BAAc,IAAI,KAAK;IACvB,iCAAiB,IAAI,KAAK;IAC3B;GACD,yCAAyB,IAAI,KAAK;GACnC;EACF"}
|
package/package.json
CHANGED
|
@@ -1,35 +1,35 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/target-mongo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|
|
7
7
|
"description": "MongoDB target pack for Prisma Next",
|
|
8
8
|
"dependencies": {
|
|
9
|
-
"@prisma-next/adapter-mongo": "0.
|
|
10
|
-
"@prisma-next/contract": "0.
|
|
11
|
-
"@prisma-next/driver-mongo": "0.
|
|
12
|
-
"@prisma-next/errors": "0.
|
|
13
|
-
"@prisma-next/family-mongo": "0.
|
|
14
|
-
"@prisma-next/framework-components": "0.
|
|
15
|
-
"@prisma-next/migration-tools": "0.
|
|
16
|
-
"@prisma-next/ts-render": "0.
|
|
17
|
-
"@prisma-next/mongo-codec": "0.
|
|
18
|
-
"@prisma-next/mongo-contract": "0.
|
|
19
|
-
"@prisma-next/mongo-lowering": "0.
|
|
20
|
-
"@prisma-next/mongo-query-ast": "0.
|
|
21
|
-
"@prisma-next/mongo-schema-ir": "0.
|
|
22
|
-
"@prisma-next/mongo-value": "0.
|
|
23
|
-
"@prisma-next/utils": "0.
|
|
9
|
+
"@prisma-next/adapter-mongo": "0.10.0",
|
|
10
|
+
"@prisma-next/contract": "0.10.0",
|
|
11
|
+
"@prisma-next/driver-mongo": "0.10.0",
|
|
12
|
+
"@prisma-next/errors": "0.10.0",
|
|
13
|
+
"@prisma-next/family-mongo": "0.10.0",
|
|
14
|
+
"@prisma-next/framework-components": "0.10.0",
|
|
15
|
+
"@prisma-next/migration-tools": "0.10.0",
|
|
16
|
+
"@prisma-next/ts-render": "0.10.0",
|
|
17
|
+
"@prisma-next/mongo-codec": "0.10.0",
|
|
18
|
+
"@prisma-next/mongo-contract": "0.10.0",
|
|
19
|
+
"@prisma-next/mongo-lowering": "0.10.0",
|
|
20
|
+
"@prisma-next/mongo-query-ast": "0.10.0",
|
|
21
|
+
"@prisma-next/mongo-schema-ir": "0.10.0",
|
|
22
|
+
"@prisma-next/mongo-value": "0.10.0",
|
|
23
|
+
"@prisma-next/utils": "0.10.0",
|
|
24
24
|
"arktype": "^2.2.0",
|
|
25
25
|
"mongodb": "^6.16.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@prisma-next/mongo-contract-psl": "0.
|
|
29
|
-
"@prisma-next/psl-parser": "0.
|
|
30
|
-
"@prisma-next/test-utils": "0.
|
|
31
|
-
"@prisma-next/tsconfig": "0.
|
|
32
|
-
"@prisma-next/tsdown": "0.
|
|
28
|
+
"@prisma-next/mongo-contract-psl": "0.10.0",
|
|
29
|
+
"@prisma-next/psl-parser": "0.10.0",
|
|
30
|
+
"@prisma-next/test-utils": "0.10.0",
|
|
31
|
+
"@prisma-next/tsconfig": "0.10.0",
|
|
32
|
+
"@prisma-next/tsdown": "0.10.0",
|
|
33
33
|
"mongodb-memory-server": "11.1.0",
|
|
34
34
|
"pathe": "^2.0.3",
|
|
35
35
|
"tsdown": "0.22.0",
|
|
@@ -1,73 +1,63 @@
|
|
|
1
1
|
import { MongoContractSerializerBase } from '@prisma-next/family-mongo/ir';
|
|
2
|
-
import {
|
|
2
|
+
import { UNBOUND_NAMESPACE_ID } from '@prisma-next/framework-components/ir';
|
|
3
3
|
import { type MongoContract, MongoStorage } from '@prisma-next/mongo-contract';
|
|
4
4
|
import type { JsonObject } from '@prisma-next/utils/json';
|
|
5
5
|
import type { MongoTargetContract } from './mongo-target-contract';
|
|
6
|
-
import {
|
|
6
|
+
import { MongoTargetDatabase, MongoTargetUnboundDatabase } from './mongo-target-database';
|
|
7
7
|
|
|
8
|
-
/**
|
|
9
|
-
* Mongo target `ContractSerializer` concretion. Plugs into the
|
|
10
|
-
* family-shared deserialization pipeline at `constructTargetContract`,
|
|
11
|
-
* wrapping the validated flat-data shape in a `MongoStorage` class
|
|
12
|
-
* instance and providing the target's default namespace map.
|
|
13
|
-
*
|
|
14
|
-
* Default namespaces is
|
|
15
|
-
* `{ [UNSPECIFIED_NAMESPACE_ID]: MongoTargetUnspecifiedDatabase.instance }`
|
|
16
|
-
* — supplied at this target-layer call site because the family-layer
|
|
17
|
-
* `MongoStorage` class is target-agnostic (it cannot import the
|
|
18
|
-
* Mongo-target's namespace concretion). Contracts authored before
|
|
19
|
-
* multi-namespace support bind to the unspecified singleton without the
|
|
20
|
-
* call site declaring anything.
|
|
21
|
-
*
|
|
22
|
-
* `validated.storage.collections` already carries `MongoCollection` IR
|
|
23
|
-
* class instances by the time this method runs — the family-base
|
|
24
|
-
* `hydrateMongoContract` walks the arktype-validated tree and
|
|
25
|
-
* constructs class instances before validation. The target serializer
|
|
26
|
-
* just wraps the envelope.
|
|
27
|
-
*/
|
|
28
8
|
export class MongoTargetContractSerializer extends MongoContractSerializerBase<MongoTargetContract> {
|
|
29
9
|
protected constructTargetContract(validated: MongoContract): MongoTargetContract {
|
|
30
10
|
const { storage, ...rest } = validated;
|
|
11
|
+
const namespaces = Object.fromEntries(
|
|
12
|
+
Object.entries(storage.namespaces).map(([nsId, nsData]) => {
|
|
13
|
+
const collections = nsData.collections;
|
|
14
|
+
const collectionCount = Object.keys(collections).length;
|
|
15
|
+
if (nsId === UNBOUND_NAMESPACE_ID && collectionCount === 0) {
|
|
16
|
+
return [nsId, MongoTargetUnboundDatabase.instance];
|
|
17
|
+
}
|
|
18
|
+
return [
|
|
19
|
+
nsId,
|
|
20
|
+
new MongoTargetDatabase({
|
|
21
|
+
id: nsData.id,
|
|
22
|
+
collections,
|
|
23
|
+
}),
|
|
24
|
+
];
|
|
25
|
+
}),
|
|
26
|
+
);
|
|
31
27
|
const targetStorage = new MongoStorage({
|
|
32
28
|
storageHash: storage.storageHash,
|
|
33
|
-
|
|
34
|
-
namespaces: {
|
|
35
|
-
[UNSPECIFIED_NAMESPACE_ID]: MongoTargetUnspecifiedDatabase.instance,
|
|
36
|
-
},
|
|
29
|
+
namespaces,
|
|
37
30
|
});
|
|
38
31
|
return { ...rest, storage: targetStorage };
|
|
39
32
|
}
|
|
40
33
|
|
|
41
|
-
/**
|
|
42
|
-
* Produce the canonical on-disk JSON shape from an in-memory Mongo
|
|
43
|
-
* contract. Strips runtime-only fields the storage class carries
|
|
44
|
-
* for its live-instance API but that don't belong in the persisted
|
|
45
|
-
* envelope: `MongoStorage.namespaces` is a Namespace-class map the
|
|
46
|
-
* verifier and runtime walk; the persisted shape omits it (today's
|
|
47
|
-
* contracts have a single implicit unspecified namespace; future
|
|
48
|
-
* explicit per-collection assignment will surface in JSON via a
|
|
49
|
-
* different field).
|
|
50
|
-
*
|
|
51
|
-
* Constructing the JsonObject here — rather than relying on
|
|
52
|
-
* non-enumerable property tricks at the storage class — keeps the
|
|
53
|
-
* "what's on disk" decision in the SPI implementer, where it
|
|
54
|
-
* belongs.
|
|
55
|
-
*/
|
|
56
34
|
override serializeContract(contract: MongoTargetContract): JsonObject {
|
|
57
35
|
const { storage, ...rest } = contract;
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
36
|
+
const namespacesJson: Record<string, JsonObject> = {};
|
|
37
|
+
for (const [nsId, ns] of Object.entries(storage.namespaces)) {
|
|
38
|
+
const collectionsOut: Record<string, JsonObject> = {};
|
|
39
|
+
for (const [collName, coll] of Object.entries(ns.collections)) {
|
|
40
|
+
collectionsOut[collName] = JSON.parse(JSON.stringify(coll)) as JsonObject;
|
|
41
|
+
}
|
|
42
|
+
namespacesJson[nsId] = {
|
|
43
|
+
id: ns.id,
|
|
44
|
+
kind: 'mongo-database',
|
|
45
|
+
collections: collectionsOut,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
65
48
|
return {
|
|
66
49
|
...rest,
|
|
67
50
|
storage: {
|
|
68
|
-
storageHash: storage.storageHash,
|
|
69
|
-
|
|
51
|
+
storageHash: String(storage.storageHash),
|
|
52
|
+
namespaces: namespacesJson,
|
|
70
53
|
},
|
|
54
|
+
// `rest` carries Contract fields typed against framework interfaces
|
|
55
|
+
// (e.g. `ContractExecutionSection`) that TypeScript can't structurally
|
|
56
|
+
// prove are JSON-compatible without a per-field re-validation pass.
|
|
57
|
+
// The runtime invariant is that an emitted MongoTargetContract has
|
|
58
|
+
// already been through validation and contains only JSON-safe values,
|
|
59
|
+
// so the two-step cast is intentional. Mirrors the pattern in
|
|
60
|
+
// PostgresContractSerializer.serializeContract.
|
|
71
61
|
} as unknown as JsonObject;
|
|
72
62
|
}
|
|
73
63
|
}
|
|
@@ -1,42 +1,50 @@
|
|
|
1
1
|
import {
|
|
2
2
|
freezeNode,
|
|
3
3
|
NamespaceBase,
|
|
4
|
-
|
|
4
|
+
UNBOUND_NAMESPACE_ID,
|
|
5
5
|
} from '@prisma-next/framework-components/ir';
|
|
6
|
+
import { MongoCollection, type MongoCollectionInput } from '@prisma-next/mongo-contract';
|
|
7
|
+
|
|
8
|
+
export interface MongoTargetDatabaseInput {
|
|
9
|
+
readonly id: string;
|
|
10
|
+
readonly collections?: Record<string, MongoCollection | MongoCollectionInput>;
|
|
11
|
+
}
|
|
6
12
|
|
|
7
13
|
/**
|
|
8
14
|
* Mongo target `Namespace` concretion. In Mongo the "namespace" concept
|
|
9
15
|
* binds to the connection's `db` field — a `MongoTargetDatabase` instance
|
|
10
|
-
* names the database the collections live under.
|
|
16
|
+
* names the database the collections live under. The unbound singleton
|
|
17
|
+
* (below) is the late-bound slot whose binding the connection's `db`
|
|
18
|
+
* resolves at runtime rather than at authoring time.
|
|
11
19
|
*
|
|
12
20
|
* Qualifier emission is the rendering seam: query / DDL emission asks the
|
|
13
21
|
* namespace for its qualifier (e.g. `"<db>.<collection>"`) and consumes
|
|
14
|
-
* the result polymorphically. The
|
|
22
|
+
* the result polymorphically. The unbound singleton overrides these
|
|
15
23
|
* methods to elide the prefix entirely — call sites stay polymorphic and
|
|
16
|
-
* never branch on `id ===
|
|
17
|
-
*
|
|
18
|
-
* **Freeze-trap warning.** The constructor calls `freezeNode(this)` at
|
|
19
|
-
* the end. Direct subclasses MUST NOT add instance fields — the freeze
|
|
20
|
-
* runs in this base constructor and any subclass field assignment will
|
|
21
|
-
* silently fail in non-strict mode or throw in strict mode. The
|
|
22
|
-
* `MongoTargetUnspecifiedDatabase` singleton below is intentionally
|
|
23
|
-
* field-free for this reason; if a future subclass needs to carry
|
|
24
|
-
* additional fields, lift this `freezeNode` to the leaf-class
|
|
25
|
-
* constructors (or to a `seal()` hook each leaf calls explicitly).
|
|
24
|
+
* never branch on `id === UNBOUND_NAMESPACE_ID`.
|
|
26
25
|
*/
|
|
27
26
|
export class MongoTargetDatabase extends NamespaceBase {
|
|
28
27
|
readonly kind = 'database' as const;
|
|
29
28
|
readonly id: string;
|
|
29
|
+
readonly collections: Readonly<Record<string, MongoCollection>>;
|
|
30
30
|
|
|
31
|
-
constructor(
|
|
31
|
+
constructor(input: MongoTargetDatabaseInput) {
|
|
32
32
|
super();
|
|
33
|
-
this.id = id;
|
|
33
|
+
this.id = input.id;
|
|
34
|
+
this.collections = Object.freeze(
|
|
35
|
+
Object.fromEntries(
|
|
36
|
+
Object.entries(input.collections ?? {}).map(([name, c]) => [
|
|
37
|
+
name,
|
|
38
|
+
c instanceof MongoCollection ? c : new MongoCollection(c),
|
|
39
|
+
]),
|
|
40
|
+
),
|
|
41
|
+
);
|
|
34
42
|
freezeNode(this);
|
|
35
43
|
}
|
|
36
44
|
|
|
37
45
|
/**
|
|
38
46
|
* The bare qualifier as it would appear in a rendered string. The
|
|
39
|
-
*
|
|
47
|
+
* unbound-database singleton overrides this to return `''`.
|
|
40
48
|
*/
|
|
41
49
|
qualifier(): string {
|
|
42
50
|
return this.id;
|
|
@@ -44,7 +52,7 @@ export class MongoTargetDatabase extends NamespaceBase {
|
|
|
44
52
|
|
|
45
53
|
/**
|
|
46
54
|
* Qualify a collection name with the database prefix. The
|
|
47
|
-
*
|
|
55
|
+
* unbound-database singleton overrides this to emit just the
|
|
48
56
|
* collection name. Used by emission/introspection paths that need a
|
|
49
57
|
* fully-qualified reference.
|
|
50
58
|
*/
|
|
@@ -55,21 +63,22 @@ export class MongoTargetDatabase extends NamespaceBase {
|
|
|
55
63
|
|
|
56
64
|
/**
|
|
57
65
|
* Singleton subclass for the reserved sentinel namespace id
|
|
58
|
-
* (`
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
66
|
+
* (`UNBOUND_NAMESPACE_ID`) — the late-bound slot whose binding the
|
|
67
|
+
* connection's `db` resolves at runtime. Overrides qualifier emission
|
|
68
|
+
* to elide the database prefix; call sites that consume `qualifier()`
|
|
69
|
+
* / `qualifyCollection()` get unqualified output without branching on
|
|
70
|
+
* the namespace id.
|
|
62
71
|
*
|
|
63
72
|
* This is the target-side materialization of "the framework provides
|
|
64
73
|
* affordances; targets implement specifics": the framework names the
|
|
65
|
-
* sentinel; Mongo decides what
|
|
66
|
-
*
|
|
74
|
+
* sentinel; Mongo decides what late-bound means here (the collection
|
|
75
|
+
* name, naked — the database is supplied by the live connection).
|
|
67
76
|
*/
|
|
68
|
-
export class
|
|
69
|
-
static readonly instance:
|
|
77
|
+
export class MongoTargetUnboundDatabase extends MongoTargetDatabase {
|
|
78
|
+
static readonly instance: MongoTargetUnboundDatabase = new MongoTargetUnboundDatabase();
|
|
70
79
|
|
|
71
80
|
private constructor() {
|
|
72
|
-
super(
|
|
81
|
+
super({ id: UNBOUND_NAMESPACE_ID });
|
|
73
82
|
}
|
|
74
83
|
|
|
75
84
|
override qualifier(): string {
|
|
@@ -17,8 +17,8 @@ import type { MongoTargetContract } from './mongo-target-contract';
|
|
|
17
17
|
* `diffMongoSchemas`) so production verification behaviour is unchanged.
|
|
18
18
|
*
|
|
19
19
|
* Today's invariant: every Mongo contract carries exactly one
|
|
20
|
-
* namespace (the
|
|
21
|
-
* `
|
|
20
|
+
* namespace (the unbound singleton, materialised as
|
|
21
|
+
* `MongoTargetUnboundDatabase`), so the family-base namespace walk
|
|
22
22
|
* dispatches exactly once and the per-namespace body runs the existing
|
|
23
23
|
* whole-schema diff. Future per-collection namespace assignment will
|
|
24
24
|
* have this hook project the diff to the namespace's owned collections.
|
package/src/exports/control.ts
CHANGED
|
@@ -16,7 +16,7 @@ export type { MongoTargetContract } from '../core/mongo-target-contract';
|
|
|
16
16
|
export { MongoTargetContractSerializer } from '../core/mongo-target-contract-serializer';
|
|
17
17
|
export {
|
|
18
18
|
MongoTargetDatabase,
|
|
19
|
-
|
|
19
|
+
MongoTargetUnboundDatabase,
|
|
20
20
|
} from '../core/mongo-target-database';
|
|
21
21
|
export { MongoTargetSchemaVerifier } from '../core/mongo-target-schema-verifier';
|
|
22
22
|
export type { CollModMeta, OpFactoryCall } from '../core/op-factory-call';
|