@prisma-next/mongo-query-ast 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,482 @@
1
+ import { MongoAstNode } from './ast-node';
2
+ import type { MongoAggExprRewriter, MongoAggExprVisitor } from './visitors';
3
+
4
+ export type AggRecordArgs = Readonly<Record<string, MongoAggExpr | ReadonlyArray<MongoAggExpr>>>;
5
+
6
+ export function isExprArray(
7
+ args: MongoAggExpr | ReadonlyArray<MongoAggExpr> | AggRecordArgs,
8
+ ): args is ReadonlyArray<MongoAggExpr> {
9
+ return Array.isArray(args);
10
+ }
11
+
12
+ export function isRecordArgs(
13
+ args: MongoAggExpr | ReadonlyArray<MongoAggExpr> | AggRecordArgs,
14
+ ): args is AggRecordArgs {
15
+ return !Array.isArray(args) && typeof args === 'object' && !('accept' in args);
16
+ }
17
+
18
+ function freezeRecordArgs(record: AggRecordArgs): AggRecordArgs {
19
+ const frozen: Record<string, MongoAggExpr | ReadonlyArray<MongoAggExpr>> = {};
20
+ for (const [key, val] of Object.entries(record)) {
21
+ frozen[key] = Array.isArray(val) ? Object.freeze([...val]) : val;
22
+ }
23
+ return Object.freeze(frozen);
24
+ }
25
+
26
+ function rewriteRecordArgs(record: AggRecordArgs, rewriter: MongoAggExprRewriter): AggRecordArgs {
27
+ const result: Record<string, MongoAggExpr | ReadonlyArray<MongoAggExpr>> = {};
28
+ for (const [key, val] of Object.entries(record)) {
29
+ if (Array.isArray(val)) {
30
+ result[key] = val.map((v: MongoAggExpr) => v.rewrite(rewriter));
31
+ } else {
32
+ result[key] = (val as MongoAggExpr).rewrite(rewriter);
33
+ }
34
+ }
35
+ return result;
36
+ }
37
+
38
+ abstract class MongoAggExprNode extends MongoAstNode {
39
+ abstract accept<R>(visitor: MongoAggExprVisitor<R>): R;
40
+ abstract rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr;
41
+ }
42
+
43
+ export class MongoAggFieldRef extends MongoAggExprNode {
44
+ readonly kind = 'fieldRef' as const;
45
+ readonly path: string;
46
+
47
+ constructor(path: string) {
48
+ super();
49
+ if (!path) {
50
+ throw new Error('Field path must not be empty');
51
+ }
52
+ this.path = path;
53
+ this.freeze();
54
+ }
55
+
56
+ static of(path: string): MongoAggFieldRef {
57
+ return new MongoAggFieldRef(path);
58
+ }
59
+
60
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
61
+ return visitor.fieldRef(this);
62
+ }
63
+
64
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
65
+ return rewriter.fieldRef ? rewriter.fieldRef(this) : this;
66
+ }
67
+ }
68
+
69
+ export class MongoAggLiteral extends MongoAggExprNode {
70
+ readonly kind = 'literal' as const;
71
+ readonly value: unknown;
72
+
73
+ constructor(value: unknown) {
74
+ super();
75
+ this.value = value;
76
+ this.freeze();
77
+ }
78
+
79
+ static of(value: unknown): MongoAggLiteral {
80
+ return new MongoAggLiteral(value);
81
+ }
82
+
83
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
84
+ return visitor.literal(this);
85
+ }
86
+
87
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
88
+ return rewriter.literal ? rewriter.literal(this) : this;
89
+ }
90
+ }
91
+
92
+ export class MongoAggOperator extends MongoAggExprNode {
93
+ readonly kind = 'operator' as const;
94
+ readonly op: string;
95
+ readonly args: MongoAggExpr | ReadonlyArray<MongoAggExpr> | AggRecordArgs;
96
+
97
+ constructor(op: string, args: MongoAggExpr | ReadonlyArray<MongoAggExpr> | AggRecordArgs) {
98
+ super();
99
+ this.op = op;
100
+ if (Array.isArray(args)) {
101
+ this.args = Object.freeze([...args]);
102
+ } else if (isRecordArgs(args)) {
103
+ this.args = freezeRecordArgs(args);
104
+ } else {
105
+ this.args = args;
106
+ }
107
+ this.freeze();
108
+ }
109
+
110
+ static of(
111
+ op: string,
112
+ args: MongoAggExpr | ReadonlyArray<MongoAggExpr> | AggRecordArgs,
113
+ ): MongoAggOperator {
114
+ return new MongoAggOperator(op, args);
115
+ }
116
+
117
+ static add(...args: ReadonlyArray<MongoAggExpr>): MongoAggOperator {
118
+ return new MongoAggOperator('$add', args);
119
+ }
120
+
121
+ static subtract(left: MongoAggExpr, right: MongoAggExpr): MongoAggOperator {
122
+ return new MongoAggOperator('$subtract', [left, right]);
123
+ }
124
+
125
+ static multiply(...args: ReadonlyArray<MongoAggExpr>): MongoAggOperator {
126
+ return new MongoAggOperator('$multiply', args);
127
+ }
128
+
129
+ static divide(dividend: MongoAggExpr, divisor: MongoAggExpr): MongoAggOperator {
130
+ return new MongoAggOperator('$divide', [dividend, divisor]);
131
+ }
132
+
133
+ static concat(...args: ReadonlyArray<MongoAggExpr>): MongoAggOperator {
134
+ return new MongoAggOperator('$concat', args);
135
+ }
136
+
137
+ static toLower(expr: MongoAggExpr): MongoAggOperator {
138
+ return new MongoAggOperator('$toLower', expr);
139
+ }
140
+
141
+ static toUpper(expr: MongoAggExpr): MongoAggOperator {
142
+ return new MongoAggOperator('$toUpper', expr);
143
+ }
144
+
145
+ static size(expr: MongoAggExpr): MongoAggOperator {
146
+ return new MongoAggOperator('$size', expr);
147
+ }
148
+
149
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
150
+ return visitor.operator(this);
151
+ }
152
+
153
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
154
+ const { args } = this;
155
+ let rewrittenArgs: MongoAggExpr | ReadonlyArray<MongoAggExpr> | AggRecordArgs;
156
+ if (isExprArray(args)) {
157
+ rewrittenArgs = args.map((a) => a.rewrite(rewriter));
158
+ } else if (isRecordArgs(args)) {
159
+ rewrittenArgs = rewriteRecordArgs(args, rewriter);
160
+ } else {
161
+ rewrittenArgs = args.rewrite(rewriter);
162
+ }
163
+ const rebuilt = new MongoAggOperator(this.op, rewrittenArgs);
164
+ return rewriter.operator ? rewriter.operator(rebuilt) : rebuilt;
165
+ }
166
+ }
167
+
168
+ export class MongoAggAccumulator extends MongoAggExprNode {
169
+ readonly kind = 'accumulator' as const;
170
+ readonly op: string;
171
+ readonly arg: MongoAggExpr | AggRecordArgs | null;
172
+
173
+ constructor(op: string, arg: MongoAggExpr | AggRecordArgs | null) {
174
+ super();
175
+ this.op = op;
176
+ if (arg !== null && isRecordArgs(arg)) {
177
+ this.arg = freezeRecordArgs(arg);
178
+ } else {
179
+ this.arg = arg;
180
+ }
181
+ this.freeze();
182
+ }
183
+
184
+ static of(op: string, arg: MongoAggExpr | AggRecordArgs | null): MongoAggAccumulator {
185
+ return new MongoAggAccumulator(op, arg);
186
+ }
187
+
188
+ static sum(expr: MongoAggExpr): MongoAggAccumulator {
189
+ return new MongoAggAccumulator('$sum', expr);
190
+ }
191
+
192
+ static avg(expr: MongoAggExpr): MongoAggAccumulator {
193
+ return new MongoAggAccumulator('$avg', expr);
194
+ }
195
+
196
+ static min(expr: MongoAggExpr): MongoAggAccumulator {
197
+ return new MongoAggAccumulator('$min', expr);
198
+ }
199
+
200
+ static max(expr: MongoAggExpr): MongoAggAccumulator {
201
+ return new MongoAggAccumulator('$max', expr);
202
+ }
203
+
204
+ static first(expr: MongoAggExpr): MongoAggAccumulator {
205
+ return new MongoAggAccumulator('$first', expr);
206
+ }
207
+
208
+ static last(expr: MongoAggExpr): MongoAggAccumulator {
209
+ return new MongoAggAccumulator('$last', expr);
210
+ }
211
+
212
+ static push(expr: MongoAggExpr): MongoAggAccumulator {
213
+ return new MongoAggAccumulator('$push', expr);
214
+ }
215
+
216
+ static addToSet(expr: MongoAggExpr): MongoAggAccumulator {
217
+ return new MongoAggAccumulator('$addToSet', expr);
218
+ }
219
+
220
+ static count(): MongoAggAccumulator {
221
+ return new MongoAggAccumulator('$count', null);
222
+ }
223
+
224
+ static stdDevPop(expr: MongoAggExpr): MongoAggAccumulator {
225
+ return new MongoAggAccumulator('$stdDevPop', expr);
226
+ }
227
+
228
+ static stdDevSamp(expr: MongoAggExpr): MongoAggAccumulator {
229
+ return new MongoAggAccumulator('$stdDevSamp', expr);
230
+ }
231
+
232
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
233
+ return visitor.accumulator(this);
234
+ }
235
+
236
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
237
+ let rewrittenArg: MongoAggExpr | AggRecordArgs | null;
238
+ if (this.arg === null) {
239
+ rewrittenArg = null;
240
+ } else if (isRecordArgs(this.arg)) {
241
+ rewrittenArg = rewriteRecordArgs(this.arg, rewriter);
242
+ } else {
243
+ rewrittenArg = this.arg.rewrite(rewriter);
244
+ }
245
+ const rebuilt = new MongoAggAccumulator(this.op, rewrittenArg);
246
+ return rewriter.accumulator ? rewriter.accumulator(rebuilt) : rebuilt;
247
+ }
248
+ }
249
+
250
+ export class MongoAggCond extends MongoAggExprNode {
251
+ readonly kind = 'cond' as const;
252
+ readonly condition: MongoAggExpr;
253
+ readonly then_: MongoAggExpr;
254
+ readonly else_: MongoAggExpr;
255
+
256
+ constructor(condition: MongoAggExpr, then_: MongoAggExpr, else_: MongoAggExpr) {
257
+ super();
258
+ this.condition = condition;
259
+ this.then_ = then_;
260
+ this.else_ = else_;
261
+ this.freeze();
262
+ }
263
+
264
+ static of(condition: MongoAggExpr, then_: MongoAggExpr, else_: MongoAggExpr): MongoAggCond {
265
+ return new MongoAggCond(condition, then_, else_);
266
+ }
267
+
268
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
269
+ return visitor.cond(this);
270
+ }
271
+
272
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
273
+ const rebuilt = new MongoAggCond(
274
+ this.condition.rewrite(rewriter),
275
+ this.then_.rewrite(rewriter),
276
+ this.else_.rewrite(rewriter),
277
+ );
278
+ return rewriter.cond ? rewriter.cond(rebuilt) : rebuilt;
279
+ }
280
+ }
281
+
282
+ export interface MongoAggSwitchBranch {
283
+ readonly case_: MongoAggExpr;
284
+ readonly then_: MongoAggExpr;
285
+ }
286
+
287
+ export class MongoAggSwitch extends MongoAggExprNode {
288
+ readonly kind = 'switch' as const;
289
+ readonly branches: ReadonlyArray<MongoAggSwitchBranch>;
290
+ readonly default_: MongoAggExpr;
291
+
292
+ constructor(branches: ReadonlyArray<MongoAggSwitchBranch>, default_: MongoAggExpr) {
293
+ super();
294
+ this.branches = Object.freeze(
295
+ branches.map((b) => Object.freeze({ case_: b.case_, then_: b.then_ })),
296
+ );
297
+ this.default_ = default_;
298
+ this.freeze();
299
+ }
300
+
301
+ static of(branches: ReadonlyArray<MongoAggSwitchBranch>, default_: MongoAggExpr): MongoAggSwitch {
302
+ return new MongoAggSwitch(branches, default_);
303
+ }
304
+
305
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
306
+ return visitor.switch_(this);
307
+ }
308
+
309
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
310
+ const rebuilt = new MongoAggSwitch(
311
+ this.branches.map((b) => ({
312
+ case_: b.case_.rewrite(rewriter),
313
+ then_: b.then_.rewrite(rewriter),
314
+ })),
315
+ this.default_.rewrite(rewriter),
316
+ );
317
+ return rewriter.switch_ ? rewriter.switch_(rebuilt) : rebuilt;
318
+ }
319
+ }
320
+
321
+ export class MongoAggArrayFilter extends MongoAggExprNode {
322
+ readonly kind = 'filter' as const;
323
+ readonly input: MongoAggExpr;
324
+ readonly cond: MongoAggExpr;
325
+ readonly as: string;
326
+
327
+ constructor(input: MongoAggExpr, cond: MongoAggExpr, as: string) {
328
+ super();
329
+ this.input = input;
330
+ this.cond = cond;
331
+ this.as = as;
332
+ this.freeze();
333
+ }
334
+
335
+ static of(input: MongoAggExpr, cond: MongoAggExpr, as: string): MongoAggArrayFilter {
336
+ return new MongoAggArrayFilter(input, cond, as);
337
+ }
338
+
339
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
340
+ return visitor.filter(this);
341
+ }
342
+
343
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
344
+ const rebuilt = new MongoAggArrayFilter(
345
+ this.input.rewrite(rewriter),
346
+ this.cond.rewrite(rewriter),
347
+ this.as,
348
+ );
349
+ return rewriter.filter ? rewriter.filter(rebuilt) : rebuilt;
350
+ }
351
+ }
352
+
353
+ export class MongoAggMap extends MongoAggExprNode {
354
+ readonly kind = 'map' as const;
355
+ readonly input: MongoAggExpr;
356
+ readonly in_: MongoAggExpr;
357
+ readonly as: string;
358
+
359
+ constructor(input: MongoAggExpr, in_: MongoAggExpr, as: string) {
360
+ super();
361
+ this.input = input;
362
+ this.in_ = in_;
363
+ this.as = as;
364
+ this.freeze();
365
+ }
366
+
367
+ static of(input: MongoAggExpr, in_: MongoAggExpr, as: string): MongoAggMap {
368
+ return new MongoAggMap(input, in_, as);
369
+ }
370
+
371
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
372
+ return visitor.map(this);
373
+ }
374
+
375
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
376
+ const rebuilt = new MongoAggMap(
377
+ this.input.rewrite(rewriter),
378
+ this.in_.rewrite(rewriter),
379
+ this.as,
380
+ );
381
+ return rewriter.map ? rewriter.map(rebuilt) : rebuilt;
382
+ }
383
+ }
384
+
385
+ export class MongoAggReduce extends MongoAggExprNode {
386
+ readonly kind = 'reduce' as const;
387
+ readonly input: MongoAggExpr;
388
+ readonly initialValue: MongoAggExpr;
389
+ readonly in_: MongoAggExpr;
390
+
391
+ constructor(input: MongoAggExpr, initialValue: MongoAggExpr, in_: MongoAggExpr) {
392
+ super();
393
+ this.input = input;
394
+ this.initialValue = initialValue;
395
+ this.in_ = in_;
396
+ this.freeze();
397
+ }
398
+
399
+ static of(input: MongoAggExpr, initialValue: MongoAggExpr, in_: MongoAggExpr): MongoAggReduce {
400
+ return new MongoAggReduce(input, initialValue, in_);
401
+ }
402
+
403
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
404
+ return visitor.reduce(this);
405
+ }
406
+
407
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
408
+ const rebuilt = new MongoAggReduce(
409
+ this.input.rewrite(rewriter),
410
+ this.initialValue.rewrite(rewriter),
411
+ this.in_.rewrite(rewriter),
412
+ );
413
+ return rewriter.reduce ? rewriter.reduce(rebuilt) : rebuilt;
414
+ }
415
+ }
416
+
417
+ export class MongoAggLet extends MongoAggExprNode {
418
+ readonly kind = 'let' as const;
419
+ readonly vars: Readonly<Record<string, MongoAggExpr>>;
420
+ readonly in_: MongoAggExpr;
421
+
422
+ constructor(vars: Record<string, MongoAggExpr>, in_: MongoAggExpr) {
423
+ super();
424
+ this.vars = Object.freeze({ ...vars });
425
+ this.in_ = in_;
426
+ this.freeze();
427
+ }
428
+
429
+ static of(vars: Record<string, MongoAggExpr>, in_: MongoAggExpr): MongoAggLet {
430
+ return new MongoAggLet(vars, in_);
431
+ }
432
+
433
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
434
+ return visitor.let_(this);
435
+ }
436
+
437
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
438
+ const rewrittenVars: Record<string, MongoAggExpr> = {};
439
+ for (const [key, val] of Object.entries(this.vars)) {
440
+ rewrittenVars[key] = val.rewrite(rewriter);
441
+ }
442
+ const rebuilt = new MongoAggLet(rewrittenVars, this.in_.rewrite(rewriter));
443
+ return rewriter.let_ ? rewriter.let_(rebuilt) : rebuilt;
444
+ }
445
+ }
446
+
447
+ export class MongoAggMergeObjects extends MongoAggExprNode {
448
+ readonly kind = 'mergeObjects' as const;
449
+ readonly exprs: ReadonlyArray<MongoAggExpr>;
450
+
451
+ constructor(exprs: ReadonlyArray<MongoAggExpr>) {
452
+ super();
453
+ this.exprs = Object.freeze([...exprs]);
454
+ this.freeze();
455
+ }
456
+
457
+ static of(exprs: ReadonlyArray<MongoAggExpr>): MongoAggMergeObjects {
458
+ return new MongoAggMergeObjects(exprs);
459
+ }
460
+
461
+ accept<R>(visitor: MongoAggExprVisitor<R>): R {
462
+ return visitor.mergeObjects(this);
463
+ }
464
+
465
+ rewrite(rewriter: MongoAggExprRewriter): MongoAggExpr {
466
+ const rebuilt = new MongoAggMergeObjects(this.exprs.map((e) => e.rewrite(rewriter)));
467
+ return rewriter.mergeObjects ? rewriter.mergeObjects(rebuilt) : rebuilt;
468
+ }
469
+ }
470
+
471
+ export type MongoAggExpr =
472
+ | MongoAggFieldRef
473
+ | MongoAggLiteral
474
+ | MongoAggOperator
475
+ | MongoAggAccumulator
476
+ | MongoAggCond
477
+ | MongoAggSwitch
478
+ | MongoAggArrayFilter
479
+ | MongoAggMap
480
+ | MongoAggReduce
481
+ | MongoAggLet
482
+ | MongoAggMergeObjects;
@@ -0,0 +1,7 @@
1
+ export abstract class MongoAstNode {
2
+ abstract readonly kind: string;
3
+
4
+ protected freeze(): void {
5
+ Object.freeze(this);
6
+ }
7
+ }
@@ -0,0 +1,148 @@
1
+ import type { MongoValue } from '@prisma-next/mongo-value';
2
+ import { MongoAstNode } from './ast-node';
3
+ import type { MongoFilterExpr } from './filter-expressions';
4
+ import type { RawMongoCommand } from './raw-commands';
5
+ import type { MongoPipelineStage, MongoUpdatePipelineStage } from './stages';
6
+ export type MongoUpdateSpec = Record<string, MongoValue> | ReadonlyArray<MongoUpdatePipelineStage>;
7
+
8
+ export class InsertOneCommand extends MongoAstNode {
9
+ readonly kind = 'insertOne' as const;
10
+ readonly collection: string;
11
+ readonly document: Record<string, MongoValue>;
12
+
13
+ constructor(collection: string, document: Record<string, MongoValue>) {
14
+ super();
15
+ this.collection = collection;
16
+ this.document = document;
17
+ this.freeze();
18
+ }
19
+ }
20
+
21
+ export class UpdateOneCommand extends MongoAstNode {
22
+ readonly kind = 'updateOne' as const;
23
+ readonly collection: string;
24
+ readonly filter: MongoFilterExpr;
25
+ readonly update: MongoUpdateSpec;
26
+
27
+ constructor(collection: string, filter: MongoFilterExpr, update: MongoUpdateSpec) {
28
+ super();
29
+ this.collection = collection;
30
+ this.filter = filter;
31
+ this.update = update;
32
+ this.freeze();
33
+ }
34
+ }
35
+
36
+ export class DeleteOneCommand extends MongoAstNode {
37
+ readonly kind = 'deleteOne' as const;
38
+ readonly collection: string;
39
+ readonly filter: MongoFilterExpr;
40
+
41
+ constructor(collection: string, filter: MongoFilterExpr) {
42
+ super();
43
+ this.collection = collection;
44
+ this.filter = filter;
45
+ this.freeze();
46
+ }
47
+ }
48
+
49
+ export class InsertManyCommand extends MongoAstNode {
50
+ readonly kind = 'insertMany' as const;
51
+ readonly collection: string;
52
+ readonly documents: ReadonlyArray<Record<string, MongoValue>>;
53
+
54
+ constructor(collection: string, documents: ReadonlyArray<Record<string, MongoValue>>) {
55
+ super();
56
+ this.collection = collection;
57
+ this.documents = documents;
58
+ this.freeze();
59
+ }
60
+ }
61
+
62
+ export class UpdateManyCommand extends MongoAstNode {
63
+ readonly kind = 'updateMany' as const;
64
+ readonly collection: string;
65
+ readonly filter: MongoFilterExpr;
66
+ readonly update: MongoUpdateSpec;
67
+
68
+ constructor(collection: string, filter: MongoFilterExpr, update: MongoUpdateSpec) {
69
+ super();
70
+ this.collection = collection;
71
+ this.filter = filter;
72
+ this.update = update;
73
+ this.freeze();
74
+ }
75
+ }
76
+
77
+ export class DeleteManyCommand extends MongoAstNode {
78
+ readonly kind = 'deleteMany' as const;
79
+ readonly collection: string;
80
+ readonly filter: MongoFilterExpr;
81
+
82
+ constructor(collection: string, filter: MongoFilterExpr) {
83
+ super();
84
+ this.collection = collection;
85
+ this.filter = filter;
86
+ this.freeze();
87
+ }
88
+ }
89
+
90
+ export class FindOneAndUpdateCommand extends MongoAstNode {
91
+ readonly kind = 'findOneAndUpdate' as const;
92
+ readonly collection: string;
93
+ readonly filter: MongoFilterExpr;
94
+ readonly update: MongoUpdateSpec;
95
+ readonly upsert: boolean;
96
+
97
+ constructor(
98
+ collection: string,
99
+ filter: MongoFilterExpr,
100
+ update: MongoUpdateSpec,
101
+ upsert: boolean,
102
+ ) {
103
+ super();
104
+ this.collection = collection;
105
+ this.filter = filter;
106
+ this.update = update;
107
+ this.upsert = upsert;
108
+ this.freeze();
109
+ }
110
+ }
111
+
112
+ export class FindOneAndDeleteCommand extends MongoAstNode {
113
+ readonly kind = 'findOneAndDelete' as const;
114
+ readonly collection: string;
115
+ readonly filter: MongoFilterExpr;
116
+
117
+ constructor(collection: string, filter: MongoFilterExpr) {
118
+ super();
119
+ this.collection = collection;
120
+ this.filter = filter;
121
+ this.freeze();
122
+ }
123
+ }
124
+
125
+ export class AggregateCommand extends MongoAstNode {
126
+ readonly kind = 'aggregate' as const;
127
+ readonly collection: string;
128
+ readonly pipeline: ReadonlyArray<MongoPipelineStage>;
129
+
130
+ constructor(collection: string, pipeline: ReadonlyArray<MongoPipelineStage>) {
131
+ super();
132
+ this.collection = collection;
133
+ this.pipeline = pipeline;
134
+ this.freeze();
135
+ }
136
+ }
137
+
138
+ export type AnyMongoCommand =
139
+ | InsertOneCommand
140
+ | InsertManyCommand
141
+ | UpdateOneCommand
142
+ | UpdateManyCommand
143
+ | DeleteOneCommand
144
+ | DeleteManyCommand
145
+ | FindOneAndUpdateCommand
146
+ | FindOneAndDeleteCommand
147
+ | AggregateCommand
148
+ | RawMongoCommand;