@zodmon/core 0.9.0 → 0.10.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 +423 -76
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +319 -10
- package/dist/index.d.ts +319 -10
- package/dist/index.js +396 -60
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -99,6 +99,245 @@ function createExpressionBuilder() {
|
|
|
99
99
|
};
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
// src/errors/wrap.ts
|
|
103
|
+
import { MongoBulkWriteError, MongoNetworkError, MongoServerError } from "mongodb";
|
|
104
|
+
|
|
105
|
+
// src/errors/base.ts
|
|
106
|
+
var ZodmonError = class extends Error {
|
|
107
|
+
name = "ZodmonError";
|
|
108
|
+
/** The MongoDB collection name associated with this error. */
|
|
109
|
+
collection;
|
|
110
|
+
/** The underlying error that caused this error, if any. */
|
|
111
|
+
cause;
|
|
112
|
+
constructor(message, collection2, options) {
|
|
113
|
+
super(message);
|
|
114
|
+
this.collection = collection2;
|
|
115
|
+
if (options?.cause) {
|
|
116
|
+
this.cause = options.cause;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// src/errors/auth.ts
|
|
122
|
+
var ZodmonAuthError = class extends ZodmonError {
|
|
123
|
+
name = "ZodmonAuthError";
|
|
124
|
+
/** The MongoDB error code (13 or 18). */
|
|
125
|
+
code;
|
|
126
|
+
constructor(collection2, code, cause) {
|
|
127
|
+
const message = code === 18 ? `Authentication failed for "${collection2}": check connection credentials` : `Not authorized to perform this operation on "${collection2}"`;
|
|
128
|
+
super(message, collection2, { cause });
|
|
129
|
+
this.code = code;
|
|
130
|
+
}
|
|
131
|
+
};
|
|
132
|
+
|
|
133
|
+
// src/errors/bulk-write.ts
|
|
134
|
+
var ZodmonBulkWriteError = class extends ZodmonError {
|
|
135
|
+
name = "ZodmonBulkWriteError";
|
|
136
|
+
/** Number of documents successfully inserted. */
|
|
137
|
+
insertedCount;
|
|
138
|
+
/** Number of documents matched by update filters. */
|
|
139
|
+
matchedCount;
|
|
140
|
+
/** Number of documents actually modified. */
|
|
141
|
+
modifiedCount;
|
|
142
|
+
/** Number of documents deleted. */
|
|
143
|
+
deletedCount;
|
|
144
|
+
/** Individual write errors with their operation index, code, and message. */
|
|
145
|
+
writeErrors;
|
|
146
|
+
constructor(collection2, cause, totalOps) {
|
|
147
|
+
const bulkErr = cause;
|
|
148
|
+
const result = bulkErr["result"] ?? {};
|
|
149
|
+
const rawErrors = bulkErr["writeErrors"] ?? [];
|
|
150
|
+
const writeErrors = rawErrors.map((e) => ({
|
|
151
|
+
index: e["index"] ?? 0,
|
|
152
|
+
code: e["code"] ?? 0,
|
|
153
|
+
message: e["errmsg"] ?? e["message"] ?? "unknown error"
|
|
154
|
+
}));
|
|
155
|
+
const failedMsg = totalOps !== void 0 ? `${writeErrors.length} of ${totalOps} operations failed` : `${writeErrors.length} operations failed`;
|
|
156
|
+
super(`Bulk write failed on "${collection2}": ${failedMsg}`, collection2, { cause });
|
|
157
|
+
this.insertedCount = result["insertedCount"] ?? 0;
|
|
158
|
+
this.matchedCount = result["matchedCount"] ?? 0;
|
|
159
|
+
this.modifiedCount = result["modifiedCount"] ?? 0;
|
|
160
|
+
this.deletedCount = result["deletedCount"] ?? 0;
|
|
161
|
+
this.writeErrors = writeErrors;
|
|
162
|
+
}
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
// src/errors/doc-validation.ts
|
|
166
|
+
var ZodmonDocValidationError = class extends ZodmonError {
|
|
167
|
+
name = "ZodmonDocValidationError";
|
|
168
|
+
/** Server-provided validation failure details. */
|
|
169
|
+
errInfo;
|
|
170
|
+
constructor(collection2, errInfo, cause) {
|
|
171
|
+
super(
|
|
172
|
+
`Server-side document validation failed for "${collection2}": ${cause.message}`,
|
|
173
|
+
collection2,
|
|
174
|
+
{ cause }
|
|
175
|
+
);
|
|
176
|
+
this.errInfo = errInfo;
|
|
177
|
+
}
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// src/errors/duplicate-key.ts
|
|
181
|
+
var INDEX_REGEX = /index:\s+(\S+)/;
|
|
182
|
+
var DUP_KEY_FIELD_REGEX = /dup key:\s*\{\s*(\w+):/;
|
|
183
|
+
var ZodmonDuplicateKeyError = class extends ZodmonError {
|
|
184
|
+
name = "ZodmonDuplicateKeyError";
|
|
185
|
+
/** The first field that caused the duplicate key violation. */
|
|
186
|
+
field;
|
|
187
|
+
/** The duplicate value, or `undefined` if it could not be extracted. */
|
|
188
|
+
value;
|
|
189
|
+
/** The name of the index that was violated. */
|
|
190
|
+
index;
|
|
191
|
+
/** The key pattern of the violated index (e.g. `{ email: 1 }`). */
|
|
192
|
+
keyPattern;
|
|
193
|
+
/** The key values that caused the violation. */
|
|
194
|
+
keyValue;
|
|
195
|
+
constructor(collection2, cause) {
|
|
196
|
+
const serverErr = cause;
|
|
197
|
+
const kp = serverErr["keyPattern"];
|
|
198
|
+
const kv = serverErr["keyValue"];
|
|
199
|
+
let field;
|
|
200
|
+
let value;
|
|
201
|
+
let keyPattern;
|
|
202
|
+
let keyValue;
|
|
203
|
+
if (kp && kv) {
|
|
204
|
+
const firstKey = Object.keys(kp)[0] ?? "unknown";
|
|
205
|
+
field = firstKey;
|
|
206
|
+
value = kv[firstKey];
|
|
207
|
+
keyPattern = kp;
|
|
208
|
+
keyValue = kv;
|
|
209
|
+
} else {
|
|
210
|
+
const fieldMatch = cause.message.match(DUP_KEY_FIELD_REGEX);
|
|
211
|
+
field = fieldMatch?.[1] ?? "unknown";
|
|
212
|
+
value = void 0;
|
|
213
|
+
keyPattern = field !== "unknown" ? { [field]: 1 } : {};
|
|
214
|
+
keyValue = {};
|
|
215
|
+
}
|
|
216
|
+
const indexMatch = cause.message.match(INDEX_REGEX);
|
|
217
|
+
const index2 = indexMatch?.[1] ?? "unknown";
|
|
218
|
+
const valueStr = typeof value === "string" ? `"${value}"` : String(value);
|
|
219
|
+
super(
|
|
220
|
+
`Duplicate key in "${collection2}": ${field} = ${valueStr} (index: ${index2})`,
|
|
221
|
+
collection2,
|
|
222
|
+
{ cause }
|
|
223
|
+
);
|
|
224
|
+
this.field = field;
|
|
225
|
+
this.value = value;
|
|
226
|
+
this.index = index2;
|
|
227
|
+
this.keyPattern = keyPattern;
|
|
228
|
+
this.keyValue = keyValue;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
|
|
232
|
+
// src/errors/index-error.ts
|
|
233
|
+
var ZodmonIndexError = class extends ZodmonError {
|
|
234
|
+
name = "ZodmonIndexError";
|
|
235
|
+
/** The MongoDB error code (67, 85, or 86). */
|
|
236
|
+
code;
|
|
237
|
+
constructor(collection2, code, errmsg, cause) {
|
|
238
|
+
const prefix = code === 67 ? "Cannot create index" : code === 85 ? "Index options conflict" : "Index key specs conflict";
|
|
239
|
+
super(`${prefix} on "${collection2}": ${errmsg}`, collection2, { cause });
|
|
240
|
+
this.code = code;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
|
|
244
|
+
// src/errors/network.ts
|
|
245
|
+
var ZodmonNetworkError = class extends ZodmonError {
|
|
246
|
+
name = "ZodmonNetworkError";
|
|
247
|
+
constructor(collection2, cause) {
|
|
248
|
+
super(`Network error on "${collection2}": ${cause.message}`, collection2, { cause });
|
|
249
|
+
}
|
|
250
|
+
};
|
|
251
|
+
|
|
252
|
+
// src/errors/query.ts
|
|
253
|
+
var ZodmonQueryError = class extends ZodmonError {
|
|
254
|
+
name = "ZodmonQueryError";
|
|
255
|
+
/** The MongoDB error code (2, 9, or 292). */
|
|
256
|
+
code;
|
|
257
|
+
constructor(collection2, code, errmsg, cause) {
|
|
258
|
+
const message = code === 292 ? `Query exceeded memory limit on "${collection2}": enable allowDiskUse for large sorts or aggregations` : code === 9 ? `Failed to parse query on "${collection2}": ${errmsg}` : `Bad value in query on "${collection2}": ${errmsg}`;
|
|
259
|
+
super(message, collection2, { cause });
|
|
260
|
+
this.code = code;
|
|
261
|
+
}
|
|
262
|
+
};
|
|
263
|
+
|
|
264
|
+
// src/errors/timeout.ts
|
|
265
|
+
var ZodmonTimeoutError = class extends ZodmonError {
|
|
266
|
+
name = "ZodmonTimeoutError";
|
|
267
|
+
/** The MongoDB error code (50 or 262). */
|
|
268
|
+
code;
|
|
269
|
+
constructor(collection2, code, cause) {
|
|
270
|
+
super(`Operation timed out on "${collection2}": exceeded server time limit`, collection2, {
|
|
271
|
+
cause
|
|
272
|
+
});
|
|
273
|
+
this.code = code;
|
|
274
|
+
}
|
|
275
|
+
};
|
|
276
|
+
|
|
277
|
+
// src/errors/write-conflict.ts
|
|
278
|
+
var ZodmonWriteConflictError = class extends ZodmonError {
|
|
279
|
+
name = "ZodmonWriteConflictError";
|
|
280
|
+
constructor(collection2, cause) {
|
|
281
|
+
super(
|
|
282
|
+
`Write conflict in "${collection2}": another operation modified this document concurrently \u2014 retry the transaction`,
|
|
283
|
+
collection2,
|
|
284
|
+
{ cause }
|
|
285
|
+
);
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
|
|
289
|
+
// src/errors/wrap.ts
|
|
290
|
+
function wrapMongoError(err, collection2) {
|
|
291
|
+
if (err instanceof ZodmonError) {
|
|
292
|
+
throw err;
|
|
293
|
+
}
|
|
294
|
+
if (err instanceof MongoBulkWriteError) {
|
|
295
|
+
throw new ZodmonBulkWriteError(collection2, err);
|
|
296
|
+
}
|
|
297
|
+
if (err instanceof MongoNetworkError) {
|
|
298
|
+
throw new ZodmonNetworkError(collection2, err);
|
|
299
|
+
}
|
|
300
|
+
if (err instanceof MongoServerError) {
|
|
301
|
+
switch (err.code) {
|
|
302
|
+
case 11e3:
|
|
303
|
+
case 11001:
|
|
304
|
+
throw new ZodmonDuplicateKeyError(collection2, err);
|
|
305
|
+
case 112:
|
|
306
|
+
throw new ZodmonWriteConflictError(collection2, err);
|
|
307
|
+
case 50:
|
|
308
|
+
case 262:
|
|
309
|
+
throw new ZodmonTimeoutError(collection2, err.code, err);
|
|
310
|
+
case 13:
|
|
311
|
+
case 18:
|
|
312
|
+
throw new ZodmonAuthError(collection2, err.code, err);
|
|
313
|
+
case 67:
|
|
314
|
+
case 85:
|
|
315
|
+
case 86:
|
|
316
|
+
throw new ZodmonIndexError(collection2, err.code, err.message, err);
|
|
317
|
+
case 2:
|
|
318
|
+
case 9:
|
|
319
|
+
case 292:
|
|
320
|
+
throw new ZodmonQueryError(collection2, err.code, err.message, err);
|
|
321
|
+
case 121:
|
|
322
|
+
throw new ZodmonDocValidationError(
|
|
323
|
+
collection2,
|
|
324
|
+
err.errInfo,
|
|
325
|
+
err
|
|
326
|
+
);
|
|
327
|
+
default:
|
|
328
|
+
throw new ZodmonError(`MongoDB error on "${collection2}": ${err.message}`, collection2, {
|
|
329
|
+
cause: err
|
|
330
|
+
});
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
if (err instanceof Error) {
|
|
334
|
+
throw new ZodmonError(`Unexpected error on "${collection2}": ${err.message}`, collection2, {
|
|
335
|
+
cause: err
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
throw new ZodmonError(`Unexpected error on "${collection2}": ${String(err)}`, collection2);
|
|
339
|
+
}
|
|
340
|
+
|
|
102
341
|
// src/schema/ref.ts
|
|
103
342
|
import { z } from "zod";
|
|
104
343
|
var refMetadata = /* @__PURE__ */ new WeakMap();
|
|
@@ -184,8 +423,12 @@ var AggregatePipeline = class _AggregatePipeline {
|
|
|
184
423
|
* ```
|
|
185
424
|
*/
|
|
186
425
|
async toArray() {
|
|
187
|
-
|
|
188
|
-
|
|
426
|
+
try {
|
|
427
|
+
const cursor = this.nativeCollection.aggregate(this.stages);
|
|
428
|
+
return await cursor.toArray();
|
|
429
|
+
} catch (err) {
|
|
430
|
+
wrapMongoError(err, this.definition.name);
|
|
431
|
+
}
|
|
189
432
|
}
|
|
190
433
|
/**
|
|
191
434
|
* Stream pipeline results one document at a time via `for await...of`.
|
|
@@ -200,9 +443,13 @@ var AggregatePipeline = class _AggregatePipeline {
|
|
|
200
443
|
* ```
|
|
201
444
|
*/
|
|
202
445
|
async *[Symbol.asyncIterator]() {
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
446
|
+
try {
|
|
447
|
+
const cursor = this.nativeCollection.aggregate(this.stages);
|
|
448
|
+
for await (const doc of cursor) {
|
|
449
|
+
yield doc;
|
|
450
|
+
}
|
|
451
|
+
} catch (err) {
|
|
452
|
+
wrapMongoError(err, this.definition.name);
|
|
206
453
|
}
|
|
207
454
|
}
|
|
208
455
|
/**
|
|
@@ -222,8 +469,12 @@ var AggregatePipeline = class _AggregatePipeline {
|
|
|
222
469
|
* ```
|
|
223
470
|
*/
|
|
224
471
|
async explain() {
|
|
225
|
-
|
|
226
|
-
|
|
472
|
+
try {
|
|
473
|
+
const cursor = this.nativeCollection.aggregate(this.stages);
|
|
474
|
+
return await cursor.explain();
|
|
475
|
+
} catch (err) {
|
|
476
|
+
wrapMongoError(err, this.definition.name);
|
|
477
|
+
}
|
|
227
478
|
}
|
|
228
479
|
// ── Shape-preserving stages ──────────────────────────────────────
|
|
229
480
|
/**
|
|
@@ -720,7 +971,7 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
|
|
|
720
971
|
const serialized = serializeIndexKey(spec.key);
|
|
721
972
|
const existing = existingByKey.get(serialized);
|
|
722
973
|
if (!existing) {
|
|
723
|
-
if (!dryRun) await native
|
|
974
|
+
if (!dryRun) await safeCreateIndex(native, spec.key, spec.options);
|
|
724
975
|
acc.created.push(resolveSpecName(spec));
|
|
725
976
|
return;
|
|
726
977
|
}
|
|
@@ -733,8 +984,8 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
|
|
|
733
984
|
}
|
|
734
985
|
if (dropOrphaned) {
|
|
735
986
|
if (!dryRun) {
|
|
736
|
-
await native
|
|
737
|
-
await native
|
|
987
|
+
await safeDropIndex(native, existingName);
|
|
988
|
+
await safeCreateIndex(native, spec.key, spec.options);
|
|
738
989
|
}
|
|
739
990
|
acc.dropped.push(existingName);
|
|
740
991
|
acc.created.push(resolveSpecName(spec));
|
|
@@ -747,6 +998,20 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
|
|
|
747
998
|
desired: spec.options
|
|
748
999
|
});
|
|
749
1000
|
}
|
|
1001
|
+
async function safeCreateIndex(native, key, options) {
|
|
1002
|
+
try {
|
|
1003
|
+
await native.createIndex(key, options);
|
|
1004
|
+
} catch (err) {
|
|
1005
|
+
wrapMongoError(err, native.collectionName);
|
|
1006
|
+
}
|
|
1007
|
+
}
|
|
1008
|
+
async function safeDropIndex(native, name) {
|
|
1009
|
+
try {
|
|
1010
|
+
await native.dropIndex(name);
|
|
1011
|
+
} catch (err) {
|
|
1012
|
+
wrapMongoError(err, native.collectionName);
|
|
1013
|
+
}
|
|
1014
|
+
}
|
|
750
1015
|
async function processOrphanedIndexes(existingIndexes, desiredKeys, matchedKeys, native, dryRun, dropOrphaned, dropped) {
|
|
751
1016
|
for (const idx of existingIndexes) {
|
|
752
1017
|
const rawName = idx["name"];
|
|
@@ -755,7 +1020,7 @@ async function processOrphanedIndexes(existingIndexes, desiredKeys, matchedKeys,
|
|
|
755
1020
|
const serialized = serializeIndexKey(idx["key"]);
|
|
756
1021
|
if (matchedKeys.has(serialized) || desiredKeys.has(serialized)) continue;
|
|
757
1022
|
if (dropOrphaned) {
|
|
758
|
-
if (!dryRun) await native
|
|
1023
|
+
if (!dryRun) await safeDropIndex(native, name);
|
|
759
1024
|
dropped.push(name);
|
|
760
1025
|
}
|
|
761
1026
|
}
|
|
@@ -767,7 +1032,7 @@ async function listIndexesSafe(native) {
|
|
|
767
1032
|
if (err instanceof Error && err.message.includes("ns does not exist")) {
|
|
768
1033
|
return [];
|
|
769
1034
|
}
|
|
770
|
-
|
|
1035
|
+
wrapMongoError(err, native.collectionName);
|
|
771
1036
|
}
|
|
772
1037
|
}
|
|
773
1038
|
async function syncIndexes(handle, options) {
|
|
@@ -816,36 +1081,49 @@ async function syncIndexes(handle, options) {
|
|
|
816
1081
|
import { z as z2 } from "zod";
|
|
817
1082
|
|
|
818
1083
|
// src/errors/validation.ts
|
|
819
|
-
var ZodmonValidationError = class extends
|
|
1084
|
+
var ZodmonValidationError = class extends ZodmonError {
|
|
820
1085
|
name = "ZodmonValidationError";
|
|
821
|
-
/** The MongoDB collection name where the validation failed. */
|
|
822
|
-
collection;
|
|
823
1086
|
/** The original Zod validation error with detailed issue information. */
|
|
824
1087
|
zodError;
|
|
825
|
-
|
|
1088
|
+
/** The document that failed validation. */
|
|
1089
|
+
document;
|
|
1090
|
+
constructor(collection2, zodError, document) {
|
|
826
1091
|
const fields = zodError.issues.map((issue) => {
|
|
827
1092
|
const path = issue.path.join(".") || "(root)";
|
|
828
1093
|
return `${path} (${issue.message})`;
|
|
829
1094
|
}).join(", ");
|
|
830
|
-
super(`Validation failed for "${collection2}": ${fields}
|
|
831
|
-
this.collection = collection2;
|
|
1095
|
+
super(`Validation failed for "${collection2}": ${fields}`, collection2, { cause: zodError });
|
|
832
1096
|
this.zodError = zodError;
|
|
1097
|
+
this.document = document;
|
|
833
1098
|
}
|
|
834
1099
|
};
|
|
835
1100
|
|
|
836
1101
|
// src/crud/delete.ts
|
|
837
1102
|
async function deleteOne(handle, filter) {
|
|
838
|
-
|
|
1103
|
+
try {
|
|
1104
|
+
return await handle.native.deleteOne(filter);
|
|
1105
|
+
} catch (err) {
|
|
1106
|
+
wrapMongoError(err, handle.definition.name);
|
|
1107
|
+
}
|
|
839
1108
|
}
|
|
840
1109
|
async function deleteMany(handle, filter) {
|
|
841
|
-
|
|
1110
|
+
try {
|
|
1111
|
+
return await handle.native.deleteMany(filter);
|
|
1112
|
+
} catch (err) {
|
|
1113
|
+
wrapMongoError(err, handle.definition.name);
|
|
1114
|
+
}
|
|
842
1115
|
}
|
|
843
1116
|
async function findOneAndDelete(handle, filter, options) {
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
1117
|
+
let result;
|
|
1118
|
+
try {
|
|
1119
|
+
result = await handle.native.findOneAndDelete(
|
|
1120
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
|
|
1121
|
+
filter,
|
|
1122
|
+
{ includeResultMetadata: false }
|
|
1123
|
+
);
|
|
1124
|
+
} catch (err) {
|
|
1125
|
+
wrapMongoError(err, handle.definition.name);
|
|
1126
|
+
}
|
|
849
1127
|
if (!result) return null;
|
|
850
1128
|
const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
|
|
851
1129
|
if (mode === false || mode === "passthrough") {
|
|
@@ -855,7 +1133,7 @@ async function findOneAndDelete(handle, filter, options) {
|
|
|
855
1133
|
return handle.definition.schema.parse(result);
|
|
856
1134
|
} catch (err) {
|
|
857
1135
|
if (err instanceof z2.ZodError) {
|
|
858
|
-
throw new ZodmonValidationError(handle.definition.name, err);
|
|
1136
|
+
throw new ZodmonValidationError(handle.definition.name, err, result);
|
|
859
1137
|
}
|
|
860
1138
|
throw err;
|
|
861
1139
|
}
|
|
@@ -865,13 +1143,13 @@ async function findOneAndDelete(handle, filter, options) {
|
|
|
865
1143
|
import { z as z4 } from "zod";
|
|
866
1144
|
|
|
867
1145
|
// src/errors/not-found.ts
|
|
868
|
-
var ZodmonNotFoundError = class extends
|
|
1146
|
+
var ZodmonNotFoundError = class extends ZodmonError {
|
|
869
1147
|
name = "ZodmonNotFoundError";
|
|
870
|
-
/** The
|
|
871
|
-
|
|
872
|
-
constructor(collection2) {
|
|
873
|
-
super(`Document not found in "${collection2}"
|
|
874
|
-
this.
|
|
1148
|
+
/** The filter that produced no results. */
|
|
1149
|
+
filter;
|
|
1150
|
+
constructor(collection2, filter) {
|
|
1151
|
+
super(`Document not found in "${collection2}"`, collection2);
|
|
1152
|
+
this.filter = filter;
|
|
875
1153
|
}
|
|
876
1154
|
};
|
|
877
1155
|
|
|
@@ -1072,10 +1350,17 @@ var TypedFindCursor = class {
|
|
|
1072
1350
|
}
|
|
1073
1351
|
/** @internal Offset pagination implementation. */
|
|
1074
1352
|
async offsetPaginate(_sortKeys, sort, opts) {
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1353
|
+
let total;
|
|
1354
|
+
let raw2;
|
|
1355
|
+
try {
|
|
1356
|
+
;
|
|
1357
|
+
[total, raw2] = await Promise.all([
|
|
1358
|
+
this.nativeCollection.countDocuments(this.filter),
|
|
1359
|
+
this.nativeCollection.find(this.filter).sort(sort).skip((opts.page - 1) * opts.perPage).limit(opts.perPage).toArray()
|
|
1360
|
+
]);
|
|
1361
|
+
} catch (err) {
|
|
1362
|
+
wrapMongoError(err, this.collectionName);
|
|
1363
|
+
}
|
|
1079
1364
|
const docs = raw2.map((doc) => this.validateDoc(doc));
|
|
1080
1365
|
const totalPages = Math.ceil(total / opts.perPage);
|
|
1081
1366
|
return {
|
|
@@ -1099,7 +1384,12 @@ var TypedFindCursor = class {
|
|
|
1099
1384
|
combinedFilter = this.filter && Object.keys(this.filter).length > 0 ? { $and: [this.filter, cursorFilter] } : cursorFilter;
|
|
1100
1385
|
}
|
|
1101
1386
|
const effectiveSort = isBackward ? Object.fromEntries(sortKeys2.map(([f, d]) => [f, d === 1 ? -1 : 1])) : sort;
|
|
1102
|
-
|
|
1387
|
+
let raw2;
|
|
1388
|
+
try {
|
|
1389
|
+
raw2 = await this.nativeCollection.find(combinedFilter).sort(effectiveSort).limit(opts.limit + 1).toArray();
|
|
1390
|
+
} catch (err) {
|
|
1391
|
+
wrapMongoError(err, this.collectionName);
|
|
1392
|
+
}
|
|
1103
1393
|
const hasMore = raw2.length > opts.limit;
|
|
1104
1394
|
if (hasMore) raw2.pop();
|
|
1105
1395
|
if (isBackward) raw2.reverse();
|
|
@@ -1127,7 +1417,12 @@ var TypedFindCursor = class {
|
|
|
1127
1417
|
* ```
|
|
1128
1418
|
*/
|
|
1129
1419
|
async toArray() {
|
|
1130
|
-
|
|
1420
|
+
let raw2;
|
|
1421
|
+
try {
|
|
1422
|
+
raw2 = await this.cursor.toArray();
|
|
1423
|
+
} catch (err) {
|
|
1424
|
+
wrapMongoError(err, this.collectionName);
|
|
1425
|
+
}
|
|
1131
1426
|
return raw2.map((doc) => this.validateDoc(doc));
|
|
1132
1427
|
}
|
|
1133
1428
|
/**
|
|
@@ -1147,8 +1442,12 @@ var TypedFindCursor = class {
|
|
|
1147
1442
|
* ```
|
|
1148
1443
|
*/
|
|
1149
1444
|
async *[Symbol.asyncIterator]() {
|
|
1150
|
-
|
|
1151
|
-
|
|
1445
|
+
try {
|
|
1446
|
+
for await (const doc of this.cursor) {
|
|
1447
|
+
yield this.validateDoc(doc);
|
|
1448
|
+
}
|
|
1449
|
+
} catch (err) {
|
|
1450
|
+
wrapMongoError(err, this.collectionName);
|
|
1152
1451
|
}
|
|
1153
1452
|
}
|
|
1154
1453
|
/** @internal Validate a single raw document against the schema. */
|
|
@@ -1160,7 +1459,7 @@ var TypedFindCursor = class {
|
|
|
1160
1459
|
return this.schema.parse(raw2);
|
|
1161
1460
|
} catch (err) {
|
|
1162
1461
|
if (err instanceof z3.ZodError) {
|
|
1163
|
-
throw new ZodmonValidationError(this.collectionName, err);
|
|
1462
|
+
throw new ZodmonValidationError(this.collectionName, err, raw2);
|
|
1164
1463
|
}
|
|
1165
1464
|
throw err;
|
|
1166
1465
|
}
|
|
@@ -1171,7 +1470,12 @@ var TypedFindCursor = class {
|
|
|
1171
1470
|
async function findOne(handle, filter, options) {
|
|
1172
1471
|
checkUnindexedFields(handle.definition, filter);
|
|
1173
1472
|
const findOptions = options?.project ? { projection: options.project } : void 0;
|
|
1174
|
-
|
|
1473
|
+
let raw2;
|
|
1474
|
+
try {
|
|
1475
|
+
raw2 = await handle.native.findOne(filter, findOptions);
|
|
1476
|
+
} catch (err) {
|
|
1477
|
+
wrapMongoError(err, handle.definition.name);
|
|
1478
|
+
}
|
|
1175
1479
|
if (!raw2) return null;
|
|
1176
1480
|
const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
|
|
1177
1481
|
if (mode === false || mode === "passthrough") {
|
|
@@ -1181,7 +1485,7 @@ async function findOne(handle, filter, options) {
|
|
|
1181
1485
|
return handle.definition.schema.parse(raw2);
|
|
1182
1486
|
} catch (err) {
|
|
1183
1487
|
if (err instanceof z4.ZodError) {
|
|
1184
|
-
throw new ZodmonValidationError(handle.definition.name, err);
|
|
1488
|
+
throw new ZodmonValidationError(handle.definition.name, err, raw2);
|
|
1185
1489
|
}
|
|
1186
1490
|
throw err;
|
|
1187
1491
|
}
|
|
@@ -1189,7 +1493,7 @@ async function findOne(handle, filter, options) {
|
|
|
1189
1493
|
async function findOneOrThrow(handle, filter, options) {
|
|
1190
1494
|
const doc = await findOne(handle, filter, options);
|
|
1191
1495
|
if (!doc) {
|
|
1192
|
-
throw new ZodmonNotFoundError(handle.definition.name);
|
|
1496
|
+
throw new ZodmonNotFoundError(handle.definition.name, filter);
|
|
1193
1497
|
}
|
|
1194
1498
|
return doc;
|
|
1195
1499
|
}
|
|
@@ -1209,11 +1513,15 @@ async function insertOne(handle, doc) {
|
|
|
1209
1513
|
parsed = handle.definition.schema.parse(doc);
|
|
1210
1514
|
} catch (err) {
|
|
1211
1515
|
if (err instanceof z5.ZodError) {
|
|
1212
|
-
throw new ZodmonValidationError(handle.definition.name, err);
|
|
1516
|
+
throw new ZodmonValidationError(handle.definition.name, err, doc);
|
|
1213
1517
|
}
|
|
1214
1518
|
throw err;
|
|
1215
1519
|
}
|
|
1216
|
-
|
|
1520
|
+
try {
|
|
1521
|
+
await handle.native.insertOne(parsed);
|
|
1522
|
+
} catch (err) {
|
|
1523
|
+
wrapMongoError(err, handle.definition.name);
|
|
1524
|
+
}
|
|
1217
1525
|
return parsed;
|
|
1218
1526
|
}
|
|
1219
1527
|
async function insertMany(handle, docs) {
|
|
@@ -1224,22 +1532,34 @@ async function insertMany(handle, docs) {
|
|
|
1224
1532
|
parsed.push(handle.definition.schema.parse(doc));
|
|
1225
1533
|
} catch (err) {
|
|
1226
1534
|
if (err instanceof z5.ZodError) {
|
|
1227
|
-
throw new ZodmonValidationError(handle.definition.name, err);
|
|
1535
|
+
throw new ZodmonValidationError(handle.definition.name, err, doc);
|
|
1228
1536
|
}
|
|
1229
1537
|
throw err;
|
|
1230
1538
|
}
|
|
1231
1539
|
}
|
|
1232
|
-
|
|
1540
|
+
try {
|
|
1541
|
+
await handle.native.insertMany(parsed);
|
|
1542
|
+
} catch (err) {
|
|
1543
|
+
wrapMongoError(err, handle.definition.name);
|
|
1544
|
+
}
|
|
1233
1545
|
return parsed;
|
|
1234
1546
|
}
|
|
1235
1547
|
|
|
1236
1548
|
// src/crud/update.ts
|
|
1237
1549
|
import { z as z6 } from "zod";
|
|
1238
1550
|
async function updateOne(handle, filter, update, options) {
|
|
1239
|
-
|
|
1551
|
+
try {
|
|
1552
|
+
return await handle.native.updateOne(filter, update, options);
|
|
1553
|
+
} catch (err) {
|
|
1554
|
+
wrapMongoError(err, handle.definition.name);
|
|
1555
|
+
}
|
|
1240
1556
|
}
|
|
1241
1557
|
async function updateMany(handle, filter, update, options) {
|
|
1242
|
-
|
|
1558
|
+
try {
|
|
1559
|
+
return await handle.native.updateMany(filter, update, options);
|
|
1560
|
+
} catch (err) {
|
|
1561
|
+
wrapMongoError(err, handle.definition.name);
|
|
1562
|
+
}
|
|
1243
1563
|
}
|
|
1244
1564
|
async function findOneAndUpdate(handle, filter, update, options) {
|
|
1245
1565
|
const driverOptions = {
|
|
@@ -1249,14 +1569,19 @@ async function findOneAndUpdate(handle, filter, update, options) {
|
|
|
1249
1569
|
if (options?.upsert !== void 0) {
|
|
1250
1570
|
driverOptions["upsert"] = options.upsert;
|
|
1251
1571
|
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1254
|
-
|
|
1255
|
-
|
|
1256
|
-
|
|
1257
|
-
|
|
1258
|
-
|
|
1259
|
-
|
|
1572
|
+
let result;
|
|
1573
|
+
try {
|
|
1574
|
+
result = await handle.native.findOneAndUpdate(
|
|
1575
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
|
|
1576
|
+
filter,
|
|
1577
|
+
// biome-ignore lint/suspicious/noExplicitAny: TypedUpdateFilter intersection type is not directly assignable to MongoDB's UpdateFilter
|
|
1578
|
+
update,
|
|
1579
|
+
// biome-ignore lint/suspicious/noExplicitAny: dynamic options object is not assignable to driver's FindOneAndUpdateOptions under exactOptionalPropertyTypes
|
|
1580
|
+
driverOptions
|
|
1581
|
+
);
|
|
1582
|
+
} catch (err) {
|
|
1583
|
+
wrapMongoError(err, handle.definition.name);
|
|
1584
|
+
}
|
|
1260
1585
|
if (!result) return null;
|
|
1261
1586
|
const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
|
|
1262
1587
|
if (mode === false || mode === "passthrough") {
|
|
@@ -1266,7 +1591,7 @@ async function findOneAndUpdate(handle, filter, update, options) {
|
|
|
1266
1591
|
return handle.definition.schema.parse(result);
|
|
1267
1592
|
} catch (err) {
|
|
1268
1593
|
if (err instanceof z6.ZodError) {
|
|
1269
|
-
throw new ZodmonValidationError(handle.definition.name, err);
|
|
1594
|
+
throw new ZodmonValidationError(handle.definition.name, err, result);
|
|
1270
1595
|
}
|
|
1271
1596
|
throw err;
|
|
1272
1597
|
}
|
|
@@ -1957,8 +2282,18 @@ export {
|
|
|
1957
2282
|
Database,
|
|
1958
2283
|
IndexBuilder,
|
|
1959
2284
|
TypedFindCursor,
|
|
2285
|
+
ZodmonAuthError,
|
|
2286
|
+
ZodmonBulkWriteError,
|
|
2287
|
+
ZodmonDocValidationError,
|
|
2288
|
+
ZodmonDuplicateKeyError,
|
|
2289
|
+
ZodmonError,
|
|
2290
|
+
ZodmonIndexError,
|
|
2291
|
+
ZodmonNetworkError,
|
|
1960
2292
|
ZodmonNotFoundError,
|
|
2293
|
+
ZodmonQueryError,
|
|
2294
|
+
ZodmonTimeoutError,
|
|
1961
2295
|
ZodmonValidationError,
|
|
2296
|
+
ZodmonWriteConflictError,
|
|
1962
2297
|
aggregate,
|
|
1963
2298
|
checkUnindexedFields,
|
|
1964
2299
|
collection,
|
|
@@ -1990,6 +2325,7 @@ export {
|
|
|
1990
2325
|
toCompoundIndexSpec,
|
|
1991
2326
|
toFieldIndexSpec,
|
|
1992
2327
|
updateMany,
|
|
1993
|
-
updateOne
|
|
2328
|
+
updateOne,
|
|
2329
|
+
wrapMongoError
|
|
1994
2330
|
};
|
|
1995
2331
|
//# sourceMappingURL=index.js.map
|