@prisma/orm-target-mongo 0.16.0-dev.36

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.
Files changed (77) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +23 -0
  3. package/dist/adapter.d.mts +19 -0
  4. package/dist/adapter.d.mts.map +1 -0
  5. package/dist/adapter.mjs +12 -0
  6. package/dist/adapter.mjs.map +1 -0
  7. package/dist/adapter__codec-ids.d.mts +12 -0
  8. package/dist/adapter__codec-ids.d.mts.map +1 -0
  9. package/dist/adapter__codec-ids.mjs +2 -0
  10. package/dist/adapter__codec-types.d.mts +38 -0
  11. package/dist/adapter__codec-types.d.mts.map +1 -0
  12. package/dist/adapter__codec-types.mjs +1 -0
  13. package/dist/adapter__codecs.d.mts +14 -0
  14. package/dist/adapter__codecs.d.mts.map +1 -0
  15. package/dist/adapter__codecs.mjs +2 -0
  16. package/dist/adapter__control.d.mts +3 -0
  17. package/dist/adapter__control.mjs +3 -0
  18. package/dist/adapter__runtime.d.mts +16 -0
  19. package/dist/adapter__runtime.d.mts.map +1 -0
  20. package/dist/adapter__runtime.mjs +25 -0
  21. package/dist/adapter__runtime.mjs.map +1 -0
  22. package/dist/codec-ids-BennPcpQ-Btzz3ILV.mjs +12 -0
  23. package/dist/codec-ids-BennPcpQ-Btzz3ILV.mjs.map +1 -0
  24. package/dist/codec-types-Bx2fHyq_.d.mts +35 -0
  25. package/dist/codec-types-Bx2fHyq_.d.mts.map +1 -0
  26. package/dist/codecs-DLWO-Cjc-CWfQj0bY.mjs +170 -0
  27. package/dist/codecs-DLWO-Cjc-CWfQj0bY.mjs.map +1 -0
  28. package/dist/control-BOc5lrQg.mjs +437 -0
  29. package/dist/control-BOc5lrQg.mjs.map +1 -0
  30. package/dist/control-CEXmcht7.mjs +1563 -0
  31. package/dist/control-CEXmcht7.mjs.map +1 -0
  32. package/dist/control-CxXmTy_h.d.mts +312 -0
  33. package/dist/control-CxXmTy_h.d.mts.map +1 -0
  34. package/dist/control-rPM2HNxW.d.mts +170 -0
  35. package/dist/control-rPM2HNxW.d.mts.map +1 -0
  36. package/dist/descriptor-meta-CBiaTwe5-HX742pZh.mjs +17 -0
  37. package/dist/descriptor-meta-CBiaTwe5-HX742pZh.mjs.map +1 -0
  38. package/dist/driver.d.mts +2 -0
  39. package/dist/driver.mjs +2 -0
  40. package/dist/driver__control.d.mts +16 -0
  41. package/dist/driver__control.d.mts.map +1 -0
  42. package/dist/driver__control.mjs +46 -0
  43. package/dist/driver__control.mjs.map +1 -0
  44. package/dist/migration-BkqcE2Uv.d.mts +42 -0
  45. package/dist/migration-BkqcE2Uv.d.mts.map +1 -0
  46. package/dist/migration-C-jfTsGU.mjs +4 -0
  47. package/dist/migration-factories-CCJFG_3e-75oJ8xn2.mjs +201 -0
  48. package/dist/migration-factories-CCJFG_3e-75oJ8xn2.mjs.map +1 -0
  49. package/dist/mongo-adapter-BkVYI6jn-ChXldtpg.mjs +807 -0
  50. package/dist/mongo-adapter-BkVYI6jn-ChXldtpg.mjs.map +1 -0
  51. package/dist/mongo-adapter-CjJU3S9o-BIJruFYW.d.mts +16 -0
  52. package/dist/mongo-adapter-CjJU3S9o-BIJruFYW.d.mts.map +1 -0
  53. package/dist/mongo-driver-C7zThOjZ-BcMrlirh.mjs +161 -0
  54. package/dist/mongo-driver-C7zThOjZ-BcMrlirh.mjs.map +1 -0
  55. package/dist/mongo-driver-D1lEf5Kl-KPfGUVXK.d.mts +33 -0
  56. package/dist/mongo-driver-D1lEf5Kl-KPfGUVXK.d.mts.map +1 -0
  57. package/dist/op-factory-call-B7EKa4Ri-B2Lb6W68.d.mts +76 -0
  58. package/dist/op-factory-call-B7EKa4Ri-B2Lb6W68.d.mts.map +1 -0
  59. package/dist/pack-MK8ZQfrL.d.mts +22 -0
  60. package/dist/pack-MK8ZQfrL.d.mts.map +1 -0
  61. package/dist/runtime-B9_-kjBX.d.mts +15 -0
  62. package/dist/runtime-B9_-kjBX.d.mts.map +1 -0
  63. package/dist/target.d.mts +8 -0
  64. package/dist/target.mjs +4 -0
  65. package/dist/target__codec-types.d.mts +2 -0
  66. package/dist/target__codec-types.mjs +1 -0
  67. package/dist/target__control.d.mts +4 -0
  68. package/dist/target__control.mjs +2 -0
  69. package/dist/target__migration.d.mts +2 -0
  70. package/dist/target__migration.mjs +3 -0
  71. package/dist/target__pack.d.mts +2 -0
  72. package/dist/target__pack.mjs +7 -0
  73. package/dist/target__pack.mjs.map +1 -0
  74. package/dist/target__runtime.d.mts +2 -0
  75. package/dist/target__runtime.mjs +21 -0
  76. package/dist/target__runtime.mjs.map +1 -0
  77. package/package.json +63 -0
