@prisma-next/adapter-mongo 0.5.0-dev.27 → 0.5.0-dev.29
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.mjs +1 -1
- package/dist/index.d.mts +4 -3
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/{mongo-adapter-DVK2I5Hs.mjs → mongo-adapter-BIZnZRsy.mjs} +57 -37
- package/dist/mongo-adapter-BIZnZRsy.mjs.map +1 -0
- package/package.json +17 -17
- package/src/lowering.ts +25 -14
- package/src/mongo-adapter.ts +26 -20
- package/src/resolve-value.ts +41 -6
- package/dist/mongo-adapter-DVK2I5Hs.mjs.map +0 -1
package/dist/control.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as mongoInt32Codec, c as mongoVectorCodec, i as mongoDoubleCodec, n as mongoBooleanCodec, o as mongoObjectIdCodec, r as mongoDateCodec, s as mongoStringCodec, t as createMongoAdapter } from "./mongo-adapter-
|
|
1
|
+
import { a as mongoInt32Codec, c as mongoVectorCodec, i as mongoDoubleCodec, n as mongoBooleanCodec, o as mongoObjectIdCodec, r as mongoDateCodec, s as mongoStringCodec, t as createMongoAdapter } from "./mongo-adapter-BIZnZRsy.mjs";
|
|
2
2
|
import { MongoServerError } from "mongodb";
|
|
3
3
|
import { keysToKeySpec } from "@prisma-next/mongo-query-ast/control";
|
|
4
4
|
import { MongoSchemaCollection, MongoSchemaCollectionOptions, MongoSchemaIR, MongoSchemaIndex, MongoSchemaValidator } from "@prisma-next/mongo-schema-ir";
|
package/dist/index.d.mts
CHANGED
|
@@ -3,6 +3,7 @@ import { Document } from "@prisma-next/mongo-value";
|
|
|
3
3
|
import { MongoCodecRegistry } from "@prisma-next/mongo-codec";
|
|
4
4
|
import { MongoAdapter } from "@prisma-next/mongo-lowering";
|
|
5
5
|
import { OperationDescriptor } from "@prisma-next/operations";
|
|
6
|
+
import { CodecCallContext } from "@prisma-next/framework-components/codec";
|
|
6
7
|
|
|
7
8
|
//#region src/core/operations.d.ts
|
|
8
9
|
declare const mongoVectorNearOperation: Readonly<{
|
|
@@ -16,9 +17,9 @@ declare const mongoVectorOperationDescriptors: readonly OperationDescriptor[];
|
|
|
16
17
|
//#endregion
|
|
17
18
|
//#region src/lowering.d.ts
|
|
18
19
|
declare function lowerAggExpr(expr: MongoAggExpr): unknown;
|
|
19
|
-
declare function lowerFilter(filter: MongoFilterExpr, codecs
|
|
20
|
-
declare function lowerStage(stage: MongoPipelineStage, codecs
|
|
21
|
-
declare function lowerPipeline(stages: ReadonlyArray<MongoPipelineStage>, codecs
|
|
20
|
+
declare function lowerFilter(filter: MongoFilterExpr, codecs: MongoCodecRegistry, ctx: CodecCallContext): Promise<Document>;
|
|
21
|
+
declare function lowerStage(stage: MongoPipelineStage, codecs: MongoCodecRegistry, ctx: CodecCallContext): Promise<Record<string, unknown>>;
|
|
22
|
+
declare function lowerPipeline(stages: ReadonlyArray<MongoPipelineStage>, codecs: MongoCodecRegistry, ctx: CodecCallContext): Promise<Array<Record<string, unknown>>>;
|
|
22
23
|
//#endregion
|
|
23
24
|
//#region src/mongo-adapter.d.ts
|
|
24
25
|
declare function createMongoAdapter(codecs?: MongoCodecRegistry): MongoAdapter;
|
package/dist/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/operations.ts","../src/lowering.ts","../src/mongo-adapter.ts"],"sourcesContent":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/operations.ts","../src/lowering.ts","../src/mongo-adapter.ts"],"sourcesContent":[],"mappings":";;;;;;;;cAGa,0BAAwB;;;;;;;AAAxB,cAMA,+BANwB,EAAA,SAMkB,mBANlB,EAAA;;;iBCqIrB,YAAA,OAAmB;iBAIb,WAAA,SACZ,yBACA,yBACH,mBACJ,QAAQ;iBA8DW,UAAA,QACb,4BACC,yBACH,mBACJ,QAAQ;iBAsNW,aAAA,SACZ,cAAc,6BACd,yBACH,mBACJ,QAAQ,MAAM;;;iBCpPD,kBAAA,UAA4B,qBAAqB"}
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { d as lowerPipeline, f as lowerStage, l as lowerAggExpr, p as MONGO_VECTOR_CODEC_ID, t as createMongoAdapter, u as lowerFilter } from "./mongo-adapter-
|
|
1
|
+
import { d as lowerPipeline, f as lowerStage, l as lowerAggExpr, p as MONGO_VECTOR_CODEC_ID, t as createMongoAdapter, u as lowerFilter } from "./mongo-adapter-BIZnZRsy.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/core/operations.ts
|
|
4
4
|
const mongoVectorNearOperation = Object.freeze({
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { isExprArray, isRecordArgs } from "@prisma-next/mongo-query-ast/execution";
|
|
2
|
-
import { runtimeError } from "@prisma-next/framework-components/runtime";
|
|
2
|
+
import { checkAborted, raceAgainstAbort, runtimeError } from "@prisma-next/framework-components/runtime";
|
|
3
3
|
import { MongoParamRef } from "@prisma-next/mongo-value";
|
|
4
4
|
import { createMongoCodecRegistry, mongoCodec } from "@prisma-next/mongo-codec";
|
|
5
5
|
import { AggregateWireCommand, DeleteManyWireCommand, DeleteOneWireCommand, FindOneAndDeleteWireCommand, FindOneAndUpdateWireCommand, InsertManyWireCommand, InsertOneWireCommand, UpdateManyWireCommand, UpdateOneWireCommand } from "@prisma-next/mongo-wire";
|
|
@@ -29,13 +29,33 @@ const MONGO_VECTOR_CODEC_ID = "mongo/vector@1";
|
|
|
29
29
|
* (mirroring SQL's `wrapEncodeFailure` shape) with `{ label, codec }` details
|
|
30
30
|
* and the original error attached on `cause`. An already-wrapped envelope is
|
|
31
31
|
* re-thrown verbatim so nested resolvers don't double-wrap.
|
|
32
|
+
*
|
|
33
|
+
* `ctx: CodecCallContext` is forwarded verbatim to every
|
|
34
|
+
* `codec.encode(value, ctx)` call. The same `ctx` reference is also passed
|
|
35
|
+
* to nested `resolveValue` invocations so codec authors observe **signal
|
|
36
|
+
* identity** across the entire recursive walk for one `runtime.execute()`.
|
|
37
|
+
*
|
|
38
|
+
* Abort observation (only when `ctx.signal` is provided):
|
|
39
|
+
*
|
|
40
|
+
* - **Already-aborted at entry** — every recursive call pre-checks
|
|
41
|
+
* `ctx.signal.aborted` and short-circuits with
|
|
42
|
+
* `RUNTIME.ABORTED { phase: 'encode' }` before any codec is invoked.
|
|
43
|
+
* - **Mid-flight abort** — each per-level `Promise.all` races against the
|
|
44
|
+
* signal via `raceAgainstAbort`. The runtime returns
|
|
45
|
+
* `RUNTIME.ABORTED { phase: 'encode' }` promptly even if codec bodies
|
|
46
|
+
* ignore the signal; in-flight bodies run to completion in the background
|
|
47
|
+
* (cooperative cancellation, see ADR 204).
|
|
48
|
+
* - `RUNTIME.ENCODE_FAILED` envelopes thrown by a codec body before the
|
|
49
|
+
* runtime sees the abort pass through unchanged (AC-ERR4).
|
|
32
50
|
*/
|
|
33
|
-
async function resolveValue(value, codecs) {
|
|
51
|
+
async function resolveValue(value, codecs, ctx) {
|
|
52
|
+
checkAborted(ctx, "encode");
|
|
53
|
+
const signal = ctx.signal;
|
|
34
54
|
if (value instanceof MongoParamRef) {
|
|
35
|
-
if (value.codecId
|
|
55
|
+
if (value.codecId) {
|
|
36
56
|
const codec = codecs.get(value.codecId);
|
|
37
57
|
if (codec?.encode) try {
|
|
38
|
-
return await codec.encode(value.value);
|
|
58
|
+
return await raceAgainstAbort(codec.encode(value.value, ctx), signal, "encode");
|
|
39
59
|
} catch (error) {
|
|
40
60
|
wrapEncodeFailure(error, value, codec.id);
|
|
41
61
|
}
|
|
@@ -44,9 +64,9 @@ async function resolveValue(value, codecs) {
|
|
|
44
64
|
}
|
|
45
65
|
if (value === null || typeof value !== "object") return value;
|
|
46
66
|
if (value instanceof Date) return value;
|
|
47
|
-
if (Array.isArray(value)) return Promise.all(value.map((v) => resolveValue(v, codecs)));
|
|
67
|
+
if (Array.isArray(value)) return raceAgainstAbort(Promise.all(value.map((v) => resolveValue(v, codecs, ctx))), signal, "encode");
|
|
48
68
|
const entries = Object.entries(value);
|
|
49
|
-
const resolved = await Promise.all(entries.map(([, val]) => resolveValue(val, codecs)));
|
|
69
|
+
const resolved = await raceAgainstAbort(Promise.all(entries.map(([, val]) => resolveValue(val, codecs, ctx))), signal, "encode");
|
|
50
70
|
const result = {};
|
|
51
71
|
for (let i = 0; i < entries.length; i++) {
|
|
52
72
|
const entry = entries[i];
|
|
@@ -150,12 +170,12 @@ function needsLiteralWrap(value) {
|
|
|
150
170
|
function lowerAggExpr(expr) {
|
|
151
171
|
return expr.accept(aggExprLoweringVisitor);
|
|
152
172
|
}
|
|
153
|
-
async function lowerFilter(filter, codecs) {
|
|
173
|
+
async function lowerFilter(filter, codecs, ctx) {
|
|
154
174
|
switch (filter.kind) {
|
|
155
|
-
case "field": return { [filter.field]: { [filter.op]: await resolveValue(filter.value, codecs) } };
|
|
156
|
-
case "and": return { $and: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs))) };
|
|
157
|
-
case "or": return { $or: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs))) };
|
|
158
|
-
case "not": return { $nor: [await lowerFilter(filter.expr, codecs)] };
|
|
175
|
+
case "field": return { [filter.field]: { [filter.op]: await resolveValue(filter.value, codecs, ctx) } };
|
|
176
|
+
case "and": return { $and: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };
|
|
177
|
+
case "or": return { $or: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };
|
|
178
|
+
case "not": return { $nor: [await lowerFilter(filter.expr, codecs, ctx)] };
|
|
159
179
|
case "exists": return { [filter.field]: { $exists: filter.exists } };
|
|
160
180
|
case "expr": return { $expr: lowerAggExpr(filter.aggExpr) };
|
|
161
181
|
default: {
|
|
@@ -189,9 +209,9 @@ function lowerWindowField(wf) {
|
|
|
189
209
|
if (wf.window) result["window"] = { ...wf.window };
|
|
190
210
|
return result;
|
|
191
211
|
}
|
|
192
|
-
async function lowerStage(stage, codecs) {
|
|
212
|
+
async function lowerStage(stage, codecs, ctx) {
|
|
193
213
|
switch (stage.kind) {
|
|
194
|
-
case "match": return { $match: await lowerFilter(stage.filter, codecs) };
|
|
214
|
+
case "match": return { $match: await lowerFilter(stage.filter, codecs, ctx) };
|
|
195
215
|
case "project": {
|
|
196
216
|
const projection = {};
|
|
197
217
|
for (const [key, val] of Object.entries(stage.projection)) projection[key] = lowerProjectionValue(val);
|
|
@@ -207,7 +227,7 @@ async function lowerStage(stage, codecs) {
|
|
|
207
227
|
};
|
|
208
228
|
if (stage.localField !== void 0) lookup["localField"] = stage.localField;
|
|
209
229
|
if (stage.foreignField !== void 0) lookup["foreignField"] = stage.foreignField;
|
|
210
|
-
if (stage.pipeline) lookup["pipeline"] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs)));
|
|
230
|
+
if (stage.pipeline) lookup["pipeline"] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs, ctx)));
|
|
211
231
|
if (stage.let_) lookup["let"] = lowerExprRecord(stage.let_);
|
|
212
232
|
return { $lookup: lookup };
|
|
213
233
|
}
|
|
@@ -236,7 +256,7 @@ async function lowerStage(stage, codecs) {
|
|
|
236
256
|
} : stage.collection };
|
|
237
257
|
case "unionWith": {
|
|
238
258
|
const unionWith = { coll: stage.collection };
|
|
239
|
-
if (stage.pipeline) unionWith["pipeline"] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs)));
|
|
259
|
+
if (stage.pipeline) unionWith["pipeline"] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs, ctx)));
|
|
240
260
|
return { $unionWith: unionWith };
|
|
241
261
|
}
|
|
242
262
|
case "bucket": {
|
|
@@ -265,7 +285,7 @@ async function lowerStage(stage, codecs) {
|
|
|
265
285
|
if (stage.spherical !== void 0) geoNear["spherical"] = stage.spherical;
|
|
266
286
|
if (stage.maxDistance !== void 0) geoNear["maxDistance"] = stage.maxDistance;
|
|
267
287
|
if (stage.minDistance !== void 0) geoNear["minDistance"] = stage.minDistance;
|
|
268
|
-
if (stage.query) geoNear["query"] = await lowerFilter(stage.query, codecs);
|
|
288
|
+
if (stage.query) geoNear["query"] = await lowerFilter(stage.query, codecs, ctx);
|
|
269
289
|
if (stage.key !== void 0) geoNear["key"] = stage.key;
|
|
270
290
|
if (stage.distanceMultiplier !== void 0) geoNear["distanceMultiplier"] = stage.distanceMultiplier;
|
|
271
291
|
if (stage.includeLocs !== void 0) geoNear["includeLocs"] = stage.includeLocs;
|
|
@@ -273,7 +293,7 @@ async function lowerStage(stage, codecs) {
|
|
|
273
293
|
}
|
|
274
294
|
case "facet": {
|
|
275
295
|
const facetEntries = Object.entries(stage.facets);
|
|
276
|
-
const facetPipelines = await Promise.all(facetEntries.map(([, pipeline]) => Promise.all(pipeline.map((s) => lowerStage(s, codecs)))));
|
|
296
|
+
const facetPipelines = await Promise.all(facetEntries.map(([, pipeline]) => Promise.all(pipeline.map((s) => lowerStage(s, codecs, ctx)))));
|
|
277
297
|
const facet = {};
|
|
278
298
|
for (let i = 0; i < facetEntries.length; i++) {
|
|
279
299
|
const entry = facetEntries[i];
|
|
@@ -291,13 +311,13 @@ async function lowerStage(stage, codecs) {
|
|
|
291
311
|
};
|
|
292
312
|
if (stage.maxDepth !== void 0) graphLookup["maxDepth"] = stage.maxDepth;
|
|
293
313
|
if (stage.depthField !== void 0) graphLookup["depthField"] = stage.depthField;
|
|
294
|
-
if (stage.restrictSearchWithMatch) graphLookup["restrictSearchWithMatch"] = await lowerFilter(stage.restrictSearchWithMatch, codecs);
|
|
314
|
+
if (stage.restrictSearchWithMatch) graphLookup["restrictSearchWithMatch"] = await lowerFilter(stage.restrictSearchWithMatch, codecs, ctx);
|
|
295
315
|
return { $graphLookup: graphLookup };
|
|
296
316
|
}
|
|
297
317
|
case "merge": {
|
|
298
318
|
const merge = { into: stage.into };
|
|
299
319
|
if (stage.on !== void 0) merge["on"] = stage.on;
|
|
300
|
-
if (stage.whenMatched !== void 0) merge["whenMatched"] = Array.isArray(stage.whenMatched) ? await Promise.all(stage.whenMatched.map((s) => lowerStage(s, codecs))) : stage.whenMatched;
|
|
320
|
+
if (stage.whenMatched !== void 0) merge["whenMatched"] = Array.isArray(stage.whenMatched) ? await Promise.all(stage.whenMatched.map((s) => lowerStage(s, codecs, ctx))) : stage.whenMatched;
|
|
301
321
|
if (stage.whenNotMatched !== void 0) merge["whenNotMatched"] = stage.whenNotMatched;
|
|
302
322
|
return { $merge: merge };
|
|
303
323
|
}
|
|
@@ -360,8 +380,8 @@ async function lowerStage(stage, codecs) {
|
|
|
360
380
|
}
|
|
361
381
|
}
|
|
362
382
|
}
|
|
363
|
-
async function lowerPipeline(stages, codecs) {
|
|
364
|
-
return Promise.all(stages.map((s) => lowerStage(s, codecs)));
|
|
383
|
+
async function lowerPipeline(stages, codecs, ctx) {
|
|
384
|
+
return Promise.all(stages.map((s) => lowerStage(s, codecs, ctx)));
|
|
365
385
|
}
|
|
366
386
|
|
|
367
387
|
//#endregion
|
|
@@ -449,9 +469,9 @@ var MongoAdapterImpl = class {
|
|
|
449
469
|
constructor(codecs) {
|
|
450
470
|
this.#codecs = codecs;
|
|
451
471
|
}
|
|
452
|
-
async #resolveDocument(expr) {
|
|
472
|
+
async #resolveDocument(expr, ctx) {
|
|
453
473
|
const entries = Object.entries(expr);
|
|
454
|
-
const resolved = await Promise.all(entries.map(([, val]) => resolveValue(val, this.#codecs)));
|
|
474
|
+
const resolved = await Promise.all(entries.map(([, val]) => resolveValue(val, this.#codecs, ctx)));
|
|
455
475
|
const result = {};
|
|
456
476
|
for (let i = 0; i < entries.length; i++) {
|
|
457
477
|
const entry = entries[i];
|
|
@@ -459,31 +479,31 @@ var MongoAdapterImpl = class {
|
|
|
459
479
|
}
|
|
460
480
|
return result;
|
|
461
481
|
}
|
|
462
|
-
async #lowerUpdate(update) {
|
|
463
|
-
if (isUpdatePipeline(update)) return Promise.all(update.map((stage) => lowerStage(stage, this.#codecs)));
|
|
464
|
-
return this.#resolveDocument(update);
|
|
482
|
+
async #lowerUpdate(update, ctx) {
|
|
483
|
+
if (isUpdatePipeline(update)) return Promise.all(update.map((stage) => lowerStage(stage, this.#codecs, ctx)));
|
|
484
|
+
return this.#resolveDocument(update, ctx);
|
|
465
485
|
}
|
|
466
|
-
async lower(plan) {
|
|
486
|
+
async lower(plan, ctx) {
|
|
467
487
|
const { command } = plan;
|
|
468
488
|
switch (command.kind) {
|
|
469
|
-
case "insertOne": return new InsertOneWireCommand(command.collection, await this.#resolveDocument(command.document));
|
|
489
|
+
case "insertOne": return new InsertOneWireCommand(command.collection, await this.#resolveDocument(command.document, ctx));
|
|
470
490
|
case "updateOne": {
|
|
471
|
-
const [filter, update] = await Promise.all([lowerFilter(command.filter, this.#codecs), this.#lowerUpdate(command.update)]);
|
|
491
|
+
const [filter, update] = await Promise.all([lowerFilter(command.filter, this.#codecs, ctx), this.#lowerUpdate(command.update, ctx)]);
|
|
472
492
|
return new UpdateOneWireCommand(command.collection, filter, update, command.upsert);
|
|
473
493
|
}
|
|
474
|
-
case "insertMany": return new InsertManyWireCommand(command.collection, await Promise.all(command.documents.map((doc) => this.#resolveDocument(doc))));
|
|
494
|
+
case "insertMany": return new InsertManyWireCommand(command.collection, await Promise.all(command.documents.map((doc) => this.#resolveDocument(doc, ctx))));
|
|
475
495
|
case "updateMany": {
|
|
476
|
-
const [filter, update] = await Promise.all([lowerFilter(command.filter, this.#codecs), this.#lowerUpdate(command.update)]);
|
|
496
|
+
const [filter, update] = await Promise.all([lowerFilter(command.filter, this.#codecs, ctx), this.#lowerUpdate(command.update, ctx)]);
|
|
477
497
|
return new UpdateManyWireCommand(command.collection, filter, update, command.upsert);
|
|
478
498
|
}
|
|
479
|
-
case "deleteOne": return new DeleteOneWireCommand(command.collection, await lowerFilter(command.filter, this.#codecs));
|
|
480
|
-
case "deleteMany": return new DeleteManyWireCommand(command.collection, await lowerFilter(command.filter, this.#codecs));
|
|
499
|
+
case "deleteOne": return new DeleteOneWireCommand(command.collection, await lowerFilter(command.filter, this.#codecs, ctx));
|
|
500
|
+
case "deleteMany": return new DeleteManyWireCommand(command.collection, await lowerFilter(command.filter, this.#codecs, ctx));
|
|
481
501
|
case "findOneAndUpdate": {
|
|
482
|
-
const [filter, update] = await Promise.all([lowerFilter(command.filter, this.#codecs), this.#lowerUpdate(command.update)]);
|
|
502
|
+
const [filter, update] = await Promise.all([lowerFilter(command.filter, this.#codecs, ctx), this.#lowerUpdate(command.update, ctx)]);
|
|
483
503
|
return new FindOneAndUpdateWireCommand(command.collection, filter, update, command.upsert, command.sort, command.returnDocument);
|
|
484
504
|
}
|
|
485
|
-
case "findOneAndDelete": return new FindOneAndDeleteWireCommand(command.collection, await lowerFilter(command.filter, this.#codecs), command.sort);
|
|
486
|
-
case "aggregate": return new AggregateWireCommand(command.collection, await lowerPipeline(command.pipeline, this.#codecs));
|
|
505
|
+
case "findOneAndDelete": return new FindOneAndDeleteWireCommand(command.collection, await lowerFilter(command.filter, this.#codecs, ctx), command.sort);
|
|
506
|
+
case "aggregate": return new AggregateWireCommand(command.collection, await lowerPipeline(command.pipeline, this.#codecs, ctx));
|
|
487
507
|
case "rawAggregate": return new AggregateWireCommand(command.collection, command.pipeline);
|
|
488
508
|
case "rawInsertOne": return new InsertOneWireCommand(command.collection, command.document);
|
|
489
509
|
case "rawInsertMany": return new InsertManyWireCommand(command.collection, command.documents);
|
|
@@ -519,4 +539,4 @@ function createMongoAdapter(codecs) {
|
|
|
519
539
|
|
|
520
540
|
//#endregion
|
|
521
541
|
export { mongoInt32Codec as a, mongoVectorCodec as c, lowerPipeline as d, lowerStage as f, mongoDoubleCodec as i, lowerAggExpr as l, mongoBooleanCodec as n, mongoObjectIdCodec as o, MONGO_VECTOR_CODEC_ID as p, mongoDateCodec as r, mongoStringCodec as s, createMongoAdapter as t, lowerFilter as u };
|
|
522
|
-
//# sourceMappingURL=mongo-adapter-
|
|
542
|
+
//# sourceMappingURL=mongo-adapter-BIZnZRsy.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mongo-adapter-BIZnZRsy.mjs","names":["result: Record<string, unknown>","entries: Array<[string, unknown]>","aggExprLoweringVisitor: MongoAggExprVisitor<unknown>","loweredArgs: unknown","vars: Record<string, unknown>","_exhaustive: never","result: Record<string, unknown>","projection: Record<string, unknown>","lookup: Record<string, unknown>","unwind: Record<string, unknown>","group: Record<string, unknown>","unionWith: Record<string, unknown>","bucket: Record<string, unknown>","bucketAuto: Record<string, unknown>","geoNear: Record<string, unknown>","facet: Record<string, unknown>","graphLookup: Record<string, unknown>","merge: Record<string, unknown>","swf: Record<string, unknown>","output: Record<string, unknown>","densify: Record<string, unknown>","fill: Record<string, unknown>","entry: Record<string, unknown>","search: Record<string, unknown>","searchMeta: Record<string, unknown>","vs: Record<string, unknown>","#codecs","#resolveDocument","result: Record<string, unknown>","#lowerUpdate","_exhaustive: never"],"sources":["../src/core/codec-ids.ts","../src/resolve-value.ts","../src/lowering.ts","../src/core/codecs.ts","../src/mongo-adapter.ts"],"sourcesContent":["export const MONGO_OBJECTID_CODEC_ID = 'mongo/objectId@1' as const;\nexport const MONGO_STRING_CODEC_ID = 'mongo/string@1' as const;\nexport const MONGO_DOUBLE_CODEC_ID = 'mongo/double@1' as const;\nexport const MONGO_INT32_CODEC_ID = 'mongo/int32@1' as const;\nexport const MONGO_BOOLEAN_CODEC_ID = 'mongo/bool@1' as const;\nexport const MONGO_DATE_CODEC_ID = 'mongo/date@1' as const;\nexport const MONGO_VECTOR_CODEC_ID = 'mongo/vector@1' as const;\n","import type { CodecCallContext } from '@prisma-next/framework-components/codec';\nimport {\n checkAborted,\n raceAgainstAbort,\n runtimeError,\n} from '@prisma-next/framework-components/runtime';\nimport type { MongoCodecRegistry } from '@prisma-next/mongo-codec';\nimport type { MongoValue } from '@prisma-next/mongo-value';\nimport { MongoParamRef } from '@prisma-next/mongo-value';\n\n/**\n * Resolves a `MongoValue` (which may contain `MongoParamRef` leaves) into the\n * driver-ready wire shape. When a leaf has a `codecId` and the registry has a\n * codec for it, the codec's async `encode` is awaited so codecs may perform\n * asynchronous work (e.g. lookups, key derivations).\n *\n * Object/array nodes dispatch their child resolutions concurrently via\n * `Promise.all` so independent leaves encode in parallel.\n *\n * Codec encode failures are wrapped in a `RUNTIME.ENCODE_FAILED` envelope\n * (mirroring SQL's `wrapEncodeFailure` shape) with `{ label, codec }` details\n * and the original error attached on `cause`. An already-wrapped envelope is\n * re-thrown verbatim so nested resolvers don't double-wrap.\n *\n * `ctx: CodecCallContext` is forwarded verbatim to every\n * `codec.encode(value, ctx)` call. The same `ctx` reference is also passed\n * to nested `resolveValue` invocations so codec authors observe **signal\n * identity** across the entire recursive walk for one `runtime.execute()`.\n *\n * Abort observation (only when `ctx.signal` is provided):\n *\n * - **Already-aborted at entry** — every recursive call pre-checks\n * `ctx.signal.aborted` and short-circuits with\n * `RUNTIME.ABORTED { phase: 'encode' }` before any codec is invoked.\n * - **Mid-flight abort** — each per-level `Promise.all` races against the\n * signal via `raceAgainstAbort`. The runtime returns\n * `RUNTIME.ABORTED { phase: 'encode' }` promptly even if codec bodies\n * ignore the signal; in-flight bodies run to completion in the background\n * (cooperative cancellation, see ADR 204).\n * - `RUNTIME.ENCODE_FAILED` envelopes thrown by a codec body before the\n * runtime sees the abort pass through unchanged (AC-ERR4).\n */\nexport async function resolveValue(\n value: MongoValue,\n codecs: MongoCodecRegistry,\n ctx: CodecCallContext,\n): Promise<unknown> {\n checkAborted(ctx, 'encode');\n const signal = ctx.signal;\n\n if (value instanceof MongoParamRef) {\n if (value.codecId) {\n const codec = codecs.get(value.codecId);\n if (codec?.encode) {\n try {\n // Race even leaf scalar encodes against the signal so a leaf\n // `MongoParamRef` (e.g. a simple field filter, or any leaf reached\n // from `MongoAdapterImpl.#resolveDocument()` outside an enclosing\n // `Promise.all`) surfaces `RUNTIME.ABORTED` promptly instead of\n // blocking on a slow codec body.\n const encoded = codec.encode(value.value, ctx);\n return await raceAgainstAbort(encoded, signal, 'encode');\n } catch (error) {\n wrapEncodeFailure(error, value, codec.id);\n }\n }\n }\n return value.value;\n }\n if (value === null || typeof value !== 'object') {\n return value;\n }\n if (value instanceof Date) {\n return value;\n }\n if (Array.isArray(value)) {\n const tasks = Promise.all(value.map((v) => resolveValue(v, codecs, ctx)));\n return raceAgainstAbort(tasks, signal, 'encode');\n }\n const entries = Object.entries(value);\n const all = Promise.all(entries.map(([, val]) => resolveValue(val, codecs, ctx)));\n const resolved = await raceAgainstAbort(all, signal, 'encode');\n const result: Record<string, unknown> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry) {\n result[entry[0]] = resolved[i];\n }\n }\n return result;\n}\n\nfunction paramRefLabel(ref: MongoParamRef, codecId: string): string {\n return ref.name ?? codecId;\n}\n\nfunction isAlreadyEncodeFailure(error: unknown): boolean {\n return (\n error instanceof Error &&\n 'code' in error &&\n (error as Error & { code?: unknown }).code === 'RUNTIME.ENCODE_FAILED'\n );\n}\n\nfunction wrapEncodeFailure(error: unknown, ref: MongoParamRef, codecId: string): never {\n if (isAlreadyEncodeFailure(error)) {\n throw error;\n }\n const label = paramRefLabel(ref, codecId);\n const message = error instanceof Error ? error.message : String(error);\n const wrapped = runtimeError(\n 'RUNTIME.ENCODE_FAILED',\n `Failed to encode parameter ${label} with codec '${codecId}': ${message}`,\n { label, codec: codecId },\n );\n wrapped.cause = error;\n throw wrapped;\n}\n","import type { CodecCallContext } from '@prisma-next/framework-components/codec';\nimport type { MongoCodecRegistry } from '@prisma-next/mongo-codec';\nimport type {\n MongoAggExpr,\n MongoAggExprVisitor,\n MongoFilterExpr,\n MongoGroupId,\n MongoPipelineStage,\n MongoProjectionValue,\n MongoWindowField,\n} from '@prisma-next/mongo-query-ast/execution';\nimport { isExprArray, isRecordArgs } from '@prisma-next/mongo-query-ast/execution';\nimport type { Document } from '@prisma-next/mongo-value';\nimport { resolveValue } from './resolve-value';\n\n// Biome flags `{ then: ... }` as a thenable object (noThenProperty). Build via Object.fromEntries to avoid.\nconst THEN_KEY = 'then';\n\nfunction condBranch(\n caseOrIf: MongoAggExpr,\n thenExpr: MongoAggExpr,\n elseExpr?: MongoAggExpr,\n): Record<string, unknown> {\n const entries: Array<[string, unknown]> = [\n [elseExpr ? 'if' : 'case', lowerAggExpr(caseOrIf)],\n [THEN_KEY, lowerAggExpr(thenExpr)],\n ];\n if (elseExpr) {\n entries.push(['else', lowerAggExpr(elseExpr)]);\n }\n return Object.fromEntries(entries);\n}\n\nconst aggExprLoweringVisitor: MongoAggExprVisitor<unknown> = {\n fieldRef(expr) {\n return `$${expr.path}`;\n },\n\n literal(expr) {\n return needsLiteralWrap(expr.value) ? { $literal: expr.value } : expr.value;\n },\n\n operator(expr) {\n const { args } = expr;\n let loweredArgs: unknown;\n if (isExprArray(args)) {\n loweredArgs = args.map((a) => lowerAggExpr(a));\n } else if (isRecordArgs(args)) {\n loweredArgs = lowerExprRecord(args);\n } else {\n loweredArgs = lowerAggExpr(args);\n }\n return { [expr.op]: loweredArgs };\n },\n\n accumulator(expr) {\n if (expr.arg === null) {\n return { [expr.op]: {} };\n }\n if (isRecordArgs(expr.arg)) {\n return { [expr.op]: lowerExprRecord(expr.arg) };\n }\n return { [expr.op]: lowerAggExpr(expr.arg) };\n },\n\n cond(expr) {\n return { $cond: condBranch(expr.condition, expr.then_, expr.else_) };\n },\n\n switch_(expr) {\n return {\n $switch: {\n branches: expr.branches.map((b) => condBranch(b.case_, b.then_)),\n default: lowerAggExpr(expr.default_),\n },\n };\n },\n\n filter(expr) {\n return {\n $filter: {\n input: lowerAggExpr(expr.input),\n cond: lowerAggExpr(expr.cond),\n as: expr.as,\n },\n };\n },\n\n map(expr) {\n return {\n $map: {\n input: lowerAggExpr(expr.input),\n in: lowerAggExpr(expr.in_),\n as: expr.as,\n },\n };\n },\n\n reduce(expr) {\n return {\n $reduce: {\n input: lowerAggExpr(expr.input),\n initialValue: lowerAggExpr(expr.initialValue),\n in: lowerAggExpr(expr.in_),\n },\n };\n },\n\n let_(expr) {\n const vars: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(expr.vars)) {\n vars[key] = lowerAggExpr(val);\n }\n return { $let: { vars, in: lowerAggExpr(expr.in_) } };\n },\n\n mergeObjects(expr) {\n return { $mergeObjects: expr.exprs.map((e) => lowerAggExpr(e)) };\n },\n};\n\nfunction needsLiteralWrap(value: unknown): boolean {\n if (typeof value === 'string' && value.startsWith('$')) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.some((v) => needsLiteralWrap(v));\n }\n if (value !== null && typeof value === 'object') {\n return Object.entries(value as Record<string, unknown>).some(\n ([k, v]) => k.startsWith('$') || needsLiteralWrap(v),\n );\n }\n return false;\n}\n\nexport function lowerAggExpr(expr: MongoAggExpr): unknown {\n return expr.accept(aggExprLoweringVisitor);\n}\n\nexport async function lowerFilter(\n filter: MongoFilterExpr,\n codecs: MongoCodecRegistry,\n ctx: CodecCallContext,\n): Promise<Document> {\n switch (filter.kind) {\n case 'field':\n return { [filter.field]: { [filter.op]: await resolveValue(filter.value, codecs, ctx) } };\n case 'and':\n return { $and: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };\n case 'or':\n return { $or: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };\n case 'not':\n return { $nor: [await lowerFilter(filter.expr, codecs, ctx)] };\n case 'exists':\n return { [filter.field]: { $exists: filter.exists } };\n case 'expr':\n return { $expr: lowerAggExpr(filter.aggExpr) };\n default: {\n const _exhaustive: never = filter;\n throw new Error(`Unhandled filter kind: ${(_exhaustive as MongoFilterExpr).kind}`);\n }\n }\n}\n\nfunction isAggExprNode(value: object): value is MongoAggExpr {\n return 'accept' in value && typeof value.accept === 'function';\n}\n\nfunction lowerGroupId(groupId: MongoGroupId): unknown {\n if (groupId === null) return null;\n if (isAggExprNode(groupId)) return lowerAggExpr(groupId);\n return lowerExprRecord(groupId);\n}\n\nfunction lowerExprRecord(\n fields: Readonly<Record<string, MongoAggExpr | ReadonlyArray<MongoAggExpr>>>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(fields)) {\n if (Array.isArray(val)) {\n result[key] = val.map((v: MongoAggExpr) => lowerAggExpr(v));\n } else {\n result[key] = lowerAggExpr(val as MongoAggExpr);\n }\n }\n return result;\n}\n\nfunction lowerProjectionValue(value: MongoProjectionValue): unknown {\n if (typeof value === 'number') return value;\n return lowerAggExpr(value);\n}\n\nfunction lowerWindowField(wf: MongoWindowField): Record<string, unknown> {\n const lowered = lowerAggExpr(wf.operator);\n if (typeof lowered !== 'object' || lowered === null) {\n throw new Error('Window field operator must lower to an object');\n }\n const result: Record<string, unknown> = { ...lowered };\n if (wf.window) {\n result['window'] = { ...wf.window };\n }\n return result;\n}\n\nexport async function lowerStage(\n stage: MongoPipelineStage,\n codecs: MongoCodecRegistry,\n ctx: CodecCallContext,\n): Promise<Record<string, unknown>> {\n switch (stage.kind) {\n case 'match':\n return { $match: await lowerFilter(stage.filter, codecs, ctx) };\n case 'project': {\n const projection: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(stage.projection)) {\n projection[key] = lowerProjectionValue(val);\n }\n return { $project: projection };\n }\n case 'sort':\n return { $sort: { ...stage.sort } };\n case 'limit':\n return { $limit: stage.limit };\n case 'skip':\n return { $skip: stage.skip };\n case 'lookup': {\n const lookup: Record<string, unknown> = {\n from: stage.from,\n as: stage.as,\n };\n if (stage.localField !== undefined) lookup['localField'] = stage.localField;\n if (stage.foreignField !== undefined) lookup['foreignField'] = stage.foreignField;\n if (stage.pipeline) {\n lookup['pipeline'] = await Promise.all(\n stage.pipeline.map((s) => lowerStage(s, codecs, ctx)),\n );\n }\n if (stage.let_) {\n lookup['let'] = lowerExprRecord(stage.let_);\n }\n return { $lookup: lookup };\n }\n case 'unwind': {\n const unwind: Record<string, unknown> = {\n path: stage.path,\n preserveNullAndEmptyArrays: stage.preserveNullAndEmptyArrays,\n };\n if (stage.includeArrayIndex !== undefined) {\n unwind['includeArrayIndex'] = stage.includeArrayIndex;\n }\n return { $unwind: unwind };\n }\n case 'group': {\n const group: Record<string, unknown> = { _id: lowerGroupId(stage.groupId) };\n for (const [key, acc] of Object.entries(stage.accumulators)) {\n group[key] = lowerAggExpr(acc);\n }\n return { $group: group };\n }\n case 'addFields':\n return { $addFields: lowerExprRecord(stage.fields) };\n case 'replaceRoot':\n return { $replaceRoot: { newRoot: lowerAggExpr(stage.newRoot) } };\n case 'count':\n return { $count: stage.field };\n case 'sortByCount':\n return { $sortByCount: lowerAggExpr(stage.expr) };\n case 'sample':\n return { $sample: { size: stage.size } };\n case 'redact':\n return { $redact: lowerAggExpr(stage.expr) };\n case 'out':\n return { $out: stage.db ? { db: stage.db, coll: stage.collection } : stage.collection };\n case 'unionWith': {\n const unionWith: Record<string, unknown> = { coll: stage.collection };\n if (stage.pipeline) {\n unionWith['pipeline'] = await Promise.all(\n stage.pipeline.map((s) => lowerStage(s, codecs, ctx)),\n );\n }\n return { $unionWith: unionWith };\n }\n case 'bucket': {\n const bucket: Record<string, unknown> = {\n groupBy: lowerAggExpr(stage.groupBy),\n boundaries: [...stage.boundaries],\n };\n if (stage.default_ !== undefined) bucket['default'] = stage.default_;\n if (stage.output) bucket['output'] = lowerExprRecord(stage.output);\n return { $bucket: bucket };\n }\n case 'bucketAuto': {\n const bucketAuto: Record<string, unknown> = {\n groupBy: lowerAggExpr(stage.groupBy),\n buckets: stage.buckets,\n };\n if (stage.output) bucketAuto['output'] = lowerExprRecord(stage.output);\n if (stage.granularity !== undefined) bucketAuto['granularity'] = stage.granularity;\n return { $bucketAuto: bucketAuto };\n }\n case 'geoNear': {\n const geoNear: Record<string, unknown> = {\n near: stage.near,\n distanceField: stage.distanceField,\n };\n if (stage.spherical !== undefined) geoNear['spherical'] = stage.spherical;\n if (stage.maxDistance !== undefined) geoNear['maxDistance'] = stage.maxDistance;\n if (stage.minDistance !== undefined) geoNear['minDistance'] = stage.minDistance;\n if (stage.query) geoNear['query'] = await lowerFilter(stage.query, codecs, ctx);\n if (stage.key !== undefined) geoNear['key'] = stage.key;\n if (stage.distanceMultiplier !== undefined)\n geoNear['distanceMultiplier'] = stage.distanceMultiplier;\n if (stage.includeLocs !== undefined) geoNear['includeLocs'] = stage.includeLocs;\n return { $geoNear: geoNear };\n }\n case 'facet': {\n const facetEntries = Object.entries(stage.facets);\n const facetPipelines = await Promise.all(\n facetEntries.map(([, pipeline]) =>\n Promise.all(pipeline.map((s) => lowerStage(s, codecs, ctx))),\n ),\n );\n const facet: Record<string, unknown> = {};\n for (let i = 0; i < facetEntries.length; i++) {\n const entry = facetEntries[i];\n if (entry) {\n facet[entry[0]] = facetPipelines[i];\n }\n }\n return { $facet: facet };\n }\n case 'graphLookup': {\n const graphLookup: Record<string, unknown> = {\n from: stage.from,\n startWith: lowerAggExpr(stage.startWith),\n connectFromField: stage.connectFromField,\n connectToField: stage.connectToField,\n as: stage.as,\n };\n if (stage.maxDepth !== undefined) graphLookup['maxDepth'] = stage.maxDepth;\n if (stage.depthField !== undefined) graphLookup['depthField'] = stage.depthField;\n if (stage.restrictSearchWithMatch)\n graphLookup['restrictSearchWithMatch'] = await lowerFilter(\n stage.restrictSearchWithMatch,\n codecs,\n ctx,\n );\n return { $graphLookup: graphLookup };\n }\n case 'merge': {\n const merge: Record<string, unknown> = { into: stage.into };\n if (stage.on !== undefined) merge['on'] = stage.on;\n if (stage.whenMatched !== undefined) {\n merge['whenMatched'] = Array.isArray(stage.whenMatched)\n ? await Promise.all(stage.whenMatched.map((s) => lowerStage(s, codecs, ctx)))\n : stage.whenMatched;\n }\n if (stage.whenNotMatched !== undefined) merge['whenNotMatched'] = stage.whenNotMatched;\n return { $merge: merge };\n }\n case 'setWindowFields': {\n const swf: Record<string, unknown> = {};\n if (stage.partitionBy) swf['partitionBy'] = lowerAggExpr(stage.partitionBy);\n if (stage.sortBy) swf['sortBy'] = { ...stage.sortBy };\n const output: Record<string, unknown> = {};\n for (const [key, wf] of Object.entries(stage.output)) {\n output[key] = lowerWindowField(wf);\n }\n swf['output'] = output;\n return { $setWindowFields: swf };\n }\n case 'densify': {\n const densify: Record<string, unknown> = {\n field: stage.field,\n range: { ...stage.range },\n };\n if (stage.partitionByFields) densify['partitionByFields'] = [...stage.partitionByFields];\n return { $densify: densify };\n }\n case 'fill': {\n const fill: Record<string, unknown> = {};\n if (stage.partitionBy) fill['partitionBy'] = lowerAggExpr(stage.partitionBy);\n if (stage.partitionByFields) fill['partitionByFields'] = [...stage.partitionByFields];\n if (stage.sortBy) fill['sortBy'] = { ...stage.sortBy };\n const output: Record<string, unknown> = {};\n for (const [key, fo] of Object.entries(stage.output)) {\n const entry: Record<string, unknown> = {};\n if (fo.method !== undefined) entry['method'] = fo.method;\n if (fo.value !== undefined) entry['value'] = lowerAggExpr(fo.value);\n output[key] = entry;\n }\n fill['output'] = output;\n return { $fill: fill };\n }\n case 'search': {\n const search: Record<string, unknown> = { ...stage.config };\n if (stage.index !== undefined) search['index'] = stage.index;\n return { $search: search };\n }\n case 'searchMeta': {\n const searchMeta: Record<string, unknown> = { ...stage.config };\n if (stage.index !== undefined) searchMeta['index'] = stage.index;\n return { $searchMeta: searchMeta };\n }\n case 'vectorSearch': {\n const vs: Record<string, unknown> = {\n index: stage.index,\n path: stage.path,\n queryVector: [...stage.queryVector],\n numCandidates: stage.numCandidates,\n limit: stage.limit,\n };\n if (stage.filter) vs['filter'] = { ...stage.filter };\n return { $vectorSearch: vs };\n }\n default: {\n const _exhaustive: never = stage;\n throw new Error(`Unhandled stage kind: ${(_exhaustive as MongoPipelineStage).kind}`);\n }\n }\n}\n\nexport async function lowerPipeline(\n stages: ReadonlyArray<MongoPipelineStage>,\n codecs: MongoCodecRegistry,\n ctx: CodecCallContext,\n): Promise<Array<Record<string, unknown>>> {\n return Promise.all(stages.map((s) => lowerStage(s, codecs, ctx)));\n}\n","import { mongoCodec } from '@prisma-next/mongo-codec';\nimport { ObjectId } from 'mongodb';\nimport {\n MONGO_BOOLEAN_CODEC_ID,\n MONGO_DATE_CODEC_ID,\n MONGO_DOUBLE_CODEC_ID,\n MONGO_INT32_CODEC_ID,\n MONGO_OBJECTID_CODEC_ID,\n MONGO_STRING_CODEC_ID,\n MONGO_VECTOR_CODEC_ID,\n} from './codec-ids';\n\nexport const mongoObjectIdCodec = mongoCodec({\n typeId: MONGO_OBJECTID_CODEC_ID,\n targetTypes: ['objectId'],\n traits: ['equality'],\n decode: (wire: ObjectId) => wire.toHexString(),\n encode: (value: string) => new ObjectId(value),\n});\n\nexport const mongoStringCodec = mongoCodec({\n typeId: MONGO_STRING_CODEC_ID,\n targetTypes: ['string'],\n traits: ['equality', 'order', 'textual'],\n decode: (wire: string) => wire,\n encode: (value: string) => value,\n});\n\nexport const mongoDoubleCodec = mongoCodec({\n typeId: MONGO_DOUBLE_CODEC_ID,\n targetTypes: ['double'],\n traits: ['equality', 'order', 'numeric'],\n decode: (wire: number) => wire,\n encode: (value: number) => value,\n});\n\nexport const mongoInt32Codec = mongoCodec({\n typeId: MONGO_INT32_CODEC_ID,\n targetTypes: ['int'],\n traits: ['equality', 'order', 'numeric'],\n decode: (wire: number) => wire,\n encode: (value: number) => value,\n});\n\nexport const mongoBooleanCodec = mongoCodec({\n typeId: MONGO_BOOLEAN_CODEC_ID,\n targetTypes: ['bool'],\n traits: ['equality', 'boolean'],\n decode: (wire: boolean) => wire,\n encode: (value: boolean) => value,\n});\n\nexport const mongoDateCodec = mongoCodec({\n typeId: MONGO_DATE_CODEC_ID,\n targetTypes: ['date'],\n traits: ['equality', 'order'],\n decode: (wire: Date) => wire,\n encode: (value: Date) => value,\n encodeJson: (value: Date) => value.toISOString(),\n decodeJson: (json) => {\n if (typeof json !== 'string') throw new Error('expected ISO date string');\n return new Date(json);\n },\n});\n\nexport const mongoVectorCodec = mongoCodec({\n typeId: MONGO_VECTOR_CODEC_ID,\n targetTypes: ['vector'],\n traits: ['equality'],\n decode: (wire: readonly number[]) => wire,\n encode: (value: readonly number[]) => value,\n renderOutputType: (typeParams) => {\n const length = typeParams['length'];\n if (length === undefined) return undefined;\n if (typeof length !== 'number' || !Number.isFinite(length) || !Number.isInteger(length)) {\n throw new Error('renderOutputType: expected positive integer \"length\" for Vector');\n }\n return `Vector<${length}>`;\n },\n});\n","import type { CodecCallContext } from '@prisma-next/framework-components/codec';\nimport { createMongoCodecRegistry, type MongoCodecRegistry } from '@prisma-next/mongo-codec';\nimport type { MongoAdapter } from '@prisma-next/mongo-lowering';\nimport type {\n MongoQueryPlan,\n MongoUpdatePipelineStage,\n MongoUpdateSpec,\n} from '@prisma-next/mongo-query-ast/execution';\nimport type { Document, MongoExpr } from '@prisma-next/mongo-value';\nimport type { AnyMongoWireCommand } from '@prisma-next/mongo-wire';\nimport {\n AggregateWireCommand,\n DeleteManyWireCommand,\n DeleteOneWireCommand,\n FindOneAndDeleteWireCommand,\n FindOneAndUpdateWireCommand,\n InsertManyWireCommand,\n InsertOneWireCommand,\n UpdateManyWireCommand,\n UpdateOneWireCommand,\n} from '@prisma-next/mongo-wire';\nimport { lowerFilter, lowerPipeline, lowerStage } from './lowering';\nimport { resolveValue } from './resolve-value';\n\nfunction isUpdatePipeline(\n update: MongoUpdateSpec,\n): update is ReadonlyArray<MongoUpdatePipelineStage> {\n return Array.isArray(update);\n}\n\nclass MongoAdapterImpl implements MongoAdapter {\n readonly #codecs: MongoCodecRegistry;\n\n constructor(codecs: MongoCodecRegistry) {\n this.#codecs = codecs;\n }\n\n async #resolveDocument(expr: MongoExpr, ctx: CodecCallContext): Promise<Document> {\n const entries = Object.entries(expr);\n const resolved = await Promise.all(\n entries.map(([, val]) => resolveValue(val, this.#codecs, ctx)),\n );\n const result: Record<string, unknown> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry) {\n result[entry[0]] = resolved[i];\n }\n }\n return result;\n }\n\n async #lowerUpdate(\n update: MongoUpdateSpec,\n ctx: CodecCallContext,\n ): Promise<Document | ReadonlyArray<Document>> {\n if (isUpdatePipeline(update)) {\n return Promise.all(update.map((stage) => lowerStage(stage, this.#codecs, ctx)));\n }\n return this.#resolveDocument(update, ctx);\n }\n\n async lower(plan: MongoQueryPlan, ctx: CodecCallContext): Promise<AnyMongoWireCommand> {\n const { command } = plan;\n switch (command.kind) {\n case 'insertOne':\n return new InsertOneWireCommand(\n command.collection,\n await this.#resolveDocument(command.document, ctx),\n );\n case 'updateOne': {\n const [filter, update] = await Promise.all([\n lowerFilter(command.filter, this.#codecs, ctx),\n this.#lowerUpdate(command.update, ctx),\n ]);\n return new UpdateOneWireCommand(command.collection, filter, update, command.upsert);\n }\n case 'insertMany':\n return new InsertManyWireCommand(\n command.collection,\n await Promise.all(command.documents.map((doc) => this.#resolveDocument(doc, ctx))),\n );\n case 'updateMany': {\n const [filter, update] = await Promise.all([\n lowerFilter(command.filter, this.#codecs, ctx),\n this.#lowerUpdate(command.update, ctx),\n ]);\n return new UpdateManyWireCommand(command.collection, filter, update, command.upsert);\n }\n case 'deleteOne':\n return new DeleteOneWireCommand(\n command.collection,\n await lowerFilter(command.filter, this.#codecs, ctx),\n );\n case 'deleteMany':\n return new DeleteManyWireCommand(\n command.collection,\n await lowerFilter(command.filter, this.#codecs, ctx),\n );\n case 'findOneAndUpdate': {\n const [filter, update] = await Promise.all([\n lowerFilter(command.filter, this.#codecs, ctx),\n this.#lowerUpdate(command.update, ctx),\n ]);\n return new FindOneAndUpdateWireCommand(\n command.collection,\n filter,\n update,\n command.upsert,\n command.sort,\n command.returnDocument,\n );\n }\n case 'findOneAndDelete':\n return new FindOneAndDeleteWireCommand(\n command.collection,\n await lowerFilter(command.filter, this.#codecs, ctx),\n command.sort,\n );\n case 'aggregate':\n return new AggregateWireCommand(\n command.collection,\n await lowerPipeline(command.pipeline, this.#codecs, ctx),\n );\n case 'rawAggregate':\n return new AggregateWireCommand(command.collection, command.pipeline);\n case 'rawInsertOne':\n return new InsertOneWireCommand(command.collection, command.document);\n case 'rawInsertMany':\n return new InsertManyWireCommand(command.collection, command.documents);\n case 'rawUpdateOne':\n return new UpdateOneWireCommand(command.collection, command.filter, command.update);\n case 'rawUpdateMany':\n return new UpdateManyWireCommand(command.collection, command.filter, command.update);\n case 'rawDeleteOne':\n return new DeleteOneWireCommand(command.collection, command.filter);\n case 'rawDeleteMany':\n return new DeleteManyWireCommand(command.collection, command.filter);\n case 'rawFindOneAndUpdate':\n return new FindOneAndUpdateWireCommand(\n command.collection,\n command.filter,\n command.update,\n command.upsert,\n command.sort,\n command.returnDocument,\n );\n case 'rawFindOneAndDelete':\n return new FindOneAndDeleteWireCommand(command.collection, command.filter, command.sort);\n // v8 ignore next 4\n default: {\n const _exhaustive: never = command;\n throw new Error(`Unknown command kind: ${(_exhaustive as { kind: string }).kind}`);\n }\n }\n }\n}\n\nimport {\n mongoBooleanCodec,\n mongoDateCodec,\n mongoDoubleCodec,\n mongoInt32Codec,\n mongoObjectIdCodec,\n mongoStringCodec,\n mongoVectorCodec,\n} from './core/codecs';\n\nfunction defaultCodecRegistry(): MongoCodecRegistry {\n const registry = createMongoCodecRegistry();\n for (const codec of [\n mongoObjectIdCodec,\n mongoStringCodec,\n mongoDoubleCodec,\n mongoInt32Codec,\n mongoBooleanCodec,\n mongoDateCodec,\n mongoVectorCodec,\n ]) {\n registry.register(codec);\n }\n return registry;\n}\n\nexport function createMongoAdapter(codecs?: MongoCodecRegistry): MongoAdapter {\n return new MongoAdapterImpl(codecs ?? defaultCodecRegistry());\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@prisma-next/adapter-mongo",
|
|
3
|
-
"version": "0.5.0-dev.
|
|
3
|
+
"version": "0.5.0-dev.29",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"sideEffects": false,
|
|
6
6
|
"description": "MongoDB adapter for Prisma Next (lowers commands to wire format)",
|
|
7
7
|
"dependencies": {
|
|
8
8
|
"arktype": "^2.1.29",
|
|
9
9
|
"mongodb": "^6.16.0",
|
|
10
|
-
"@prisma-next/
|
|
11
|
-
"@prisma-next/
|
|
12
|
-
"@prisma-next/
|
|
13
|
-
"@prisma-next/
|
|
14
|
-
"@prisma-next/mongo-
|
|
15
|
-
"@prisma-next/mongo-
|
|
16
|
-
"@prisma-next/mongo-
|
|
17
|
-
"@prisma-next/mongo-
|
|
18
|
-
"@prisma-next/mongo-
|
|
19
|
-
"@prisma-next/mongo-
|
|
20
|
-
"@prisma-next/
|
|
21
|
-
"@prisma-next/
|
|
22
|
-
"@prisma-next/utils": "0.5.0-dev.
|
|
10
|
+
"@prisma-next/config": "0.5.0-dev.29",
|
|
11
|
+
"@prisma-next/contract": "0.5.0-dev.29",
|
|
12
|
+
"@prisma-next/framework-components": "0.5.0-dev.29",
|
|
13
|
+
"@prisma-next/target-mongo": "0.5.0-dev.29",
|
|
14
|
+
"@prisma-next/mongo-contract": "0.5.0-dev.29",
|
|
15
|
+
"@prisma-next/mongo-lowering": "0.5.0-dev.29",
|
|
16
|
+
"@prisma-next/mongo-codec": "0.5.0-dev.29",
|
|
17
|
+
"@prisma-next/mongo-schema-ir": "0.5.0-dev.29",
|
|
18
|
+
"@prisma-next/mongo-wire": "0.5.0-dev.29",
|
|
19
|
+
"@prisma-next/mongo-query-ast": "0.5.0-dev.29",
|
|
20
|
+
"@prisma-next/operations": "0.5.0-dev.29",
|
|
21
|
+
"@prisma-next/mongo-value": "0.5.0-dev.29",
|
|
22
|
+
"@prisma-next/utils": "0.5.0-dev.29"
|
|
23
23
|
},
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"mongodb-memory-server": "10.4.3",
|
|
26
26
|
"tsdown": "0.18.4",
|
|
27
27
|
"typescript": "5.9.3",
|
|
28
28
|
"vitest": "4.0.17",
|
|
29
|
-
"@prisma-next/driver-mongo": "0.5.0-dev.
|
|
30
|
-
"@prisma-next/mongo-contract-psl": "0.5.0-dev.
|
|
31
|
-
"@prisma-next/psl-parser": "0.5.0-dev.
|
|
29
|
+
"@prisma-next/driver-mongo": "0.5.0-dev.29",
|
|
30
|
+
"@prisma-next/mongo-contract-psl": "0.5.0-dev.29",
|
|
31
|
+
"@prisma-next/psl-parser": "0.5.0-dev.29",
|
|
32
32
|
"@prisma-next/test-utils": "0.0.1",
|
|
33
33
|
"@prisma-next/tsconfig": "0.0.0",
|
|
34
34
|
"@prisma-next/tsdown": "0.0.0"
|
package/src/lowering.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CodecCallContext } from '@prisma-next/framework-components/codec';
|
|
1
2
|
import type { MongoCodecRegistry } from '@prisma-next/mongo-codec';
|
|
2
3
|
import type {
|
|
3
4
|
MongoAggExpr,
|
|
@@ -139,17 +140,18 @@ export function lowerAggExpr(expr: MongoAggExpr): unknown {
|
|
|
139
140
|
|
|
140
141
|
export async function lowerFilter(
|
|
141
142
|
filter: MongoFilterExpr,
|
|
142
|
-
codecs
|
|
143
|
+
codecs: MongoCodecRegistry,
|
|
144
|
+
ctx: CodecCallContext,
|
|
143
145
|
): Promise<Document> {
|
|
144
146
|
switch (filter.kind) {
|
|
145
147
|
case 'field':
|
|
146
|
-
return { [filter.field]: { [filter.op]: await resolveValue(filter.value, codecs) } };
|
|
148
|
+
return { [filter.field]: { [filter.op]: await resolveValue(filter.value, codecs, ctx) } };
|
|
147
149
|
case 'and':
|
|
148
|
-
return { $and: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs))) };
|
|
150
|
+
return { $and: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };
|
|
149
151
|
case 'or':
|
|
150
|
-
return { $or: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs))) };
|
|
152
|
+
return { $or: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };
|
|
151
153
|
case 'not':
|
|
152
|
-
return { $nor: [await lowerFilter(filter.expr, codecs)] };
|
|
154
|
+
return { $nor: [await lowerFilter(filter.expr, codecs, ctx)] };
|
|
153
155
|
case 'exists':
|
|
154
156
|
return { [filter.field]: { $exists: filter.exists } };
|
|
155
157
|
case 'expr':
|
|
@@ -204,11 +206,12 @@ function lowerWindowField(wf: MongoWindowField): Record<string, unknown> {
|
|
|
204
206
|
|
|
205
207
|
export async function lowerStage(
|
|
206
208
|
stage: MongoPipelineStage,
|
|
207
|
-
codecs
|
|
209
|
+
codecs: MongoCodecRegistry,
|
|
210
|
+
ctx: CodecCallContext,
|
|
208
211
|
): Promise<Record<string, unknown>> {
|
|
209
212
|
switch (stage.kind) {
|
|
210
213
|
case 'match':
|
|
211
|
-
return { $match: await lowerFilter(stage.filter, codecs) };
|
|
214
|
+
return { $match: await lowerFilter(stage.filter, codecs, ctx) };
|
|
212
215
|
case 'project': {
|
|
213
216
|
const projection: Record<string, unknown> = {};
|
|
214
217
|
for (const [key, val] of Object.entries(stage.projection)) {
|
|
@@ -230,7 +233,9 @@ export async function lowerStage(
|
|
|
230
233
|
if (stage.localField !== undefined) lookup['localField'] = stage.localField;
|
|
231
234
|
if (stage.foreignField !== undefined) lookup['foreignField'] = stage.foreignField;
|
|
232
235
|
if (stage.pipeline) {
|
|
233
|
-
lookup['pipeline'] = await Promise.all(
|
|
236
|
+
lookup['pipeline'] = await Promise.all(
|
|
237
|
+
stage.pipeline.map((s) => lowerStage(s, codecs, ctx)),
|
|
238
|
+
);
|
|
234
239
|
}
|
|
235
240
|
if (stage.let_) {
|
|
236
241
|
lookup['let'] = lowerExprRecord(stage.let_);
|
|
@@ -271,7 +276,9 @@ export async function lowerStage(
|
|
|
271
276
|
case 'unionWith': {
|
|
272
277
|
const unionWith: Record<string, unknown> = { coll: stage.collection };
|
|
273
278
|
if (stage.pipeline) {
|
|
274
|
-
unionWith['pipeline'] = await Promise.all(
|
|
279
|
+
unionWith['pipeline'] = await Promise.all(
|
|
280
|
+
stage.pipeline.map((s) => lowerStage(s, codecs, ctx)),
|
|
281
|
+
);
|
|
275
282
|
}
|
|
276
283
|
return { $unionWith: unionWith };
|
|
277
284
|
}
|
|
@@ -301,7 +308,7 @@ export async function lowerStage(
|
|
|
301
308
|
if (stage.spherical !== undefined) geoNear['spherical'] = stage.spherical;
|
|
302
309
|
if (stage.maxDistance !== undefined) geoNear['maxDistance'] = stage.maxDistance;
|
|
303
310
|
if (stage.minDistance !== undefined) geoNear['minDistance'] = stage.minDistance;
|
|
304
|
-
if (stage.query) geoNear['query'] = await lowerFilter(stage.query, codecs);
|
|
311
|
+
if (stage.query) geoNear['query'] = await lowerFilter(stage.query, codecs, ctx);
|
|
305
312
|
if (stage.key !== undefined) geoNear['key'] = stage.key;
|
|
306
313
|
if (stage.distanceMultiplier !== undefined)
|
|
307
314
|
geoNear['distanceMultiplier'] = stage.distanceMultiplier;
|
|
@@ -311,7 +318,9 @@ export async function lowerStage(
|
|
|
311
318
|
case 'facet': {
|
|
312
319
|
const facetEntries = Object.entries(stage.facets);
|
|
313
320
|
const facetPipelines = await Promise.all(
|
|
314
|
-
facetEntries.map(([, pipeline]) =>
|
|
321
|
+
facetEntries.map(([, pipeline]) =>
|
|
322
|
+
Promise.all(pipeline.map((s) => lowerStage(s, codecs, ctx))),
|
|
323
|
+
),
|
|
315
324
|
);
|
|
316
325
|
const facet: Record<string, unknown> = {};
|
|
317
326
|
for (let i = 0; i < facetEntries.length; i++) {
|
|
@@ -336,6 +345,7 @@ export async function lowerStage(
|
|
|
336
345
|
graphLookup['restrictSearchWithMatch'] = await lowerFilter(
|
|
337
346
|
stage.restrictSearchWithMatch,
|
|
338
347
|
codecs,
|
|
348
|
+
ctx,
|
|
339
349
|
);
|
|
340
350
|
return { $graphLookup: graphLookup };
|
|
341
351
|
}
|
|
@@ -344,7 +354,7 @@ export async function lowerStage(
|
|
|
344
354
|
if (stage.on !== undefined) merge['on'] = stage.on;
|
|
345
355
|
if (stage.whenMatched !== undefined) {
|
|
346
356
|
merge['whenMatched'] = Array.isArray(stage.whenMatched)
|
|
347
|
-
? await Promise.all(stage.whenMatched.map((s) => lowerStage(s, codecs)))
|
|
357
|
+
? await Promise.all(stage.whenMatched.map((s) => lowerStage(s, codecs, ctx)))
|
|
348
358
|
: stage.whenMatched;
|
|
349
359
|
}
|
|
350
360
|
if (stage.whenNotMatched !== undefined) merge['whenNotMatched'] = stage.whenNotMatched;
|
|
@@ -414,7 +424,8 @@ export async function lowerStage(
|
|
|
414
424
|
|
|
415
425
|
export async function lowerPipeline(
|
|
416
426
|
stages: ReadonlyArray<MongoPipelineStage>,
|
|
417
|
-
codecs
|
|
427
|
+
codecs: MongoCodecRegistry,
|
|
428
|
+
ctx: CodecCallContext,
|
|
418
429
|
): Promise<Array<Record<string, unknown>>> {
|
|
419
|
-
return Promise.all(stages.map((s) => lowerStage(s, codecs)));
|
|
430
|
+
return Promise.all(stages.map((s) => lowerStage(s, codecs, ctx)));
|
|
420
431
|
}
|
package/src/mongo-adapter.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import type { CodecCallContext } from '@prisma-next/framework-components/codec';
|
|
1
2
|
import { createMongoCodecRegistry, type MongoCodecRegistry } from '@prisma-next/mongo-codec';
|
|
2
3
|
import type { MongoAdapter } from '@prisma-next/mongo-lowering';
|
|
3
4
|
import type {
|
|
@@ -28,15 +29,17 @@ function isUpdatePipeline(
|
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
class MongoAdapterImpl implements MongoAdapter {
|
|
31
|
-
readonly #codecs: MongoCodecRegistry
|
|
32
|
+
readonly #codecs: MongoCodecRegistry;
|
|
32
33
|
|
|
33
|
-
constructor(codecs
|
|
34
|
+
constructor(codecs: MongoCodecRegistry) {
|
|
34
35
|
this.#codecs = codecs;
|
|
35
36
|
}
|
|
36
37
|
|
|
37
|
-
async #resolveDocument(expr: MongoExpr): Promise<Document> {
|
|
38
|
+
async #resolveDocument(expr: MongoExpr, ctx: CodecCallContext): Promise<Document> {
|
|
38
39
|
const entries = Object.entries(expr);
|
|
39
|
-
const resolved = await Promise.all(
|
|
40
|
+
const resolved = await Promise.all(
|
|
41
|
+
entries.map(([, val]) => resolveValue(val, this.#codecs, ctx)),
|
|
42
|
+
);
|
|
40
43
|
const result: Record<string, unknown> = {};
|
|
41
44
|
for (let i = 0; i < entries.length; i++) {
|
|
42
45
|
const entry = entries[i];
|
|
@@ -47,54 +50,57 @@ class MongoAdapterImpl implements MongoAdapter {
|
|
|
47
50
|
return result;
|
|
48
51
|
}
|
|
49
52
|
|
|
50
|
-
async #lowerUpdate(
|
|
53
|
+
async #lowerUpdate(
|
|
54
|
+
update: MongoUpdateSpec,
|
|
55
|
+
ctx: CodecCallContext,
|
|
56
|
+
): Promise<Document | ReadonlyArray<Document>> {
|
|
51
57
|
if (isUpdatePipeline(update)) {
|
|
52
|
-
return Promise.all(update.map((stage) => lowerStage(stage, this.#codecs)));
|
|
58
|
+
return Promise.all(update.map((stage) => lowerStage(stage, this.#codecs, ctx)));
|
|
53
59
|
}
|
|
54
|
-
return this.#resolveDocument(update);
|
|
60
|
+
return this.#resolveDocument(update, ctx);
|
|
55
61
|
}
|
|
56
62
|
|
|
57
|
-
async lower(plan: MongoQueryPlan): Promise<AnyMongoWireCommand> {
|
|
63
|
+
async lower(plan: MongoQueryPlan, ctx: CodecCallContext): Promise<AnyMongoWireCommand> {
|
|
58
64
|
const { command } = plan;
|
|
59
65
|
switch (command.kind) {
|
|
60
66
|
case 'insertOne':
|
|
61
67
|
return new InsertOneWireCommand(
|
|
62
68
|
command.collection,
|
|
63
|
-
await this.#resolveDocument(command.document),
|
|
69
|
+
await this.#resolveDocument(command.document, ctx),
|
|
64
70
|
);
|
|
65
71
|
case 'updateOne': {
|
|
66
72
|
const [filter, update] = await Promise.all([
|
|
67
|
-
lowerFilter(command.filter, this.#codecs),
|
|
68
|
-
this.#lowerUpdate(command.update),
|
|
73
|
+
lowerFilter(command.filter, this.#codecs, ctx),
|
|
74
|
+
this.#lowerUpdate(command.update, ctx),
|
|
69
75
|
]);
|
|
70
76
|
return new UpdateOneWireCommand(command.collection, filter, update, command.upsert);
|
|
71
77
|
}
|
|
72
78
|
case 'insertMany':
|
|
73
79
|
return new InsertManyWireCommand(
|
|
74
80
|
command.collection,
|
|
75
|
-
await Promise.all(command.documents.map((doc) => this.#resolveDocument(doc))),
|
|
81
|
+
await Promise.all(command.documents.map((doc) => this.#resolveDocument(doc, ctx))),
|
|
76
82
|
);
|
|
77
83
|
case 'updateMany': {
|
|
78
84
|
const [filter, update] = await Promise.all([
|
|
79
|
-
lowerFilter(command.filter, this.#codecs),
|
|
80
|
-
this.#lowerUpdate(command.update),
|
|
85
|
+
lowerFilter(command.filter, this.#codecs, ctx),
|
|
86
|
+
this.#lowerUpdate(command.update, ctx),
|
|
81
87
|
]);
|
|
82
88
|
return new UpdateManyWireCommand(command.collection, filter, update, command.upsert);
|
|
83
89
|
}
|
|
84
90
|
case 'deleteOne':
|
|
85
91
|
return new DeleteOneWireCommand(
|
|
86
92
|
command.collection,
|
|
87
|
-
await lowerFilter(command.filter, this.#codecs),
|
|
93
|
+
await lowerFilter(command.filter, this.#codecs, ctx),
|
|
88
94
|
);
|
|
89
95
|
case 'deleteMany':
|
|
90
96
|
return new DeleteManyWireCommand(
|
|
91
97
|
command.collection,
|
|
92
|
-
await lowerFilter(command.filter, this.#codecs),
|
|
98
|
+
await lowerFilter(command.filter, this.#codecs, ctx),
|
|
93
99
|
);
|
|
94
100
|
case 'findOneAndUpdate': {
|
|
95
101
|
const [filter, update] = await Promise.all([
|
|
96
|
-
lowerFilter(command.filter, this.#codecs),
|
|
97
|
-
this.#lowerUpdate(command.update),
|
|
102
|
+
lowerFilter(command.filter, this.#codecs, ctx),
|
|
103
|
+
this.#lowerUpdate(command.update, ctx),
|
|
98
104
|
]);
|
|
99
105
|
return new FindOneAndUpdateWireCommand(
|
|
100
106
|
command.collection,
|
|
@@ -108,13 +114,13 @@ class MongoAdapterImpl implements MongoAdapter {
|
|
|
108
114
|
case 'findOneAndDelete':
|
|
109
115
|
return new FindOneAndDeleteWireCommand(
|
|
110
116
|
command.collection,
|
|
111
|
-
await lowerFilter(command.filter, this.#codecs),
|
|
117
|
+
await lowerFilter(command.filter, this.#codecs, ctx),
|
|
112
118
|
command.sort,
|
|
113
119
|
);
|
|
114
120
|
case 'aggregate':
|
|
115
121
|
return new AggregateWireCommand(
|
|
116
122
|
command.collection,
|
|
117
|
-
await lowerPipeline(command.pipeline, this.#codecs),
|
|
123
|
+
await lowerPipeline(command.pipeline, this.#codecs, ctx),
|
|
118
124
|
);
|
|
119
125
|
case 'rawAggregate':
|
|
120
126
|
return new AggregateWireCommand(command.collection, command.pipeline);
|
package/src/resolve-value.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import type { CodecCallContext } from '@prisma-next/framework-components/codec';
|
|
2
|
+
import {
|
|
3
|
+
checkAborted,
|
|
4
|
+
raceAgainstAbort,
|
|
5
|
+
runtimeError,
|
|
6
|
+
} from '@prisma-next/framework-components/runtime';
|
|
2
7
|
import type { MongoCodecRegistry } from '@prisma-next/mongo-codec';
|
|
3
8
|
import type { MongoValue } from '@prisma-next/mongo-value';
|
|
4
9
|
import { MongoParamRef } from '@prisma-next/mongo-value';
|
|
@@ -16,17 +21,45 @@ import { MongoParamRef } from '@prisma-next/mongo-value';
|
|
|
16
21
|
* (mirroring SQL's `wrapEncodeFailure` shape) with `{ label, codec }` details
|
|
17
22
|
* and the original error attached on `cause`. An already-wrapped envelope is
|
|
18
23
|
* re-thrown verbatim so nested resolvers don't double-wrap.
|
|
24
|
+
*
|
|
25
|
+
* `ctx: CodecCallContext` is forwarded verbatim to every
|
|
26
|
+
* `codec.encode(value, ctx)` call. The same `ctx` reference is also passed
|
|
27
|
+
* to nested `resolveValue` invocations so codec authors observe **signal
|
|
28
|
+
* identity** across the entire recursive walk for one `runtime.execute()`.
|
|
29
|
+
*
|
|
30
|
+
* Abort observation (only when `ctx.signal` is provided):
|
|
31
|
+
*
|
|
32
|
+
* - **Already-aborted at entry** — every recursive call pre-checks
|
|
33
|
+
* `ctx.signal.aborted` and short-circuits with
|
|
34
|
+
* `RUNTIME.ABORTED { phase: 'encode' }` before any codec is invoked.
|
|
35
|
+
* - **Mid-flight abort** — each per-level `Promise.all` races against the
|
|
36
|
+
* signal via `raceAgainstAbort`. The runtime returns
|
|
37
|
+
* `RUNTIME.ABORTED { phase: 'encode' }` promptly even if codec bodies
|
|
38
|
+
* ignore the signal; in-flight bodies run to completion in the background
|
|
39
|
+
* (cooperative cancellation, see ADR 204).
|
|
40
|
+
* - `RUNTIME.ENCODE_FAILED` envelopes thrown by a codec body before the
|
|
41
|
+
* runtime sees the abort pass through unchanged (AC-ERR4).
|
|
19
42
|
*/
|
|
20
43
|
export async function resolveValue(
|
|
21
44
|
value: MongoValue,
|
|
22
|
-
codecs
|
|
45
|
+
codecs: MongoCodecRegistry,
|
|
46
|
+
ctx: CodecCallContext,
|
|
23
47
|
): Promise<unknown> {
|
|
48
|
+
checkAborted(ctx, 'encode');
|
|
49
|
+
const signal = ctx.signal;
|
|
50
|
+
|
|
24
51
|
if (value instanceof MongoParamRef) {
|
|
25
|
-
if (value.codecId
|
|
52
|
+
if (value.codecId) {
|
|
26
53
|
const codec = codecs.get(value.codecId);
|
|
27
54
|
if (codec?.encode) {
|
|
28
55
|
try {
|
|
29
|
-
|
|
56
|
+
// Race even leaf scalar encodes against the signal so a leaf
|
|
57
|
+
// `MongoParamRef` (e.g. a simple field filter, or any leaf reached
|
|
58
|
+
// from `MongoAdapterImpl.#resolveDocument()` outside an enclosing
|
|
59
|
+
// `Promise.all`) surfaces `RUNTIME.ABORTED` promptly instead of
|
|
60
|
+
// blocking on a slow codec body.
|
|
61
|
+
const encoded = codec.encode(value.value, ctx);
|
|
62
|
+
return await raceAgainstAbort(encoded, signal, 'encode');
|
|
30
63
|
} catch (error) {
|
|
31
64
|
wrapEncodeFailure(error, value, codec.id);
|
|
32
65
|
}
|
|
@@ -41,10 +74,12 @@ export async function resolveValue(
|
|
|
41
74
|
return value;
|
|
42
75
|
}
|
|
43
76
|
if (Array.isArray(value)) {
|
|
44
|
-
|
|
77
|
+
const tasks = Promise.all(value.map((v) => resolveValue(v, codecs, ctx)));
|
|
78
|
+
return raceAgainstAbort(tasks, signal, 'encode');
|
|
45
79
|
}
|
|
46
80
|
const entries = Object.entries(value);
|
|
47
|
-
const
|
|
81
|
+
const all = Promise.all(entries.map(([, val]) => resolveValue(val, codecs, ctx)));
|
|
82
|
+
const resolved = await raceAgainstAbort(all, signal, 'encode');
|
|
48
83
|
const result: Record<string, unknown> = {};
|
|
49
84
|
for (let i = 0; i < entries.length; i++) {
|
|
50
85
|
const entry = entries[i];
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mongo-adapter-DVK2I5Hs.mjs","names":["result: Record<string, unknown>","entries: Array<[string, unknown]>","aggExprLoweringVisitor: MongoAggExprVisitor<unknown>","loweredArgs: unknown","vars: Record<string, unknown>","_exhaustive: never","result: Record<string, unknown>","projection: Record<string, unknown>","lookup: Record<string, unknown>","unwind: Record<string, unknown>","group: Record<string, unknown>","unionWith: Record<string, unknown>","bucket: Record<string, unknown>","bucketAuto: Record<string, unknown>","geoNear: Record<string, unknown>","facet: Record<string, unknown>","graphLookup: Record<string, unknown>","merge: Record<string, unknown>","swf: Record<string, unknown>","output: Record<string, unknown>","densify: Record<string, unknown>","fill: Record<string, unknown>","entry: Record<string, unknown>","search: Record<string, unknown>","searchMeta: Record<string, unknown>","vs: Record<string, unknown>","#codecs","#resolveDocument","result: Record<string, unknown>","#lowerUpdate","_exhaustive: never"],"sources":["../src/core/codec-ids.ts","../src/resolve-value.ts","../src/lowering.ts","../src/core/codecs.ts","../src/mongo-adapter.ts"],"sourcesContent":["export const MONGO_OBJECTID_CODEC_ID = 'mongo/objectId@1' as const;\nexport const MONGO_STRING_CODEC_ID = 'mongo/string@1' as const;\nexport const MONGO_DOUBLE_CODEC_ID = 'mongo/double@1' as const;\nexport const MONGO_INT32_CODEC_ID = 'mongo/int32@1' as const;\nexport const MONGO_BOOLEAN_CODEC_ID = 'mongo/bool@1' as const;\nexport const MONGO_DATE_CODEC_ID = 'mongo/date@1' as const;\nexport const MONGO_VECTOR_CODEC_ID = 'mongo/vector@1' as const;\n","import { runtimeError } from '@prisma-next/framework-components/runtime';\nimport type { MongoCodecRegistry } from '@prisma-next/mongo-codec';\nimport type { MongoValue } from '@prisma-next/mongo-value';\nimport { MongoParamRef } from '@prisma-next/mongo-value';\n\n/**\n * Resolves a `MongoValue` (which may contain `MongoParamRef` leaves) into the\n * driver-ready wire shape. When a leaf has a `codecId` and the registry has a\n * codec for it, the codec's async `encode` is awaited so codecs may perform\n * asynchronous work (e.g. lookups, key derivations).\n *\n * Object/array nodes dispatch their child resolutions concurrently via\n * `Promise.all` so independent leaves encode in parallel.\n *\n * Codec encode failures are wrapped in a `RUNTIME.ENCODE_FAILED` envelope\n * (mirroring SQL's `wrapEncodeFailure` shape) with `{ label, codec }` details\n * and the original error attached on `cause`. An already-wrapped envelope is\n * re-thrown verbatim so nested resolvers don't double-wrap.\n */\nexport async function resolveValue(\n value: MongoValue,\n codecs?: MongoCodecRegistry,\n): Promise<unknown> {\n if (value instanceof MongoParamRef) {\n if (value.codecId && codecs) {\n const codec = codecs.get(value.codecId);\n if (codec?.encode) {\n try {\n return await codec.encode(value.value);\n } catch (error) {\n wrapEncodeFailure(error, value, codec.id);\n }\n }\n }\n return value.value;\n }\n if (value === null || typeof value !== 'object') {\n return value;\n }\n if (value instanceof Date) {\n return value;\n }\n if (Array.isArray(value)) {\n return Promise.all(value.map((v) => resolveValue(v, codecs)));\n }\n const entries = Object.entries(value);\n const resolved = await Promise.all(entries.map(([, val]) => resolveValue(val, codecs)));\n const result: Record<string, unknown> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry) {\n result[entry[0]] = resolved[i];\n }\n }\n return result;\n}\n\nfunction paramRefLabel(ref: MongoParamRef, codecId: string): string {\n return ref.name ?? codecId;\n}\n\nfunction isAlreadyEncodeFailure(error: unknown): boolean {\n return (\n error instanceof Error &&\n 'code' in error &&\n (error as Error & { code?: unknown }).code === 'RUNTIME.ENCODE_FAILED'\n );\n}\n\nfunction wrapEncodeFailure(error: unknown, ref: MongoParamRef, codecId: string): never {\n if (isAlreadyEncodeFailure(error)) {\n throw error;\n }\n const label = paramRefLabel(ref, codecId);\n const message = error instanceof Error ? error.message : String(error);\n const wrapped = runtimeError(\n 'RUNTIME.ENCODE_FAILED',\n `Failed to encode parameter ${label} with codec '${codecId}': ${message}`,\n { label, codec: codecId },\n );\n wrapped.cause = error;\n throw wrapped;\n}\n","import type { MongoCodecRegistry } from '@prisma-next/mongo-codec';\nimport type {\n MongoAggExpr,\n MongoAggExprVisitor,\n MongoFilterExpr,\n MongoGroupId,\n MongoPipelineStage,\n MongoProjectionValue,\n MongoWindowField,\n} from '@prisma-next/mongo-query-ast/execution';\nimport { isExprArray, isRecordArgs } from '@prisma-next/mongo-query-ast/execution';\nimport type { Document } from '@prisma-next/mongo-value';\nimport { resolveValue } from './resolve-value';\n\n// Biome flags `{ then: ... }` as a thenable object (noThenProperty). Build via Object.fromEntries to avoid.\nconst THEN_KEY = 'then';\n\nfunction condBranch(\n caseOrIf: MongoAggExpr,\n thenExpr: MongoAggExpr,\n elseExpr?: MongoAggExpr,\n): Record<string, unknown> {\n const entries: Array<[string, unknown]> = [\n [elseExpr ? 'if' : 'case', lowerAggExpr(caseOrIf)],\n [THEN_KEY, lowerAggExpr(thenExpr)],\n ];\n if (elseExpr) {\n entries.push(['else', lowerAggExpr(elseExpr)]);\n }\n return Object.fromEntries(entries);\n}\n\nconst aggExprLoweringVisitor: MongoAggExprVisitor<unknown> = {\n fieldRef(expr) {\n return `$${expr.path}`;\n },\n\n literal(expr) {\n return needsLiteralWrap(expr.value) ? { $literal: expr.value } : expr.value;\n },\n\n operator(expr) {\n const { args } = expr;\n let loweredArgs: unknown;\n if (isExprArray(args)) {\n loweredArgs = args.map((a) => lowerAggExpr(a));\n } else if (isRecordArgs(args)) {\n loweredArgs = lowerExprRecord(args);\n } else {\n loweredArgs = lowerAggExpr(args);\n }\n return { [expr.op]: loweredArgs };\n },\n\n accumulator(expr) {\n if (expr.arg === null) {\n return { [expr.op]: {} };\n }\n if (isRecordArgs(expr.arg)) {\n return { [expr.op]: lowerExprRecord(expr.arg) };\n }\n return { [expr.op]: lowerAggExpr(expr.arg) };\n },\n\n cond(expr) {\n return { $cond: condBranch(expr.condition, expr.then_, expr.else_) };\n },\n\n switch_(expr) {\n return {\n $switch: {\n branches: expr.branches.map((b) => condBranch(b.case_, b.then_)),\n default: lowerAggExpr(expr.default_),\n },\n };\n },\n\n filter(expr) {\n return {\n $filter: {\n input: lowerAggExpr(expr.input),\n cond: lowerAggExpr(expr.cond),\n as: expr.as,\n },\n };\n },\n\n map(expr) {\n return {\n $map: {\n input: lowerAggExpr(expr.input),\n in: lowerAggExpr(expr.in_),\n as: expr.as,\n },\n };\n },\n\n reduce(expr) {\n return {\n $reduce: {\n input: lowerAggExpr(expr.input),\n initialValue: lowerAggExpr(expr.initialValue),\n in: lowerAggExpr(expr.in_),\n },\n };\n },\n\n let_(expr) {\n const vars: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(expr.vars)) {\n vars[key] = lowerAggExpr(val);\n }\n return { $let: { vars, in: lowerAggExpr(expr.in_) } };\n },\n\n mergeObjects(expr) {\n return { $mergeObjects: expr.exprs.map((e) => lowerAggExpr(e)) };\n },\n};\n\nfunction needsLiteralWrap(value: unknown): boolean {\n if (typeof value === 'string' && value.startsWith('$')) {\n return true;\n }\n if (Array.isArray(value)) {\n return value.some((v) => needsLiteralWrap(v));\n }\n if (value !== null && typeof value === 'object') {\n return Object.entries(value as Record<string, unknown>).some(\n ([k, v]) => k.startsWith('$') || needsLiteralWrap(v),\n );\n }\n return false;\n}\n\nexport function lowerAggExpr(expr: MongoAggExpr): unknown {\n return expr.accept(aggExprLoweringVisitor);\n}\n\nexport async function lowerFilter(\n filter: MongoFilterExpr,\n codecs?: MongoCodecRegistry,\n): Promise<Document> {\n switch (filter.kind) {\n case 'field':\n return { [filter.field]: { [filter.op]: await resolveValue(filter.value, codecs) } };\n case 'and':\n return { $and: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs))) };\n case 'or':\n return { $or: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs))) };\n case 'not':\n return { $nor: [await lowerFilter(filter.expr, codecs)] };\n case 'exists':\n return { [filter.field]: { $exists: filter.exists } };\n case 'expr':\n return { $expr: lowerAggExpr(filter.aggExpr) };\n default: {\n const _exhaustive: never = filter;\n throw new Error(`Unhandled filter kind: ${(_exhaustive as MongoFilterExpr).kind}`);\n }\n }\n}\n\nfunction isAggExprNode(value: object): value is MongoAggExpr {\n return 'accept' in value && typeof value.accept === 'function';\n}\n\nfunction lowerGroupId(groupId: MongoGroupId): unknown {\n if (groupId === null) return null;\n if (isAggExprNode(groupId)) return lowerAggExpr(groupId);\n return lowerExprRecord(groupId);\n}\n\nfunction lowerExprRecord(\n fields: Readonly<Record<string, MongoAggExpr | ReadonlyArray<MongoAggExpr>>>,\n): Record<string, unknown> {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(fields)) {\n if (Array.isArray(val)) {\n result[key] = val.map((v: MongoAggExpr) => lowerAggExpr(v));\n } else {\n result[key] = lowerAggExpr(val as MongoAggExpr);\n }\n }\n return result;\n}\n\nfunction lowerProjectionValue(value: MongoProjectionValue): unknown {\n if (typeof value === 'number') return value;\n return lowerAggExpr(value);\n}\n\nfunction lowerWindowField(wf: MongoWindowField): Record<string, unknown> {\n const lowered = lowerAggExpr(wf.operator);\n if (typeof lowered !== 'object' || lowered === null) {\n throw new Error('Window field operator must lower to an object');\n }\n const result: Record<string, unknown> = { ...lowered };\n if (wf.window) {\n result['window'] = { ...wf.window };\n }\n return result;\n}\n\nexport async function lowerStage(\n stage: MongoPipelineStage,\n codecs?: MongoCodecRegistry,\n): Promise<Record<string, unknown>> {\n switch (stage.kind) {\n case 'match':\n return { $match: await lowerFilter(stage.filter, codecs) };\n case 'project': {\n const projection: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(stage.projection)) {\n projection[key] = lowerProjectionValue(val);\n }\n return { $project: projection };\n }\n case 'sort':\n return { $sort: { ...stage.sort } };\n case 'limit':\n return { $limit: stage.limit };\n case 'skip':\n return { $skip: stage.skip };\n case 'lookup': {\n const lookup: Record<string, unknown> = {\n from: stage.from,\n as: stage.as,\n };\n if (stage.localField !== undefined) lookup['localField'] = stage.localField;\n if (stage.foreignField !== undefined) lookup['foreignField'] = stage.foreignField;\n if (stage.pipeline) {\n lookup['pipeline'] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs)));\n }\n if (stage.let_) {\n lookup['let'] = lowerExprRecord(stage.let_);\n }\n return { $lookup: lookup };\n }\n case 'unwind': {\n const unwind: Record<string, unknown> = {\n path: stage.path,\n preserveNullAndEmptyArrays: stage.preserveNullAndEmptyArrays,\n };\n if (stage.includeArrayIndex !== undefined) {\n unwind['includeArrayIndex'] = stage.includeArrayIndex;\n }\n return { $unwind: unwind };\n }\n case 'group': {\n const group: Record<string, unknown> = { _id: lowerGroupId(stage.groupId) };\n for (const [key, acc] of Object.entries(stage.accumulators)) {\n group[key] = lowerAggExpr(acc);\n }\n return { $group: group };\n }\n case 'addFields':\n return { $addFields: lowerExprRecord(stage.fields) };\n case 'replaceRoot':\n return { $replaceRoot: { newRoot: lowerAggExpr(stage.newRoot) } };\n case 'count':\n return { $count: stage.field };\n case 'sortByCount':\n return { $sortByCount: lowerAggExpr(stage.expr) };\n case 'sample':\n return { $sample: { size: stage.size } };\n case 'redact':\n return { $redact: lowerAggExpr(stage.expr) };\n case 'out':\n return { $out: stage.db ? { db: stage.db, coll: stage.collection } : stage.collection };\n case 'unionWith': {\n const unionWith: Record<string, unknown> = { coll: stage.collection };\n if (stage.pipeline) {\n unionWith['pipeline'] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs)));\n }\n return { $unionWith: unionWith };\n }\n case 'bucket': {\n const bucket: Record<string, unknown> = {\n groupBy: lowerAggExpr(stage.groupBy),\n boundaries: [...stage.boundaries],\n };\n if (stage.default_ !== undefined) bucket['default'] = stage.default_;\n if (stage.output) bucket['output'] = lowerExprRecord(stage.output);\n return { $bucket: bucket };\n }\n case 'bucketAuto': {\n const bucketAuto: Record<string, unknown> = {\n groupBy: lowerAggExpr(stage.groupBy),\n buckets: stage.buckets,\n };\n if (stage.output) bucketAuto['output'] = lowerExprRecord(stage.output);\n if (stage.granularity !== undefined) bucketAuto['granularity'] = stage.granularity;\n return { $bucketAuto: bucketAuto };\n }\n case 'geoNear': {\n const geoNear: Record<string, unknown> = {\n near: stage.near,\n distanceField: stage.distanceField,\n };\n if (stage.spherical !== undefined) geoNear['spherical'] = stage.spherical;\n if (stage.maxDistance !== undefined) geoNear['maxDistance'] = stage.maxDistance;\n if (stage.minDistance !== undefined) geoNear['minDistance'] = stage.minDistance;\n if (stage.query) geoNear['query'] = await lowerFilter(stage.query, codecs);\n if (stage.key !== undefined) geoNear['key'] = stage.key;\n if (stage.distanceMultiplier !== undefined)\n geoNear['distanceMultiplier'] = stage.distanceMultiplier;\n if (stage.includeLocs !== undefined) geoNear['includeLocs'] = stage.includeLocs;\n return { $geoNear: geoNear };\n }\n case 'facet': {\n const facetEntries = Object.entries(stage.facets);\n const facetPipelines = await Promise.all(\n facetEntries.map(([, pipeline]) => Promise.all(pipeline.map((s) => lowerStage(s, codecs)))),\n );\n const facet: Record<string, unknown> = {};\n for (let i = 0; i < facetEntries.length; i++) {\n const entry = facetEntries[i];\n if (entry) {\n facet[entry[0]] = facetPipelines[i];\n }\n }\n return { $facet: facet };\n }\n case 'graphLookup': {\n const graphLookup: Record<string, unknown> = {\n from: stage.from,\n startWith: lowerAggExpr(stage.startWith),\n connectFromField: stage.connectFromField,\n connectToField: stage.connectToField,\n as: stage.as,\n };\n if (stage.maxDepth !== undefined) graphLookup['maxDepth'] = stage.maxDepth;\n if (stage.depthField !== undefined) graphLookup['depthField'] = stage.depthField;\n if (stage.restrictSearchWithMatch)\n graphLookup['restrictSearchWithMatch'] = await lowerFilter(\n stage.restrictSearchWithMatch,\n codecs,\n );\n return { $graphLookup: graphLookup };\n }\n case 'merge': {\n const merge: Record<string, unknown> = { into: stage.into };\n if (stage.on !== undefined) merge['on'] = stage.on;\n if (stage.whenMatched !== undefined) {\n merge['whenMatched'] = Array.isArray(stage.whenMatched)\n ? await Promise.all(stage.whenMatched.map((s) => lowerStage(s, codecs)))\n : stage.whenMatched;\n }\n if (stage.whenNotMatched !== undefined) merge['whenNotMatched'] = stage.whenNotMatched;\n return { $merge: merge };\n }\n case 'setWindowFields': {\n const swf: Record<string, unknown> = {};\n if (stage.partitionBy) swf['partitionBy'] = lowerAggExpr(stage.partitionBy);\n if (stage.sortBy) swf['sortBy'] = { ...stage.sortBy };\n const output: Record<string, unknown> = {};\n for (const [key, wf] of Object.entries(stage.output)) {\n output[key] = lowerWindowField(wf);\n }\n swf['output'] = output;\n return { $setWindowFields: swf };\n }\n case 'densify': {\n const densify: Record<string, unknown> = {\n field: stage.field,\n range: { ...stage.range },\n };\n if (stage.partitionByFields) densify['partitionByFields'] = [...stage.partitionByFields];\n return { $densify: densify };\n }\n case 'fill': {\n const fill: Record<string, unknown> = {};\n if (stage.partitionBy) fill['partitionBy'] = lowerAggExpr(stage.partitionBy);\n if (stage.partitionByFields) fill['partitionByFields'] = [...stage.partitionByFields];\n if (stage.sortBy) fill['sortBy'] = { ...stage.sortBy };\n const output: Record<string, unknown> = {};\n for (const [key, fo] of Object.entries(stage.output)) {\n const entry: Record<string, unknown> = {};\n if (fo.method !== undefined) entry['method'] = fo.method;\n if (fo.value !== undefined) entry['value'] = lowerAggExpr(fo.value);\n output[key] = entry;\n }\n fill['output'] = output;\n return { $fill: fill };\n }\n case 'search': {\n const search: Record<string, unknown> = { ...stage.config };\n if (stage.index !== undefined) search['index'] = stage.index;\n return { $search: search };\n }\n case 'searchMeta': {\n const searchMeta: Record<string, unknown> = { ...stage.config };\n if (stage.index !== undefined) searchMeta['index'] = stage.index;\n return { $searchMeta: searchMeta };\n }\n case 'vectorSearch': {\n const vs: Record<string, unknown> = {\n index: stage.index,\n path: stage.path,\n queryVector: [...stage.queryVector],\n numCandidates: stage.numCandidates,\n limit: stage.limit,\n };\n if (stage.filter) vs['filter'] = { ...stage.filter };\n return { $vectorSearch: vs };\n }\n default: {\n const _exhaustive: never = stage;\n throw new Error(`Unhandled stage kind: ${(_exhaustive as MongoPipelineStage).kind}`);\n }\n }\n}\n\nexport async function lowerPipeline(\n stages: ReadonlyArray<MongoPipelineStage>,\n codecs?: MongoCodecRegistry,\n): Promise<Array<Record<string, unknown>>> {\n return Promise.all(stages.map((s) => lowerStage(s, codecs)));\n}\n","import { mongoCodec } from '@prisma-next/mongo-codec';\nimport { ObjectId } from 'mongodb';\nimport {\n MONGO_BOOLEAN_CODEC_ID,\n MONGO_DATE_CODEC_ID,\n MONGO_DOUBLE_CODEC_ID,\n MONGO_INT32_CODEC_ID,\n MONGO_OBJECTID_CODEC_ID,\n MONGO_STRING_CODEC_ID,\n MONGO_VECTOR_CODEC_ID,\n} from './codec-ids';\n\nexport const mongoObjectIdCodec = mongoCodec({\n typeId: MONGO_OBJECTID_CODEC_ID,\n targetTypes: ['objectId'],\n traits: ['equality'],\n decode: (wire: ObjectId) => wire.toHexString(),\n encode: (value: string) => new ObjectId(value),\n});\n\nexport const mongoStringCodec = mongoCodec({\n typeId: MONGO_STRING_CODEC_ID,\n targetTypes: ['string'],\n traits: ['equality', 'order', 'textual'],\n decode: (wire: string) => wire,\n encode: (value: string) => value,\n});\n\nexport const mongoDoubleCodec = mongoCodec({\n typeId: MONGO_DOUBLE_CODEC_ID,\n targetTypes: ['double'],\n traits: ['equality', 'order', 'numeric'],\n decode: (wire: number) => wire,\n encode: (value: number) => value,\n});\n\nexport const mongoInt32Codec = mongoCodec({\n typeId: MONGO_INT32_CODEC_ID,\n targetTypes: ['int'],\n traits: ['equality', 'order', 'numeric'],\n decode: (wire: number) => wire,\n encode: (value: number) => value,\n});\n\nexport const mongoBooleanCodec = mongoCodec({\n typeId: MONGO_BOOLEAN_CODEC_ID,\n targetTypes: ['bool'],\n traits: ['equality', 'boolean'],\n decode: (wire: boolean) => wire,\n encode: (value: boolean) => value,\n});\n\nexport const mongoDateCodec = mongoCodec({\n typeId: MONGO_DATE_CODEC_ID,\n targetTypes: ['date'],\n traits: ['equality', 'order'],\n decode: (wire: Date) => wire,\n encode: (value: Date) => value,\n encodeJson: (value: Date) => value.toISOString(),\n decodeJson: (json) => {\n if (typeof json !== 'string') throw new Error('expected ISO date string');\n return new Date(json);\n },\n});\n\nexport const mongoVectorCodec = mongoCodec({\n typeId: MONGO_VECTOR_CODEC_ID,\n targetTypes: ['vector'],\n traits: ['equality'],\n decode: (wire: readonly number[]) => wire,\n encode: (value: readonly number[]) => value,\n renderOutputType: (typeParams) => {\n const length = typeParams['length'];\n if (length === undefined) return undefined;\n if (typeof length !== 'number' || !Number.isFinite(length) || !Number.isInteger(length)) {\n throw new Error('renderOutputType: expected positive integer \"length\" for Vector');\n }\n return `Vector<${length}>`;\n },\n});\n","import { createMongoCodecRegistry, type MongoCodecRegistry } from '@prisma-next/mongo-codec';\nimport type { MongoAdapter } from '@prisma-next/mongo-lowering';\nimport type {\n MongoQueryPlan,\n MongoUpdatePipelineStage,\n MongoUpdateSpec,\n} from '@prisma-next/mongo-query-ast/execution';\nimport type { Document, MongoExpr } from '@prisma-next/mongo-value';\nimport type { AnyMongoWireCommand } from '@prisma-next/mongo-wire';\nimport {\n AggregateWireCommand,\n DeleteManyWireCommand,\n DeleteOneWireCommand,\n FindOneAndDeleteWireCommand,\n FindOneAndUpdateWireCommand,\n InsertManyWireCommand,\n InsertOneWireCommand,\n UpdateManyWireCommand,\n UpdateOneWireCommand,\n} from '@prisma-next/mongo-wire';\nimport { lowerFilter, lowerPipeline, lowerStage } from './lowering';\nimport { resolveValue } from './resolve-value';\n\nfunction isUpdatePipeline(\n update: MongoUpdateSpec,\n): update is ReadonlyArray<MongoUpdatePipelineStage> {\n return Array.isArray(update);\n}\n\nclass MongoAdapterImpl implements MongoAdapter {\n readonly #codecs: MongoCodecRegistry | undefined;\n\n constructor(codecs?: MongoCodecRegistry) {\n this.#codecs = codecs;\n }\n\n async #resolveDocument(expr: MongoExpr): Promise<Document> {\n const entries = Object.entries(expr);\n const resolved = await Promise.all(entries.map(([, val]) => resolveValue(val, this.#codecs)));\n const result: Record<string, unknown> = {};\n for (let i = 0; i < entries.length; i++) {\n const entry = entries[i];\n if (entry) {\n result[entry[0]] = resolved[i];\n }\n }\n return result;\n }\n\n async #lowerUpdate(update: MongoUpdateSpec): Promise<Document | ReadonlyArray<Document>> {\n if (isUpdatePipeline(update)) {\n return Promise.all(update.map((stage) => lowerStage(stage, this.#codecs)));\n }\n return this.#resolveDocument(update);\n }\n\n async lower(plan: MongoQueryPlan): Promise<AnyMongoWireCommand> {\n const { command } = plan;\n switch (command.kind) {\n case 'insertOne':\n return new InsertOneWireCommand(\n command.collection,\n await this.#resolveDocument(command.document),\n );\n case 'updateOne': {\n const [filter, update] = await Promise.all([\n lowerFilter(command.filter, this.#codecs),\n this.#lowerUpdate(command.update),\n ]);\n return new UpdateOneWireCommand(command.collection, filter, update, command.upsert);\n }\n case 'insertMany':\n return new InsertManyWireCommand(\n command.collection,\n await Promise.all(command.documents.map((doc) => this.#resolveDocument(doc))),\n );\n case 'updateMany': {\n const [filter, update] = await Promise.all([\n lowerFilter(command.filter, this.#codecs),\n this.#lowerUpdate(command.update),\n ]);\n return new UpdateManyWireCommand(command.collection, filter, update, command.upsert);\n }\n case 'deleteOne':\n return new DeleteOneWireCommand(\n command.collection,\n await lowerFilter(command.filter, this.#codecs),\n );\n case 'deleteMany':\n return new DeleteManyWireCommand(\n command.collection,\n await lowerFilter(command.filter, this.#codecs),\n );\n case 'findOneAndUpdate': {\n const [filter, update] = await Promise.all([\n lowerFilter(command.filter, this.#codecs),\n this.#lowerUpdate(command.update),\n ]);\n return new FindOneAndUpdateWireCommand(\n command.collection,\n filter,\n update,\n command.upsert,\n command.sort,\n command.returnDocument,\n );\n }\n case 'findOneAndDelete':\n return new FindOneAndDeleteWireCommand(\n command.collection,\n await lowerFilter(command.filter, this.#codecs),\n command.sort,\n );\n case 'aggregate':\n return new AggregateWireCommand(\n command.collection,\n await lowerPipeline(command.pipeline, this.#codecs),\n );\n case 'rawAggregate':\n return new AggregateWireCommand(command.collection, command.pipeline);\n case 'rawInsertOne':\n return new InsertOneWireCommand(command.collection, command.document);\n case 'rawInsertMany':\n return new InsertManyWireCommand(command.collection, command.documents);\n case 'rawUpdateOne':\n return new UpdateOneWireCommand(command.collection, command.filter, command.update);\n case 'rawUpdateMany':\n return new UpdateManyWireCommand(command.collection, command.filter, command.update);\n case 'rawDeleteOne':\n return new DeleteOneWireCommand(command.collection, command.filter);\n case 'rawDeleteMany':\n return new DeleteManyWireCommand(command.collection, command.filter);\n case 'rawFindOneAndUpdate':\n return new FindOneAndUpdateWireCommand(\n command.collection,\n command.filter,\n command.update,\n command.upsert,\n command.sort,\n command.returnDocument,\n );\n case 'rawFindOneAndDelete':\n return new FindOneAndDeleteWireCommand(command.collection, command.filter, command.sort);\n // v8 ignore next 4\n default: {\n const _exhaustive: never = command;\n throw new Error(`Unknown command kind: ${(_exhaustive as { kind: string }).kind}`);\n }\n }\n }\n}\n\nimport {\n mongoBooleanCodec,\n mongoDateCodec,\n mongoDoubleCodec,\n mongoInt32Codec,\n mongoObjectIdCodec,\n mongoStringCodec,\n mongoVectorCodec,\n} from './core/codecs';\n\nfunction defaultCodecRegistry(): MongoCodecRegistry {\n const registry = createMongoCodecRegistry();\n for (const codec of [\n mongoObjectIdCodec,\n mongoStringCodec,\n mongoDoubleCodec,\n mongoInt32Codec,\n mongoBooleanCodec,\n mongoDateCodec,\n mongoVectorCodec,\n ]) {\n registry.register(codec);\n }\n return registry;\n}\n\nexport function createMongoAdapter(codecs?: MongoCodecRegistry): MongoAdapter {\n return new MongoAdapterImpl(codecs ?? defaultCodecRegistry());\n}\n"],"mappings":"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"}
|