@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 CHANGED
@@ -49,8 +49,18 @@ __export(index_exports, {
49
49
  Database: () => Database,
50
50
  IndexBuilder: () => IndexBuilder,
51
51
  TypedFindCursor: () => TypedFindCursor,
52
+ ZodmonAuthError: () => ZodmonAuthError,
53
+ ZodmonBulkWriteError: () => ZodmonBulkWriteError,
54
+ ZodmonDocValidationError: () => ZodmonDocValidationError,
55
+ ZodmonDuplicateKeyError: () => ZodmonDuplicateKeyError,
56
+ ZodmonError: () => ZodmonError,
57
+ ZodmonIndexError: () => ZodmonIndexError,
58
+ ZodmonNetworkError: () => ZodmonNetworkError,
52
59
  ZodmonNotFoundError: () => ZodmonNotFoundError,
60
+ ZodmonQueryError: () => ZodmonQueryError,
61
+ ZodmonTimeoutError: () => ZodmonTimeoutError,
53
62
  ZodmonValidationError: () => ZodmonValidationError,
63
+ ZodmonWriteConflictError: () => ZodmonWriteConflictError,
54
64
  aggregate: () => aggregate,
55
65
  checkUnindexedFields: () => checkUnindexedFields,
56
66
  collection: () => collection,
@@ -82,7 +92,8 @@ __export(index_exports, {
82
92
  toCompoundIndexSpec: () => toCompoundIndexSpec,
83
93
  toFieldIndexSpec: () => toFieldIndexSpec,
84
94
  updateMany: () => updateMany,
85
- updateOne: () => updateOne
95
+ updateOne: () => updateOne,
96
+ wrapMongoError: () => wrapMongoError
86
97
  });
87
98
  module.exports = __toCommonJS(index_exports);
88
99
 
@@ -187,6 +198,245 @@ function createExpressionBuilder() {
187
198
  };
188
199
  }
189
200
 
201
+ // src/errors/wrap.ts
202
+ var import_mongodb = require("mongodb");
203
+
204
+ // src/errors/base.ts
205
+ var ZodmonError = class extends Error {
206
+ name = "ZodmonError";
207
+ /** The MongoDB collection name associated with this error. */
208
+ collection;
209
+ /** The underlying error that caused this error, if any. */
210
+ cause;
211
+ constructor(message, collection2, options) {
212
+ super(message);
213
+ this.collection = collection2;
214
+ if (options?.cause) {
215
+ this.cause = options.cause;
216
+ }
217
+ }
218
+ };
219
+
220
+ // src/errors/auth.ts
221
+ var ZodmonAuthError = class extends ZodmonError {
222
+ name = "ZodmonAuthError";
223
+ /** The MongoDB error code (13 or 18). */
224
+ code;
225
+ constructor(collection2, code, cause) {
226
+ const message = code === 18 ? `Authentication failed for "${collection2}": check connection credentials` : `Not authorized to perform this operation on "${collection2}"`;
227
+ super(message, collection2, { cause });
228
+ this.code = code;
229
+ }
230
+ };
231
+
232
+ // src/errors/bulk-write.ts
233
+ var ZodmonBulkWriteError = class extends ZodmonError {
234
+ name = "ZodmonBulkWriteError";
235
+ /** Number of documents successfully inserted. */
236
+ insertedCount;
237
+ /** Number of documents matched by update filters. */
238
+ matchedCount;
239
+ /** Number of documents actually modified. */
240
+ modifiedCount;
241
+ /** Number of documents deleted. */
242
+ deletedCount;
243
+ /** Individual write errors with their operation index, code, and message. */
244
+ writeErrors;
245
+ constructor(collection2, cause, totalOps) {
246
+ const bulkErr = cause;
247
+ const result = bulkErr["result"] ?? {};
248
+ const rawErrors = bulkErr["writeErrors"] ?? [];
249
+ const writeErrors = rawErrors.map((e) => ({
250
+ index: e["index"] ?? 0,
251
+ code: e["code"] ?? 0,
252
+ message: e["errmsg"] ?? e["message"] ?? "unknown error"
253
+ }));
254
+ const failedMsg = totalOps !== void 0 ? `${writeErrors.length} of ${totalOps} operations failed` : `${writeErrors.length} operations failed`;
255
+ super(`Bulk write failed on "${collection2}": ${failedMsg}`, collection2, { cause });
256
+ this.insertedCount = result["insertedCount"] ?? 0;
257
+ this.matchedCount = result["matchedCount"] ?? 0;
258
+ this.modifiedCount = result["modifiedCount"] ?? 0;
259
+ this.deletedCount = result["deletedCount"] ?? 0;
260
+ this.writeErrors = writeErrors;
261
+ }
262
+ };
263
+
264
+ // src/errors/doc-validation.ts
265
+ var ZodmonDocValidationError = class extends ZodmonError {
266
+ name = "ZodmonDocValidationError";
267
+ /** Server-provided validation failure details. */
268
+ errInfo;
269
+ constructor(collection2, errInfo, cause) {
270
+ super(
271
+ `Server-side document validation failed for "${collection2}": ${cause.message}`,
272
+ collection2,
273
+ { cause }
274
+ );
275
+ this.errInfo = errInfo;
276
+ }
277
+ };
278
+
279
+ // src/errors/duplicate-key.ts
280
+ var INDEX_REGEX = /index:\s+(\S+)/;
281
+ var DUP_KEY_FIELD_REGEX = /dup key:\s*\{\s*(\w+):/;
282
+ var ZodmonDuplicateKeyError = class extends ZodmonError {
283
+ name = "ZodmonDuplicateKeyError";
284
+ /** The first field that caused the duplicate key violation. */
285
+ field;
286
+ /** The duplicate value, or `undefined` if it could not be extracted. */
287
+ value;
288
+ /** The name of the index that was violated. */
289
+ index;
290
+ /** The key pattern of the violated index (e.g. `{ email: 1 }`). */
291
+ keyPattern;
292
+ /** The key values that caused the violation. */
293
+ keyValue;
294
+ constructor(collection2, cause) {
295
+ const serverErr = cause;
296
+ const kp = serverErr["keyPattern"];
297
+ const kv = serverErr["keyValue"];
298
+ let field;
299
+ let value;
300
+ let keyPattern;
301
+ let keyValue;
302
+ if (kp && kv) {
303
+ const firstKey = Object.keys(kp)[0] ?? "unknown";
304
+ field = firstKey;
305
+ value = kv[firstKey];
306
+ keyPattern = kp;
307
+ keyValue = kv;
308
+ } else {
309
+ const fieldMatch = cause.message.match(DUP_KEY_FIELD_REGEX);
310
+ field = fieldMatch?.[1] ?? "unknown";
311
+ value = void 0;
312
+ keyPattern = field !== "unknown" ? { [field]: 1 } : {};
313
+ keyValue = {};
314
+ }
315
+ const indexMatch = cause.message.match(INDEX_REGEX);
316
+ const index2 = indexMatch?.[1] ?? "unknown";
317
+ const valueStr = typeof value === "string" ? `"${value}"` : String(value);
318
+ super(
319
+ `Duplicate key in "${collection2}": ${field} = ${valueStr} (index: ${index2})`,
320
+ collection2,
321
+ { cause }
322
+ );
323
+ this.field = field;
324
+ this.value = value;
325
+ this.index = index2;
326
+ this.keyPattern = keyPattern;
327
+ this.keyValue = keyValue;
328
+ }
329
+ };
330
+
331
+ // src/errors/index-error.ts
332
+ var ZodmonIndexError = class extends ZodmonError {
333
+ name = "ZodmonIndexError";
334
+ /** The MongoDB error code (67, 85, or 86). */
335
+ code;
336
+ constructor(collection2, code, errmsg, cause) {
337
+ const prefix = code === 67 ? "Cannot create index" : code === 85 ? "Index options conflict" : "Index key specs conflict";
338
+ super(`${prefix} on "${collection2}": ${errmsg}`, collection2, { cause });
339
+ this.code = code;
340
+ }
341
+ };
342
+
343
+ // src/errors/network.ts
344
+ var ZodmonNetworkError = class extends ZodmonError {
345
+ name = "ZodmonNetworkError";
346
+ constructor(collection2, cause) {
347
+ super(`Network error on "${collection2}": ${cause.message}`, collection2, { cause });
348
+ }
349
+ };
350
+
351
+ // src/errors/query.ts
352
+ var ZodmonQueryError = class extends ZodmonError {
353
+ name = "ZodmonQueryError";
354
+ /** The MongoDB error code (2, 9, or 292). */
355
+ code;
356
+ constructor(collection2, code, errmsg, cause) {
357
+ 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}`;
358
+ super(message, collection2, { cause });
359
+ this.code = code;
360
+ }
361
+ };
362
+
363
+ // src/errors/timeout.ts
364
+ var ZodmonTimeoutError = class extends ZodmonError {
365
+ name = "ZodmonTimeoutError";
366
+ /** The MongoDB error code (50 or 262). */
367
+ code;
368
+ constructor(collection2, code, cause) {
369
+ super(`Operation timed out on "${collection2}": exceeded server time limit`, collection2, {
370
+ cause
371
+ });
372
+ this.code = code;
373
+ }
374
+ };
375
+
376
+ // src/errors/write-conflict.ts
377
+ var ZodmonWriteConflictError = class extends ZodmonError {
378
+ name = "ZodmonWriteConflictError";
379
+ constructor(collection2, cause) {
380
+ super(
381
+ `Write conflict in "${collection2}": another operation modified this document concurrently \u2014 retry the transaction`,
382
+ collection2,
383
+ { cause }
384
+ );
385
+ }
386
+ };
387
+
388
+ // src/errors/wrap.ts
389
+ function wrapMongoError(err, collection2) {
390
+ if (err instanceof ZodmonError) {
391
+ throw err;
392
+ }
393
+ if (err instanceof import_mongodb.MongoBulkWriteError) {
394
+ throw new ZodmonBulkWriteError(collection2, err);
395
+ }
396
+ if (err instanceof import_mongodb.MongoNetworkError) {
397
+ throw new ZodmonNetworkError(collection2, err);
398
+ }
399
+ if (err instanceof import_mongodb.MongoServerError) {
400
+ switch (err.code) {
401
+ case 11e3:
402
+ case 11001:
403
+ throw new ZodmonDuplicateKeyError(collection2, err);
404
+ case 112:
405
+ throw new ZodmonWriteConflictError(collection2, err);
406
+ case 50:
407
+ case 262:
408
+ throw new ZodmonTimeoutError(collection2, err.code, err);
409
+ case 13:
410
+ case 18:
411
+ throw new ZodmonAuthError(collection2, err.code, err);
412
+ case 67:
413
+ case 85:
414
+ case 86:
415
+ throw new ZodmonIndexError(collection2, err.code, err.message, err);
416
+ case 2:
417
+ case 9:
418
+ case 292:
419
+ throw new ZodmonQueryError(collection2, err.code, err.message, err);
420
+ case 121:
421
+ throw new ZodmonDocValidationError(
422
+ collection2,
423
+ err.errInfo,
424
+ err
425
+ );
426
+ default:
427
+ throw new ZodmonError(`MongoDB error on "${collection2}": ${err.message}`, collection2, {
428
+ cause: err
429
+ });
430
+ }
431
+ }
432
+ if (err instanceof Error) {
433
+ throw new ZodmonError(`Unexpected error on "${collection2}": ${err.message}`, collection2, {
434
+ cause: err
435
+ });
436
+ }
437
+ throw new ZodmonError(`Unexpected error on "${collection2}": ${String(err)}`, collection2);
438
+ }
439
+
190
440
  // src/schema/ref.ts
191
441
  var import_zod = require("zod");
192
442
  var refMetadata = /* @__PURE__ */ new WeakMap();
@@ -272,8 +522,12 @@ var AggregatePipeline = class _AggregatePipeline {
272
522
  * ```
273
523
  */
274
524
  async toArray() {
275
- const cursor = this.nativeCollection.aggregate(this.stages);
276
- return await cursor.toArray();
525
+ try {
526
+ const cursor = this.nativeCollection.aggregate(this.stages);
527
+ return await cursor.toArray();
528
+ } catch (err) {
529
+ wrapMongoError(err, this.definition.name);
530
+ }
277
531
  }
278
532
  /**
279
533
  * Stream pipeline results one document at a time via `for await...of`.
@@ -288,9 +542,13 @@ var AggregatePipeline = class _AggregatePipeline {
288
542
  * ```
289
543
  */
290
544
  async *[Symbol.asyncIterator]() {
291
- const cursor = this.nativeCollection.aggregate(this.stages);
292
- for await (const doc of cursor) {
293
- yield doc;
545
+ try {
546
+ const cursor = this.nativeCollection.aggregate(this.stages);
547
+ for await (const doc of cursor) {
548
+ yield doc;
549
+ }
550
+ } catch (err) {
551
+ wrapMongoError(err, this.definition.name);
294
552
  }
295
553
  }
296
554
  /**
@@ -310,8 +568,12 @@ var AggregatePipeline = class _AggregatePipeline {
310
568
  * ```
311
569
  */
312
570
  async explain() {
313
- const cursor = this.nativeCollection.aggregate(this.stages);
314
- return await cursor.explain();
571
+ try {
572
+ const cursor = this.nativeCollection.aggregate(this.stages);
573
+ return await cursor.explain();
574
+ } catch (err) {
575
+ wrapMongoError(err, this.definition.name);
576
+ }
315
577
  }
316
578
  // ── Shape-preserving stages ──────────────────────────────────────
317
579
  /**
@@ -736,7 +998,7 @@ function aggregate(handle) {
736
998
  }
737
999
 
738
1000
  // src/client/client.ts
739
- var import_mongodb2 = require("mongodb");
1001
+ var import_mongodb3 = require("mongodb");
740
1002
 
741
1003
  // src/indexes/spec.ts
742
1004
  function toFieldIndexSpec(def) {
@@ -808,7 +1070,7 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
808
1070
  const serialized = serializeIndexKey(spec.key);
809
1071
  const existing = existingByKey.get(serialized);
810
1072
  if (!existing) {
811
- if (!dryRun) await native.createIndex(spec.key, spec.options);
1073
+ if (!dryRun) await safeCreateIndex(native, spec.key, spec.options);
812
1074
  acc.created.push(resolveSpecName(spec));
813
1075
  return;
814
1076
  }
@@ -821,8 +1083,8 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
821
1083
  }
822
1084
  if (dropOrphaned) {
823
1085
  if (!dryRun) {
824
- await native.dropIndex(existingName);
825
- await native.createIndex(spec.key, spec.options);
1086
+ await safeDropIndex(native, existingName);
1087
+ await safeCreateIndex(native, spec.key, spec.options);
826
1088
  }
827
1089
  acc.dropped.push(existingName);
828
1090
  acc.created.push(resolveSpecName(spec));
@@ -835,6 +1097,20 @@ async function processDesiredSpec(spec, existingByKey, native, dryRun, dropOrpha
835
1097
  desired: spec.options
836
1098
  });
837
1099
  }
1100
+ async function safeCreateIndex(native, key, options) {
1101
+ try {
1102
+ await native.createIndex(key, options);
1103
+ } catch (err) {
1104
+ wrapMongoError(err, native.collectionName);
1105
+ }
1106
+ }
1107
+ async function safeDropIndex(native, name) {
1108
+ try {
1109
+ await native.dropIndex(name);
1110
+ } catch (err) {
1111
+ wrapMongoError(err, native.collectionName);
1112
+ }
1113
+ }
838
1114
  async function processOrphanedIndexes(existingIndexes, desiredKeys, matchedKeys, native, dryRun, dropOrphaned, dropped) {
839
1115
  for (const idx of existingIndexes) {
840
1116
  const rawName = idx["name"];
@@ -843,7 +1119,7 @@ async function processOrphanedIndexes(existingIndexes, desiredKeys, matchedKeys,
843
1119
  const serialized = serializeIndexKey(idx["key"]);
844
1120
  if (matchedKeys.has(serialized) || desiredKeys.has(serialized)) continue;
845
1121
  if (dropOrphaned) {
846
- if (!dryRun) await native.dropIndex(name);
1122
+ if (!dryRun) await safeDropIndex(native, name);
847
1123
  dropped.push(name);
848
1124
  }
849
1125
  }
@@ -855,7 +1131,7 @@ async function listIndexesSafe(native) {
855
1131
  if (err instanceof Error && err.message.includes("ns does not exist")) {
856
1132
  return [];
857
1133
  }
858
- throw err;
1134
+ wrapMongoError(err, native.collectionName);
859
1135
  }
860
1136
  }
861
1137
  async function syncIndexes(handle, options) {
@@ -904,36 +1180,49 @@ async function syncIndexes(handle, options) {
904
1180
  var import_zod2 = require("zod");
905
1181
 
906
1182
  // src/errors/validation.ts
907
- var ZodmonValidationError = class extends Error {
1183
+ var ZodmonValidationError = class extends ZodmonError {
908
1184
  name = "ZodmonValidationError";
909
- /** The MongoDB collection name where the validation failed. */
910
- collection;
911
1185
  /** The original Zod validation error with detailed issue information. */
912
1186
  zodError;
913
- constructor(collection2, zodError) {
1187
+ /** The document that failed validation. */
1188
+ document;
1189
+ constructor(collection2, zodError, document) {
914
1190
  const fields = zodError.issues.map((issue) => {
915
1191
  const path = issue.path.join(".") || "(root)";
916
1192
  return `${path} (${issue.message})`;
917
1193
  }).join(", ");
918
- super(`Validation failed for "${collection2}": ${fields}`);
919
- this.collection = collection2;
1194
+ super(`Validation failed for "${collection2}": ${fields}`, collection2, { cause: zodError });
920
1195
  this.zodError = zodError;
1196
+ this.document = document;
921
1197
  }
922
1198
  };
923
1199
 
924
1200
  // src/crud/delete.ts
925
1201
  async function deleteOne(handle, filter) {
926
- return await handle.native.deleteOne(filter);
1202
+ try {
1203
+ return await handle.native.deleteOne(filter);
1204
+ } catch (err) {
1205
+ wrapMongoError(err, handle.definition.name);
1206
+ }
927
1207
  }
928
1208
  async function deleteMany(handle, filter) {
929
- return await handle.native.deleteMany(filter);
1209
+ try {
1210
+ return await handle.native.deleteMany(filter);
1211
+ } catch (err) {
1212
+ wrapMongoError(err, handle.definition.name);
1213
+ }
930
1214
  }
931
1215
  async function findOneAndDelete(handle, filter, options) {
932
- const result = await handle.native.findOneAndDelete(
933
- // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
934
- filter,
935
- { includeResultMetadata: false }
936
- );
1216
+ let result;
1217
+ try {
1218
+ result = await handle.native.findOneAndDelete(
1219
+ // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
1220
+ filter,
1221
+ { includeResultMetadata: false }
1222
+ );
1223
+ } catch (err) {
1224
+ wrapMongoError(err, handle.definition.name);
1225
+ }
937
1226
  if (!result) return null;
938
1227
  const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
939
1228
  if (mode === false || mode === "passthrough") {
@@ -943,7 +1232,7 @@ async function findOneAndDelete(handle, filter, options) {
943
1232
  return handle.definition.schema.parse(result);
944
1233
  } catch (err) {
945
1234
  if (err instanceof import_zod2.z.ZodError) {
946
- throw new ZodmonValidationError(handle.definition.name, err);
1235
+ throw new ZodmonValidationError(handle.definition.name, err, result);
947
1236
  }
948
1237
  throw err;
949
1238
  }
@@ -953,13 +1242,13 @@ async function findOneAndDelete(handle, filter, options) {
953
1242
  var import_zod4 = require("zod");
954
1243
 
955
1244
  // src/errors/not-found.ts
956
- var ZodmonNotFoundError = class extends Error {
1245
+ var ZodmonNotFoundError = class extends ZodmonError {
957
1246
  name = "ZodmonNotFoundError";
958
- /** The MongoDB collection name where the query found no results. */
959
- collection;
960
- constructor(collection2) {
961
- super(`Document not found in "${collection2}"`);
962
- this.collection = collection2;
1247
+ /** The filter that produced no results. */
1248
+ filter;
1249
+ constructor(collection2, filter) {
1250
+ super(`Document not found in "${collection2}"`, collection2);
1251
+ this.filter = filter;
963
1252
  }
964
1253
  };
965
1254
 
@@ -990,15 +1279,15 @@ function checkUnindexedFields(definition, filter) {
990
1279
  var import_zod3 = require("zod");
991
1280
 
992
1281
  // src/crud/paginate.ts
993
- var import_mongodb = require("mongodb");
1282
+ var import_mongodb2 = require("mongodb");
994
1283
  function serializeValue(value) {
995
- if (value instanceof import_mongodb.ObjectId) return { $oid: value.toHexString() };
1284
+ if (value instanceof import_mongodb2.ObjectId) return { $oid: value.toHexString() };
996
1285
  if (value instanceof Date) return { $date: value.getTime() };
997
1286
  return value;
998
1287
  }
999
1288
  function deserializeValue(value) {
1000
1289
  if (value != null && typeof value === "object") {
1001
- if ("$oid" in value) return new import_mongodb.ObjectId(value.$oid);
1290
+ if ("$oid" in value) return new import_mongodb2.ObjectId(value.$oid);
1002
1291
  if ("$date" in value) return new Date(value.$date);
1003
1292
  }
1004
1293
  return value;
@@ -1160,10 +1449,17 @@ var TypedFindCursor = class {
1160
1449
  }
1161
1450
  /** @internal Offset pagination implementation. */
1162
1451
  async offsetPaginate(_sortKeys, sort, opts) {
1163
- const [total, raw2] = await Promise.all([
1164
- this.nativeCollection.countDocuments(this.filter),
1165
- this.nativeCollection.find(this.filter).sort(sort).skip((opts.page - 1) * opts.perPage).limit(opts.perPage).toArray()
1166
- ]);
1452
+ let total;
1453
+ let raw2;
1454
+ try {
1455
+ ;
1456
+ [total, raw2] = await Promise.all([
1457
+ this.nativeCollection.countDocuments(this.filter),
1458
+ this.nativeCollection.find(this.filter).sort(sort).skip((opts.page - 1) * opts.perPage).limit(opts.perPage).toArray()
1459
+ ]);
1460
+ } catch (err) {
1461
+ wrapMongoError(err, this.collectionName);
1462
+ }
1167
1463
  const docs = raw2.map((doc) => this.validateDoc(doc));
1168
1464
  const totalPages = Math.ceil(total / opts.perPage);
1169
1465
  return {
@@ -1187,7 +1483,12 @@ var TypedFindCursor = class {
1187
1483
  combinedFilter = this.filter && Object.keys(this.filter).length > 0 ? { $and: [this.filter, cursorFilter] } : cursorFilter;
1188
1484
  }
1189
1485
  const effectiveSort = isBackward ? Object.fromEntries(sortKeys2.map(([f, d]) => [f, d === 1 ? -1 : 1])) : sort;
1190
- const raw2 = await this.nativeCollection.find(combinedFilter).sort(effectiveSort).limit(opts.limit + 1).toArray();
1486
+ let raw2;
1487
+ try {
1488
+ raw2 = await this.nativeCollection.find(combinedFilter).sort(effectiveSort).limit(opts.limit + 1).toArray();
1489
+ } catch (err) {
1490
+ wrapMongoError(err, this.collectionName);
1491
+ }
1191
1492
  const hasMore = raw2.length > opts.limit;
1192
1493
  if (hasMore) raw2.pop();
1193
1494
  if (isBackward) raw2.reverse();
@@ -1215,7 +1516,12 @@ var TypedFindCursor = class {
1215
1516
  * ```
1216
1517
  */
1217
1518
  async toArray() {
1218
- const raw2 = await this.cursor.toArray();
1519
+ let raw2;
1520
+ try {
1521
+ raw2 = await this.cursor.toArray();
1522
+ } catch (err) {
1523
+ wrapMongoError(err, this.collectionName);
1524
+ }
1219
1525
  return raw2.map((doc) => this.validateDoc(doc));
1220
1526
  }
1221
1527
  /**
@@ -1235,8 +1541,12 @@ var TypedFindCursor = class {
1235
1541
  * ```
1236
1542
  */
1237
1543
  async *[Symbol.asyncIterator]() {
1238
- for await (const doc of this.cursor) {
1239
- yield this.validateDoc(doc);
1544
+ try {
1545
+ for await (const doc of this.cursor) {
1546
+ yield this.validateDoc(doc);
1547
+ }
1548
+ } catch (err) {
1549
+ wrapMongoError(err, this.collectionName);
1240
1550
  }
1241
1551
  }
1242
1552
  /** @internal Validate a single raw document against the schema. */
@@ -1248,7 +1558,7 @@ var TypedFindCursor = class {
1248
1558
  return this.schema.parse(raw2);
1249
1559
  } catch (err) {
1250
1560
  if (err instanceof import_zod3.z.ZodError) {
1251
- throw new ZodmonValidationError(this.collectionName, err);
1561
+ throw new ZodmonValidationError(this.collectionName, err, raw2);
1252
1562
  }
1253
1563
  throw err;
1254
1564
  }
@@ -1259,7 +1569,12 @@ var TypedFindCursor = class {
1259
1569
  async function findOne(handle, filter, options) {
1260
1570
  checkUnindexedFields(handle.definition, filter);
1261
1571
  const findOptions = options?.project ? { projection: options.project } : void 0;
1262
- const raw2 = await handle.native.findOne(filter, findOptions);
1572
+ let raw2;
1573
+ try {
1574
+ raw2 = await handle.native.findOne(filter, findOptions);
1575
+ } catch (err) {
1576
+ wrapMongoError(err, handle.definition.name);
1577
+ }
1263
1578
  if (!raw2) return null;
1264
1579
  const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
1265
1580
  if (mode === false || mode === "passthrough") {
@@ -1269,7 +1584,7 @@ async function findOne(handle, filter, options) {
1269
1584
  return handle.definition.schema.parse(raw2);
1270
1585
  } catch (err) {
1271
1586
  if (err instanceof import_zod4.z.ZodError) {
1272
- throw new ZodmonValidationError(handle.definition.name, err);
1587
+ throw new ZodmonValidationError(handle.definition.name, err, raw2);
1273
1588
  }
1274
1589
  throw err;
1275
1590
  }
@@ -1277,7 +1592,7 @@ async function findOne(handle, filter, options) {
1277
1592
  async function findOneOrThrow(handle, filter, options) {
1278
1593
  const doc = await findOne(handle, filter, options);
1279
1594
  if (!doc) {
1280
- throw new ZodmonNotFoundError(handle.definition.name);
1595
+ throw new ZodmonNotFoundError(handle.definition.name, filter);
1281
1596
  }
1282
1597
  return doc;
1283
1598
  }
@@ -1297,11 +1612,15 @@ async function insertOne(handle, doc) {
1297
1612
  parsed = handle.definition.schema.parse(doc);
1298
1613
  } catch (err) {
1299
1614
  if (err instanceof import_zod5.z.ZodError) {
1300
- throw new ZodmonValidationError(handle.definition.name, err);
1615
+ throw new ZodmonValidationError(handle.definition.name, err, doc);
1301
1616
  }
1302
1617
  throw err;
1303
1618
  }
1304
- await handle.native.insertOne(parsed);
1619
+ try {
1620
+ await handle.native.insertOne(parsed);
1621
+ } catch (err) {
1622
+ wrapMongoError(err, handle.definition.name);
1623
+ }
1305
1624
  return parsed;
1306
1625
  }
1307
1626
  async function insertMany(handle, docs) {
@@ -1312,22 +1631,34 @@ async function insertMany(handle, docs) {
1312
1631
  parsed.push(handle.definition.schema.parse(doc));
1313
1632
  } catch (err) {
1314
1633
  if (err instanceof import_zod5.z.ZodError) {
1315
- throw new ZodmonValidationError(handle.definition.name, err);
1634
+ throw new ZodmonValidationError(handle.definition.name, err, doc);
1316
1635
  }
1317
1636
  throw err;
1318
1637
  }
1319
1638
  }
1320
- await handle.native.insertMany(parsed);
1639
+ try {
1640
+ await handle.native.insertMany(parsed);
1641
+ } catch (err) {
1642
+ wrapMongoError(err, handle.definition.name);
1643
+ }
1321
1644
  return parsed;
1322
1645
  }
1323
1646
 
1324
1647
  // src/crud/update.ts
1325
1648
  var import_zod6 = require("zod");
1326
1649
  async function updateOne(handle, filter, update, options) {
1327
- return await handle.native.updateOne(filter, update, options);
1650
+ try {
1651
+ return await handle.native.updateOne(filter, update, options);
1652
+ } catch (err) {
1653
+ wrapMongoError(err, handle.definition.name);
1654
+ }
1328
1655
  }
1329
1656
  async function updateMany(handle, filter, update, options) {
1330
- return await handle.native.updateMany(filter, update, options);
1657
+ try {
1658
+ return await handle.native.updateMany(filter, update, options);
1659
+ } catch (err) {
1660
+ wrapMongoError(err, handle.definition.name);
1661
+ }
1331
1662
  }
1332
1663
  async function findOneAndUpdate(handle, filter, update, options) {
1333
1664
  const driverOptions = {
@@ -1337,14 +1668,19 @@ async function findOneAndUpdate(handle, filter, update, options) {
1337
1668
  if (options?.upsert !== void 0) {
1338
1669
  driverOptions["upsert"] = options.upsert;
1339
1670
  }
1340
- const result = await handle.native.findOneAndUpdate(
1341
- // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
1342
- filter,
1343
- // biome-ignore lint/suspicious/noExplicitAny: TypedUpdateFilter intersection type is not directly assignable to MongoDB's UpdateFilter
1344
- update,
1345
- // biome-ignore lint/suspicious/noExplicitAny: dynamic options object is not assignable to driver's FindOneAndUpdateOptions under exactOptionalPropertyTypes
1346
- driverOptions
1347
- );
1671
+ let result;
1672
+ try {
1673
+ result = await handle.native.findOneAndUpdate(
1674
+ // biome-ignore lint/suspicious/noExplicitAny: TypedFilter intersection type is not directly assignable to MongoDB's Filter
1675
+ filter,
1676
+ // biome-ignore lint/suspicious/noExplicitAny: TypedUpdateFilter intersection type is not directly assignable to MongoDB's UpdateFilter
1677
+ update,
1678
+ // biome-ignore lint/suspicious/noExplicitAny: dynamic options object is not assignable to driver's FindOneAndUpdateOptions under exactOptionalPropertyTypes
1679
+ driverOptions
1680
+ );
1681
+ } catch (err) {
1682
+ wrapMongoError(err, handle.definition.name);
1683
+ }
1348
1684
  if (!result) return null;
1349
1685
  const mode = options?.validate !== void 0 ? options.validate : handle.definition.options.validation;
1350
1686
  if (mode === false || mode === "passthrough") {
@@ -1354,7 +1690,7 @@ async function findOneAndUpdate(handle, filter, update, options) {
1354
1690
  return handle.definition.schema.parse(result);
1355
1691
  } catch (err) {
1356
1692
  if (err instanceof import_zod6.z.ZodError) {
1357
- throw new ZodmonValidationError(handle.definition.name, err);
1693
+ throw new ZodmonValidationError(handle.definition.name, err, result);
1358
1694
  }
1359
1695
  throw err;
1360
1696
  }
@@ -1674,7 +2010,7 @@ var Database = class {
1674
2010
  /** Registered collection definitions, keyed by name. Used by syncIndexes(). */
1675
2011
  _collections = /* @__PURE__ */ new Map();
1676
2012
  constructor(uri, dbName, options) {
1677
- this._client = new import_mongodb2.MongoClient(uri, options);
2013
+ this._client = new import_mongodb3.MongoClient(uri, options);
1678
2014
  this._db = this._client.db(dbName);
1679
2015
  }
1680
2016
  /**
@@ -1763,7 +2099,7 @@ function createClient(uri, dbNameOrOptions, maybeOptions) {
1763
2099
  }
1764
2100
 
1765
2101
  // src/collection/collection.ts
1766
- var import_mongodb4 = require("mongodb");
2102
+ var import_mongodb5 = require("mongodb");
1767
2103
  var import_zod9 = require("zod");
1768
2104
 
1769
2105
  // src/schema/extensions.ts
@@ -1873,14 +2209,14 @@ function installExtensions() {
1873
2209
  installExtensions();
1874
2210
 
1875
2211
  // src/schema/object-id.ts
1876
- var import_mongodb3 = require("mongodb");
2212
+ var import_mongodb4 = require("mongodb");
1877
2213
  var import_zod8 = require("zod");
1878
2214
  var OBJECT_ID_HEX = /^[a-f\d]{24}$/i;
1879
2215
  function objectId() {
1880
2216
  return import_zod8.z.custom((val) => {
1881
- if (val instanceof import_mongodb3.ObjectId) return true;
2217
+ if (val instanceof import_mongodb4.ObjectId) return true;
1882
2218
  return typeof val === "string" && OBJECT_ID_HEX.test(val);
1883
- }, "Invalid ObjectId").transform((val) => val instanceof import_mongodb3.ObjectId ? val : import_mongodb3.ObjectId.createFromHexString(val));
2219
+ }, "Invalid ObjectId").transform((val) => val instanceof import_mongodb4.ObjectId ? val : import_mongodb4.ObjectId.createFromHexString(val));
1884
2220
  }
1885
2221
 
1886
2222
  // src/collection/collection.ts
@@ -1895,7 +2231,7 @@ function extractFieldIndexes(shape) {
1895
2231
  return result;
1896
2232
  }
1897
2233
  function collection(name, shape, options) {
1898
- const resolvedShape = "_id" in shape ? shape : { _id: objectId().default(() => new import_mongodb4.ObjectId()), ...shape };
2234
+ const resolvedShape = "_id" in shape ? shape : { _id: objectId().default(() => new import_mongodb5.ObjectId()), ...shape };
1899
2235
  const schema = import_zod9.z.object(resolvedShape);
1900
2236
  const fieldIndexes = extractFieldIndexes(shape);
1901
2237
  const { indexes: compoundIndexes, validation, ...rest } = options ?? {};
@@ -1966,14 +2302,14 @@ function index(fields) {
1966
2302
  }
1967
2303
 
1968
2304
  // src/helpers/oid.ts
1969
- var import_mongodb5 = require("mongodb");
2305
+ var import_mongodb6 = require("mongodb");
1970
2306
  function oid(value) {
1971
- if (value === void 0) return new import_mongodb5.ObjectId();
1972
- if (value instanceof import_mongodb5.ObjectId) return value;
1973
- return import_mongodb5.ObjectId.createFromHexString(value);
2307
+ if (value === void 0) return new import_mongodb6.ObjectId();
2308
+ if (value instanceof import_mongodb6.ObjectId) return value;
2309
+ return import_mongodb6.ObjectId.createFromHexString(value);
1974
2310
  }
1975
2311
  function isOid(value) {
1976
- return value instanceof import_mongodb5.ObjectId;
2312
+ return value instanceof import_mongodb6.ObjectId;
1977
2313
  }
1978
2314
 
1979
2315
  // src/query/operators.ts
@@ -2046,8 +2382,18 @@ var $ = {
2046
2382
  Database,
2047
2383
  IndexBuilder,
2048
2384
  TypedFindCursor,
2385
+ ZodmonAuthError,
2386
+ ZodmonBulkWriteError,
2387
+ ZodmonDocValidationError,
2388
+ ZodmonDuplicateKeyError,
2389
+ ZodmonError,
2390
+ ZodmonIndexError,
2391
+ ZodmonNetworkError,
2049
2392
  ZodmonNotFoundError,
2393
+ ZodmonQueryError,
2394
+ ZodmonTimeoutError,
2050
2395
  ZodmonValidationError,
2396
+ ZodmonWriteConflictError,
2051
2397
  aggregate,
2052
2398
  checkUnindexedFields,
2053
2399
  collection,
@@ -2079,6 +2425,7 @@ var $ = {
2079
2425
  toCompoundIndexSpec,
2080
2426
  toFieldIndexSpec,
2081
2427
  updateMany,
2082
- updateOne
2428
+ updateOne,
2429
+ wrapMongoError
2083
2430
  });
2084
2431
  //# sourceMappingURL=index.cjs.map