@classytic/mongokit 3.4.2 → 3.4.4

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
@@ -16,8 +16,8 @@
16
16
  - **Distributed cache safety** - List cache versions stored in the adapter (Redis) for multi-pod correctness
17
17
  - **Search governance** - Text index guard (throws `400` if no index), allowlisted sort/filter fields, ReDoS protection
18
18
  - **Vector search** - MongoDB Atlas `$vectorSearch` with auto-embedding and multimodal support
19
- - **TypeScript first** - Full type safety with discriminated unions
20
- - **1090+ passing tests** - Battle-tested and production-ready
19
+ - **TypeScript first** - Full type safety with discriminated unions, typed events, and field autocomplete
20
+ - **1150+ passing tests** - Battle-tested and production-ready
21
21
 
22
22
  ## Installation
23
23
 
@@ -119,20 +119,34 @@ UserSchema.index({ organizationId: 1, createdAt: -1, _id: -1 });
119
119
 
120
120
  ### CRUD Operations
121
121
 
122
- | Method | Description |
123
- | -------------------------------- | ---------------------------------- |
124
- | `create(data, opts)` | Create single document |
125
- | `createMany(data[], opts)` | Create multiple documents |
126
- | `getById(id, opts)` | Find by ID |
127
- | `getByQuery(query, opts)` | Find one by query |
128
- | `getAll(params, opts)` | Paginated list (auto-detects mode) |
129
- | `getOrCreate(query, data, opts)` | Find or create |
130
- | `update(id, data, opts)` | Update document |
131
- | `delete(id, opts)` | Delete document |
132
- | `count(query, opts)` | Count documents |
133
- | `exists(query, opts)` | Check existence |
134
-
135
- > **Note:** All read operations (`getById`, `getByQuery`, `getAll`, `count`, `exists`, `aggregate`, etc.) accept a `readPreference` option in the `opts` parameter (e.g., `readPreference: 'secondaryPreferred'`) to support scaling reads across replica sets.
122
+ | Method | Options Type | Description |
123
+ | -------------------------------- | -------------------- | ---------------------------------- |
124
+ | `create(data, opts)` | `CreateOptions` | Create single document |
125
+ | `createMany(data[], opts)` | `CreateOptions` | Create multiple documents |
126
+ | `getById(id, opts)` | `CacheableOptions` | Find by ID |
127
+ | `getByQuery(query, opts)` | `CacheableOptions` | Find one by query |
128
+ | `getAll(params, opts)` | `CacheableOptions` | Paginated list (auto-detects mode) |
129
+ | `findAll(filters, opts)` | `OperationOptions` | All docs without pagination |
130
+ | `getOrCreate(query, data, opts)` | `SessionOptions` | Find or create |
131
+ | `update(id, data, opts)` | `UpdateOptions` | Update document |
132
+ | `delete(id, opts)` | `SessionOptions` | Delete document |
133
+ | `count(query, opts)` | `ReadOptions` | Count documents |
134
+ | `exists(query, opts)` | `ReadOptions` | Check existence |
135
+ | `aggregate(pipeline, opts)` | `AggregateOptions` | Run aggregation pipeline |
136
+ | `distinct(field, query, opts)` | `ReadOptions` | Get distinct values |
137
+
138
+ All option types inherit from a clean hierarchy — import only what you need:
139
+
140
+ ```
141
+ SessionOptions → { session }
142
+ └─ ReadOptions → + readPreference
143
+ ├─ OperationOptions → + select, populate, populateOptions, lean, throwOnNotFound
144
+ │ ├─ CacheableOptions → + skipCache, cacheTtl
145
+ │ └─ UpdateOptions → + updatePipeline, arrayFilters
146
+ ├─ AggregateOptions → + allowDiskUse, collation, maxTimeMS, maxPipelineStages
147
+ └─ LookupPopulateOptions → + filters, lookups, sort, page, limit, collation
148
+ └─ CreateOptions → + ordered
149
+ ```
136
150
 
137
151
  ### Aggregation
138
152
 
@@ -895,34 +909,46 @@ class UserRepo extends Repository<IUser> {}
895
909
  const repo = new UserRepo(Model, [
896
910
  methodRegistryPlugin(),
897
911
  mongoOperationsPlugin(),
898
- // ... other plugins
912
+ softDeletePlugin(),
899
913
  ]) as WithPlugins<IUser, UserRepo>;
900
914
 
901
- // Full TypeScript autocomplete!
902
- await repo.increment(id, "views", 1);
903
- await repo.restore(id);
915
+ // Full TypeScript autocomplete — field names inferred from IUser!
916
+ await repo.increment(id, "age", 1); // ✅ "age" autocompleted from IUser
917
+ await repo.groupBy("status"); // ✅ "status" autocompleted
918
+ await repo.restore(id); // ✅ Returns Promise<IUser>
919
+ await repo.getDeleted(); // ✅ Returns OffsetPaginationResult<IUser>
904
920
  await repo.invalidateCache(id);
905
921
  ```
906
922
 
923
+ Field params use `DocField<TDoc>` — autocomplete for known fields, still accepts arbitrary strings for nested paths like `'address.city'`.
924
+
907
925
  **Individual plugin types:** `MongoOperationsMethods<T>`, `BatchOperationsMethods`, `AggregateHelpersMethods`, `SubdocumentMethods<T>`, `SoftDeleteMethods<T>`, `CacheMethods`, `AuditTrailMethods`
908
926
 
909
927
  ## Event System
910
928
 
911
- ```javascript
929
+ Event names are typed as `RepositoryEvent` — full autocomplete in TypeScript:
930
+
931
+ ```typescript
932
+ // before:* receives context directly — mutate in-place
912
933
  repo.on("before:create", async (context) => {
913
934
  context.data.processedAt = new Date();
914
935
  });
915
936
 
937
+ // after:* receives { context, result }
916
938
  repo.on("after:create", ({ context, result }) => {
917
939
  console.log("Created:", result);
918
940
  });
919
941
 
942
+ // error:* receives { context, error }
920
943
  repo.on("error:create", ({ context, error }) => {
921
944
  console.error("Failed:", error);
922
945
  });
946
+
947
+ // Remove a listener
948
+ repo.off("after:create", myListener);
923
949
  ```
924
950
 
925
- **Events:** `before:*`, `after:*`, `error:*` for `create`, `createMany`, `update`, `delete`, `deleteMany`, `updateMany`, `getById`, `getByQuery`, `getAll`, `aggregatePaginate`
951
+ **Events:** `before:*`, `after:*`, `error:*` for `create`, `createMany`, `update`, `delete`, `deleteMany`, `updateMany`, `getById`, `getByQuery`, `getAll`, `aggregate`, `aggregatePaginate`, `lookupPopulate`, `getOrCreate`, `count`, `exists`, `distinct`, `bulkWrite`
926
952
 
927
953
  ### Microservice Integration (Kafka / RabbitMQ / Redis Pub-Sub)
928
954
 
@@ -1020,10 +1046,18 @@ const parser = new QueryParser({
1020
1046
  maxLimit: 100, // Prevent excessive queries
1021
1047
  maxFilterDepth: 5, // Prevent nested injection
1022
1048
  maxRegexLength: 100, // ReDoS protection
1049
+ allowedFilterFields: ['status', 'name', 'email'], // Whitelist filter fields
1050
+ allowedSortFields: ['createdAt', 'name'], // Whitelist sort fields
1051
+ allowedOperators: ['eq', 'ne', 'in', 'gt', 'lt'], // Whitelist operators
1023
1052
  });
1024
1053
 
1025
1054
  // Parse request query
1026
1055
  const { filters, limit, page, sort, search } = parser.parse(req.query);