@@ -0,0 +1,807 @@
1
+ import { t as buildStandardCodecRegistry } from "./codecs-DLWO-Cjc-CWfQj0bY.mjs";
2
+ import { isStructuredError } from "@prisma/orm-framework/utils/structured-error";
3
+ import { blindCast } from "@prisma/orm-framework/utils/casts";
4
+ import { keysToKeySpec } from "@prisma/orm-family-mongo/query-ast/control";
5
+ import { isExprArray, isRecordArgs } from "@prisma/orm-family-mongo/query-ast/execution";
6
+ import { InternalError, assertNever } from "@prisma/orm-framework/utils/internal-error";
7
+ import { checkAborted, raceAgainstAbort, runtimeError } from "@prisma/orm-framework/components/runtime";
8
+ import { MongoParamRef } from "@prisma/orm-family-mongo/value";
9
+ import { AggregateWireCommand, CollModWireCommand, CreateCollectionWireCommand, CreateIndexWireCommand, DeleteManyWireCommand, DeleteOneWireCommand, DropCollectionWireCommand, DropIndexWireCommand, FindOneAndDeleteWireCommand, FindOneAndUpdateWireCommand, InsertManyWireCommand, InsertOneWireCommand, UpdateManyWireCommand, UpdateOneWireCommand } from "@prisma/orm-family-mongo/wire";
10
+ //#region ../../../3-mongo-target/2-mongo-adapter/dist/mongo-adapter-BkVYI6jn.mjs
11
+ /**
12
+ * Resolves a `MongoValue` (which may contain `MongoParamRef` leaves) into the
13
+ * driver-ready wire shape. When a leaf has a `codecId` and the registry has a
14
+ * codec for it, the codec's async `encode` is awaited so codecs may perform
15
+ * asynchronous work (e.g. lookups, key derivations).
16
+ *
17
+ * Object/array nodes dispatch their child resolutions concurrently via
18
+ * `Promise.all` so independent leaves encode in parallel.
19
+ *
20
+ * Codec encode failures are wrapped in a `RUNTIME.ENCODE_FAILED` envelope
21
+ * (mirroring SQL's `wrapEncodeFailure` shape) with `{ label, codec }` details
22
+ * and the original error attached on `cause`. A structured envelope (any error
23
+ * with a dotted `code`, per `isStructuredError`) is re-thrown verbatim so
24
+ * codec-raised envelopes and nested resolvers don't get double-wrapped.
25
+ *
26
+ * `ctx: CodecCallContext` is forwarded verbatim to every
27
+ * `codec.encode(value, ctx)` call. The same `ctx` reference is also passed
28
+ * to nested `resolveValue` invocations so codec authors observe **signal
29
+ * identity** across the entire recursive walk for one `runtime.execute()`.
30
+ *
31
+ * Abort observation (only when `ctx.signal` is provided):
32
+ *
33
+ * - **Already-aborted at entry** — every recursive call pre-checks
34
+ * `ctx.signal.aborted` and short-circuits with
35
+ * `RUNTIME.ABORTED { phase: 'encode' }` before any codec is invoked.
36
+ * - **Mid-flight abort** — each per-level `Promise.all` races against the
37
+ * signal via `raceAgainstAbort`. The runtime returns
38
+ * `RUNTIME.ABORTED { phase: 'encode' }` promptly even if codec bodies
39
+ * ignore the signal; in-flight bodies run to completion in the background
40
+ * (cooperative cancellation, see ADR 204).
41
+ * - `RUNTIME.ENCODE_FAILED` envelopes thrown by a codec body before the
42
+ * runtime sees the abort pass through unchanged (AC-ERR4).
43
+ */
44
+ async function resolveValue(value, codecs, ctx) {
45
+ checkAborted(ctx, "encode");
46
+ const signal = ctx.signal;
47
+ if (value instanceof MongoParamRef) {
48
+ if (value.codecId) {
49
+ const codec = codecs.get(value.codecId);
50
+ if (codec?.encode) try {
51
+ return await raceAgainstAbort(codec.encode(value.value, ctx), signal, "encode");
52
+ } catch (error) {
53
+ wrapEncodeFailure(error, value, codec.id);
54
+ }
55
+ }
56
+ return value.value;
57
+ }
58
+ if (value === null || typeof value !== "object") return value;
59
+ if (value instanceof Date) return value;
60
+ if (Array.isArray(value)) return raceAgainstAbort(Promise.all(value.map((v) => resolveValue(v, codecs, ctx))), signal, "encode");
61
+ const entries = Object.entries(value);
62
+ const resolved = await raceAgainstAbort(Promise.all(entries.map(([, val]) => resolveValue(val, codecs, ctx))), signal, "encode");
63
+ const result = {};
64
+ for (let i = 0; i < entries.length; i++) {
65
+ const entry = entries[i];
66
+ if (entry) result[entry[0]] = resolved[i];
67
+ }
68
+ return result;
69
+ }
70
+ /**
71
+ * Resolves a draft slot value — which may be `MongoParamRef`, a primitive, a
72
+ * nested plain-object, or an array — into the corresponding wire value.
73
+ * Mirrors `resolveValue`'s traversal strategy but accepts `unknown` so it can
74
+ * handle pipeline stage documents whose field types cannot be narrowed to
75
+ * `MongoValue` statically (e.g. `$geoNear.near: unknown`).
76
+ */
77
+ async function resolveDraftSlot(value, codecs, ctx) {
78
+ if (value instanceof MongoParamRef) return resolveValue(value, codecs, ctx);
79
+ if (value === null || typeof value !== "object") return value;
80
+ if (value instanceof Date) return value;
81
+ if (Array.isArray(value)) return raceAgainstAbort(Promise.all(value.map((v) => resolveDraftSlot(v, codecs, ctx))), ctx.signal, "encode");
82
+ return resolveDraftDoc(blindCast(value), codecs, ctx);
83
+ }
84
+ /**
85
+ * Resolves a pipeline stage draft document by walking every entry and
86
+ * forwarding to {@link resolveDraftSlot}. Used by `MongoAdapterImpl.resolveParams`
87
+ * for aggregate pipeline stages, which carry `unknown`-typed fields (e.g.
88
+ * `$geoNear.near`) alongside filter sub-documents that may contain
89
+ * `MongoParamRef` leaves.
90
+ */
91
+ async function resolveDraftDoc(doc, codecs, ctx) {
92
+ checkAborted(ctx, "encode");
93
+ const entries = Object.entries(doc);
94
+ const resolved = await raceAgainstAbort(Promise.all(entries.map(([, val]) => resolveDraftSlot(val, codecs, ctx))), ctx.signal, "encode");
95
+ const result = {};
96
+ for (let i = 0; i < entries.length; i++) {
97
+ const entry = entries[i];
98
+ if (entry) result[entry[0]] = resolved[i];
99
+ }
100
+ return result;
101
+ }
102
+ function paramRefLabel(ref, codecId) {
103
+ return ref.name ?? codecId;
104
+ }
105
+ function wrapEncodeFailure(error, ref, codecId) {
106
+ if (isStructuredError(error)) throw error;
107
+ const label = paramRefLabel(ref, codecId);
108
+ const wrapped = runtimeError("RUNTIME.ENCODE_FAILED", `Failed to encode parameter ${label} with codec '${codecId}': ${error instanceof Error ? error.message : String(error)}`, {
109
+ label,
110
+ codec: codecId
111
+ });
112
+ wrapped.cause = error;
113
+ throw wrapped;
114
+ }
115
+ const THEN_KEY = "then";
116
+ function condBranch(caseOrIf, thenExpr, elseExpr) {
117
+ const entries = [[elseExpr ? "if" : "case", lowerAggExpr(caseOrIf)], [THEN_KEY, lowerAggExpr(thenExpr)]];
118
+ if (elseExpr) entries.push(["else", lowerAggExpr(elseExpr)]);
119
+ return Object.fromEntries(entries);
120
+ }
121
+ const aggExprLoweringVisitor = {
122
+ fieldRef(expr) {
123
+ return `$${expr.path}`;
124
+ },
125
+ literal(expr) {
126
+ return needsLiteralWrap(expr.value) ? { $literal: expr.value } : expr.value;
127
+ },
128
+ operator(expr) {
129
+ const { args } = expr;
130
+ let loweredArgs;
131
+ if (isExprArray(args)) loweredArgs = args.map((a) => lowerAggExpr(a));
132
+ else if (isRecordArgs(args)) loweredArgs = lowerExprRecord(args);
133
+ else loweredArgs = lowerAggExpr(args);
134
+ return { [expr.op]: loweredArgs };
135
+ },
136
+ accumulator(expr) {
137
+ if (expr.arg === null) return { [expr.op]: {} };
138
+ if (isRecordArgs(expr.arg)) return { [expr.op]: lowerExprRecord(expr.arg) };
139
+ return { [expr.op]: lowerAggExpr(expr.arg) };
140
+ },
141
+ cond(expr) {
142
+ return { $cond: condBranch(expr.condition, expr.then_, expr.else_) };
143
+ },
144
+ switch_(expr) {
145
+ return { $switch: {
146
+ branches: expr.branches.map((b) => condBranch(b.case_, b.then_)),
147
+ default: lowerAggExpr(expr.default_)
148
+ } };
149
+ },
150
+ filter(expr) {
151
+ return { $filter: {
152
+ input: lowerAggExpr(expr.input),
153
+ cond: lowerAggExpr(expr.cond),
154
+ as: expr.as
155
+ } };
156
+ },
157
+ map(expr) {
158
+ return { $map: {
159
+ input: lowerAggExpr(expr.input),
160
+ in: lowerAggExpr(expr.in_),
161
+ as: expr.as
162
+ } };
163
+ },
164
+ reduce(expr) {
165
+ return { $reduce: {
166
+ input: lowerAggExpr(expr.input),
167
+ initialValue: lowerAggExpr(expr.initialValue),
168
+ in: lowerAggExpr(expr.in_)
169
+ } };
170
+ },
171
+ let_(expr) {
172
+ const vars = {};
173
+ for (const [key, val] of Object.entries(expr.vars)) vars[key] = lowerAggExpr(val);
174
+ return { $let: {
175
+ vars,
176
+ in: lowerAggExpr(expr.in_)
177
+ } };
178
+ },
179
+ mergeObjects(expr) {
180
+ return { $mergeObjects: expr.exprs.map((e) => lowerAggExpr(e)) };
181
+ }
182
+ };
183
+ function needsLiteralWrap(value) {
184
+ if (typeof value === "string" && value.startsWith("$")) return true;
185
+ if (Array.isArray(value)) return value.some((v) => needsLiteralWrap(v));
186
+ if (value !== null && typeof value === "object") return Object.entries(value).some(([k, v]) => k.startsWith("$") || needsLiteralWrap(v));
187
+ return false;
188
+ }
189
+ function lowerAggExpr(expr) {
190
+ return expr.accept(aggExprLoweringVisitor);
191
+ }
192
+ /**
193
+ * Structural phase of filter lowering: transforms the filter AST into a
194
+ * plain object without resolving any `MongoParamRef` leaves. Field filter
195
+ * values remain as `MongoValue` (which includes `MongoParamRef`), so the
196
+ * returned document can be passed to `resolveDraftDoc` in the resolve phase.
197
+ * Synchronous — no codec calls.
198
+ */
199
+ function structuralLowerFilter(filter) {
200
+ switch (filter.kind) {
201
+ case "field": return { [filter.field]: { [filter.op]: filter.value } };
202
+ case "and": return { $and: filter.exprs.map((e) => structuralLowerFilter(e)) };
203
+ case "or": return { $or: filter.exprs.map((e) => structuralLowerFilter(e)) };
204
+ case "not": return { $nor: [structuralLowerFilter(filter.expr)] };
205
+ case "exists": return { [filter.field]: { $exists: filter.exists } };
206
+ case "expr": return { $expr: lowerAggExpr(filter.aggExpr) };
207
+ default: {
208
+ const _exhaustive = filter;
209
+ return assertNever(_exhaustive, `Unhandled filter kind: ${blindCast(_exhaustive).kind}`);
210
+ }
211
+ }
212
+ }
213
+ async function lowerFilter(filter, codecs, ctx) {
214
+ switch (filter.kind) {
215
+ case "field": return { [filter.field]: { [filter.op]: await resolveValue(filter.value, codecs, ctx) } };
216
+ case "and": return { $and: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };
217
+ case "or": return { $or: await Promise.all(filter.exprs.map((e) => lowerFilter(e, codecs, ctx))) };
218
+ case "not": return { $nor: [await lowerFilter(filter.expr, codecs, ctx)] };
219
+ case "exists": return { [filter.field]: { $exists: filter.exists } };
220
+ case "expr": return { $expr: lowerAggExpr(filter.aggExpr) };
221
+ default: {
222
+ const _exhaustive = filter;
223
+ return assertNever(_exhaustive, `Unhandled filter kind: ${blindCast(_exhaustive).kind}`);
224
+ }
225
+ }
226
+ }
227
+ function isAggExprNode(value) {
228
+ return "accept" in value && typeof value.accept === "function";
229
+ }
230
+ function isAggExprArray(val) {
231
+ return Array.isArray(val);
232
+ }
233
+ function lowerGroupId(groupId) {
234
+ if (groupId === null) return null;
235
+ if (isAggExprNode(groupId)) return lowerAggExpr(groupId);
236
+ return lowerExprRecord(groupId);
237
+ }
238
+ function lowerExprRecord(fields) {
239
+ const result = {};
240
+ for (const [key, val] of Object.entries(fields)) if (isAggExprArray(val)) result[key] = val.map((v) => lowerAggExpr(v));
241
+ else result[key] = lowerAggExpr(val);
242
+ return result;
243
+ }
244
+ function lowerProjectionValue(value) {
245
+ if (typeof value === "number") return value;
246
+ return lowerAggExpr(value);
247
+ }
248
+ function lowerWindowField(wf) {
249
+ const lowered = lowerAggExpr(wf.operator);
250
+ if (typeof lowered !== "object" || lowered === null) throw new InternalError("Window field operator must lower to an object");
251
+ const result = { ...lowered };
252
+ if (wf.window) result["window"] = { ...wf.window };
253
+ return result;
254
+ }
255
+ async function lowerStage(stage, codecs, ctx) {
256
+ switch (stage.kind) {
257
+ case "match": return { $match: await lowerFilter(stage.filter, codecs, ctx) };
258
+ case "project": {
259
+ const projection = {};
260
+ for (const [key, val] of Object.entries(stage.projection)) projection[key] = lowerProjectionValue(val);
261
+ return { $project: projection };
262
+ }
263
+ case "sort": return { $sort: { ...stage.sort } };
264
+ case "limit": return { $limit: stage.limit };
265
+ case "skip": return { $skip: stage.skip };
266
+ case "lookup": {
267
+ const lookup = {
268
+ from: stage.from,
269
+ as: stage.as
270
+ };
271
+ if (stage.localField !== void 0) lookup["localField"] = stage.localField;
272
+ if (stage.foreignField !== void 0) lookup["foreignField"] = stage.foreignField;
273
+ if (stage.pipeline) lookup["pipeline"] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs, ctx)));
274
+ if (stage.let_) lookup["let"] = lowerExprRecord(stage.let_);
275
+ return { $lookup: lookup };
276
+ }
277
+ case "unwind": {
278
+ const unwind = {
279
+ path: stage.path,
280
+ preserveNullAndEmptyArrays: stage.preserveNullAndEmptyArrays
281
+ };
282
+ if (stage.includeArrayIndex !== void 0) unwind["includeArrayIndex"] = stage.includeArrayIndex;
283
+ return { $unwind: unwind };
284
+ }
285
+ case "group": {
286
+ const group = { _id: lowerGroupId(stage.groupId) };
287
+ for (const [key, acc] of Object.entries(stage.accumulators)) group[key] = lowerAggExpr(acc);
288
+ return { $group: group };
289
+ }
290
+ case "addFields": return { $addFields: lowerExprRecord(stage.fields) };
291
+ case "replaceRoot": return { $replaceRoot: { newRoot: lowerAggExpr(stage.newRoot) } };
292
+ case "count": return { $count: stage.field };
293
+ case "sortByCount": return { $sortByCount: lowerAggExpr(stage.expr) };
294
+ case "sample": return { $sample: { size: stage.size } };
295
+ case "redact": return { $redact: lowerAggExpr(stage.expr) };
296
+ case "out": return { $out: stage.db ? {
297
+ db: stage.db,
298
+ coll: stage.collection
299
+ } : stage.collection };
300
+ case "unionWith": {
301
+ const unionWith = { coll: stage.collection };
302
+ if (stage.pipeline) unionWith["pipeline"] = await Promise.all(stage.pipeline.map((s) => lowerStage(s, codecs, ctx)));
303
+ return { $unionWith: unionWith };
304
+ }
305
+ case "bucket": {
306
+ const bucket = {
307
+ groupBy: lowerAggExpr(stage.groupBy),
308
+ boundaries: [...stage.boundaries]
309
+ };
310
+ if (stage.default_ !== void 0) bucket["default"] = stage.default_;
311
+ if (stage.output) bucket["output"] = lowerExprRecord(stage.output);
312
+ return { $bucket: bucket };
313
+ }
314
+ case "bucketAuto": {
315
+ const bucketAuto = {
316
+ groupBy: lowerAggExpr(stage.groupBy),
317
+ buckets: stage.buckets
318
+ };
319
+ if (stage.output) bucketAuto["output"] = lowerExprRecord(stage.output);
320
+ if (stage.granularity !== void 0) bucketAuto["granularity"] = stage.granularity;
321
+ return { $bucketAuto: bucketAuto };
322
+ }
323
+ case "geoNear": {
324
+ const geoNear = {
325
+ near: stage.near,
326
+ distanceField: stage.distanceField
327
+ };
328
+ if (stage.spherical !== void 0) geoNear["spherical"] = stage.spherical;
329
+ if (stage.maxDistance !== void 0) geoNear["maxDistance"] = stage.maxDistance;
330
+ if (stage.minDistance !== void 0) geoNear["minDistance"] = stage.minDistance;
331
+ if (stage.query) geoNear["query"] = await lowerFilter(stage.query, codecs, ctx);
332
+ if (stage.key !== void 0) geoNear["key"] = stage.key;
333
+ if (stage.distanceMultiplier !== void 0) geoNear["distanceMultiplier"] = stage.distanceMultiplier;
334
+ if (stage.includeLocs !== void 0) geoNear["includeLocs"] = stage.includeLocs;
335
+ return { $geoNear: geoNear };
336
+ }
337
+ case "facet": {
338
+ const facetEntries = Object.entries(stage.facets);
339
+ const facetPipelines = await Promise.all(facetEntries.map(([, pipeline]) => Promise.all(pipeline.map((s) => lowerStage(s, codecs, ctx)))));
340
+ const facet = {};
341
+ for (let i = 0; i < facetEntries.length; i++) {
342
+ const entry = facetEntries[i];
343
+ if (entry) facet[entry[0]] = facetPipelines[i];
344
+ }
345
+ return { $facet: facet };
346
+ }
347
+ case "graphLookup": {
348
+ const graphLookup = {
349
+ from: stage.from,
350
+ startWith: lowerAggExpr(stage.startWith),
351
+ connectFromField: stage.connectFromField,
352
+ connectToField: stage.connectToField,
353
+ as: stage.as
354
+ };
355
+ if (stage.maxDepth !== void 0) graphLookup["maxDepth"] = stage.maxDepth;
356
+ if (stage.depthField !== void 0) graphLookup["depthField"] = stage.depthField;
357
+ if (stage.restrictSearchWithMatch) graphLookup["restrictSearchWithMatch"] = await lowerFilter(stage.restrictSearchWithMatch, codecs, ctx);
358
+ return { $graphLookup: graphLookup };
359
+ }
360
+ case "merge": {
361
+ const merge = { into: stage.into };
362
+ if (stage.on !== void 0) merge["on"] = stage.on;
363
+ if (stage.whenMatched !== void 0) merge["whenMatched"] = Array.isArray(stage.whenMatched) ? await Promise.all(stage.whenMatched.map((s) => lowerStage(s, codecs, ctx))) : stage.whenMatched;
364
+ if (stage.whenNotMatched !== void 0) merge["whenNotMatched"] = stage.whenNotMatched;
365
+ return { $merge: merge };
366
+ }
367
+ case "setWindowFields": {
368
+ const swf = {};
369
+ if (stage.partitionBy) swf["partitionBy"] = lowerAggExpr(stage.partitionBy);
370
+ if (stage.sortBy) swf["sortBy"] = { ...stage.sortBy };
371
+ const output = {};
372
+ for (const [key, wf] of Object.entries(stage.output)) output[key] = lowerWindowField(wf);
373
+ swf["output"] = output;
374
+ return { $setWindowFields: swf };
375
+ }
376
+ case "densify": {
377
+ const densify = {
378
+ field: stage.field,
379
+ range: { ...stage.range }
380
+ };
381
+ if (stage.partitionByFields) densify["partitionByFields"] = [...stage.partitionByFields];
382
+ return { $densify: densify };
383
+ }
384
+ case "fill": {
385
+ const fill = {};
386
+ if (stage.partitionBy) fill["partitionBy"] = lowerAggExpr(stage.partitionBy);
387
+ if (stage.partitionByFields) fill["partitionByFields"] = [...stage.partitionByFields];
388
+ if (stage.sortBy) fill["sortBy"] = { ...stage.sortBy };
389
+ const output = {};
390
+ for (const [key, fo] of Object.entries(stage.output)) {
391
+ const entry = {};
392
+ if (fo.method !== void 0) entry["method"] = fo.method;
393
+ if (fo.value !== void 0) entry["value"] = lowerAggExpr(fo.value);
394
+ output[key] = entry;
395
+ }
396
+ fill["output"] = output;
397
+ return { $fill: fill };
398
+ }
399
+ case "search": {
400
+ const search = { ...stage.config };
401
+ if (stage.index !== void 0) search["index"] = stage.index;
402
+ return { $search: search };
403
+ }
404
+ case "searchMeta": {
405
+ const searchMeta = { ...stage.config };
406
+ if (stage.index !== void 0) searchMeta["index"] = stage.index;
407
+ return { $searchMeta: searchMeta };
408
+ }
409
+ case "vectorSearch": {
410
+ const vs = {
411
+ index: stage.index,
412
+ path: stage.path,
413
+ queryVector: [...stage.queryVector],
414
+ numCandidates: stage.numCandidates,
415
+ limit: stage.limit
416
+ };
417
+ if (stage.filter) vs["filter"] = { ...stage.filter };
418
+ return { $vectorSearch: vs };
419
+ }
420
+ default: {
421
+ const _exhaustive = stage;
422
+ return assertNever(_exhaustive, `Unhandled stage kind: ${blindCast(_exhaustive).kind}`);
423
+ }
424
+ }
425
+ }
426
+ async function lowerPipeline(stages, codecs, ctx) {
427
+ return Promise.all(stages.map((s) => lowerStage(s, codecs, ctx)));
428
+ }
429
+ /**
430
+ * Structural phase of stage lowering: mirrors `lowerStage` but defers all
431
+ * `MongoParamRef` resolution. Filter sub-documents within stages (e.g.
432
+ * `$match`, `$geoNear.query`, `$graphLookup.restrictSearchWithMatch`) are
433
+ * produced by `structuralLowerFilter` and therefore retain `MongoParamRef`
434
+ * leaves. Sub-pipelines (e.g. `$lookup.pipeline`, `$facet.*`) recurse via
435
+ * `structuralLowerPipeline`. Synchronous — no codec calls.
436
+ */
437
+ function structuralLowerStage(stage) {
438
+ switch (stage.kind) {
439
+ case "match": return { $match: structuralLowerFilter(stage.filter) };
440
+ case "project": {
441
+ const projection = {};
442
+ for (const [key, val] of Object.entries(stage.projection)) projection[key] = lowerProjectionValue(val);
443
+ return { $project: projection };
444
+ }
445
+ case "sort": return { $sort: { ...stage.sort } };
446
+ case "limit": return { $limit: stage.limit };
447
+ case "skip": return { $skip: stage.skip };
448
+ case "lookup": {
449
+ const lookup = {
450
+ from: stage.from,
451
+ as: stage.as
452
+ };
453
+ if (stage.localField !== void 0) lookup["localField"] = stage.localField;
454
+ if (stage.foreignField !== void 0) lookup["foreignField"] = stage.foreignField;
455
+ if (stage.pipeline) lookup["pipeline"] = structuralLowerPipeline(stage.pipeline);
456
+ if (stage.let_) lookup["let"] = lowerExprRecord(stage.let_);
457
+ return { $lookup: lookup };
458
+ }
459
+ case "unwind": {
460
+ const unwind = {
461
+ path: stage.path,
462
+ preserveNullAndEmptyArrays: stage.preserveNullAndEmptyArrays
463
+ };
464
+ if (stage.includeArrayIndex !== void 0) unwind["includeArrayIndex"] = stage.includeArrayIndex;
465
+ return { $unwind: unwind };
466
+ }
467
+ case "group": {
468
+ const group = { _id: lowerGroupId(stage.groupId) };
469
+ for (const [key, acc] of Object.entries(stage.accumulators)) group[key] = lowerAggExpr(acc);
470
+ return { $group: group };
471
+ }
472
+ case "addFields": return { $addFields: lowerExprRecord(stage.fields) };
473
+ case "replaceRoot": return { $replaceRoot: { newRoot: lowerAggExpr(stage.newRoot) } };
474
+ case "count": return { $count: stage.field };
475
+ case "sortByCount": return { $sortByCount: lowerAggExpr(stage.expr) };
476
+ case "sample": return { $sample: { size: stage.size } };
477
+ case "redact": return { $redact: lowerAggExpr(stage.expr) };
478
+ case "out": return { $out: stage.db ? {
479
+ db: stage.db,
480
+ coll: stage.collection
481
+ } : stage.collection };
482
+ case "unionWith": {
483
+ const unionWith = { coll: stage.collection };
484
+ if (stage.pipeline) unionWith["pipeline"] = structuralLowerPipeline(stage.pipeline);
485
+ return { $unionWith: unionWith };
486
+ }
487
+ case "bucket": {
488
+ const bucket = {
489
+ groupBy: lowerAggExpr(stage.groupBy),
490
+ boundaries: [...stage.boundaries]
491
+ };
492
+ if (stage.default_ !== void 0) bucket["default"] = stage.default_;
493
+ if (stage.output) bucket["output"] = lowerExprRecord(stage.output);
494
+ return { $bucket: bucket };
495
+ }
496
+ case "bucketAuto": {
497
+ const bucketAuto = {
498
+ groupBy: lowerAggExpr(stage.groupBy),
499
+ buckets: stage.buckets
500
+ };
501
+ if (stage.output) bucketAuto["output"] = lowerExprRecord(stage.output);
502
+ if (stage.granularity !== void 0) bucketAuto["granularity"] = stage.granularity;
503
+ return { $bucketAuto: bucketAuto };
504
+ }
505
+ case "geoNear": {
506
+ const geoNear = {
507
+ near: stage.near,
508
+ distanceField: stage.distanceField
509
+ };
510
+ if (stage.spherical !== void 0) geoNear["spherical"] = stage.spherical;
511
+ if (stage.maxDistance !== void 0) geoNear["maxDistance"] = stage.maxDistance;
512
+ if (stage.minDistance !== void 0) geoNear["minDistance"] = stage.minDistance;
513
+ if (stage.query) geoNear["query"] = structuralLowerFilter(stage.query);
514
+ if (stage.key !== void 0) geoNear["key"] = stage.key;
515
+ if (stage.distanceMultiplier !== void 0) geoNear["distanceMultiplier"] = stage.distanceMultiplier;
516
+ if (stage.includeLocs !== void 0) geoNear["includeLocs"] = stage.includeLocs;
517
+ return { $geoNear: geoNear };
518
+ }
519
+ case "facet": {
520
+ const facet = {};
521
+ for (const [key, pipeline] of Object.entries(stage.facets)) facet[key] = structuralLowerPipeline(pipeline);
522
+ return { $facet: facet };
523
+ }
524
+ case "graphLookup": {
525
+ const graphLookup = {
526
+ from: stage.from,
527
+ startWith: lowerAggExpr(stage.startWith),
528
+ connectFromField: stage.connectFromField,
529
+ connectToField: stage.connectToField,
530
+ as: stage.as
531
+ };
532
+ if (stage.maxDepth !== void 0) graphLookup["maxDepth"] = stage.maxDepth;
533
+ if (stage.depthField !== void 0) graphLookup["depthField"] = stage.depthField;
534
+ if (stage.restrictSearchWithMatch) graphLookup["restrictSearchWithMatch"] = structuralLowerFilter(stage.restrictSearchWithMatch);
535
+ return { $graphLookup: graphLookup };
536
+ }
537
+ case "merge": {
538
+ const merge = { into: stage.into };
539
+ if (stage.on !== void 0) merge["on"] = stage.on;
540
+ if (stage.whenMatched !== void 0) merge["whenMatched"] = Array.isArray(stage.whenMatched) ? structuralLowerPipeline(stage.whenMatched) : stage.whenMatched;
541
+ if (stage.whenNotMatched !== void 0) merge["whenNotMatched"] = stage.whenNotMatched;
542
+ return { $merge: merge };
543
+ }
544
+ case "setWindowFields": {
545
+ const swf = {};
546
+ if (stage.partitionBy) swf["partitionBy"] = lowerAggExpr(stage.partitionBy);
547
+ if (stage.sortBy) swf["sortBy"] = { ...stage.sortBy };
548
+ const output = {};
549
+ for (const [key, wf] of Object.entries(stage.output)) output[key] = lowerWindowField(wf);
550
+ swf["output"] = output;
551
+ return { $setWindowFields: swf };
552
+ }
553
+ case "densify": {
554
+ const densify = {
555
+ field: stage.field,
556
+ range: { ...stage.range }
557
+ };
558
+ if (stage.partitionByFields) densify["partitionByFields"] = [...stage.partitionByFields];
559
+ return { $densify: densify };
560
+ }
561
+ case "fill": {
562
+ const fill = {};
563
+ if (stage.partitionBy) fill["partitionBy"] = lowerAggExpr(stage.partitionBy);
564
+ if (stage.partitionByFields) fill["partitionByFields"] = [...stage.partitionByFields];
565
+ if (stage.sortBy) fill["sortBy"] = { ...stage.sortBy };
566
+ const output = {};
567
+ for (const [key, fo] of Object.entries(stage.output)) {
568
+ const entry = {};
569
+ if (fo.method !== void 0) entry["method"] = fo.method;
570
+ if (fo.value !== void 0) entry["value"] = lowerAggExpr(fo.value);
571
+ output[key] = entry;
572
+ }
573
+ fill["output"] = output;
574
+ return { $fill: fill };
575
+ }
576
+ case "search": {
577
+ const search = { ...stage.config };
578
+ if (stage.index !== void 0) search["index"] = stage.index;
579
+ return { $search: search };
580
+ }
581
+ case "searchMeta": {
582
+ const searchMeta = { ...stage.config };
583
+ if (stage.index !== void 0) searchMeta["index"] = stage.index;
584
+ return { $searchMeta: searchMeta };
585
+ }
586
+ case "vectorSearch": {
587
+ const vs = {
588
+ index: stage.index,
589
+ path: stage.path,
590
+ queryVector: [...stage.queryVector],
591
+ numCandidates: stage.numCandidates,
592
+ limit: stage.limit
593
+ };
594
+ if (stage.filter) vs["filter"] = { ...stage.filter };
595
+ return { $vectorSearch: vs };
596
+ }
597
+ default: {
598
+ const _exhaustive = stage;
599
+ return assertNever(_exhaustive, `Unhandled stage kind: ${blindCast(_exhaustive).kind}`);
600
+ }
601
+ }
602
+ }
603
+ function structuralLowerPipeline(stages) {
604
+ return stages.map((s) => structuralLowerStage(s));
605
+ }
606
+ function isUpdatePipeline(update) {
607
+ return Array.isArray(update);
608
+ }
609
+ function isDraftUpdatePipeline(update) {
610
+ return Array.isArray(update);
611
+ }
612
+ async function resolveUpdate(update, codecs, ctx) {
613
+ if (isDraftUpdatePipeline(update)) return Promise.all(update.map((stage) => resolveDraftDoc(stage, codecs, ctx)));
614
+ return resolveDraftDoc(update, codecs, ctx);
615
+ }
616
+ function lowerDdlCommand(command) {
617
+ switch (command.kind) {
618
+ case "createCollection": return new CreateCollectionWireCommand(command.collection, command);
619
+ case "createIndex": return new CreateIndexWireCommand(command.collection, keysToKeySpec(command.keys), command);
620
+ case "dropCollection": return new DropCollectionWireCommand(command.collection);
621
+ case "dropIndex": return new DropIndexWireCommand(command.collection, command.name);
622
+ case "collMod": return new CollModWireCommand(command.collection, command);
623
+ // v8 ignore next 4
624
+ default: {
625
+ const _exhaustive = command;
626
+ return assertNever(_exhaustive, `Unknown DDL command kind: ${blindCast(_exhaustive).kind}`);
627
+ }
628
+ }
629
+ }
630
+ var MongoAdapterImpl = class {
631
+ #codecs;
632
+ constructor(codecs) {
633
+ this.#codecs = codecs;
634
+ }
635
+ structuralLower(plan) {
636
+ const { command } = plan;
637
+ switch (command.kind) {
638
+ case "insertOne": return {
639
+ kind: "insertOne",
640
+ collection: command.collection,
641
+ document: command.document
642
+ };
643
+ case "insertMany": return {
644
+ kind: "insertMany",
645
+ collection: command.collection,
646
+ documents: command.documents
647
+ };
648
+ case "updateOne": return {
649
+ kind: "updateOne",
650
+ collection: command.collection,
651
+ filter: structuralLowerFilter(command.filter),
652
+ update: isUpdatePipeline(command.update) ? structuralLowerPipeline(command.update) : command.update,
653
+ upsert: command.upsert
654
+ };
655
+ case "updateMany": return {
656
+ kind: "updateMany",
657
+ collection: command.collection,
658
+ filter: structuralLowerFilter(command.filter),
659
+ update: isUpdatePipeline(command.update) ? structuralLowerPipeline(command.update) : command.update,
660
+ upsert: command.upsert
661
+ };
662
+ case "deleteOne": return {
663
+ kind: "deleteOne",
664
+ collection: command.collection,
665
+ filter: structuralLowerFilter(command.filter)
666
+ };
667
+ case "deleteMany": return {
668
+ kind: "deleteMany",
669
+ collection: command.collection,
670
+ filter: structuralLowerFilter(command.filter)
671
+ };
672
+ case "findOneAndUpdate": return {
673
+ kind: "findOneAndUpdate",
674
+ collection: command.collection,
675
+ filter: structuralLowerFilter(command.filter),
676
+ update: isUpdatePipeline(command.update) ? structuralLowerPipeline(command.update) : command.update,
677
+ upsert: command.upsert,
678
+ sort: command.sort,
679
+ returnDocument: command.returnDocument
680
+ };
681
+ case "findOneAndDelete": return {
682
+ kind: "findOneAndDelete",
683
+ collection: command.collection,
684
+ filter: structuralLowerFilter(command.filter),
685
+ sort: command.sort
686
+ };
687
+ case "aggregate": return {
688
+ kind: "aggregate",
689
+ collection: command.collection,
690
+ pipeline: structuralLowerPipeline(command.pipeline)
691
+ };
692
+ case "rawAggregate": return {
693
+ kind: "rawAggregate",
694
+ collection: command.collection,
695
+ pipeline: command.pipeline
696
+ };
697
+ case "rawInsertOne": return {
698
+ kind: "rawInsertOne",
699
+ collection: command.collection,
700
+ document: command.document
701
+ };
702
+ case "rawInsertMany": return {
703
+ kind: "rawInsertMany",
704
+ collection: command.collection,
705
+ documents: command.documents
706
+ };
707
+ case "rawUpdateOne": return {
708
+ kind: "rawUpdateOne",
709
+ collection: command.collection,
710
+ filter: command.filter,
711
+ update: command.update
712
+ };
713
+ case "rawUpdateMany": return {
714
+ kind: "rawUpdateMany",
715
+ collection: command.collection,
716
+ filter: command.filter,
717
+ update: command.update
718
+ };
719
+ case "rawDeleteOne": return {
720
+ kind: "rawDeleteOne",
721
+ collection: command.collection,
722
+ filter: command.filter
723
+ };
724
+ case "rawDeleteMany": return {
725
+ kind: "rawDeleteMany",
726
+ collection: command.collection,
727
+ filter: command.filter
728
+ };
729
+ case "rawFindOneAndUpdate": return {
730
+ kind: "rawFindOneAndUpdate",
731
+ collection: command.collection,
732
+ filter: command.filter,
733
+ update: command.update,
734
+ upsert: command.upsert,
735
+ sort: command.sort,
736
+ returnDocument: command.returnDocument
737
+ };
738
+ case "rawFindOneAndDelete": return {
739
+ kind: "rawFindOneAndDelete",
740
+ collection: command.collection,
741
+ filter: command.filter,
742
+ sort: command.sort
743
+ };
744
+ // v8 ignore next 4
745
+ default: {
746
+ const _exhaustive = command;
747
+ return assertNever(_exhaustive, `Unknown command kind: ${blindCast(_exhaustive).kind}`);
748
+ }
749
+ }
750
+ }
751
+ async resolveParams(draft, ctx) {
752
+ switch (draft.kind) {
753
+ case "insertOne": return new InsertOneWireCommand(draft.collection, await resolveDraftDoc(draft.document, this.#codecs, ctx));
754
+ case "insertMany": return new InsertManyWireCommand(draft.collection, await Promise.all(draft.documents.map((doc) => resolveDraftDoc(doc, this.#codecs, ctx))));
755
+ case "updateOne": {
756
+ const [filter, update] = await Promise.all([resolveDraftDoc(draft.filter, this.#codecs, ctx), resolveUpdate(draft.update, this.#codecs, ctx)]);
757
+ return new UpdateOneWireCommand(draft.collection, filter, update, draft.upsert);
758
+ }
759
+ case "updateMany": {
760
+ const [filter, update] = await Promise.all([resolveDraftDoc(draft.filter, this.#codecs, ctx), resolveUpdate(draft.update, this.#codecs, ctx)]);
761
+ return new UpdateManyWireCommand(draft.collection, filter, update, draft.upsert);
762
+ }
763
+ case "deleteOne": return new DeleteOneWireCommand(draft.collection, await resolveDraftDoc(draft.filter, this.#codecs, ctx));
764
+ case "deleteMany": return new DeleteManyWireCommand(draft.collection, await resolveDraftDoc(draft.filter, this.#codecs, ctx));
765
+ case "findOneAndUpdate": {
766
+ const [filter, update] = await Promise.all([resolveDraftDoc(draft.filter, this.#codecs, ctx), resolveUpdate(draft.update, this.#codecs, ctx)]);
767
+ return new FindOneAndUpdateWireCommand(draft.collection, filter, update, draft.upsert, draft.sort, draft.returnDocument);
768
+ }
769
+ case "findOneAndDelete": return new FindOneAndDeleteWireCommand(draft.collection, await resolveDraftDoc(draft.filter, this.#codecs, ctx), draft.sort);
770
+ case "aggregate": return new AggregateWireCommand(draft.collection, await Promise.all(draft.pipeline.map((stage) => resolveDraftDoc(stage, this.#codecs, ctx))));
771
+ case "rawAggregate": return new AggregateWireCommand(draft.collection, draft.pipeline);
772
+ case "rawInsertOne": return new InsertOneWireCommand(draft.collection, draft.document);
773
+ case "rawInsertMany": return new InsertManyWireCommand(draft.collection, draft.documents);
774
+ case "rawUpdateOne": return new UpdateOneWireCommand(draft.collection, draft.filter, draft.update);
775
+ case "rawUpdateMany": return new UpdateManyWireCommand(draft.collection, draft.filter, draft.update);
776
+ case "rawDeleteOne": return new DeleteOneWireCommand(draft.collection, draft.filter);
777
+ case "rawDeleteMany": return new DeleteManyWireCommand(draft.collection, draft.filter);
778
+ case "rawFindOneAndUpdate": return new FindOneAndUpdateWireCommand(draft.collection, draft.filter, draft.update, draft.upsert, draft.sort, draft.returnDocument);
779
+ case "rawFindOneAndDelete": return new FindOneAndDeleteWireCommand(draft.collection, draft.filter, draft.sort);
780
+ // v8 ignore next 4
781
+ default: {
782
+ const _exhaustive = draft;
783
+ return assertNever(_exhaustive, `Unknown draft kind: ${blindCast(_exhaustive).kind}`);
784
+ }
785
+ }
786
+ }
787
+ lower(plan, ctx) {
788
+ if ("collection" in plan) return this.resolveParams(this.structuralLower(plan), ctx);
789
+ return Promise.resolve(lowerDdlCommand(plan.command));
790
+ }
791
+ };
792
+ /**
793
+ * Construct a Mongo adapter with the standard wire-type codecs registered
794
+ * for encode-side dispatch (`MongoParamRef.codecId` lookups).
795
+ *
796
+ * The runtime-side codec registry the runtime decodes against is composed
797
+ * separately by `createMongoExecutionContext`. This factory exists for
798
+ * direct adapter use (the runtime descriptor's `create(stack)` calls
799
+ * through it). User code should compose a stack/context instead.
800
+ */
801
+ function createMongoAdapter() {
802
+ return new MongoAdapterImpl(buildStandardCodecRegistry());
803
+ }
804
+ //#endregion
805
+ export { lowerStage as a, lowerPipeline as i, lowerAggExpr as n, lowerFilter as r, createMongoAdapter as t };
806
+
807
+ //# sourceMappingURL=mongo-adapter-BkVYI6jn-ChXldtpg.mjs.map