@prisma-next/target-mongo 0.4.0-dev.6 → 0.4.0-dev.7
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 +53 -4
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +168 -99
- package/dist/control.mjs.map +1 -1
- package/dist/migration.d.mts +2 -1
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +2 -1
- package/package.json +10 -8
- package/src/core/mongo-planner.ts +25 -8
- package/src/core/planner-produced-migration.ts +54 -0
- package/src/core/render-typescript.ts +17 -7
- package/src/exports/control.ts +2 -1
- package/src/exports/migration.ts +1 -0
package/dist/control.d.mts
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { a as DropCollectionCall, c as OpFactoryCallVisitor, i as CreateIndexCall, l as schemaCollectionToCreateCollectionOptions, n as CollModMeta, o as DropIndexCall, r as CreateCollectionCall, s as OpFactoryCall, t as CollModCall, u as schemaIndexToCreateIndexOptions } from "./op-factory-call-CfPGebEH.mjs";
|
|
2
2
|
import { MongoSchemaIR } from "@prisma-next/mongo-schema-ir";
|
|
3
|
-
import { MongoAndExpr, MongoDdlCommandVisitor, MongoExistsExpr, MongoExprFilter, MongoFieldFilter, MongoFilterExpr, MongoFilterVisitor, MongoInspectionCommandVisitor, MongoMigrationPlanOperation, MongoNotExpr, MongoOrExpr } from "@prisma-next/mongo-query-ast/control";
|
|
3
|
+
import { AnyMongoMigrationOperation, MongoAndExpr, MongoDdlCommandVisitor, MongoExistsExpr, MongoExprFilter, MongoFieldFilter, MongoFilterExpr, MongoFilterVisitor, MongoInspectionCommandVisitor, MongoMigrationPlanOperation, MongoNotExpr, MongoOrExpr } from "@prisma-next/mongo-query-ast/control";
|
|
4
|
+
import { Migration, MigrationMeta } from "@prisma-next/migration-tools/migration";
|
|
4
5
|
import { MongoContract } from "@prisma-next/mongo-contract";
|
|
5
|
-
import { MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlanner, MigrationPlannerConflict, MigrationPlannerResult, MigrationRunnerExecutionChecks, MigrationRunnerResult } from "@prisma-next/framework-components/control";
|
|
6
|
+
import { MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlanWithAuthoringSurface, MigrationPlanner, MigrationPlannerConflict, MigrationPlannerResult, MigrationRunnerExecutionChecks, MigrationRunnerResult, MigrationScaffoldContext } from "@prisma-next/framework-components/control";
|
|
6
7
|
import { ContractMarkerRecord } from "@prisma-next/contract/types";
|
|
7
8
|
import { Db } from "mongodb";
|
|
8
9
|
import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
|
|
@@ -65,8 +66,20 @@ declare class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'
|
|
|
65
66
|
readonly contract: unknown;
|
|
66
67
|
readonly schema: unknown;
|
|
67
68
|
readonly policy: MigrationOperationPolicy;
|
|
69
|
+
readonly fromHash: string;
|
|
68
70
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;
|
|
69
71
|
}): MigrationPlannerResult;
|
|
72
|
+
/**
|
|
73
|
+
* Produce an empty `migration.ts` authoring surface for `migration new`.
|
|
74
|
+
*
|
|
75
|
+
* Mongo is a class-flow target, so the "empty migration" is a
|
|
76
|
+
* `PlannerProducedMongoMigration` with no operations; `renderTypeScript()`
|
|
77
|
+
* emits a stub class with the correct `from`/`to` metadata that the user
|
|
78
|
+
* then fills in with operations. The contract path on the context is
|
|
79
|
+
* unused — Mongo's emitted source does not import from the generated
|
|
80
|
+
* contract `.d.ts`.
|
|
81
|
+
*/
|
|
82
|
+
emptyMigration(context: MigrationScaffoldContext): MigrationPlanWithAuthoringSurface;
|
|
70
83
|
}
|
|
71
84
|
//#endregion
|
|
72
85
|
//#region src/core/mongo-runner.d.ts
|
|
@@ -111,6 +124,33 @@ declare class MongoMigrationRunner {
|
|
|
111
124
|
private ensureMarkerCompatibility;
|
|
112
125
|
}
|
|
113
126
|
//#endregion
|
|
127
|
+
//#region src/core/planner-produced-migration.d.ts
|
|
128
|
+
/**
|
|
129
|
+
* Planner-produced Mongo migration, returned by `MongoMigrationPlanner.plan(...)`
|
|
130
|
+
* and `MongoMigrationPlanner.emptyMigration(...)`.
|
|
131
|
+
*
|
|
132
|
+
* Unlike user-authored migrations (which extend `MongoMigration` from
|
|
133
|
+
* `@prisma-next/family-mongo/migration`), this class lives inside the target
|
|
134
|
+
* and holds the richer authoring IR (`OpFactoryCall[]`) needed to render
|
|
135
|
+
* itself back to TypeScript source. It implements
|
|
136
|
+
* `MigrationPlanWithAuthoringSurface` so that the CLI can uniformly ask any
|
|
137
|
+
* planner result to serialize itself to a `migration.ts`.
|
|
138
|
+
*
|
|
139
|
+
* Extends the framework `Migration` base class directly (not
|
|
140
|
+
* `MongoMigration`) because `MongoMigration` lives in `@prisma-next/family-mongo`,
|
|
141
|
+
* which depends on this package — extending it here would create a dependency
|
|
142
|
+
* cycle.
|
|
143
|
+
*/
|
|
144
|
+
declare class PlannerProducedMongoMigration extends Migration<AnyMongoMigrationOperation> implements MigrationPlanWithAuthoringSurface {
|
|
145
|
+
private readonly calls;
|
|
146
|
+
private readonly meta;
|
|
147
|
+
readonly targetId: "mongo";
|
|
148
|
+
constructor(calls: readonly OpFactoryCall[], meta: MigrationMeta);
|
|
149
|
+
get operations(): readonly AnyMongoMigrationOperation[];
|
|
150
|
+
describe(): MigrationMeta;
|
|
151
|
+
renderTypeScript(): string;
|
|
152
|
+
}
|
|
153
|
+
//#endregion
|
|
114
154
|
//#region src/core/render-ops.d.ts
|
|
115
155
|
declare function renderOps(calls: ReadonlyArray<OpFactoryCall>): MongoMigrationPlanOperation[];
|
|
116
156
|
//#endregion
|
|
@@ -121,7 +161,16 @@ interface RenderMigrationMeta {
|
|
|
121
161
|
readonly kind?: string;
|
|
122
162
|
readonly labels?: readonly string[];
|
|
123
163
|
}
|
|
124
|
-
|
|
164
|
+
/**
|
|
165
|
+
* Render a list of Mongo `OpFactoryCall`s as a class-flow `migration.ts`
|
|
166
|
+
* source string. The result is shebanged, extends the user-facing
|
|
167
|
+
* `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
|
|
168
|
+
* implements the abstract `operations` and `describe` members. `meta` is
|
|
169
|
+
* always rendered — `describe()` is part of the `Migration` contract, so
|
|
170
|
+
* even an empty stub must satisfy it; callers pass empty strings for a
|
|
171
|
+
* migration-new scaffold.
|
|
172
|
+
*/
|
|
173
|
+
declare function renderCallsToTypeScript(calls: ReadonlyArray<OpFactoryCall>, meta: RenderMigrationMeta): string;
|
|
125
174
|
//#endregion
|
|
126
|
-
export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoRunnerDependencies, type OpFactoryCall, type OpFactoryCallVisitor, type PlanCallsResult, type RenderMigrationMeta, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker,
|
|
175
|
+
export { CollModCall, type CollModMeta, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, type MarkerOperations, MongoMigrationPlanner, MongoMigrationRunner, type MongoRunnerDependencies, type OpFactoryCall, type OpFactoryCallVisitor, type PlanCallsResult, PlannerProducedMongoMigration, type RenderMigrationMeta, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
|
|
127
176
|
//# 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/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"sourcesContent":[],"mappings":";;;;;;;;;;;iBAoDgB,uBAAA,WAAkC,uBAAuB;;;iBC6CzD,qBAAA,sBAA2C;;;cC/C9C,eAAA,YAA2B;;mBAGrB,sBAAsB;cAK3B;YAKF;WAID;YAIC;eAIG;cAKD;;;;iBCjDQ,UAAA,KAAe,KAAK,QAAQ;iBAgB5B,UAAA,KAChB;;;IAEH;iBAcmB,YAAA,KAChB;;;IAGH;AHhBa,iBGiCM,gBAAA,CHjCiB,EAAW,EGkC5C,EHlC4C,EAAA,KAAA,EAAA;;;;AC6ClD,CAAA,CAAA,EETG,OFSa,CAAA,IAAA,CAAA;;;iBGiKA,kBAAA,iBAAmC;iBAYnC,mBAAA,4BAA+C;iBAI/C,iBAAA,eAAgC;;;KC9KpC,eAAA;;kBACoC;;;sBACI;;cAEvC,qBAAA,YAAiC;ELpD9B,SAAA,CAAA,OAAA,EAAA;;;qBKwDK;IJXL,SAAA,mBAAqB,EIYH,aJZyB,CIYX,8BJZiC,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;MIa3E;;;IH5DO,SAAA,MAAgB,EAAA,OAAA;IAGV,SAAA,MAAA,EG6KE,wBH7KF;IAAsB,SAAA,QAAA,EAAA,MAAA;IAK3B,SAAA,mBAAA,EG0KoB,aH1KpB,CG0KkC,8BH1KlC,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;EAKF,CAAA,CAAA,EGsKN,sBHtKM;EAID;;;;;;;;;ACpCX;EAAqC,cAAA,CAAA,OAAA,EE6NX,wBF7NW,CAAA,EE6NgB,iCF7NhB;;;;UGXpB,gBAAA;gBACD,QAAQ;;;;MAIlB;;IN2BU,SAAA,WAAA,EAAuB,MAAA;;MMvBlC;;ILoEW,SAAA,MAAA,EAAA,MAAqB;;;MK/D/B;AJgBN;AAGmB,UIhBF,uBAAA,CJgBE;EAAsB,SAAA,eAAA,EIfb,sBJea,CIfU,OJeV,CAAA,IAAA,CAAA,CAAA;EAK3B,SAAA,kBAAA,EInBiB,6BJmBjB,CInB+C,OJmB/C,CInBuD,MJmBvD,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,CAAA,CAAA;EAKF,SAAA,SAAA,EIvBU,gBJuBV;;AAQA,cIhBC,oBAAA,CJgBD;EAIG,iBAAA,IAAA;EAKD,WAAA,CAAA,IAAA,EIxBuB,uBJwBvB;EA9B0B,OAAA,CAAA,OAAA,EAAA;IAAkB,SAAA,IAAA,EISvC,aJTuC;;qBIWrC;;MH9BC,gBAAU,EAAA,EAAA,EGgCJ,sBHhCI,CAAA,EAAA,IAAA;MAAK,mBAAA,EAAA,EAAA,EGiCN,sBHjCM,CAAA,EAAA,IAAA;IAAa,CAAA;IAAR,SAAA,eAAA,CAAA,EGmCX,8BHnCW;IAAO,SAAA,mBAAA,EGoCf,aHpCe,CGoCD,8BHpCC,CAAA,OAAA,EAAA,OAAA,CAAA,CAAA;EAgB3B,CAAA,CAAA,EGqBhB,OHrBgB,CGqBR,qBHlBX,CAAA;EAcmB,QAAA,cAAY;EAqBZ,QAAA,kBAAgB;;;;;;;;;;;;;AHjCtC;;;;AC6CA;;;;AC/CA;AAGmB,cK7BN,6BAAA,SACH,SL4BS,CK5BC,0BL4BD,CAAA,YK3BN,iCL2BM,CAAA;EAAsB,iBAAA,KAAA;EAK3B,iBAAA,IAAA;EAKF,SAAA,QAAA,EAAA,OAAA;EAID,WAAA,CAAA,KAAA,EAAA,SKpC0B,aLoC1B,EAAA,EAAA,IAAA,EKnCgB,aLmChB;EAIC,IAAA,UAAA,CAAA,CAAA,EAAA,SKlC0B,0BLkC1B,EAAA;EAIG,QAAA,CAAA,CAAA,EKlCQ,aLkCR;EAKD,gBAAA,CAAA,CAAA,EAAA,MAAA;;;;iBM5CE,SAAA,QAAiB,cAAc,iBAAiB;;;UCzB/C,mBAAA;;;;;;;;;;ATyCjB;;;;AC6CA;iBQtEgB,uBAAA,QACP,cAAc,sBACf"}
|
package/dist/control.mjs
CHANGED
|
@@ -3,6 +3,9 @@ import { MongoSchemaCollection, MongoSchemaCollectionOptions, MongoSchemaIR, Mon
|
|
|
3
3
|
import { RawAggregateCommand, RawFindOneAndUpdateCommand, RawInsertOneCommand } from "@prisma-next/mongo-query-ast/execution";
|
|
4
4
|
import { CollModCommand, CreateCollectionCommand, CreateIndexCommand, DropCollectionCommand, DropIndexCommand, ListCollectionsCommand, ListIndexesCommand, MongoAndExpr, MongoExistsExpr, MongoFieldFilter, MongoNotExpr, MongoOrExpr } from "@prisma-next/mongo-query-ast/control";
|
|
5
5
|
import { type } from "arktype";
|
|
6
|
+
import { Migration } from "@prisma-next/migration-tools/migration";
|
|
7
|
+
import { ifDefined } from "@prisma-next/utils/defined";
|
|
8
|
+
import { detectScaffoldRuntime, shebangLineFor } from "@prisma-next/migration-tools/migration-ts";
|
|
6
9
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
7
10
|
|
|
8
11
|
//#region src/core/contract-to-schema.ts
|
|
@@ -600,6 +603,150 @@ function renderOps(calls) {
|
|
|
600
603
|
return calls.map((call) => call.accept(renderVisitor));
|
|
601
604
|
}
|
|
602
605
|
|
|
606
|
+
//#endregion
|
|
607
|
+
//#region src/core/render-typescript.ts
|
|
608
|
+
/**
|
|
609
|
+
* Render a list of Mongo `OpFactoryCall`s as a class-flow `migration.ts`
|
|
610
|
+
* source string. The result is shebanged, extends the user-facing
|
|
611
|
+
* `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
|
|
612
|
+
* implements the abstract `operations` and `describe` members. `meta` is
|
|
613
|
+
* always rendered — `describe()` is part of the `Migration` contract, so
|
|
614
|
+
* even an empty stub must satisfy it; callers pass empty strings for a
|
|
615
|
+
* migration-new scaffold.
|
|
616
|
+
*/
|
|
617
|
+
function renderCallsToTypeScript(calls, meta) {
|
|
618
|
+
const imports = buildImports(collectFactoryNames(calls));
|
|
619
|
+
const operationsBody = calls.map((c) => c.accept(renderCallVisitor)).join(",\n");
|
|
620
|
+
return [
|
|
621
|
+
shebangLineFor(detectScaffoldRuntime()),
|
|
622
|
+
imports,
|
|
623
|
+
"",
|
|
624
|
+
"class M extends Migration {",
|
|
625
|
+
buildDescribeMethod(meta),
|
|
626
|
+
" override get operations() {",
|
|
627
|
+
" return [",
|
|
628
|
+
indent(operationsBody, 6),
|
|
629
|
+
" ];",
|
|
630
|
+
" }",
|
|
631
|
+
"}",
|
|
632
|
+
"",
|
|
633
|
+
"export default M;",
|
|
634
|
+
"Migration.run(import.meta.url, M);",
|
|
635
|
+
""
|
|
636
|
+
].join("\n");
|
|
637
|
+
}
|
|
638
|
+
function collectFactoryNames(calls) {
|
|
639
|
+
const names = /* @__PURE__ */ new Set();
|
|
640
|
+
for (const call of calls) names.add(call.factory);
|
|
641
|
+
return [...names].sort();
|
|
642
|
+
}
|
|
643
|
+
function buildImports(factoryNames) {
|
|
644
|
+
const lines = ["import { Migration } from '@prisma-next/family-mongo/migration';"];
|
|
645
|
+
if (factoryNames.length > 0) lines.push(`import { ${factoryNames.join(", ")} } from '@prisma-next/target-mongo/migration';`);
|
|
646
|
+
return lines.join("\n");
|
|
647
|
+
}
|
|
648
|
+
function buildDescribeMethod(meta) {
|
|
649
|
+
const lines = [];
|
|
650
|
+
lines.push(" override describe() {");
|
|
651
|
+
lines.push(" return {");
|
|
652
|
+
lines.push(` from: ${JSON.stringify(meta.from)},`);
|
|
653
|
+
lines.push(` to: ${JSON.stringify(meta.to)},`);
|
|
654
|
+
if (meta.kind) lines.push(` kind: ${JSON.stringify(meta.kind)},`);
|
|
655
|
+
if (meta.labels && meta.labels.length > 0) lines.push(` labels: ${renderLiteral(meta.labels)},`);
|
|
656
|
+
lines.push(" };");
|
|
657
|
+
lines.push(" }");
|
|
658
|
+
lines.push("");
|
|
659
|
+
return lines.join("\n");
|
|
660
|
+
}
|
|
661
|
+
const renderCallVisitor = {
|
|
662
|
+
createIndex(call) {
|
|
663
|
+
return call.options ? `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)}, ${renderLiteral(call.options)})` : `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
|
|
664
|
+
},
|
|
665
|
+
dropIndex(call) {
|
|
666
|
+
return `dropIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
|
|
667
|
+
},
|
|
668
|
+
createCollection(call) {
|
|
669
|
+
return call.options ? `createCollection(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})` : `createCollection(${renderLiteral(call.collection)})`;
|
|
670
|
+
},
|
|
671
|
+
dropCollection(call) {
|
|
672
|
+
return `dropCollection(${renderLiteral(call.collection)})`;
|
|
673
|
+
},
|
|
674
|
+
collMod(call) {
|
|
675
|
+
return call.meta ? `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)}, ${renderLiteral(call.meta)})` : `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`;
|
|
676
|
+
}
|
|
677
|
+
};
|
|
678
|
+
function renderLiteral(value) {
|
|
679
|
+
if (value === void 0) return "undefined";
|
|
680
|
+
if (value === null) return "null";
|
|
681
|
+
if (typeof value === "string") return JSON.stringify(value);
|
|
682
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
683
|
+
if (Array.isArray(value)) {
|
|
684
|
+
if (value.length === 0) return "[]";
|
|
685
|
+
const items = value.map((v) => renderLiteral(v));
|
|
686
|
+
const singleLine = `[${items.join(", ")}]`;
|
|
687
|
+
if (singleLine.length <= 80) return singleLine;
|
|
688
|
+
return `[\n${items.map((i) => ` ${i}`).join(",\n")},\n]`;
|
|
689
|
+
}
|
|
690
|
+
if (typeof value === "object") {
|
|
691
|
+
const entries = Object.entries(value).filter(([, v]) => v !== void 0);
|
|
692
|
+
if (entries.length === 0) return "{}";
|
|
693
|
+
const items = entries.map(([k, v]) => `${renderKey(k)}: ${renderLiteral(v)}`);
|
|
694
|
+
const singleLine = `{ ${items.join(", ")} }`;
|
|
695
|
+
if (singleLine.length <= 80) return singleLine;
|
|
696
|
+
return `{\n${items.map((i) => ` ${i}`).join(",\n")},\n}`;
|
|
697
|
+
}
|
|
698
|
+
return String(value);
|
|
699
|
+
}
|
|
700
|
+
function renderKey(key) {
|
|
701
|
+
if (key === "__proto__") return JSON.stringify(key);
|
|
702
|
+
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
|
|
703
|
+
}
|
|
704
|
+
function indent(text, spaces) {
|
|
705
|
+
const pad = " ".repeat(spaces);
|
|
706
|
+
return text.split("\n").map((line) => line.trim() ? `${pad}${line}` : line).join("\n");
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
//#endregion
|
|
710
|
+
//#region src/core/planner-produced-migration.ts
|
|
711
|
+
/**
|
|
712
|
+
* Planner-produced Mongo migration, returned by `MongoMigrationPlanner.plan(...)`
|
|
713
|
+
* and `MongoMigrationPlanner.emptyMigration(...)`.
|
|
714
|
+
*
|
|
715
|
+
* Unlike user-authored migrations (which extend `MongoMigration` from
|
|
716
|
+
* `@prisma-next/family-mongo/migration`), this class lives inside the target
|
|
717
|
+
* and holds the richer authoring IR (`OpFactoryCall[]`) needed to render
|
|
718
|
+
* itself back to TypeScript source. It implements
|
|
719
|
+
* `MigrationPlanWithAuthoringSurface` so that the CLI can uniformly ask any
|
|
720
|
+
* planner result to serialize itself to a `migration.ts`.
|
|
721
|
+
*
|
|
722
|
+
* Extends the framework `Migration` base class directly (not
|
|
723
|
+
* `MongoMigration`) because `MongoMigration` lives in `@prisma-next/family-mongo`,
|
|
724
|
+
* which depends on this package — extending it here would create a dependency
|
|
725
|
+
* cycle.
|
|
726
|
+
*/
|
|
727
|
+
var PlannerProducedMongoMigration = class extends Migration {
|
|
728
|
+
targetId = "mongo";
|
|
729
|
+
constructor(calls, meta) {
|
|
730
|
+
super();
|
|
731
|
+
this.calls = calls;
|
|
732
|
+
this.meta = meta;
|
|
733
|
+
}
|
|
734
|
+
get operations() {
|
|
735
|
+
return renderOps(this.calls);
|
|
736
|
+
}
|
|
737
|
+
describe() {
|
|
738
|
+
return this.meta;
|
|
739
|
+
}
|
|
740
|
+
renderTypeScript() {
|
|
741
|
+
return renderCallsToTypeScript(this.calls, {
|
|
742
|
+
from: this.meta.from,
|
|
743
|
+
to: this.meta.to,
|
|
744
|
+
...ifDefined("kind", this.meta.kind),
|
|
745
|
+
...ifDefined("labels", this.meta.labels)
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
};
|
|
749
|
+
|
|
603
750
|
//#endregion
|
|
604
751
|
//#region src/core/mongo-planner.ts
|
|
605
752
|
function buildIndexLookupKey(index) {
|
|
@@ -715,13 +862,28 @@ var MongoMigrationPlanner = class {
|
|
|
715
862
|
if (result.kind === "failure") return result;
|
|
716
863
|
return {
|
|
717
864
|
kind: "success",
|
|
718
|
-
plan: {
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
}
|
|
865
|
+
plan: new PlannerProducedMongoMigration(result.calls, {
|
|
866
|
+
from: options.fromHash,
|
|
867
|
+
to: contract.storage.storageHash
|
|
868
|
+
})
|
|
723
869
|
};
|
|
724
870
|
}
|
|
871
|
+
/**
|
|
872
|
+
* Produce an empty `migration.ts` authoring surface for `migration new`.
|
|
873
|
+
*
|
|
874
|
+
* Mongo is a class-flow target, so the "empty migration" is a
|
|
875
|
+
* `PlannerProducedMongoMigration` with no operations; `renderTypeScript()`
|
|
876
|
+
* emits a stub class with the correct `from`/`to` metadata that the user
|
|
877
|
+
* then fills in with operations. The contract path on the context is
|
|
878
|
+
* unused — Mongo's emitted source does not import from the generated
|
|
879
|
+
* contract `.d.ts`.
|
|
880
|
+
*/
|
|
881
|
+
emptyMigration(context) {
|
|
882
|
+
return new PlannerProducedMongoMigration([], {
|
|
883
|
+
from: context.fromHash,
|
|
884
|
+
to: context.toHash
|
|
885
|
+
});
|
|
886
|
+
}
|
|
725
887
|
};
|
|
726
888
|
function planValidatorDiffCall(collName, originValidator, destValidator) {
|
|
727
889
|
if (validatorsEqual(originValidator, destValidator)) return void 0;
|
|
@@ -869,98 +1031,5 @@ var MongoMigrationRunner = class {
|
|
|
869
1031
|
};
|
|
870
1032
|
|
|
871
1033
|
//#endregion
|
|
872
|
-
|
|
873
|
-
function renderTypeScript(calls, meta) {
|
|
874
|
-
const imports = buildImports(collectFactoryNames(calls));
|
|
875
|
-
const planBody = calls.map((c) => c.accept(renderCallVisitor)).join(",\n");
|
|
876
|
-
return [
|
|
877
|
-
imports,
|
|
878
|
-
"",
|
|
879
|
-
"class M extends Migration {",
|
|
880
|
-
meta ? buildDescribeMethod(meta) : "",
|
|
881
|
-
" override plan() {",
|
|
882
|
-
" return [",
|
|
883
|
-
indent(planBody, 6),
|
|
884
|
-
" ];",
|
|
885
|
-
" }",
|
|
886
|
-
"}",
|
|
887
|
-
"",
|
|
888
|
-
"export default M;",
|
|
889
|
-
"Migration.run(import.meta.url, M);",
|
|
890
|
-
""
|
|
891
|
-
].join("\n");
|
|
892
|
-
}
|
|
893
|
-
function collectFactoryNames(calls) {
|
|
894
|
-
const names = /* @__PURE__ */ new Set();
|
|
895
|
-
for (const call of calls) names.add(call.factory);
|
|
896
|
-
return [...names].sort();
|
|
897
|
-
}
|
|
898
|
-
function buildImports(factoryNames) {
|
|
899
|
-
const lines = ["import { Migration } from '@prisma-next/family-mongo/migration';"];
|
|
900
|
-
if (factoryNames.length > 0) lines.push(`import { ${factoryNames.join(", ")} } from '@prisma-next/target-mongo/migration';`);
|
|
901
|
-
return lines.join("\n");
|
|
902
|
-
}
|
|
903
|
-
function buildDescribeMethod(meta) {
|
|
904
|
-
const lines = [];
|
|
905
|
-
lines.push(" override describe() {");
|
|
906
|
-
lines.push(" return {");
|
|
907
|
-
lines.push(` from: ${JSON.stringify(meta.from)},`);
|
|
908
|
-
lines.push(` to: ${JSON.stringify(meta.to)},`);
|
|
909
|
-
if (meta.kind) lines.push(` kind: ${JSON.stringify(meta.kind)},`);
|
|
910
|
-
if (meta.labels && meta.labels.length > 0) lines.push(` labels: ${renderLiteral(meta.labels)},`);
|
|
911
|
-
lines.push(" };");
|
|
912
|
-
lines.push(" }");
|
|
913
|
-
lines.push("");
|
|
914
|
-
return lines.join("\n");
|
|
915
|
-
}
|
|
916
|
-
const renderCallVisitor = {
|
|
917
|
-
createIndex(call) {
|
|
918
|
-
return call.options ? `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)}, ${renderLiteral(call.options)})` : `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
|
|
919
|
-
},
|
|
920
|
-
dropIndex(call) {
|
|
921
|
-
return `dropIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;
|
|
922
|
-
},
|
|
923
|
-
createCollection(call) {
|
|
924
|
-
return call.options ? `createCollection(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})` : `createCollection(${renderLiteral(call.collection)})`;
|
|
925
|
-
},
|
|
926
|
-
dropCollection(call) {
|
|
927
|
-
return `dropCollection(${renderLiteral(call.collection)})`;
|
|
928
|
-
},
|
|
929
|
-
collMod(call) {
|
|
930
|
-
return call.meta ? `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)}, ${renderLiteral(call.meta)})` : `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`;
|
|
931
|
-
}
|
|
932
|
-
};
|
|
933
|
-
function renderLiteral(value) {
|
|
934
|
-
if (value === void 0) return "undefined";
|
|
935
|
-
if (value === null) return "null";
|
|
936
|
-
if (typeof value === "string") return JSON.stringify(value);
|
|
937
|
-
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
938
|
-
if (Array.isArray(value)) {
|
|
939
|
-
if (value.length === 0) return "[]";
|
|
940
|
-
const items = value.map((v) => renderLiteral(v));
|
|
941
|
-
const singleLine = `[${items.join(", ")}]`;
|
|
942
|
-
if (singleLine.length <= 80) return singleLine;
|
|
943
|
-
return `[\n${items.map((i) => ` ${i}`).join(",\n")},\n]`;
|
|
944
|
-
}
|
|
945
|
-
if (typeof value === "object") {
|
|
946
|
-
const entries = Object.entries(value).filter(([, v]) => v !== void 0);
|
|
947
|
-
if (entries.length === 0) return "{}";
|
|
948
|
-
const items = entries.map(([k, v]) => `${renderKey(k)}: ${renderLiteral(v)}`);
|
|
949
|
-
const singleLine = `{ ${items.join(", ")} }`;
|
|
950
|
-
if (singleLine.length <= 80) return singleLine;
|
|
951
|
-
return `{\n${items.map((i) => ` ${i}`).join(",\n")},\n}`;
|
|
952
|
-
}
|
|
953
|
-
return String(value);
|
|
954
|
-
}
|
|
955
|
-
function renderKey(key) {
|
|
956
|
-
if (key === "__proto__") return JSON.stringify(key);
|
|
957
|
-
return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
|
|
958
|
-
}
|
|
959
|
-
function indent(text, spaces) {
|
|
960
|
-
const pad = " ".repeat(spaces);
|
|
961
|
-
return text.split("\n").map((line) => line.trim() ? `${pad}${line}` : line).join("\n");
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
//#endregion
|
|
965
|
-
export { CollModCall, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, MongoMigrationPlanner, MongoMigrationRunner, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderOps, renderTypeScript, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
|
|
1034
|
+
export { CollModCall, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, MongoMigrationPlanner, MongoMigrationRunner, PlannerProducedMongoMigration, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
|
|
966
1035
|
//# sourceMappingURL=control.mjs.map
|
package/dist/control.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"control.mjs","names":["parts: string[]","statements: string[]","current: unknown","opts: MongoSchemaCollectionOptions | undefined","validator: MongoSchemaValidator | undefined","renderVisitor: OpFactoryCallVisitor<MongoMigrationPlanOperation>","collCreates: OpFactoryCall[]","drops: OpFactoryCall[]","creates: OpFactoryCall[]","validatorOps: OpFactoryCall[]","mutableOptionOps: OpFactoryCall[]","collDrops: OpFactoryCall[]","conflicts: MigrationPlannerConflict[]","operationClass: MigrationOperationClass","deps: MongoRunnerDependencies","lines: string[]","renderCallVisitor: OpFactoryCallVisitor<string>"],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/op-factory-call.ts","../src/core/render-ops.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/render-typescript.ts"],"sourcesContent":["import type {\n MongoContract,\n MongoStorageCollection,\n MongoStorageCollectionOptions,\n MongoStorageIndex,\n MongoStorageValidator,\n} from '@prisma-next/mongo-contract';\nimport {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaIR,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\n\nfunction convertIndex(index: MongoStorageIndex): MongoSchemaIndex {\n return new MongoSchemaIndex({\n keys: index.keys,\n unique: index.unique,\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\nfunction convertValidator(v: MongoStorageValidator): MongoSchemaValidator {\n return new MongoSchemaValidator({\n jsonSchema: v.jsonSchema,\n validationLevel: v.validationLevel,\n validationAction: v.validationAction,\n });\n}\n\nfunction convertOptions(o: MongoStorageCollectionOptions): MongoSchemaCollectionOptions {\n return new MongoSchemaCollectionOptions(o);\n}\n\nfunction convertCollection(name: string, def: MongoStorageCollection): MongoSchemaCollection {\n const indexes = (def.indexes ?? []).map(convertIndex);\n return new MongoSchemaCollection({\n name,\n indexes,\n ...(def.validator != null && { validator: convertValidator(def.validator) }),\n ...(def.options != null && { options: convertOptions(def.options) }),\n });\n}\n\nexport function contractToMongoSchemaIR(contract: MongoContract | null): MongoSchemaIR {\n if (!contract) {\n return new MongoSchemaIR([]);\n }\n\n const collections = Object.entries(contract.storage.collections).map(([name, def]) =>\n convertCollection(name, def),\n );\n\n return new MongoSchemaIR(collections);\n}\n","import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport type {\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n MongoDdlCommandVisitor,\n MongoIndexKey,\n} from '@prisma-next/mongo-query-ast/control';\n\nfunction formatKeySpec(keys: ReadonlyArray<MongoIndexKey>): string {\n const entries = keys.map((k) => `${JSON.stringify(k.field)}: ${JSON.stringify(k.direction)}`);\n return `{ ${entries.join(', ')} }`;\n}\n\nfunction formatOptions(cmd: CreateIndexCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.unique) parts.push('unique: true');\n if (cmd.sparse) parts.push('sparse: true');\n if (cmd.expireAfterSeconds !== undefined)\n parts.push(`expireAfterSeconds: ${cmd.expireAfterSeconds}`);\n if (cmd.name) parts.push(`name: ${JSON.stringify(cmd.name)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.weights) parts.push(`weights: ${JSON.stringify(cmd.weights)}`);\n if (cmd.default_language) parts.push(`default_language: ${JSON.stringify(cmd.default_language)}`);\n if (cmd.language_override)\n parts.push(`language_override: ${JSON.stringify(cmd.language_override)}`);\n if (cmd.wildcardProjection)\n parts.push(`wildcardProjection: ${JSON.stringify(cmd.wildcardProjection)}`);\n if (cmd.partialFilterExpression)\n parts.push(`partialFilterExpression: ${JSON.stringify(cmd.partialFilterExpression)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nfunction formatCreateCollectionOptions(cmd: CreateCollectionCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.capped) parts.push('capped: true');\n if (cmd.size !== undefined) parts.push(`size: ${cmd.size}`);\n if (cmd.max !== undefined) parts.push(`max: ${cmd.max}`);\n if (cmd.timeseries) parts.push(`timeseries: ${JSON.stringify(cmd.timeseries)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.clusteredIndex) parts.push(`clusteredIndex: ${JSON.stringify(cmd.clusteredIndex)}`);\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction) parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(`changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nclass MongoDdlCommandFormatter implements MongoDdlCommandVisitor<string> {\n createIndex(cmd: CreateIndexCommand): string {\n const keySpec = formatKeySpec(cmd.keys);\n const opts = formatOptions(cmd);\n return opts\n ? `db.${cmd.collection}.createIndex(${keySpec}, ${opts})`\n : `db.${cmd.collection}.createIndex(${keySpec})`;\n }\n\n dropIndex(cmd: DropIndexCommand): string {\n return `db.${cmd.collection}.dropIndex(${JSON.stringify(cmd.name)})`;\n }\n\n createCollection(cmd: CreateCollectionCommand): string {\n const opts = formatCreateCollectionOptions(cmd);\n return opts\n ? `db.createCollection(${JSON.stringify(cmd.collection)}, ${opts})`\n : `db.createCollection(${JSON.stringify(cmd.collection)})`;\n }\n\n dropCollection(cmd: DropCollectionCommand): string {\n return `db.${cmd.collection}.drop()`;\n }\n\n collMod(cmd: CollModCommand): string {\n const parts: string[] = [`collMod: ${JSON.stringify(cmd.collection)}`];\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction)\n parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(\n `changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`,\n );\n return `db.runCommand({ ${parts.join(', ')} })`;\n }\n}\n\nconst formatter = new MongoDdlCommandFormatter();\n\ninterface MongoExecuteStep {\n readonly command: { readonly accept: <R>(visitor: MongoDdlCommandVisitor<R>) => R };\n}\n\nexport function formatMongoOperations(operations: readonly MigrationPlanOperation[]): string[] {\n const statements: string[] = [];\n for (const operation of operations) {\n const candidate = operation as unknown as Record<string, unknown>;\n if (!('execute' in candidate) || !Array.isArray(candidate['execute'])) {\n continue;\n }\n for (const step of candidate['execute'] as MongoExecuteStep[]) {\n if (step.command && typeof step.command.accept === 'function') {\n statements.push(step.command.accept(formatter));\n }\n }\n }\n return statements;\n}\n","import type {\n MongoAndExpr,\n MongoExistsExpr,\n MongoExprFilter,\n MongoFieldFilter,\n MongoFilterExpr,\n MongoFilterVisitor,\n MongoNotExpr,\n MongoOrExpr,\n} from '@prisma-next/mongo-query-ast/control';\nimport { deepEqual } from '@prisma-next/mongo-schema-ir';\nimport type { MongoValue } from '@prisma-next/mongo-value';\n\nfunction getNestedField(doc: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = doc;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n const record = current as Record<string, unknown>;\n if (!Object.hasOwn(record, part)) {\n return undefined;\n }\n current = record[part];\n }\n return current;\n}\n\nfunction evaluateFieldOp(op: string, actual: unknown, expected: MongoValue): boolean {\n switch (op) {\n case '$eq':\n return deepEqual(actual, expected);\n case '$ne':\n return !deepEqual(actual, expected);\n case '$gt':\n return typeof actual === typeof expected && (actual as number) > (expected as number);\n case '$gte':\n return typeof actual === typeof expected && (actual as number) >= (expected as number);\n case '$lt':\n return typeof actual === typeof expected && (actual as number) < (expected as number);\n case '$lte':\n return typeof actual === typeof expected && (actual as number) <= (expected as number);\n case '$in':\n return Array.isArray(expected) && expected.some((v) => deepEqual(actual, v));\n default:\n throw new Error(`Unsupported filter operator in migration check: ${op}`);\n }\n}\n\nexport class FilterEvaluator implements MongoFilterVisitor<boolean> {\n private doc: Record<string, unknown> = {};\n\n evaluate(filter: MongoFilterExpr, doc: Record<string, unknown>): boolean {\n this.doc = doc;\n return filter.accept(this);\n }\n\n field(expr: MongoFieldFilter): boolean {\n const value = getNestedField(this.doc, expr.field);\n return evaluateFieldOp(expr.op, value, expr.value);\n }\n\n and(expr: MongoAndExpr): boolean {\n return expr.exprs.every((child) => child.accept(this));\n }\n\n or(expr: MongoOrExpr): boolean {\n return expr.exprs.some((child) => child.accept(this));\n }\n\n not(expr: MongoNotExpr): boolean {\n return !expr.expr.accept(this);\n }\n\n exists(expr: MongoExistsExpr): boolean {\n const has = getNestedField(this.doc, expr.field) !== undefined;\n return expr.exists ? has : !has;\n }\n\n expr(_expr: MongoExprFilter): boolean {\n throw new Error('Aggregation expression filters are not supported in migration checks');\n }\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport {\n RawAggregateCommand,\n RawFindOneAndUpdateCommand,\n RawInsertOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport type { Db, Document } from 'mongodb';\n\nconst COLLECTION = '_prisma_migrations';\nconst MARKER_ID = 'marker';\n\nasync function executeAggregate(db: Db, cmd: RawAggregateCommand): Promise<Document[]> {\n return db\n .collection(cmd.collection)\n .aggregate(cmd.pipeline as Record<string, unknown>[])\n .toArray();\n}\n\nasync function executeInsertOne(db: Db, cmd: RawInsertOneCommand): Promise<void> {\n await db.collection(cmd.collection).insertOne(cmd.document);\n}\n\nasync function executeFindOneAndUpdate(\n db: Db,\n cmd: RawFindOneAndUpdateCommand,\n): Promise<Document | null> {\n return db\n .collection(cmd.collection)\n .findOneAndUpdate(cmd.filter, cmd.update as Record<string, unknown>, { upsert: cmd.upsert });\n}\n\nexport async function readMarker(db: Db): Promise<ContractMarkerRecord | null> {\n const cmd = new RawAggregateCommand(COLLECTION, [{ $match: { _id: MARKER_ID } }, { $limit: 1 }]);\n const docs = await executeAggregate(db, cmd);\n const doc = docs[0];\n if (!doc) return null;\n return {\n storageHash: doc['storageHash'] as string,\n profileHash: doc['profileHash'] as string,\n contractJson: (doc['contractJson'] as unknown) ?? null,\n canonicalVersion: (doc['canonicalVersion'] as number) ?? null,\n updatedAt: doc['updatedAt'] as Date,\n appTag: (doc['appTag'] as string) ?? null,\n meta: (doc['meta'] as Record<string, unknown>) ?? {},\n };\n}\n\nexport async function initMarker(\n db: Db,\n destination: { readonly storageHash: string; readonly profileHash: string },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n _id: MARKER_ID,\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n contractJson: null,\n canonicalVersion: null,\n updatedAt: new Date(),\n appTag: null,\n meta: {},\n });\n await executeInsertOne(db, cmd);\n}\n\nexport async function updateMarker(\n db: Db,\n expectedFrom: string,\n destination: { readonly storageHash: string; readonly profileHash: string },\n): Promise<boolean> {\n const cmd = new RawFindOneAndUpdateCommand(\n COLLECTION,\n { _id: MARKER_ID, storageHash: expectedFrom },\n {\n $set: {\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n updatedAt: new Date(),\n },\n },\n false,\n );\n const result = await executeFindOneAndUpdate(db, cmd);\n return result !== null;\n}\n\nexport async function writeLedgerEntry(\n db: Db,\n entry: { readonly edgeId: string; readonly from: string; readonly to: string },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n type: 'ledger',\n edgeId: entry.edgeId,\n from: entry.from,\n to: entry.to,\n appliedAt: new Date(),\n });\n await executeInsertOne(db, cmd);\n}\n","import type { MigrationOperationClass } from '@prisma-next/framework-components/control';\nimport {\n type AnyMongoDdlCommand,\n type AnyMongoInspectionCommand,\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n ListCollectionsCommand,\n ListIndexesCommand,\n MongoAndExpr,\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 { 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\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 OperationJson = 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\nfunction validate<T>(schema: { assert: (data: unknown) => T }, data: unknown, context: string): T {\n try {\n return schema.assert(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\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\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\nexport function deserializeMongoOp(json: unknown): MongoMigrationPlanOperation {\n const data = validate(OperationJson, 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\nexport function deserializeMongoOps(json: readonly unknown[]): MongoMigrationPlanOperation[] {\n return json.map(deserializeMongoOp);\n}\n\nexport function serializeMongoOps(ops: readonly MongoMigrationPlanOperation[]): string {\n return JSON.stringify(ops, null, 2);\n}\n","import type { MigrationOperationClass } from '@prisma-next/framework-components/control';\nimport type {\n CollModOptions,\n CreateCollectionOptions,\n CreateIndexOptions,\n MongoIndexKey,\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';\n\nexport interface CollModMeta {\n readonly id?: string;\n readonly label?: string;\n readonly operationClass?: MigrationOperationClass;\n}\n\nexport interface OpFactoryCallVisitor<R> {\n createIndex(call: CreateIndexCall): R;\n dropIndex(call: DropIndexCall): R;\n createCollection(call: CreateCollectionCall): R;\n dropCollection(call: DropCollectionCall): R;\n collMod(call: CollModCall): R;\n}\n\nabstract class OpFactoryCallNode {\n abstract readonly factory: string;\n abstract readonly operationClass: MigrationOperationClass;\n abstract readonly label: string;\n abstract accept<R>(visitor: OpFactoryCallVisitor<R>): R;\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 factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.createIndex(this);\n }\n}\n\nexport class DropIndexCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.dropIndex(this);\n }\n}\n\nexport class CreateCollectionCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.createCollection(this);\n }\n}\n\nexport class DropCollectionCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.dropCollection(this);\n }\n}\n\nexport class CollModCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.collMod(this);\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 {\n collMod,\n createCollection,\n createIndex,\n dropCollection,\n dropIndex,\n} from './migration-factories';\nimport type {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n OpFactoryCall,\n OpFactoryCallVisitor,\n} from './op-factory-call';\n\nconst renderVisitor: OpFactoryCallVisitor<MongoMigrationPlanOperation> = {\n createIndex(call: CreateIndexCall) {\n return createIndex(call.collection, call.keys, call.options);\n },\n dropIndex(call: DropIndexCall) {\n return dropIndex(call.collection, call.keys);\n },\n createCollection(call: CreateCollectionCall) {\n return createCollection(call.collection, call.options);\n },\n dropCollection(call: DropCollectionCall) {\n return dropCollection(call.collection);\n },\n collMod(call: CollModCall) {\n return collMod(call.collection, call.options, call.meta);\n },\n};\n\nexport function renderOps(calls: ReadonlyArray<OpFactoryCall>): MongoMigrationPlanOperation[] {\n return calls.map((call) => call.accept(renderVisitor));\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationOperationClass,\n MigrationOperationPolicy,\n MigrationPlanner,\n MigrationPlannerConflict,\n MigrationPlannerResult,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaIR,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\nimport { canonicalize, deepEqual } from '@prisma-next/mongo-schema-ir';\nimport { contractToMongoSchemaIR } from './contract-to-schema';\nimport type { OpFactoryCall } from './op-factory-call';\nimport {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n schemaCollectionToCreateCollectionOptions,\n schemaIndexToCreateIndexOptions,\n} from './op-factory-call';\nimport { renderOps } from './render-ops';\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 if (destColl && collectionHasOptions(destColl)) {\n const opts = schemaCollectionToCreateCollectionOptions(destColl);\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 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: {\n targetId: 'mongo',\n destination: {\n storageHash: contract.storage.storageHash,\n },\n operations: renderOps(result.calls),\n },\n };\n }\n}\n\nfunction planValidatorDiffCall(\n collName: string,\n originValidator: MongoSchemaValidator | undefined,\n destValidator: MongoSchemaValidator | undefined,\n): OpFactoryCall | undefined {\n if (validatorsEqual(originValidator, destValidator)) return undefined;\n\n if (destValidator) {\n const operationClass: MigrationOperationClass = originValidator\n ? classifyValidatorUpdate(originValidator, destValidator)\n : 'destructive';\n return new CollModCall(\n collName,\n {\n validator: { $jsonSchema: destValidator.jsonSchema },\n validationLevel: destValidator.validationLevel,\n validationAction: destValidator.validationAction,\n },\n {\n id: `validator.${collName}.${originValidator ? 'update' : 'add'}`,\n label: `${originValidator ? 'Update' : 'Add'} validator on ${collName}`,\n operationClass,\n },\n );\n }\n\n return new CollModCall(\n collName,\n {\n validator: {},\n validationLevel: 'strict',\n validationAction: 'error',\n },\n {\n id: `validator.${collName}.remove`,\n label: `Remove validator on ${collName}`,\n operationClass: 'widening',\n },\n );\n}\n\nfunction planMutableOptionsDiffCall(\n collName: string,\n origin: MongoSchemaCollectionOptions | undefined,\n dest: MongoSchemaCollectionOptions | undefined,\n): OpFactoryCall | undefined {\n const originCSPPI = origin?.changeStreamPreAndPostImages;\n const destCSPPI = dest?.changeStreamPreAndPostImages;\n if (deepEqual(originCSPPI, destCSPPI)) return undefined;\n\n const desiredCSPPI = destCSPPI ?? { enabled: false };\n return new CollModCall(\n collName,\n {\n changeStreamPreAndPostImages: desiredCSPPI,\n },\n {\n id: `options.${collName}.update`,\n label: `Update mutable options on ${collName}`,\n operationClass: desiredCSPPI.enabled ? 'widening' : 'destructive',\n },\n );\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlanOperation,\n MigrationRunnerExecutionChecks,\n MigrationRunnerFailure,\n MigrationRunnerResult,\n} from '@prisma-next/framework-components/control';\nimport type {\n MongoDdlCommandVisitor,\n MongoInspectionCommandVisitor,\n MongoMigrationCheck,\n MongoMigrationPlanOperation,\n} from '@prisma-next/mongo-query-ast/control';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { FilterEvaluator } from './filter-evaluator';\nimport { deserializeMongoOps } from './mongo-ops-serializer';\n\nexport interface MarkerOperations {\n readMarker(): Promise<ContractMarkerRecord | null>;\n initMarker(destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n }): Promise<void>;\n updateMarker(\n expectedFrom: string,\n destination: { readonly storageHash: string; readonly profileHash: string },\n ): Promise<boolean>;\n writeLedgerEntry(entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n }): Promise<void>;\n}\n\nexport interface MongoRunnerDependencies {\n readonly commandExecutor: MongoDdlCommandVisitor<Promise<void>>;\n readonly inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>;\n readonly markerOps: MarkerOperations;\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: {\n readonly plan: MigrationPlan;\n readonly destinationContract: unknown;\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 }): Promise<MigrationRunnerResult> {\n const { commandExecutor, inspectionExecutor, markerOps } = this.deps;\n const operations = deserializeMongoOps(options.plan.operations as readonly unknown[]);\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, operations);\n if (policyCheck) return policyCheck;\n\n const existingMarker = await markerOps.readMarker();\n\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (markerCheck) return markerCheck;\n\n const checks = options.executionChecks;\n const runPrechecks = checks?.prechecks !== false;\n const runPostchecks = checks?.postchecks !== false;\n const runIdempotency = checks?.idempotencyChecks !== false;\n\n const filterEvaluator = new FilterEvaluator();\n\n let operationsExecuted = 0;\n\n for (const operation of operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n if (runPostchecks && runIdempotency) {\n const allSatisfied = await this.allChecksSatisfied(\n operation.postcheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (allSatisfied) continue;\n }\n\n if (runPrechecks) {\n const precheckResult = await this.evaluateChecks(\n operation.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 operation.execute) {\n await step.command.accept(commandExecutor);\n }\n\n if (runPostchecks) {\n const postcheckResult = await this.evaluateChecks(\n operation.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 contract = options.destinationContract as { profileHash?: string };\n const profileHash = contract.profileHash ?? destination.storageHash;\n\n if (\n operationsExecuted === 0 &&\n existingMarker?.storageHash === destination.storageHash &&\n existingMarker.profileHash === profileHash\n ) {\n return ok({ operationsPlanned: operations.length, operationsExecuted });\n }\n\n if (existingMarker) {\n const updated = await markerOps.updateMarker(existingMarker.storageHash, {\n storageHash: destination.storageHash,\n profileHash,\n });\n if (!updated) {\n return runnerFailure(\n 'MARKER_CAS_FAILURE',\n 'Marker was modified by another process during migration execution.',\n {\n meta: {\n expectedStorageHash: existingMarker.storageHash,\n destinationStorageHash: destination.storageHash,\n },\n },\n );\n }\n } else {\n await markerOps.initMarker({\n storageHash: destination.storageHash,\n profileHash,\n });\n }\n\n const originHash = existingMarker?.storageHash ?? '';\n await markerOps.writeLedgerEntry({\n edgeId: `${originHash}->${destination.storageHash}`,\n from: originHash,\n to: destination.storageHash,\n });\n\n return ok({ operationsPlanned: operations.length, operationsExecuted });\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 MongoMigrationPlanOperation[],\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 if (marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n 'Database already has a contract marker but the plan has no origin. This would silently overwrite the existing marker.',\n { meta: { markerStorageHash: marker.storageHash } },\n );\n }\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 type {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n OpFactoryCall,\n OpFactoryCallVisitor,\n} from './op-factory-call';\n\nexport interface RenderMigrationMeta {\n readonly from: string;\n readonly to: string;\n readonly kind?: string;\n readonly labels?: readonly string[];\n}\n\nexport function renderTypeScript(\n calls: ReadonlyArray<OpFactoryCall>,\n meta?: RenderMigrationMeta,\n): string {\n const factoryNames = collectFactoryNames(calls);\n const imports = buildImports(factoryNames);\n const planBody = calls.map((c) => c.accept(renderCallVisitor)).join(',\\n');\n const describeMethod = meta ? buildDescribeMethod(meta) : '';\n\n return [\n imports,\n '',\n 'class M extends Migration {',\n describeMethod,\n ' override plan() {',\n ' return [',\n indent(planBody, 6),\n ' ];',\n ' }',\n '}',\n '',\n 'export default M;',\n 'Migration.run(import.meta.url, M);',\n '',\n ].join('\\n');\n}\n\nfunction collectFactoryNames(calls: ReadonlyArray<OpFactoryCall>): string[] {\n const names = new Set<string>();\n for (const call of calls) {\n names.add(call.factory);\n }\n return [...names].sort();\n}\n\nfunction buildImports(factoryNames: string[]): string {\n const lines = [\"import { Migration } from '@prisma-next/family-mongo/migration';\"];\n if (factoryNames.length > 0) {\n lines.push(`import { ${factoryNames.join(', ')} } from '@prisma-next/target-mongo/migration';`);\n }\n return lines.join('\\n');\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.kind) {\n lines.push(` kind: ${JSON.stringify(meta.kind)},`);\n }\n if (meta.labels && meta.labels.length > 0) {\n lines.push(` labels: ${renderLiteral(meta.labels)},`);\n }\n lines.push(' };');\n lines.push(' }');\n lines.push('');\n return lines.join('\\n');\n}\n\nconst renderCallVisitor: OpFactoryCallVisitor<string> = {\n createIndex(call: CreateIndexCall) {\n return call.options\n ? `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)}, ${renderLiteral(call.options)})`\n : `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;\n },\n dropIndex(call: DropIndexCall) {\n return `dropIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;\n },\n createCollection(call: CreateCollectionCall) {\n return call.options\n ? `createCollection(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`\n : `createCollection(${renderLiteral(call.collection)})`;\n },\n dropCollection(call: DropCollectionCall) {\n return `dropCollection(${renderLiteral(call.collection)})`;\n },\n collMod(call: CollModCall) {\n return call.meta\n ? `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)}, ${renderLiteral(call.meta)})`\n : `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`;\n },\n};\n\nfunction renderLiteral(value: unknown): string {\n if (value === undefined) return 'undefined';\n if (value === null) return 'null';\n if (typeof value === 'string') return JSON.stringify(value);\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (Array.isArray(value)) {\n if (value.length === 0) return '[]';\n const items = value.map((v) => renderLiteral(v));\n const singleLine = `[${items.join(', ')}]`;\n if (singleLine.length <= 80) return singleLine;\n return `[\\n${items.map((i) => ` ${i}`).join(',\\n')},\\n]`;\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return '{}';\n const items = entries.map(([k, v]) => `${renderKey(k)}: ${renderLiteral(v)}`);\n const singleLine = `{ ${items.join(', ')} }`;\n if (singleLine.length <= 80) return singleLine;\n return `{\\n${items.map((i) => ` ${i}`).join(',\\n')},\\n}`;\n }\n return String(value);\n}\n\nfunction renderKey(key: string): string {\n if (key === '__proto__') return JSON.stringify(key);\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\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"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"control.mjs","names":["parts: string[]","statements: string[]","current: unknown","opts: MongoSchemaCollectionOptions | undefined","validator: MongoSchemaValidator | undefined","renderVisitor: OpFactoryCallVisitor<MongoMigrationPlanOperation>","lines: string[]","renderCallVisitor: OpFactoryCallVisitor<string>","calls: readonly OpFactoryCall[]","meta: MigrationMeta","collCreates: OpFactoryCall[]","drops: OpFactoryCall[]","creates: OpFactoryCall[]","validatorOps: OpFactoryCall[]","mutableOptionOps: OpFactoryCall[]","collDrops: OpFactoryCall[]","conflicts: MigrationPlannerConflict[]","operationClass: MigrationOperationClass","deps: MongoRunnerDependencies"],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/op-factory-call.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts","../src/core/planner-produced-migration.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts"],"sourcesContent":["import type {\n MongoContract,\n MongoStorageCollection,\n MongoStorageCollectionOptions,\n MongoStorageIndex,\n MongoStorageValidator,\n} from '@prisma-next/mongo-contract';\nimport {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaIR,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\n\nfunction convertIndex(index: MongoStorageIndex): MongoSchemaIndex {\n return new MongoSchemaIndex({\n keys: index.keys,\n unique: index.unique,\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\nfunction convertValidator(v: MongoStorageValidator): MongoSchemaValidator {\n return new MongoSchemaValidator({\n jsonSchema: v.jsonSchema,\n validationLevel: v.validationLevel,\n validationAction: v.validationAction,\n });\n}\n\nfunction convertOptions(o: MongoStorageCollectionOptions): MongoSchemaCollectionOptions {\n return new MongoSchemaCollectionOptions(o);\n}\n\nfunction convertCollection(name: string, def: MongoStorageCollection): MongoSchemaCollection {\n const indexes = (def.indexes ?? []).map(convertIndex);\n return new MongoSchemaCollection({\n name,\n indexes,\n ...(def.validator != null && { validator: convertValidator(def.validator) }),\n ...(def.options != null && { options: convertOptions(def.options) }),\n });\n}\n\nexport function contractToMongoSchemaIR(contract: MongoContract | null): MongoSchemaIR {\n if (!contract) {\n return new MongoSchemaIR([]);\n }\n\n const collections = Object.entries(contract.storage.collections).map(([name, def]) =>\n convertCollection(name, def),\n );\n\n return new MongoSchemaIR(collections);\n}\n","import type { MigrationPlanOperation } from '@prisma-next/framework-components/control';\nimport type {\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n MongoDdlCommandVisitor,\n MongoIndexKey,\n} from '@prisma-next/mongo-query-ast/control';\n\nfunction formatKeySpec(keys: ReadonlyArray<MongoIndexKey>): string {\n const entries = keys.map((k) => `${JSON.stringify(k.field)}: ${JSON.stringify(k.direction)}`);\n return `{ ${entries.join(', ')} }`;\n}\n\nfunction formatOptions(cmd: CreateIndexCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.unique) parts.push('unique: true');\n if (cmd.sparse) parts.push('sparse: true');\n if (cmd.expireAfterSeconds !== undefined)\n parts.push(`expireAfterSeconds: ${cmd.expireAfterSeconds}`);\n if (cmd.name) parts.push(`name: ${JSON.stringify(cmd.name)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.weights) parts.push(`weights: ${JSON.stringify(cmd.weights)}`);\n if (cmd.default_language) parts.push(`default_language: ${JSON.stringify(cmd.default_language)}`);\n if (cmd.language_override)\n parts.push(`language_override: ${JSON.stringify(cmd.language_override)}`);\n if (cmd.wildcardProjection)\n parts.push(`wildcardProjection: ${JSON.stringify(cmd.wildcardProjection)}`);\n if (cmd.partialFilterExpression)\n parts.push(`partialFilterExpression: ${JSON.stringify(cmd.partialFilterExpression)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nfunction formatCreateCollectionOptions(cmd: CreateCollectionCommand): string | undefined {\n const parts: string[] = [];\n if (cmd.capped) parts.push('capped: true');\n if (cmd.size !== undefined) parts.push(`size: ${cmd.size}`);\n if (cmd.max !== undefined) parts.push(`max: ${cmd.max}`);\n if (cmd.timeseries) parts.push(`timeseries: ${JSON.stringify(cmd.timeseries)}`);\n if (cmd.collation) parts.push(`collation: ${JSON.stringify(cmd.collation)}`);\n if (cmd.clusteredIndex) parts.push(`clusteredIndex: ${JSON.stringify(cmd.clusteredIndex)}`);\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction) parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(`changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`);\n if (parts.length === 0) return undefined;\n return `{ ${parts.join(', ')} }`;\n}\n\nclass MongoDdlCommandFormatter implements MongoDdlCommandVisitor<string> {\n createIndex(cmd: CreateIndexCommand): string {\n const keySpec = formatKeySpec(cmd.keys);\n const opts = formatOptions(cmd);\n return opts\n ? `db.${cmd.collection}.createIndex(${keySpec}, ${opts})`\n : `db.${cmd.collection}.createIndex(${keySpec})`;\n }\n\n dropIndex(cmd: DropIndexCommand): string {\n return `db.${cmd.collection}.dropIndex(${JSON.stringify(cmd.name)})`;\n }\n\n createCollection(cmd: CreateCollectionCommand): string {\n const opts = formatCreateCollectionOptions(cmd);\n return opts\n ? `db.createCollection(${JSON.stringify(cmd.collection)}, ${opts})`\n : `db.createCollection(${JSON.stringify(cmd.collection)})`;\n }\n\n dropCollection(cmd: DropCollectionCommand): string {\n return `db.${cmd.collection}.drop()`;\n }\n\n collMod(cmd: CollModCommand): string {\n const parts: string[] = [`collMod: ${JSON.stringify(cmd.collection)}`];\n if (cmd.validator) parts.push(`validator: ${JSON.stringify(cmd.validator)}`);\n if (cmd.validationLevel) parts.push(`validationLevel: ${JSON.stringify(cmd.validationLevel)}`);\n if (cmd.validationAction)\n parts.push(`validationAction: ${JSON.stringify(cmd.validationAction)}`);\n if (cmd.changeStreamPreAndPostImages)\n parts.push(\n `changeStreamPreAndPostImages: ${JSON.stringify(cmd.changeStreamPreAndPostImages)}`,\n );\n return `db.runCommand({ ${parts.join(', ')} })`;\n }\n}\n\nconst formatter = new MongoDdlCommandFormatter();\n\ninterface MongoExecuteStep {\n readonly command: { readonly accept: <R>(visitor: MongoDdlCommandVisitor<R>) => R };\n}\n\nexport function formatMongoOperations(operations: readonly MigrationPlanOperation[]): string[] {\n const statements: string[] = [];\n for (const operation of operations) {\n const candidate = operation as unknown as Record<string, unknown>;\n if (!('execute' in candidate) || !Array.isArray(candidate['execute'])) {\n continue;\n }\n for (const step of candidate['execute'] as MongoExecuteStep[]) {\n if (step.command && typeof step.command.accept === 'function') {\n statements.push(step.command.accept(formatter));\n }\n }\n }\n return statements;\n}\n","import type {\n MongoAndExpr,\n MongoExistsExpr,\n MongoExprFilter,\n MongoFieldFilter,\n MongoFilterExpr,\n MongoFilterVisitor,\n MongoNotExpr,\n MongoOrExpr,\n} from '@prisma-next/mongo-query-ast/control';\nimport { deepEqual } from '@prisma-next/mongo-schema-ir';\nimport type { MongoValue } from '@prisma-next/mongo-value';\n\nfunction getNestedField(doc: Record<string, unknown>, path: string): unknown {\n const parts = path.split('.');\n let current: unknown = doc;\n for (const part of parts) {\n if (current === null || current === undefined || typeof current !== 'object') {\n return undefined;\n }\n const record = current as Record<string, unknown>;\n if (!Object.hasOwn(record, part)) {\n return undefined;\n }\n current = record[part];\n }\n return current;\n}\n\nfunction evaluateFieldOp(op: string, actual: unknown, expected: MongoValue): boolean {\n switch (op) {\n case '$eq':\n return deepEqual(actual, expected);\n case '$ne':\n return !deepEqual(actual, expected);\n case '$gt':\n return typeof actual === typeof expected && (actual as number) > (expected as number);\n case '$gte':\n return typeof actual === typeof expected && (actual as number) >= (expected as number);\n case '$lt':\n return typeof actual === typeof expected && (actual as number) < (expected as number);\n case '$lte':\n return typeof actual === typeof expected && (actual as number) <= (expected as number);\n case '$in':\n return Array.isArray(expected) && expected.some((v) => deepEqual(actual, v));\n default:\n throw new Error(`Unsupported filter operator in migration check: ${op}`);\n }\n}\n\nexport class FilterEvaluator implements MongoFilterVisitor<boolean> {\n private doc: Record<string, unknown> = {};\n\n evaluate(filter: MongoFilterExpr, doc: Record<string, unknown>): boolean {\n this.doc = doc;\n return filter.accept(this);\n }\n\n field(expr: MongoFieldFilter): boolean {\n const value = getNestedField(this.doc, expr.field);\n return evaluateFieldOp(expr.op, value, expr.value);\n }\n\n and(expr: MongoAndExpr): boolean {\n return expr.exprs.every((child) => child.accept(this));\n }\n\n or(expr: MongoOrExpr): boolean {\n return expr.exprs.some((child) => child.accept(this));\n }\n\n not(expr: MongoNotExpr): boolean {\n return !expr.expr.accept(this);\n }\n\n exists(expr: MongoExistsExpr): boolean {\n const has = getNestedField(this.doc, expr.field) !== undefined;\n return expr.exists ? has : !has;\n }\n\n expr(_expr: MongoExprFilter): boolean {\n throw new Error('Aggregation expression filters are not supported in migration checks');\n }\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport {\n RawAggregateCommand,\n RawFindOneAndUpdateCommand,\n RawInsertOneCommand,\n} from '@prisma-next/mongo-query-ast/execution';\nimport type { Db, Document } from 'mongodb';\n\nconst COLLECTION = '_prisma_migrations';\nconst MARKER_ID = 'marker';\n\nasync function executeAggregate(db: Db, cmd: RawAggregateCommand): Promise<Document[]> {\n return db\n .collection(cmd.collection)\n .aggregate(cmd.pipeline as Record<string, unknown>[])\n .toArray();\n}\n\nasync function executeInsertOne(db: Db, cmd: RawInsertOneCommand): Promise<void> {\n await db.collection(cmd.collection).insertOne(cmd.document);\n}\n\nasync function executeFindOneAndUpdate(\n db: Db,\n cmd: RawFindOneAndUpdateCommand,\n): Promise<Document | null> {\n return db\n .collection(cmd.collection)\n .findOneAndUpdate(cmd.filter, cmd.update as Record<string, unknown>, { upsert: cmd.upsert });\n}\n\nexport async function readMarker(db: Db): Promise<ContractMarkerRecord | null> {\n const cmd = new RawAggregateCommand(COLLECTION, [{ $match: { _id: MARKER_ID } }, { $limit: 1 }]);\n const docs = await executeAggregate(db, cmd);\n const doc = docs[0];\n if (!doc) return null;\n return {\n storageHash: doc['storageHash'] as string,\n profileHash: doc['profileHash'] as string,\n contractJson: (doc['contractJson'] as unknown) ?? null,\n canonicalVersion: (doc['canonicalVersion'] as number) ?? null,\n updatedAt: doc['updatedAt'] as Date,\n appTag: (doc['appTag'] as string) ?? null,\n meta: (doc['meta'] as Record<string, unknown>) ?? {},\n };\n}\n\nexport async function initMarker(\n db: Db,\n destination: { readonly storageHash: string; readonly profileHash: string },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n _id: MARKER_ID,\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n contractJson: null,\n canonicalVersion: null,\n updatedAt: new Date(),\n appTag: null,\n meta: {},\n });\n await executeInsertOne(db, cmd);\n}\n\nexport async function updateMarker(\n db: Db,\n expectedFrom: string,\n destination: { readonly storageHash: string; readonly profileHash: string },\n): Promise<boolean> {\n const cmd = new RawFindOneAndUpdateCommand(\n COLLECTION,\n { _id: MARKER_ID, storageHash: expectedFrom },\n {\n $set: {\n storageHash: destination.storageHash,\n profileHash: destination.profileHash,\n updatedAt: new Date(),\n },\n },\n false,\n );\n const result = await executeFindOneAndUpdate(db, cmd);\n return result !== null;\n}\n\nexport async function writeLedgerEntry(\n db: Db,\n entry: { readonly edgeId: string; readonly from: string; readonly to: string },\n): Promise<void> {\n const cmd = new RawInsertOneCommand(COLLECTION, {\n type: 'ledger',\n edgeId: entry.edgeId,\n from: entry.from,\n to: entry.to,\n appliedAt: new Date(),\n });\n await executeInsertOne(db, cmd);\n}\n","import type { MigrationOperationClass } from '@prisma-next/framework-components/control';\nimport {\n type AnyMongoDdlCommand,\n type AnyMongoInspectionCommand,\n CollModCommand,\n CreateCollectionCommand,\n CreateIndexCommand,\n DropCollectionCommand,\n DropIndexCommand,\n ListCollectionsCommand,\n ListIndexesCommand,\n MongoAndExpr,\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 { 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\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 OperationJson = 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\nfunction validate<T>(schema: { assert: (data: unknown) => T }, data: unknown, context: string): T {\n try {\n return schema.assert(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\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\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\nexport function deserializeMongoOp(json: unknown): MongoMigrationPlanOperation {\n const data = validate(OperationJson, 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\nexport function deserializeMongoOps(json: readonly unknown[]): MongoMigrationPlanOperation[] {\n return json.map(deserializeMongoOp);\n}\n\nexport function serializeMongoOps(ops: readonly MongoMigrationPlanOperation[]): string {\n return JSON.stringify(ops, null, 2);\n}\n","import type { MigrationOperationClass } from '@prisma-next/framework-components/control';\nimport type {\n CollModOptions,\n CreateCollectionOptions,\n CreateIndexOptions,\n MongoIndexKey,\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';\n\nexport interface CollModMeta {\n readonly id?: string;\n readonly label?: string;\n readonly operationClass?: MigrationOperationClass;\n}\n\nexport interface OpFactoryCallVisitor<R> {\n createIndex(call: CreateIndexCall): R;\n dropIndex(call: DropIndexCall): R;\n createCollection(call: CreateCollectionCall): R;\n dropCollection(call: DropCollectionCall): R;\n collMod(call: CollModCall): R;\n}\n\nabstract class OpFactoryCallNode {\n abstract readonly factory: string;\n abstract readonly operationClass: MigrationOperationClass;\n abstract readonly label: string;\n abstract accept<R>(visitor: OpFactoryCallVisitor<R>): R;\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 factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.createIndex(this);\n }\n}\n\nexport class DropIndexCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.dropIndex(this);\n }\n}\n\nexport class CreateCollectionCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.createCollection(this);\n }\n}\n\nexport class DropCollectionCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.dropCollection(this);\n }\n}\n\nexport class CollModCall extends OpFactoryCallNode {\n readonly factory = '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 accept<R>(visitor: OpFactoryCallVisitor<R>): R {\n return visitor.collMod(this);\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 {\n collMod,\n createCollection,\n createIndex,\n dropCollection,\n dropIndex,\n} from './migration-factories';\nimport type {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n OpFactoryCall,\n OpFactoryCallVisitor,\n} from './op-factory-call';\n\nconst renderVisitor: OpFactoryCallVisitor<MongoMigrationPlanOperation> = {\n createIndex(call: CreateIndexCall) {\n return createIndex(call.collection, call.keys, call.options);\n },\n dropIndex(call: DropIndexCall) {\n return dropIndex(call.collection, call.keys);\n },\n createCollection(call: CreateCollectionCall) {\n return createCollection(call.collection, call.options);\n },\n dropCollection(call: DropCollectionCall) {\n return dropCollection(call.collection);\n },\n collMod(call: CollModCall) {\n return collMod(call.collection, call.options, call.meta);\n },\n};\n\nexport function renderOps(calls: ReadonlyArray<OpFactoryCall>): MongoMigrationPlanOperation[] {\n return calls.map((call) => call.accept(renderVisitor));\n}\n","import { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';\nimport type {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n OpFactoryCall,\n OpFactoryCallVisitor,\n} from './op-factory-call';\n\nexport interface RenderMigrationMeta {\n readonly from: string;\n readonly to: string;\n readonly kind?: string;\n readonly labels?: readonly string[];\n}\n\n/**\n * Render a list of Mongo `OpFactoryCall`s as a class-flow `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 empty strings for a\n * migration-new scaffold.\n */\nexport function renderCallsToTypeScript(\n calls: ReadonlyArray<OpFactoryCall>,\n meta: RenderMigrationMeta,\n): string {\n const factoryNames = collectFactoryNames(calls);\n const imports = buildImports(factoryNames);\n const operationsBody = calls.map((c) => c.accept(renderCallVisitor)).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 'Migration.run(import.meta.url, M);',\n '',\n ].join('\\n');\n}\n\nfunction collectFactoryNames(calls: ReadonlyArray<OpFactoryCall>): string[] {\n const names = new Set<string>();\n for (const call of calls) {\n names.add(call.factory);\n }\n return [...names].sort();\n}\n\nfunction buildImports(factoryNames: string[]): string {\n const lines = [\"import { Migration } from '@prisma-next/family-mongo/migration';\"];\n if (factoryNames.length > 0) {\n lines.push(`import { ${factoryNames.join(', ')} } from '@prisma-next/target-mongo/migration';`);\n }\n return lines.join('\\n');\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.kind) {\n lines.push(` kind: ${JSON.stringify(meta.kind)},`);\n }\n if (meta.labels && meta.labels.length > 0) {\n lines.push(` labels: ${renderLiteral(meta.labels)},`);\n }\n lines.push(' };');\n lines.push(' }');\n lines.push('');\n return lines.join('\\n');\n}\n\nconst renderCallVisitor: OpFactoryCallVisitor<string> = {\n createIndex(call: CreateIndexCall) {\n return call.options\n ? `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)}, ${renderLiteral(call.options)})`\n : `createIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;\n },\n dropIndex(call: DropIndexCall) {\n return `dropIndex(${renderLiteral(call.collection)}, ${renderLiteral(call.keys)})`;\n },\n createCollection(call: CreateCollectionCall) {\n return call.options\n ? `createCollection(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`\n : `createCollection(${renderLiteral(call.collection)})`;\n },\n dropCollection(call: DropCollectionCall) {\n return `dropCollection(${renderLiteral(call.collection)})`;\n },\n collMod(call: CollModCall) {\n return call.meta\n ? `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)}, ${renderLiteral(call.meta)})`\n : `collMod(${renderLiteral(call.collection)}, ${renderLiteral(call.options)})`;\n },\n};\n\nfunction renderLiteral(value: unknown): string {\n if (value === undefined) return 'undefined';\n if (value === null) return 'null';\n if (typeof value === 'string') return JSON.stringify(value);\n if (typeof value === 'number' || typeof value === 'boolean') return String(value);\n if (Array.isArray(value)) {\n if (value.length === 0) return '[]';\n const items = value.map((v) => renderLiteral(v));\n const singleLine = `[${items.join(', ')}]`;\n if (singleLine.length <= 80) return singleLine;\n return `[\\n${items.map((i) => ` ${i}`).join(',\\n')},\\n]`;\n }\n if (typeof value === 'object') {\n const entries = Object.entries(value).filter(([, v]) => v !== undefined);\n if (entries.length === 0) return '{}';\n const items = entries.map(([k, v]) => `${renderKey(k)}: ${renderLiteral(v)}`);\n const singleLine = `{ ${items.join(', ')} }`;\n if (singleLine.length <= 80) return singleLine;\n return `{\\n${items.map((i) => ` ${i}`).join(',\\n')},\\n}`;\n }\n return String(value);\n}\n\nfunction renderKey(key: string): string {\n if (key === '__proto__') return JSON.stringify(key);\n return /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(key) ? key : JSON.stringify(key);\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('kind', this.meta.kind),\n ...ifDefined('labels', this.meta.labels),\n });\n }\n}\n","import type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationOperationClass,\n MigrationOperationPolicy,\n MigrationPlanner,\n MigrationPlannerConflict,\n MigrationPlannerResult,\n MigrationPlanWithAuthoringSurface,\n MigrationScaffoldContext,\n} from '@prisma-next/framework-components/control';\nimport type { MongoContract } from '@prisma-next/mongo-contract';\nimport type {\n MongoSchemaCollection,\n MongoSchemaCollectionOptions,\n MongoSchemaIndex,\n MongoSchemaIR,\n MongoSchemaValidator,\n} from '@prisma-next/mongo-schema-ir';\nimport { canonicalize, deepEqual } from '@prisma-next/mongo-schema-ir';\nimport { contractToMongoSchemaIR } from './contract-to-schema';\nimport type { OpFactoryCall } from './op-factory-call';\nimport {\n CollModCall,\n CreateCollectionCall,\n CreateIndexCall,\n DropCollectionCall,\n DropIndexCall,\n schemaCollectionToCreateCollectionOptions,\n schemaIndexToCreateIndexOptions,\n} from './op-factory-call';\nimport { PlannerProducedMongoMigration } from './planner-produced-migration';\n\nfunction buildIndexLookupKey(index: MongoSchemaIndex): string {\n const keys = index.keys.map((k) => `${k.field}:${k.direction}`).join(',');\n const opts = [\n index.unique ? 'unique' : '',\n index.sparse ? 'sparse' : '',\n index.expireAfterSeconds != null ? `ttl:${index.expireAfterSeconds}` : '',\n index.partialFilterExpression ? `pfe:${canonicalize(index.partialFilterExpression)}` : '',\n index.wildcardProjection ? `wp:${canonicalize(index.wildcardProjection)}` : '',\n index.collation ? `col:${canonicalize(index.collation)}` : '',\n index.weights ? `wt:${canonicalize(index.weights)}` : '',\n index.default_language ? `dl:${index.default_language}` : '',\n index.language_override ? `lo:${index.language_override}` : '',\n ]\n .filter(Boolean)\n .join(';');\n return opts ? `${keys}|${opts}` : keys;\n}\n\nfunction validatorsEqual(\n a: MongoSchemaValidator | undefined,\n b: MongoSchemaValidator | undefined,\n): boolean {\n if (!a && !b) return true;\n if (!a || !b) return false;\n return (\n a.validationLevel === b.validationLevel &&\n a.validationAction === b.validationAction &&\n canonicalize(a.jsonSchema) === canonicalize(b.jsonSchema)\n );\n}\n\nfunction classifyValidatorUpdate(\n origin: MongoSchemaValidator,\n dest: MongoSchemaValidator,\n): 'widening' | 'destructive' {\n let hasDestructive = false;\n\n if (canonicalize(origin.jsonSchema) !== canonicalize(dest.jsonSchema)) {\n hasDestructive = true;\n }\n\n if (origin.validationAction !== dest.validationAction) {\n if (dest.validationAction === 'error') hasDestructive = true;\n }\n\n if (origin.validationLevel !== dest.validationLevel) {\n if (dest.validationLevel === 'strict') hasDestructive = true;\n }\n\n return hasDestructive ? 'destructive' : 'widening';\n}\n\nfunction hasImmutableOptionChange(\n origin: MongoSchemaCollectionOptions | undefined,\n dest: MongoSchemaCollectionOptions | undefined,\n): string | undefined {\n if (canonicalize(origin?.capped) !== canonicalize(dest?.capped)) return 'capped';\n if (canonicalize(origin?.timeseries) !== canonicalize(dest?.timeseries)) return 'timeseries';\n if (canonicalize(origin?.collation) !== canonicalize(dest?.collation)) return 'collation';\n if (canonicalize(origin?.clusteredIndex) !== canonicalize(dest?.clusteredIndex))\n return 'clusteredIndex';\n return undefined;\n}\n\nfunction collectionHasOptions(coll: MongoSchemaCollection): boolean {\n return !!(coll.options || coll.validator);\n}\n\nexport type PlanCallsResult =\n | { readonly kind: 'success'; readonly calls: OpFactoryCall[] }\n | { readonly kind: 'failure'; readonly conflicts: MigrationPlannerConflict[] };\n\nexport class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'> {\n planCalls(options: {\n readonly contract: unknown;\n readonly schema: unknown;\n readonly policy: MigrationOperationPolicy;\n readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;\n }): PlanCallsResult {\n const contract = options.contract as MongoContract;\n const originIR = options.schema as MongoSchemaIR;\n const destinationIR = contractToMongoSchemaIR(contract);\n\n const collCreates: OpFactoryCall[] = [];\n const drops: OpFactoryCall[] = [];\n const creates: OpFactoryCall[] = [];\n const validatorOps: OpFactoryCall[] = [];\n const mutableOptionOps: OpFactoryCall[] = [];\n const collDrops: OpFactoryCall[] = [];\n const conflicts: MigrationPlannerConflict[] = [];\n\n const allCollectionNames = new Set([\n ...originIR.collectionNames,\n ...destinationIR.collectionNames,\n ]);\n\n for (const collName of [...allCollectionNames].sort()) {\n const originColl = originIR.collection(collName);\n const destColl = destinationIR.collection(collName);\n\n if (!originColl) {\n if (destColl && collectionHasOptions(destColl)) {\n const opts = schemaCollectionToCreateCollectionOptions(destColl);\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 readonly fromHash: string;\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.fromHash,\n to: contract.storage.storageHash,\n }),\n };\n }\n\n /**\n * Produce an empty `migration.ts` authoring surface for `migration new`.\n *\n * Mongo is a class-flow target, so the \"empty migration\" is a\n * `PlannerProducedMongoMigration` with no operations; `renderTypeScript()`\n * emits a stub class with the correct `from`/`to` metadata that the user\n * then fills in with operations. The contract path on the context is\n * unused — Mongo's emitted source does not import from the generated\n * contract `.d.ts`.\n */\n emptyMigration(context: MigrationScaffoldContext): MigrationPlanWithAuthoringSurface {\n return new PlannerProducedMongoMigration([], {\n from: context.fromHash,\n to: context.toHash,\n });\n }\n}\n\nfunction planValidatorDiffCall(\n collName: string,\n originValidator: MongoSchemaValidator | undefined,\n destValidator: MongoSchemaValidator | undefined,\n): OpFactoryCall | undefined {\n if (validatorsEqual(originValidator, destValidator)) return undefined;\n\n if (destValidator) {\n const operationClass: MigrationOperationClass = originValidator\n ? classifyValidatorUpdate(originValidator, destValidator)\n : 'destructive';\n return new CollModCall(\n collName,\n {\n validator: { $jsonSchema: destValidator.jsonSchema },\n validationLevel: destValidator.validationLevel,\n validationAction: destValidator.validationAction,\n },\n {\n id: `validator.${collName}.${originValidator ? 'update' : 'add'}`,\n label: `${originValidator ? 'Update' : 'Add'} validator on ${collName}`,\n operationClass,\n },\n );\n }\n\n return new CollModCall(\n collName,\n {\n validator: {},\n validationLevel: 'strict',\n validationAction: 'error',\n },\n {\n id: `validator.${collName}.remove`,\n label: `Remove validator on ${collName}`,\n operationClass: 'widening',\n },\n );\n}\n\nfunction planMutableOptionsDiffCall(\n collName: string,\n origin: MongoSchemaCollectionOptions | undefined,\n dest: MongoSchemaCollectionOptions | undefined,\n): OpFactoryCall | undefined {\n const originCSPPI = origin?.changeStreamPreAndPostImages;\n const destCSPPI = dest?.changeStreamPreAndPostImages;\n if (deepEqual(originCSPPI, destCSPPI)) return undefined;\n\n const desiredCSPPI = destCSPPI ?? { enabled: false };\n return new CollModCall(\n collName,\n {\n changeStreamPreAndPostImages: desiredCSPPI,\n },\n {\n id: `options.${collName}.update`,\n label: `Update mutable options on ${collName}`,\n operationClass: desiredCSPPI.enabled ? 'widening' : 'destructive',\n },\n );\n}\n","import type { ContractMarkerRecord } from '@prisma-next/contract/types';\nimport type { TargetBoundComponentDescriptor } from '@prisma-next/framework-components/components';\nimport type {\n MigrationOperationPolicy,\n MigrationPlan,\n MigrationPlanOperation,\n MigrationRunnerExecutionChecks,\n MigrationRunnerFailure,\n MigrationRunnerResult,\n} from '@prisma-next/framework-components/control';\nimport type {\n MongoDdlCommandVisitor,\n MongoInspectionCommandVisitor,\n MongoMigrationCheck,\n MongoMigrationPlanOperation,\n} from '@prisma-next/mongo-query-ast/control';\nimport { notOk, ok } from '@prisma-next/utils/result';\nimport { FilterEvaluator } from './filter-evaluator';\nimport { deserializeMongoOps } from './mongo-ops-serializer';\n\nexport interface MarkerOperations {\n readMarker(): Promise<ContractMarkerRecord | null>;\n initMarker(destination: {\n readonly storageHash: string;\n readonly profileHash: string;\n }): Promise<void>;\n updateMarker(\n expectedFrom: string,\n destination: { readonly storageHash: string; readonly profileHash: string },\n ): Promise<boolean>;\n writeLedgerEntry(entry: {\n readonly edgeId: string;\n readonly from: string;\n readonly to: string;\n }): Promise<void>;\n}\n\nexport interface MongoRunnerDependencies {\n readonly commandExecutor: MongoDdlCommandVisitor<Promise<void>>;\n readonly inspectionExecutor: MongoInspectionCommandVisitor<Promise<Record<string, unknown>[]>>;\n readonly markerOps: MarkerOperations;\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: {\n readonly plan: MigrationPlan;\n readonly destinationContract: unknown;\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 }): Promise<MigrationRunnerResult> {\n const { commandExecutor, inspectionExecutor, markerOps } = this.deps;\n const operations = deserializeMongoOps(options.plan.operations as readonly unknown[]);\n\n const policyCheck = this.enforcePolicyCompatibility(options.policy, operations);\n if (policyCheck) return policyCheck;\n\n const existingMarker = await markerOps.readMarker();\n\n const markerCheck = this.ensureMarkerCompatibility(existingMarker, options.plan);\n if (markerCheck) return markerCheck;\n\n const checks = options.executionChecks;\n const runPrechecks = checks?.prechecks !== false;\n const runPostchecks = checks?.postchecks !== false;\n const runIdempotency = checks?.idempotencyChecks !== false;\n\n const filterEvaluator = new FilterEvaluator();\n\n let operationsExecuted = 0;\n\n for (const operation of operations) {\n options.callbacks?.onOperationStart?.(operation);\n try {\n if (runPostchecks && runIdempotency) {\n const allSatisfied = await this.allChecksSatisfied(\n operation.postcheck,\n inspectionExecutor,\n filterEvaluator,\n );\n if (allSatisfied) continue;\n }\n\n if (runPrechecks) {\n const precheckResult = await this.evaluateChecks(\n operation.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 operation.execute) {\n await step.command.accept(commandExecutor);\n }\n\n if (runPostchecks) {\n const postcheckResult = await this.evaluateChecks(\n operation.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 contract = options.destinationContract as { profileHash?: string };\n const profileHash = contract.profileHash ?? destination.storageHash;\n\n if (\n operationsExecuted === 0 &&\n existingMarker?.storageHash === destination.storageHash &&\n existingMarker.profileHash === profileHash\n ) {\n return ok({ operationsPlanned: operations.length, operationsExecuted });\n }\n\n if (existingMarker) {\n const updated = await markerOps.updateMarker(existingMarker.storageHash, {\n storageHash: destination.storageHash,\n profileHash,\n });\n if (!updated) {\n return runnerFailure(\n 'MARKER_CAS_FAILURE',\n 'Marker was modified by another process during migration execution.',\n {\n meta: {\n expectedStorageHash: existingMarker.storageHash,\n destinationStorageHash: destination.storageHash,\n },\n },\n );\n }\n } else {\n await markerOps.initMarker({\n storageHash: destination.storageHash,\n profileHash,\n });\n }\n\n const originHash = existingMarker?.storageHash ?? '';\n await markerOps.writeLedgerEntry({\n edgeId: `${originHash}->${destination.storageHash}`,\n from: originHash,\n to: destination.storageHash,\n });\n\n return ok({ operationsPlanned: operations.length, operationsExecuted });\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 MongoMigrationPlanOperation[],\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 if (marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n 'Database already has a contract marker but the plan has no origin. This would silently overwrite the existing marker.',\n { meta: { markerStorageHash: marker.storageHash } },\n );\n }\n return undefined;\n }\n\n if (!marker) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Missing contract marker: expected origin storage hash ${origin.storageHash}.`,\n { meta: { expectedOriginStorageHash: origin.storageHash } },\n );\n }\n\n if (marker.storageHash !== origin.storageHash) {\n return runnerFailure(\n 'MARKER_ORIGIN_MISMATCH',\n `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`,\n {\n meta: {\n markerStorageHash: marker.storageHash,\n expectedOriginStorageHash: origin.storageHash,\n },\n },\n );\n }\n\n return undefined;\n }\n}\n"],"mappings":"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"}
|
package/dist/migration.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { n as CollModMeta } from "./op-factory-call-CfPGebEH.mjs";
|
|
2
2
|
import { CollModOptions, CreateCollectionOptions, CreateIndexOptions, MongoIndexKey, MongoMigrationPlanOperation } from "@prisma-next/mongo-query-ast/control";
|
|
3
|
+
import { placeholder } from "@prisma-next/errors/migration";
|
|
3
4
|
|
|
4
5
|
//#region src/core/migration-factories.d.ts
|
|
5
6
|
declare function createIndex(collection: string, keys: ReadonlyArray<MongoIndexKey>, options?: CreateIndexOptions): MongoMigrationPlanOperation;
|
|
@@ -16,5 +17,5 @@ declare function validatedCollection(name: string, schema: Record<string, unknow
|
|
|
16
17
|
unique?: boolean;
|
|
17
18
|
}>): MongoMigrationPlanOperation[];
|
|
18
19
|
//#endregion
|
|
19
|
-
export { collMod, createCollection, createIndex, dropCollection, dropIndex, setValidation, validatedCollection };
|
|
20
|
+
export { collMod, createCollection, createIndex, dropCollection, dropIndex, placeholder, setValidation, validatedCollection };
|
|
20
21
|
//# sourceMappingURL=migration.d.mts.map
|
package/dist/migration.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/migration-factories.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"migration.d.mts","names":[],"sources":["../src/core/migration-factories.ts"],"sourcesContent":[],"mappings":";;;;;iBAmCgB,WAAA,2BAER,cAAc,0BACV,qBACT;iBAwCa,SAAA,2BAER,cAAc,iBACnB;AA/Ca,iBAgFA,gBAAA,CAhFW,UAAA,EAAA,MAAA,EAAA,OAAA,CAAA,EAkFf,uBAlFe,CAAA,EAmFxB,2BAnFwB;AAEL,iBAwGN,cAAA,CAxGM,UAAA,EAAA,MAAA,CAAA,EAwG8B,2BAxG9B;AAAd,iBAwHQ,aAAA,CAxHR,UAAA,EAAA,MAAA,EAAA,MAAA,EA0HE,MA1HF,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAEsB,CAFtB,EAAA;EACI,eAAA,CAAA,EAAA,QAAA,GAAA,UAAA;EACT,gBAAA,CAAA,EAAA,OAAA,GAAA,MAAA;CAA2B,CAAA,EA0H3B,2BA1H2B;AAwCd,iBAsGA,OAAA,CAtGS,UAAA,EAAA,MAAA,EAAA,OAAA,EAwGd,cAxGc,EAAA,IAAA,CAAA,EAyGhB,WAzGgB,CAAA,EA0GtB,2BA1GsB;AAEH,iBAqJN,mBAAA,CArJM,IAAA,EAAA,MAAA,EAAA,MAAA,EAuJZ,MAvJY,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,OAAA,EAwJX,aAxJW,CAAA;EAAd,IAAA,EAwJyB,aAxJzB,EAAA;EACL,MAAA,CAAA,EAAA,OAAA;CAA2B,CAAA,CAAA,EAwJ3B,2BAxJ2B,EAAA"}
|
package/dist/migration.mjs
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import { a as dropIndex, i as dropCollection, n as createCollection, o as setValidation, r as createIndex, s as validatedCollection, t as collMod } from "./migration-factories-Brzz-QGG.mjs";
|
|
2
|
+
import { placeholder } from "@prisma-next/errors/migration";
|
|
2
3
|
|
|
3
|
-
export { collMod, createCollection, createIndex, dropCollection, dropIndex, setValidation, validatedCollection };
|
|
4
|
+
export { collMod, createCollection, createIndex, dropCollection, dropIndex, placeholder, setValidation, validatedCollection };
|
package/package.json
CHANGED
|
@@ -1,19 +1,21 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/target-mongo",
|
|
3
|
-
"version": "0.4.0-dev.
|
|
3
|
+
"version": "0.4.0-dev.7",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "MongoDB target pack for Prisma Next",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"arktype": "^2.1.29",
|
|
9
9
|
"mongodb": "^6.16.0",
|
|
10
|
-
"@prisma-next/
|
|
11
|
-
"@prisma-next/
|
|
12
|
-
"@prisma-next/framework-components": "0.4.0-dev.
|
|
13
|
-
"@prisma-next/
|
|
14
|
-
"@prisma-next/
|
|
15
|
-
"@prisma-next/mongo-
|
|
16
|
-
"@prisma-next/mongo-
|
|
10
|
+
"@prisma-next/errors": "0.4.0-dev.7",
|
|
11
|
+
"@prisma-next/contract": "0.4.0-dev.7",
|
|
12
|
+
"@prisma-next/framework-components": "0.4.0-dev.7",
|
|
13
|
+
"@prisma-next/migration-tools": "0.4.0-dev.7",
|
|
14
|
+
"@prisma-next/mongo-contract": "0.4.0-dev.7",
|
|
15
|
+
"@prisma-next/mongo-value": "0.4.0-dev.7",
|
|
16
|
+
"@prisma-next/mongo-schema-ir": "0.4.0-dev.7",
|
|
17
|
+
"@prisma-next/utils": "0.4.0-dev.7",
|
|
18
|
+
"@prisma-next/mongo-query-ast": "0.4.0-dev.7"
|
|
17
19
|
},
|
|
18
20
|
"devDependencies": {
|
|
19
21
|
"mongodb-memory-server": "10.4.3",
|
|
@@ -5,6 +5,8 @@ import type {
|
|
|
5
5
|
MigrationPlanner,
|
|
6
6
|
MigrationPlannerConflict,
|
|
7
7
|
MigrationPlannerResult,
|
|
8
|
+
MigrationPlanWithAuthoringSurface,
|
|
9
|
+
MigrationScaffoldContext,
|
|
8
10
|
} from '@prisma-next/framework-components/control';
|
|
9
11
|
import type { MongoContract } from '@prisma-next/mongo-contract';
|
|
10
12
|
import type {
|
|
@@ -26,7 +28,7 @@ import {
|
|
|
26
28
|
schemaCollectionToCreateCollectionOptions,
|
|
27
29
|
schemaIndexToCreateIndexOptions,
|
|
28
30
|
} from './op-factory-call';
|
|
29
|
-
import {
|
|
31
|
+
import { PlannerProducedMongoMigration } from './planner-produced-migration';
|
|
30
32
|
|
|
31
33
|
function buildIndexLookupKey(index: MongoSchemaIndex): string {
|
|
32
34
|
const keys = index.keys.map((k) => `${k.field}:${k.direction}`).join(',');
|
|
@@ -223,6 +225,7 @@ export class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'>
|
|
|
223
225
|
readonly contract: unknown;
|
|
224
226
|
readonly schema: unknown;
|
|
225
227
|
readonly policy: MigrationOperationPolicy;
|
|
228
|
+
readonly fromHash: string;
|
|
226
229
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;
|
|
227
230
|
}): MigrationPlannerResult {
|
|
228
231
|
const contract = options.contract as MongoContract;
|
|
@@ -230,15 +233,29 @@ export class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'>
|
|
|
230
233
|
if (result.kind === 'failure') return result;
|
|
231
234
|
return {
|
|
232
235
|
kind: 'success',
|
|
233
|
-
plan: {
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
},
|
|
238
|
-
operations: renderOps(result.calls),
|
|
239
|
-
},
|
|
236
|
+
plan: new PlannerProducedMongoMigration(result.calls, {
|
|
237
|
+
from: options.fromHash,
|
|
238
|
+
to: contract.storage.storageHash,
|
|
239
|
+
}),
|
|
240
240
|
};
|
|
241
241
|
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Produce an empty `migration.ts` authoring surface for `migration new`.
|
|
245
|
+
*
|
|
246
|
+
* Mongo is a class-flow target, so the "empty migration" is a
|
|
247
|
+
* `PlannerProducedMongoMigration` with no operations; `renderTypeScript()`
|
|
248
|
+
* emits a stub class with the correct `from`/`to` metadata that the user
|
|
249
|
+
* then fills in with operations. The contract path on the context is
|
|
250
|
+
* unused — Mongo's emitted source does not import from the generated
|
|
251
|
+
* contract `.d.ts`.
|
|
252
|
+
*/
|
|
253
|
+
emptyMigration(context: MigrationScaffoldContext): MigrationPlanWithAuthoringSurface {
|
|
254
|
+
return new PlannerProducedMongoMigration([], {
|
|
255
|
+
from: context.fromHash,
|
|
256
|
+
to: context.toHash,
|
|
257
|
+
});
|
|
258
|
+
}
|
|
242
259
|
}
|
|
243
260
|
|
|
244
261
|
function planValidatorDiffCall(
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import type { MigrationPlanWithAuthoringSurface } from '@prisma-next/framework-components/control';
|
|
2
|
+
import { Migration, type MigrationMeta } from '@prisma-next/migration-tools/migration';
|
|
3
|
+
import type { AnyMongoMigrationOperation } from '@prisma-next/mongo-query-ast/control';
|
|
4
|
+
import { ifDefined } from '@prisma-next/utils/defined';
|
|
5
|
+
import type { OpFactoryCall } from './op-factory-call';
|
|
6
|
+
import { renderOps } from './render-ops';
|
|
7
|
+
import { renderCallsToTypeScript } from './render-typescript';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Planner-produced Mongo migration, returned by `MongoMigrationPlanner.plan(...)`
|
|
11
|
+
* and `MongoMigrationPlanner.emptyMigration(...)`.
|
|
12
|
+
*
|
|
13
|
+
* Unlike user-authored migrations (which extend `MongoMigration` from
|
|
14
|
+
* `@prisma-next/family-mongo/migration`), this class lives inside the target
|
|
15
|
+
* and holds the richer authoring IR (`OpFactoryCall[]`) needed to render
|
|
16
|
+
* itself back to TypeScript source. It implements
|
|
17
|
+
* `MigrationPlanWithAuthoringSurface` so that the CLI can uniformly ask any
|
|
18
|
+
* planner result to serialize itself to a `migration.ts`.
|
|
19
|
+
*
|
|
20
|
+
* Extends the framework `Migration` base class directly (not
|
|
21
|
+
* `MongoMigration`) because `MongoMigration` lives in `@prisma-next/family-mongo`,
|
|
22
|
+
* which depends on this package — extending it here would create a dependency
|
|
23
|
+
* cycle.
|
|
24
|
+
*/
|
|
25
|
+
export class PlannerProducedMongoMigration
|
|
26
|
+
extends Migration<AnyMongoMigrationOperation>
|
|
27
|
+
implements MigrationPlanWithAuthoringSurface
|
|
28
|
+
{
|
|
29
|
+
readonly targetId = 'mongo' as const;
|
|
30
|
+
|
|
31
|
+
constructor(
|
|
32
|
+
private readonly calls: readonly OpFactoryCall[],
|
|
33
|
+
private readonly meta: MigrationMeta,
|
|
34
|
+
) {
|
|
35
|
+
super();
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
override get operations(): readonly AnyMongoMigrationOperation[] {
|
|
39
|
+
return renderOps(this.calls);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
override describe(): MigrationMeta {
|
|
43
|
+
return this.meta;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
renderTypeScript(): string {
|
|
47
|
+
return renderCallsToTypeScript(this.calls, {
|
|
48
|
+
from: this.meta.from,
|
|
49
|
+
to: this.meta.to,
|
|
50
|
+
...ifDefined('kind', this.meta.kind),
|
|
51
|
+
...ifDefined('labels', this.meta.labels),
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { detectScaffoldRuntime, shebangLineFor } from '@prisma-next/migration-tools/migration-ts';
|
|
1
2
|
import type {
|
|
2
3
|
CollModCall,
|
|
3
4
|
CreateCollectionCall,
|
|
@@ -15,23 +16,32 @@ export interface RenderMigrationMeta {
|
|
|
15
16
|
readonly labels?: readonly string[];
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
|
|
19
|
+
/**
|
|
20
|
+
* Render a list of Mongo `OpFactoryCall`s as a class-flow `migration.ts`
|
|
21
|
+
* source string. The result is shebanged, extends the user-facing
|
|
22
|
+
* `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
|
|
23
|
+
* implements the abstract `operations` and `describe` members. `meta` is
|
|
24
|
+
* always rendered — `describe()` is part of the `Migration` contract, so
|
|
25
|
+
* even an empty stub must satisfy it; callers pass empty strings for a
|
|
26
|
+
* migration-new scaffold.
|
|
27
|
+
*/
|
|
28
|
+
export function renderCallsToTypeScript(
|
|
19
29
|
calls: ReadonlyArray<OpFactoryCall>,
|
|
20
|
-
meta
|
|
30
|
+
meta: RenderMigrationMeta,
|
|
21
31
|
): string {
|
|
22
32
|
const factoryNames = collectFactoryNames(calls);
|
|
23
33
|
const imports = buildImports(factoryNames);
|
|
24
|
-
const
|
|
25
|
-
const describeMethod = meta ? buildDescribeMethod(meta) : '';
|
|
34
|
+
const operationsBody = calls.map((c) => c.accept(renderCallVisitor)).join(',\n');
|
|
26
35
|
|
|
27
36
|
return [
|
|
37
|
+
shebangLineFor(detectScaffoldRuntime()),
|
|
28
38
|
imports,
|
|
29
39
|
'',
|
|
30
40
|
'class M extends Migration {',
|
|
31
|
-
|
|
32
|
-
' override
|
|
41
|
+
buildDescribeMethod(meta),
|
|
42
|
+
' override get operations() {',
|
|
33
43
|
' return [',
|
|
34
|
-
indent(
|
|
44
|
+
indent(operationsBody, 6),
|
|
35
45
|
' ];',
|
|
36
46
|
' }',
|
|
37
47
|
'}',
|
package/src/exports/control.ts
CHANGED
|
@@ -21,6 +21,7 @@ export {
|
|
|
21
21
|
schemaCollectionToCreateCollectionOptions,
|
|
22
22
|
schemaIndexToCreateIndexOptions,
|
|
23
23
|
} from '../core/op-factory-call';
|
|
24
|
+
export { PlannerProducedMongoMigration } from '../core/planner-produced-migration';
|
|
24
25
|
export { renderOps } from '../core/render-ops';
|
|
25
26
|
export type { RenderMigrationMeta } from '../core/render-typescript';
|
|
26
|
-
export {
|
|
27
|
+
export { renderCallsToTypeScript } from '../core/render-typescript';
|
package/src/exports/migration.ts
CHANGED