1056
+
1057
+ // Read back configured whitelists (used by Arc MCP integration)
1058
+ parser.allowedFilterFields; // ['status', 'name', 'email'] or undefined
1059
+ parser.allowedSortFields; // ['createdAt', 'name'] or undefined
1060
+ parser.allowedOperators; // ['eq', 'ne', 'in', 'gt', 'lt'] or undefined
1027
1061
  ```
1028
1062
 
1029
1063
  **Supported query patterns:**
@@ -1062,6 +1096,8 @@ GET /posts?populate[author][populate][department][select]=name # Nested
1062
1096
  - Blocks `$where`, `$function`, `$accumulator` operators (`$expr` allowed for `$lookup` correlation)
1063
1097
  - ReDoS protection for regex patterns
1064
1098
  - Max filter depth enforcement
1099
+ - Field allowlists for filters and sorting (`allowedFilterFields`, `allowedSortFields`)
1100
+ - Operator allowlists (`allowedOperators`)
1065
1101
  - Collection allowlists for lookups
1066
1102
  - Populate path sanitization (blocks `$where`, `__proto__`, etc.)
1067
1103
  - Max populate depth limit (default: 5)
@@ -1245,29 +1281,45 @@ app.post("/users", async (req, res) => {
1245
1281
 
1246
1282
  ## TypeScript
1247
1283
 
1248
- ```typescript
1249
- import {
1250
- Repository,
1251
- OffsetPaginationResult,
1252
- KeysetPaginationResult,
1253
- } from "@classytic/mongokit";
1284
+ `TDoc` is inferred from the Mongoose model — no manual annotation needed:
1254
1285
 
1255
- interface IUser extends Document {
1256
- name: string;
1257
- email: string;
1258
- }
1286
+ ```typescript
1287
+ import { Repository } from "@classytic/mongokit";
1288
+ import type { CacheableOptions, ReadOptions } from "@classytic/mongokit";
1259
1289
 
1260
- const repo = new Repository<IUser>(UserModel);
1290
+ const repo = new Repository(UserModel); // TDoc inferred from UserModel
1261
1291
 
1262
- const result = await repo.getAll({ page: 1, limit: 20 });
1292
+ // All return types flow correctly
1293
+ const user = await repo.getById("123"); // IUser | null
1294
+ const users = await repo.getAll({ page: 1 }); // OffsetPaginationResult<IUser> | KeysetPaginationResult<IUser>
1263
1295
 
1264
- // Discriminated union - TypeScript knows the type
1265
- if (result.method === "offset") {
1266
- console.log(result.total, result.pages); // Available
1296
+ // Discriminated union TypeScript narrows the type
1297
+ if (users.method === "offset") {
1298
+ console.log(users.total, users.pages); // Available
1267
1299
  }
1268
- if (result.method === "keyset") {
1269
- console.log(result.next, result.hasMore); // Available
1300
+ if (users.method === "keyset") {
1301
+ console.log(users.next, users.hasMore); // Available
1270
1302
  }
1303
+
1304
+ // Typed options — import and reuse
1305
+ const opts: CacheableOptions = { skipCache: true, lean: true };
1306
+ const fresh = await repo.getById("123", opts);
1307
+ ```
1308
+
1309
+ ### Utility Types
1310
+
1311
+ ```typescript
1312
+ import type {
1313
+ InferDocument, // Extract TDoc from Model: InferDocument<typeof UserModel>
1314
+ InferRawDoc, // TDoc without Mongoose Document methods
1315
+ CreateInput, // Omit<TDoc, '_id' | 'createdAt' | 'updatedAt' | '__v'>
1316
+ UpdateInput, // Partial<Omit<TDoc, '_id' | 'createdAt' | '__v'>>
1317
+ DocField, // (keyof TDoc & string) | (string & {}) — autocomplete + nested paths
1318
+ PartialBy, // Make specific fields optional
1319
+ RequiredBy, // Make specific fields required
1320
+ DeepPartial, // Recursive partial
1321
+ KeysOfType, // Extract keys by value type: KeysOfType<IUser, string>
1322
+ } from "@classytic/mongokit";
1271
1323
  ```
1272
1324
 
1273
1325
  ## Extending Repository
@@ -12,8 +12,10 @@ import { r as validateKeysetSort, t as getPrimaryField } from "./sort-C-BJEWUZ.m
12
12
  */
13
13
  function validateLimit(limit, config) {
14
14
  const parsed = Number(limit);
15
- if (!Number.isFinite(parsed) || parsed < 1) return config.defaultLimit || 10;
16
- return Math.min(Math.floor(parsed), config.maxLimit || 100);
15
+ if (!Number.isFinite(parsed) || parsed < 1) return config.defaultLimit ?? 10;
16
+ const max = config.maxLimit ?? 100;
17
+ if (max === 0) return Math.floor(parsed);
18
+ return Math.min(Math.floor(parsed), max);
17
19
  }
18
20
  /**
19
21
  * Validates and sanitizes page number
@@ -101,12 +103,12 @@ var PaginationEngine = class {
101
103
  constructor(Model, config = {}) {
102
104
  this.Model = Model;
103
105
  this.config = {
104
- defaultLimit: config.defaultLimit || 10,
105
- maxLimit: config.maxLimit || 100,
106
- maxPage: config.maxPage || 1e4,
107
- deepPageThreshold: config.deepPageThreshold || 100,
108
- cursorVersion: config.cursorVersion || 1,
109
- useEstimatedCount: config.useEstimatedCount || false
106
+ defaultLimit: config.defaultLimit ?? 10,
107
+ maxLimit: config.maxLimit ?? 100,
108
+ maxPage: config.maxPage ?? 1e4,
109
+ deepPageThreshold: config.deepPageThreshold ?? 100,
110
+ cursorVersion: config.cursorVersion ?? 1,
111
+ useEstimatedCount: config.useEstimatedCount ?? false
110
112
  };
111
113
  }
112
114
  /**
@@ -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-BuoZIZ15.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-DxNyLB2w.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 { c as read_exports, h as aggregate_exports, n as update_exports, p as create_exports, u as delete_exports } from "../update-DGKMmBgG.mjs";
2
+ import { c as read_exports, h as aggregate_exports, n as update_exports, p as create_exports, u as delete_exports } from "../update-D6FFSUUO.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 { U as Plugin } from "../types-COINbsdL.mjs";
1
+ import { J as Plugin } from "../types-sOh6QSzc.mjs";
2
2
  import { ClientSession, PipelineStage } from "mongoose";
3
3
 
4
4
  //#region src/ai/types.d.ts
@@ -1,4 +1,4 @@
1
- import { Ct as LookupOptions, I as ObjectId, K as PopulateSpec, P as MinMaxResult, dt as UpdateWithValidationResult, i as AnyDocument, lt as UpdateManyResult, m as CreateOptions, ot as SortSpec, q as ReadPreferenceType, tt as SelectSpec, ut as UpdateOptions, v as DeleteResult, w as GroupResult, z as OperationOptions } from "./types-COINbsdL.mjs";
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-sOh6QSzc.mjs";
2
2
  import { ClientSession, Model, PipelineStage } from "mongoose";
3
3
 
4
4
  //#region src/actions/aggregate.d.ts
package/dist/index.d.mts CHANGED
@@ -1,8 +1,8 @@
1
- import { $ as RequiredBy, A as KeysOfType, B as PaginationConfig, C as FieldRules, Ct as LookupOptions, D as InferDocument, E as HttpError, F as NonNullableFields, G as PluginType, H as PartialBy, I as ObjectId, J as RepositoryContext, K as PopulateSpec, L as OffsetPaginationOptions, M as KeysetPaginationResult, N as Logger, O as InferRawDoc, P as MinMaxResult, Q as RepositoryOptions, R as OffsetPaginationResult, S as FieldPreset, St as LookupBuilder, T as HookMode, U as Plugin, V as PaginationResult, W as PluginFunction, X as RepositoryInstance, Y as RepositoryEvent, Z as RepositoryOperation, _ as DeepPartial, _t as WithTransactionOptions, a as AnyModel, at as SortDirection, b as EventPayload, bt as IRequestContext, c as CacheOptions, ct as UpdateInput, d as CascadeRelation, dt as UpdateWithValidationResult, et as SchemaBuilderOptions, f as CollationOptions, ft as UserContext, g as DecodedCursor, gt as WithPlugins, h as CrudSchemas, ht as ValidatorDefinition, i as AnyDocument, it as SoftDeleteRepository, j as KeysetPaginationOptions, k as JsonSchema, l as CacheStats, lt as UpdateManyResult, m as CreateOptions, mt as ValidationResult, n as AggregatePaginationResult, nt as SoftDeleteFilterMode, o as CacheAdapter, ot as SortSpec, p as CreateInput, pt as ValidationChainOptions, q as ReadPreferenceType, r as AllPluginMethods, rt as SoftDeleteOptions, s as CacheOperationOptions, st as Strict, t as AggregatePaginationOptions, tt as SelectSpec, u as CascadeOptions, ut as UpdateOptions, v as DeleteResult, vt as IController, w as GroupResult, x as EventPhase, xt as IResponseFormatter, y as EventHandlers, yt as IControllerResponse, z as OperationOptions } from "./types-COINbsdL.mjs";
2
- import { t as index_d_exports } from "./index-BuoZIZ15.mjs";
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-sOh6QSzc.mjs";
2
+ import { t as index_d_exports } from "./index-DxNyLB2w.mjs";
3
3
  import { PaginationEngine } from "./pagination/PaginationEngine.mjs";
4
- import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, R as BulkWriteResult, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, z as batchOperationsPlugin } from "./validation-chain.plugin-BNoaKDOm.mjs";
5
- 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-RX9YfJLu.mjs";
4
+ import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, R as BulkWriteResult, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, z as batchOperationsPlugin } from "./validation-chain.plugin-nJtqOI-E.mjs";
5
+ 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-C374oVAV.mjs";
6
6
  import * as _$mongoose from "mongoose";
7
7
  import { ClientSession, Expression, Model, PipelineStage, PopulateOptions } from "mongoose";
8
8
 
@@ -554,6 +554,24 @@ declare class QueryParser {
554
554
  */
