@classytic/mongokit 3.2.0 → 3.2.2
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 +470 -193
- package/dist/actions/index.d.mts +9 -0
- package/dist/actions/index.mjs +15 -0
- package/dist/aggregate-BAi4Do-X.mjs +767 -0
- package/dist/aggregate-CCHI7F51.d.mts +269 -0
- package/dist/ai/index.d.mts +125 -0
- package/dist/ai/index.mjs +203 -0
- package/dist/cache-keys-C8Z9B5sw.mjs +204 -0
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/create-BuO6xt0v.mjs +55 -0
- package/dist/custom-id.plugin-B_zIs6gE.mjs +1818 -0
- package/dist/custom-id.plugin-BzZI4gnE.d.mts +893 -0
- package/dist/index.d.mts +1012 -0
- package/dist/index.mjs +1906 -0
- package/dist/limits-DsNeCx4D.mjs +299 -0
- package/dist/logger-D8ily-PP.mjs +51 -0
- package/dist/mongooseToJsonSchema-COdDEkIJ.mjs +317 -0
- package/dist/{mongooseToJsonSchema-CaRF_bCN.d.ts → mongooseToJsonSchema-Wbvjfwkn.d.mts} +16 -89
- package/dist/pagination/PaginationEngine.d.mts +93 -0
- package/dist/pagination/PaginationEngine.mjs +196 -0
- package/dist/plugins/index.d.mts +3 -0
- package/dist/plugins/index.mjs +3 -0
- package/dist/types-D-gploPr.d.mts +1241 -0
- package/dist/utils/{index.d.ts → index.d.mts} +14 -21
- package/dist/utils/index.mjs +5 -0
- package/package.json +21 -21
- package/dist/actions/index.d.ts +0 -3
- package/dist/actions/index.js +0 -5
- package/dist/ai/index.d.ts +0 -175
- package/dist/ai/index.js +0 -206
- package/dist/chunks/chunk-2ZN65ZOP.js +0 -93
- package/dist/chunks/chunk-44KXLGPO.js +0 -388
- package/dist/chunks/chunk-DEVXDBRL.js +0 -1226
- package/dist/chunks/chunk-I7CWNAJB.js +0 -46
- package/dist/chunks/chunk-JWUAVZ3L.js +0 -8
- package/dist/chunks/chunk-UE2IEXZJ.js +0 -306
- package/dist/chunks/chunk-URLJFIR7.js +0 -22
- package/dist/chunks/chunk-VWKIKZYF.js +0 -737
- package/dist/chunks/chunk-WSFCRVEQ.js +0 -7
- package/dist/index-BDn5fSTE.d.ts +0 -516
- package/dist/index.d.ts +0 -1422
- package/dist/index.js +0 -1893
- package/dist/pagination/PaginationEngine.d.ts +0 -117
- package/dist/pagination/PaginationEngine.js +0 -3
- package/dist/plugins/index.d.ts +0 -922
- package/dist/plugins/index.js +0 -6
- package/dist/types-Jni1KgkP.d.ts +0 -780
- package/dist/utils/index.js +0 -5
|
@@ -0,0 +1,893 @@
|
|
|
1
|
+
import { F as ObjectId, G as PopulateSpec, H as Plugin, L as OffsetPaginationResult, M as Logger, Y as RepositoryInstance, at as SortSpec, c as CacheOptions, et as SelectSpec, ft as ValidationChainOptions, l as CacheStats, mt as ValidatorDefinition, nt as SoftDeleteOptions, q as RepositoryContext, u as CascadeOptions, x as FieldPreset } from "./types-D-gploPr.mjs";
|
|
2
|
+
import mongoose, { ClientSession } from "mongoose";
|
|
3
|
+
|
|
4
|
+
//#region src/plugins/field-filter.plugin.d.ts
|
|
5
|
+
/**
|
|
6
|
+
* Field filter plugin that restricts fields based on user context
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* const fieldPreset = {
|
|
10
|
+
* public: ['id', 'name'],
|
|
11
|
+
* authenticated: ['email'],
|
|
12
|
+
* admin: ['createdAt', 'internalNotes']
|
|
13
|
+
* };
|
|
14
|
+
*
|
|
15
|
+
* const repo = new Repository(Model, [fieldFilterPlugin(fieldPreset)]);
|
|
16
|
+
*/
|
|
17
|
+
declare function fieldFilterPlugin(fieldPreset: FieldPreset): Plugin;
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/plugins/timestamp.plugin.d.ts
|
|
20
|
+
/**
|
|
21
|
+
* Timestamp plugin that auto-injects timestamps
|
|
22
|
+
*
|
|
23
|
+
* @example
|
|
24
|
+
* const repo = new Repository(Model, [timestampPlugin()]);
|
|
25
|
+
*/
|
|
26
|
+
declare function timestampPlugin(): Plugin;
|
|
27
|
+
//#endregion
|
|
28
|
+
//#region src/plugins/audit-log.plugin.d.ts
|
|
29
|
+
/**
|
|
30
|
+
* Audit log plugin that logs all repository operations
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* const repo = new Repository(Model, [auditLogPlugin(console)]);
|
|
34
|
+
*/
|
|
35
|
+
declare function auditLogPlugin(logger: Logger): Plugin;
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/plugins/soft-delete.plugin.d.ts
|
|
38
|
+
/**
|
|
39
|
+
* Soft delete plugin
|
|
40
|
+
*
|
|
41
|
+
* @example Basic usage
|
|
42
|
+
* ```typescript
|
|
43
|
+
* const repo = new Repository(Model, [
|
|
44
|
+
* softDeletePlugin({ deletedField: 'deletedAt' })
|
|
45
|
+
* ]);
|
|
46
|
+
*
|
|
47
|
+
* // Delete (soft)
|
|
48
|
+
* await repo.delete(id);
|
|
49
|
+
*
|
|
50
|
+
* // Restore
|
|
51
|
+
* await repo.restore(id);
|
|
52
|
+
*
|
|
53
|
+
* // Get deleted documents
|
|
54
|
+
* await repo.getDeleted({ page: 1, limit: 20 });
|
|
55
|
+
* ```
|
|
56
|
+
*
|
|
57
|
+
* @example With null filter mode (for schemas with default: null)
|
|
58
|
+
* ```typescript
|
|
59
|
+
* // Schema: { deletedAt: { type: Date, default: null } }
|
|
60
|
+
* const repo = new Repository(Model, [
|
|
61
|
+
* softDeletePlugin({
|
|
62
|
+
* deletedField: 'deletedAt',
|
|
63
|
+
* filterMode: 'null', // default - works with default: null
|
|
64
|
+
* })
|
|
65
|
+
* ]);
|
|
66
|
+
* ```
|
|
67
|
+
*
|
|
68
|
+
* @example With TTL for auto-cleanup
|
|
69
|
+
* ```typescript
|
|
70
|
+
* const repo = new Repository(Model, [
|
|
71
|
+
* softDeletePlugin({
|
|
72
|
+
* deletedField: 'deletedAt',
|
|
73
|
+
* ttlDays: 30, // Auto-delete after 30 days
|
|
74
|
+
* })
|
|
75
|
+
* ]);
|
|
76
|
+
* ```
|
|
77
|
+
*/
|
|
78
|
+
declare function softDeletePlugin(options?: SoftDeleteOptions): Plugin;
|
|
79
|
+
/**
|
|
80
|
+
* TypeScript interface for soft delete plugin methods
|
|
81
|
+
*
|
|
82
|
+
* @example
|
|
83
|
+
* ```typescript
|
|
84
|
+
* import type { SoftDeleteMethods } from '@classytic/mongokit';
|
|
85
|
+
*
|
|
86
|
+
* type UserRepoWithSoftDelete = UserRepo & SoftDeleteMethods<IUser>;
|
|
87
|
+
*
|
|
88
|
+
* const userRepo = new UserRepo(UserModel, [
|
|
89
|
+
* methodRegistryPlugin(),
|
|
90
|
+
* softDeletePlugin({ deletedField: 'deletedAt' }),
|
|
91
|
+
* ]) as UserRepoWithSoftDelete;
|
|
92
|
+
*
|
|
93
|
+
* // TypeScript autocomplete for soft delete methods
|
|
94
|
+
* await userRepo.restore(userId);
|
|
95
|
+
* const deleted = await userRepo.getDeleted({ page: 1, limit: 20 });
|
|
96
|
+
* ```
|
|
97
|
+
*/
|
|
98
|
+
interface SoftDeleteMethods<TDoc> {
|
|
99
|
+
/**
|
|
100
|
+
* Restore a soft-deleted document
|
|
101
|
+
* @param id - Document ID to restore
|
|
102
|
+
* @param options - Optional restore options
|
|
103
|
+
* @returns Restored document
|
|
104
|
+
*/
|
|
105
|
+
restore(id: string | ObjectId, options?: {
|
|
106
|
+
session?: ClientSession;
|
|
107
|
+
}): Promise<TDoc>;
|
|
108
|
+
/**
|
|
109
|
+
* Get paginated list of soft-deleted documents
|
|
110
|
+
* @param params - Query parameters (filters, sort, pagination)
|
|
111
|
+
* @param options - Query options (select, populate, lean, session)
|
|
112
|
+
* @returns Paginated result of deleted documents
|
|
113
|
+
*/
|
|
114
|
+
getDeleted(params?: {
|
|
115
|
+
filters?: Record<string, unknown>;
|
|
116
|
+
sort?: SortSpec | string;
|
|
117
|
+
page?: number;
|
|
118
|
+
limit?: number;
|
|
119
|
+
}, options?: {
|
|
120
|
+
select?: SelectSpec;
|
|
121
|
+
populate?: PopulateSpec;
|
|
122
|
+
lean?: boolean;
|
|
123
|
+
session?: ClientSession;
|
|
124
|
+
}): Promise<OffsetPaginationResult<TDoc>>;
|
|
125
|
+
}
|
|
126
|
+
//#endregion
|
|
127
|
+
//#region src/plugins/method-registry.plugin.d.ts
|
|
128
|
+
/**
|
|
129
|
+
* Extended repository interface with method registry
|
|
130
|
+
*/
|
|
131
|
+
interface MethodRegistryRepository extends RepositoryInstance {
|
|
132
|
+
registerMethod(name: string, fn: Function): void;
|
|
133
|
+
hasMethod(name: string): boolean;
|
|
134
|
+
getRegisteredMethods(): string[];
|
|
135
|
+
}
|
|
136
|
+
/**
|
|
137
|
+
* Method registry plugin that enables dynamic method registration
|
|
138
|
+
*/
|
|
139
|
+
declare function methodRegistryPlugin(): Plugin;
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region src/plugins/validation-chain.plugin.d.ts
|
|
142
|
+
type OperationType = 'create' | 'createMany' | 'update' | 'delete';
|
|
143
|
+
/**
|
|
144
|
+
* Validation chain plugin
|
|
145
|
+
*
|
|
146
|
+
* @example
|
|
147
|
+
* const repo = new Repository(Model, [
|
|
148
|
+
* validationChainPlugin([
|
|
149
|
+
* requireField('email'),
|
|
150
|
+
* uniqueField('email', 'Email already exists'),
|
|
151
|
+
* blockIf('no-delete-admin', ['delete'], ctx => ctx.data?.role === 'admin', 'Cannot delete admin'),
|
|
152
|
+
* ])
|
|
153
|
+
* ]);
|
|
154
|
+
*/
|
|
155
|
+
declare function validationChainPlugin(validators?: ValidatorDefinition[], options?: ValidationChainOptions): Plugin;
|
|
156
|
+
/**
|
|
157
|
+
* Block operation if condition is true
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* blockIf('block-library', ['delete'], ctx => ctx.data?.managed, 'Cannot delete managed records')
|
|
161
|
+
*/
|
|
162
|
+
declare function blockIf(name: string, operations: OperationType[], condition: (context: RepositoryContext) => boolean, errorMessage: string): ValidatorDefinition;
|
|
163
|
+
/**
|
|
164
|
+
* Require a field to be present
|
|
165
|
+
*/
|
|
166
|
+
declare function requireField(field: string, operations?: OperationType[]): ValidatorDefinition;
|
|
167
|
+
/**
|
|
168
|
+
* Auto-inject a value if not present
|
|
169
|
+
*/
|
|
170
|
+
declare function autoInject(field: string, getter: (context: RepositoryContext) => unknown, operations?: OperationType[]): ValidatorDefinition;
|
|
171
|
+
/**
|
|
172
|
+
* Make a field immutable (cannot be updated)
|
|
173
|
+
*/
|
|
174
|
+
declare function immutableField(field: string): ValidatorDefinition;
|
|
175
|
+
/**
|
|
176
|
+
* Ensure field value is unique
|
|
177
|
+
*/
|
|
178
|
+
declare function uniqueField(field: string, errorMessage?: string): ValidatorDefinition;
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/plugins/mongo-operations.plugin.d.ts
|
|
181
|
+
/**
|
|
182
|
+
* MongoDB operations plugin
|
|
183
|
+
*
|
|
184
|
+
* Adds MongoDB-specific atomic operations to repositories:
|
|
185
|
+
* - upsert: Create or update document
|
|
186
|
+
* - increment/decrement: Atomic numeric operations
|
|
187
|
+
* - pushToArray/pullFromArray/addToSet: Array operations
|
|
188
|
+
* - setField/unsetField/renameField: Field operations
|
|
189
|
+
* - multiplyField: Multiply numeric field
|
|
190
|
+
* - setMin/setMax: Conditional min/max updates
|
|
191
|
+
*
|
|
192
|
+
* @example Basic usage (no TypeScript autocomplete)
|
|
193
|
+
* ```typescript
|
|
194
|
+
* const repo = new Repository(ProductModel, [
|
|
195
|
+
* methodRegistryPlugin(),
|
|
196
|
+
* mongoOperationsPlugin(),
|
|
197
|
+
* ]);
|
|
198
|
+
*
|
|
199
|
+
* // Works at runtime but TypeScript doesn't know about these methods
|
|
200
|
+
* await (repo as any).increment(productId, 'views', 1);
|
|
201
|
+
* await (repo as any).pushToArray(productId, 'tags', 'featured');
|
|
202
|
+
* ```
|
|
203
|
+
*
|
|
204
|
+
* @example With TypeScript type safety (recommended)
|
|
205
|
+
* ```typescript
|
|
206
|
+
* import { Repository, mongoOperationsPlugin, methodRegistryPlugin } from '@classytic/mongokit';
|
|
207
|
+
* import type { MongoOperationsMethods } from '@classytic/mongokit';
|
|
208
|
+
*
|
|
209
|
+
* class ProductRepo extends Repository<IProduct> {
|
|
210
|
+
* // Add your custom methods here
|
|
211
|
+
* }
|
|
212
|
+
*
|
|
213
|
+
* // Create with type assertion to get autocomplete for plugin methods
|
|
214
|
+
* type ProductRepoWithPlugins = ProductRepo & MongoOperationsMethods<IProduct>;
|
|
215
|
+
*
|
|
216
|
+
* const repo = new ProductRepo(ProductModel, [
|
|
217
|
+
* methodRegistryPlugin(),
|
|
218
|
+
* mongoOperationsPlugin(),
|
|
219
|
+
* ]) as ProductRepoWithPlugins;
|
|
220
|
+
*
|
|
221
|
+
* // Now TypeScript provides autocomplete and type checking!
|
|
222
|
+
* await repo.increment(productId, 'views', 1);
|
|
223
|
+
* await repo.upsert({ sku: 'ABC' }, { name: 'Product', price: 99 });
|
|
224
|
+
* await repo.pushToArray(productId, 'tags', 'featured');
|
|
225
|
+
* ```
|
|
226
|
+
*/
|
|
227
|
+
declare function mongoOperationsPlugin(): Plugin;
|
|
228
|
+
/**
|
|
229
|
+
* Type interface for repositories using mongoOperationsPlugin
|
|
230
|
+
*
|
|
231
|
+
* Use this interface to get TypeScript autocomplete and type safety
|
|
232
|
+
* for the methods added by mongoOperationsPlugin.
|
|
233
|
+
*
|
|
234
|
+
* @example
|
|
235
|
+
* ```typescript
|
|
236
|
+
* import { Repository, mongoOperationsPlugin, methodRegistryPlugin } from '@classytic/mongokit';
|
|
237
|
+
* import type { MongoOperationsMethods } from '@classytic/mongokit';
|
|
238
|
+
*
|
|
239
|
+
* // Without type safety (base is flexible)
|
|
240
|
+
* class ProductRepo extends Repository<IProduct> {
|
|
241
|
+
* // Can add anything - fully flexible
|
|
242
|
+
* }
|
|
243
|
+
*
|
|
244
|
+
* // With type safety for plugin methods
|
|
245
|
+
* class ProductRepo extends Repository<IProduct> implements MongoOperationsMethods<IProduct> {
|
|
246
|
+
* // TypeScript knows about upsert, increment, decrement, etc.
|
|
247
|
+
* }
|
|
248
|
+
*
|
|
249
|
+
* const repo = new ProductRepo(ProductModel, [
|
|
250
|
+
* methodRegistryPlugin(),
|
|
251
|
+
* mongoOperationsPlugin(),
|
|
252
|
+
* ]);
|
|
253
|
+
*
|
|
254
|
+
* // Now TypeScript provides autocomplete and type checking
|
|
255
|
+
* await repo.increment(productId, 'views', 1);
|
|
256
|
+
* await repo.upsert({ sku: 'ABC' }, { name: 'Product' });
|
|
257
|
+
* ```
|
|
258
|
+
*/
|
|
259
|
+
interface MongoOperationsMethods<TDoc> {
|
|
260
|
+
/**
|
|
261
|
+
* Update existing document or insert new one
|
|
262
|
+
* @param query - Query to find document
|
|
263
|
+
* @param data - Data to update or insert
|
|
264
|
+
* @param options - Operation options (session, etc.)
|
|
265
|
+
* @returns Created or updated document
|
|
266
|
+
*/
|
|
267
|
+
upsert(query: Record<string, unknown>, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<TDoc>;
|
|
268
|
+
/**
|
|
269
|
+
* Atomically increment numeric field
|
|
270
|
+
* @param id - Document ID
|
|
271
|
+
* @param field - Field name to increment
|
|
272
|
+
* @param value - Value to increment by (default: 1)
|
|
273
|
+
* @param options - Operation options (session, etc.)
|
|
274
|
+
* @returns Updated document
|
|
275
|
+
*/
|
|
276
|
+
increment(id: string | ObjectId, field: string, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
|
|
277
|
+
/**
|
|
278
|
+
* Atomically decrement numeric field
|
|
279
|
+
* @param id - Document ID
|
|
280
|
+
* @param field - Field name to decrement
|
|
281
|
+
* @param value - Value to decrement by (default: 1)
|
|
282
|
+
* @param options - Operation options (session, etc.)
|
|
283
|
+
* @returns Updated document
|
|
284
|
+
*/
|
|
285
|
+
decrement(id: string | ObjectId, field: string, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
|
|
286
|
+
/**
|
|
287
|
+
* Push value to array field
|
|
288
|
+
* @param id - Document ID
|
|
289
|
+
* @param field - Array field name
|
|
290
|
+
* @param value - Value to push
|
|
291
|
+
* @param options - Operation options (session, etc.)
|
|
292
|
+
* @returns Updated document
|
|
293
|
+
*/
|
|
294
|
+
pushToArray(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
295
|
+
/**
|
|
296
|
+
* Remove value from array field
|
|
297
|
+
* @param id - Document ID
|
|
298
|
+
* @param field - Array field name
|
|
299
|
+
* @param value - Value to remove
|
|
300
|
+
* @param options - Operation options (session, etc.)
|
|
301
|
+
* @returns Updated document
|
|
302
|
+
*/
|
|
303
|
+
pullFromArray(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
304
|
+
/**
|
|
305
|
+
* Add value to array only if not already present (unique)
|
|
306
|
+
* @param id - Document ID
|
|
307
|
+
* @param field - Array field name
|
|
308
|
+
* @param value - Value to add
|
|
309
|
+
* @param options - Operation options (session, etc.)
|
|
310
|
+
* @returns Updated document
|
|
311
|
+
*/
|
|
312
|
+
addToSet(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
313
|
+
/**
|
|
314
|
+
* Set field value (alias for update with $set)
|
|
315
|
+
* @param id - Document ID
|
|
316
|
+
* @param field - Field name
|
|
317
|
+
* @param value - Value to set
|
|
318
|
+
* @param options - Operation options (session, etc.)
|
|
319
|
+
* @returns Updated document
|
|
320
|
+
*/
|
|
321
|
+
setField(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
322
|
+
/**
|
|
323
|
+
* Unset (remove) field from document
|
|
324
|
+
* @param id - Document ID
|
|
325
|
+
* @param fields - Field name or array of field names to remove
|
|
326
|
+
* @param options - Operation options (session, etc.)
|
|
327
|
+
* @returns Updated document
|
|
328
|
+
*/
|
|
329
|
+
unsetField(id: string | ObjectId, fields: string | string[], options?: Record<string, unknown>): Promise<TDoc>;
|
|
330
|
+
/**
|
|
331
|
+
* Rename field in document
|
|
332
|
+
* @param id - Document ID
|
|
333
|
+
* @param oldName - Current field name
|
|
334
|
+
* @param newName - New field name
|
|
335
|
+
* @param options - Operation options (session, etc.)
|
|
336
|
+
* @returns Updated document
|
|
337
|
+
*/
|
|
338
|
+
renameField(id: string | ObjectId, oldName: string, newName: string, options?: Record<string, unknown>): Promise<TDoc>;
|
|
339
|
+
/**
|
|
340
|
+
* Multiply numeric field by value
|
|
341
|
+
* @param id - Document ID
|
|
342
|
+
* @param field - Field name
|
|
343
|
+
* @param multiplier - Multiplier value
|
|
344
|
+
* @param options - Operation options (session, etc.)
|
|
345
|
+
* @returns Updated document
|
|
346
|
+
*/
|
|
347
|
+
multiplyField(id: string | ObjectId, field: string, multiplier: number, options?: Record<string, unknown>): Promise<TDoc>;
|
|
348
|
+
/**
|
|
349
|
+
* Set field to minimum value (only if current value is greater)
|
|
350
|
+
* @param id - Document ID
|
|
351
|
+
* @param field - Field name
|
|
352
|
+
* @param value - Minimum value
|
|
353
|
+
* @param options - Operation options (session, etc.)
|
|
354
|
+
* @returns Updated document
|
|
355
|
+
*/
|
|
356
|
+
setMin(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
357
|
+
/**
|
|
358
|
+
* Set field to maximum value (only if current value is less)
|
|
359
|
+
* @param id - Document ID
|
|
360
|
+
* @param field - Field name
|
|
361
|
+
* @param value - Maximum value
|
|
362
|
+
* @param options - Operation options (session, etc.)
|
|
363
|
+
* @returns Updated document
|
|
364
|
+
*/
|
|
365
|
+
setMax(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
366
|
+
}
|
|
367
|
+
//#endregion
|
|
368
|
+
//#region src/plugins/batch-operations.plugin.d.ts
|
|
369
|
+
/**
|
|
370
|
+
* Batch operations plugin
|
|
371
|
+
*
|
|
372
|
+
* @example
|
|
373
|
+
* const repo = new Repository(Model, [
|
|
374
|
+
* methodRegistryPlugin(),
|
|
375
|
+
* batchOperationsPlugin(),
|
|
376
|
+
* ]);
|
|
377
|
+
*
|
|
378
|
+
* await repo.updateMany({ status: 'pending' }, { status: 'active' });
|
|
379
|
+
* await repo.deleteMany({ status: 'deleted' });
|
|
380
|
+
*/
|
|
381
|
+
declare function batchOperationsPlugin(): Plugin;
|
|
382
|
+
/**
|
|
383
|
+
* Type interface for repositories using batchOperationsPlugin
|
|
384
|
+
*
|
|
385
|
+
* @example
|
|
386
|
+
* ```typescript
|
|
387
|
+
* import { Repository, methodRegistryPlugin, batchOperationsPlugin } from '@classytic/mongokit';
|
|
388
|
+
* import type { BatchOperationsMethods } from '@classytic/mongokit';
|
|
389
|
+
*
|
|
390
|
+
* class ProductRepo extends Repository<IProduct> {}
|
|
391
|
+
*
|
|
392
|
+
* type ProductRepoWithBatch = ProductRepo & BatchOperationsMethods;
|
|
393
|
+
*
|
|
394
|
+
* const repo = new ProductRepo(ProductModel, [
|
|
395
|
+
* methodRegistryPlugin(),
|
|
396
|
+
* batchOperationsPlugin(),
|
|
397
|
+
* ]) as ProductRepoWithBatch;
|
|
398
|
+
*
|
|
399
|
+
* // TypeScript autocomplete works!
|
|
400
|
+
* await repo.updateMany({ status: 'pending' }, { status: 'active' });
|
|
401
|
+
* await repo.deleteMany({ status: 'archived' });
|
|
402
|
+
* ```
|
|
403
|
+
*/
|
|
404
|
+
interface BatchOperationsMethods {
|
|
405
|
+
/**
|
|
406
|
+
* Update multiple documents matching the query
|
|
407
|
+
* @param query - Query to match documents
|
|
408
|
+
* @param data - Update data
|
|
409
|
+
* @param options - Operation options
|
|
410
|
+
* @returns Update result with matchedCount, modifiedCount, etc.
|
|
411
|
+
*/
|
|
412
|
+
updateMany(query: Record<string, unknown>, data: Record<string, unknown>, options?: {
|
|
413
|
+
session?: ClientSession;
|
|
414
|
+
updatePipeline?: boolean;
|
|
415
|
+
}): Promise<{
|
|
416
|
+
acknowledged: boolean;
|
|
417
|
+
matchedCount: number;
|
|
418
|
+
modifiedCount: number;
|
|
419
|
+
upsertedCount: number;
|
|
420
|
+
upsertedId: unknown;
|
|
421
|
+
}>;
|
|
422
|
+
/**
|
|
423
|
+
* Delete multiple documents matching the query
|
|
424
|
+
* @param query - Query to match documents
|
|
425
|
+
* @param options - Operation options
|
|
426
|
+
* @returns Delete result with deletedCount
|
|
427
|
+
*/
|
|
428
|
+
deleteMany(query: Record<string, unknown>, options?: Record<string, unknown>): Promise<{
|
|
429
|
+
acknowledged: boolean;
|
|
430
|
+
deletedCount: number;
|
|
431
|
+
}>;
|
|
432
|
+
}
|
|
433
|
+
//#endregion
|
|
434
|
+
//#region src/plugins/aggregate-helpers.plugin.d.ts
|
|
435
|
+
/**
|
|
436
|
+
* Aggregate helpers plugin
|
|
437
|
+
*
|
|
438
|
+
* @example
|
|
439
|
+
* const repo = new Repository(Model, [
|
|
440
|
+
* methodRegistryPlugin(),
|
|
441
|
+
* aggregateHelpersPlugin(),
|
|
442
|
+
* ]);
|
|
443
|
+
*
|
|
444
|
+
* const groups = await repo.groupBy('category');
|
|
445
|
+
* const total = await repo.sum('amount', { status: 'completed' });
|
|
446
|
+
*/
|
|
447
|
+
declare function aggregateHelpersPlugin(): Plugin;
|
|
448
|
+
/**
|
|
449
|
+
* Type interface for repositories using aggregateHelpersPlugin
|
|
450
|
+
*
|
|
451
|
+
* @example
|
|
452
|
+
* ```typescript
|
|
453
|
+
* import { Repository, methodRegistryPlugin, aggregateHelpersPlugin } from '@classytic/mongokit';
|
|
454
|
+
* import type { AggregateHelpersMethods } from '@classytic/mongokit';
|
|
455
|
+
*
|
|
456
|
+
* class OrderRepo extends Repository<IOrder> {}
|
|
457
|
+
*
|
|
458
|
+
* type OrderRepoWithAggregates = OrderRepo & AggregateHelpersMethods;
|
|
459
|
+
*
|
|
460
|
+
* const repo = new OrderRepo(OrderModel, [
|
|
461
|
+
* methodRegistryPlugin(),
|
|
462
|
+
* aggregateHelpersPlugin(),
|
|
463
|
+
* ]) as OrderRepoWithAggregates;
|
|
464
|
+
*
|
|
465
|
+
* // TypeScript autocomplete works!
|
|
466
|
+
* const groups = await repo.groupBy('status');
|
|
467
|
+
* const total = await repo.sum('amount', { status: 'completed' });
|
|
468
|
+
* const avg = await repo.average('amount');
|
|
469
|
+
* ```
|
|
470
|
+
*/
|
|
471
|
+
interface AggregateHelpersMethods {
|
|
472
|
+
/**
|
|
473
|
+
* Group documents by field value and count occurrences
|
|
474
|
+
* @param field - Field to group by
|
|
475
|
+
* @param options - Operation options
|
|
476
|
+
* @returns Array of groups with _id and count
|
|
477
|
+
*/
|
|
478
|
+
groupBy(field: string, options?: {
|
|
479
|
+
limit?: number;
|
|
480
|
+
session?: unknown;
|
|
481
|
+
}): Promise<Array<{
|
|
482
|
+
_id: unknown;
|
|
483
|
+
count: number;
|
|
484
|
+
}>>;
|
|
485
|
+
/**
|
|
486
|
+
* Calculate sum of field values
|
|
487
|
+
* @param field - Field to sum
|
|
488
|
+
* @param query - Filter query
|
|
489
|
+
* @param options - Operation options
|
|
490
|
+
* @returns Sum of field values
|
|
491
|
+
*/
|
|
492
|
+
sum(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
493
|
+
/**
|
|
494
|
+
* Calculate average of field values
|
|
495
|
+
* @param field - Field to average
|
|
496
|
+
* @param query - Filter query
|
|
497
|
+
* @param options - Operation options
|
|
498
|
+
* @returns Average of field values
|
|
499
|
+
*/
|
|
500
|
+
average(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
501
|
+
/**
|
|
502
|
+
* Get minimum field value
|
|
503
|
+
* @param field - Field to get minimum from
|
|
504
|
+
* @param query - Filter query
|
|
505
|
+
* @param options - Operation options
|
|
506
|
+
* @returns Minimum field value
|
|
507
|
+
*/
|
|
508
|
+
min(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
509
|
+
/**
|
|
510
|
+
* Get maximum field value
|
|
511
|
+
* @param field - Field to get maximum from
|
|
512
|
+
* @param query - Filter query
|
|
513
|
+
* @param options - Operation options
|
|
514
|
+
* @returns Maximum field value
|
|
515
|
+
*/
|
|
516
|
+
max(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
517
|
+
}
|
|
518
|
+
//#endregion
|
|
519
|
+
//#region src/plugins/subdocument.plugin.d.ts
|
|
520
|
+
/**
|
|
521
|
+
* Subdocument plugin for managing nested arrays
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* const repo = new Repository(Model, [
|
|
525
|
+
* methodRegistryPlugin(),
|
|
526
|
+
* subdocumentPlugin(),
|
|
527
|
+
* ]);
|
|
528
|
+
*
|
|
529
|
+
* await repo.addSubdocument(parentId, 'items', { name: 'Item 1' });
|
|
530
|
+
* await repo.updateSubdocument(parentId, 'items', itemId, { name: 'Updated Item' });
|
|
531
|
+
*/
|
|
532
|
+
declare function subdocumentPlugin(): Plugin;
|
|
533
|
+
/**
|
|
534
|
+
* Type interface for repositories using subdocumentPlugin
|
|
535
|
+
*
|
|
536
|
+
* @example
|
|
537
|
+
* ```typescript
|
|
538
|
+
* import { Repository, methodRegistryPlugin, subdocumentPlugin } from '@classytic/mongokit';
|
|
539
|
+
* import type { SubdocumentMethods } from '@classytic/mongokit';
|
|
540
|
+
*
|
|
541
|
+
* class OrderRepo extends Repository<IOrder> {}
|
|
542
|
+
*
|
|
543
|
+
* type OrderRepoWithSubdocs = OrderRepo & SubdocumentMethods<IOrder>;
|
|
544
|
+
*
|
|
545
|
+
* const repo = new OrderRepo(OrderModel, [
|
|
546
|
+
* methodRegistryPlugin(),
|
|
547
|
+
* subdocumentPlugin(),
|
|
548
|
+
* ]) as OrderRepoWithSubdocs;
|
|
549
|
+
*
|
|
550
|
+
* // TypeScript autocomplete works!
|
|
551
|
+
* await repo.addSubdocument(orderId, 'items', { productId: '123', quantity: 2 });
|
|
552
|
+
* await repo.updateSubdocument(orderId, 'items', itemId, { quantity: 5 });
|
|
553
|
+
* await repo.deleteSubdocument(orderId, 'items', itemId);
|
|
554
|
+
* ```
|
|
555
|
+
*/
|
|
556
|
+
interface SubdocumentMethods<TDoc> {
|
|
557
|
+
/**
|
|
558
|
+
* Add subdocument to array field
|
|
559
|
+
* @param parentId - Parent document ID
|
|
560
|
+
* @param arrayPath - Path to array field (e.g., 'items', 'addresses')
|
|
561
|
+
* @param subData - Subdocument data
|
|
562
|
+
* @param options - Operation options
|
|
563
|
+
* @returns Updated parent document
|
|
564
|
+
*/
|
|
565
|
+
addSubdocument(parentId: string | ObjectId, arrayPath: string, subData: Record<string, unknown>, options?: Record<string, unknown>): Promise<TDoc>;
|
|
566
|
+
/**
|
|
567
|
+
* Get subdocument from array field
|
|
568
|
+
* @param parentId - Parent document ID
|
|
569
|
+
* @param arrayPath - Path to array field
|
|
570
|
+
* @param subId - Subdocument ID
|
|
571
|
+
* @param options - Operation options
|
|
572
|
+
* @returns Subdocument
|
|
573
|
+
*/
|
|
574
|
+
getSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: {
|
|
575
|
+
lean?: boolean;
|
|
576
|
+
session?: unknown;
|
|
577
|
+
}): Promise<Record<string, unknown>>;
|
|
578
|
+
/**
|
|
579
|
+
* Update subdocument in array field
|
|
580
|
+
* @param parentId - Parent document ID
|
|
581
|
+
* @param arrayPath - Path to array field
|
|
582
|
+
* @param subId - Subdocument ID
|
|
583
|
+
* @param updateData - Update data
|
|
584
|
+
* @param options - Operation options
|
|
585
|
+
* @returns Updated parent document
|
|
586
|
+
*/
|
|
587
|
+
updateSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, updateData: Record<string, unknown>, options?: {
|
|
588
|
+
session?: unknown;
|
|
589
|
+
}): Promise<TDoc>;
|
|
590
|
+
/**
|
|
591
|
+
* Delete subdocument from array field
|
|
592
|
+
* @param parentId - Parent document ID
|
|
593
|
+
* @param arrayPath - Path to array field
|
|
594
|
+
* @param subId - Subdocument ID
|
|
595
|
+
* @param options - Operation options
|
|
596
|
+
* @returns Updated parent document
|
|
597
|
+
*/
|
|
598
|
+
deleteSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: Record<string, unknown>): Promise<TDoc>;
|
|
599
|
+
}
|
|
600
|
+
//#endregion
|
|
601
|
+
//#region src/plugins/cache.plugin.d.ts
|
|
602
|
+
/**
|
|
603
|
+
* Cache plugin factory
|
|
604
|
+
*
|
|
605
|
+
* @param options - Cache configuration
|
|
606
|
+
* @returns Plugin instance
|
|
607
|
+
*/
|
|
608
|
+
declare function cachePlugin(options: CacheOptions): Plugin;
|
|
609
|
+
/**
|
|
610
|
+
* TypeScript interface for cache plugin methods
|
|
611
|
+
*
|
|
612
|
+
* @example
|
|
613
|
+
* ```typescript
|
|
614
|
+
* import type { CacheMethods } from '@classytic/mongokit';
|
|
615
|
+
*
|
|
616
|
+
* type ProductRepoWithCache = ProductRepo & CacheMethods;
|
|
617
|
+
*
|
|
618
|
+
* const productRepo = new ProductRepo(ProductModel, [
|
|
619
|
+
* methodRegistryPlugin(),
|
|
620
|
+
* cachePlugin({ adapter: redisAdapter, ttl: 60 }),
|
|
621
|
+
* ]) as ProductRepoWithCache;
|
|
622
|
+
*
|
|
623
|
+
* // TypeScript autocomplete for cache methods
|
|
624
|
+
* await productRepo.invalidateCache(productId);
|
|
625
|
+
* await productRepo.invalidateListCache();
|
|
626
|
+
* await productRepo.invalidateAllCache();
|
|
627
|
+
* const stats = productRepo.getCacheStats();
|
|
628
|
+
* productRepo.resetCacheStats();
|
|
629
|
+
* ```
|
|
630
|
+
*/
|
|
631
|
+
interface CacheMethods {
|
|
632
|
+
/**
|
|
633
|
+
* Invalidate cache for a specific document
|
|
634
|
+
* Use when document was updated outside this service
|
|
635
|
+
* @param id - Document ID to invalidate
|
|
636
|
+
*/
|
|
637
|
+
invalidateCache(id: string): Promise<void>;
|
|
638
|
+
/**
|
|
639
|
+
* Invalidate all list caches for this model
|
|
640
|
+
* Use when bulk changes happened outside this service
|
|
641
|
+
*/
|
|
642
|
+
invalidateListCache(): Promise<void>;
|
|
643
|
+
/**
|
|
644
|
+
* Invalidate ALL cache entries for this model
|
|
645
|
+
* Nuclear option - use sparingly
|
|
646
|
+
*/
|
|
647
|
+
invalidateAllCache(): Promise<void>;
|
|
648
|
+
/**
|
|
649
|
+
* Get cache statistics for monitoring
|
|
650
|
+
* @returns Cache statistics (hits, misses, sets, invalidations)
|
|
651
|
+
*/
|
|
652
|
+
getCacheStats(): CacheStats;
|
|
653
|
+
/**
|
|
654
|
+
* Reset cache statistics
|
|
655
|
+
*/
|
|
656
|
+
resetCacheStats(): void;
|
|
657
|
+
}
|
|
658
|
+
//#endregion
|
|
659
|
+
//#region src/plugins/cascade.plugin.d.ts
|
|
660
|
+
/**
|
|
661
|
+
* Cascade delete plugin
|
|
662
|
+
*
|
|
663
|
+
* Deletes related documents after the parent document is deleted.
|
|
664
|
+
* Works with both hard delete and soft delete scenarios.
|
|
665
|
+
*
|
|
666
|
+
* @param options - Cascade configuration
|
|
667
|
+
* @returns Plugin
|
|
668
|
+
*/
|
|
669
|
+
declare function cascadePlugin(options: CascadeOptions): Plugin;
|
|
670
|
+
//#endregion
|
|
671
|
+
//#region src/plugins/multi-tenant.plugin.d.ts
|
|
672
|
+
interface MultiTenantOptions {
|
|
673
|
+
/** Field name used for tenant isolation (default: 'organizationId') */
|
|
674
|
+
tenantField?: string;
|
|
675
|
+
/** Context key to read tenant ID from (default: 'organizationId') */
|
|
676
|
+
contextKey?: string;
|
|
677
|
+
/** Throw if tenant ID is missing from context (default: true) */
|
|
678
|
+
required?: boolean;
|
|
679
|
+
/** Operations to skip tenant injection (e.g., for admin/system queries) */
|
|
680
|
+
skipOperations?: string[];
|
|
681
|
+
/**
|
|
682
|
+
* Dynamic skip — receives the context and operation name, returns true to
|
|
683
|
+
* bypass tenant scoping for this call. Use for role-based bypass (e.g.,
|
|
684
|
+
* super admin) without needing a separate repo instance.
|
|
685
|
+
*
|
|
686
|
+
* @example
|
|
687
|
+
* ```typescript
|
|
688
|
+
* skipWhen: (context) => context.role === 'superadmin'
|
|
689
|
+
* ```
|
|
690
|
+
*/
|
|
691
|
+
skipWhen?: (context: RepositoryContext, operation: string) => boolean;
|
|
692
|
+
/**
|
|
693
|
+
* Resolve tenant ID from external source (e.g., AsyncLocalStorage, CLS).
|
|
694
|
+
* Called when tenant ID is not found in context. If it returns a value,
|
|
695
|
+
* that value is used as the tenant ID without requiring it in context.
|
|
696
|
+
*
|
|
697
|
+
* @example
|
|
698
|
+
* ```typescript
|
|
699
|
+
* resolveContext: () => asyncLocalStorage.getStore()?.tenantId
|
|
700
|
+
* ```
|
|
701
|
+
*/
|
|
702
|
+
resolveContext?: () => string | undefined;
|
|
703
|
+
}
|
|
704
|
+
declare function multiTenantPlugin(options?: MultiTenantOptions): Plugin;
|
|
705
|
+
//#endregion
|
|
706
|
+
//#region src/plugins/observability.plugin.d.ts
|
|
707
|
+
interface OperationMetric {
|
|
708
|
+
/** Operation name (e.g., 'create', 'getAll', 'update') */
|
|
709
|
+
operation: string;
|
|
710
|
+
/** Model/collection name */
|
|
711
|
+
model: string;
|
|
712
|
+
/** Duration in milliseconds */
|
|
713
|
+
durationMs: number;
|
|
714
|
+
/** Whether the operation succeeded */
|
|
715
|
+
success: boolean;
|
|
716
|
+
/** Error message if failed */
|
|
717
|
+
error?: string;
|
|
718
|
+
/** Timestamp when the operation started */
|
|
719
|
+
startedAt: Date;
|
|
720
|
+
/** User ID if available */
|
|
721
|
+
userId?: string;
|
|
722
|
+
/** Organization ID if available */
|
|
723
|
+
organizationId?: string;
|
|
724
|
+
}
|
|
725
|
+
interface ObservabilityOptions {
|
|
726
|
+
/** Callback invoked after every operation with timing data */
|
|
727
|
+
onMetric: (metric: OperationMetric) => void;
|
|
728
|
+
/** Operations to track (default: all) */
|
|
729
|
+
operations?: string[];
|
|
730
|
+
/** Threshold in ms — only report operations slower than this */
|
|
731
|
+
slowThresholdMs?: number;
|
|
732
|
+
}
|
|
733
|
+
declare function observabilityPlugin(options: ObservabilityOptions): Plugin;
|
|
734
|
+
//#endregion
|
|
735
|
+
//#region src/plugins/elastic.plugin.d.ts
|
|
736
|
+
interface ElasticSearchOptions {
|
|
737
|
+
/** Elasticsearch or OpenSearch client instance */
|
|
738
|
+
client: any;
|
|
739
|
+
/** Index name to perform search against */
|
|
740
|
+
index: string;
|
|
741
|
+
/** Field to extract MongoDB ID from the indexed document (default: '_id') */
|
|
742
|
+
idField?: string;
|
|
743
|
+
}
|
|
744
|
+
declare function elasticSearchPlugin(options: ElasticSearchOptions): Plugin;
|
|
745
|
+
//#endregion
|
|
746
|
+
//#region src/plugins/custom-id.plugin.d.ts
|
|
747
|
+
/**
|
|
748
|
+
* Generator function that produces a unique ID.
|
|
749
|
+
* Receives the full repository context for conditional logic.
|
|
750
|
+
*/
|
|
751
|
+
type IdGenerator = (context: RepositoryContext) => string | Promise<string>;
|
|
752
|
+
interface CustomIdOptions {
|
|
753
|
+
/** Field to store the custom ID (default: 'customId') */
|
|
754
|
+
field?: string;
|
|
755
|
+
/** Function to generate the ID. Can be async. */
|
|
756
|
+
generator: IdGenerator;
|
|
757
|
+
/** Only generate if the field is missing/empty (default: true) */
|
|
758
|
+
generateOnlyIfEmpty?: boolean;
|
|
759
|
+
}
|
|
760
|
+
/**
|
|
761
|
+
* Atomically increment and return the next sequence value for a given key.
|
|
762
|
+
* Uses `findOneAndUpdate` with `upsert` + `$inc` — fully atomic even under
|
|
763
|
+
* heavy concurrency.
|
|
764
|
+
*
|
|
765
|
+
* @param counterKey - Unique key identifying this counter (e.g., "Invoice" or "Invoice:2026-02")
|
|
766
|
+
* @param increment - Value to increment by (default: 1)
|
|
767
|
+
* @returns The next sequence number (after increment)
|
|
768
|
+
*
|
|
769
|
+
* @example
|
|
770
|
+
* const seq = await getNextSequence('invoices');
|
|
771
|
+
* // First call → 1, second → 2, ...
|
|
772
|
+
*
|
|
773
|
+
* @example Batch increment for createMany
|
|
774
|
+
* const startSeq = await getNextSequence('invoices', 5);
|
|
775
|
+
* // If current was 10, returns 15 (you use 11, 12, 13, 14, 15)
|
|
776
|
+
*/
|
|
777
|
+
declare function getNextSequence(counterKey: string, increment?: number): Promise<number>;
|
|
778
|
+
interface SequentialIdOptions {
|
|
779
|
+
/** Prefix string (e.g., 'INV', 'ORD') */
|
|
780
|
+
prefix: string;
|
|
781
|
+
/** Mongoose model — used to derive the counter key from model name */
|
|
782
|
+
model: mongoose.Model<any>;
|
|
783
|
+
/** Number of digits to pad to (default: 4 → "0001") */
|
|
784
|
+
padding?: number;
|
|
785
|
+
/** Separator between prefix and number (default: '-') */
|
|
786
|
+
separator?: string;
|
|
787
|
+
/** Custom counter key override (default: model.modelName) */
|
|
788
|
+
counterKey?: string;
|
|
789
|
+
}
|
|
790
|
+
/**
|
|
791
|
+
* Generator: Simple sequential counter.
|
|
792
|
+
* Produces IDs like `INV-0001`, `INV-0002`, etc.
|
|
793
|
+
*
|
|
794
|
+
* Uses atomic MongoDB counters — safe under concurrency.
|
|
795
|
+
*
|
|
796
|
+
* @example
|
|
797
|
+
* ```typescript
|
|
798
|
+
* customIdPlugin({
|
|
799
|
+
* field: 'invoiceNumber',
|
|
800
|
+
* generator: sequentialId({ prefix: 'INV', model: InvoiceModel }),
|
|
801
|
+
* })
|
|
802
|
+
* ```
|
|
803
|
+
*/
|
|
804
|
+
declare function sequentialId(options: SequentialIdOptions): IdGenerator;
|
|
805
|
+
interface DateSequentialIdOptions {
|
|
806
|
+
/** Prefix string (e.g., 'BILL', 'INV') */
|
|
807
|
+
prefix: string;
|
|
808
|
+
/** Mongoose model — used to derive the counter key */
|
|
809
|
+
model: mongoose.Model<any>;
|
|
810
|
+
/**
|
|
811
|
+
* Partition granularity — counter resets each period.
|
|
812
|
+
* - 'yearly' → BILL-2026-0001, resets every January
|
|
813
|
+
* - 'monthly' → BILL-2026-02-0001, resets every month
|
|
814
|
+
* - 'daily' → BILL-2026-02-20-0001, resets every day
|
|
815
|
+
*/
|
|
816
|
+
partition?: 'yearly' | 'monthly' | 'daily';
|
|
817
|
+
/** Number of digits to pad to (default: 4) */
|
|
818
|
+
padding?: number;
|
|
819
|
+
/** Separator (default: '-') */
|
|
820
|
+
separator?: string;
|
|
821
|
+
}
|
|
822
|
+
/**
|
|
823
|
+
* Generator: Date-partitioned sequential counter.
|
|
824
|
+
* Counter resets per period — great for invoice/bill numbering.
|
|
825
|
+
*
|
|
826
|
+
* Produces IDs like:
|
|
827
|
+
* - yearly: `BILL-2026-0001`
|
|
828
|
+
* - monthly: `BILL-2026-02-0001`
|
|
829
|
+
* - daily: `BILL-2026-02-20-0001`
|
|
830
|
+
*
|
|
831
|
+
* @example
|
|
832
|
+
* ```typescript
|
|
833
|
+
* customIdPlugin({
|
|
834
|
+
* field: 'billNumber',
|
|
835
|
+
* generator: dateSequentialId({
|
|
836
|
+
* prefix: 'BILL',
|
|
837
|
+
* model: BillModel,
|
|
838
|
+
* partition: 'monthly',
|
|
839
|
+
* }),
|
|
840
|
+
* })
|
|
841
|
+
* ```
|
|
842
|
+
*/
|
|
843
|
+
declare function dateSequentialId(options: DateSequentialIdOptions): IdGenerator;
|
|
844
|
+
interface PrefixedIdOptions {
|
|
845
|
+
/** Prefix string (e.g., 'USR', 'TXN') */
|
|
846
|
+
prefix: string;
|
|
847
|
+
/** Separator (default: '_') */
|
|
848
|
+
separator?: string;
|
|
849
|
+
/** Length of the random suffix (default: 12) */
|
|
850
|
+
length?: number;
|
|
851
|
+
}
|
|
852
|
+
/**
|
|
853
|
+
* Generator: Prefix + random alphanumeric suffix.
|
|
854
|
+
* Does NOT require a database round-trip — purely in-memory.
|
|
855
|
+
*
|
|
856
|
+
* Produces IDs like: `USR_a7b3xk9m2p1q`
|
|
857
|
+
*
|
|
858
|
+
* Good for: user-facing IDs where ordering doesn't matter.
|
|
859
|
+
* Not suitable for sequential numbering.
|
|
860
|
+
*
|
|
861
|
+
* @example
|
|
862
|
+
* ```typescript
|
|
863
|
+
* customIdPlugin({
|
|
864
|
+
* field: 'publicId',
|
|
865
|
+
* generator: prefixedId({ prefix: 'USR', length: 10 }),
|
|
866
|
+
* })
|
|
867
|
+
* ```
|
|
868
|
+
*/
|
|
869
|
+
declare function prefixedId(options: PrefixedIdOptions): IdGenerator;
|
|
870
|
+
/**
|
|
871
|
+
* Custom ID plugin — injects generated IDs into documents before creation.
|
|
872
|
+
*
|
|
873
|
+
* @param options - Configuration for ID generation
|
|
874
|
+
* @returns Plugin instance
|
|
875
|
+
*
|
|
876
|
+
* @example
|
|
877
|
+
* ```typescript
|
|
878
|
+
* import { Repository, customIdPlugin, sequentialId } from '@classytic/mongokit';
|
|
879
|
+
*
|
|
880
|
+
* const invoiceRepo = new Repository(InvoiceModel, [
|
|
881
|
+
* customIdPlugin({
|
|
882
|
+
* field: 'invoiceNumber',
|
|
883
|
+
* generator: sequentialId({ prefix: 'INV', model: InvoiceModel }),
|
|
884
|
+
* }),
|
|
885
|
+
* ]);
|
|
886
|
+
*
|
|
887
|
+
* const inv = await invoiceRepo.create({ amount: 100 });
|
|
888
|
+
* console.log(inv.invoiceNumber); // "INV-0001"
|
|
889
|
+
* ```
|
|
890
|
+
*/
|
|
891
|
+
declare function customIdPlugin(options: CustomIdOptions): Plugin;
|
|
892
|
+
//#endregion
|
|
893
|
+
export { blockIf as A, timestampPlugin as B, AggregateHelpersMethods as C, MongoOperationsMethods as D, batchOperationsPlugin as E, MethodRegistryRepository as F, methodRegistryPlugin as I, SoftDeleteMethods as L, requireField as M, uniqueField as N, mongoOperationsPlugin as O, validationChainPlugin as P, softDeletePlugin as R, subdocumentPlugin as S, BatchOperationsMethods as T, fieldFilterPlugin as V, multiTenantPlugin as _, SequentialIdOptions as a, cachePlugin as b, getNextSequence as c, ElasticSearchOptions as d, elasticSearchPlugin as f, MultiTenantOptions as g, observabilityPlugin as h, PrefixedIdOptions as i, immutableField as j, autoInject as k, prefixedId as l, OperationMetric as m, DateSequentialIdOptions as n, customIdPlugin as o, ObservabilityOptions as p, IdGenerator as r, dateSequentialId as s, CustomIdOptions as t, sequentialId as u, cascadePlugin as v, aggregateHelpersPlugin as w, SubdocumentMethods as x, CacheMethods as y, auditLogPlugin as z };
|