@classytic/mongokit 3.7.0 → 3.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/README.md CHANGED
@@ -3,13 +3,22 @@
3
3
  [![npm version](https://badge.fury.io/js/@classytic%2Fmongokit.svg)](https://www.npmjs.com/package/@classytic/mongokit)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
- Production-grade MongoDB repository pattern for Node.js. Zero runtime deps, Mongoose as a peer.
6
+ Production-grade MongoDB repository pattern for Node.js. Zero runtime deps — Mongoose and `@classytic/repo-core` are peers.
7
7
 
8
8
  ```bash
9
- npm install @classytic/mongokit mongoose
9
+ npm install @classytic/mongokit @classytic/repo-core mongoose
10
10
  ```
11
11
 
12
- Requires Mongoose `>=9.4.1`, Node.js `>=22`.
12
+ Requires Mongoose `>=9.4.1`, `@classytic/repo-core` `>=0.1.0`, Node.js `>=22`.
13
+
14
+ > **Swap-able with sqlitekit.** Mongokit implements the `StandardRepo<TDoc>` contract from `@classytic/repo-core/repository`. Controller code written against the contract runs unchanged on [@classytic/sqlitekit](https://www.npmjs.com/package/@classytic/sqlitekit) — both kits share an identical conformance suite.
15
+
16
+ ### Miss semantics (MinimalRepo contract)
17
+
18
+ - `getById(id)` → returns `null` on miss (not thrown). Invalid-shape ids (e.g. `'not-a-valid-id'` on an ObjectId `_id`) short-circuit to `null` rather than raising mongoose `CastError`.
19
+ - `update(id, data)` → returns `null` on miss.
20
+ - `delete(id)` → returns `{ success: false, message: 'Document not found' }` on miss.
21
+ - Pass `{ throwOnNotFound: true }` to opt back into the legacy 404-throw behavior for any of the three.
13
22
 
14
23
  ---
15
24
 
@@ -1,7 +1,7 @@
1
1
  import { r as warn } from "./logger-DJ7egMnd.mjs";
2
- import { t as createError } from "./error-Lw9GEAro.mjs";
3
- import { n as encodeCursor, r as resolveCursorFilter } from "./cursor-DZ9JSoMM.mjs";
4
- import { r as validateKeysetSort, t as getPrimaryField } from "./sort-ffe-9JBg.mjs";
2
+ import { t as createError } from "./error-CzYwrfUP.mjs";
3
+ import { n as encodeCursor, r as resolveCursorFilter } from "./cursor-J84rR6wG.mjs";
4
+ import { r as validateKeysetSort, t as getPrimaryField } from "./sort-CrZjTK25.mjs";
5
5
  //#region src/pagination/utils/index-hint.ts
6
6
  /**
7
7
  * Read a Mongoose schema's declared indexes, defensively.
@@ -1,2 +1,2 @@
1
- import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-C-qZUqv8.mjs";
1
+ import { a as create_d_exports, i as delete_d_exports, n as update_d_exports, o as aggregate_d_exports, r as read_d_exports } from "../index-C7WmYP6F.mjs";
2
2
  export { aggregate_d_exports as aggregate, create_d_exports as create, delete_d_exports as deleteActions, read_d_exports as read, update_d_exports as update };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "../chunk-CfYAbeIz.mjs";
2
- import { _ as aggregate_exports, f as delete_exports, h as create_exports, l as read_exports, r as update_exports } from "../update-BDsQ3cdy.mjs";
2
+ import { g as create_exports, i as update_exports, p as delete_exports, u as read_exports, v as aggregate_exports } from "../update-CWXfFC6O.mjs";
3
3
  //#region src/actions/index.ts
4
4
  var actions_exports = /* @__PURE__ */ __exportAll({
5
5
  aggregate: () => aggregate_exports,
@@ -1,4 +1,4 @@
1
- import { J as Plugin } from "../types-BgdeBXI1.mjs";
1
+ import { K as Plugin } from "../types-BUS0Zj8y.mjs";
2
2
  import { ClientSession, PipelineStage } from "mongoose";
3
3
 
4
4
  //#region src/ai/types.d.ts
@@ -17,6 +17,29 @@ function createError(status, message) {
17
17
  return error;
18
18
  }
19
19
  /**
20
+ * Boolean classifier: true when `err` is an authoritative MongoDB duplicate
21
+ * key error — and ONLY then. Used by arc's outbox / idempotency adapters to
22
+ * distinguish "write already landed (idempotent no-op)" from "transient DB
23
+ * error (must retry)".
24
+ *
25
+ * Deliberately narrow — matches only:
26
+ * - `code === 11000`
27
+ * - `codeName === 'DuplicateKey'`
28
+ *
29
+ * Does NOT match `err.name === 'MongoServerError'`, which is also true for
30
+ * WriteConflict (112), NotWritablePrimary (10107), ExceededTimeLimit, and
31
+ * every other server-side error. Treating those as duplicate keys would
32
+ * cause arc's outbox to silently swallow transactional retries and lose
33
+ * events.
34
+ */
35
+ function isDuplicateKeyError(err) {
36
+ if (!err || typeof err !== "object") return false;
37
+ const e = err;
38
+ if (e.code === 11e3 || e.codeName === "DuplicateKey") return true;
39
+ if (e.status === 409 && e.duplicate !== void 0) return true;
40
+ return false;
41
+ }
42
+ /**
20
43
  * Detect and convert a MongoDB E11000 duplicate-key error into
21
44
  * a 409 HttpError with an actionable message.
22
45
  *
@@ -29,9 +52,8 @@ function createError(status, message) {
29
52
  * Returns `null` when the error is not a duplicate-key error.
30
53
  */
31
54
  function parseDuplicateKeyError(error, options = {}) {
32
- if (!error || typeof error !== "object") return null;
55
+ if (!isDuplicateKeyError(error)) return null;
33
56
  const mongoErr = error;
34
- if (mongoErr.code !== 11e3) return null;
35
57
  const fields = mongoErr.keyPattern ? Object.keys(mongoErr.keyPattern) : [];
36
58
  const exposed = options.exposeValues === true;
37
59
  const valuesString = exposed && mongoErr.keyValue ? Object.entries(mongoErr.keyValue).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(", ") : "";
@@ -43,4 +65,4 @@ function parseDuplicateKeyError(error, options = {}) {
43
65
  return httpError;
44
66
  }
45
67
  //#endregion
46
- export { parseDuplicateKeyError as n, createError as t };
68
+ export { isDuplicateKeyError as n, parseDuplicateKeyError as r, createError as t };
@@ -1,4 +1,4 @@
1
- import { $ as ReadPreferenceType, At as LookupOptions, D as GroupResult, V as ObjectId, W as OperationOptions, Z as PopulateSpec, _t as UpdateOptions, a as AnyDocument, b as DeleteResult, g as CreateOptions, gt as UpdateManyResult, pt as SortSpec, st as SelectSpec, vt as UpdateWithValidationResult, z as MinMaxResult } from "./types-BgdeBXI1.mjs";
1
+ import { Dt as LookupOptions, E as GroupResult, H as OperationOptions, L as MinMaxResult, Q as ReadPreferenceType, T as FindOneAndUpdateOptions, Y as PopulateSpec, a as AnyDocument, at as SelectSpec, dt as SortSpec, g as CreateOptions, gt as UpdateWithValidationResult, ht as UpdateOptions, mt as UpdateManyResult, y as DeleteResult, z as ObjectId } from "./types-BUS0Zj8y.mjs";
2
2
  import { ClientSession, Model, PipelineStage } from "mongoose";
3
3
 
4
4
  //#region src/actions/aggregate.d.ts
@@ -213,12 +213,12 @@ declare function exists<TDoc = AnyDocument>(Model: Model<TDoc>, query: Record<st
213
213
  _id: unknown;
214
214
  } | null>;
215
215
  declare namespace update_d_exports {
216
- export { increment, pullFromArray, pushToArray, update, updateByQuery, updateMany, updateWithConstraints, updateWithValidation };
216
+ export { findOneAndUpdate, increment, pullFromArray, pushToArray, update, updateByQuery, updateMany, updateWithConstraints, updateWithValidation };
217
217
  }
218
218
  /**
219
219
  * Update by ID
220
220
  */
221
- declare function update<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc>;
221
+ declare function update<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc | null>;
222
222
  /**
223
223
  * Update with query constraints (optimized)
224
224
  * Returns null if constraints not met (not an error)
@@ -255,18 +255,26 @@ declare function updateMany(Model: Model<unknown>, query: Record<string, unknown
255
255
  * Update by query
256
256
  */
257
257
  declare function updateByQuery<TDoc = AnyDocument>(Model: Model<TDoc>, query: Record<string, unknown>, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc | null>;
258
+ /**
259
+ * Atomic findOneAndUpdate primitive.
260
+ *
261
+ * Returns the matched document (post-update by default) or null when no doc
262
+ * matches and `upsert` is false. Used by outbox relays, distributed locks,
263
+ * and workflow semaphores that need compare-and-set in a single round-trip.
264
+ */
265
+ declare function findOneAndUpdate<TDoc = AnyDocument>(Model: Model<TDoc>, filter: Record<string, unknown>, update: Record<string, unknown> | Record<string, unknown>[], options?: FindOneAndUpdateOptions): Promise<TDoc | null>;
258
266
  /**
259
267
  * Increment field
260
268
  */
261
- declare function increment<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value?: number, options?: UpdateOptions): Promise<TDoc>;
269
+ declare function increment<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value?: number, options?: UpdateOptions): Promise<TDoc | null>;
262
270
  /**
263
271
  * Push to array
264
272
  */
265
- declare function pushToArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc>;
273
+ declare function pushToArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc | null>;
266
274
  /**
267
275
  * Pull from array
268
276
  */
269
- declare function pullFromArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc>;
277
+ declare function pullFromArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc | null>;
270
278
  declare namespace index_d_exports {
271
279
  export { aggregate_d_exports as aggregate, create_d_exports as create, delete_d_exports as deleteActions, read_d_exports as read, update_d_exports as update };
272
280
  }
package/dist/index.d.mts CHANGED
@@ -1,13 +1,51 @@
1
- import { $ as ReadPreferenceType, A as InferDocument, At as LookupOptions, B as NonNullableFields, C as EventPayload, Ct as WithPlugins, D as GroupResult, Dt as IRequestContext, E as FieldRules, Et as IControllerResponse, F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, I as Logger, J as Plugin, K as PaginationResult, L as LookupPopulateOptions, M as JsonSchema, N as KeysOfType, O as HookMode, Ot as IResponseFormatter, P as KeysetPaginationOptions, Q as ReadOptions, R as LookupPopulateResult, S as EventHandlers, St as ValidatorDefinition, T as FieldPreset, Tt as IController, U as OffsetPaginationResult, V as ObjectId, W as OperationOptions, X as PluginType, Y as PluginFunction, Z as PopulateSpec, _ as CrudSchemas, _t as UpdateOptions, a as AnyDocument, at as RequiredBy, b as DeleteResult, bt as ValidationChainOptions, c as CacheOperationOptions, ct as SessionOptions, d as CacheableOptions, dt as SoftDeleteRepository, et as RepositoryContext, f as CascadeOptions, ft as SortDirection, g as CreateOptions, gt as UpdateManyResult, h as CreateInput, ht as UpdateInput, i as AllPluginMethods, it as RepositoryOptions, j as InferRawDoc, k as HttpError, kt as LookupBuilder, l as CacheOptions, lt as SoftDeleteFilterMode, m as CollationOptions, mt as Strict, n as AggregatePaginationOptions, nt as RepositoryInstance, o as AnyModel, ot as SchemaBuilderOptions, p as CascadeRelation, pt as SortSpec, q as PartialBy, r as AggregatePaginationResult, rt as RepositoryOperation, s as CacheAdapter, st as SelectSpec, t as AggregateOptions, tt as RepositoryEvent, u as CacheStats, ut as SoftDeleteOptions, v as DecodedCursor, vt as UpdateWithValidationResult, w as EventPhase, wt as WithTransactionOptions, x as DocField, xt as ValidationResult, y as DeepPartial, yt as UserContext, z as MinMaxResult } from "./types-BgdeBXI1.mjs";
2
- import { t as index_d_exports } from "./index-C-qZUqv8.mjs";
1
+ import { $ as RepositoryContext, A as InferRawDoc, B as OffsetPaginationOptions, C as EventPhase, Ct as IControllerResponse, D as HookMode, Dt as LookupOptions, E as GroupResult, Et as LookupBuilder, F as LookupPopulateOptions, G as PartialBy, H as OperationOptions, I as LookupPopulateResult, J as PluginType, K as Plugin, L as MinMaxResult, M as KeysetPaginationOptions, N as KeysetPaginationResult, O as HttpError, P as Logger, Q as ReadPreferenceType, R as NonNullableFields, S as EventPayload, St as IController, T as FindOneAndUpdateOptions, Tt as IResponseFormatter, U as PaginationConfig, V as OffsetPaginationResult, W as PaginationResult, X as PrioritizedHook, Y as PopulateSpec, Z as ReadOptions, _ as DecodedCursor, _t as UserContext, a as AnyDocument, at as SelectSpec, b as DocField, bt as WithPlugins, c as CacheOperationOptions, ct as SoftDeleteOptions, d as CacheableOptions, dt as SortSpec, et as RepositoryEvent, f as CascadeOptions, ft as Strict, g as CreateOptions, gt as UpdateWithValidationResult, h as CreateInput, ht as UpdateOptions, i as AllPluginMethods, it as RequiredBy, j as KeysOfType, k as InferDocument, l as CacheOptions, lt as SoftDeleteRepository, m as CollationOptions, mt as UpdateManyResult, n as AggregatePaginationOptions, nt as RepositoryOperation, o as AnyModel, ot as SessionOptions, p as CascadeRelation, pt as UpdateInput, q as PluginFunction, r as AggregatePaginationResult, rt as RepositoryOptions, s as CacheAdapter, st as SoftDeleteFilterMode, t as AggregateOptions, tt as RepositoryInstance, u as CacheStats, ut as SortDirection, v as DeepPartial, vt as ValidationChainOptions, w as FieldPreset, wt as IRequestContext, x as EventHandlers, xt as WithTransactionOptions, y as DeleteResult, yt as ValidatorDefinition, z as ObjectId } from "./types-BUS0Zj8y.mjs";
2
+ import { t as index_d_exports } from "./index-C7WmYP6F.mjs";
3
3
  import { PaginationEngine } from "./pagination/PaginationEngine.mjs";
4
- import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, T as ElasticSearchOptions, U as AuditEntry, V as BulkWriteResult, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "./validation-chain.plugin-Be9rG04B.mjs";
4
+ import { $ as aggregateHelpersPlugin, A as PrefixedIdOptions, B as BatchOperationsMethods, C as methodRegistryPlugin, D as CustomIdOptions, E as elasticSearchPlugin, F as prefixedId, G as AuditQueryOptions, H as batchOperationsPlugin, I as sequentialId, J as AuditTrailOptions, K as AuditQueryResult, L as cascadePlugin, M as customIdPlugin, N as dateSequentialId, O as DateSequentialIdOptions, P as getNextSequence, Q as AggregateHelpersMethods, R as CacheMethods, T as ElasticSearchOptions, U as AuditEntry, V as BulkWriteResult, W as AuditOperation, X as auditTrailPlugin, Y as AuditTrailQuery, Z as auditLogPlugin, _ as observabilityPlugin, a as uniqueField, b as MongoOperationsMethods, c as TenantContext, d as SubdocumentMethods, f as subdocumentPlugin, g as OperationMetric, h as ObservabilityOptions, i as requireField, j as SequentialIdOptions, k as IdGenerator, l as TenantStore, m as softDeletePlugin, n as blockIf, o as validationChainPlugin, p as SoftDeleteMethods, q as AuditTrailMethods, r as immutableField, s as timestampPlugin, t as autoInject, u as createTenantContext, v as MultiTenantOptions, w as fieldFilterPlugin, x as mongoOperationsPlugin, y as multiTenantPlugin, z as cachePlugin } from "./validation-chain.plugin-JkipjuOR.mjs";
5
5
  import { n as SchemaPathsLike, t as FieldType$1 } from "./coercion-oM8G4b6m.mjs";
6
6
  import { n as SchemaIndexes } from "./indexes-C26GNZRU.mjs";
7
- import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, m as parseDuplicateKeyError, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "./mongooseToJsonSchema-Du-UopRK.mjs";
7
+ import { a as createFieldPreset, c as getMongooseProjection, d as parseDuplicateKeyError, i as configureLogger, l as createError, n as buildCrudSchemasFromMongooseSchema, o as filterResponseData, r as createMemoryCache, s as getFieldsForUser, t as buildCrudSchemasFromModel, u as isDuplicateKeyError } from "./mongooseToJsonSchema-t-MoVleF.mjs";
8
8
  import * as _$mongoose from "mongoose";
9
9
  import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
10
+ import { AggPaginationRequest, AggRequest, AggResult, RepositoryBase } from "@classytic/repo-core/repository";
11
+ import { OffsetPaginationResultCore } from "@classytic/repo-core/pagination";
10
12
 
13
+ //#region src/operations.d.ts
14
+ /**
15
+ * Where a plugin should inject its scoping filter (multi-tenant scope,
16
+ * soft-delete filter, etc.) on the RepositoryContext.
17
+ *
18
+ * - `data` — single-doc create payload (`context.data`)
19
+ * - `dataArray` — multi-doc create payload (`context.dataArray`)
20
+ * - `query` — raw filter (`context.query`); the dominant convention
21
+ * - `filters` — paginated list options' filter sub-bag (`context.filters`)
22
+ * - `operations` — bulkWrite per-sub-op (special — plugins walk each entry)
23
+ * - `none` — no scoping target (op accepts no filter input)
24
+ */
25
+ type PolicyKey = 'data' | 'dataArray' | 'query' | 'filters' | 'operations' | 'none';
26
+ interface OperationDescriptor {
27
+ /** Where multi-tenant / soft-delete plugins inject their scoping filter. */
28
+ policyKey: PolicyKey;
29
+ /** Whether this op writes to the database. Drives audit + cache invalidation. */
30
+ mutates: boolean;
31
+ /** True when `context.id` is populated by the time before/after hooks fire. */
32
+ hasIdContext: boolean;
33
+ }
34
+ /**
35
+ * The registry. Order intentionally groups by category for readability.
36
+ * Adding a new RepositoryOperation requires exactly one entry here, after
37
+ * which every bundled plugin auto-classifies it correctly.
38
+ */
39
+ declare const OP_REGISTRY: Readonly<Record<RepositoryOperation, OperationDescriptor>>;
40
+ /** All known repository operations, in registry order. */
41
+ declare const ALL_OPERATIONS: RepositoryOperation[];
42
+ /** Operations that mutate the database. Drives audit + cache invalidation lists. */
43
+ declare const MUTATING_OPERATIONS: readonly RepositoryOperation[];
44
+ /** Operations that don't mutate. Drives default cacheable ops. */
45
+ declare const READ_OPERATIONS: readonly RepositoryOperation[];
46
+ /** Filter ops by their policy injection key. */
47
+ declare function operationsByPolicyKey(key: PolicyKey): RepositoryOperation[];
48
+ //#endregion
11
49
  //#region src/query/AggregationBuilder.d.ts
12
50
  /** Options for $vectorSearch stage (Atlas only) */
13
51
  interface VectorSearchOptions {
@@ -829,33 +867,43 @@ declare class QueryParser {
829
867
  }
830
868
  //#endregion
831
869
  //#region src/Repository.d.ts
832
- type HookListener = (data: any) => void | Promise<void>;
833
- /** Hook with priority for phase ordering */
834
- interface PrioritizedHook {
835
- listener: HookListener;
836
- priority: number;
837
- }
838
870
  /**
839
- * Plugin phase priorities (lower = runs first)
840
- * Policy hooks (multi-tenant, soft-delete, validation) MUST run before cache
841
- * to ensure filters are injected before cache keys are computed.
871
+ * Plugin phase priorities (lower = runs first).
872
+ *
873
+ * Re-exported from `@classytic/repo-core/hooks` so mongokit 3.10 callers see
874
+ * the same constant whether they import from mongokit or directly from
875
+ * repo-core — priorities are identical (POLICY=100, CACHE=200,
876
+ * OBSERVABILITY=300, DEFAULT=500) and the two refs are reference-equal.
842
877
  */
843
878
  declare const HOOK_PRIORITY: {
844
- /** Policy enforcement: tenant isolation, soft-delete filtering, validation */readonly POLICY: 100; /** Caching: lookup/store after policy filters are applied */
845
- readonly CACHE: 200; /** Observability: audit logging, metrics, telemetry */
846
- readonly OBSERVABILITY: 300; /** Default priority for user-registered hooks */
879
+ readonly POLICY: 100;
880
+ readonly CACHE: 200;
881
+ readonly OBSERVABILITY: 300;
847
882
  readonly DEFAULT: 500;
848
883
  };
849
884
  /**
850
- * Production-grade repository for MongoDB
851
- * Event-driven, plugin-based, with smart pagination
885
+ * Production-grade repository for MongoDB.
886
+ *
887
+ * Extends `@classytic/repo-core/repository`'s `RepositoryBase` for the
888
+ * driver-agnostic hook + plugin plumbing (context builder, priority-sorted
889
+ * event engine, plugin-order validator) while layering every Mongo-specific
890
+ * concern — populate, aggregate, lookup, keyset + cursor pagination, $near
891
+ * rewriting — on top.
892
+ *
893
+ * Public surface is byte-stable with mongokit 3.9 (the `_hooks` property is
894
+ * preserved as a live read-through getter; all CRUD, event, and plugin method
895
+ * signatures unchanged). 3.10 is an internal re-plumbing release; consumers
896
+ * upgrading from 3.9 need no code changes.
852
897
  */
853
- declare class Repository<TDoc = unknown> {
898
+ declare class Repository<TDoc = unknown> extends RepositoryBase {
854
899
  readonly Model: Model<TDoc>;
900
+ /**
901
+ * Mongoose model name. Duplicated on the instance for BC — arc / catalog /
902
+ * user code read `repo.model`. `RepositoryBase.modelName` points to the
903
+ * same string; prefer `modelName` in new code.
904
+ */
855
905
  readonly model: string;
856
- readonly _hooks: Map<string, PrioritizedHook[]>;
857
906
  readonly _pagination: PaginationEngine<TDoc>;
858
- private readonly _hookMode;
859
907
  readonly idField: string;
860
908
  readonly searchMode: 'text' | 'regex' | 'auto';
861
909
  readonly searchFields: string[] | undefined;
@@ -863,37 +911,22 @@ declare class Repository<TDoc = unknown> {
863
911
  private _hasTextIndex;
864
912
  constructor(Model: Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions);
865
913
  /**
866
- * Register a plugin
867
- */
868
- use(plugin: PluginType): this;
869
- /**
870
- * Register event listener with optional priority for phase ordering.
914
+ * Live read-through view of the hook engine's listener registry.
871
915
  *
872
- * @param event - Event name (e.g. 'before:getAll')
873
- * @param listener - Hook function
874
- * @param options - Optional { priority } — use HOOK_PRIORITY constants.
875
- * Lower priority numbers run first.
876
- * Default: HOOK_PRIORITY.DEFAULT (500)
877
- */
878
- on(event: RepositoryEvent | (string & {}), listener: HookListener, options?: {
879
- priority?: number;
880
- }): this;
881
- /**
882
- * Remove a specific event listener
883
- */
884
- off(event: RepositoryEvent | (string & {}), listener: HookListener): this;
885
- /**
886
- * Remove all listeners for an event, or all listeners entirely
887
- */
888
- removeAllListeners(event?: string): this;
889
- /**
890
- * Emit event (sync - for backwards compatibility)
916
+ * Preserved as a public field on the Repository for back-compat with
917
+ * mongokit ≤3.9 — existing tests and observability code pattern-match
918
+ * `repo._hooks.get('before:getAll')` / `repo._hooks.size`. Each access
919
+ * returns a fresh snapshot of the underlying HookEngine state.
920
+ *
921
+ * Read-only. To register listeners use `repo.on(event, listener, { priority })`.
891
922
  */
892
- emit(event: string, data: unknown): void;
923
+ get _hooks(): Map<string, PrioritizedHook[]>;
893
924
  /**
894
- * Emit event and await all async handlers (sorted by priority)
925
+ * Fire-and-forget emit aliased through RepositoryBase's async path so
926
+ * error hooks converted to/from sync mode still route uniformly. Mongokit
927
+ * ≤3.9 made this a private method on its subclass; the base class exposes
928
+ * it publicly and wraps it in `_emitHook` below for internal use.
895
929
  */
896
- emitAsync(event: string, data: unknown): Promise<void>;
897
930
  private _emitHook;
898
931
  private _emitErrorHook;
899
932
  /**
@@ -997,7 +1030,37 @@ declare class Repository<TDoc = unknown> {
997
1030
  /**
998
1031
  * Update document by ID
999
1032
  */
1000
- update(id: string | ObjectId, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc>;
1033
+ update(id: string | ObjectId, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc | null>;
1034
+ /**
1035
+ * Atomic findOneAndUpdate (compare-and-set primitive).
1036
+ *
1037
+ * Single round-trip match-and-mutate for outbox relays, distributed locks,
1038
+ * and workflow semaphores. Goes through the full hook pipeline so
1039
+ * multi-tenant scope, soft-delete, audit, and cache plugins all apply.
1040
+ *
1041
+ * Returns the matched document (post-update by default) or `null` when no
1042
+ * document matches and `upsert` is false.
1043
+ *
1044
+ * @example FIFO claim-lease for an outbox worker
1045
+ * ```ts
1046
+ * const claimed = await outboxRepo.findOneAndUpdate(
1047
+ * { status: 'pending', leaseExpiresAt: { $lt: new Date() } },
1048
+ * { $set: { status: 'processing', leaseExpiresAt: leaseUntil, leasedBy: workerId } },
1049
+ * { sort: { createdAt: 1 }, returnDocument: 'after' },
1050
+ * );
1051
+ * if (!claimed) return; // queue empty
1052
+ * ```
1053
+ *
1054
+ * @example CAS upsert
1055
+ * ```ts
1056
+ * const lock = await locksRepo.findOneAndUpdate(
1057
+ * { _id: lockKey, ownerId: { $in: [null, workerId] } },
1058
+ * { $set: { ownerId: workerId, expiresAt: leaseUntil } },
1059
+ * { upsert: true },
1060
+ * );
1061
+ * ```
1062
+ */
1063
+ findOneAndUpdate<TResult = TDoc>(filter: Record<string, unknown>, update: Record<string, unknown> | Record<string, unknown>[], options?: FindOneAndUpdateOptions): Promise<TResult | null>;
1001
1064
  /**
1002
1065
  * Delete a document by ID.
1003
1066
  *
@@ -1021,24 +1084,86 @@ declare class Repository<TDoc = unknown> {
1021
1084
  */
1022
1085
  delete(id: string | ObjectId, options?: SessionOptions & {
1023
1086
  idField?: string;
1024
- mode?: 'hard' | 'soft';
1087
+ mode?: 'hard' | 'soft'; /** Legacy opt-in: throw a 404 error on miss instead of returning `{ success: false }`. */
1088
+ throwOnNotFound?: boolean;
1025
1089
  }): Promise<DeleteResult>;
1026
1090
  /**
1027
- * Execute aggregation pipeline
1028
- * Routes through hook system for policy enforcement (multi-tenant, soft-delete)
1091
+ * Kit-native aggregation pipeline — takes a MongoDB stage array and
1092
+ * returns the raw pipeline output. Use this for `$lookup`, `$unwind`,
1093
+ * `$facet`, `$graphLookup`, and any other mongo-specific power
1094
+ * features that don't translate to SQL.
1095
+ *
1096
+ * For backend-portable aggregations (filter + group + measures +
1097
+ * sort + limit) use `aggregate(req: AggRequest)` instead — it
1098
+ * compiles the repo-core IR to the equivalent pipeline internally
1099
+ * and produces the same row shape sqlitekit emits.
1100
+ *
1101
+ * Routes through the hook system for policy enforcement
1102
+ * (multi-tenant, soft-delete).
1103
+ *
1104
+ * @param pipeline - MongoDB aggregation stage array
1105
+ * @param options - Aggregation options including governance controls
1106
+ */
1107
+ aggregatePipeline<TResult = unknown>(pipeline: PipelineStage[], options?: AggregateOptions): Promise<TResult[]>;
1108
+ /**
1109
+ * Paginated kit-native aggregation pipeline. Same mongo-specific
1110
+ * scope as `aggregatePipeline` — reach for this when you need
1111
+ * `$lookup` / `$unwind` / `$facet` alongside pagination.
1112
+ *
1113
+ * Prefer `aggregatePaginate(req: AggPaginationRequest)` for
1114
+ * cross-backend dashboard code; that method compiles the portable
1115
+ * IR to an equivalent pipeline.
1116
+ *
1117
+ * Policy hooks (multi-tenant, soft-delete) inject context.filters
1118
+ * which are prepended as a `$match` stage.
1119
+ */
1120
+ aggregatePipelinePaginate(options?: AggregatePaginationOptions): Promise<AggregatePaginationResult<TDoc>>;
1121
+ /**
1122
+ * Portable aggregation. Compiles the repo-core `AggRequest` IR to
1123
+ * `[{$match}, {$group}, {$addFields}, {$project}, {$match}, {$sort},
1124
+ * {$skip}, {$limit}]` against this repo's collection. Output rows
1125
+ * carry one key per `groupBy` column plus one key per measure alias
1126
+ * — identical shape to sqlitekit's `aggregate(req)`, so dashboards
1127
+ * work unchanged across backends.
1128
+ *
1129
+ * Without `groupBy`: returns a single-row result with just the
1130
+ * measures (scalar aggregation). Pass
1131
+ * `{ measures: { total: { op: 'sum', field: 'amount' } } }` for a
1132
+ * simple summary.
1133
+ *
1134
+ * For mongo-specific power features (`$lookup`, `$unwind`, `$facet`,
1135
+ * `$graphLookup`, window operators) reach for `aggregatePipeline`
1136
+ * — that's the kit-native escape hatch.
1029
1137
  *
1030
- * @param pipeline - Aggregation pipeline stages
1031
- * @param options - Aggregation options including governance controls
1138
+ * Routes through the hook system for policy enforcement
1139
+ * (multi-tenant, soft-delete) — plugins inject their scope into
1140
+ * `context.filter`, which is merged into the pre-aggregate `$match`
1141
+ * before compilation.
1032
1142
  */
1033
- aggregate<TResult = unknown>(pipeline: PipelineStage[], options?: AggregateOptions): Promise<TResult[]>;
1143
+ aggregate<TRow extends Record<string, unknown> = Record<string, unknown>>(req: AggRequest): Promise<AggResult<TRow>>;
1034
1144
  /**
1035
- * Aggregate pipeline with pagination
1036
- * Best for: Complex queries, grouping, joins
1145
+ * Offset-paginated portable aggregation. Same IR as `aggregate`,
1146
+ * wrapped in the standard `OffsetPaginationResultCore` envelope so
1147
+ * UI code paginates aggregated dashboards with the same primitives
1148
+ * as raw document lists.
1037
1149
  *
1038
- * Policy hooks (multi-tenant, soft-delete) inject context.filters which are
1039
- * prepended as a $match stage to the pipeline, ensuring tenant isolation.
1150
+ * `countStrategy: 'none'` skips the second round-trip that computes
1151
+ * `total`; the envelope reports `total: 0`, `pages: 0`, and derives
1152
+ * `hasNext` from a `LIMIT N+1` peek on the data pipeline.
1040
1153
  */
1041
- aggregatePaginate(options?: AggregatePaginationOptions): Promise<AggregatePaginationResult<TDoc>>;
1154
+ aggregatePaginate<TRow extends Record<string, unknown> = Record<string, unknown>>(req: AggPaginationRequest): Promise<OffsetPaginationResultCore<TRow>>;
1155
+ /**
1156
+ * Merge policy-hook-injected filters (multi-tenant scope,
1157
+ * soft-delete) into the pre-aggregate `filter` slot of the request.
1158
+ * Plugins speak mongo-query shape (`context.query` / `context.filters`);
1159
+ * we merge those with the portable `req.filter` using `$and`.
1160
+ *
1161
+ * When the caller's filter is a Filter IR node we don't unwrap it —
1162
+ * the pipeline compiler does Filter→mongo translation. Merging here
1163
+ * as a mongo-shaped `$and` is safe because `compileFilterToMongo`
1164
+ * passes through already-mongo queries unchanged.
1165
+ */
1166
+ private _injectPolicyScopeIntoAgg;
1042
1167
  /**
1043
1168
  * Get distinct values
1044
1169
  * Routes through hook system for policy enforcement (multi-tenant, soft-delete)
@@ -1107,42 +1232,66 @@ declare class Repository<TDoc = unknown> {
1107
1232
  */
1108
1233
  buildLookup(from?: string): LookupBuilder;
1109
1234
  /**
1110
- * Execute callback within a transaction with automatic retry on transient failures.
1235
+ * Execute callback within a MongoDB transaction with automatic retry on
1236
+ * transient failures.
1111
1237
  *
1112
- * Uses the MongoDB driver's `session.withTransaction()` which automatically retries
1113
- * on `TransientTransactionError` and `UnknownTransactionCommitResult`.
1238
+ * **BREAKING (3.10):** the callback now receives a **tx-bound repository**,
1239
+ * not a raw `ClientSession`. This matches repo-core's `StandardRepo.withTransaction`
1240
+ * contract that every kit (sqlitekit, pgkit, prismakit) already implements
1241
+ * — so cross-kit plugins and apps are portable. Session threading happens
1242
+ * transparently: every CRUD call on `txRepo` auto-injects the session into
1243
+ * its options bag, including plugin-added methods (`upsert`, `increment`,
1244
+ * `updateMany`, `restore`, ...). Nested `txRepo.withTransaction(...)` throws.
1114
1245
  *
1115
- * The callback always receives a `ClientSession`. When `allowFallback` is true
1116
- * and the MongoDB deployment doesn't support transactions (e.g., standalone),
1117
- * the callback runs without a transaction on the same session.
1246
+ * For raw-session cross-repo workflows — multiple repositories coordinating
1247
+ * writes — use the standalone `withTransaction(connection, fn)` export
1248
+ * from `@classytic/mongokit`. That helper remains session-based by design.
1118
1249
  *
1119
- * @param callback - Receives a `ClientSession` to pass to repository operations
1250
+ * @param callback - Receives a tx-bound `Repository<TDoc>` — call its
1251
+ * methods directly, no need to pass `{ session }` manually
1120
1252
  * @param options.allowFallback - Run without transaction on standalone MongoDB (default: false)
1121
1253
  * @param options.onFallback - Called when falling back to non-transactional execution
1122
1254
  * @param options.transactionOptions - MongoDB driver transaction options (readConcern, writeConcern, etc.)
1123
1255
  *
1124
1256
  * @example
1125
1257
  * ```typescript
1126
- * const result = await repo.withTransaction(async (session) => {
1127
- * const order = await repo.create({ total: 100 }, { session });
1128
- * await paymentRepo.create({ orderId: order._id }, { session });
1129
- * return order;
1258
+ * const order = await repo.withTransaction(async (txRepo) => {
1259
+ * const created = await txRepo.create({ total: 100 });
1260
+ * await txRepo.update(created._id, { confirmed: true });
1261
+ * return created;
1130
1262
  * });
1131
1263
  *
1132
1264
  * // With fallback for standalone/dev environments
1133
- * await repo.withTransaction(callback, {
1134
- * allowFallback: true,
1135
- * onFallback: (err) => logger.warn('Running without transaction', err),
1265
+ * await repo.withTransaction(
1266
+ * async (txRepo) => {
1267
+ * await txRepo.create(doc);
1268
+ * },
1269
+ * {
1270
+ * allowFallback: true,
1271
+ * onFallback: (err) => logger.warn('Running without transaction', err),
1272
+ * },
1273
+ * );
1274
+ *
1275
+ * // Cross-repo with explicit session:
1276
+ * import { withTransaction } from '@classytic/mongokit';
1277
+ * await withTransaction(mongoose.connection, async (session) => {
1278
+ * const order = await orderRepo.create(data, { session });
1279
+ * await inventoryRepo.decrement(..., { session });
1136
1280
  * });
1137
1281
  * ```
1138
1282
  */
1139
- withTransaction<T>(callback: (session: ClientSession) => Promise<T>, options?: WithTransactionOptions): Promise<T>;
1283
+ withTransaction<T>(callback: (txRepo: this) => Promise<T>, options?: WithTransactionOptions): Promise<T>;
1140
1284
  /**
1141
1285
  * Execute custom query with event emission
1142
1286
  */
1143
1287
  _executeQuery<T>(buildQuery: (Model: Model<TDoc>) => Promise<T>): Promise<T>;
1144
1288
  /**
1145
- * Build operation context and run before hooks (sorted by priority).
1289
+ * Build operation context and run before-hooks (sorted by priority).
1290
+ *
1291
+ * Narrows `RepositoryBase._buildContext`'s return type to mongokit's
1292
+ * richer `RepositoryContext` (which carries `softDeleted`, `_cacheHit`,
1293
+ * populate / readPreference / session, etc.). Runtime is inherited from
1294
+ * the base class — this override is purely a type-narrowing shim.
1146
1295
  *
1147
1296
  * Hook execution order is deterministic:
1148
1297
  * 1. POLICY (100) — tenant isolation, soft-delete filtering, validation
@@ -1151,6 +1300,13 @@ declare class Repository<TDoc = unknown> {
1151
1300
  * 4. DEFAULT (500) — user-registered hooks
1152
1301
  */
1153
1302
  _buildContext(operation: string, options: Record<string, unknown> | object): Promise<RepositoryContext>;
1303
+ /**
1304
+ * Walk the well-known filter-carrying keys (`query`, `filters`,
1305
+ * `having`) and route any Filter IR through `compileFilterToMongo`.
1306
+ * Plain Mongo queries pass through untouched — `isFilter` is the
1307
+ * discriminator. Returns a shallow clone; never mutates input.
1308
+ */
1309
+ private _normalizeFilterSlots;
1154
1310
  /**
1155
1311
  * Resolve the effective sort for getAll. Handles $near conflict detection
1156
1312
  * (warns + drops explicit sort when $near is in filters).
@@ -1174,6 +1330,36 @@ declare class Repository<TDoc = unknown> {
1174
1330
  * Parse populate specification
1175
1331
  */
1176
1332
  _parsePopulate(populate: PopulateSpec | undefined): string[] | PopulateOptions[];
1333
+ /**
1334
+ * Classify a driver error as an authoritative duplicate-key conflict.
1335
+ *
1336
+ * Used by arc's outbox / idempotency adapters to distinguish
1337
+ * "write already landed (idempotent no-op)" from "transient DB error
1338
+ * (must retry)". Every backend signals duplicate keys differently —
1339
+ * MongoDB `code: 11000`, Prisma `P2002`, Postgres `23505` — so this
1340
+ * predicate lives on the kit that knows its driver. Cross-driver
1341
+ * adapters then depend only on the boolean outcome, not the shape of
1342
+ * the underlying error.
1343
+ *
1344
+ * Deliberately narrow: matches ONLY `code === 11000` and
1345
+ * `codeName === 'DuplicateKey'`. Does NOT match
1346
+ * `err.name === 'MongoServerError'`, which is also true for
1347
+ * WriteConflict, NotWritablePrimary, ExceededTimeLimit, and every
1348
+ * other server-side error — treating those as duplicate keys would
1349
+ * silently swallow transactional retries.
1350
+ *
1351
+ * @example
1352
+ * try {
1353
+ * await outboxRepo.create(event);
1354
+ * } catch (err) {
1355
+ * if (outboxRepo.isDuplicateKeyError(err)) {
1356
+ * // Idempotent no-op — event was already written by a prior attempt.
1357
+ * return;
1358
+ * }
1359
+ * throw err; // transient DB error — upstream retries
1360
+ * }
1361
+ */
1362
+ isDuplicateKeyError(err: unknown): boolean;
1177
1363
  /**
1178
1364
  * Handle errors with proper HTTP status codes
1179
1365
  */
@@ -1232,4 +1418,4 @@ declare function isTransactionUnsupported(error: Error): boolean;
1232
1418
  */
1233
1419
  declare function createRepository<TDoc>(Model: _$mongoose.Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions): Repository<TDoc>;
1234
1420
  //#endregion
1235
- export { type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, type FieldType, type FilterQuery, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type JsonSchema, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type TenantContext, type TenantStore, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidationResult, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, isTransactionUnsupported, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin, withTransaction };
1421
+ export { ALL_OPERATIONS, type AggregateHelpersMethods, type AggregateOptions, type AggregatePaginationOptions, type AggregatePaginationResult, AggregationBuilder, type AllPluginMethods, type AnyDocument, type AnyModel, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type BulkWriteResult, type CacheAdapter, type CacheMethods, type CacheOperationOptions, type CacheOptions, type CacheStats, type CacheableOptions, type CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type DocField, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldType, type FilterQuery, type FindOneAndUpdateOptions, type GroupResult, HOOK_PRIORITY, type HookMode, type HttpError, type IController, type IControllerResponse, type IRequestContext, type IResponseFormatter, type IdGenerator, type InferDocument, type InferRawDoc, type KeysOfType, type KeysetPaginationOptions, type KeysetPaginationResult, type Logger, LookupBuilder, type LookupOptions, type LookupPopulateOptions, type LookupPopulateResult, MUTATING_OPERATIONS, type MinMaxResult, type MongoOperationsMethods, type MultiTenantOptions, type NonNullableFields, OP_REGISTRY, type ObjectId, type ObservabilityOptions, type OffsetPaginationOptions, type OffsetPaginationResult, type OperationDescriptor, type OperationMetric, type OperationOptions, type PaginationConfig, PaginationEngine, type PaginationResult, type ParsedQuery, type PartialBy, type Plugin, type PluginFunction, type PluginType, type PolicyKey, type PopulateOption, type PopulateSpec, type PrefixedIdOptions, QueryParser, type QueryParserOptions, READ_OPERATIONS, type ReadOptions, type ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaLike, type SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, type TenantContext, type TenantStore, type UpdateInput, type UpdateManyResult, type UpdateOptions, type UpdateWithValidationResult, type UserContext, type ValidationChainOptions, type ValidatorDefinition, type WithPlugins, type WithTransactionOptions, index_d_exports as actions, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, buildCrudSchemasFromModel, buildCrudSchemasFromMongooseSchema, cachePlugin, cascadePlugin, configureLogger, createError, createFieldPreset, createMemoryCache, createRepository, createTenantContext, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getMongooseProjection, getNextSequence, immutableField, isDuplicateKeyError, isTransactionUnsupported, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, operationsByPolicyKey, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin, withTransaction };