@zodmon/core 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +708 -44
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2101 -954
- package/dist/index.d.ts +2101 -954
- package/dist/index.js +695 -44
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -21,29 +21,42 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
var index_exports = {};
|
|
22
22
|
__export(index_exports, {
|
|
23
23
|
$: () => $,
|
|
24
|
+
$addToSet: () => $addToSet,
|
|
24
25
|
$and: () => $and,
|
|
26
|
+
$avg: () => $avg,
|
|
27
|
+
$count: () => $count,
|
|
25
28
|
$eq: () => $eq,
|
|
26
29
|
$exists: () => $exists,
|
|
30
|
+
$first: () => $first,
|
|
27
31
|
$gt: () => $gt,
|
|
28
32
|
$gte: () => $gte,
|
|
29
33
|
$in: () => $in,
|
|
34
|
+
$last: () => $last,
|
|
30
35
|
$lt: () => $lt,
|
|
31
36
|
$lte: () => $lte,
|
|
37
|
+
$max: () => $max,
|
|
38
|
+
$min: () => $min,
|
|
32
39
|
$ne: () => $ne,
|
|
33
40
|
$nin: () => $nin,
|
|
34
41
|
$nor: () => $nor,
|
|
35
42
|
$not: () => $not,
|
|
36
43
|
$or: () => $or,
|
|
44
|
+
$push: () => $push,
|
|
37
45
|
$regex: () => $regex,
|
|
46
|
+
$sum: () => $sum,
|
|
47
|
+
AggregatePipeline: () => AggregatePipeline,
|
|
38
48
|
CollectionHandle: () => CollectionHandle,
|
|
39
49
|
Database: () => Database,
|
|
40
50
|
IndexBuilder: () => IndexBuilder,
|
|
41
51
|
TypedFindCursor: () => TypedFindCursor,
|
|
42
52
|
ZodmonNotFoundError: () => ZodmonNotFoundError,
|
|
43
53
|
ZodmonValidationError: () => ZodmonValidationError,
|
|
54
|
+
aggregate: () => aggregate,
|
|
44
55
|
checkUnindexedFields: () => checkUnindexedFields,
|
|
45
56
|
collection: () => collection,
|
|
57
|
+
createAccumulatorBuilder: () => createAccumulatorBuilder,
|
|
46
58
|
createClient: () => createClient,
|
|
59
|
+
createExpressionBuilder: () => createExpressionBuilder,
|
|
47
60
|
deleteMany: () => deleteMany,
|
|
48
61
|
deleteOne: () => deleteOne,
|
|
49
62
|
extractComparableOptions: () => extractComparableOptions,
|
|
@@ -73,6 +86,655 @@ __export(index_exports, {
|
|
|
73
86
|
});
|
|
74
87
|
module.exports = __toCommonJS(index_exports);
|
|
75
88
|
|
|
89
|
+
// src/aggregate/expressions.ts
|
|
90
|
+
var $count = () => ({
|
|
91
|
+
__accum: true,
|
|
92
|
+
expr: { $sum: 1 }
|
|
93
|
+
});
|
|
94
|
+
var $sum = (field) => ({
|
|
95
|
+
__accum: true,
|
|
96
|
+
expr: { $sum: field }
|
|
97
|
+
});
|
|
98
|
+
var $avg = (field) => ({
|
|
99
|
+
__accum: true,
|
|
100
|
+
expr: { $avg: field }
|
|
101
|
+
});
|
|
102
|
+
var $min = (field) => ({
|
|
103
|
+
__accum: true,
|
|
104
|
+
expr: { $min: field }
|
|
105
|
+
});
|
|
106
|
+
var $max = (field) => ({
|
|
107
|
+
__accum: true,
|
|
108
|
+
expr: { $max: field }
|
|
109
|
+
});
|
|
110
|
+
var $first = (field) => ({
|
|
111
|
+
__accum: true,
|
|
112
|
+
expr: { $first: field }
|
|
113
|
+
});
|
|
114
|
+
var $last = (field) => ({
|
|
115
|
+
__accum: true,
|
|
116
|
+
expr: { $last: field }
|
|
117
|
+
});
|
|
118
|
+
var $push = (field) => ({
|
|
119
|
+
__accum: true,
|
|
120
|
+
expr: { $push: field }
|
|
121
|
+
});
|
|
122
|
+
var $addToSet = (field) => ({
|
|
123
|
+
__accum: true,
|
|
124
|
+
expr: { $addToSet: field }
|
|
125
|
+
});
|
|
126
|
+
function createAccumulatorBuilder() {
|
|
127
|
+
return {
|
|
128
|
+
count: () => ({ __accum: true, expr: { $sum: 1 } }),
|
|
129
|
+
sum: (field) => ({
|
|
130
|
+
__accum: true,
|
|
131
|
+
expr: { $sum: typeof field === "number" ? field : `$${field}` }
|
|
132
|
+
}),
|
|
133
|
+
avg: (field) => ({ __accum: true, expr: { $avg: `$${field}` } }),
|
|
134
|
+
min: (field) => ({ __accum: true, expr: { $min: `$${field}` } }),
|
|
135
|
+
max: (field) => ({ __accum: true, expr: { $max: `$${field}` } }),
|
|
136
|
+
first: (field) => ({ __accum: true, expr: { $first: `$${field}` } }),
|
|
137
|
+
last: (field) => ({ __accum: true, expr: { $last: `$${field}` } }),
|
|
138
|
+
push: (field) => ({ __accum: true, expr: { $push: `$${field}` } }),
|
|
139
|
+
addToSet: (field) => ({ __accum: true, expr: { $addToSet: `$${field}` } })
|
|
140
|
+
// biome-ignore lint/suspicious/noExplicitAny: Runtime implementation uses string field names and returns plain objects — TypeScript cannot verify that the runtime Accumulator objects match the generic AccumulatorBuilder<T> return types. Safe because type resolution happens at compile time via AccumulatorBuilder<T>, and runtime values are identical to what the standalone $min/$max/etc. produce.
|
|
141
|
+
};
|
|
142
|
+
}
|
|
143
|
+
function createExpressionBuilder() {
|
|
144
|
+
const $2 = (field) => `$${field}`;
|
|
145
|
+
const val = (v) => typeof v === "number" ? v : `$${v}`;
|
|
146
|
+
const expr = (value) => ({ __expr: true, value });
|
|
147
|
+
return {
|
|
148
|
+
// Arithmetic
|
|
149
|
+
add: (field, value) => expr({ $add: [$2(field), val(value)] }),
|
|
150
|
+
subtract: (field, value) => expr({ $subtract: [$2(field), val(value)] }),
|
|
151
|
+
multiply: (field, value) => expr({ $multiply: [$2(field), val(value)] }),
|
|
152
|
+
divide: (field, value) => expr({ $divide: [$2(field), val(value)] }),
|
|
153
|
+
mod: (field, value) => expr({ $mod: [$2(field), val(value)] }),
|
|
154
|
+
abs: (field) => expr({ $abs: $2(field) }),
|
|
155
|
+
ceil: (field) => expr({ $ceil: $2(field) }),
|
|
156
|
+
floor: (field) => expr({ $floor: $2(field) }),
|
|
157
|
+
round: (field, place = 0) => expr({ $round: [$2(field), place] }),
|
|
158
|
+
// String
|
|
159
|
+
concat: (...parts) => {
|
|
160
|
+
const resolved = parts.map((p) => {
|
|
161
|
+
if (/^[a-zA-Z_][a-zA-Z0-9_]*$/.test(p)) return $2(p);
|
|
162
|
+
return p;
|
|
163
|
+
});
|
|
164
|
+
return expr({ $concat: resolved });
|
|
165
|
+
},
|
|
166
|
+
toLower: (field) => expr({ $toLower: $2(field) }),
|
|
167
|
+
toUpper: (field) => expr({ $toUpper: $2(field) }),
|
|
168
|
+
trim: (field) => expr({ $trim: { input: $2(field) } }),
|
|
169
|
+
substr: (field, start, length) => expr({ $substrBytes: [$2(field), start, length] }),
|
|
170
|
+
// Comparison
|
|
171
|
+
eq: (field, value) => expr({ $eq: [$2(field), value] }),
|
|
172
|
+
gt: (field, value) => expr({ $gt: [$2(field), value] }),
|
|
173
|
+
gte: (field, value) => expr({ $gte: [$2(field), value] }),
|
|
174
|
+
lt: (field, value) => expr({ $lt: [$2(field), value] }),
|
|
175
|
+
lte: (field, value) => expr({ $lte: [$2(field), value] }),
|
|
176
|
+
ne: (field, value) => expr({ $ne: [$2(field), value] }),
|
|
177
|
+
// Date
|
|
178
|
+
year: (field) => expr({ $year: $2(field) }),
|
|
179
|
+
month: (field) => expr({ $month: $2(field) }),
|
|
180
|
+
dayOfMonth: (field) => expr({ $dayOfMonth: $2(field) }),
|
|
181
|
+
// Array
|
|
182
|
+
size: (field) => expr({ $size: $2(field) }),
|
|
183
|
+
// Conditional
|
|
184
|
+
cond: (condition, thenValue, elseValue) => expr({ $cond: [condition.value, thenValue, elseValue] }),
|
|
185
|
+
ifNull: (field, fallback) => expr({ $ifNull: [$2(field), fallback] })
|
|
186
|
+
// biome-ignore lint/suspicious/noExplicitAny: Runtime implementation uses string field names — TypeScript cannot verify generic ExpressionBuilder<T> return types match. Safe because type resolution happens at compile time.
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/schema/ref.ts
|
|
191
|
+
var import_zod = require("zod");
|
|
192
|
+
var refMetadata = /* @__PURE__ */ new WeakMap();
|
|
193
|
+
function getRefMetadata(schema) {
|
|
194
|
+
if (typeof schema !== "object" || schema === null) return void 0;
|
|
195
|
+
return refMetadata.get(schema);
|
|
196
|
+
}
|
|
197
|
+
var REF_GUARD = /* @__PURE__ */ Symbol.for("zodmon_ref");
|
|
198
|
+
function installRefExtension() {
|
|
199
|
+
const proto = import_zod.z.ZodType.prototype;
|
|
200
|
+
if (REF_GUARD in proto) return;
|
|
201
|
+
Object.defineProperty(proto, "ref", {
|
|
202
|
+
value(collection2) {
|
|
203
|
+
refMetadata.set(this, { collection: collection2 });
|
|
204
|
+
return this;
|
|
205
|
+
},
|
|
206
|
+
enumerable: true,
|
|
207
|
+
configurable: true,
|
|
208
|
+
writable: true
|
|
209
|
+
});
|
|
210
|
+
Object.defineProperty(proto, REF_GUARD, {
|
|
211
|
+
value: true,
|
|
212
|
+
enumerable: false,
|
|
213
|
+
configurable: false,
|
|
214
|
+
writable: false
|
|
215
|
+
});
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// src/aggregate/pipeline.ts
|
|
219
|
+
var AggregatePipeline = class _AggregatePipeline {
|
|
220
|
+
definition;
|
|
221
|
+
nativeCollection;
|
|
222
|
+
stages;
|
|
223
|
+
constructor(definition, nativeCollection, stages) {
|
|
224
|
+
this.definition = definition;
|
|
225
|
+
this.nativeCollection = nativeCollection;
|
|
226
|
+
this.stages = stages;
|
|
227
|
+
}
|
|
228
|
+
/**
|
|
229
|
+
* Append an arbitrary aggregation stage to the pipeline (escape hatch).
|
|
230
|
+
*
|
|
231
|
+
* Returns a new pipeline instance with the stage appended — the
|
|
232
|
+
* original pipeline is not modified.
|
|
233
|
+
*
|
|
234
|
+
* Optionally accepts a type parameter `TNew` to change the output
|
|
235
|
+
* type when the stage transforms the document shape.
|
|
236
|
+
*
|
|
237
|
+
* @typeParam TNew - The output type after this stage. Defaults to the current output type.
|
|
238
|
+
* @param stage - A raw MongoDB aggregation stage document (e.g. `{ $match: { ... } }`).
|
|
239
|
+
* @returns A new pipeline with the stage appended.
|
|
240
|
+
*
|
|
241
|
+
* @example
|
|
242
|
+
* ```ts
|
|
243
|
+
* const admins = aggregate(users)
|
|
244
|
+
* .raw({ $match: { role: 'admin' } })
|
|
245
|
+
* .toArray()
|
|
246
|
+
* ```
|
|
247
|
+
*
|
|
248
|
+
* @example
|
|
249
|
+
* ```ts
|
|
250
|
+
* // Change output type with a $project stage
|
|
251
|
+
* const names = aggregate(users)
|
|
252
|
+
* .raw<{ name: string }>({ $project: { name: 1, _id: 0 } })
|
|
253
|
+
* .toArray()
|
|
254
|
+
* ```
|
|
255
|
+
*/
|
|
256
|
+
raw(stage) {
|
|
257
|
+
return new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
258
|
+
...this.stages,
|
|
259
|
+
stage
|
|
260
|
+
]);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Execute the pipeline and return all results as an array.
|
|
264
|
+
*
|
|
265
|
+
* @returns A promise resolving to the array of output documents.
|
|
266
|
+
*
|
|
267
|
+
* @example
|
|
268
|
+
* ```ts
|
|
269
|
+
* const results = await aggregate(users)
|
|
270
|
+
* .raw({ $match: { age: { $gte: 18 } } })
|
|
271
|
+
* .toArray()
|
|
272
|
+
* ```
|
|
273
|
+
*/
|
|
274
|
+
async toArray() {
|
|
275
|
+
const cursor = this.nativeCollection.aggregate(this.stages);
|
|
276
|
+
return await cursor.toArray();
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Stream pipeline results one document at a time via `for await...of`.
|
|
280
|
+
*
|
|
281
|
+
* @returns An async generator yielding output documents.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* ```ts
|
|
285
|
+
* for await (const user of aggregate(users).raw({ $match: { role: 'admin' } })) {
|
|
286
|
+
* console.log(user.name)
|
|
287
|
+
* }
|
|
288
|
+
* ```
|
|
289
|
+
*/
|
|
290
|
+
async *[Symbol.asyncIterator]() {
|
|
291
|
+
const cursor = this.nativeCollection.aggregate(this.stages);
|
|
292
|
+
for await (const doc of cursor) {
|
|
293
|
+
yield doc;
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Return the query execution plan without running the pipeline.
|
|
298
|
+
*
|
|
299
|
+
* Useful for debugging and understanding how MongoDB will process
|
|
300
|
+
* the pipeline stages.
|
|
301
|
+
*
|
|
302
|
+
* @returns A promise resolving to the explain output document.
|
|
303
|
+
*
|
|
304
|
+
* @example
|
|
305
|
+
* ```ts
|
|
306
|
+
* const plan = await aggregate(users)
|
|
307
|
+
* .raw({ $match: { role: 'admin' } })
|
|
308
|
+
* .explain()
|
|
309
|
+
* console.log(plan)
|
|
310
|
+
* ```
|
|
311
|
+
*/
|
|
312
|
+
async explain() {
|
|
313
|
+
const cursor = this.nativeCollection.aggregate(this.stages);
|
|
314
|
+
return await cursor.explain();
|
|
315
|
+
}
|
|
316
|
+
// ── Shape-preserving stages ──────────────────────────────────────
|
|
317
|
+
/**
|
|
318
|
+
* Filter documents using a type-safe match expression.
|
|
319
|
+
*
|
|
320
|
+
* Appends a `$match` stage to the pipeline. The filter is constrained
|
|
321
|
+
* to the current output type, so only valid fields and operators are accepted.
|
|
322
|
+
*
|
|
323
|
+
* Supports two forms of type narrowing:
|
|
324
|
+
*
|
|
325
|
+
* **Tier 1 — Explicit type parameter:**
|
|
326
|
+
* ```ts
|
|
327
|
+
* .match<{ role: 'engineer' | 'designer' }>({ role: { $in: ['engineer', 'designer'] } })
|
|
328
|
+
* // role narrows to 'engineer' | 'designer'
|
|
329
|
+
* ```
|
|
330
|
+
*
|
|
331
|
+
* **Tier 2 — Automatic inference from filter literals:**
|
|
332
|
+
* ```ts
|
|
333
|
+
* .match({ role: 'engineer' }) // role narrows to 'engineer'
|
|
334
|
+
* .match({ role: { $ne: 'intern' } }) // role narrows to Exclude<Role, 'intern'>
|
|
335
|
+
* .match({ role: { $in: ['engineer', 'designer'] as const } }) // needs as const
|
|
336
|
+
* ```
|
|
337
|
+
*
|
|
338
|
+
* When no type parameter is provided and the filter doesn't contain
|
|
339
|
+
* inferrable literals, the output type is unchanged (backward compatible).
|
|
340
|
+
*
|
|
341
|
+
* @typeParam TNarrow - Optional object mapping field names to narrowed types. Must be a subtype of the corresponding fields in TOutput.
|
|
342
|
+
* @typeParam F - Inferred from the filter argument. Do not provide explicitly.
|
|
343
|
+
* @param filter - A type-safe filter for the current output type.
|
|
344
|
+
* @returns A new pipeline with the `$match` stage appended and output type narrowed.
|
|
345
|
+
*
|
|
346
|
+
* @example
|
|
347
|
+
* ```ts
|
|
348
|
+
* // Explicit narrowing
|
|
349
|
+
* const filtered = await users.aggregate()
|
|
350
|
+
* .match<{ role: 'engineer' }>({ role: 'engineer' })
|
|
351
|
+
* .toArray()
|
|
352
|
+
* // filtered[0].role → 'engineer'
|
|
353
|
+
*
|
|
354
|
+
* // Automatic narrowing with $in (requires as const)
|
|
355
|
+
* const subset = await users.aggregate()
|
|
356
|
+
* .match({ role: { $in: ['engineer', 'designer'] as const } })
|
|
357
|
+
* .toArray()
|
|
358
|
+
* // subset[0].role → 'engineer' | 'designer'
|
|
359
|
+
* ```
|
|
360
|
+
*/
|
|
361
|
+
match(filter) {
|
|
362
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
363
|
+
...this.stages,
|
|
364
|
+
{ $match: filter }
|
|
365
|
+
]);
|
|
366
|
+
return pipeline;
|
|
367
|
+
}
|
|
368
|
+
/**
|
|
369
|
+
* Sort documents by one or more fields.
|
|
370
|
+
*
|
|
371
|
+
* Appends a `$sort` stage. Keys are constrained to `keyof TOutput & string`
|
|
372
|
+
* and values must be `1` (ascending) or `-1` (descending).
|
|
373
|
+
*
|
|
374
|
+
* @param spec - A sort specification mapping field names to sort direction.
|
|
375
|
+
* @returns A new pipeline with the `$sort` stage appended.
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```ts
|
|
379
|
+
* const sorted = await aggregate(users)
|
|
380
|
+
* .sort({ age: -1, name: 1 })
|
|
381
|
+
* .toArray()
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
sort(spec) {
|
|
385
|
+
return new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
386
|
+
...this.stages,
|
|
387
|
+
{ $sort: spec }
|
|
388
|
+
]);
|
|
389
|
+
}
|
|
390
|
+
/**
|
|
391
|
+
* Skip a number of documents in the pipeline.
|
|
392
|
+
*
|
|
393
|
+
* Appends a `$skip` stage. Commonly used with {@link limit} for pagination.
|
|
394
|
+
*
|
|
395
|
+
* @param n - The number of documents to skip.
|
|
396
|
+
* @returns A new pipeline with the `$skip` stage appended.
|
|
397
|
+
*
|
|
398
|
+
* @example
|
|
399
|
+
* ```ts
|
|
400
|
+
* // Page 2 (10 items per page)
|
|
401
|
+
* const page2 = await aggregate(users)
|
|
402
|
+
* .sort({ name: 1 })
|
|
403
|
+
* .skip(10)
|
|
404
|
+
* .limit(10)
|
|
405
|
+
* .toArray()
|
|
406
|
+
* ```
|
|
407
|
+
*/
|
|
408
|
+
skip(n) {
|
|
409
|
+
return new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
410
|
+
...this.stages,
|
|
411
|
+
{ $skip: n }
|
|
412
|
+
]);
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Limit the number of documents passing through the pipeline.
|
|
416
|
+
*
|
|
417
|
+
* Appends a `$limit` stage. Commonly used with {@link skip} for pagination,
|
|
418
|
+
* or after {@link sort} to get top/bottom N results.
|
|
419
|
+
*
|
|
420
|
+
* @param n - The maximum number of documents to pass through.
|
|
421
|
+
* @returns A new pipeline with the `$limit` stage appended.
|
|
422
|
+
*
|
|
423
|
+
* @example
|
|
424
|
+
* ```ts
|
|
425
|
+
* const top5 = await aggregate(users)
|
|
426
|
+
* .sort({ score: -1 })
|
|
427
|
+
* .limit(5)
|
|
428
|
+
* .toArray()
|
|
429
|
+
* ```
|
|
430
|
+
*/
|
|
431
|
+
limit(n) {
|
|
432
|
+
return new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
433
|
+
...this.stages,
|
|
434
|
+
{ $limit: n }
|
|
435
|
+
]);
|
|
436
|
+
}
|
|
437
|
+
// ── Shape-transforming projection stages ─────────────────────────
|
|
438
|
+
/**
|
|
439
|
+
* Include only specified fields in the output.
|
|
440
|
+
*
|
|
441
|
+
* Appends a `$project` stage with inclusion (`1`) for each key.
|
|
442
|
+
* The `_id` field is always included. The output type narrows to
|
|
443
|
+
* `Pick<TOutput, K | '_id'>`.
|
|
444
|
+
*
|
|
445
|
+
* @param spec - An object mapping field names to `1` for inclusion.
|
|
446
|
+
* @returns A new pipeline with the `$project` stage appended.
|
|
447
|
+
*
|
|
448
|
+
* @example
|
|
449
|
+
* ```ts
|
|
450
|
+
* const namesOnly = await aggregate(users)
|
|
451
|
+
* .project({ name: 1 })
|
|
452
|
+
* .toArray()
|
|
453
|
+
* // [{ _id: ..., name: 'Ada' }, ...]
|
|
454
|
+
* ```
|
|
455
|
+
*/
|
|
456
|
+
project(spec) {
|
|
457
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
458
|
+
...this.stages,
|
|
459
|
+
{ $project: spec }
|
|
460
|
+
]);
|
|
461
|
+
return pipeline;
|
|
462
|
+
}
|
|
463
|
+
/**
|
|
464
|
+
* Variadic shorthand for {@link project} — pick fields to include.
|
|
465
|
+
*
|
|
466
|
+
* Generates a `$project` stage that includes only the listed fields
|
|
467
|
+
* (plus `_id`). Equivalent to `.project({ field1: 1, field2: 1 })`.
|
|
468
|
+
*
|
|
469
|
+
* @param fields - Field names to include in the output.
|
|
470
|
+
* @returns A new pipeline with the `$project` stage appended.
|
|
471
|
+
*
|
|
472
|
+
* @example
|
|
473
|
+
* ```ts
|
|
474
|
+
* const namesAndRoles = await aggregate(users)
|
|
475
|
+
* .pick('name', 'role')
|
|
476
|
+
* .toArray()
|
|
477
|
+
* ```
|
|
478
|
+
*/
|
|
479
|
+
pick(...fields) {
|
|
480
|
+
const spec = Object.fromEntries(fields.map((f) => [f, 1]));
|
|
481
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
482
|
+
...this.stages,
|
|
483
|
+
{ $project: spec }
|
|
484
|
+
]);
|
|
485
|
+
return pipeline;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Exclude specified fields from the output.
|
|
489
|
+
*
|
|
490
|
+
* Appends a `$project` stage with exclusion (`0`) for each key.
|
|
491
|
+
* All other fields pass through. The output type becomes `Omit<TOutput, K>`.
|
|
492
|
+
*
|
|
493
|
+
* @param fields - Field names to exclude from the output.
|
|
494
|
+
* @returns A new pipeline with the `$project` stage appended.
|
|
495
|
+
*
|
|
496
|
+
* @example
|
|
497
|
+
* ```ts
|
|
498
|
+
* const noAge = await aggregate(users)
|
|
499
|
+
* .omit('age')
|
|
500
|
+
* .toArray()
|
|
501
|
+
* ```
|
|
502
|
+
*/
|
|
503
|
+
omit(...fields) {
|
|
504
|
+
const spec = Object.fromEntries(fields.map((f) => [f, 0]));
|
|
505
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
506
|
+
...this.stages,
|
|
507
|
+
{ $project: spec }
|
|
508
|
+
]);
|
|
509
|
+
return pipeline;
|
|
510
|
+
}
|
|
511
|
+
groupBy(field, accumulators) {
|
|
512
|
+
const resolved = typeof accumulators === "function" ? accumulators(createAccumulatorBuilder()) : accumulators;
|
|
513
|
+
const _id = Array.isArray(field) ? Object.fromEntries(field.map((f) => [f, `$${f}`])) : `$${field}`;
|
|
514
|
+
const accumExprs = Object.fromEntries(
|
|
515
|
+
Object.entries(resolved).map(([key, acc]) => [key, acc.expr])
|
|
516
|
+
);
|
|
517
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
518
|
+
...this.stages,
|
|
519
|
+
{ $group: { _id, ...accumExprs } }
|
|
520
|
+
]);
|
|
521
|
+
return pipeline;
|
|
522
|
+
}
|
|
523
|
+
// Implementation
|
|
524
|
+
addFields(fields) {
|
|
525
|
+
const resolved = typeof fields === "function" ? fields(createExpressionBuilder()) : fields;
|
|
526
|
+
const stage = Object.fromEntries(
|
|
527
|
+
Object.entries(resolved).map(([k, v]) => [
|
|
528
|
+
k,
|
|
529
|
+
v && typeof v === "object" && "__expr" in v ? v.value : v
|
|
530
|
+
])
|
|
531
|
+
);
|
|
532
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
533
|
+
...this.stages,
|
|
534
|
+
{ $addFields: stage }
|
|
535
|
+
]);
|
|
536
|
+
return pipeline;
|
|
537
|
+
}
|
|
538
|
+
// ── unwind stage ─────────────────────────────────────────────────
|
|
539
|
+
/**
|
|
540
|
+
* Deconstruct an array field, outputting one document per array element.
|
|
541
|
+
*
|
|
542
|
+
* Appends an `$unwind` stage. The unwound field's type changes from
|
|
543
|
+
* `T[]` to `T` in the output type. Documents with empty or missing
|
|
544
|
+
* arrays are dropped unless `preserveEmpty` is `true`.
|
|
545
|
+
*
|
|
546
|
+
* @param field - The name of the array field to unwind.
|
|
547
|
+
* @param options - Optional settings for the unwind stage.
|
|
548
|
+
* @param options.preserveEmpty - If `true`, documents with null, missing, or empty arrays are preserved.
|
|
549
|
+
* @returns A new pipeline with the `$unwind` stage appended.
|
|
550
|
+
*
|
|
551
|
+
* @example
|
|
552
|
+
* ```ts
|
|
553
|
+
* const flat = await aggregate(orders)
|
|
554
|
+
* .unwind('items')
|
|
555
|
+
* .toArray()
|
|
556
|
+
* // Each result has a single `items` value instead of an array
|
|
557
|
+
* ```
|
|
558
|
+
*/
|
|
559
|
+
unwind(field, options) {
|
|
560
|
+
const stage = options?.preserveEmpty ? { $unwind: { path: `$${field}`, preserveNullAndEmptyArrays: true } } : { $unwind: `$${field}` };
|
|
561
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
562
|
+
...this.stages,
|
|
563
|
+
stage
|
|
564
|
+
]);
|
|
565
|
+
return pipeline;
|
|
566
|
+
}
|
|
567
|
+
lookup(fieldOrFrom, options) {
|
|
568
|
+
const stages = [...this.stages];
|
|
569
|
+
if (typeof fieldOrFrom === "object") {
|
|
570
|
+
const foreignName = fieldOrFrom.name;
|
|
571
|
+
const foreignField = options?.on;
|
|
572
|
+
if (!foreignField) {
|
|
573
|
+
throw new Error(
|
|
574
|
+
`[zodmon] lookup: reverse lookup on '${foreignName}' requires an 'on' option specifying which field on the foreign collection references this collection.`
|
|
575
|
+
);
|
|
576
|
+
}
|
|
577
|
+
const asField = options?.as ?? foreignName;
|
|
578
|
+
stages.push({
|
|
579
|
+
$lookup: {
|
|
580
|
+
from: foreignName,
|
|
581
|
+
localField: "_id",
|
|
582
|
+
foreignField,
|
|
583
|
+
as: asField
|
|
584
|
+
}
|
|
585
|
+
});
|
|
586
|
+
if (options?.unwind) {
|
|
587
|
+
stages.push({ $unwind: { path: `$${asField}`, preserveNullAndEmptyArrays: true } });
|
|
588
|
+
}
|
|
589
|
+
} else {
|
|
590
|
+
const shape = this.definition.shape;
|
|
591
|
+
const fieldSchema = shape[fieldOrFrom];
|
|
592
|
+
const ref = getRefMetadata(fieldSchema);
|
|
593
|
+
if (!ref) {
|
|
594
|
+
throw new Error(
|
|
595
|
+
`[zodmon] lookup: field '${fieldOrFrom}' has no .ref() metadata. Use .lookup(CollectionDef, { on: foreignKey }) for reverse lookups, or add .ref(TargetCollection) to the field schema.`
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
const targetName = ref.collection.name;
|
|
599
|
+
const asField = options?.as ?? targetName;
|
|
600
|
+
stages.push({
|
|
601
|
+
$lookup: {
|
|
602
|
+
from: targetName,
|
|
603
|
+
localField: fieldOrFrom,
|
|
604
|
+
foreignField: "_id",
|
|
605
|
+
as: asField
|
|
606
|
+
}
|
|
607
|
+
});
|
|
608
|
+
if (options?.unwind) {
|
|
609
|
+
stages.push({ $unwind: { path: `$${asField}`, preserveNullAndEmptyArrays: true } });
|
|
610
|
+
}
|
|
611
|
+
}
|
|
612
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, stages);
|
|
613
|
+
return pipeline;
|
|
614
|
+
}
|
|
615
|
+
// ── Convenience shortcuts ────────────────────────────────────────
|
|
616
|
+
/**
|
|
617
|
+
* Count documents per group, sorted by count descending.
|
|
618
|
+
*
|
|
619
|
+
* Shorthand for `.groupBy(field, { count: $count() }).sort({ count: -1 })`.
|
|
620
|
+
*
|
|
621
|
+
* @param field - The field to group and count by.
|
|
622
|
+
* @returns A new pipeline producing `{ _id: TOutput[K], count: number }` results.
|
|
623
|
+
*
|
|
624
|
+
* @example
|
|
625
|
+
* ```ts
|
|
626
|
+
* const roleCounts = await aggregate(users)
|
|
627
|
+
* .countBy('role')
|
|
628
|
+
* .toArray()
|
|
629
|
+
* // [{ _id: 'user', count: 3 }, { _id: 'admin', count: 2 }]
|
|
630
|
+
* ```
|
|
631
|
+
*/
|
|
632
|
+
countBy(field) {
|
|
633
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
634
|
+
...this.stages,
|
|
635
|
+
{ $group: { _id: `$${field}`, count: { $sum: 1 } } },
|
|
636
|
+
{ $sort: { count: -1 } }
|
|
637
|
+
]);
|
|
638
|
+
return pipeline;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Sum a numeric field per group, sorted by total descending.
|
|
642
|
+
*
|
|
643
|
+
* Shorthand for `.groupBy(field, { total: $sum('$sumField') }).sort({ total: -1 })`.
|
|
644
|
+
*
|
|
645
|
+
* @param field - The field to group by.
|
|
646
|
+
* @param sumField - The numeric field to sum.
|
|
647
|
+
* @returns A new pipeline producing `{ _id: TOutput[K], total: number }` results.
|
|
648
|
+
*
|
|
649
|
+
* @example
|
|
650
|
+
* ```ts
|
|
651
|
+
* const revenueByCategory = await aggregate(orders)
|
|
652
|
+
* .sumBy('category', 'amount')
|
|
653
|
+
* .toArray()
|
|
654
|
+
* // [{ _id: 'electronics', total: 5000 }, ...]
|
|
655
|
+
* ```
|
|
656
|
+
*/
|
|
657
|
+
sumBy(field, sumField) {
|
|
658
|
+
const pipeline = new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
659
|
+
...this.stages,
|
|
660
|
+
{ $group: { _id: `$${field}`, total: { $sum: `$${sumField}` } } },
|
|
661
|
+
{ $sort: { total: -1 } }
|
|
662
|
+
]);
|
|
663
|
+
return pipeline;
|
|
664
|
+
}
|
|
665
|
+
/**
|
|
666
|
+
* Sort by a single field with a friendly direction name.
|
|
667
|
+
*
|
|
668
|
+
* Shorthand for `.sort({ [field]: direction === 'desc' ? -1 : 1 })`.
|
|
669
|
+
*
|
|
670
|
+
* @param field - The field to sort by.
|
|
671
|
+
* @param direction - Sort direction: `'asc'` (default) or `'desc'`.
|
|
672
|
+
* @returns A new pipeline with the `$sort` stage appended.
|
|
673
|
+
*
|
|
674
|
+
* @example
|
|
675
|
+
* ```ts
|
|
676
|
+
* const youngest = await aggregate(users)
|
|
677
|
+
* .sortBy('age')
|
|
678
|
+
* .toArray()
|
|
679
|
+
* ```
|
|
680
|
+
*/
|
|
681
|
+
sortBy(field, direction = "asc") {
|
|
682
|
+
return new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
683
|
+
...this.stages,
|
|
684
|
+
{ $sort: { [field]: direction === "desc" ? -1 : 1 } }
|
|
685
|
+
]);
|
|
686
|
+
}
|
|
687
|
+
/**
|
|
688
|
+
* Return the top N documents sorted by a field descending.
|
|
689
|
+
*
|
|
690
|
+
* Shorthand for `.sort({ [by]: -1 }).limit(n)`.
|
|
691
|
+
*
|
|
692
|
+
* @param n - The number of documents to return.
|
|
693
|
+
* @param options - An object with a `by` field specifying the sort key.
|
|
694
|
+
* @returns A new pipeline with `$sort` and `$limit` stages appended.
|
|
695
|
+
*
|
|
696
|
+
* @example
|
|
697
|
+
* ```ts
|
|
698
|
+
* const top3 = await aggregate(users)
|
|
699
|
+
* .top(3, { by: 'score' })
|
|
700
|
+
* .toArray()
|
|
701
|
+
* ```
|
|
702
|
+
*/
|
|
703
|
+
top(n, options) {
|
|
704
|
+
return new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
705
|
+
...this.stages,
|
|
706
|
+
{ $sort: { [options.by]: -1 } },
|
|
707
|
+
{ $limit: n }
|
|
708
|
+
]);
|
|
709
|
+
}
|
|
710
|
+
/**
|
|
711
|
+
* Return the bottom N documents sorted by a field ascending.
|
|
712
|
+
*
|
|
713
|
+
* Shorthand for `.sort({ [by]: 1 }).limit(n)`.
|
|
714
|
+
*
|
|
715
|
+
* @param n - The number of documents to return.
|
|
716
|
+
* @param options - An object with a `by` field specifying the sort key.
|
|
717
|
+
* @returns A new pipeline with `$sort` and `$limit` stages appended.
|
|
718
|
+
*
|
|
719
|
+
* @example
|
|
720
|
+
* ```ts
|
|
721
|
+
* const bottom3 = await aggregate(users)
|
|
722
|
+
* .bottom(3, { by: 'score' })
|
|
723
|
+
* .toArray()
|
|
724
|
+
* ```
|
|
725
|
+
*/
|
|
726
|
+
bottom(n, options) {
|
|
727
|
+
return new _AggregatePipeline(this.definition, this.nativeCollection, [
|
|
728
|
+
...this.stages,
|
|
729
|
+
{ $sort: { [options.by]: 1 } },
|
|
730
|
+
{ $limit: n }
|
|
731
|
+
]);
|
|
732
|
+
}
|
|
733
|
+
};
|
|
734
|
+
function aggregate(handle) {
|
|
735
|
+
return new AggregatePipeline(handle.definition, handle.native, []);
|
|
736
|
+
}
|
|
737
|
+
|
|
76
738
|
// src/client/client.ts
|
|
77
739
|
var import_mongodb2 = require("mongodb");
|
|
78
740
|
|
|
@@ -239,7 +901,7 @@ async function syncIndexes(handle, options) {
|
|
|
239
901
|
}
|
|
240
902
|
|
|
241
903
|
// src/crud/delete.ts
|
|
242
|
-
var
|
|
904
|
+
var import_zod2 = require("zod");
|
|
243
905
|
|
|
244
906
|
// src/errors/validation.ts
|
|
245
907
|
var ZodmonValidationError = class extends Error {
|
|
@@ -280,7 +942,7 @@ async function findOneAndDelete(handle, filter, options) {
|
|
|
280
942
|
try {
|
|
281
943
|
return handle.definition.schema.parse(result);
|
|
282
944
|
} catch (err) {
|
|
283
|
-
if (err instanceof
|
|
945
|
+
if (err instanceof import_zod2.z.ZodError) {
|
|
284
946
|
throw new ZodmonValidationError(handle.definition.name, err);
|
|
285
947
|
}
|
|
286
948
|
throw err;
|
|
@@ -288,7 +950,7 @@ async function findOneAndDelete(handle, filter, options) {
|
|
|
288
950
|
}
|
|
289
951
|
|
|
290
952
|
// src/crud/find.ts
|
|
291
|
-
var
|
|
953
|
+
var import_zod4 = require("zod");
|
|
292
954
|
|
|
293
955
|
// src/errors/not-found.ts
|
|
294
956
|
var ZodmonNotFoundError = class extends Error {
|
|
@@ -325,7 +987,7 @@ function checkUnindexedFields(definition, filter) {
|
|
|
325
987
|
}
|
|
326
988
|
|
|
327
989
|
// src/query/cursor.ts
|
|
328
|
-
var
|
|
990
|
+
var import_zod3 = require("zod");
|
|
329
991
|
|
|
330
992
|
// src/crud/paginate.ts
|
|
331
993
|
var import_mongodb = require("mongodb");
|
|
@@ -585,7 +1247,7 @@ var TypedFindCursor = class {
|
|
|
585
1247
|
try {
|
|
586
1248
|
return this.schema.parse(raw2);
|
|
587
1249
|
} catch (err) {
|
|
588
|
-
if (err instanceof
|
|
1250
|
+
if (err instanceof import_zod3.z.ZodError) {
|
|
589
1251
|
throw new ZodmonValidationError(this.collectionName, err);
|
|
590
1252
|
}
|
|
591
1253
|
throw err;
|
|
@@ -606,7 +1268,7 @@ async function findOne(handle, filter, options) {
|
|
|
606
1268
|
try {
|
|
607
1269
|
return handle.definition.schema.parse(raw2);
|
|
608
1270
|
} catch (err) {
|
|
609
|
-
if (err instanceof
|
|
1271
|
+
if (err instanceof import_zod4.z.ZodError) {
|
|
610
1272
|
throw new ZodmonValidationError(handle.definition.name, err);
|
|
611
1273
|
}
|
|
612
1274
|
throw err;
|
|
@@ -628,13 +1290,13 @@ function find(handle, filter, options) {
|
|
|
628
1290
|
}
|
|
629
1291
|
|
|
630
1292
|
// src/crud/insert.ts
|
|
631
|
-
var
|
|
1293
|
+
var import_zod5 = require("zod");
|
|
632
1294
|
async function insertOne(handle, doc) {
|
|
633
1295
|
let parsed;
|
|
634
1296
|
try {
|
|
635
1297
|
parsed = handle.definition.schema.parse(doc);
|
|
636
1298
|
} catch (err) {
|
|
637
|
-
if (err instanceof
|
|
1299
|
+
if (err instanceof import_zod5.z.ZodError) {
|
|
638
1300
|
throw new ZodmonValidationError(handle.definition.name, err);
|
|
639
1301
|
}
|
|
640
1302
|
throw err;
|
|
@@ -649,7 +1311,7 @@ async function insertMany(handle, docs) {
|
|
|
649
1311
|
try {
|
|
650
1312
|
parsed.push(handle.definition.schema.parse(doc));
|
|
651
1313
|
} catch (err) {
|
|
652
|
-
if (err instanceof
|
|
1314
|
+
if (err instanceof import_zod5.z.ZodError) {
|
|
653
1315
|
throw new ZodmonValidationError(handle.definition.name, err);
|
|
654
1316
|
}
|
|
655
1317
|
throw err;
|
|
@@ -660,7 +1322,7 @@ async function insertMany(handle, docs) {
|
|
|
660
1322
|
}
|
|
661
1323
|
|
|
662
1324
|
// src/crud/update.ts
|
|
663
|
-
var
|
|
1325
|
+
var import_zod6 = require("zod");
|
|
664
1326
|
async function updateOne(handle, filter, update, options) {
|
|
665
1327
|
return await handle.native.updateOne(filter, update, options);
|
|
666
1328
|
}
|
|
@@ -691,7 +1353,7 @@ async function findOneAndUpdate(handle, filter, update, options) {
|
|
|
691
1353
|
try {
|
|
692
1354
|
return handle.definition.schema.parse(result);
|
|
693
1355
|
} catch (err) {
|
|
694
|
-
if (err instanceof
|
|
1356
|
+
if (err instanceof import_zod6.z.ZodError) {
|
|
695
1357
|
throw new ZodmonValidationError(handle.definition.name, err);
|
|
696
1358
|
}
|
|
697
1359
|
throw err;
|
|
@@ -982,6 +1644,27 @@ var CollectionHandle = class {
|
|
|
982
1644
|
async syncIndexes(options) {
|
|
983
1645
|
return await syncIndexes(this, options);
|
|
984
1646
|
}
|
|
1647
|
+
/**
|
|
1648
|
+
* Start a type-safe aggregation pipeline on this collection.
|
|
1649
|
+
*
|
|
1650
|
+
* Returns a fluent pipeline builder that tracks the output document
|
|
1651
|
+
* shape through each stage. The pipeline is lazy — no query executes
|
|
1652
|
+
* until a terminal method (`toArray`, `for await`, `explain`) is called.
|
|
1653
|
+
*
|
|
1654
|
+
* @returns A new pipeline builder starting with this collection's document type.
|
|
1655
|
+
*
|
|
1656
|
+
* @example
|
|
1657
|
+
* ```ts
|
|
1658
|
+
* const users = db.use(Users)
|
|
1659
|
+
* const result = await users.aggregate()
|
|
1660
|
+
* .match({ role: 'admin' })
|
|
1661
|
+
* .groupBy('role', { count: $count() })
|
|
1662
|
+
* .toArray()
|
|
1663
|
+
* ```
|
|
1664
|
+
*/
|
|
1665
|
+
aggregate() {
|
|
1666
|
+
return aggregate(this);
|
|
1667
|
+
}
|
|
985
1668
|
};
|
|
986
1669
|
|
|
987
1670
|
// src/client/client.ts
|
|
@@ -1007,9 +1690,7 @@ var Database = class {
|
|
|
1007
1690
|
*/
|
|
1008
1691
|
use(def) {
|
|
1009
1692
|
this._collections.set(def.name, def);
|
|
1010
|
-
const native = this._db.collection(
|
|
1011
|
-
def.name
|
|
1012
|
-
);
|
|
1693
|
+
const native = this._db.collection(def.name);
|
|
1013
1694
|
return new CollectionHandle(
|
|
1014
1695
|
def,
|
|
1015
1696
|
native
|
|
@@ -1087,36 +1768,6 @@ var import_zod9 = require("zod");
|
|
|
1087
1768
|
|
|
1088
1769
|
// src/schema/extensions.ts
|
|
1089
1770
|
var import_zod7 = require("zod");
|
|
1090
|
-
|
|
1091
|
-
// src/schema/ref.ts
|
|
1092
|
-
var import_zod6 = require("zod");
|
|
1093
|
-
var refMetadata = /* @__PURE__ */ new WeakMap();
|
|
1094
|
-
function getRefMetadata(schema) {
|
|
1095
|
-
if (typeof schema !== "object" || schema === null) return void 0;
|
|
1096
|
-
return refMetadata.get(schema);
|
|
1097
|
-
}
|
|
1098
|
-
var REF_GUARD = /* @__PURE__ */ Symbol.for("zodmon_ref");
|
|
1099
|
-
function installRefExtension() {
|
|
1100
|
-
const proto = import_zod6.z.ZodType.prototype;
|
|
1101
|
-
if (REF_GUARD in proto) return;
|
|
1102
|
-
Object.defineProperty(proto, "ref", {
|
|
1103
|
-
value(collection2) {
|
|
1104
|
-
refMetadata.set(this, { collection: collection2 });
|
|
1105
|
-
return this;
|
|
1106
|
-
},
|
|
1107
|
-
enumerable: true,
|
|
1108
|
-
configurable: true,
|
|
1109
|
-
writable: true
|
|
1110
|
-
});
|
|
1111
|
-
Object.defineProperty(proto, REF_GUARD, {
|
|
1112
|
-
value: true,
|
|
1113
|
-
enumerable: false,
|
|
1114
|
-
configurable: false,
|
|
1115
|
-
writable: false
|
|
1116
|
-
});
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
// src/schema/extensions.ts
|
|
1120
1771
|
var indexMetadata = /* @__PURE__ */ new WeakMap();
|
|
1121
1772
|
function getIndexMetadata(schema) {
|
|
1122
1773
|
if (typeof schema !== "object" || schema === null) return void 0;
|
|
@@ -1367,29 +2018,42 @@ var $ = {
|
|
|
1367
2018
|
// Annotate the CommonJS export names for ESM import in node:
|
|
1368
2019
|
0 && (module.exports = {
|
|
1369
2020
|
$,
|
|
2021
|
+
$addToSet,
|
|
1370
2022
|
$and,
|
|
2023
|
+
$avg,
|
|
2024
|
+
$count,
|
|
1371
2025
|
$eq,
|
|
1372
2026
|
$exists,
|
|
2027
|
+
$first,
|
|
1373
2028
|
$gt,
|
|
1374
2029
|
$gte,
|
|
1375
2030
|
$in,
|
|
2031
|
+
$last,
|
|
1376
2032
|
$lt,
|
|
1377
2033
|
$lte,
|
|
2034
|
+
$max,
|
|
2035
|
+
$min,
|
|
1378
2036
|
$ne,
|
|
1379
2037
|
$nin,
|
|
1380
2038
|
$nor,
|
|
1381
2039
|
$not,
|
|
1382
2040
|
$or,
|
|
2041
|
+
$push,
|
|
1383
2042
|
$regex,
|
|
2043
|
+
$sum,
|
|
2044
|
+
AggregatePipeline,
|
|
1384
2045
|
CollectionHandle,
|
|
1385
2046
|
Database,
|
|
1386
2047
|
IndexBuilder,
|
|
1387
2048
|
TypedFindCursor,
|
|
1388
2049
|
ZodmonNotFoundError,
|
|
1389
2050
|
ZodmonValidationError,
|
|
2051
|
+
aggregate,
|
|
1390
2052
|
checkUnindexedFields,
|
|
1391
2053
|
collection,
|
|
2054
|
+
createAccumulatorBuilder,
|
|
1392
2055
|
createClient,
|
|
2056
|
+
createExpressionBuilder,
|
|
1393
2057
|
deleteMany,
|
|
1394
2058
|
deleteOne,
|
|
1395
2059
|
extractComparableOptions,
|