@prisma-next/adapter-mongo 0.5.0-dev.7 → 0.5.0-dev.71

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.
@@ -1,4 +1,5 @@
1
- import { createMongoCodecRegistry, type MongoCodecRegistry } from '@prisma-next/mongo-codec';
1
+ import type { CodecCallContext } from '@prisma-next/framework-components/codec';
2
+ import type { MongoCodecRegistry } from '@prisma-next/mongo-codec';
2
3
  import type { MongoAdapter } from '@prisma-next/mongo-lowering';
3
4
  import type {
4
5
  MongoQueryPlan,
@@ -18,6 +19,7 @@ import {
18
19
  UpdateManyWireCommand,
19
20
  UpdateOneWireCommand,
20
21
  } from '@prisma-next/mongo-wire';
22
+ import { buildStandardCodecRegistry } from './core/codecs';
21
23
  import { lowerFilter, lowerPipeline, lowerStage } from './lowering';
22
24
  import { resolveValue } from './resolve-value';
23
25
 
@@ -28,75 +30,99 @@ function isUpdatePipeline(
28
30
  }
29
31
 
30
32
  class MongoAdapterImpl implements MongoAdapter {
31
- readonly #codecs: MongoCodecRegistry | undefined;
33
+ readonly #codecs: MongoCodecRegistry;
32
34
 
33
- constructor(codecs?: MongoCodecRegistry) {
35
+ constructor(codecs: MongoCodecRegistry) {
34
36
  this.#codecs = codecs;
35
37
  }
36
38
 
37
- #resolveDocument(expr: MongoExpr): Document {
39
+ async #resolveDocument(expr: MongoExpr, ctx: CodecCallContext): Promise<Document> {
40
+ const entries = Object.entries(expr);
41
+ const resolved = await Promise.all(
42
+ entries.map(([, val]) => resolveValue(val, this.#codecs, ctx)),
43
+ );
38
44
  const result: Record<string, unknown> = {};
39
- for (const [key, val] of Object.entries(expr)) {
40
- result[key] = resolveValue(val, this.#codecs);
45
+ for (let i = 0; i < entries.length; i++) {
46
+ const entry = entries[i];
47
+ if (entry) {
48
+ result[entry[0]] = resolved[i];
49
+ }
41
50
  }
42
51
  return result;
43
52
  }
44
53
 
45
- #lowerUpdate(update: MongoUpdateSpec): Document | ReadonlyArray<Document> {
54
+ async #lowerUpdate(
55
+ update: MongoUpdateSpec,
56
+ ctx: CodecCallContext,
57
+ ): Promise<Document | ReadonlyArray<Document>> {
46
58
  if (isUpdatePipeline(update)) {
47
- return update.map((stage) => lowerStage(stage));
59
+ return Promise.all(update.map((stage) => lowerStage(stage, this.#codecs, ctx)));
48
60
  }
49
- return this.#resolveDocument(update);
61
+ return this.#resolveDocument(update, ctx);
50
62
  }
51
63
 
52
- lower(plan: MongoQueryPlan): AnyMongoWireCommand {
64
+ async lower(plan: MongoQueryPlan, ctx: CodecCallContext): Promise<AnyMongoWireCommand> {
53
65
  const { command } = plan;
54
66
  switch (command.kind) {
55
67
  case 'insertOne':
56
68
  return new InsertOneWireCommand(
57
69
  command.collection,
58
- this.#resolveDocument(command.document),
59
- );
60
- case 'updateOne':
61
- return new UpdateOneWireCommand(
62
- command.collection,
63
- lowerFilter(command.filter),
64
- this.#lowerUpdate(command.update),
65
- command.upsert,
70
+ await this.#resolveDocument(command.document, ctx),
66
71
  );
72
+ case 'updateOne': {
73
+ const [filter, update] = await Promise.all([
74
+ lowerFilter(command.filter, this.#codecs, ctx),
75
+ this.#lowerUpdate(command.update, ctx),
76
+ ]);
77
+ return new UpdateOneWireCommand(command.collection, filter, update, command.upsert);
78
+ }
67
79
  case 'insertMany':
68
80
  return new InsertManyWireCommand(
69
81
  command.collection,
70
- command.documents.map((doc) => this.#resolveDocument(doc)),
82
+ await Promise.all(command.documents.map((doc) => this.#resolveDocument(doc, ctx))),
71
83
  );
72
- case 'updateMany':
73
- return new UpdateManyWireCommand(
84
+ case 'updateMany': {
85
+ const [filter, update] = await Promise.all([
86
+ lowerFilter(command.filter, this.#codecs, ctx),
87
+ this.#lowerUpdate(command.update, ctx),
88
+ ]);
89
+ return new UpdateManyWireCommand(command.collection, filter, update, command.upsert);
90
+ }
91
+ case 'deleteOne':
92
+ return new DeleteOneWireCommand(
74
93
  command.collection,
75
- lowerFilter(command.filter),
76
- this.#lowerUpdate(command.update),
77
- command.upsert,
94
+ await lowerFilter(command.filter, this.#codecs, ctx),
78
95
  );
79
- case 'deleteOne':
80
- return new DeleteOneWireCommand(command.collection, lowerFilter(command.filter));
81
96
  case 'deleteMany':
82
- return new DeleteManyWireCommand(command.collection, lowerFilter(command.filter));
83
- case 'findOneAndUpdate':
97
+ return new DeleteManyWireCommand(
98
+ command.collection,
99
+ await lowerFilter(command.filter, this.#codecs, ctx),
100
+ );
101
+ case 'findOneAndUpdate': {
102
+ const [filter, update] = await Promise.all([
103
+ lowerFilter(command.filter, this.#codecs, ctx),
104
+ this.#lowerUpdate(command.update, ctx),
105
+ ]);
84
106
  return new FindOneAndUpdateWireCommand(
85
107
  command.collection,
86
- lowerFilter(command.filter),
87
- this.#lowerUpdate(command.update),
108
+ filter,
109
+ update,
88
110
  command.upsert,
89
111
  command.sort,
90
112
  command.returnDocument,
91
113
  );
114
+ }
92
115
  case 'findOneAndDelete':
93
116
  return new FindOneAndDeleteWireCommand(
94
117
  command.collection,
95
- lowerFilter(command.filter),
118
+ await lowerFilter(command.filter, this.#codecs, ctx),
96
119
  command.sort,
97
120
  );
98
121
  case 'aggregate':
99
- return new AggregateWireCommand(command.collection, lowerPipeline(command.pipeline));
122
+ return new AggregateWireCommand(
123
+ command.collection,
124
+ await lowerPipeline(command.pipeline, this.#codecs, ctx),
125
+ );
100
126
  case 'rawAggregate':
101
127
  return new AggregateWireCommand(command.collection, command.pipeline);
102
128
  case 'rawInsertOne':
@@ -131,32 +157,26 @@ class MongoAdapterImpl implements MongoAdapter {
131
157
  }
132
158
  }
133
159
 
134
- import {
135
- mongoBooleanCodec,
136
- mongoDateCodec,
137
- mongoDoubleCodec,
138
- mongoInt32Codec,
139
- mongoObjectIdCodec,
140
- mongoStringCodec,
141
- mongoVectorCodec,
142
- } from './core/codecs';
143
-
144
- function defaultCodecRegistry(): MongoCodecRegistry {
145
- const registry = createMongoCodecRegistry();
146
- for (const codec of [
147
- mongoObjectIdCodec,
148
- mongoStringCodec,
149
- mongoDoubleCodec,
150
- mongoInt32Codec,
151
- mongoBooleanCodec,
152
- mongoDateCodec,
153
- mongoVectorCodec,
154
- ]) {
155
- registry.register(codec);
156
- }
157
- return registry;
160
+ /**
161
+ * Construct a Mongo adapter with the standard wire-type codecs registered
162
+ * for encode-side dispatch (`MongoParamRef.codecId` lookups).
163
+ *
164
+ * The runtime-side codec registry the runtime decodes against is composed
165
+ * separately by `createMongoExecutionContext`. This factory exists for
166
+ * direct adapter use (the runtime descriptor's `create(stack)` calls
167
+ * through it). User code should compose a stack/context instead.
168
+ */
169
+ export function createMongoAdapter(): MongoAdapter {
170
+ return new MongoAdapterImpl(buildStandardCodecRegistry());
158
171
  }
159
172
 
160
- export function createMongoAdapter(codecs?: MongoCodecRegistry): MongoAdapter {
161
- return new MongoAdapterImpl(codecs ?? defaultCodecRegistry());
173
+ /**
174
+ * Internal escape hatch — direct adapter construction with a caller-supplied
175
+ * codec registry, used only by adapter unit tests that exercise the
176
+ * encode-side codec-dispatch path with synthetic codecs. Not re-exported
177
+ * from the package's public surface and not for production use; production
178
+ * callers compose a `MongoExecutionStack` and `MongoExecutionContext`.
179
+ */
180
+ export function _unstable_createMongoAdapterWithCodecs(codecs: MongoCodecRegistry): MongoAdapter {
181
+ return new MongoAdapterImpl(codecs);
162
182
  }
@@ -1,12 +1,69 @@
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';
1
7
  import type { MongoCodecRegistry } from '@prisma-next/mongo-codec';
2
8
  import type { MongoValue } from '@prisma-next/mongo-value';
3
9
  import { MongoParamRef } from '@prisma-next/mongo-value';
4
10
 
5
- export function resolveValue(value: MongoValue, codecs?: MongoCodecRegistry): unknown {
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`. An already-wrapped envelope is
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).
42
+ */
43
+ export async function resolveValue(
44
+ value: MongoValue,
45
+ codecs: MongoCodecRegistry,
46
+ ctx: CodecCallContext,
47
+ ): Promise<unknown> {
48
+ checkAborted(ctx, 'encode');
49
+ const signal = ctx.signal;
50
+
6
51
  if (value instanceof MongoParamRef) {
7
- if (value.codecId && codecs) {
52
+ if (value.codecId) {
8
53
  const codec = codecs.get(value.codecId);
9
- if (codec?.encode) return codec.encode(value.value);
54
+ if (codec?.encode) {
55
+ try {
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');
63
+ } catch (error) {
64
+ wrapEncodeFailure(error, value, codec.id);
65
+ }
66
+ }
10
67
  }
11
68
  return value.value;
12
69
  }
@@ -17,11 +74,45 @@ export function resolveValue(value: MongoValue, codecs?: MongoCodecRegistry): un
17
74
  return value;
18
75
  }
19
76
  if (Array.isArray(value)) {
20
- return value.map((v) => resolveValue(v, codecs));
77
+ const tasks = Promise.all(value.map((v) => resolveValue(v, codecs, ctx)));
78
+ return raceAgainstAbort(tasks, signal, 'encode');
21
79
  }
80
+ const entries = Object.entries(value);
81
+ const all = Promise.all(entries.map(([, val]) => resolveValue(val, codecs, ctx)));
82
+ const resolved = await raceAgainstAbort(all, signal, 'encode');
22
83
  const result: Record<string, unknown> = {};
23
- for (const [key, val] of Object.entries(value)) {
24
- result[key] = resolveValue(val, codecs);
84
+ for (let i = 0; i < entries.length; i++) {
85
+ const entry = entries[i];
86
+ if (entry) {
87
+ result[entry[0]] = resolved[i];
88
+ }
25
89
  }
26
90
  return result;
27
91
  }
92
+
93
+ function paramRefLabel(ref: MongoParamRef, codecId: string): string {
94
+ return ref.name ?? codecId;
95
+ }
96
+
97
+ function isAlreadyEncodeFailure(error: unknown): boolean {
98
+ return (
99
+ error instanceof Error &&
100
+ 'code' in error &&
101
+ (error as Error & { code?: unknown }).code === 'RUNTIME.ENCODE_FAILED'
102
+ );
103
+ }
104
+
105
+ function wrapEncodeFailure(error: unknown, ref: MongoParamRef, codecId: string): never {
106
+ if (isAlreadyEncodeFailure(error)) {
107
+ throw error;
108
+ }
109
+ const label = paramRefLabel(ref, codecId);
110
+ const message = error instanceof Error ? error.message : String(error);
111
+ const wrapped = runtimeError(
112
+ 'RUNTIME.ENCODE_FAILED',
113
+ `Failed to encode parameter ${label} with codec '${codecId}': ${message}`,
114
+ { label, codec: codecId },
115
+ );
116
+ wrapped.cause = error;
117
+ throw wrapped;
118
+ }
@@ -1 +0,0 @@
1
- {"version":3,"file":"mongo-adapter-aVo8aZrf.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","result: Record<string, unknown>","#resolveDocument","#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 { MongoCodecRegistry } from '@prisma-next/mongo-codec';\nimport type { MongoValue } from '@prisma-next/mongo-value';\nimport { MongoParamRef } from '@prisma-next/mongo-value';\n\nexport function resolveValue(value: MongoValue, codecs?: MongoCodecRegistry): unknown {\n if (value instanceof MongoParamRef) {\n if (value.codecId && codecs) {\n const codec = codecs.get(value.codecId);\n if (codec?.encode) return codec.encode(value.value);\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 value.map((v) => resolveValue(v, codecs));\n }\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(value)) {\n result[key] = resolveValue(val, codecs);\n }\n return result;\n}\n","import 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 function lowerFilter(filter: MongoFilterExpr): Document {\n switch (filter.kind) {\n case 'field':\n return { [filter.field]: { [filter.op]: resolveValue(filter.value) } };\n case 'and':\n return { $and: filter.exprs.map((e) => lowerFilter(e)) };\n case 'or':\n return { $or: filter.exprs.map((e) => lowerFilter(e)) };\n case 'not':\n return { $nor: [lowerFilter(filter.expr)] };\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 function lowerStage(stage: MongoPipelineStage): Record<string, unknown> {\n switch (stage.kind) {\n case 'match':\n return { $match: lowerFilter(stage.filter) };\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'] = stage.pipeline.map((s) => lowerStage(s));\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'] = stage.pipeline.map((s) => lowerStage(s));\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'] = lowerFilter(stage.query);\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 facet: Record<string, unknown> = {};\n for (const [key, pipeline] of Object.entries(stage.facets)) {\n facet[key] = pipeline.map((s) => lowerStage(s));\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'] = lowerFilter(stage.restrictSearchWithMatch);\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 ? stage.whenMatched.map((s) => lowerStage(s))\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 function lowerPipeline(\n stages: ReadonlyArray<MongoPipelineStage>,\n): Array<Record<string, unknown>> {\n return stages.map(lowerStage);\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});\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 #resolveDocument(expr: MongoExpr): Document {\n const result: Record<string, unknown> = {};\n for (const [key, val] of Object.entries(expr)) {\n result[key] = resolveValue(val, this.#codecs);\n }\n return result;\n }\n\n #lowerUpdate(update: MongoUpdateSpec): Document | ReadonlyArray<Document> {\n if (isUpdatePipeline(update)) {\n return update.map((stage) => lowerStage(stage));\n }\n return this.#resolveDocument(update);\n }\n\n lower(plan: MongoQueryPlan): AnyMongoWireCommand {\n const { command } = plan;\n switch (command.kind) {\n case 'insertOne':\n return new InsertOneWireCommand(\n command.collection,\n this.#resolveDocument(command.document),\n );\n case 'updateOne':\n return new UpdateOneWireCommand(\n command.collection,\n lowerFilter(command.filter),\n this.#lowerUpdate(command.update),\n command.upsert,\n );\n case 'insertMany':\n return new InsertManyWireCommand(\n command.collection,\n command.documents.map((doc) => this.#resolveDocument(doc)),\n );\n case 'updateMany':\n return new UpdateManyWireCommand(\n command.collection,\n lowerFilter(command.filter),\n this.#lowerUpdate(command.update),\n command.upsert,\n );\n case 'deleteOne':\n return new DeleteOneWireCommand(command.collection, lowerFilter(command.filter));\n case 'deleteMany':\n return new DeleteManyWireCommand(command.collection, lowerFilter(command.filter));\n case 'findOneAndUpdate':\n return new FindOneAndUpdateWireCommand(\n command.collection,\n lowerFilter(command.filter),\n this.#lowerUpdate(command.update),\n command.upsert,\n command.sort,\n command.returnDocument,\n );\n case 'findOneAndDelete':\n return new FindOneAndDeleteWireCommand(\n command.collection,\n lowerFilter(command.filter),\n command.sort,\n );\n case 'aggregate':\n return new AggregateWireCommand(command.collection, lowerPipeline(command.pipeline));\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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"}