@prisma-next/target-mongo 0.5.0-dev.9 → 0.6.0-dev.1
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/codec-types.d.mts.map +1 -1
- package/dist/codec-types.mjs +1 -1
- package/dist/control.d.mts +24 -7
- package/dist/control.d.mts.map +1 -1
- package/dist/control.mjs +102 -83
- package/dist/control.mjs.map +1 -1
- package/dist/descriptor-meta-DdXFJeK1.mjs +12 -0
- package/dist/descriptor-meta-DdXFJeK1.mjs.map +1 -0
- package/dist/{migration-factories-Dbk5afMU.mjs → migration-factories-ZBsWqXt-.mjs} +4 -3
- package/dist/migration-factories-ZBsWqXt-.mjs.map +1 -0
- package/dist/migration.d.mts +7 -1
- package/dist/migration.d.mts.map +1 -1
- package/dist/migration.mjs +2 -3
- package/dist/{op-factory-call-CVgzmLJh.d.mts → op-factory-call-9z5D19cP.d.mts} +1 -2
- package/dist/op-factory-call-9z5D19cP.d.mts.map +1 -0
- package/dist/pack.d.mts.map +1 -1
- package/dist/pack.mjs +3 -15
- package/dist/pack.mjs.map +1 -1
- package/dist/runtime.d.mts +15 -0
- package/dist/runtime.d.mts.map +1 -0
- package/dist/runtime.mjs +21 -0
- package/dist/runtime.mjs.map +1 -0
- package/dist/schema-verify.d.mts.map +1 -1
- package/dist/schema-verify.mjs +2 -3
- package/dist/{verify-mongo-schema-P0TRBJNs.mjs → verify-mongo-schema-DlPXaotB.mjs} +2 -6
- package/dist/verify-mongo-schema-DlPXaotB.mjs.map +1 -0
- package/package.json +20 -17
- package/src/core/marker-ledger.ts +90 -20
- package/src/core/migration-factories.ts +8 -0
- package/src/core/mongo-ops-serializer.ts +0 -8
- package/src/core/mongo-planner.ts +8 -2
- package/src/core/mongo-runner.ts +80 -57
- package/src/core/planner-produced-migration.ts +0 -1
- package/src/core/render-typescript.ts +3 -7
- package/src/exports/runtime.ts +32 -0
- package/dist/migration-factories-Dbk5afMU.mjs.map +0 -1
- package/dist/op-factory-call-CVgzmLJh.d.mts.map +0 -1
- package/dist/verify-mongo-schema-P0TRBJNs.mjs.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"codec-types.d.mts","names":[],"sources":["../src/exports/codec-types.ts"],"
|
|
1
|
+
{"version":3,"file":"codec-types.d.mts","names":[],"sources":["../src/exports/codec-types.ts"],"mappings":";KAAY,UAAA;EAAA,SACD,kBAAA;IAAA,SAA+B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACvD,gBAAA;IAAA,SAA6B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACrD,gBAAA;IAAA,SAA6B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACrD,eAAA;IAAA,SAA4B,KAAA;IAAA,SAAwB,MAAA;EAAA;EAAA,SACpD,cAAA;IAAA,SAA2B,KAAA;IAAA,SAAyB,MAAA;EAAA;EAAA,SACpD,cAAA;IAAA,SAA2B,KAAA,EAAO,IAAA;IAAA,SAAe,MAAA,EAAQ,IAAA;EAAA;EAAA,SACzD,gBAAA;IAAA,SACE,KAAA;IAAA,SACA,MAAA;EAAA;AAAA"}
|
package/dist/codec-types.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export {};
|
package/dist/control.d.mts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { a as DropCollectionCall, c as schemaCollectionToCreateCollectionOptions, i as CreateIndexCall, l as schemaIndexToCreateIndexOptions, n as CollModMeta, o as DropIndexCall, r as CreateCollectionCall, s as OpFactoryCall, t as CollModCall } from "./op-factory-call-
|
|
1
|
+
import { a as DropCollectionCall, c as schemaCollectionToCreateCollectionOptions, i as CreateIndexCall, l as schemaIndexToCreateIndexOptions, n as CollModMeta, o as DropIndexCall, r as CreateCollectionCall, s as OpFactoryCall, t as CollModCall } from "./op-factory-call-9z5D19cP.mjs";
|
|
2
2
|
import { MongoSchemaIR } from "@prisma-next/mongo-schema-ir";
|
|
3
3
|
import { MongoQueryPlan } from "@prisma-next/mongo-query-ast/execution";
|
|
4
4
|
import { AnyMongoMigrationOperation, MongoAndExpr, MongoDdlCommandVisitor, MongoExistsExpr, MongoExprFilter, MongoFieldFilter, MongoFilterExpr, MongoFilterVisitor, MongoInspectionCommandVisitor, MongoMigrationPlanOperation, MongoNotExpr, MongoOrExpr } from "@prisma-next/mongo-query-ast/control";
|
|
5
5
|
import { Migration, MigrationMeta } from "@prisma-next/migration-tools/migration";
|
|
6
6
|
import { MigrationOperationPolicy, MigrationPlan, MigrationPlanOperation, MigrationPlanWithAuthoringSurface, MigrationPlanner, MigrationPlannerConflict, MigrationPlannerResult, MigrationRunnerExecutionChecks, MigrationRunnerResult, MigrationScaffoldContext, OperationContext } from "@prisma-next/framework-components/control";
|
|
7
7
|
import { MongoContract } from "@prisma-next/mongo-contract";
|
|
8
|
-
import { ContractMarkerRecord } from "@prisma-next/contract/types";
|
|
8
|
+
import { Contract, ContractMarkerRecord } from "@prisma-next/contract/types";
|
|
9
9
|
import { Db } from "mongodb";
|
|
10
10
|
import { TargetBoundComponentDescriptor } from "@prisma-next/framework-components/components";
|
|
11
11
|
import { MongoAdapter, MongoDriver } from "@prisma-next/mongo-lowering";
|
|
@@ -33,10 +33,21 @@ declare function readMarker(db: Db): Promise<ContractMarkerRecord | null>;
|
|
|
33
33
|
declare function initMarker(db: Db, destination: {
|
|
34
34
|
readonly storageHash: string;
|
|
35
35
|
readonly profileHash: string;
|
|
36
|
+
readonly invariants?: readonly string[];
|
|
36
37
|
}): Promise<void>;
|
|
38
|
+
/**
|
|
39
|
+
* Updates the marker doc atomically (CAS on `expectedFrom`).
|
|
40
|
+
*
|
|
41
|
+
* `destination.invariants`:
|
|
42
|
+
* - `undefined` → existing field left untouched.
|
|
43
|
+
* - explicit value → merged into the existing field server-side via an
|
|
44
|
+
* aggregation pipeline (`$setUnion + $sortArray`), atomic at the
|
|
45
|
+
* document level. `[]` is a no-op merge.
|
|
46
|
+
*/
|
|
37
47
|
declare function updateMarker(db: Db, expectedFrom: string, destination: {
|
|
38
48
|
readonly storageHash: string;
|
|
39
49
|
readonly profileHash: string;
|
|
50
|
+
readonly invariants?: readonly string[];
|
|
40
51
|
}): Promise<boolean>;
|
|
41
52
|
declare function writeLedgerEntry(db: Db, entry: {
|
|
42
53
|
readonly edgeId: string;
|
|
@@ -68,7 +79,12 @@ declare class MongoMigrationPlanner implements MigrationPlanner<'mongo', 'mongo'
|
|
|
68
79
|
readonly contract: unknown;
|
|
69
80
|
readonly schema: unknown;
|
|
70
81
|
readonly policy: MigrationOperationPolicy;
|
|
71
|
-
|
|
82
|
+
/**
|
|
83
|
+
* The "from" contract (state the planner assumes the database starts at),
|
|
84
|
+
* or `null` for reconciliation flows. Used to populate `describe().from`
|
|
85
|
+
* on the produced plan as `fromContract?.storage.storageHash ?? null`.
|
|
86
|
+
*/
|
|
87
|
+
readonly fromContract: Contract | null;
|
|
72
88
|
readonly frameworkComponents: ReadonlyArray<TargetBoundComponentDescriptor<'mongo', 'mongo'>>;
|
|
73
89
|
}): MigrationPlannerResult;
|
|
74
90
|
/**
|
|
@@ -89,10 +105,12 @@ interface MarkerOperations {
|
|
|
89
105
|
initMarker(destination: {
|
|
90
106
|
readonly storageHash: string;
|
|
91
107
|
readonly profileHash: string;
|
|
108
|
+
readonly invariants?: readonly string[];
|
|
92
109
|
}): Promise<void>;
|
|
93
110
|
updateMarker(expectedFrom: string, destination: {
|
|
94
111
|
readonly storageHash: string;
|
|
95
112
|
readonly profileHash: string;
|
|
113
|
+
readonly invariants?: readonly string[];
|
|
96
114
|
}): Promise<boolean>;
|
|
97
115
|
writeLedgerEntry(entry: {
|
|
98
116
|
readonly edgeId: string;
|
|
@@ -165,9 +183,8 @@ declare function renderOps(calls: ReadonlyArray<OpFactoryCall>): MongoMigrationP
|
|
|
165
183
|
//#endregion
|
|
166
184
|
//#region src/core/render-typescript.d.ts
|
|
167
185
|
interface RenderMigrationMeta {
|
|
168
|
-
readonly from: string;
|
|
186
|
+
readonly from: string | null;
|
|
169
187
|
readonly to: string;
|
|
170
|
-
readonly kind?: string;
|
|
171
188
|
readonly labels?: readonly string[];
|
|
172
189
|
}
|
|
173
190
|
/**
|
|
@@ -176,8 +193,8 @@ interface RenderMigrationMeta {
|
|
|
176
193
|
* `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
|
|
177
194
|
* implements the abstract `operations` and `describe` members. `meta` is
|
|
178
195
|
* always rendered — `describe()` is part of the `Migration` contract, so
|
|
179
|
-
* even an empty stub must satisfy it; callers pass
|
|
180
|
-
* migration-new scaffold.
|
|
196
|
+
* even an empty stub must satisfy it; callers pass `from: null` for a
|
|
197
|
+
* baseline `migration-new` scaffold (and a real `to` hash either way).
|
|
181
198
|
*
|
|
182
199
|
* The walk is polymorphic: each call node contributes its own
|
|
183
200
|
* `renderTypeScript()` expression and declares its own
|
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/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"
|
|
1
|
+
{"version":3,"file":"control.d.mts","names":[],"sources":["../src/core/contract-to-schema.ts","../src/core/ddl-formatter.ts","../src/core/filter-evaluator.ts","../src/core/marker-ledger.ts","../src/core/mongo-ops-serializer.ts","../src/core/mongo-planner.ts","../src/core/mongo-runner.ts","../src/core/planner-produced-migration.ts","../src/core/render-ops.ts","../src/core/render-typescript.ts"],"mappings":"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"}
|
package/dist/control.mjs
CHANGED
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import { n as contractToMongoSchemaIR, t as verifyMongoSchema } from "./verify-mongo-schema-
|
|
2
|
-
import { a as dropCollection, n as createCollection, o as dropIndex, r as createIndex, t as collMod } from "./migration-factories-
|
|
1
|
+
import { n as contractToMongoSchemaIR, t as verifyMongoSchema } from "./verify-mongo-schema-DlPXaotB.mjs";
|
|
2
|
+
import { a as dropCollection, n as createCollection, o as dropIndex, r as createIndex, t as collMod } from "./migration-factories-ZBsWqXt-.mjs";
|
|
3
3
|
import { canonicalize, deepEqual } from "@prisma-next/mongo-schema-ir";
|
|
4
4
|
import { AggregateCommand, MongoAddFieldsStage, MongoLimitStage, MongoLookupStage, MongoMatchStage, MongoMergeStage, MongoProjectStage, MongoSortStage, RawAggregateCommand, RawDeleteManyCommand, RawDeleteOneCommand, RawFindOneAndDeleteCommand, RawFindOneAndUpdateCommand, RawInsertManyCommand, RawInsertOneCommand, RawUpdateManyCommand, RawUpdateOneCommand } from "@prisma-next/mongo-query-ast/execution";
|
|
5
|
+
import { type } from "arktype";
|
|
5
6
|
import { CollModCommand, CreateCollectionCommand, CreateIndexCommand, DropCollectionCommand, DropIndexCommand, ListCollectionsCommand, ListIndexesCommand, MongoAndExpr, MongoExistsExpr, MongoFieldFilter, MongoNotExpr, MongoOrExpr } from "@prisma-next/mongo-query-ast/control";
|
|
6
7
|
import { ifDefined } from "@prisma-next/utils/defined";
|
|
7
|
-
import { type } from "arktype";
|
|
8
8
|
import { TsExpression, jsonToTsSource, renderImports } from "@prisma-next/ts-render";
|
|
9
9
|
import { Migration } from "@prisma-next/migration-tools/migration";
|
|
10
10
|
import { detectScaffoldRuntime, shebangLineFor } from "@prisma-next/migration-tools/migration-ts";
|
|
11
11
|
import { errorRunnerFailed } from "@prisma-next/errors/execution";
|
|
12
12
|
import { notOk, ok } from "@prisma-next/utils/result";
|
|
13
|
-
|
|
14
13
|
//#region src/core/ddl-formatter.ts
|
|
15
14
|
function formatKeySpec(keys) {
|
|
16
15
|
return `{ ${keys.map((k) => `${JSON.stringify(k.field)}: ${JSON.stringify(k.direction)}`).join(", ")} }`;
|
|
@@ -80,7 +79,6 @@ function formatMongoOperations(operations) {
|
|
|
80
79
|
}
|
|
81
80
|
return statements;
|
|
82
81
|
}
|
|
83
|
-
|
|
84
82
|
//#endregion
|
|
85
83
|
//#region src/core/filter-evaluator.ts
|
|
86
84
|
function getNestedField(doc, path) {
|
|
@@ -133,11 +131,35 @@ var FilterEvaluator = class {
|
|
|
133
131
|
throw new Error("Aggregation expression filters are not supported in migration checks");
|
|
134
132
|
}
|
|
135
133
|
};
|
|
136
|
-
|
|
137
134
|
//#endregion
|
|
138
135
|
//#region src/core/marker-ledger.ts
|
|
139
136
|
const COLLECTION = "_prisma_migrations";
|
|
140
137
|
const MARKER_ID = "marker";
|
|
138
|
+
const MongoMarkerDocSchema = type({
|
|
139
|
+
storageHash: "string",
|
|
140
|
+
profileHash: "string",
|
|
141
|
+
"contractJson?": "unknown | null",
|
|
142
|
+
"canonicalVersion?": "number | null",
|
|
143
|
+
"updatedAt?": "Date",
|
|
144
|
+
"appTag?": "string | null",
|
|
145
|
+
"meta?": type({ "[string]": "unknown" }).or("null"),
|
|
146
|
+
"invariants?": type("string").array(),
|
|
147
|
+
"+": "delete"
|
|
148
|
+
});
|
|
149
|
+
function parseMongoMarkerDoc(doc) {
|
|
150
|
+
const result = MongoMarkerDocSchema(doc);
|
|
151
|
+
if (result instanceof type.errors) throw new Error(`Invalid marker doc on ${COLLECTION}: ${result.summary}`);
|
|
152
|
+
return {
|
|
153
|
+
storageHash: result.storageHash,
|
|
154
|
+
profileHash: result.profileHash,
|
|
155
|
+
contractJson: result.contractJson ?? null,
|
|
156
|
+
canonicalVersion: result.canonicalVersion ?? null,
|
|
157
|
+
updatedAt: result.updatedAt ?? /* @__PURE__ */ new Date(),
|
|
158
|
+
appTag: result.appTag ?? null,
|
|
159
|
+
meta: result.meta ?? {},
|
|
160
|
+
invariants: result.invariants ?? []
|
|
161
|
+
};
|
|
162
|
+
}
|
|
141
163
|
async function executeAggregate(db, cmd) {
|
|
142
164
|
return db.collection(cmd.collection).aggregate(cmd.pipeline).toArray();
|
|
143
165
|
}
|
|
@@ -150,15 +172,7 @@ async function executeFindOneAndUpdate(db, cmd) {
|
|
|
150
172
|
async function readMarker(db) {
|
|
151
173
|
const doc = (await executeAggregate(db, new RawAggregateCommand(COLLECTION, [{ $match: { _id: MARKER_ID } }, { $limit: 1 }])))[0];
|
|
152
174
|
if (!doc) return null;
|
|
153
|
-
return
|
|
154
|
-
storageHash: doc["storageHash"],
|
|
155
|
-
profileHash: doc["profileHash"],
|
|
156
|
-
contractJson: doc["contractJson"] ?? null,
|
|
157
|
-
canonicalVersion: doc["canonicalVersion"] ?? null,
|
|
158
|
-
updatedAt: doc["updatedAt"],
|
|
159
|
-
appTag: doc["appTag"] ?? null,
|
|
160
|
-
meta: doc["meta"] ?? {}
|
|
161
|
-
};
|
|
175
|
+
return parseMongoMarkerDoc(doc);
|
|
162
176
|
}
|
|
163
177
|
async function initMarker(db, destination) {
|
|
164
178
|
await executeInsertOne(db, new RawInsertOneCommand(COLLECTION, {
|
|
@@ -169,18 +183,36 @@ async function initMarker(db, destination) {
|
|
|
169
183
|
canonicalVersion: null,
|
|
170
184
|
updatedAt: /* @__PURE__ */ new Date(),
|
|
171
185
|
appTag: null,
|
|
172
|
-
meta: {}
|
|
186
|
+
meta: {},
|
|
187
|
+
invariants: destination.invariants ?? []
|
|
173
188
|
}));
|
|
174
189
|
}
|
|
190
|
+
/**
|
|
191
|
+
* Updates the marker doc atomically (CAS on `expectedFrom`).
|
|
192
|
+
*
|
|
193
|
+
* `destination.invariants`:
|
|
194
|
+
* - `undefined` → existing field left untouched.
|
|
195
|
+
* - explicit value → merged into the existing field server-side via an
|
|
196
|
+
* aggregation pipeline (`$setUnion + $sortArray`), atomic at the
|
|
197
|
+
* document level. `[]` is a no-op merge.
|
|
198
|
+
*/
|
|
175
199
|
async function updateMarker(db, expectedFrom, destination) {
|
|
176
|
-
|
|
177
|
-
_id: MARKER_ID,
|
|
178
|
-
storageHash: expectedFrom
|
|
179
|
-
}, { $set: {
|
|
200
|
+
const setBase = {
|
|
180
201
|
storageHash: destination.storageHash,
|
|
181
202
|
profileHash: destination.profileHash,
|
|
182
203
|
updatedAt: /* @__PURE__ */ new Date()
|
|
183
|
-
}
|
|
204
|
+
};
|
|
205
|
+
const update = destination.invariants === void 0 ? { $set: setBase } : [{ $set: {
|
|
206
|
+
...setBase,
|
|
207
|
+
invariants: { $sortArray: {
|
|
208
|
+
input: { $setUnion: [{ $ifNull: ["$invariants", []] }, destination.invariants] },
|
|
209
|
+
sortBy: 1
|
|
210
|
+
} }
|
|
211
|
+
} }];
|
|
212
|
+
return await executeFindOneAndUpdate(db, new RawFindOneAndUpdateCommand(COLLECTION, {
|
|
213
|
+
_id: MARKER_ID,
|
|
214
|
+
storageHash: expectedFrom
|
|
215
|
+
}, update, false)) !== null;
|
|
184
216
|
}
|
|
185
217
|
async function writeLedgerEntry(db, entry) {
|
|
186
218
|
await executeInsertOne(db, new RawInsertOneCommand(COLLECTION, {
|
|
@@ -191,7 +223,6 @@ async function writeLedgerEntry(db, entry) {
|
|
|
191
223
|
appliedAt: /* @__PURE__ */ new Date()
|
|
192
224
|
}));
|
|
193
225
|
}
|
|
194
|
-
|
|
195
226
|
//#endregion
|
|
196
227
|
//#region src/core/mongo-ops-serializer.ts
|
|
197
228
|
const CreateIndexJson = type({
|
|
@@ -320,13 +351,9 @@ const QueryPlanJson = type({
|
|
|
320
351
|
target: "string",
|
|
321
352
|
storageHash: "string",
|
|
322
353
|
lane: "string",
|
|
323
|
-
paramDescriptors: "unknown[]",
|
|
324
354
|
"targetFamily?": "string",
|
|
325
355
|
"profileHash?": "string",
|
|
326
|
-
"annotations?": "Record<string, unknown>"
|
|
327
|
-
"refs?": "Record<string, unknown>",
|
|
328
|
-
"projection?": "Record<string, string> | string[]",
|
|
329
|
-
"projectionTypes?": "Record<string, string>"
|
|
356
|
+
"annotations?": "Record<string, unknown>"
|
|
330
357
|
})
|
|
331
358
|
});
|
|
332
359
|
const CheckJson = type({
|
|
@@ -490,13 +517,9 @@ function deserializeMongoQueryPlan(json) {
|
|
|
490
517
|
target: m.target,
|
|
491
518
|
storageHash: m.storageHash,
|
|
492
519
|
lane: m.lane,
|
|
493
|
-
paramDescriptors: m.paramDescriptors,
|
|
494
520
|
...ifDefined("targetFamily", m.targetFamily),
|
|
495
521
|
...ifDefined("profileHash", m.profileHash),
|
|
496
|
-
...ifDefined("annotations", m.annotations)
|
|
497
|
-
...ifDefined("refs", m.refs),
|
|
498
|
-
...ifDefined("projection", m.projection),
|
|
499
|
-
...ifDefined("projectionTypes", m.projectionTypes)
|
|
522
|
+
...ifDefined("annotations", m.annotations)
|
|
500
523
|
};
|
|
501
524
|
return {
|
|
502
525
|
collection: data.collection,
|
|
@@ -625,7 +648,6 @@ function deserializeMongoOps(json) {
|
|
|
625
648
|
function serializeMongoOps(ops) {
|
|
626
649
|
return JSON.stringify(ops, null, 2);
|
|
627
650
|
}
|
|
628
|
-
|
|
629
651
|
//#endregion
|
|
630
652
|
//#region src/core/op-factory-call.ts
|
|
631
653
|
const TARGET_MIGRATION_MODULE = "@prisma-next/target-mongo/migration";
|
|
@@ -780,13 +802,11 @@ function schemaCollectionToCreateCollectionOptions(coll) {
|
|
|
780
802
|
changeStreamPreAndPostImages: opts?.changeStreamPreAndPostImages
|
|
781
803
|
};
|
|
782
804
|
}
|
|
783
|
-
|
|
784
805
|
//#endregion
|
|
785
806
|
//#region src/core/render-ops.ts
|
|
786
807
|
function renderOps(calls) {
|
|
787
808
|
return calls.map((call) => call.toOp());
|
|
788
809
|
}
|
|
789
|
-
|
|
790
810
|
//#endregion
|
|
791
811
|
//#region src/core/render-typescript.ts
|
|
792
812
|
/**
|
|
@@ -818,8 +838,8 @@ const BASE_IMPORTS = [{
|
|
|
818
838
|
* `Migration` (i.e. `MongoMigration`) from `@prisma-next/family-mongo`, and
|
|
819
839
|
* implements the abstract `operations` and `describe` members. `meta` is
|
|
820
840
|
* always rendered — `describe()` is part of the `Migration` contract, so
|
|
821
|
-
* even an empty stub must satisfy it; callers pass
|
|
822
|
-
* migration-new scaffold.
|
|
841
|
+
* even an empty stub must satisfy it; callers pass `from: null` for a
|
|
842
|
+
* baseline `migration-new` scaffold (and a real `to` hash either way).
|
|
823
843
|
*
|
|
824
844
|
* The walk is polymorphic: each call node contributes its own
|
|
825
845
|
* `renderTypeScript()` expression and declares its own
|
|
@@ -861,7 +881,6 @@ function buildDescribeMethod(meta) {
|
|
|
861
881
|
lines.push(" return {");
|
|
862
882
|
lines.push(` from: ${JSON.stringify(meta.from)},`);
|
|
863
883
|
lines.push(` to: ${JSON.stringify(meta.to)},`);
|
|
864
|
-
if (meta.kind) lines.push(` kind: ${JSON.stringify(meta.kind)},`);
|
|
865
884
|
if (meta.labels && meta.labels.length > 0) lines.push(` labels: ${jsonToTsSource(meta.labels)},`);
|
|
866
885
|
lines.push(" };");
|
|
867
886
|
lines.push(" }");
|
|
@@ -872,7 +891,6 @@ function indent(text, spaces) {
|
|
|
872
891
|
const pad = " ".repeat(spaces);
|
|
873
892
|
return text.split("\n").map((line) => line.trim() ? `${pad}${line}` : line).join("\n");
|
|
874
893
|
}
|
|
875
|
-
|
|
876
894
|
//#endregion
|
|
877
895
|
//#region src/core/planner-produced-migration.ts
|
|
878
896
|
/**
|
|
@@ -892,6 +910,8 @@ function indent(text, spaces) {
|
|
|
892
910
|
* cycle.
|
|
893
911
|
*/
|
|
894
912
|
var PlannerProducedMongoMigration = class extends Migration {
|
|
913
|
+
calls;
|
|
914
|
+
meta;
|
|
895
915
|
targetId = "mongo";
|
|
896
916
|
constructor(calls, meta) {
|
|
897
917
|
super();
|
|
@@ -908,12 +928,10 @@ var PlannerProducedMongoMigration = class extends Migration {
|
|
|
908
928
|
return renderCallsToTypeScript(this.calls, {
|
|
909
929
|
from: this.meta.from,
|
|
910
930
|
to: this.meta.to,
|
|
911
|
-
...ifDefined("kind", this.meta.kind),
|
|
912
931
|
...ifDefined("labels", this.meta.labels)
|
|
913
932
|
});
|
|
914
933
|
}
|
|
915
934
|
};
|
|
916
|
-
|
|
917
935
|
//#endregion
|
|
918
936
|
//#region src/core/mongo-planner.ts
|
|
919
937
|
function buildIndexLookupKey(index) {
|
|
@@ -1030,7 +1048,7 @@ var MongoMigrationPlanner = class {
|
|
|
1030
1048
|
return {
|
|
1031
1049
|
kind: "success",
|
|
1032
1050
|
plan: new PlannerProducedMongoMigration(result.calls, {
|
|
1033
|
-
from: options.
|
|
1051
|
+
from: options.fromContract?.storage.storageHash ?? null,
|
|
1034
1052
|
to: contract.storage.storageHash
|
|
1035
1053
|
})
|
|
1036
1054
|
};
|
|
@@ -1086,7 +1104,6 @@ function planMutableOptionsDiffCall(collName, origin, dest) {
|
|
|
1086
1104
|
operationClass: desiredCSPPI.enabled ? "widening" : "destructive"
|
|
1087
1105
|
});
|
|
1088
1106
|
}
|
|
1089
|
-
|
|
1090
1107
|
//#endregion
|
|
1091
1108
|
//#region src/core/mongo-runner.ts
|
|
1092
1109
|
const READ_ONLY_CHECK_COMMAND_KINDS = new Set(["aggregate", "rawAggregate"]);
|
|
@@ -1098,6 +1115,7 @@ function runnerFailure(code, summary, opts) {
|
|
|
1098
1115
|
});
|
|
1099
1116
|
}
|
|
1100
1117
|
var MongoMigrationRunner = class {
|
|
1118
|
+
deps;
|
|
1101
1119
|
constructor(deps) {
|
|
1102
1120
|
this.deps = deps;
|
|
1103
1121
|
}
|
|
@@ -1142,40 +1160,44 @@ var MongoMigrationRunner = class {
|
|
|
1142
1160
|
}
|
|
1143
1161
|
const destination = options.plan.destination;
|
|
1144
1162
|
const profileHash = options.destinationContract.profileHash ?? destination.storageHash;
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
if (
|
|
1163
|
+
const incomingInvariants = options.plan.providedInvariants ?? [];
|
|
1164
|
+
const existingInvariantSet = new Set(existingMarker?.invariants ?? []);
|
|
1165
|
+
const incomingIsSubsetOfExisting = incomingInvariants.every((id) => existingInvariantSet.has(id));
|
|
1166
|
+
const markerAlreadyAtDestination = existingMarker !== null && existingMarker.storageHash === destination.storageHash && existingMarker.profileHash === profileHash;
|
|
1167
|
+
if (!(operationsExecuted === 0 && markerAlreadyAtDestination && incomingIsSubsetOfExisting)) {
|
|
1168
|
+
const liveSchema = await this.deps.introspectSchema();
|
|
1169
|
+
const verifyResult = verifyMongoSchema({
|
|
1170
|
+
contract: options.destinationContract,
|
|
1171
|
+
schema: liveSchema,
|
|
1172
|
+
strict: options.strictVerification ?? true,
|
|
1173
|
+
frameworkComponents: options.frameworkComponents,
|
|
1174
|
+
...options.context ? { context: options.context } : {}
|
|
1175
|
+
});
|
|
1176
|
+
if (!verifyResult.ok) return runnerFailure("SCHEMA_VERIFY_FAILED", verifyResult.summary, {
|
|
1177
|
+
why: "The resulting database schema does not satisfy the destination contract.",
|
|
1178
|
+
meta: { issues: verifyResult.schema.issues }
|
|
1179
|
+
});
|
|
1180
|
+
if (existingMarker) {
|
|
1181
|
+
if (!await markerOps.updateMarker(existingMarker.storageHash, {
|
|
1182
|
+
storageHash: destination.storageHash,
|
|
1183
|
+
profileHash,
|
|
1184
|
+
invariants: incomingInvariants
|
|
1185
|
+
})) return runnerFailure("MARKER_CAS_FAILURE", "Marker was modified by another process during migration execution.", { meta: {
|
|
1186
|
+
expectedStorageHash: existingMarker.storageHash,
|
|
1187
|
+
destinationStorageHash: destination.storageHash
|
|
1188
|
+
} });
|
|
1189
|
+
} else await markerOps.initMarker({
|
|
1163
1190
|
storageHash: destination.storageHash,
|
|
1164
|
-
profileHash
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
await markerOps.writeLedgerEntry({
|
|
1175
|
-
edgeId: `${originHash}->${destination.storageHash}`,
|
|
1176
|
-
from: originHash,
|
|
1177
|
-
to: destination.storageHash
|
|
1178
|
-
});
|
|
1191
|
+
profileHash,
|
|
1192
|
+
invariants: incomingInvariants
|
|
1193
|
+
});
|
|
1194
|
+
const originHash = existingMarker?.storageHash ?? "";
|
|
1195
|
+
await markerOps.writeLedgerEntry({
|
|
1196
|
+
edgeId: `${originHash}->${destination.storageHash}`,
|
|
1197
|
+
from: originHash,
|
|
1198
|
+
to: destination.storageHash
|
|
1199
|
+
});
|
|
1200
|
+
}
|
|
1179
1201
|
return ok({
|
|
1180
1202
|
operationsPlanned: operations.length,
|
|
1181
1203
|
operationsExecuted
|
|
@@ -1195,7 +1217,7 @@ var MongoMigrationRunner = class {
|
|
|
1195
1217
|
};
|
|
1196
1218
|
}
|
|
1197
1219
|
for (const plan of op.run) {
|
|
1198
|
-
const wireCommand = await adapter.lower(plan);
|
|
1220
|
+
const wireCommand = await adapter.lower(plan, {});
|
|
1199
1221
|
for await (const _ of driver.execute(wireCommand));
|
|
1200
1222
|
}
|
|
1201
1223
|
if (runPostchecks && op.postcheck.length > 0) {
|
|
@@ -1221,7 +1243,7 @@ var MongoMigrationRunner = class {
|
|
|
1221
1243
|
collection: check.source.collection
|
|
1222
1244
|
}
|
|
1223
1245
|
});
|
|
1224
|
-
const wireCommand = await adapter.lower(check.source);
|
|
1246
|
+
const wireCommand = await adapter.lower(check.source, {});
|
|
1225
1247
|
let matchFound = false;
|
|
1226
1248
|
for await (const row of driver.execute(wireCommand)) if (filterEvaluator.evaluate(check.filter, row)) {
|
|
1227
1249
|
matchFound = true;
|
|
@@ -1254,10 +1276,7 @@ var MongoMigrationRunner = class {
|
|
|
1254
1276
|
}
|
|
1255
1277
|
ensureMarkerCompatibility(marker, plan) {
|
|
1256
1278
|
const origin = plan.origin ?? null;
|
|
1257
|
-
if (!origin)
|
|
1258
|
-
if (marker) return runnerFailure("MARKER_ORIGIN_MISMATCH", "Database already has a contract marker but the plan has no origin. This would silently overwrite the existing marker.", { meta: { markerStorageHash: marker.storageHash } });
|
|
1259
|
-
return;
|
|
1260
|
-
}
|
|
1279
|
+
if (!origin) return;
|
|
1261
1280
|
if (!marker) return runnerFailure("MARKER_ORIGIN_MISMATCH", `Missing contract marker: expected origin storage hash ${origin.storageHash}.`, { meta: { expectedOriginStorageHash: origin.storageHash } });
|
|
1262
1281
|
if (marker.storageHash !== origin.storageHash) return runnerFailure("MARKER_ORIGIN_MISMATCH", `Existing contract marker (${marker.storageHash}) does not match plan origin (${origin.storageHash}).`, { meta: {
|
|
1263
1282
|
markerStorageHash: marker.storageHash,
|
|
@@ -1265,7 +1284,7 @@ var MongoMigrationRunner = class {
|
|
|
1265
1284
|
} });
|
|
1266
1285
|
}
|
|
1267
1286
|
};
|
|
1268
|
-
|
|
1269
1287
|
//#endregion
|
|
1270
1288
|
export { CollModCall, CreateCollectionCall, CreateIndexCall, DropCollectionCall, DropIndexCall, FilterEvaluator, MongoMigrationPlanner, MongoMigrationRunner, PlannerProducedMongoMigration, contractToMongoSchemaIR, deserializeMongoOp, deserializeMongoOps, formatMongoOperations, initMarker, readMarker, renderCallsToTypeScript, renderOps, schemaCollectionToCreateCollectionOptions, schemaIndexToCreateIndexOptions, serializeMongoOps, updateMarker, writeLedgerEntry };
|
|
1289
|
+
|
|
1271
1290
|
//# sourceMappingURL=control.mjs.map
|