@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
package/dist/plugins/index.d.ts
DELETED
|
@@ -1,922 +0,0 @@
|
|
|
1
|
-
import { Q as FieldPreset, g as Plugin, a1 as Logger, a2 as SoftDeleteOptions, j as ObjectId, f as SortSpec, S as SelectSpec, e as PopulateSpec, a as OffsetPaginationResult, E as RepositoryInstance, $ as ValidatorDefinition, a0 as ValidationChainOptions, k as RepositoryContext, a8 as CacheOptions, aa as CacheStats, ac as CascadeOptions } from '../types-Jni1KgkP.js';
|
|
2
|
-
import { ClientSession } from 'mongoose';
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Field Filter Plugin
|
|
6
|
-
* Automatically filters response fields based on user roles
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Field filter plugin that restricts fields based on user context
|
|
11
|
-
*
|
|
12
|
-
* @example
|
|
13
|
-
* const fieldPreset = {
|
|
14
|
-
* public: ['id', 'name'],
|
|
15
|
-
* authenticated: ['email'],
|
|
16
|
-
* admin: ['createdAt', 'internalNotes']
|
|
17
|
-
* };
|
|
18
|
-
*
|
|
19
|
-
* const repo = new Repository(Model, [fieldFilterPlugin(fieldPreset)]);
|
|
20
|
-
*/
|
|
21
|
-
declare function fieldFilterPlugin(fieldPreset: FieldPreset): Plugin;
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* Timestamp Plugin
|
|
25
|
-
* Auto-injects createdAt/updatedAt timestamps on create/update
|
|
26
|
-
*/
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Timestamp plugin that auto-injects timestamps
|
|
30
|
-
*
|
|
31
|
-
* @example
|
|
32
|
-
* const repo = new Repository(Model, [timestampPlugin()]);
|
|
33
|
-
*/
|
|
34
|
-
declare function timestampPlugin(): Plugin;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Audit Log Plugin
|
|
38
|
-
* Logs repository operations for auditing purposes
|
|
39
|
-
*/
|
|
40
|
-
|
|
41
|
-
/**
|
|
42
|
-
* Audit log plugin that logs all repository operations
|
|
43
|
-
*
|
|
44
|
-
* @example
|
|
45
|
-
* const repo = new Repository(Model, [auditLogPlugin(console)]);
|
|
46
|
-
*/
|
|
47
|
-
declare function auditLogPlugin(logger: Logger): Plugin;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Soft Delete Plugin
|
|
51
|
-
* Implements soft delete pattern - marks documents as deleted instead of removing
|
|
52
|
-
*/
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Soft delete plugin
|
|
56
|
-
*
|
|
57
|
-
* @example Basic usage
|
|
58
|
-
* ```typescript
|
|
59
|
-
* const repo = new Repository(Model, [
|
|
60
|
-
* softDeletePlugin({ deletedField: 'deletedAt' })
|
|
61
|
-
* ]);
|
|
62
|
-
*
|
|
63
|
-
* // Delete (soft)
|
|
64
|
-
* await repo.delete(id);
|
|
65
|
-
*
|
|
66
|
-
* // Restore
|
|
67
|
-
* await repo.restore(id);
|
|
68
|
-
*
|
|
69
|
-
* // Get deleted documents
|
|
70
|
-
* await repo.getDeleted({ page: 1, limit: 20 });
|
|
71
|
-
* ```
|
|
72
|
-
*
|
|
73
|
-
* @example With null filter mode (for schemas with default: null)
|
|
74
|
-
* ```typescript
|
|
75
|
-
* // Schema: { deletedAt: { type: Date, default: null } }
|
|
76
|
-
* const repo = new Repository(Model, [
|
|
77
|
-
* softDeletePlugin({
|
|
78
|
-
* deletedField: 'deletedAt',
|
|
79
|
-
* filterMode: 'null', // default - works with default: null
|
|
80
|
-
* })
|
|
81
|
-
* ]);
|
|
82
|
-
* ```
|
|
83
|
-
*
|
|
84
|
-
* @example With TTL for auto-cleanup
|
|
85
|
-
* ```typescript
|
|
86
|
-
* const repo = new Repository(Model, [
|
|
87
|
-
* softDeletePlugin({
|
|
88
|
-
* deletedField: 'deletedAt',
|
|
89
|
-
* ttlDays: 30, // Auto-delete after 30 days
|
|
90
|
-
* })
|
|
91
|
-
* ]);
|
|
92
|
-
* ```
|
|
93
|
-
*/
|
|
94
|
-
declare function softDeletePlugin(options?: SoftDeleteOptions): Plugin;
|
|
95
|
-
/**
|
|
96
|
-
* TypeScript interface for soft delete plugin methods
|
|
97
|
-
*
|
|
98
|
-
* @example
|
|
99
|
-
* ```typescript
|
|
100
|
-
* import type { SoftDeleteMethods } from '@classytic/mongokit';
|
|
101
|
-
*
|
|
102
|
-
* type UserRepoWithSoftDelete = UserRepo & SoftDeleteMethods<IUser>;
|
|
103
|
-
*
|
|
104
|
-
* const userRepo = new UserRepo(UserModel, [
|
|
105
|
-
* methodRegistryPlugin(),
|
|
106
|
-
* softDeletePlugin({ deletedField: 'deletedAt' }),
|
|
107
|
-
* ]) as UserRepoWithSoftDelete;
|
|
108
|
-
*
|
|
109
|
-
* // TypeScript autocomplete for soft delete methods
|
|
110
|
-
* await userRepo.restore(userId);
|
|
111
|
-
* const deleted = await userRepo.getDeleted({ page: 1, limit: 20 });
|
|
112
|
-
* ```
|
|
113
|
-
*/
|
|
114
|
-
interface SoftDeleteMethods<TDoc> {
|
|
115
|
-
/**
|
|
116
|
-
* Restore a soft-deleted document
|
|
117
|
-
* @param id - Document ID to restore
|
|
118
|
-
* @param options - Optional restore options
|
|
119
|
-
* @returns Restored document
|
|
120
|
-
*/
|
|
121
|
-
restore(id: string | ObjectId, options?: {
|
|
122
|
-
session?: ClientSession;
|
|
123
|
-
}): Promise<TDoc>;
|
|
124
|
-
/**
|
|
125
|
-
* Get paginated list of soft-deleted documents
|
|
126
|
-
* @param params - Query parameters (filters, sort, pagination)
|
|
127
|
-
* @param options - Query options (select, populate, lean, session)
|
|
128
|
-
* @returns Paginated result of deleted documents
|
|
129
|
-
*/
|
|
130
|
-
getDeleted(params?: {
|
|
131
|
-
filters?: Record<string, unknown>;
|
|
132
|
-
sort?: SortSpec | string;
|
|
133
|
-
page?: number;
|
|
134
|
-
limit?: number;
|
|
135
|
-
}, options?: {
|
|
136
|
-
select?: SelectSpec;
|
|
137
|
-
populate?: PopulateSpec;
|
|
138
|
-
lean?: boolean;
|
|
139
|
-
session?: ClientSession;
|
|
140
|
-
}): Promise<OffsetPaginationResult<TDoc>>;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Method Registry Plugin
|
|
145
|
-
*
|
|
146
|
-
* Enables plugins to dynamically add methods to repository instances.
|
|
147
|
-
* Foundation for extensibility - allows other plugins to extend repositories
|
|
148
|
-
* with custom methods while maintaining type safety and proper binding.
|
|
149
|
-
*
|
|
150
|
-
* @example
|
|
151
|
-
* ```typescript
|
|
152
|
-
* const repo = new Repository(User, [methodRegistryPlugin()]);
|
|
153
|
-
*
|
|
154
|
-
* // Now you can register custom methods
|
|
155
|
-
* repo.registerMethod('findActive', async function() {
|
|
156
|
-
* return this.getAll({ filters: { status: 'active' } });
|
|
157
|
-
* });
|
|
158
|
-
* ```
|
|
159
|
-
*/
|
|
160
|
-
|
|
161
|
-
/**
|
|
162
|
-
* Extended repository interface with method registry
|
|
163
|
-
*/
|
|
164
|
-
interface MethodRegistryRepository extends RepositoryInstance {
|
|
165
|
-
registerMethod(name: string, fn: Function): void;
|
|
166
|
-
hasMethod(name: string): boolean;
|
|
167
|
-
getRegisteredMethods(): string[];
|
|
168
|
-
}
|
|
169
|
-
/**
|
|
170
|
-
* Method registry plugin that enables dynamic method registration
|
|
171
|
-
*/
|
|
172
|
-
declare function methodRegistryPlugin(): Plugin;
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Validation Chain Plugin
|
|
176
|
-
*
|
|
177
|
-
* Composable validation for repository operations with customizable rules.
|
|
178
|
-
*/
|
|
179
|
-
|
|
180
|
-
type OperationType = 'create' | 'createMany' | 'update' | 'delete';
|
|
181
|
-
/**
|
|
182
|
-
* Validation chain plugin
|
|
183
|
-
*
|
|
184
|
-
* @example
|
|
185
|
-
* const repo = new Repository(Model, [
|
|
186
|
-
* validationChainPlugin([
|
|
187
|
-
* requireField('email'),
|
|
188
|
-
* uniqueField('email', 'Email already exists'),
|
|
189
|
-
* blockIf('no-delete-admin', ['delete'], ctx => ctx.data?.role === 'admin', 'Cannot delete admin'),
|
|
190
|
-
* ])
|
|
191
|
-
* ]);
|
|
192
|
-
*/
|
|
193
|
-
declare function validationChainPlugin(validators?: ValidatorDefinition[], options?: ValidationChainOptions): Plugin;
|
|
194
|
-
/**
|
|
195
|
-
* Block operation if condition is true
|
|
196
|
-
*
|
|
197
|
-
* @example
|
|
198
|
-
* blockIf('block-library', ['delete'], ctx => ctx.data?.managed, 'Cannot delete managed records')
|
|
199
|
-
*/
|
|
200
|
-
declare function blockIf(name: string, operations: OperationType[], condition: (context: RepositoryContext) => boolean, errorMessage: string): ValidatorDefinition;
|
|
201
|
-
/**
|
|
202
|
-
* Require a field to be present
|
|
203
|
-
*/
|
|
204
|
-
declare function requireField(field: string, operations?: OperationType[]): ValidatorDefinition;
|
|
205
|
-
/**
|
|
206
|
-
* Auto-inject a value if not present
|
|
207
|
-
*/
|
|
208
|
-
declare function autoInject(field: string, getter: (context: RepositoryContext) => unknown, operations?: OperationType[]): ValidatorDefinition;
|
|
209
|
-
/**
|
|
210
|
-
* Make a field immutable (cannot be updated)
|
|
211
|
-
*/
|
|
212
|
-
declare function immutableField(field: string): ValidatorDefinition;
|
|
213
|
-
/**
|
|
214
|
-
* Ensure field value is unique
|
|
215
|
-
*/
|
|
216
|
-
declare function uniqueField(field: string, errorMessage?: string): ValidatorDefinition;
|
|
217
|
-
|
|
218
|
-
/**
|
|
219
|
-
* MongoDB Operations Plugin
|
|
220
|
-
*
|
|
221
|
-
* Adds MongoDB-specific operations to repositories.
|
|
222
|
-
* Requires method-registry.plugin.js to be loaded first.
|
|
223
|
-
*/
|
|
224
|
-
|
|
225
|
-
/**
|
|
226
|
-
* MongoDB operations plugin
|
|
227
|
-
*
|
|
228
|
-
* Adds MongoDB-specific atomic operations to repositories:
|
|
229
|
-
* - upsert: Create or update document
|
|
230
|
-
* - increment/decrement: Atomic numeric operations
|
|
231
|
-
* - pushToArray/pullFromArray/addToSet: Array operations
|
|
232
|
-
* - setField/unsetField/renameField: Field operations
|
|
233
|
-
* - multiplyField: Multiply numeric field
|
|
234
|
-
* - setMin/setMax: Conditional min/max updates
|
|
235
|
-
*
|
|
236
|
-
* @example Basic usage (no TypeScript autocomplete)
|
|
237
|
-
* ```typescript
|
|
238
|
-
* const repo = new Repository(ProductModel, [
|
|
239
|
-
* methodRegistryPlugin(),
|
|
240
|
-
* mongoOperationsPlugin(),
|
|
241
|
-
* ]);
|
|
242
|
-
*
|
|
243
|
-
* // Works at runtime but TypeScript doesn't know about these methods
|
|
244
|
-
* await (repo as any).increment(productId, 'views', 1);
|
|
245
|
-
* await (repo as any).pushToArray(productId, 'tags', 'featured');
|
|
246
|
-
* ```
|
|
247
|
-
*
|
|
248
|
-
* @example With TypeScript type safety (recommended)
|
|
249
|
-
* ```typescript
|
|
250
|
-
* import { Repository, mongoOperationsPlugin, methodRegistryPlugin } from '@classytic/mongokit';
|
|
251
|
-
* import type { MongoOperationsMethods } from '@classytic/mongokit';
|
|
252
|
-
*
|
|
253
|
-
* class ProductRepo extends Repository<IProduct> {
|
|
254
|
-
* // Add your custom methods here
|
|
255
|
-
* }
|
|
256
|
-
*
|
|
257
|
-
* // Create with type assertion to get autocomplete for plugin methods
|
|
258
|
-
* type ProductRepoWithPlugins = ProductRepo & MongoOperationsMethods<IProduct>;
|
|
259
|
-
*
|
|
260
|
-
* const repo = new ProductRepo(ProductModel, [
|
|
261
|
-
* methodRegistryPlugin(),
|
|
262
|
-
* mongoOperationsPlugin(),
|
|
263
|
-
* ]) as ProductRepoWithPlugins;
|
|
264
|
-
*
|
|
265
|
-
* // Now TypeScript provides autocomplete and type checking!
|
|
266
|
-
* await repo.increment(productId, 'views', 1);
|
|
267
|
-
* await repo.upsert({ sku: 'ABC' }, { name: 'Product', price: 99 });
|
|
268
|
-
* await repo.pushToArray(productId, 'tags', 'featured');
|
|
269
|
-
* ```
|
|
270
|
-
*/
|
|
271
|
-
declare function mongoOperationsPlugin(): Plugin;
|
|
272
|
-
/**
|
|
273
|
-
* Type interface for repositories using mongoOperationsPlugin
|
|
274
|
-
*
|
|
275
|
-
* Use this interface to get TypeScript autocomplete and type safety
|
|
276
|
-
* for the methods added by mongoOperationsPlugin.
|
|
277
|
-
*
|
|
278
|
-
* @example
|
|
279
|
-
* ```typescript
|
|
280
|
-
* import { Repository, mongoOperationsPlugin, methodRegistryPlugin } from '@classytic/mongokit';
|
|
281
|
-
* import type { MongoOperationsMethods } from '@classytic/mongokit';
|
|
282
|
-
*
|
|
283
|
-
* // Without type safety (base is flexible)
|
|
284
|
-
* class ProductRepo extends Repository<IProduct> {
|
|
285
|
-
* // Can add anything - fully flexible
|
|
286
|
-
* }
|
|
287
|
-
*
|
|
288
|
-
* // With type safety for plugin methods
|
|
289
|
-
* class ProductRepo extends Repository<IProduct> implements MongoOperationsMethods<IProduct> {
|
|
290
|
-
* // TypeScript knows about upsert, increment, decrement, etc.
|
|
291
|
-
* }
|
|
292
|
-
*
|
|
293
|
-
* const repo = new ProductRepo(ProductModel, [
|
|
294
|
-
* methodRegistryPlugin(),
|
|
295
|
-
* mongoOperationsPlugin(),
|
|
296
|
-
* ]);
|
|
297
|
-
*
|
|
298
|
-
* // Now TypeScript provides autocomplete and type checking
|
|
299
|
-
* await repo.increment(productId, 'views', 1);
|
|
300
|
-
* await repo.upsert({ sku: 'ABC' }, { name: 'Product' });
|
|
301
|
-
* ```
|
|
302
|
-
*/
|
|
303
|
-
interface MongoOperationsMethods<TDoc> {
|
|
304
|
-
/**
|
|
305
|
-
* Update existing document or insert new one
|
|
306
|
-
* @param query - Query to find document
|
|
307
|
-
* @param data - Data to update or insert
|
|
308
|
-
* @param options - Operation options (session, etc.)
|
|
309
|
-
* @returns Created or updated document
|
|
310
|
-
*/
|
|
311
|
-
upsert(query: Record<string, unknown>, data: Record<string, unknown>, options?: Record<string, unknown>): Promise<TDoc>;
|
|
312
|
-
/**
|
|
313
|
-
* Atomically increment numeric field
|
|
314
|
-
* @param id - Document ID
|
|
315
|
-
* @param field - Field name to increment
|
|
316
|
-
* @param value - Value to increment by (default: 1)
|
|
317
|
-
* @param options - Operation options (session, etc.)
|
|
318
|
-
* @returns Updated document
|
|
319
|
-
*/
|
|
320
|
-
increment(id: string | ObjectId, field: string, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
|
|
321
|
-
/**
|
|
322
|
-
* Atomically decrement numeric field
|
|
323
|
-
* @param id - Document ID
|
|
324
|
-
* @param field - Field name to decrement
|
|
325
|
-
* @param value - Value to decrement by (default: 1)
|
|
326
|
-
* @param options - Operation options (session, etc.)
|
|
327
|
-
* @returns Updated document
|
|
328
|
-
*/
|
|
329
|
-
decrement(id: string | ObjectId, field: string, value?: number, options?: Record<string, unknown>): Promise<TDoc>;
|
|
330
|
-
/**
|
|
331
|
-
* Push value to array field
|
|
332
|
-
* @param id - Document ID
|
|
333
|
-
* @param field - Array field name
|
|
334
|
-
* @param value - Value to push
|
|
335
|
-
* @param options - Operation options (session, etc.)
|
|
336
|
-
* @returns Updated document
|
|
337
|
-
*/
|
|
338
|
-
pushToArray(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
339
|
-
/**
|
|
340
|
-
* Remove value from array field
|
|
341
|
-
* @param id - Document ID
|
|
342
|
-
* @param field - Array field name
|
|
343
|
-
* @param value - Value to remove
|
|
344
|
-
* @param options - Operation options (session, etc.)
|
|
345
|
-
* @returns Updated document
|
|
346
|
-
*/
|
|
347
|
-
pullFromArray(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
348
|
-
/**
|
|
349
|
-
* Add value to array only if not already present (unique)
|
|
350
|
-
* @param id - Document ID
|
|
351
|
-
* @param field - Array field name
|
|
352
|
-
* @param value - Value to add
|
|
353
|
-
* @param options - Operation options (session, etc.)
|
|
354
|
-
* @returns Updated document
|
|
355
|
-
*/
|
|
356
|
-
addToSet(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
357
|
-
/**
|
|
358
|
-
* Set field value (alias for update with $set)
|
|
359
|
-
* @param id - Document ID
|
|
360
|
-
* @param field - Field name
|
|
361
|
-
* @param value - Value to set
|
|
362
|
-
* @param options - Operation options (session, etc.)
|
|
363
|
-
* @returns Updated document
|
|
364
|
-
*/
|
|
365
|
-
setField(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
366
|
-
/**
|
|
367
|
-
* Unset (remove) field from document
|
|
368
|
-
* @param id - Document ID
|
|
369
|
-
* @param fields - Field name or array of field names to remove
|
|
370
|
-
* @param options - Operation options (session, etc.)
|
|
371
|
-
* @returns Updated document
|
|
372
|
-
*/
|
|
373
|
-
unsetField(id: string | ObjectId, fields: string | string[], options?: Record<string, unknown>): Promise<TDoc>;
|
|
374
|
-
/**
|
|
375
|
-
* Rename field in document
|
|
376
|
-
* @param id - Document ID
|
|
377
|
-
* @param oldName - Current field name
|
|
378
|
-
* @param newName - New field name
|
|
379
|
-
* @param options - Operation options (session, etc.)
|
|
380
|
-
* @returns Updated document
|
|
381
|
-
*/
|
|
382
|
-
renameField(id: string | ObjectId, oldName: string, newName: string, options?: Record<string, unknown>): Promise<TDoc>;
|
|
383
|
-
/**
|
|
384
|
-
* Multiply numeric field by value
|
|
385
|
-
* @param id - Document ID
|
|
386
|
-
* @param field - Field name
|
|
387
|
-
* @param multiplier - Multiplier value
|
|
388
|
-
* @param options - Operation options (session, etc.)
|
|
389
|
-
* @returns Updated document
|
|
390
|
-
*/
|
|
391
|
-
multiplyField(id: string | ObjectId, field: string, multiplier: number, options?: Record<string, unknown>): Promise<TDoc>;
|
|
392
|
-
/**
|
|
393
|
-
* Set field to minimum value (only if current value is greater)
|
|
394
|
-
* @param id - Document ID
|
|
395
|
-
* @param field - Field name
|
|
396
|
-
* @param value - Minimum value
|
|
397
|
-
* @param options - Operation options (session, etc.)
|
|
398
|
-
* @returns Updated document
|
|
399
|
-
*/
|
|
400
|
-
setMin(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
401
|
-
/**
|
|
402
|
-
* Set field to maximum value (only if current value is less)
|
|
403
|
-
* @param id - Document ID
|
|
404
|
-
* @param field - Field name
|
|
405
|
-
* @param value - Maximum value
|
|
406
|
-
* @param options - Operation options (session, etc.)
|
|
407
|
-
* @returns Updated document
|
|
408
|
-
*/
|
|
409
|
-
setMax(id: string | ObjectId, field: string, value: unknown, options?: Record<string, unknown>): Promise<TDoc>;
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
/**
|
|
413
|
-
* Batch Operations Plugin
|
|
414
|
-
* Adds bulk update/delete operations with proper event emission
|
|
415
|
-
*/
|
|
416
|
-
|
|
417
|
-
/**
|
|
418
|
-
* Batch operations plugin
|
|
419
|
-
*
|
|
420
|
-
* @example
|
|
421
|
-
* const repo = new Repository(Model, [
|
|
422
|
-
* methodRegistryPlugin(),
|
|
423
|
-
* batchOperationsPlugin(),
|
|
424
|
-
* ]);
|
|
425
|
-
*
|
|
426
|
-
* await repo.updateMany({ status: 'pending' }, { status: 'active' });
|
|
427
|
-
* await repo.deleteMany({ status: 'deleted' });
|
|
428
|
-
*/
|
|
429
|
-
declare function batchOperationsPlugin(): Plugin;
|
|
430
|
-
/**
|
|
431
|
-
* Type interface for repositories using batchOperationsPlugin
|
|
432
|
-
*
|
|
433
|
-
* @example
|
|
434
|
-
* ```typescript
|
|
435
|
-
* import { Repository, methodRegistryPlugin, batchOperationsPlugin } from '@classytic/mongokit';
|
|
436
|
-
* import type { BatchOperationsMethods } from '@classytic/mongokit';
|
|
437
|
-
*
|
|
438
|
-
* class ProductRepo extends Repository<IProduct> {}
|
|
439
|
-
*
|
|
440
|
-
* type ProductRepoWithBatch = ProductRepo & BatchOperationsMethods;
|
|
441
|
-
*
|
|
442
|
-
* const repo = new ProductRepo(ProductModel, [
|
|
443
|
-
* methodRegistryPlugin(),
|
|
444
|
-
* batchOperationsPlugin(),
|
|
445
|
-
* ]) as ProductRepoWithBatch;
|
|
446
|
-
*
|
|
447
|
-
* // TypeScript autocomplete works!
|
|
448
|
-
* await repo.updateMany({ status: 'pending' }, { status: 'active' });
|
|
449
|
-
* await repo.deleteMany({ status: 'archived' });
|
|
450
|
-
* ```
|
|
451
|
-
*/
|
|
452
|
-
interface BatchOperationsMethods {
|
|
453
|
-
/**
|
|
454
|
-
* Update multiple documents matching the query
|
|
455
|
-
* @param query - Query to match documents
|
|
456
|
-
* @param data - Update data
|
|
457
|
-
* @param options - Operation options
|
|
458
|
-
* @returns Update result with matchedCount, modifiedCount, etc.
|
|
459
|
-
*/
|
|
460
|
-
updateMany(query: Record<string, unknown>, data: Record<string, unknown>, options?: {
|
|
461
|
-
session?: ClientSession;
|
|
462
|
-
updatePipeline?: boolean;
|
|
463
|
-
}): Promise<{
|
|
464
|
-
acknowledged: boolean;
|
|
465
|
-
matchedCount: number;
|
|
466
|
-
modifiedCount: number;
|
|
467
|
-
upsertedCount: number;
|
|
468
|
-
upsertedId: unknown;
|
|
469
|
-
}>;
|
|
470
|
-
/**
|
|
471
|
-
* Delete multiple documents matching the query
|
|
472
|
-
* @param query - Query to match documents
|
|
473
|
-
* @param options - Operation options
|
|
474
|
-
* @returns Delete result with deletedCount
|
|
475
|
-
*/
|
|
476
|
-
deleteMany(query: Record<string, unknown>, options?: Record<string, unknown>): Promise<{
|
|
477
|
-
acknowledged: boolean;
|
|
478
|
-
deletedCount: number;
|
|
479
|
-
}>;
|
|
480
|
-
}
|
|
481
|
-
|
|
482
|
-
/**
|
|
483
|
-
* Aggregate Helpers Plugin
|
|
484
|
-
* Adds common aggregation helper methods
|
|
485
|
-
*/
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Aggregate helpers plugin
|
|
489
|
-
*
|
|
490
|
-
* @example
|
|
491
|
-
* const repo = new Repository(Model, [
|
|
492
|
-
* methodRegistryPlugin(),
|
|
493
|
-
* aggregateHelpersPlugin(),
|
|
494
|
-
* ]);
|
|
495
|
-
*
|
|
496
|
-
* const groups = await repo.groupBy('category');
|
|
497
|
-
* const total = await repo.sum('amount', { status: 'completed' });
|
|
498
|
-
*/
|
|
499
|
-
declare function aggregateHelpersPlugin(): Plugin;
|
|
500
|
-
/**
|
|
501
|
-
* Type interface for repositories using aggregateHelpersPlugin
|
|
502
|
-
*
|
|
503
|
-
* @example
|
|
504
|
-
* ```typescript
|
|
505
|
-
* import { Repository, methodRegistryPlugin, aggregateHelpersPlugin } from '@classytic/mongokit';
|
|
506
|
-
* import type { AggregateHelpersMethods } from '@classytic/mongokit';
|
|
507
|
-
*
|
|
508
|
-
* class OrderRepo extends Repository<IOrder> {}
|
|
509
|
-
*
|
|
510
|
-
* type OrderRepoWithAggregates = OrderRepo & AggregateHelpersMethods;
|
|
511
|
-
*
|
|
512
|
-
* const repo = new OrderRepo(OrderModel, [
|
|
513
|
-
* methodRegistryPlugin(),
|
|
514
|
-
* aggregateHelpersPlugin(),
|
|
515
|
-
* ]) as OrderRepoWithAggregates;
|
|
516
|
-
*
|
|
517
|
-
* // TypeScript autocomplete works!
|
|
518
|
-
* const groups = await repo.groupBy('status');
|
|
519
|
-
* const total = await repo.sum('amount', { status: 'completed' });
|
|
520
|
-
* const avg = await repo.average('amount');
|
|
521
|
-
* ```
|
|
522
|
-
*/
|
|
523
|
-
interface AggregateHelpersMethods {
|
|
524
|
-
/**
|
|
525
|
-
* Group documents by field value and count occurrences
|
|
526
|
-
* @param field - Field to group by
|
|
527
|
-
* @param options - Operation options
|
|
528
|
-
* @returns Array of groups with _id and count
|
|
529
|
-
*/
|
|
530
|
-
groupBy(field: string, options?: {
|
|
531
|
-
limit?: number;
|
|
532
|
-
session?: unknown;
|
|
533
|
-
}): Promise<Array<{
|
|
534
|
-
_id: unknown;
|
|
535
|
-
count: number;
|
|
536
|
-
}>>;
|
|
537
|
-
/**
|
|
538
|
-
* Calculate sum of field values
|
|
539
|
-
* @param field - Field to sum
|
|
540
|
-
* @param query - Filter query
|
|
541
|
-
* @param options - Operation options
|
|
542
|
-
* @returns Sum of field values
|
|
543
|
-
*/
|
|
544
|
-
sum(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
545
|
-
/**
|
|
546
|
-
* Calculate average of field values
|
|
547
|
-
* @param field - Field to average
|
|
548
|
-
* @param query - Filter query
|
|
549
|
-
* @param options - Operation options
|
|
550
|
-
* @returns Average of field values
|
|
551
|
-
*/
|
|
552
|
-
average(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
553
|
-
/**
|
|
554
|
-
* Get minimum field value
|
|
555
|
-
* @param field - Field to get minimum from
|
|
556
|
-
* @param query - Filter query
|
|
557
|
-
* @param options - Operation options
|
|
558
|
-
* @returns Minimum field value
|
|
559
|
-
*/
|
|
560
|
-
min(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
561
|
-
/**
|
|
562
|
-
* Get maximum field value
|
|
563
|
-
* @param field - Field to get maximum from
|
|
564
|
-
* @param query - Filter query
|
|
565
|
-
* @param options - Operation options
|
|
566
|
-
* @returns Maximum field value
|
|
567
|
-
*/
|
|
568
|
-
max(field: string, query?: Record<string, unknown>, options?: Record<string, unknown>): Promise<number>;
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
/**
|
|
572
|
-
* Subdocument Plugin
|
|
573
|
-
* Adds subdocument array operations
|
|
574
|
-
*/
|
|
575
|
-
|
|
576
|
-
/**
|
|
577
|
-
* Subdocument plugin for managing nested arrays
|
|
578
|
-
*
|
|
579
|
-
* @example
|
|
580
|
-
* const repo = new Repository(Model, [
|
|
581
|
-
* methodRegistryPlugin(),
|
|
582
|
-
* subdocumentPlugin(),
|
|
583
|
-
* ]);
|
|
584
|
-
*
|
|
585
|
-
* await repo.addSubdocument(parentId, 'items', { name: 'Item 1' });
|
|
586
|
-
* await repo.updateSubdocument(parentId, 'items', itemId, { name: 'Updated Item' });
|
|
587
|
-
*/
|
|
588
|
-
declare function subdocumentPlugin(): Plugin;
|
|
589
|
-
/**
|
|
590
|
-
* Type interface for repositories using subdocumentPlugin
|
|
591
|
-
*
|
|
592
|
-
* @example
|
|
593
|
-
* ```typescript
|
|
594
|
-
* import { Repository, methodRegistryPlugin, subdocumentPlugin } from '@classytic/mongokit';
|
|
595
|
-
* import type { SubdocumentMethods } from '@classytic/mongokit';
|
|
596
|
-
*
|
|
597
|
-
* class OrderRepo extends Repository<IOrder> {}
|
|
598
|
-
*
|
|
599
|
-
* type OrderRepoWithSubdocs = OrderRepo & SubdocumentMethods<IOrder>;
|
|
600
|
-
*
|
|
601
|
-
* const repo = new OrderRepo(OrderModel, [
|
|
602
|
-
* methodRegistryPlugin(),
|
|
603
|
-
* subdocumentPlugin(),
|
|
604
|
-
* ]) as OrderRepoWithSubdocs;
|
|
605
|
-
*
|
|
606
|
-
* // TypeScript autocomplete works!
|
|
607
|
-
* await repo.addSubdocument(orderId, 'items', { productId: '123', quantity: 2 });
|
|
608
|
-
* await repo.updateSubdocument(orderId, 'items', itemId, { quantity: 5 });
|
|
609
|
-
* await repo.deleteSubdocument(orderId, 'items', itemId);
|
|
610
|
-
* ```
|
|
611
|
-
*/
|
|
612
|
-
interface SubdocumentMethods<TDoc> {
|
|
613
|
-
/**
|
|
614
|
-
* Add subdocument to array field
|
|
615
|
-
* @param parentId - Parent document ID
|
|
616
|
-
* @param arrayPath - Path to array field (e.g., 'items', 'addresses')
|
|
617
|
-
* @param subData - Subdocument data
|
|
618
|
-
* @param options - Operation options
|
|
619
|
-
* @returns Updated parent document
|
|
620
|
-
*/
|
|
621
|
-
addSubdocument(parentId: string | ObjectId, arrayPath: string, subData: Record<string, unknown>, options?: Record<string, unknown>): Promise<TDoc>;
|
|
622
|
-
/**
|
|
623
|
-
* Get subdocument from array field
|
|
624
|
-
* @param parentId - Parent document ID
|
|
625
|
-
* @param arrayPath - Path to array field
|
|
626
|
-
* @param subId - Subdocument ID
|
|
627
|
-
* @param options - Operation options
|
|
628
|
-
* @returns Subdocument
|
|
629
|
-
*/
|
|
630
|
-
getSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: {
|
|
631
|
-
lean?: boolean;
|
|
632
|
-
session?: unknown;
|
|
633
|
-
}): Promise<Record<string, unknown>>;
|
|
634
|
-
/**
|
|
635
|
-
* Update subdocument in array field
|
|
636
|
-
* @param parentId - Parent document ID
|
|
637
|
-
* @param arrayPath - Path to array field
|
|
638
|
-
* @param subId - Subdocument ID
|
|
639
|
-
* @param updateData - Update data
|
|
640
|
-
* @param options - Operation options
|
|
641
|
-
* @returns Updated parent document
|
|
642
|
-
*/
|
|
643
|
-
updateSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, updateData: Record<string, unknown>, options?: {
|
|
644
|
-
session?: unknown;
|
|
645
|
-
}): Promise<TDoc>;
|
|
646
|
-
/**
|
|
647
|
-
* Delete subdocument from array field
|
|
648
|
-
* @param parentId - Parent document ID
|
|
649
|
-
* @param arrayPath - Path to array field
|
|
650
|
-
* @param subId - Subdocument ID
|
|
651
|
-
* @param options - Operation options
|
|
652
|
-
* @returns Updated parent document
|
|
653
|
-
*/
|
|
654
|
-
deleteSubdocument(parentId: string | ObjectId, arrayPath: string, subId: string | ObjectId, options?: Record<string, unknown>): Promise<TDoc>;
|
|
655
|
-
}
|
|
656
|
-
|
|
657
|
-
/**
|
|
658
|
-
* Cache Plugin
|
|
659
|
-
*
|
|
660
|
-
* Optional caching layer for MongoKit with automatic invalidation.
|
|
661
|
-
* Bring-your-own cache adapter (Redis, Memcached, in-memory, etc.)
|
|
662
|
-
*
|
|
663
|
-
* Features:
|
|
664
|
-
* - Cache-aside (read-through) pattern with configurable TTLs
|
|
665
|
-
* - Automatic invalidation on create/update/delete
|
|
666
|
-
* - Collection version tags for efficient list cache invalidation
|
|
667
|
-
* - Manual invalidation methods for microservice scenarios
|
|
668
|
-
* - Skip cache per-operation with `skipCache: true`
|
|
669
|
-
*
|
|
670
|
-
* @example
|
|
671
|
-
* ```typescript
|
|
672
|
-
* import { Repository, cachePlugin } from '@classytic/mongokit';
|
|
673
|
-
* import Redis from 'ioredis';
|
|
674
|
-
*
|
|
675
|
-
* const redis = new Redis();
|
|
676
|
-
*
|
|
677
|
-
* const userRepo = new Repository(UserModel, [
|
|
678
|
-
* cachePlugin({
|
|
679
|
-
* adapter: {
|
|
680
|
-
* async get(key) { return JSON.parse(await redis.get(key) || 'null'); },
|
|
681
|
-
* async set(key, value, ttl) { await redis.setex(key, ttl, JSON.stringify(value)); },
|
|
682
|
-
* async del(key) { await redis.del(key); },
|
|
683
|
-
* async clear(pattern) {
|
|
684
|
-
* const keys = await redis.keys(pattern || '*');
|
|
685
|
-
* if (keys.length) await redis.del(...keys);
|
|
686
|
-
* }
|
|
687
|
-
* },
|
|
688
|
-
* ttl: 60, // 1 minute default
|
|
689
|
-
* })
|
|
690
|
-
* ]);
|
|
691
|
-
*
|
|
692
|
-
* // Reads check cache first
|
|
693
|
-
* const user = await userRepo.getById(id); // cached
|
|
694
|
-
*
|
|
695
|
-
* // Skip cache for fresh data
|
|
696
|
-
* const fresh = await userRepo.getById(id, { skipCache: true });
|
|
697
|
-
*
|
|
698
|
-
* // Mutations auto-invalidate
|
|
699
|
-
* await userRepo.update(id, { name: 'New Name' }); // invalidates cache
|
|
700
|
-
*
|
|
701
|
-
* // Manual invalidation for microservice sync
|
|
702
|
-
* await userRepo.invalidateCache(id); // invalidate single doc
|
|
703
|
-
* await userRepo.invalidateAllCache(); // invalidate all for this model
|
|
704
|
-
* ```
|
|
705
|
-
*/
|
|
706
|
-
|
|
707
|
-
/**
|
|
708
|
-
* Cache plugin factory
|
|
709
|
-
*
|
|
710
|
-
* @param options - Cache configuration
|
|
711
|
-
* @returns Plugin instance
|
|
712
|
-
*/
|
|
713
|
-
declare function cachePlugin(options: CacheOptions): Plugin;
|
|
714
|
-
/**
|
|
715
|
-
* TypeScript interface for cache plugin methods
|
|
716
|
-
*
|
|
717
|
-
* @example
|
|
718
|
-
* ```typescript
|
|
719
|
-
* import type { CacheMethods } from '@classytic/mongokit';
|
|
720
|
-
*
|
|
721
|
-
* type ProductRepoWithCache = ProductRepo & CacheMethods;
|
|
722
|
-
*
|
|
723
|
-
* const productRepo = new ProductRepo(ProductModel, [
|
|
724
|
-
* methodRegistryPlugin(),
|
|
725
|
-
* cachePlugin({ adapter: redisAdapter, ttl: 60 }),
|
|
726
|
-
* ]) as ProductRepoWithCache;
|
|
727
|
-
*
|
|
728
|
-
* // TypeScript autocomplete for cache methods
|
|
729
|
-
* await productRepo.invalidateCache(productId);
|
|
730
|
-
* await productRepo.invalidateListCache();
|
|
731
|
-
* await productRepo.invalidateAllCache();
|
|
732
|
-
* const stats = productRepo.getCacheStats();
|
|
733
|
-
* productRepo.resetCacheStats();
|
|
734
|
-
* ```
|
|
735
|
-
*/
|
|
736
|
-
interface CacheMethods {
|
|
737
|
-
/**
|
|
738
|
-
* Invalidate cache for a specific document
|
|
739
|
-
* Use when document was updated outside this service
|
|
740
|
-
* @param id - Document ID to invalidate
|
|
741
|
-
*/
|
|
742
|
-
invalidateCache(id: string): Promise<void>;
|
|
743
|
-
/**
|
|
744
|
-
* Invalidate all list caches for this model
|
|
745
|
-
* Use when bulk changes happened outside this service
|
|
746
|
-
*/
|
|
747
|
-
invalidateListCache(): Promise<void>;
|
|
748
|
-
/**
|
|
749
|
-
* Invalidate ALL cache entries for this model
|
|
750
|
-
* Nuclear option - use sparingly
|
|
751
|
-
*/
|
|
752
|
-
invalidateAllCache(): Promise<void>;
|
|
753
|
-
/**
|
|
754
|
-
* Get cache statistics for monitoring
|
|
755
|
-
* @returns Cache statistics (hits, misses, sets, invalidations)
|
|
756
|
-
*/
|
|
757
|
-
getCacheStats(): CacheStats;
|
|
758
|
-
/**
|
|
759
|
-
* Reset cache statistics
|
|
760
|
-
*/
|
|
761
|
-
resetCacheStats(): void;
|
|
762
|
-
}
|
|
763
|
-
|
|
764
|
-
/**
|
|
765
|
-
* Cascade Delete Plugin
|
|
766
|
-
* Automatically deletes related documents when a parent document is deleted
|
|
767
|
-
*
|
|
768
|
-
* @example
|
|
769
|
-
* ```typescript
|
|
770
|
-
* import mongoose from 'mongoose';
|
|
771
|
-
* import { Repository, cascadePlugin, methodRegistryPlugin } from '@classytic/mongokit';
|
|
772
|
-
*
|
|
773
|
-
* const productRepo = new Repository(Product, [
|
|
774
|
-
* methodRegistryPlugin(),
|
|
775
|
-
* cascadePlugin({
|
|
776
|
-
* relations: [
|
|
777
|
-
* { model: 'StockEntry', foreignKey: 'product' },
|
|
778
|
-
* { model: 'StockMovement', foreignKey: 'product' },
|
|
779
|
-
* ]
|
|
780
|
-
* })
|
|
781
|
-
* ]);
|
|
782
|
-
*
|
|
783
|
-
* // When a product is deleted, all related StockEntry and StockMovement docs are also deleted
|
|
784
|
-
* await productRepo.delete(productId);
|
|
785
|
-
* ```
|
|
786
|
-
*/
|
|
787
|
-
|
|
788
|
-
/**
|
|
789
|
-
* Cascade delete plugin
|
|
790
|
-
*
|
|
791
|
-
* Deletes related documents after the parent document is deleted.
|
|
792
|
-
* Works with both hard delete and soft delete scenarios.
|
|
793
|
-
*
|
|
794
|
-
* @param options - Cascade configuration
|
|
795
|
-
* @returns Plugin
|
|
796
|
-
*/
|
|
797
|
-
declare function cascadePlugin(options: CascadeOptions): Plugin;
|
|
798
|
-
|
|
799
|
-
/**
|
|
800
|
-
* Multi-Tenant Plugin
|
|
801
|
-
*
|
|
802
|
-
* Automatically injects tenant isolation filters into all queries.
|
|
803
|
-
* Ensures data isolation by adding organizationId (or custom tenant field)
|
|
804
|
-
* to every read and write operation.
|
|
805
|
-
*
|
|
806
|
-
* @example
|
|
807
|
-
* ```typescript
|
|
808
|
-
* // Basic — scopes every operation by organizationId from context
|
|
809
|
-
* const repo = new Repository(Invoice, [
|
|
810
|
-
* multiTenantPlugin({ tenantField: 'organizationId' }),
|
|
811
|
-
* ]);
|
|
812
|
-
*
|
|
813
|
-
* const invoices = await repo.getAll(
|
|
814
|
-
* { filters: { status: 'paid' } },
|
|
815
|
-
* { organizationId: 'org_123' }
|
|
816
|
-
* );
|
|
817
|
-
* // Actual query: { status: 'paid', organizationId: 'org_123' }
|
|
818
|
-
*
|
|
819
|
-
* // Super admin bypass — skip scoping based on context
|
|
820
|
-
* const repo = new Repository(Invoice, [
|
|
821
|
-
* multiTenantPlugin({
|
|
822
|
-
* tenantField: 'organizationId',
|
|
823
|
-
* skipWhen: (context) => context.role === 'superadmin',
|
|
824
|
-
* }),
|
|
825
|
-
* ]);
|
|
826
|
-
*
|
|
827
|
-
* // Admin sees all orgs
|
|
828
|
-
* await repo.getAll({ page: 1, limit: 10 }, { role: 'superadmin' });
|
|
829
|
-
*
|
|
830
|
-
* // Automatic context — resolve tenant from AsyncLocalStorage
|
|
831
|
-
* const repo = new Repository(Invoice, [
|
|
832
|
-
* multiTenantPlugin({
|
|
833
|
-
* tenantField: 'organizationId',
|
|
834
|
-
* resolveContext: () => asyncLocalStorage.getStore()?.tenantId,
|
|
835
|
-
* }),
|
|
836
|
-
* ]);
|
|
837
|
-
* ```
|
|
838
|
-
*/
|
|
839
|
-
|
|
840
|
-
interface MultiTenantOptions {
|
|
841
|
-
/** Field name used for tenant isolation (default: 'organizationId') */
|
|
842
|
-
tenantField?: string;
|
|
843
|
-
/** Context key to read tenant ID from (default: 'organizationId') */
|
|
844
|
-
contextKey?: string;
|
|
845
|
-
/** Throw if tenant ID is missing from context (default: true) */
|
|
846
|
-
required?: boolean;
|
|
847
|
-
/** Operations to skip tenant injection (e.g., for admin/system queries) */
|
|
848
|
-
skipOperations?: string[];
|
|
849
|
-
/**
|
|
850
|
-
* Dynamic skip — receives the context and operation name, returns true to
|
|
851
|
-
* bypass tenant scoping for this call. Use for role-based bypass (e.g.,
|
|
852
|
-
* super admin) without needing a separate repo instance.
|
|
853
|
-
*
|
|
854
|
-
* @example
|
|
855
|
-
* ```typescript
|
|
856
|
-
* skipWhen: (context) => context.role === 'superadmin'
|
|
857
|
-
* ```
|
|
858
|
-
*/
|
|
859
|
-
skipWhen?: (context: RepositoryContext, operation: string) => boolean;
|
|
860
|
-
/**
|
|
861
|
-
* Resolve tenant ID from external source (e.g., AsyncLocalStorage, CLS).
|
|
862
|
-
* Called when tenant ID is not found in context. If it returns a value,
|
|
863
|
-
* that value is used as the tenant ID without requiring it in context.
|
|
864
|
-
*
|
|
865
|
-
* @example
|
|
866
|
-
* ```typescript
|
|
867
|
-
* resolveContext: () => asyncLocalStorage.getStore()?.tenantId
|
|
868
|
-
* ```
|
|
869
|
-
*/
|
|
870
|
-
resolveContext?: () => string | undefined;
|
|
871
|
-
}
|
|
872
|
-
declare function multiTenantPlugin(options?: MultiTenantOptions): Plugin;
|
|
873
|
-
|
|
874
|
-
/**
|
|
875
|
-
* Observability Plugin
|
|
876
|
-
*
|
|
877
|
-
* Adds operation timing, structured metrics, and APM hook points.
|
|
878
|
-
* Works with any monitoring system — just provide an onMetric callback.
|
|
879
|
-
*
|
|
880
|
-
* @example
|
|
881
|
-
* ```typescript
|
|
882
|
-
* const repo = new Repository(User, [
|
|
883
|
-
* observabilityPlugin({
|
|
884
|
-
* onMetric: (metric) => {
|
|
885
|
-
* // Send to DataDog, New Relic, OpenTelemetry, or console
|
|
886
|
-
* console.log(`${metric.operation} took ${metric.durationMs}ms`);
|
|
887
|
-
* statsd.histogram('mongokit.operation', metric.durationMs, { op: metric.operation });
|
|
888
|
-
* },
|
|
889
|
-
* }),
|
|
890
|
-
* ]);
|
|
891
|
-
* ```
|
|
892
|
-
*/
|
|
893
|
-
|
|
894
|
-
interface OperationMetric {
|
|
895
|
-
/** Operation name (e.g., 'create', 'getAll', 'update') */
|
|
896
|
-
operation: string;
|
|
897
|
-
/** Model/collection name */
|
|
898
|
-
model: string;
|
|
899
|
-
/** Duration in milliseconds */
|
|
900
|
-
durationMs: number;
|
|
901
|
-
/** Whether the operation succeeded */
|
|
902
|
-
success: boolean;
|
|
903
|
-
/** Error message if failed */
|
|
904
|
-
error?: string;
|
|
905
|
-
/** Timestamp when the operation started */
|
|
906
|
-
startedAt: Date;
|
|
907
|
-
/** User ID if available */
|
|
908
|
-
userId?: string;
|
|
909
|
-
/** Organization ID if available */
|
|
910
|
-
organizationId?: string;
|
|
911
|
-
}
|
|
912
|
-
interface ObservabilityOptions {
|
|
913
|
-
/** Callback invoked after every operation with timing data */
|
|
914
|
-
onMetric: (metric: OperationMetric) => void;
|
|
915
|
-
/** Operations to track (default: all) */
|
|
916
|
-
operations?: string[];
|
|
917
|
-
/** Threshold in ms — only report operations slower than this */
|
|
918
|
-
slowThresholdMs?: number;
|
|
919
|
-
}
|
|
920
|
-
declare function observabilityPlugin(options: ObservabilityOptions): Plugin;
|
|
921
|
-
|
|
922
|
-
export { type AggregateHelpersMethods, type BatchOperationsMethods, type CacheMethods, type MethodRegistryRepository, type MongoOperationsMethods, type MultiTenantOptions, type ObservabilityOptions, type OperationMetric, type SoftDeleteMethods, type SubdocumentMethods, aggregateHelpersPlugin, auditLogPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, fieldFilterPlugin, immutableField, methodRegistryPlugin, mongoOperationsPlugin, multiTenantPlugin, observabilityPlugin, requireField, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin };
|