@ignex/ninox 0.1.7 → 0.2.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/README.md CHANGED
@@ -281,7 +281,7 @@ builder, and the MongoDB `$jsonSchema` validator + indexes installed by
281
281
  | field kind | `s.*` | inferred TS type |
282
282
  | --- | --- | --- |
283
283
  | string / int / number | `s.string()` / `s.integer()` / `s.number()` | `string` / `number` / `number` |
284
- | exact BSON kinds | `s.double()` / `s.long()` / `s.decimal()` | `number` / `number` / `Decimal128` |
284
+ | exact BSON kinds | `s.double()` / `s.long()` / `s.decimal()` | `number` / `Long` / `Decimal128` |
285
285
  | other scalars | `s.boolean()` / `s.date()` / `s.objectId()` | `boolean` / `Date` / `ObjectId` |
286
286
  | enum | `s.enum(['a', 'b'] as const)` | `'a' \| 'b'` (string or numeric literals) |
287
287
  | array | `s.array(s.string())` | `string[]` |
@@ -293,8 +293,10 @@ builder, and the MongoDB `$jsonSchema` validator + indexes installed by
293
293
  Constraints mirror `$jsonSchema`: strings (`minLength` / `maxLength` / `pattern`),
294
294
  numbers (`minimum` / `maximum` / `multipleOf` / `exclusiveMinimum` /
295
295
  `exclusiveMaximum`), arrays (`minItems` / `maxItems` / `uniqueItems`), objects
296
- (`minProperties` / `maxProperties` / `additionalProperties`). `format` is
297
- accepted but a no-op (MongoDB rejects the `$jsonSchema` keyword).
296
+ (`minProperties` / `maxProperties` / `additionalProperties`). String `format`
297
+ is validated client-side for `email`, `uri`, `date-time`, `date`, `uuid`,
298
+ `hostname`, `ipv4`, and `ipv6`; it is not sent to MongoDB because the server
299
+ rejects that `$jsonSchema` keyword.
298
300
 
299
301
  ```ts
300
302
  const userSchema = s.object({
@@ -342,7 +344,10 @@ do {
342
344
  ```
343
345
 
344
346
  `paginateCursor` supports `after` (forward) and `before` (backward); a sort whose
345
- keys don't match the cursor's is rejected at runtime.
347
+ keys don't match the cursor's is rejected at runtime. The final sort key must be
348
+ `_id` or an explicitly named `uniqueTiebreaker` with a unique index. Dotted paths
349
+ and BSON values are supported. Offset pagination rejects offsets above 10,000 by
350
+ default (`maxOffset` overrides); use keyset pagination for deep traversal.
346
351
 
347
352
  ## Geospatial
348
353
 