555
555
  private readonly dangerousRegexPatterns;
556
556
  constructor(options?: QueryParserOptions);
557
+ /**
558
+ * Get the configured allowed filter fields.
559
+ * Returns `undefined` if no whitelist is set (all fields allowed).
560
+ *
561
+ * Used by Arc's MCP integration to auto-derive `filterableFields`
562
+ * from the QueryParser when `schemaOptions.filterableFields` is not set.
563
+ */
564
+ get allowedFilterFields(): string[] | undefined;
565
+ /**
566
+ * Get the configured allowed sort fields.
567
+ * Returns `undefined` if no whitelist is set (all fields allowed).
568
+ */
569
+ get allowedSortFields(): string[] | undefined;
570
+ /**
571
+ * Get the configured allowed operators.
572
+ * Returns `undefined` if no whitelist is set (all built-in operators allowed).
573
+ */
574
+ get allowedOperators(): string[] | undefined;
557
575
  /**
558
576
  * Parse URL query parameters into MongoDB query format
559
577
  *
@@ -749,7 +767,7 @@ declare const HOOK_PRIORITY: {
749
767
  * Production-grade repository for MongoDB
750
768
  * Event-driven, plugin-based, with smart pagination
751
769
  */
752
- declare class Repository<TDoc = any> {
770
+ declare class Repository<TDoc = unknown> {
753
771
  readonly Model: Model<TDoc>;
754
772
  readonly model: string;
755
773
  readonly _hooks: Map<string, PrioritizedHook[]>;
@@ -771,13 +789,13 @@ declare class Repository<TDoc = any> {
771
789
  * Lower priority numbers run first.
772
790
  * Default: HOOK_PRIORITY.DEFAULT (500)
773
791
  */
774
- on(event: string, listener: HookListener, options?: {
792
+ on(event: RepositoryEvent | (string & {}), listener: HookListener, options?: {
775
793
  priority?: number;
776
794
  }): this;
777
795
  /**
778
796
  * Remove a specific event listener
779
797
  */
780
- off(event: string, listener: HookListener): this;
798
+ off(event: RepositoryEvent | (string & {}), listener: HookListener): this;
781
799
  /**
782
800
  * Remove all listeners for an event, or all listeners entirely
783
801
  */
@@ -795,44 +813,28 @@ declare class Repository<TDoc = any> {
795
813
  /**
796
814
  * Create single document
797
815
  */
798
- create(data: Record<string, unknown>, options?: {
799
- session?: ClientSession;
800
- }): Promise<TDoc>;
816
+ create(data: Record<string, unknown>, options?: CreateOptions): Promise<TDoc>;
801
817
  /**
802
818
  * Create multiple documents
803
819
  */
804
- createMany(dataArray: Record<string, unknown>[], options?: {
805
- session?: ClientSession;
806
- ordered?: boolean;
807
- }): Promise<TDoc[]>;
820
+ createMany(dataArray: Record<string, unknown>[], options?: CreateOptions): Promise<TDoc[]>;
808
821
  /**
809
822
  * Get document by ID
810
823
  */
811
- getById(id: string | ObjectId, options?: {
812
- select?: SelectSpec;
813
- populate?: PopulateSpec;
814
- populateOptions?: PopulateOptions[];
815
- lean?: boolean;
816
- session?: ClientSession;
817
- throwOnNotFound?: boolean;
818
- skipCache?: boolean;
819
- cacheTtl?: number;
820
- readPreference?: ReadPreferenceType;
821
- }): Promise<TDoc | null>;
824
+ getById(id: string | ObjectId, options?: CacheableOptions): Promise<TDoc | null>;
822
825
  /**
823
826
  * Get single document by query
824
827
  */
825
- getByQuery(query: Record<string, unknown>, options?: {
826
- select?: SelectSpec;
827
- populate?: PopulateSpec;
828
- populateOptions?: PopulateOptions[];
829
- lean?: boolean;
830
- session?: ClientSession;
831
- throwOnNotFound?: boolean;
832
- skipCache?: boolean;
833
- cacheTtl?: number;
834
- readPreference?: ReadPreferenceType;
835
- }): Promise<TDoc | null>;
828
+ getByQuery(query: Record<string, unknown>, options?: CacheableOptions): Promise<TDoc | null>;
829
+ /**
830
+ * Fetch ALL documents matching filters without pagination.
831
+ * Use for background jobs, exports, batch processing where you need every doc.
832
+ *
833
+ * @example
834
+ * const all = await repo.findAll({ status: 'active' });
835
+ * const allLean = await repo.findAll({}, { select: 'name email', lean: true });
836
+ */
837
+ findAll(filters?: Record<string, unknown>, options?: OperationOptions): Promise<TDoc[]>;
836
838
  /**
837
839
  * Unified pagination - auto-detects offset vs keyset based on params
838
840
  *
@@ -875,40 +877,24 @@ declare class Repository<TDoc = any> {
875
877
  readPreference?: ReadPreferenceType; /** Advanced populate options (from QueryParser or Arc's BaseController) */
876
878
  populateOptions?: PopulateOptions[]; /** Collation for locale-aware string comparison */
877
879
  collation?: CollationOptions; /** Lookup configurations for $lookup joins (from QueryParser or manual) */
878
- lookups?: LookupOptions[];
879
- }, options?: {
880
- select?: SelectSpec;
881
- populate?: PopulateSpec;
882
- populateOptions?: PopulateOptions[];
883
- lean?: boolean;
884
- session?: ClientSession;
885
- skipCache?: boolean;
886
- cacheTtl?: number;
887
- readPreference?: ReadPreferenceType;
888
- }): Promise<OffsetPaginationResult<TDoc> | KeysetPaginationResult<TDoc>>;
880
+ lookups?: LookupOptions[]; /** Skip pagination entirely — returns raw TDoc[] (same as findAll) */
881
+ noPagination?: boolean;
882
+ }, options?: CacheableOptions): Promise<OffsetPaginationResult<TDoc> | KeysetPaginationResult<TDoc> | TDoc[]>;
889
883
  /**
890
884
  * Get or create document
891
885
  * Routes through hook system for policy enforcement (multi-tenant, soft-delete)
892
886
  */
893
- getOrCreate(query: Record<string, unknown>, createData: Record<string, unknown>, options?: {
894
- session?: ClientSession;
895
- }): Promise<TDoc | null>;
887
+ getOrCreate(query: Record<string, unknown>, createData: Record<string, unknown>, options?: SessionOptions): Promise<TDoc | null>;
896
888
  /**
897
889
  * Count documents
898
890
  * Routes through hook system for policy enforcement (multi-tenant, soft-delete)
899
891
  */
900
- count(query?: Record<string, unknown>, options?: {
901
- session?: ClientSession;
902
- readPreference?: ReadPreferenceType;
903
- }): Promise<number>;
892
+ count(query?: Record<string, unknown>, options?: ReadOptions): Promise<number>;
904
893
  /**
905
894
  * Check if document exists
906
895
  * Routes through hook system for policy enforcement (multi-tenant, soft-delete)
907
896
  */
908
- exists(query: Record<string, unknown>, options?: {
909
- session?: ClientSession;
910
- readPreference?: ReadPreferenceType;
911
- }): Promise<{
897
+ exists(query: Record<string, unknown>, options?: ReadOptions): Promise<{
912
898
  _id: unknown;
913
899
  } | null>;
914
900
  /**
@@ -918,9 +904,7 @@ declare class Repository<TDoc = any> {
918
904
  /**
919
905
  * Delete document by ID
920
906
  */
921
- delete(id: string | ObjectId, options?: {
922
- session?: ClientSession;
923
- }): Promise<DeleteResult>;
907
+ delete(id: string | ObjectId, options?: SessionOptions): Promise<DeleteResult>;
924
908
  /**
925
909
  * Execute aggregation pipeline
926
910
  * Routes through hook system for policy enforcement (multi-tenant, soft-delete)
@@ -928,18 +912,7 @@ declare class Repository<TDoc = any> {
928
912
  * @param pipeline - Aggregation pipeline stages
929
913
  * @param options - Aggregation options including governance controls
930
914
  */
931
- aggregate<TResult = unknown>(pipeline: PipelineStage[], options?: {
932
- session?: ClientSession;
933
- allowDiskUse?: boolean;
934
- comment?: string;
935
- readPreference?: ReadPreferenceType;
936
- maxTimeMS?: number;
937
- readConcern?: {
938
- level: string;
939
- };
940
- collation?: Record<string, unknown>;
941
- maxPipelineStages?: number;
942
- }): Promise<TResult[]>;
915
+ aggregate<TResult = unknown>(pipeline: PipelineStage[], options?: AggregateOptions): Promise<TResult[]>;
943
916
  /**
944
917
  * Aggregate pipeline with pagination
945
918
  * Best for: Complex queries, grouping, joins
@@ -952,10 +925,7 @@ declare class Repository<TDoc = any> {
952
925
  * Get distinct values
953
926
  * Routes through hook system for policy enforcement (multi-tenant, soft-delete)
954
927
  */
955
- distinct<T = unknown>(field: string, query?: Record<string, unknown>, options?: {
956
- session?: ClientSession;
957
- readPreference?: ReadPreferenceType;
958
- }): Promise<T[]>;
928
+ distinct<T = unknown>(field: string, query?: Record<string, unknown>, options?: ReadOptions): Promise<T[]>;
959
929
  /**
960
930
  * Query with custom field lookups ($lookup)
961
931
  * Best for: Joins on slugs, SKUs, codes, or other indexed custom fields
@@ -980,26 +950,7 @@ declare class Repository<TDoc = any> {
980
950
  * });
981
951
  * ```
982
952
  */
983
- lookupPopulate(options: {
984
- filters?: Record<string, unknown>;
985
- lookups: LookupOptions[];
986
- sort?: SortSpec | string;
987
- page?: number;
988
- after?: string;
989
- limit?: number;
990
- select?: SelectSpec;
991
- session?: ClientSession;
992
- readPreference?: ReadPreferenceType;
993
- collation?: CollationOptions;
994
- countStrategy?: 'exact' | 'estimated' | 'none';
995
- }): Promise<{
996
- data: TDoc[];
997
- total: number;
998
- page?: number;
999
- limit: number;
1000
- next?: string | null;
1001
- hasMore?: boolean;
1002
- }>;
953
+ lookupPopulate(options: LookupPopulateOptions): Promise<LookupPopulateResult<TDoc>>;
1003
954
  /**
1004
955
  * Create an aggregation builder for this model
1005
956
  * Useful for building complex custom aggregations
@@ -1082,7 +1033,7 @@ declare class Repository<TDoc = any> {
1082
1033
  * 3. OBSERVABILITY (300) — audit logging, metrics
1083
1034
  * 4. DEFAULT (500) — user-registered hooks
1084
1035
  */
1085
- _buildContext(operation: string, options: Record<string, unknown>): Promise<RepositoryContext>;
1036
+ _buildContext(operation: string, options: Record<string, unknown> | object): Promise<RepositoryContext>;
1086
1037
  /**
1087
1038
  * Parse sort string or object
1088
1039
  */
@@ -1110,4 +1061,4 @@ declare class Repository<TDoc = any> {
1110
1061
  */
1111
1062
  declare function createRepository<TDoc>(Model: _$mongoose.Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions): Repository<TDoc>;
1112
1063
  //#endregion
1113
- export { type AggregateHelpersMethods, 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 CascadeOptions, type CascadeRelation, type CollationOptions, type CreateInput, type CreateOptions, type CrudSchemas, type CustomIdOptions, type DateSequentialIdOptions, type DecodedCursor, type DeepPartial, type DeleteResult, type ElasticSearchOptions, type EventHandlers, type EventPayload, type EventPhase, type FieldPreset, type FieldRules, 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 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 ReadPreferenceType, Repository, Repository as default, type RepositoryContext, type RepositoryEvent, type RepositoryInstance, type RepositoryOperation, type RepositoryOptions, type RequiredBy, type SchemaBuilderOptions, type SearchMode, type SelectSpec, type SequentialIdOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, 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, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin };
1064
+ 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 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 SearchMode, type SelectSpec, type SequentialIdOptions, type SessionOptions, type SoftDeleteFilterMode, type SoftDeleteMethods, type SoftDeleteOptions, type SoftDeleteRepository, type SortDirection, type SortSpec, type Strict, type SubdocumentMethods, 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, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, filterResponseData, getFieldsForUser, getImmutableFields, getMongooseProjection, getNextSequence, getSystemManagedFields, immutableField, isFieldUpdateAllowed, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, parseDuplicateKeyError, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validateUpdateBody, validationChainPlugin };
package/dist/index.mjs CHANGED
@@ -1,8 +1,8 @@
1
1
  import { a as warn, n as parseDuplicateKeyError, r as configureLogger, t as createError } from "./error-Bpbi_NKo.mjs";
2
- import { _ as LookupBuilder } from "./update-DGKMmBgG.mjs";
2
+ import { _ as LookupBuilder } from "./update-D6FFSUUO.mjs";
3
3
  import { t as actions_exports } from "./actions/index.mjs";
4
- import { t as PaginationEngine } from "./PaginationEngine-nY04eGUM.mjs";
5
- import { A as aggregateHelpersPlugin, C as HOOK_PRIORITY, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, T as AggregationBuilder, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, w as Repository, x as cascadePlugin, y as prefixedId } from "./validation-chain.plugin-Cp5X5IZu.mjs";
4
+ import { t as PaginationEngine } from "./PaginationEngine-DCs-zKwZ.mjs";
5
+ import { A as aggregateHelpersPlugin, C as HOOK_PRIORITY, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, T as AggregationBuilder, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, w as Repository, x as cascadePlugin, y as prefixedId } from "./validation-chain.plugin-7Pa1wIsD.mjs";
6
6
  import { i as getMongooseProjection, n as filterResponseData, r as getFieldsForUser, t as createFieldPreset } from "./field-selection-reyDRzXf.mjs";
7
7
  import { a as isFieldUpdateAllowed, i as getSystemManagedFields, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel } from "./mongooseToJsonSchema-B6Qyl8BK.mjs";
8
8
  import mongoose from "mongoose";
@@ -69,6 +69,30 @@ var QueryParser = class {
69
69
  ];
70
70
  }
71
71
  /**
72
+ * Get the configured allowed filter fields.
73
+ * Returns `undefined` if no whitelist is set (all fields allowed).
74
+ *
75
+ * Used by Arc's MCP integration to auto-derive `filterableFields`
76
+ * from the QueryParser when `schemaOptions.filterableFields` is not set.
77
+ */
78
+ get allowedFilterFields() {
79
+ return this.options.allowedFilterFields;
80
+ }
81
+ /**
82
+ * Get the configured allowed sort fields.
83
+ * Returns `undefined` if no whitelist is set (all fields allowed).
84
+ */
85
+ get allowedSortFields() {
86
+ return this.options.allowedSortFields;
87
+ }
88
+ /**
89
+ * Get the configured allowed operators.
90
+ * Returns `undefined` if no whitelist is set (all built-in operators allowed).
91
+ */
92
+ get allowedOperators() {
93
+ return this.options.allowedOperators;
94
+ }
95
+ /**
72
96
  * Parse URL query parameters into MongoDB query format
73
97
  *
74
98
  * @example
@@ -1,4 +1,4 @@
1
- import { E as HttpError, S as FieldPreset, et as SchemaBuilderOptions, ft as UserContext, h as CrudSchemas, mt as ValidationResult, o as CacheAdapter } from "./types-COINbsdL.mjs";
1
+ import { T as FieldPreset, _ as CrudSchemas, k as HttpError, ot as SchemaBuilderOptions, s as CacheAdapter, xt as ValidationResult, yt as UserContext } from "./types-sOh6QSzc.mjs";
2
2
  import mongoose, { Schema } from "mongoose";
3
3
 
4
4
  //#region src/utils/error.d.ts
@@ -1,4 +1,4 @@
1
- import { B as PaginationConfig, L as OffsetPaginationOptions, M as KeysetPaginationResult, R as OffsetPaginationResult, i as AnyDocument, j as KeysetPaginationOptions, n as AggregatePaginationResult, t as AggregatePaginationOptions } from "../types-COINbsdL.mjs";
1
+ import { F as KeysetPaginationResult, G as PaginationConfig, H as OffsetPaginationOptions, P as KeysetPaginationOptions, U as OffsetPaginationResult, a as AnyDocument, n as AggregatePaginationOptions, r as AggregatePaginationResult } from "../types-sOh6QSzc.mjs";
2
2
  import { Model } from "mongoose";
3
3
 
4
4
  //#region src/pagination/PaginationEngine.d.ts
@@ -1,2 +1,2 @@
1
- import { t as PaginationEngine } from "../PaginationEngine-nY04eGUM.mjs";
1
+ import { t as PaginationEngine } from "../PaginationEngine-DCs-zKwZ.mjs";
2
2
  export { PaginationEngine };
@@ -1,2 +1,2 @@
1
- import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, y as MethodRegistryRepository, z as batchOperationsPlugin } from "../validation-chain.plugin-BNoaKDOm.mjs";
1
+ import { A as dateSequentialId, B as AuditEntry, C as elasticSearchPlugin, D as PrefixedIdOptions, E as IdGenerator, F as CacheMethods, G as AuditTrailOptions, H as AuditQueryOptions, I as cachePlugin, J as auditLogPlugin, K as AuditTrailQuery, L as BatchOperationsMethods, M as prefixedId, N as sequentialId, O as SequentialIdOptions, P as cascadePlugin, S as ElasticSearchOptions, T as DateSequentialIdOptions, U as AuditQueryResult, V as AuditOperation, W as AuditTrailMethods, X as aggregateHelpersPlugin, Y as AggregateHelpersMethods, _ as MongoOperationsMethods, a as uniqueField, b as methodRegistryPlugin, c as SubdocumentMethods, d as softDeletePlugin, f as ObservabilityOptions, g as multiTenantPlugin, h as MultiTenantOptions, i as requireField, j as getNextSequence, k as customIdPlugin, l as subdocumentPlugin, m as observabilityPlugin, n as blockIf, o as validationChainPlugin, p as OperationMetric, q as auditTrailPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as SoftDeleteMethods, v as mongoOperationsPlugin, w as CustomIdOptions, x as fieldFilterPlugin, y as MethodRegistryRepository, z as batchOperationsPlugin } from "../validation-chain.plugin-nJtqOI-E.mjs";
2
2
  export { type AggregateHelpersMethods, type AuditEntry, type AuditOperation, type AuditQueryOptions, type AuditQueryResult, type AuditTrailMethods, type AuditTrailOptions, AuditTrailQuery, type BatchOperationsMethods, type CacheMethods, type CustomIdOptions, type DateSequentialIdOptions, type ElasticSearchOptions, type IdGenerator, type MethodRegistryRepository, type MongoOperationsMethods, type MultiTenantOptions, type ObservabilityOptions, type OperationMetric, type PrefixedIdOptions, type SequentialIdOptions, type SoftDeleteMethods, type SubdocumentMethods, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
@@ -1,2 +1,2 @@
1
- import { A as aggregateHelpersPlugin, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, x as cascadePlugin, y as prefixedId } from "../validation-chain.plugin-Cp5X5IZu.mjs";
1
+ import { A as aggregateHelpersPlugin, D as AuditTrailQuery, E as batchOperationsPlugin, O as auditTrailPlugin, S as cachePlugin, _ as dateSequentialId, a as uniqueField, b as sequentialId, c as subdocumentPlugin, d as multiTenantPlugin, f as mongoOperationsPlugin, g as customIdPlugin, h as elasticSearchPlugin, i as requireField, k as auditLogPlugin, l as softDeletePlugin, m as fieldFilterPlugin, n as blockIf, o as validationChainPlugin, p as methodRegistryPlugin, r as immutableField, s as timestampPlugin, t as autoInject, u as observabilityPlugin, v as getNextSequence, x as cascadePlugin, y as prefixedId } from "../validation-chain.plugin-7Pa1wIsD.mjs";
2
2
  export { AuditTrailQuery, aggregateHelpersPlugin, auditLogPlugin, auditTrailPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, customIdPlugin, dateSequentialId, elasticSearchPlugin, fieldFilterPlugin, getNextSequence, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, prefixedId, requireField, sequentialId, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
@@ -677,22 +677,37 @@ interface AggregatePaginationResult<T = unknown> {
677
677
  }
678
678
  /** Union type for all pagination results */
679
679
  type PaginationResult<T = unknown> = OffsetPaginationResult<T> | KeysetPaginationResult<T> | AggregatePaginationResult<T>;
680
- /** Repository operation options */
681
- interface OperationOptions {
680
+ /** Session-only options — shared base for lightweight operations */
681
+ interface SessionOptions {
682
682
  /** MongoDB session for transactions */
683
683
  session?: ClientSession;
684
+ }
685
+ /** Read options — session + readPreference for read-only operations */
686
+ interface ReadOptions extends SessionOptions {
687
+ /** Read preference for replica sets (e.g. 'secondaryPreferred') */
688
+ readPreference?: ReadPreferenceType;
689
+ }
690
+ /** Repository operation options */
691
+ interface OperationOptions extends ReadOptions {
684
692
  /** Fields to select */
685
693
  select?: SelectSpec;
686
694
  /** Fields to populate */
687
695
  populate?: PopulateSpec;
696
+ /** Advanced populate options (from QueryParser or Arc's BaseController) */
697
+ populateOptions?: PopulateOptions[];
688
698
  /** Return plain JavaScript objects */
689
699
  lean?: boolean;
690
700
  /** Throw error if document not found (default: true) */
691
701
  throwOnNotFound?: boolean;
692
702
  /** Additional query filters (e.g., for soft delete) */
693
703
  query?: Record<string, unknown>;
694
- /** Read preference for replica sets (e.g. 'secondaryPreferred') */
695
- readPreference?: 'primary' | 'primaryPreferred' | 'secondary' | 'secondaryPreferred' | 'nearest' | string;
704
+ }
705
+ /** Cache-aware operation options extends OperationOptions with cache controls */
706
+ interface CacheableOptions extends OperationOptions {
707
+ /** Skip cache for this operation (read from DB directly) */
708
+ skipCache?: boolean;
709
+ /** Custom TTL for this operation in seconds */
710
+ cacheTtl?: number;
696
711
  }
697
712
  /** withTransaction options */
698
713
  interface WithTransactionOptions {
@@ -704,10 +719,10 @@ interface WithTransactionOptions {
704
719
  transactionOptions?: _$mongoose.mongo.TransactionOptions;
705
720
  }
706
721
  /** Create operation options */
707
- interface CreateOptions {
708
- /** MongoDB session for transactions */
709
- session?: ClientSession;
710
- /** Keep insertion order on error (default: true) */
722
+ interface CreateOptions extends SessionOptions {
723
+ /** Keep insertion order on error (default: false).
724
+ * When false, all valid documents insert even if some fail (e.g. duplicates).
725
+ * Set to true to abort remaining inserts on first error. */
711
726
  ordered?: boolean;
712
727
  }
713
728
  /** Update operation options */
@@ -717,6 +732,53 @@ interface UpdateOptions extends OperationOptions {
717
732
  /** Array filters for positional operator $[<identifier>] updates */
718
733
  arrayFilters?: Record<string, unknown>[];
719
734
  }
735
+ /** Aggregate operation options */
736
+ interface AggregateOptions extends ReadOptions {
737
+ /** Allow aggregation to use disk for large sorts/groups */
738
+ allowDiskUse?: boolean;
739
+ /** Comment for profiler/logs */
740
+ comment?: string;
741
+ /** Maximum execution time in milliseconds */
742
+ maxTimeMS?: number;
743
+ /** Read concern level */
744
+ readConcern?: {
745
+ level: string;
746
+ };
747
+ /** Collation for locale-aware string comparison */
748
+ collation?: CollationOptions;
749
+ /** Maximum allowed pipeline stages (governance) */
750
+ maxPipelineStages?: number;
751
+ }
752
+ /** Lookup populate options */
753
+ interface LookupPopulateOptions extends ReadOptions {
754
+ /** MongoDB query filters */
755
+ filters?: Record<string, unknown>;
756
+ /** Lookup configurations for $lookup joins */
757
+ lookups: LookupOptions[];
758
+ /** Sort specification */
759
+ sort?: SortSpec | string;
760
+ /** Page number (offset mode, 1-indexed) */
761
+ page?: number;
762
+ /** Cursor token for next page (keyset mode) */
763
+ after?: string;
764
+ /** Number of documents per page */
765
+ limit?: number;
766
+ /** Fields to select */
767
+ select?: SelectSpec;
768
+ /** Collation for locale-aware string comparison */
769
+ collation?: CollationOptions;
770
+ /** Count strategy for offset pagination */
771
+ countStrategy?: 'exact' | 'estimated' | 'none';
772
+ }
773
+ /** Lookup populate result */
774
+ interface LookupPopulateResult<T = unknown> {
775
+ data: T[];
776
+ total: number;
777
+ page?: number;
778
+ limit: number;
779
+ next?: string | null;
780
+ hasMore?: boolean;
781
+ }
720
782
  /** Delete result */
721
783
  interface DeleteResult {
722
784
  success: boolean;
@@ -846,16 +908,16 @@ interface RepositoryInstance {
846
908
  _hooks: Map<string, PrioritizedHook[]>;
847
909
  _pagination: unknown;
848
910
  use(plugin: PluginType): this;
849
- on(event: string, listener: (data: any) => void | Promise<void>, options?: {
911
+ on(event: RepositoryEvent | (string & {}), listener: (data: any) => void | Promise<void>, options?: {
850
912
  priority?: number;
851
913
  }): this;
852
- off(event: string, listener: (data: any) => void | Promise<void>): this;
914
+ off(event: RepositoryEvent | (string & {}), listener: (data: any) => void | Promise<void>): this;
853
915
  removeAllListeners(event?: string): this;
854
916
  emit(event: string, data: unknown): void;
855
917
  emitAsync(event: string, data: unknown): Promise<void>;
856
918
  registerMethod?(name: string, fn: (...args: any[]) => any): void;
857
919
  hasMethod?(name: string): boolean;
858
- _buildContext(operation: string, options: Record<string, unknown>): Promise<RepositoryContext>;
920
+ _buildContext(operation: string, options: Record<string, unknown> | object): Promise<RepositoryContext>;
859
921
  _handleError(error: Error): HttpError;
860
922
  update(id: string | ObjectId, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<unknown>;
861
923
  aggregate(pipeline: PipelineStage[], options?: Record<string, unknown>): Promise<unknown[]>;
@@ -864,7 +926,7 @@ interface RepositoryInstance {
864
926
  [key: string]: unknown;
865
927
  }
866
928
  /** Repository operation names */
867
- type RepositoryOperation = 'create' | 'createMany' | 'update' | 'updateMany' | 'delete' | 'deleteMany' | 'getById' | 'getByQuery' | 'getAll' | 'getOrCreate' | 'count' | 'exists' | 'distinct' | 'aggregate' | 'aggregatePaginate' | 'lookupPopulate' | 'bulkWrite';
929
+ type RepositoryOperation = 'create' | 'createMany' | 'update' | 'updateMany' | 'delete' | 'deleteMany' | 'getById' | 'getByQuery' | 'getAll' | 'findAll' | 'getOrCreate' | 'count' | 'exists' | 'distinct' | 'aggregate' | 'aggregatePaginate' | 'lookupPopulate' | 'bulkWrite';
868
930
  /** Event lifecycle phases */
869
931
  type EventPhase = 'before' | 'after' | 'error';
870
932
  /** Repository event names (generated from template literals) */
@@ -1028,7 +1090,7 @@ interface SoftDeleteOptions {
1028
1090
  ttlDays?: number;
1029
1091
  }
1030
1092
  /** Repository with soft delete methods */
1031
- interface SoftDeleteRepository {
1093
+ interface SoftDeleteRepository<TDoc = unknown> {
1032
1094
  /**
1033
1095
  * Restore a soft-deleted document by setting deletedAt to null
1034
1096
  * @param id - Document ID to restore
@@ -1037,7 +1099,7 @@ interface SoftDeleteRepository {
1037
1099
  */
1038
1100
  restore(id: string | ObjectId, options?: {
1039
1101
  session?: ClientSession;
1040
- }): Promise<unknown>;
1102
+ }): Promise<TDoc>;
1041
1103
  /**
1042
1104
  * Get all soft-deleted documents
1043
1105
  * @param params - Query parameters (filters, pagination, etc.)
@@ -1054,7 +1116,7 @@ interface SoftDeleteRepository {
1054
1116
  populate?: PopulateSpec;
1055
1117
  lean?: boolean;
1056
1118
  session?: ClientSession;
1057
- }): Promise<OffsetPaginationResult<unknown>>;
1119
+ }): Promise<OffsetPaginationResult<TDoc>>;
1058
1120
  }
1059
1121
  /** Group result */
1060
1122
  interface GroupResult {
@@ -1187,19 +1249,25 @@ interface HttpError extends Error {
1187
1249
  * } from '@classytic/mongokit';
1188
1250
  * ```
1189
1251
  */
1252
+ /**
1253
+ * Extract string keys from a document type, with `string` fallback for untyped usage.
1254
+ * Provides autocomplete for known fields while still accepting arbitrary strings
1255
+ * (e.g. for nested paths like 'address.city').
1256
+ */
1257
+ type DocField<TDoc> = (keyof TDoc & string) | (string & {});
1190
1258
  type AllPluginMethods<TDoc> = {
1191
1259
  upsert(query: Record<string, unknown>, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<TDoc>;
1192
- increment(id: string | ObjectId, field: string, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
1193
- decrement(id: string | ObjectId, field: string, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
1194
- pushToArray(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1195
- pullFromArray(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1196
- addToSet(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1197
- setField(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1198
- unsetField(id: string | ObjectId, fields: string | string[], options?: Record<string, unknown>): Promise<TDoc>;
1199
- renameField(id: string | ObjectId, oldName: string, newName: string, options?: Record<string, unknown>): Promise<TDoc>;
1200
- multiplyField(id: string | ObjectId, field: string, multiplier: number, options?: Record<string, unknown>): Promise<TDoc>;
1201
- setMin(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1202
- setMax(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1260
+ increment(id: string | ObjectId, field: DocField<TDoc>, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
1261
+ decrement(id: string | ObjectId, field: DocField<TDoc>, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
1262
+ pushToArray(id: string | ObjectId, field: DocField<TDoc>, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1263
+ pullFromArray(id: string | ObjectId, field: DocField<TDoc>, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1264
+ addToSet(id: string | ObjectId, field: DocField<TDoc>, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1265
+ setField(id: string | ObjectId, field: DocField<TDoc>, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1266
+ unsetField(id: string | ObjectId, fields: DocField<TDoc> | DocField<TDoc>[], options?: Record<string, unknown>): Promise<TDoc>;
1267
+ renameField(id: string | ObjectId, oldName: DocField<TDoc>, newName: string, options?: Record<string, unknown>): Promise<TDoc>;
1268
+ multiplyField(id: string | ObjectId, field: DocField<TDoc>, multiplier: number, options?: Record<string, unknown>): Promise<TDoc>;
1269
+ setMin(id: string | ObjectId, field: DocField<TDoc>, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1270
+ setMax(id: string | ObjectId, field: DocField<TDoc>, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
1203
1271
  atomicUpdate(id: string | ObjectId, operators: Record<string, Record<string, unknown>>, options?: Record<string, unknown>): Promise<TDoc>;
1204
1272
  updateMany(query: Record<string, unknown>, data: Record<string, unknown>, options?: {
1205
1273
  session?: ClientSession;
@@ -1228,26 +1296,26 @@ type AllPluginMethods<TDoc> = {
1228
1296
  insertedIds: Record<number, unknown>;
1229
1297
  upsertedIds: Record<number, unknown>;
1230
1298
  }>;
1231
- groupBy(field: string, options?: {
1299
+ groupBy(field: DocField<TDoc>, options?: {
1232
1300
  limit?: number;
1233
1301
  session?: unknown;
1234
1302
  }): Promise<Array<{
1235
1303
  _id: unknown;
1236
1304
  count: number;
1237
1305
  }>>;
1238
- sum(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1239
- average(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1240
- min(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1241
- max(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1242
- addSubdocument(parentId: string | ObjectId, arrayPath: string, subData: Record<string, unknown>, options?: Record<string, unknown>): Promise<TDoc>;
1243
- getSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: {
1306
+ sum(field: DocField<TDoc>, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1307
+ average(field: DocField<TDoc>, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1308
+ min(field: DocField<TDoc>, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1309
+ max(field: DocField<TDoc>, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
1310
+ addSubdocument(parentId: string | ObjectId, arrayPath: DocField<TDoc>, subData: Record<string, unknown>, options?: Record<string, unknown>): Promise<TDoc>;
1311
+ getSubdocument(parentId: string | ObjectId, arrayPath: DocField<TDoc>, subId: string | ObjectId, options?: {
1244
1312
  lean?: boolean;
1245
1313
  session?: unknown;
1246
1314
  }): Promise<Record<string, unknown>>;
1247
- updateSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, updateData: Record<string, unknown>, options?: {
1315
+ updateSubdocument(parentId: string | ObjectId, arrayPath: DocField<TDoc>, subId: string | ObjectId, updateData: Record<string, unknown>, options?: {
1248
1316
  session?: unknown;
1249
1317
  }): Promise<TDoc>;
1250
- deleteSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: Record<string, unknown>): Promise<TDoc>;
1318
+ deleteSubdocument(parentId: string | ObjectId, arrayPath: DocField<TDoc>, subId: string | ObjectId, options?: Record<string, unknown>): Promise<TDoc>;
1251
1319
  restore(id: string | ObjectId, options?: {
1252
1320
  session?: ClientSession;
1253
1321
  }): Promise<TDoc>;
@@ -1294,4 +1362,4 @@ type AllPluginMethods<TDoc> = {
1294
1362
  */
1295
1363
  type WithPlugins<TDoc, TRepo extends RepositoryInstance = RepositoryInstance> = TRepo & AllPluginMethods<TDoc>;
1296
1364
  //#endregion
1297
- export { RequiredBy as $, KeysOfType as A, PaginationConfig as B, FieldRules as C, LookupOptions as Ct, InferDocument as D, HttpError as E, NonNullableFields as F, PluginType as G, PartialBy as H, ObjectId as I, RepositoryContext as J, PopulateSpec as K, OffsetPaginationOptions as L, KeysetPaginationResult as M, Logger as N, InferRawDoc as O, MinMaxResult as P, RepositoryOptions as Q, OffsetPaginationResult as R, FieldPreset as S, LookupBuilder as St, HookMode as T, Plugin as U, PaginationResult as V, PluginFunction as W, RepositoryInstance as X, RepositoryEvent as Y, RepositoryOperation as Z, DeepPartial as _, WithTransactionOptions as _t, AnyModel as a, SortDirection as at, EventPayload as b, IRequestContext as bt, CacheOptions as c, UpdateInput as ct, CascadeRelation as d, UpdateWithValidationResult as dt, SchemaBuilderOptions as et, CollationOptions as f, UserContext as ft, DecodedCursor as g, WithPlugins as gt, CrudSchemas as h, ValidatorDefinition as ht, AnyDocument as i, SoftDeleteRepository as it, KeysetPaginationOptions as j, JsonSchema as k, CacheStats as l, UpdateManyResult as lt, CreateOptions as m, ValidationResult as mt, AggregatePaginationResult as n, SoftDeleteFilterMode as nt, CacheAdapter as o, SortSpec as ot, CreateInput as p, ValidationChainOptions as pt, ReadPreferenceType as q, AllPluginMethods as r, SoftDeleteOptions as rt, CacheOperationOptions as s, Strict as st, AggregatePaginationOptions as t, SelectSpec as tt, CascadeOptions as u, UpdateOptions as ut, DeleteResult as v, IController as vt, GroupResult as w, EventPhase as x, IResponseFormatter as xt, EventHandlers as y, IControllerResponse as yt, OperationOptions as z };
1365
+ export { ReadPreferenceType as $, InferDocument as A, LookupOptions as At, NonNullableFields as B, EventPayload as C, WithPlugins as Ct, GroupResult as D, IRequestContext as Dt, FieldRules as E, IControllerResponse as Et, KeysetPaginationResult as F, PaginationConfig as G, OffsetPaginationOptions as H, Logger as I, Plugin as J, PaginationResult as K, LookupPopulateOptions as L, JsonSchema as M, KeysOfType as N, HookMode as O, IResponseFormatter as Ot, KeysetPaginationOptions as P, ReadOptions as Q, LookupPopulateResult as R, EventHandlers as S, ValidatorDefinition as St, FieldPreset as T, IController as Tt, OffsetPaginationResult as U, ObjectId as V, OperationOptions as W, PluginType as X, PluginFunction as Y, PopulateSpec as Z, CrudSchemas as _, UpdateOptions as _t, AnyDocument as a, RequiredBy as at, DeleteResult as b, ValidationChainOptions as bt, CacheOperationOptions as c, SessionOptions as ct, CacheableOptions as d, SoftDeleteRepository as dt, RepositoryContext as et, CascadeOptions as f, SortDirection as ft, CreateOptions as g, UpdateManyResult as gt, CreateInput as h, UpdateInput as ht, AllPluginMethods as i, RepositoryOptions as it, InferRawDoc as j, HttpError as k, LookupBuilder as kt, CacheOptions as l, SoftDeleteFilterMode as lt, CollationOptions as m, Strict as mt, AggregatePaginationOptions as n, RepositoryInstance as nt, AnyModel as o, SchemaBuilderOptions as ot, CascadeRelation as p, SortSpec as pt, PartialBy as q, AggregatePaginationResult as r, RepositoryOperation as rt, CacheAdapter as s, SelectSpec as st, AggregateOptions as t, RepositoryEvent as tt, CacheStats as u, SoftDeleteOptions as ut, DecodedCursor as v, UpdateWithValidationResult as vt, EventPhase as w, WithTransactionOptions as wt, DocField as x, ValidationResult as xt, DeepPartial as y, UserContext as yt, MinMaxResult as z };
@@ -461,7 +461,7 @@ async function create(Model, data, options = {}) {
461
461
  async function createMany(Model, dataArray, options = {}) {
462
462
  return Model.insertMany(dataArray, {
463
463
  session: options.session,
464
- ordered: options.ordered !== false
464
+ ordered: options.ordered === true
465
465
  });
466
466
  }
467
467
  /**
@@ -1,5 +1,5 @@
1
- import { K as PopulateSpec, ot as SortSpec, tt as SelectSpec } from "../types-COINbsdL.mjs";
2
- import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "../mongooseToJsonSchema-RX9YfJLu.mjs";
1
+ import { Z as PopulateSpec, pt as SortSpec, st as SelectSpec } from "../types-sOh6QSzc.mjs";
2
+ import { a as isFieldUpdateAllowed, c as configureLogger, d as getFieldsForUser, f as getMongooseProjection, i as getSystemManagedFields, l as createFieldPreset, n as buildCrudSchemasFromMongooseSchema, o as validateUpdateBody, p as createError, r as getImmutableFields, s as createMemoryCache, t as buildCrudSchemasFromModel, u as filterResponseData } from "../mongooseToJsonSchema-C374oVAV.mjs";
3
3
 
4
4
  //#region src/utils/cache-keys.d.ts
5
5
  /**
@@ -1,6 +1,6 @@
1
1
  import { a as warn, i as debug, n as parseDuplicateKeyError, t as createError } from "./error-Bpbi_NKo.mjs";
2
- import { _ as LookupBuilder, a as getById, d as create, f as createMany, g as distinct, i as exists, l as deleteById, m as upsert, o as getByQuery, r as count, s as getOrCreate, t as update } from "./update-DGKMmBgG.mjs";
3
- import { t as PaginationEngine } from "./PaginationEngine-nY04eGUM.mjs";
2
+ import { _ as LookupBuilder, a as getById, d as create, f as createMany, g as distinct, i as exists, l as deleteById, m as upsert, o as getByQuery, r as count, s as getOrCreate, t as update } from "./update-D6FFSUUO.mjs";
3
+ import { t as PaginationEngine } from "./PaginationEngine-DCs-zKwZ.mjs";
4
4
  import { a as byIdKey, c as listQueryKey, l as modelPattern, o as byQueryKey, r as getFieldsForUser, u as versionKey } from "./field-selection-reyDRzXf.mjs";
5
5
  import mongoose from "mongoose";
6
6
  //#region src/plugins/aggregate-helpers.plugin.ts
@@ -1302,6 +1302,10 @@ var Repository = class {
1302
1302
  return cachedResult;
1303
1303
  }
1304
1304
  try {
1305
+ if (typeof id === "string" && !mongoose.Types.ObjectId.isValid(id)) {
1306
+ if (context.throwOnNotFound === false || options.throwOnNotFound === false) return null;
1307
+ throw createError(404, "Document not found");
1308
+ }
1305
1309
  const result = await getById(this.Model, id, context);
1306
1310
  await this._emitHook("after:getById", {
1307
1311
  context,
@@ -1352,6 +1356,42 @@ var Repository = class {
1352
1356
  }
1353
1357
  }
1354
1358
  /**
1359
+ * Fetch ALL documents matching filters without pagination.
1360
+ * Use for background jobs, exports, batch processing where you need every doc.
1361
+ *
1362
+ * @example
1363
+ * const all = await repo.findAll({ status: 'active' });
1364
+ * const allLean = await repo.findAll({}, { select: 'name email', lean: true });
1365
+ */
1366
+ async findAll(filters = {}, options = {}) {
1367
+ const context = await this._buildContext("findAll", {
1368
+ filters,
1369
+ ...options
1370
+ });
1371
+ const resolvedFilters = context.filters ?? filters;
1372
+ try {
1373
+ const query = this.Model.find(resolvedFilters);
1374
+ const selectSpec = context.select || options.select;
1375
+ if (selectSpec) query.select(selectSpec);
1376
+ if (options.populate || context.populate) query.populate(this._parsePopulate(context.populate || options.populate));
1377
+ if (context.lean ?? options.lean ?? true) query.lean();
1378
+ if (options.session) query.session(options.session);
1379
+ if (options.readPreference) query.read(options.readPreference);
1380
+ const result = await query.exec();
1381
+ await this._emitHook("after:findAll", {
1382
+ context,
1383
+ result
1384
+ });
1385
+ return result;
1386
+ } catch (error) {
1387
+ await this._emitErrorHook("error:findAll", {
1388
+ context,
1389
+ error
1390
+ });
1391
+ throw this._handleError(error);
1392
+ }
1393
+ }
1394
+ /**
1355
1395
  * Unified pagination - auto-detects offset vs keyset based on params
1356
1396
  *
1357
1397
  * Auto-detection logic:
@@ -1393,6 +1433,7 @@ var Repository = class {
1393
1433
  });
1394
1434
  return cachedResult;
1395
1435
  }
1436
+ if (params.noPagination) return this.findAll(params.filters ?? {}, options);
1396
1437
  const filters = context.filters ?? params.filters ?? {};
1397
1438
  const search = context.search ?? params.search;
1398
1439
  const sort = context.sort ?? params.sort ?? "-createdAt";
@@ -1,4 +1,4 @@
1
- import { I as ObjectId, J as RepositoryContext, K as PopulateSpec, N as Logger, R as OffsetPaginationResult, S as FieldPreset, U as Plugin, X as RepositoryInstance, c as CacheOptions, ht as ValidatorDefinition, l as CacheStats, ot as SortSpec, pt as ValidationChainOptions, rt as SoftDeleteOptions, tt as SelectSpec, u as CascadeOptions } from "./types-COINbsdL.mjs";
1
+ import { I as Logger, J as Plugin, St as ValidatorDefinition, T as FieldPreset, U as OffsetPaginationResult, V as ObjectId, Z as PopulateSpec, bt as ValidationChainOptions, et as RepositoryContext, f as CascadeOptions, l as CacheOptions, nt as RepositoryInstance, pt as SortSpec, st as SelectSpec, u as CacheStats, ut as SoftDeleteOptions } from "./types-sOh6QSzc.mjs";
2
2
  import mongoose, { ClientSession } from "mongoose";
3
3
 
4
4
  //#region src/plugins/aggregate-helpers.plugin.d.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classytic/mongokit",
3
- "version": "3.4.2",
3
+ "version": "3.4.4",
4
4
  "description": "Production-grade MongoDB repositories with zero dependencies - smart pagination, events, and plugins",
5
5
  "type": "module",
6
6
  "sideEffects": false,