@@ -423,6 +428,11 @@ await db.populate(products, [
423
428
  // orders[0].customer, orders[0].more, products[0].tags are all typed.
424
429
  ```
425
430
 
431
+ Populate reads are fresh by default. Pass `session`, `maxTimeMS`, read concern,
432
+ or read preference in the options. `maxDocs` is an optional safety cap that
433
+ throws on overflow rather than silently truncating a relation; `queryCache:
434
+ true` explicitly opts into the shared read cache.
435
+
426
436
  ## Repository layer
427
437
 
428
438
  `createRepository(manager, 'collection')` wraps a manager + collection into a
@@ -454,12 +464,14 @@ const users = defineCollection('users', userSchema, {
454
464
 
455
465
  ## Transactions & migrations
456
466
 
457
- - `db.transaction(async (session) => ...)` — graceful session transactions with a
458
- capability probe; on standalone servers (no transactions) it falls back to
459
- plain non-transactional execution with `session === null`.
467
+ - `db.transaction(async (session) => ...)` throws on standalone servers by
468
+ default. To accept non-atomic execution explicitly, pass
469
+ `{ allowNonTransactionalFallback: true }`; the callback then receives `null`.
460
470
  - `createMongoMigrationRunner(service, { migrationDir })` — file-based migrations
461
- (`NNN_name.ts`, each exporting `up` / `down`) with a claim-based idempotency
462
- journal (`_migrations`), safe under concurrent runners.
471
+ (`NNN_name.ts`, each exporting `up` / `down`) with a lease- and owner-token-
472
+ fenced journal (`_migrations`), safe under concurrent runners and stale-worker
473
+ takeover. Migrations should remain idempotent: file migrations are not
474
+ automatically wrapped in a database transaction.
463
475
 
464
476
  ```ts
465
477
  const runner = createMongoMigrationRunner(service, { migrationDir: './migrations' });
@@ -501,8 +513,8 @@ reports current size plus lifetime `hits` / `misses` / `sets` / `deletes` /
501
513
  > ⚠️ **Cache invalidation is write-through only.** Every ninox write drops that
502
514
  > collection's cached reads, but reads are **not** invalidated by external
503
515
  > writers — other processes, the raw `client` escape hatch, or direct DB
504
- > writes. With the default `ttlMs: 0` those reads stay stale indefinitely, so
505
- > multi-writer deployments should set `cache: { ttlMs }`, disable the cache,
516
+ > writes. The default `ttlMs: 30_000` bounds that staleness; `ttlMs: 0` is an
517
+ > explicit unbounded-cache opt-in. Multi-writer deployments can disable the cache,
506
518
  > route latency-critical reads through the change-stream-aware
507
519
  > [`createHotCache()`](#hot-cache-high-throughput), or — on a replica set — opt
508
520
  > into `cacheWatch: true`:
@@ -786,16 +798,18 @@ you need the code → status mapping yourself.
786
798
  > (at-least-once); opt in per op with `retryWrites: true`. Reads always retry
787
799
  > transient errors.
788
800
 
789
- Schema validation is enforced **by MongoDB** — the DB `$jsonSchema` validator
790
- derived from your schema is installed with `createSchema`, and the DB rejects
791
- violating writes with `VALIDATION_FAILED`. `createSchema` is **idempotent and
801
+ Schema validation is enforced **by ninox and MongoDB** — inserts and full
802
+ replacements are validated client-side by default (`validateWrites: false` opts
803
+ out), while the DB `$jsonSchema` validator remains the backstop for partial
804
+ updates, raw writes, and other clients. Violations raise `VALIDATION_FAILED`. `createSchema` is **idempotent and
792
805
  self-reconciling**: it provisions a NEW collection, and when the collection
793
806
  already exists it upgrades the DB schema to match the current ORM schema
794
807
  (hot-swapping the validator via `collMod` only when it has drifted, and
795
808
  creating any newly-declared indexes) — so calling it on every boot keeps
796
809
  Mongo's schema in lockstep with your models as they change. `updateSchema`
797
- hot-swaps a validator explicitly (via `collMod`). ninox deliberately does
798
- **not** validate *incoming user input* at runtime (no client-side/zod layer).
810
+ hot-swaps a validator explicitly (via `collMod`) and updates the manager's
811
+ active schema. Client validation covers the DSL and raw `$jsonSchema` keywords;
812
+ partial update operators are still enforced by the database.
799
813
 
800
814
  - **Strict by default** — `additionalProperties: false` is emitted unless a
801
815
  field opts out (`s.object({ ... }, { additionalProperties: true })`), so
@@ -898,6 +912,8 @@ createMongoService(clients, {
898
912
  cache: { maxSize: 1000, ttlMs: 30_000, clone: true }, // configure the default cache
899
913
  cacheWatch: true, // change-stream invalidation of the cache (replica sets)
900
914
  drift: 'report', // read-time schema-drift detection ('report'|'throw'|'off')
915
+ validateWrites: true, // validate inserts/replacements before the DB call
916
+ allowNonTransactionalFallback: false, // throw instead of losing atomicity
901
917
  dedupeReads: true,
902
918
  perf: true, // master switch for cache + dedup
903
919
  });
@@ -908,8 +924,8 @@ createMongoService(clients, {
908
924
  - `service.health()` — ping every connected DB and report `{ ok, latencyMs, dbs }`.
909
925
  - **Multi-DB services** — define several clients in one service; each gets its own
910
926
  typed manager (`service.db.primaryClient`, `service.db.auditClient`, …), one
911
- connection pool per URL, and **cache/dedup keys are namespaced by database** so
912
- same-named collections in different databases never collide.
927
+ connection pool per URL, and **cache/dedup keys are namespaced by deployment,
928
+ database, and collection** so same-named collections never collide.
913
929
  - `watchCollection` / repository `.watch()` — caller-owned change streams.
914
930
  - `eachDb(fn)` — run a function over every connected manager.
915
931
 
@@ -1000,8 +1016,8 @@ bun run bench # → bench/results/summary.json
1000
1016
 
1001
1017
  **Multi-DB cache isolation.** A single service can define several DB clients; the
1002
1018
  query cache and in-flight dedup are shared across them, and their keys are
1003
- namespaced by **database** — so same-named physical collections in different
1004
- databases can never share (or coalesce) entries. No action needed; it's handled.
1019
+ namespaced by **deployment and database** — same-named physical collections in
1020
+ different databases or clusters can never share (or coalesce) entries.
1005
1021
 
1006
1022
  **Standalone HotCache freshness is opt-in per query.** In standalone mode the
1007
1023
  ticker only refreshes queries that set `refreshIntervalMs`. A query with neither
@@ -1037,9 +1053,16 @@ the cache-effectiveness signals to watch in production.
1037
1053
  ## Tests
1038
1054
 
1039
1055
  ```bash
1040
- bun test # unit + integration (integration skips when no Mongo is reachable)
1056
+ bun test # unit + integration (Mongo suites skip when no server is reachable)
1057
+ bun run test:e2e # public-API workflows; fails unless MONGO_URL is reachable
1041
1058
  ```
1042
1059
 
1060
+ The e2e suite exercises real MongoDB schema validation, CRUD/repository flows,
1061
+ relations, aggregation, both pagination strategies, cache consistency,
1062
+ migrations, multi-DB behavior, and health checks. On a replica set it also
1063
+ verifies transaction commit/rollback; on standalone it verifies the explicit
1064
+ non-transactional fallback. Set `MONGO_URL` to select the server.
1065
+
1043
1066
  ## Development
1044
1067
 
1045
1068
  ```bash
@@ -1058,7 +1081,8 @@ npm pack --dry-run # inspect the published tarball contents
1058
1081
  The `files` allowlist ships `dist/`, `LICENSE`, and `README.md` — no `src/`,
1059
1082
  tests, or examples. CI enforces typecheck, lint, dependency audit, coverage
1060
1083
  (≥ 85%), the full example suite, a replica-set job for the HotCache
1061
- change-stream tests, and an `npm pack` → fresh Node consumer smoke test.
1084
+ change-stream tests, e2e compatibility jobs for MongoDB 4.4/5/6/7/8, and an
1085
+ `npm pack` → fresh Node consumer that runs real CRUD and pagination.
1062
1086
 
1063
1087
  Release notes are kept in [`CHANGELOG.md`](./CHANGELOG.md). The publish gate
1064
1088
  (`prepublishOnly`) runs typecheck + lint + build.
package/dist/index.d.ts CHANGED
@@ -1,7 +1,8 @@
1
1
  import * as mongodb from 'mongodb';
2
- import { Db, MongoClient, ClientSession, Document, Filter, Hint, CollationOptions, ReadPreferenceLike, ReadConcern, WriteConcern, WithId, Condition, RootFilterOperators, Collection, FindOptions, Sort, FindCursor, ObjectId, Decimal128, ReadConcernLike, AggregateOptions, AggregationCursor, CreateCollectionOptions, TransactionOptions, InsertOneOptions, InsertOneResult, InsertManyResult, UpdateOptions, UpdateResult, FindOneAndUpdateOptions, DeleteResult, ChangeStreamOptions, ChangeStream } from 'mongodb';
3
- import { L as LoggerLike } from './timeout-B10CTiGm.js';
4
- export { C as CacheOptions, a as LRU, b as LRUOptions, c as LogFn, d as LogLevel, e as createCachedAsyncFactory, f as createCachedFactory, g as createConsoleLogger, h as createNoopLogger, i as hashString, s as sleep, j as sleepJittered, k as stableHash, l as stableStringify, w as withTimeout } from './timeout-B10CTiGm.js';
2
+ import { Db, MongoClient, ClientSession, Document, Filter, Hint, CollationOptions, ReadPreferenceLike, ReadConcernLike, WriteConcern, WithId, Condition, RootFilterOperators, Collection, FindOptions, Sort, FindCursor, ObjectId, Long, Decimal128, IndexDirection, CreateIndexesOptions, AggregateOptions, AggregationCursor, CreateCollectionOptions, TransactionOptions as TransactionOptions$1, InsertOneOptions, InsertOneResult, InsertManyResult, UpdateOptions, UpdateResult, FindOneAndUpdateOptions, DeleteResult, ChangeStreamOptions, ChangeStream } from 'mongodb';
3
+ import { L as LoggerLike } from './timeout-BaP92Iyg.js';
4
+ export { C as CacheOptions, a as LRU, b as LRUOptions, c as LogFn, d as LogLevel, e as createCachedAsyncFactory, f as createCachedFactory, g as createConsoleLogger, h as createNoopLogger, i as hashString, s as sleep, j as sleepJittered, k as stableHash, l as stableStringify, w as withTimeout } from './timeout-BaP92Iyg.js';
5
+ import * as bson from 'bson';
5
6
 
6
7
  /**
7
8
  * Types + constants for the HotCache layer. All type-only (plus the stream-key
@@ -296,12 +297,11 @@ declare class InFlight {
296
297
  interface QueryCacheOptions {
297
298
  /** Max cached entries (default 500). */
298
299
  maxSize?: number;
299
- /** Per-entry TTL in ms (default 0 = no expiry). */
300
+ /** Per-entry TTL in ms (default 30_000; set 0 explicitly for no expiry). */
300
301
  ttlMs?: number;
301
302
  /**
302
303
  * Clone results on every read so callers can't mutate the shared cache entry
303
- * (default false — cloning has a per-read cost; treat cached results as
304
- * read-only when disabled).
304
+ * (default true; set false only for read-only results where zero-copy matters).
305
305
  */
306
306
  clone?: boolean;
307
307
  }
@@ -325,15 +325,15 @@ interface QueryCacheStats {
325
325
  evictions: number;
326
326
  }
327
327
  /**
328
- * Compose the "collection" part of a cache key, namespaced by the DATABASE name.
329
- * One service shares a single QueryCache + InFlight across every DB client; without
330
- * the namespace, same-named physical collections in different databases would
331
- * collide — a read on DB A could be served DB B's cached rows, and identical
328
+ * Compose the collection part of a cache key, namespaced by deployment and DB.
329
+ * One service shares a QueryCache + InFlight across every client; without these
330
+ * namespaces, same-named physical collections in different databases/clusters
331
+ * would collide — a read on DB A could be served DB B's cached rows, and identical
332
332
  * concurrent reads across DBs could coalesce into one driver call. Reads,
333
333
  * write-through invalidations, and change-stream invalidations MUST all use the
334
334
  * same namespace so they agree.
335
335
  */
336
- declare const cacheCollectionKey: (dbName: string, physical: string) => string;
336
+ declare const cacheCollectionKey: (dbName: string, physical: string, clusterNamespace?: string) => string;
337
337
  /**
338
338
  * Read-through query cache with per-collection invalidation.
339
339
  *
@@ -344,8 +344,8 @@ declare const cacheCollectionKey: (dbName: string, physical: string) => string;
344
344
  * collections changes. Invalidation is WRITE-THROUGH only: the ORM drops a
345
345
  * collection's entries on every write it performs. Reads are NOT invalidated by
346
346
  * external writers (other processes, the raw `client` escape hatch, or direct
347
- * DB writes) — with `ttlMs: 0` (default) those reads stay stale indefinitely,
348
- * so multi-writer deployments should set `ttlMs` or use the change-stream aware
347
+ * DB writes). The default 30-second TTL bounds staleness; `ttlMs: 0` explicitly
348
+ * disables expiry, so multi-writer deployments can also use the change-stream aware
349
349
  * `createHotCache()`. Perf wins: cache hits perform zero driver round-trips.
350
350
  */
351
351
  declare class QueryCache {
@@ -556,7 +556,9 @@ declare const isTransactionUnsupportedError: (error: unknown) => boolean;
556
556
 
557
557
  /** Minimal transaction runner surface (satisfied by the service `transaction`). */
558
558
  interface MongoTransactionRunner {
559
- transaction: <T>(fn: (session: ClientSession | null) => Promise<T>) => Promise<T>;
559
+ transaction: <T>(fn: (session: ClientSession | null) => Promise<T>, options?: {
560
+ allowNonTransactionalFallback?: boolean;
561
+ }) => Promise<T>;
560
562
  }
561
563
  interface GracefulTransactionOptions {
562
564
  capabilities?: ReturnType<typeof createMongoCapabilitiesStore>;
@@ -564,17 +566,18 @@ interface GracefulTransactionOptions {
564
566
  logger?: LoggerLike;
565
567
  /** Map driver errors to typed DomainError/InfraError before rethrowing (default true). */
566
568
  wrapMongoErrors?: boolean;
569
+ /** Explicitly permit non-atomic execution on deployments without transactions. */
570
+ allowNonTransactionalFallback?: boolean;
567
571
  }
568
572
  /**
569
- * Run `fn` inside a transaction when the deployment supports it; otherwise run
570
- * with a `null` session (no-op fallback). Also handles "transactions
571
- * unsupported" errors by re-running with a null session.
573
+ * Run `fn` inside a transaction. Unsupported deployments throw unless
574
+ * `allowNonTransactionalFallback: true` explicitly permits a `null` session.
572
575
  *
573
576
  * When capability state is UNKNOWN (probe failed/timed out and no URL hint or
574
577
  * env override says otherwise), we ATTEMPT the real transaction rather than
575
578
  * silently downgrading — a transient startup blip must not turn an atomic
576
579
  * write into a non-atomic one. The catch path still falls back cleanly on a
577
- * genuinely unsupported deployment (at the cost of one failed round trip).
580
+ * genuinely unsupported deployment only after explicit opt-in.
578
581
  */
579
582
  declare const withGracefulMongoTransaction: <T>(runner: MongoTransactionRunner, fn: (session: ClientSession | null) => Promise<T>, options?: GracefulTransactionOptions) => Promise<T>;
580
583
 
@@ -691,9 +694,8 @@ interface MongoMigrationRunnerOptions {
691
694
  * - `./journal.ts` — lease-based `_migrations` journal (atomic, crash-safe)
692
695
  *
693
696
  * `up()` applies pending migrations in numeric order under an exclusive claim
694
- * with an auto-renewed lease (long migrations can't be stolen by another
695
- * runner, but a crashed runner's claim expires); `down()` rolls back applied
696
- * migrations in reverse order and validates its target BEFORE destroying
697
+ * with an auto-renewed, owner-fenced lease; `down()` uses the same fencing,
698
+ * rolls back in reverse order, and validates its target BEFORE destroying
697
699
  * anything; `status()` reports applied/pending; `create()` scaffolds a new file
698
700
  * atomically (`wx` — concurrent scaffolds never clobber each other).
699
701
  */
@@ -857,7 +859,7 @@ interface DoubleField extends FieldMeta {
857
859
  exclusiveMinimum?: boolean;
858
860
  exclusiveMaximum?: boolean;
859
861
  }
860
- /** Strict BSON `long` (int64) field — inferred as `number` (precision caveat). */
862
+ /** BSON `long` (int64) field — inferred as the driver's lossless `Long` type. */
861
863
  interface LongField extends FieldMeta {
862
864
  kind: 'long';
863
865
  minimum?: number;
@@ -1075,14 +1077,14 @@ interface QueryOptions {
1075
1077
  * Per-op schema-drift policy override for reads (see `MongoServiceConfig.drift`).
1076
1078
  * `true` → `'throw'`, `false` → `'off'`, or an explicit `DriftMode` string.
1077
1079
  * Unset inherits the service-level default (`'report'`). Only checked when a
1078
- * document is fetched from the DB (cache-miss); projected/partial reads are
1079
- * skipped.
1080
+ * document is fetched from the DB (cache-miss); projections ignore absent
1081
+ * required fields but still validate returned values.
1080
1082
  */
1081
1083
  drift?: DriftMode | boolean;
1082
1084
  /** Driver-level options forwarded untouched to the underlying call. */
1083
1085
  collation?: CollationOptions;
1084
1086
  readPreference?: ReadPreferenceLike;
1085
- readConcern?: ReadConcern;
1087
+ readConcern?: ReadConcernLike;
1086
1088
  writeConcern?: WriteConcern;
1087
1089
  comment?: string | Document;
1088
1090
  let?: Document;
@@ -1252,7 +1254,7 @@ type InferField<T extends SchemaType> = T extends {
1252
1254
  kind: 'double';
1253
1255
  } ? number : T extends {
1254
1256
  kind: 'long';
1255
- } ? number : T extends {
1257
+ } ? Long : T extends {
1256
1258
  kind: 'decimal';
1257
1259
  } ? Decimal128 : T extends {
1258
1260
  kind: 'geoPoint';
@@ -1284,13 +1286,8 @@ type InferDoc<T extends ObjectField> = InferObject<T>;
1284
1286
 
1285
1287
  /** A Mongo index definition usable by `createIndexes`. */
1286
1288
  interface IndexSpec {
1287
- key: Record<string, 1 | -1 | 'text' | 'hashed' | '2dsphere'>;
1288
- options?: {
1289
- name?: string;
1290
- unique?: boolean;
1291
- sparse?: boolean;
1292
- expireAfterSeconds?: number;
1293
- };
1289
+ key: Record<string, IndexDirection>;
1290
+ options?: CreateIndexesOptions;
1294
1291
  }
1295
1292
  /** Auto-timestamp field names maintained by the ORM when `timestamps` is set. */
1296
1293
  interface CollectionTimestamps {
@@ -1333,6 +1330,8 @@ interface DBClientDefinition<TCollections extends Record<string, CollectionLike>
1333
1330
  /** Per-logical-collection physical-name overrides. */
1334
1331
  collectionPhysicalNames?: Partial<Record<string, string>>;
1335
1332
  connectTimeoutMs?: number;
1333
+ /** Enable driver command events before pools open (required for wire tracing). */
1334
+ monitorCommands?: boolean;
1336
1335
  readPreference?: ReadPreferenceLike;
1337
1336
  readConcern?: ReadConcernLike;
1338
1337
  writeConcern?: WriteConcern;
@@ -1482,13 +1481,16 @@ declare const manyToMany: <const C extends string, const A extends string, const
1482
1481
 
1483
1482
  interface PopulateOptions {
1484
1483
  maxBatchSize?: number;
1484
+ /** Cache keys only within this populate call (default true). */
1485
1485
  cache?: boolean;
1486
- /**
1487
- * Cap on docs fetched per foreign-key batch (default 10_000). A `hasMany` /
1488
- * `manyToMany` relation with more children than this is silently truncated —
1489
- * raise the cap when you expect larger joins.
1490
- */
1486
+ /** Opt into the shared read-through query cache (default false for fresh joins). */
1487
+ queryCache?: boolean;
1488
+ /** Safety cap per foreign-key batch. Exceeding it throws instead of truncating. */
1491
1489
  maxDocs?: number;
1490
+ session?: ClientSession;
1491
+ maxTimeMS?: number;
1492
+ readPreference?: ReadPreferenceLike;
1493
+ readConcern?: ReadConcernLike;
1492
1494
  }
1493
1495
 
1494
1496
  /** Structured metadata attached to every logged DB operation. */
@@ -1505,12 +1507,14 @@ interface DbOpMeta {
1505
1507
  */
1506
1508
  params?: unknown;
1507
1509
  }
1508
-
1509
1510
  /**
1510
- * Aggregation types + the shared context handed to the aggregation op-group
1511
- * factories (`./aggregate.ts`, `./group.ts`, `./text-search.ts`,
1512
- * `./lookup-join.ts`). Type-only plus the `AggregationCtx` interface.
1511
+ * The ignex-debugbar `debugQuery` free helper (`@ignex/core/debug`), resolved
1512
+ * lazily so the ORM stays standalone: `undefined` until probed, `null` when
1513
+ * `@ignex/core` is not installed (plain ORM usage), the function otherwise.
1514
+ * `debugQuery` itself is a zero-cost pass-through when no request trace is
1515
+ * active, so production ignex apps pay nothing either.
1513
1516
  */
1517
+ type DebugQuery = <T>(sql: string, params: unknown, fn: () => T | Promise<T>) => T | Promise<T>;
1514
1518
 
1515
1519
  interface GroupByConfig {
1516
1520
  /** Group key: a field name or a document of `$`-expressions. */
@@ -1554,7 +1558,9 @@ interface PipelineCustomization {
1554
1558
  }
1555
1559
  interface AggregationOpsOptions {
1556
1560
  resolveCollectionName: (logical: string) => string;
1561
+ cacheNamespace?: string;
1557
1562
  wrapMongoErrors?: boolean;
1563
+ debugQuery?: DebugQuery | null;
1558
1564
  /** Shared read cache (`undefined` = caching disabled). */
1559
1565
  cache?: QueryCache;
1560
1566
  /** Service default for in-flight read dedup. */
@@ -2010,17 +2016,6 @@ type UpdateOperators<T> = {
2010
2016
  */
2011
2017
  type UpdateInput<T> = Partial<T> | UpdateOperators<T>;
2012
2018
 
2013
- /**
2014
- * Shared CRUD context: the cross-cutting helpers every CRUD op group depends
2015
- * on (collection resolution, tracing, retry plumbing, cache/dedup/drift read
2016
- * pipeline, auto-timestamps, `select` normalization).
2017
- *
2018
- * `makeCrudOps` (see `./index.ts`) builds ONE context via `createCrudContext`
2019
- * and hands it to the read / write / watch op-group factories, so the helpers
2020
- * live in exactly one place instead of being duplicated per op. This module is
2021
- * the dependency-injection seam of the CRUD layer.
2022
- */
2023
-
2024
2019
  type ColNames<TClients extends DbClientsDefinition, TDb extends ExtractDbNames<TClients>> = ExtractCollectionNames<TClients, TDb>;
2025
2020
  /** Input accepted by insert ops: the doc without `_id`, or with an explicit `_id`. */
2026
2021
  type InsertInput<T> = Omit<T, '_id'> & {
@@ -2048,13 +2043,17 @@ type FindQueryOptions<T> = FindOptions & QueryOptions & {
2048
2043
  type TimestampsByCollection = Record<string, CollectionTimestamps | undefined>;
2049
2044
  interface CrudOpsOptions {
2050
2045
  resolveCollectionName: (logical: string) => string;
2046
+ /** Stable, non-secret identity of the MongoDB deployment for shared caches. */
2047
+ cacheNamespace?: string;
2051
2048
  wrapMongoErrors?: boolean;
2049
+ debugQuery?: DebugQuery | null;
2052
2050
  cache?: QueryCache;
2053
2051
  dedupeReads?: boolean;
2054
2052
  inFlight?: InFlight;
2055
2053
  hooks?: HooksRegistry;
2056
2054
  /** Auto-timestamp field names per collection (from the collection definition). */
2057
2055
  timestamps?: TimestampsByCollection;
2056
+ validateWrites?: boolean;
2058
2057
  /** Service-level schema-drift policy for reads (default `'report'`). */
2059
2058
  drift?: DriftMode;
2060
2059
  /** Resolve the declared schema for a logical collection (drift detection). */
@@ -2068,7 +2067,7 @@ interface CrudOpsOptions {
2068
2067
  * and fire lifecycle hooks.
2069
2068
  */
2070
2069
  declare const makeCrudOps: <TClients extends DbClientsDefinition, TDb extends ExtractDbNames<TClients>>(client: Db, dbLabel: string, logger: LoggerLike, opts: CrudOpsOptions) => {
2071
- watchCollection: <X extends ColNames<TClients, TDb>>(collection: X, pipeline?: mongodb.Document[], options?: mongodb.ChangeStreamOptions) => mongodb.ChangeStream<CollectionDoc<TClients[TDb]["collections"][X]>, mongodb.ChangeStreamDocument<CollectionDoc<TClients[TDb]["collections"][X]>>>;
2070
+ watchCollection: <X extends ColNames<TClients, TDb>>(collection: X, pipeline?: bson.Document[], options?: mongodb.ChangeStreamOptions) => mongodb.ChangeStream<CollectionDoc<TClients[TDb]["collections"][X]>, mongodb.ChangeStreamDocument<CollectionDoc<TClients[TDb]["collections"][X]>>>;
2072
2071
  query: <X extends ColNames<TClients, TDb>>(collection: X) => QueryBuilder<CollectionDoc<TClients[TDb]["collections"][X]>, CollectionDoc<TClients[TDb]["collections"][X]>>;
2073
2072
  insertOne: <X extends ColNames<TClients, TDb>>(collection: X, doc: InsertInput<CollectionDoc<TClients[TDb]["collections"][X]>>, options?: mongodb.InsertOneOptions & QueryOptions) => Promise<mongodb.InsertOneResult<CollectionDoc<TClients[TDb]["collections"][X]>>>;
2074
2073
  insertMany: <X extends ColNames<TClients, TDb>>(collection: X, docs: readonly InsertInput<CollectionDoc<TClients[TDb]["collections"][X]>>[], options?: mongodb.BulkWriteOptions & QueryOptions) => Promise<mongodb.InsertManyResult<CollectionDoc<TClients[TDb]["collections"][X]>>>;
@@ -2084,8 +2083,8 @@ declare const makeCrudOps: <TClients extends DbClientsDefinition, TDb extends Ex
2084
2083
  filter: FilterInput<CollectionDoc<TClients[TDb]["collections"][X]>>;
2085
2084
  update: UpdateInput<CollectionDoc<TClients[TDb]["collections"][X]>>;
2086
2085
  upsert?: boolean;
2087
- }[], options?: mongodb.BulkWriteOptions & QueryOptions) => Promise<mongodb.Document>;
2088
- bulkWrite: <X extends ColNames<TClients, TDb>>(collection: X, operations: mongodb.AnyBulkWriteOperation<CollectionDoc<TClients[TDb]["collections"][X]>>[], options?: mongodb.BulkWriteOptions & QueryOptions) => Promise<mongodb.Document>;
2086
+ }[], options?: mongodb.BulkWriteOptions & QueryOptions) => Promise<bson.Document>;
2087
+ bulkWrite: <X extends ColNames<TClients, TDb>>(collection: X, operations: mongodb.AnyBulkWriteOperation<CollectionDoc<TClients[TDb]["collections"][X]>>[], options?: mongodb.BulkWriteOptions & QueryOptions) => Promise<bson.Document>;
2089
2088
  updateWithVersion: <X extends ColNames<TClients, TDb>>(collection: X, filter: FilterInput<CollectionDoc<TClients[TDb]["collections"][X]>>, update: UpdateInput<CollectionDoc<TClients[TDb]["collections"][X]>>, options?: mongodb.FindOneAndUpdateOptions & QueryOptions) => Promise<VersionedUpdateResult<CollectionDoc<TClients[TDb]["collections"][X]>>>;
2090
2089
  findOneAndDelete: <X extends ColNames<TClients, TDb>>(collection: X, filter: FilterInput<CollectionDoc<TClients[TDb]["collections"][X]>>, options?: mongodb.FindOneAndDeleteOptions & QueryOptions) => Promise<CollectionDoc<TClients[TDb]["collections"][X]> | null>;
2091
2090
  replaceOne: <X extends ColNames<TClients, TDb>>(collection: X, filter: FilterInput<CollectionDoc<TClients[TDb]["collections"][X]>>, replacement: InsertInput<CollectionDoc<TClients[TDb]["collections"][X]>>, options?: mongodb.ReplaceOptions & QueryOptions) => Promise<mongodb.UpdateResult<CollectionDoc<TClients[TDb]["collections"][X]>>>;
@@ -2113,6 +2112,8 @@ interface MongoServiceConfig {
2113
2112
  migrationDir?: string;
2114
2113
  appName?: string;
2115
2114
  logger?: LoggerLike;
2115
+ /** Explicit host tracer (Ignex debugQuery); null disables the optional probe. */
2116
+ debugQuery?: DebugQuery | null;
2116
2117
  /**
2117
2118
  * Map driver errors to typed DomainError/InfraError before rethrowing. ON by
2118
2119
  * default — set `false` to surface raw driver errors instead.
@@ -2126,9 +2127,9 @@ interface MongoServiceConfig {
2126
2127
  * INVALIDATION: entries are dropped write-through — every ORM write
2127
2128
  * invalidates that collection's cached reads. External writers (other
2128
2129
  * processes, the raw `client` escape hatch, direct DB writes) do NOT
2129
- * invalidate; with the default `ttlMs: 0` those reads stay stale
2130
- * indefinitely, so multi-writer deployments should set `QueryCacheOptions.ttlMs`,
2131
- * disable the cache, route latency-critical reads through the
2130
+ * invalidate. The default 30-second TTL bounds staleness; `ttlMs: 0`
2131
+ * explicitly selects unbounded entries. Multi-writer deployments can disable
2132
+ * the cache, route latency-critical reads through the
2132
2133
  * change-stream aware `createHotCache()`, or set `cacheWatch: true`.
2133
2134
  */
2134
2135
  cache?: QueryCache | QueryCacheOptions | null;
@@ -2143,6 +2144,8 @@ interface MongoServiceConfig {
2143
2144
  * `closeConnections()`. Default: false.
2144
2145
  */
2145
2146
  cacheWatch?: boolean;
2147
+ /** Permit transaction callbacks to run non-atomically on unsupported servers. Default: false. */
2148
+ allowNonTransactionalFallback?: boolean;
2146
2149
  /** Coalesce identical concurrent reads into one driver call. ON by default. */
2147
2150
  dedupeReads?: boolean;
2148
2151
  /**
@@ -2150,6 +2153,8 @@ interface MongoServiceConfig {
2150
2153
  * in-flight dedup even when the granular options are set. Defaults to true.
2151
2154
  */
2152
2155
  perf?: boolean;
2156
+ /** Validate inserts and replacements against the schema before sending them. Default: true. */
2157
+ validateWrites?: boolean;
2153
2158
  /**
2154
2159
  * Schema-drift policy for reads. When a document fetched from the DB
2155
2160
  * (cache-miss) doesn't match its declared schema:
@@ -2157,8 +2162,8 @@ interface MongoServiceConfig {
2157
2162
  * - `'throw'` — throw `DomainError SCHEMA_DRIFT` (the document is never
2158
2163
  * cached or returned)
2159
2164
  * - `'off'` — no drift checking (previous behavior)
2160
- * Detection-only: documents are never mutated. Projected/partial reads are
2161
- * skipped. Overridable per op via `QueryOptions.drift`.
2165
+ * Detection-only: documents are never mutated. Projected reads ignore absent
2166
+ * fields but validate returned values. Overridable via `QueryOptions.drift`.
2162
2167
  */
2163
2168
  drift?: DriftMode;
2164
2169
  }
@@ -2251,6 +2256,8 @@ interface CacheInvalidationRef {
2251
2256
  db: Db;
2252
2257
  /** PHYSICAL collection name — cache keys use it, so invalidation must too. */
2253
2258
  collection: string;
2259
+ /** Stable deployment identity shared with the manager's cache keys. */
2260
+ namespace?: string;
2254
2261
  }
2255
2262
  declare class CacheInvalidator {
2256
2263
  private cache;
@@ -2276,25 +2283,19 @@ declare class CacheInvalidator {
2276
2283
  private watchLoop;
2277
2284
  }
2278
2285
 
2279
- /**
2280
- * Pagination types + the shared context handed to the two pagination
2281
- * strategies (`./offset.ts`, `./cursor.ts`). Type-only plus the `PaginationCtx`
2282
- * interface, so the strategy modules and the composing `makePaginationOps`
2283
- * (in `./index.ts`) share one vocabulary without importing each other's logic.
2284
- */
2285
-
2286
2286
  interface PaginationConfig {
2287
2287
  page?: number;
2288
2288
  limit?: number;
2289
2289
  sort?: Record<string, 1 | -1>;
2290
2290
  /** Cap on the requested limit (default DEFAULT_MAX_LIMIT=1000). */
2291
2291
  maxLimit?: number;
2292
+ /** Maximum offset before callers must switch to keyset pagination (default 10_000). */
2293
+ maxOffset?: number;
2292
2294
  /**
2293
2295
  * Projection applied to the data facet (e.g. `{ _id: 1, updatedAt: 1 }`).
2294
2296
  *
2295
- * Enables lean list reads — only the projected fields cross the wire. When
2296
- * set, the schema-drift check is skipped for the page (projected docs
2297
- * intentionally lack the collection's full field set).
2297
+ * Enables lean list reads — only the projected fields cross the wire. Drift
2298
+ * checks ignore absent fields but still validate the returned values.
2298
2299
  */
2299
2300
  projection?: Document;
2300
2301
  /** Stages prepended to the data facet (e.g. extra $match). */
@@ -2311,6 +2312,8 @@ interface CursorPaginationConfig {
2311
2312
  * exist on every document for deterministic ordering.
2312
2313
  */
2313
2314
  sort: Record<string, 1 | -1>;
2315
+ /** Unique final sort field. Defaults to `_id`; custom fields must have a unique index. */
2316
+ uniqueTiebreaker?: string;
2314
2317
  /** Opaque cursor from a previous `nextCursor` — fetch the page after it. */
2315
2318
  after?: string;
2316
2319
  /** Opaque cursor — fetch the page before it (backward navigation). */
@@ -2328,7 +2331,9 @@ interface CursorPage<T> {
2328
2331
  }
2329
2332
  interface PaginationOpsOptions {
2330
2333
  resolveCollectionName: (logical: string) => string;
2334
+ cacheNamespace?: string;
2331
2335
  wrapMongoErrors?: boolean;
2336
+ debugQuery?: DebugQuery | null;
2332
2337
  /** Service-level schema-drift policy for reads (default `'report'`). */
2333
2338
  drift?: DriftMode;
2334
2339
  /** Resolve the declared schema for a logical collection (drift detection). */
@@ -2477,29 +2482,23 @@ declare const makeSchemaOps: (client: Db, _logger: LoggerLike, opts: SchemaOpsOp
2477
2482
  syncIndexes: (collection: string) => Promise<SyncIndexesResult>;
2478
2483
  };
2479
2484
 
2485
+ interface TransactionOptions extends TransactionOptions$1 {
2486
+ /** Explicitly permit non-atomic execution when transactions are unsupported. */
2487
+ allowNonTransactionalFallback?: boolean;
2488
+ }
2480
2489
  interface TransactionOpsOptions {
2481
2490
  migrationCollectionPhysical: string;
2482
- /** Map driver errors to typed DomainError/InfraError before rethrowing. */
2483
2491
  wrapMongoErrors?: boolean;
2492
+ allowNonTransactionalFallback?: boolean;
2484
2493
  }
2485
- /**
2486
- * Transaction + idempotent-migration ops for one database handle.
2487
- */
2494
+ /** Transaction + fenced idempotent-migration ops for one database handle. */
2488
2495
  declare const makeTransactionOps: (client: MongoClient, handle: Db, logger: LoggerLike, _config: Record<string, unknown>, opts: TransactionOpsOptions) => {
2489
2496
  transaction: <T>(fn: (session: ClientSession | null) => Promise<T>, options?: TransactionOptions) => Promise<T>;
2490
- migrate: (name: string, fn: (session: ClientSession | null) => Promise<void>, filePath?: string) => Promise<void>;
2497
+ migrate: (name: string, fn: (session: ClientSession | null) => Promise<void>, filePath?: string, options?: {
2498
+ allowNonTransactionalFallback?: boolean;
2499
+ }) => Promise<void>;
2491
2500
  };
2492
2501
 
2493
- /**
2494
- * Per-database manager assembly. `buildManager` is the composition point of the
2495
- * op-factory pattern: it builds the collection registry (schema/hooks/
2496
- * timestamps), resolves logical→physical names, and **spreads** every
2497
- * `make*Ops` factory into one `CollectionManager` object per database.
2498
- *
2499
- * The `CollectionManager` type mirrors that spread as an intersection so both
2500
- * the runtime value and its type stay in sync from a single source.
2501
- */
2502
-
2503
2502
  /** One collection manager per connected DB — the ORM's primary surface. */
2504
2503
  type CollectionManager<TClients extends DbClientsDefinition, TDb extends ExtractDbNames<TClients>> = CrudOps<TClients, TDb> & ReturnType<typeof makePaginationOps<TClients, TDb>> & ReturnType<typeof makeAggregationOps<TClients, TDb>> & ReturnType<typeof makeSchemaOps> & ReturnType<typeof makeTransactionOps> & {
2505
2504
  /**
@@ -2512,6 +2511,8 @@ type CollectionManager<TClients extends DbClientsDefinition, TDb extends Extract
2512
2511
  }, options?: PopulateOptions) => Promise<Array<T & JoinedFields<TClients, TDb, R>>>;
2513
2512
  /** Raw `db()` handle escape hatch. */
2514
2513
  client: Db;
2514
+ /** Raw pooled client for host integrations (e.g. command monitoring). */
2515
+ mongoClient: MongoClient;
2515
2516
  /** Reference to sibling managers (cross-DB). */
2516
2517
  db: Record<string, unknown>;
2517
2518
  };
@@ -2798,4 +2799,4 @@ declare const createMongoToolkit: <TClients extends DbClientsDefinition = DbClie
2798
2799
  };
2799
2800
  type MongoToolkit<TClients extends DbClientsDefinition> = ReturnType<typeof createMongoToolkit<TClients>>;
2800
2801
 
2801
- export { type AccumulatorResult, type AccumulatorSpec, type Added, type AggregationMeta, type AggregationStages, type AnyField, AppError, type ArrayField, BadRequest, type BelongsToRelation, type BooleanField, type CacheInvalidationRef, CacheInvalidator, type Chainable, type CollectionDefinition, type CollectionDoc, type CollectionLike, type CollectionManager, type CollectionMap, type CollectionName, type CollectionTimestamps, type CollectionValue, type CrudListQuery, type CrudOps, type CursorPage, type CursorPaginationConfig, type DBClientDefinition, DEFAULT_FIND_LIMIT, DEFAULT_MAX_LIMIT, DataLoader, type DataLoaderOptions, type DateField, type DateRangeConfig, type DbClientsDefinition, type DbHealthResult, type DecimalField, DomainError, type DoubleField, type DriftIssue, type DriftIssueCode, type DriftMode, ERROR_HTTP_STATUS, type EnumField, type ErrorContext, type ExprResult, type ExtractCollectionNames, type ExtractCollectionType, type ExtractDbNames, type FacetOutput, type FacetPipelineStage, type FacetSpec, type FieldFlags, type FieldMeta, type FieldName, type FieldRef, type FilterInput, type FindQueryOptions, type ForeignDocOf, type GeoNearOutput, type GeoNearSpec, type GeoPoint, type GeoPointField, type GracefulTransactionOptions, type GroupByConfig, type GroupSpec, type Grouped, HOOK_NAMES, type HasManyRelation, type HealthReport, type Hook, type HookContext, type HookMap, type HookName, type HooksRegistry, HotCache, type HotCacheMode, type HotCacheOptions, type HotCacheStats, type HotCollectionRef, type HotQueryAccessor, type HotQueryConfig, type HotQueryStats, InFlight, type IndexSpec, type InferDoc, type InferField, InfraError, type InsertInput, type IntegerField, type JoinedFields, type KeysetCursor, LoggerLike, type LongField, type LookupConfig, type LookupJoinedFor, type LookupParams, type LookupSpecFor, MAX_BATCH_OPS, type ManyToManyRelation, type MigrationContext, type MigrationModule, type MongoCapabilities, type MongoCapabilitiesStore, type MongoJsonSchema, type MongoMigrationRunner, type MongoMigrationRunnerOptions, type MongoService, type MongoServiceConfig, type MongoToolkit, type MongoToolkitOptions, type MongoTransactionRunner, type NamedCollection, type NamedCollectionDefinition, type NamedObjectField, type NormalizedPagination, type NullField, type NumberBounds, type NumberField, type ObjectField, type ObjectIdField, type PaginationConfig, type PaginationResult, PipelineBuilder, type PipelineCustomization, type PipelineStage, type PopulateOptions, type Projected, type Projection, QueryBuilder, type QueryBuilderContext, QueryCache, type QueryCacheOptions, type QueryCacheStats, type QueryOptions, type RawField, type RelationDef, type RelationDefBase, type RemoveIndexSignature, type Repository, type RepositoryOptions, type ResolvedQueryOptions, type RetryOptions, type SchemaType, type SearchConfig, type SortKeys, type StringField, type SyncIndexesResult, TRANSIENT_MONGO_ERROR_CODES, type TimestampsByCollection, type Unsetted, type UnwindSpec, type Unwound, type UpdateInput, type UpdateOperators, type ValidRelation, type VersionedUpdateResult, belongsTo, buildKeysetFilter, buildMongoActiveFilter, buildPaginationResult, cacheCollectionKey, canonicalKey, createHotCache, createMongoCapabilitiesStore, createMongoMigrationRunner, createMongoService, createMongoToolkit, createRepository, createResolveCollectionName, decodeCursor, defineCollection, defineCollections, encodeCursor, hasMany, httpStatusForError, isAppError, isDomainError, isInfraError, isMappedMongoError, isMongoDuplicateKeyError, isMongoTransientError, isTransactionUnsupportedError, manyToMany, mapMongoDriverError, mergeMongoActiveFilter, mergeMongoFilters, normalizeMongoUrl, normalizePageLimit, optional, probeMongoCapabilities, runHooks, s, serializeError, stripDocumentId, stripPrimaryKey, toMongoSchema, toMongoValidator, validateDoc, withDefault, withGracefulMongoTransaction, withRetry, withTransaction };
2802
+ export { type AccumulatorResult, type AccumulatorSpec, type Added, type AggregationMeta, type AggregationStages, type AnyField, AppError, type ArrayField, BadRequest, type BelongsToRelation, type BooleanField, type CacheInvalidationRef, CacheInvalidator, type Chainable, type CollectionDefinition, type CollectionDoc, type CollectionLike, type CollectionManager, type CollectionMap, type CollectionName, type CollectionTimestamps, type CollectionValue, type CrudListQuery, type CrudOps, type CursorPage, type CursorPaginationConfig, type DBClientDefinition, DEFAULT_FIND_LIMIT, DEFAULT_MAX_LIMIT, DataLoader, type DataLoaderOptions, type DateField, type DateRangeConfig, type DbClientsDefinition, type DbHealthResult, type DebugQuery, type DecimalField, DomainError, type DoubleField, type DriftIssue, type DriftIssueCode, type DriftMode, ERROR_HTTP_STATUS, type EnumField, type ErrorContext, type ExprResult, type ExtractCollectionNames, type ExtractCollectionType, type ExtractDbNames, type FacetOutput, type FacetPipelineStage, type FacetSpec, type FieldFlags, type FieldMeta, type FieldName, type FieldRef, type FilterInput, type FindQueryOptions, type ForeignDocOf, type GeoNearOutput, type GeoNearSpec, type GeoPoint, type GeoPointField, type GracefulTransactionOptions, type GroupByConfig, type GroupSpec, type Grouped, HOOK_NAMES, type HasManyRelation, type HealthReport, type Hook, type HookContext, type HookMap, type HookName, type HooksRegistry, HotCache, type HotCacheMode, type HotCacheOptions, type HotCacheStats, type HotCollectionRef, type HotQueryAccessor, type HotQueryConfig, type HotQueryStats, InFlight, type IndexSpec, type InferDoc, type InferField, InfraError, type InsertInput, type IntegerField, type JoinedFields, type KeysetCursor, LoggerLike, type LongField, type LookupConfig, type LookupJoinedFor, type LookupParams, type LookupSpecFor, MAX_BATCH_OPS, type ManyToManyRelation, type MigrationContext, type MigrationModule, type MongoCapabilities, type MongoCapabilitiesStore, type MongoJsonSchema, type MongoMigrationRunner, type MongoMigrationRunnerOptions, type MongoService, type MongoServiceConfig, type MongoToolkit, type MongoToolkitOptions, type MongoTransactionRunner, type NamedCollection, type NamedCollectionDefinition, type NamedObjectField, type NormalizedPagination, type NullField, type NumberBounds, type NumberField, type ObjectField, type ObjectIdField, type PaginationConfig, type PaginationResult, PipelineBuilder, type PipelineCustomization, type PipelineStage, type PopulateOptions, type Projected, type Projection, QueryBuilder, type QueryBuilderContext, QueryCache, type QueryCacheOptions, type QueryCacheStats, type QueryOptions, type RawField, type RelationDef, type RelationDefBase, type RemoveIndexSignature, type Repository, type RepositoryOptions, type ResolvedQueryOptions, type RetryOptions, type SchemaType, type SearchConfig, type SortKeys, type StringField, type SyncIndexesResult, TRANSIENT_MONGO_ERROR_CODES, type TimestampsByCollection, type TransactionOptions, type Unsetted, type UnwindSpec, type Unwound, type UpdateInput, type UpdateOperators, type ValidRelation, type VersionedUpdateResult, belongsTo, buildKeysetFilter, buildMongoActiveFilter, buildPaginationResult, cacheCollectionKey, canonicalKey, createHotCache, createMongoCapabilitiesStore, createMongoMigrationRunner, createMongoService, createMongoToolkit, createRepository, createResolveCollectionName, decodeCursor, defineCollection, defineCollections, encodeCursor, hasMany, httpStatusForError, isAppError, isDomainError, isInfraError, isMappedMongoError, isMongoDuplicateKeyError, isMongoTransientError, isTransactionUnsupportedError, manyToMany, mapMongoDriverError, mergeMongoActiveFilter, mergeMongoFilters, normalizeMongoUrl, normalizePageLimit, optional, probeMongoCapabilities, runHooks, s, serializeError, stripDocumentId, stripPrimaryKey, toMongoSchema, toMongoValidator, validateDoc, withDefault, withGracefulMongoTransaction, withRetry, withTransaction };