@classytic/mongokit 3.0.1 → 3.0.3
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 +245 -871
- package/dist/actions/index.d.ts +2 -2
- package/dist/actions/index.js +13 -0
- package/dist/{index-CKy3H2SY.d.ts → index-CMCrkd2v.d.ts} +11 -11
- package/dist/index.d.ts +13 -15
- package/dist/index.js +70 -19
- package/dist/{memory-cache-tn3v1xgG.d.ts → memory-cache-Bn_-Kk-0.d.ts} +1 -1
- package/dist/pagination/PaginationEngine.d.ts +2 -2
- package/dist/pagination/PaginationEngine.js +1 -0
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.js +8 -1
- package/dist/{types-vDtcOhyx.d.ts → types-B3dPUKjs.d.ts} +10 -2
- package/dist/utils/index.d.ts +2 -2
- package/package.json +2 -1
package/dist/actions/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { a as aggregate, c as create, _ as deleteActions, r as read, u as update } from '../index-
|
|
1
|
+
export { a as aggregate, c as create, _ as deleteActions, r as read, u as update } from '../index-CMCrkd2v.js';
|
|
2
2
|
import 'mongoose';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-B3dPUKjs.js';
|
package/dist/actions/index.js
CHANGED
|
@@ -147,6 +147,14 @@ __export(update_exports, {
|
|
|
147
147
|
updateWithConstraints: () => updateWithConstraints,
|
|
148
148
|
updateWithValidation: () => updateWithValidation
|
|
149
149
|
});
|
|
150
|
+
function assertUpdatePipelineAllowed(update2, updatePipeline) {
|
|
151
|
+
if (Array.isArray(update2) && updatePipeline !== true) {
|
|
152
|
+
throw createError(
|
|
153
|
+
400,
|
|
154
|
+
"Update pipelines (array updates) are disabled by default; pass `{ updatePipeline: true }` to explicitly allow pipeline-style updates."
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
150
158
|
function parsePopulate2(populate) {
|
|
151
159
|
if (!populate) return [];
|
|
152
160
|
if (typeof populate === "string") {
|
|
@@ -158,6 +166,7 @@ function parsePopulate2(populate) {
|
|
|
158
166
|
return [populate];
|
|
159
167
|
}
|
|
160
168
|
async function update(Model, id, data, options = {}) {
|
|
169
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
161
170
|
const document = await Model.findByIdAndUpdate(id, data, {
|
|
162
171
|
new: true,
|
|
163
172
|
runValidators: true,
|
|
@@ -170,6 +179,7 @@ async function update(Model, id, data, options = {}) {
|
|
|
170
179
|
return document;
|
|
171
180
|
}
|
|
172
181
|
async function updateWithConstraints(Model, id, data, constraints = {}, options = {}) {
|
|
182
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
173
183
|
const query = { _id: id, ...constraints };
|
|
174
184
|
const document = await Model.findOneAndUpdate(query, data, {
|
|
175
185
|
new: true,
|
|
@@ -181,6 +191,7 @@ async function updateWithConstraints(Model, id, data, constraints = {}, options
|
|
|
181
191
|
}
|
|
182
192
|
async function updateWithValidation(Model, id, data, validationOptions = {}, options = {}) {
|
|
183
193
|
const { buildConstraints, validateUpdate } = validationOptions;
|
|
194
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
184
195
|
if (buildConstraints) {
|
|
185
196
|
const constraints = buildConstraints(data);
|
|
186
197
|
const document = await updateWithConstraints(Model, id, data, constraints, options);
|
|
@@ -215,6 +226,7 @@ async function updateWithValidation(Model, id, data, validationOptions = {}, opt
|
|
|
215
226
|
return { success: true, data: updated };
|
|
216
227
|
}
|
|
217
228
|
async function updateMany(Model, query, data, options = {}) {
|
|
229
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
218
230
|
const result = await Model.updateMany(query, data, {
|
|
219
231
|
runValidators: true,
|
|
220
232
|
session: options.session,
|
|
@@ -226,6 +238,7 @@ async function updateMany(Model, query, data, options = {}) {
|
|
|
226
238
|
};
|
|
227
239
|
}
|
|
228
240
|
async function updateByQuery(Model, query, data, options = {}) {
|
|
241
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
229
242
|
const document = await Model.findOneAndUpdate(query, data, {
|
|
230
243
|
new: true,
|
|
231
244
|
runValidators: true,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Model, ClientSession, PipelineStage } from 'mongoose';
|
|
2
|
-
import { A as AnyDocument, C as CreateOptions,
|
|
2
|
+
import { A as AnyDocument, C as CreateOptions, f as ObjectId, n as OperationOptions, S as SelectSpec, g as PopulateSpec, h as SortSpec, U as UpdateOptions, p as UpdateWithValidationResult, o as UpdateManyResult, D as DeleteResult, N as GroupResult, M as LookupOptions, Q as MinMaxResult } from './types-B3dPUKjs.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Create Actions
|
|
@@ -48,7 +48,7 @@ declare namespace create$1 {
|
|
|
48
48
|
* @returns Document or null
|
|
49
49
|
* @throws Error if document not found and throwOnNotFound is true
|
|
50
50
|
*/
|
|
51
|
-
declare function getById<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, options?: OperationOptions): Promise<TDoc | null>;
|
|
51
|
+
declare function getById<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, options?: OperationOptions): Promise<TDoc | null>;
|
|
52
52
|
/**
|
|
53
53
|
* Get document by query
|
|
54
54
|
*
|
|
@@ -117,12 +117,12 @@ declare namespace read {
|
|
|
117
117
|
/**
|
|
118
118
|
* Update by ID
|
|
119
119
|
*/
|
|
120
|
-
declare function update<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc>;
|
|
120
|
+
declare function update<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc>;
|
|
121
121
|
/**
|
|
122
122
|
* Update with query constraints (optimized)
|
|
123
123
|
* Returns null if constraints not met (not an error)
|
|
124
124
|
*/
|
|
125
|
-
declare function updateWithConstraints<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, data: Record<string, unknown>, constraints?: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc | null>;
|
|
125
|
+
declare function updateWithConstraints<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, data: Record<string, unknown>, constraints?: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc | null>;
|
|
126
126
|
/**
|
|
127
127
|
* Validation options for smart update
|
|
128
128
|
*/
|
|
@@ -141,7 +141,7 @@ interface ValidationOptions {
|
|
|
141
141
|
* Update with validation (smart optimization)
|
|
142
142
|
* 1-query on success, 2-queries for detailed errors
|
|
143
143
|
*/
|
|
144
|
-
declare function updateWithValidation<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, data: Record<string, unknown>, validationOptions?: ValidationOptions, options?: UpdateOptions): Promise<UpdateWithValidationResult<TDoc>>;
|
|
144
|
+
declare function updateWithValidation<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, data: Record<string, unknown>, validationOptions?: ValidationOptions, options?: UpdateOptions): Promise<UpdateWithValidationResult<TDoc>>;
|
|
145
145
|
/**
|
|
146
146
|
* Update many documents
|
|
147
147
|
*/
|
|
@@ -156,15 +156,15 @@ declare function updateByQuery<TDoc = AnyDocument>(Model: Model<TDoc>, query: Re
|
|
|
156
156
|
/**
|
|
157
157
|
* Increment field
|
|
158
158
|
*/
|
|
159
|
-
declare function increment<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, field: string, value?: number, options?: UpdateOptions): Promise<TDoc>;
|
|
159
|
+
declare function increment<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value?: number, options?: UpdateOptions): Promise<TDoc>;
|
|
160
160
|
/**
|
|
161
161
|
* Push to array
|
|
162
162
|
*/
|
|
163
|
-
declare function pushToArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc>;
|
|
163
|
+
declare function pushToArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc>;
|
|
164
164
|
/**
|
|
165
165
|
* Pull from array
|
|
166
166
|
*/
|
|
167
|
-
declare function pullFromArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc>;
|
|
167
|
+
declare function pullFromArray<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, field: string, value: unknown, options?: UpdateOptions): Promise<TDoc>;
|
|
168
168
|
|
|
169
169
|
declare const update$1_increment: typeof increment;
|
|
170
170
|
declare const update$1_pullFromArray: typeof pullFromArray;
|
|
@@ -186,7 +186,7 @@ declare namespace update$1 {
|
|
|
186
186
|
/**
|
|
187
187
|
* Delete by ID
|
|
188
188
|
*/
|
|
189
|
-
declare function deleteById(Model: Model<any>, id: string, options?: {
|
|
189
|
+
declare function deleteById(Model: Model<any>, id: string | ObjectId, options?: {
|
|
190
190
|
session?: ClientSession;
|
|
191
191
|
}): Promise<DeleteResult>;
|
|
192
192
|
/**
|
|
@@ -205,14 +205,14 @@ declare function deleteByQuery(Model: Model<any>, query: Record<string, unknown>
|
|
|
205
205
|
/**
|
|
206
206
|
* Soft delete (set deleted flag)
|
|
207
207
|
*/
|
|
208
|
-
declare function softDelete<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, options?: {
|
|
208
|
+
declare function softDelete<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, options?: {
|
|
209
209
|
session?: ClientSession;
|
|
210
210
|
userId?: string;
|
|
211
211
|
}): Promise<DeleteResult>;
|
|
212
212
|
/**
|
|
213
213
|
* Restore soft deleted document
|
|
214
214
|
*/
|
|
215
|
-
declare function restore<TDoc = AnyDocument>(Model: Model<TDoc>, id: string, options?: {
|
|
215
|
+
declare function restore<TDoc = AnyDocument>(Model: Model<TDoc>, id: string | ObjectId, options?: {
|
|
216
216
|
session?: ClientSession;
|
|
217
217
|
}): Promise<DeleteResult>;
|
|
218
218
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { A as AnyDocument, e as PluginType, P as PaginationConfig, S as SelectSpec,
|
|
2
|
-
export { c as AggregatePaginationOptions,
|
|
1
|
+
import { A as AnyDocument, e as PluginType, P as PaginationConfig, R as RepositoryOptions, f as ObjectId, S as SelectSpec, g as PopulateSpec, h as SortSpec, a as OffsetPaginationResult, b as KeysetPaginationResult, U as UpdateOptions, d as AggregatePaginationResult, i as RepositoryContext, H as HttpError } from './types-B3dPUKjs.js';
|
|
2
|
+
export { c as AggregatePaginationOptions, j as AnyModel, T as CacheAdapter, X as CacheOperationOptions, W as CacheOptions, Y as CacheStats, _ as CascadeOptions, Z as CascadeRelation, C as CreateOptions, y as CrudSchemas, z as DecodedCursor, D as DeleteResult, E as EventPayload, F as FieldPreset, w as FieldRules, N as GroupResult, l as HookMode, J as JsonSchema, K as KeysetPaginationOptions, L as Logger, M as LookupOptions, Q as MinMaxResult, O as OffsetPaginationOptions, n as OperationOptions, m as PaginationResult, v as ParsedQuery, r as Plugin, s as PluginFunction, u as RepositoryEvent, t as RepositoryInstance, x as SchemaBuilderOptions, I as SoftDeleteOptions, k as SortDirection, o as UpdateManyResult, p as UpdateWithValidationResult, q as UserContext, G as ValidationChainOptions, V as ValidationResult, B as ValidatorDefinition } from './types-B3dPUKjs.js';
|
|
3
3
|
import * as mongoose from 'mongoose';
|
|
4
4
|
import { Model, ClientSession, PipelineStage, PopulateOptions } from 'mongoose';
|
|
5
5
|
import { PaginationEngine } from './pagination/PaginationEngine.js';
|
|
6
6
|
export { aggregateHelpersPlugin, auditLogPlugin, autoInject, batchOperationsPlugin, blockIf, cachePlugin, cascadePlugin, fieldFilterPlugin, immutableField, methodRegistryPlugin, mongoOperationsPlugin, requireField, softDeletePlugin, subdocumentPlugin, timestampPlugin, uniqueField, validationChainPlugin } from './plugins/index.js';
|
|
7
|
-
export { b as createError, c as createFieldPreset, d as createMemoryCache, f as filterResponseData, g as getFieldsForUser, a as getMongooseProjection } from './memory-cache-
|
|
8
|
-
export { i as actions } from './index-
|
|
7
|
+
export { b as createError, c as createFieldPreset, d as createMemoryCache, f as filterResponseData, g as getFieldsForUser, a as getMongooseProjection } from './memory-cache-Bn_-Kk-0.js';
|
|
8
|
+
export { i as actions } from './index-CMCrkd2v.js';
|
|
9
9
|
|
|
10
10
|
/**
|
|
11
11
|
* Repository Pattern - Data Access Layer
|
|
@@ -44,8 +44,9 @@ declare class Repository<TDoc = AnyDocument> {
|
|
|
44
44
|
readonly model: string;
|
|
45
45
|
readonly _hooks: Map<string, HookListener[]>;
|
|
46
46
|
readonly _pagination: PaginationEngine<TDoc>;
|
|
47
|
+
private readonly _hookMode;
|
|
47
48
|
[key: string]: unknown;
|
|
48
|
-
constructor(Model: Model<TDoc>, plugins?: PluginType[], paginationConfig?: PaginationConfig);
|
|
49
|
+
constructor(Model: Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions);
|
|
49
50
|
/**
|
|
50
51
|
* Register a plugin
|
|
51
52
|
*/
|
|
@@ -62,6 +63,8 @@ declare class Repository<TDoc = AnyDocument> {
|
|
|
62
63
|
* Emit event and await all async handlers
|
|
63
64
|
*/
|
|
64
65
|
emitAsync(event: string, data: unknown): Promise<void>;
|
|
66
|
+
private _emitHook;
|
|
67
|
+
private _emitErrorHook;
|
|
65
68
|
/**
|
|
66
69
|
* Create single document
|
|
67
70
|
*/
|
|
@@ -78,7 +81,7 @@ declare class Repository<TDoc = AnyDocument> {
|
|
|
78
81
|
/**
|
|
79
82
|
* Get document by ID
|
|
80
83
|
*/
|
|
81
|
-
getById(id: string, options?: {
|
|
84
|
+
getById(id: string | ObjectId, options?: {
|
|
82
85
|
select?: SelectSpec;
|
|
83
86
|
populate?: PopulateSpec;
|
|
84
87
|
lean?: boolean;
|
|
@@ -165,16 +168,11 @@ declare class Repository<TDoc = AnyDocument> {
|
|
|
165
168
|
/**
|
|
166
169
|
* Update document by ID
|
|
167
170
|
*/
|
|
168
|
-
update(id: string, data: Record<string, unknown>, options?:
|
|
169
|
-
select?: SelectSpec;
|
|
170
|
-
populate?: PopulateSpec;
|
|
171
|
-
lean?: boolean;
|
|
172
|
-
session?: ClientSession;
|
|
173
|
-
}): Promise<TDoc>;
|
|
171
|
+
update(id: string | ObjectId, data: Record<string, unknown>, options?: UpdateOptions): Promise<TDoc>;
|
|
174
172
|
/**
|
|
175
173
|
* Delete document by ID
|
|
176
174
|
*/
|
|
177
|
-
delete(id: string, options?: {
|
|
175
|
+
delete(id: string | ObjectId, options?: {
|
|
178
176
|
session?: ClientSession;
|
|
179
177
|
}): Promise<{
|
|
180
178
|
success: boolean;
|
|
@@ -238,6 +236,6 @@ declare class Repository<TDoc = AnyDocument> {
|
|
|
238
236
|
* @example
|
|
239
237
|
* const userRepo = createRepository(UserModel, [timestampPlugin()]);
|
|
240
238
|
*/
|
|
241
|
-
declare function createRepository<TDoc>(Model: mongoose.Model<TDoc>, plugins?: PluginType[]): Repository<TDoc>;
|
|
239
|
+
declare function createRepository<TDoc>(Model: mongoose.Model<TDoc, any, any, any>, plugins?: PluginType[], paginationConfig?: PaginationConfig, options?: RepositoryOptions): Repository<TDoc>;
|
|
242
240
|
|
|
243
|
-
export { AggregatePaginationResult, AnyDocument, HttpError, KeysetPaginationResult, OffsetPaginationResult, PaginationConfig, PaginationEngine, PluginType, PopulateSpec, Repository, RepositoryContext, SelectSpec, SortSpec, createRepository, Repository as default };
|
|
241
|
+
export { AggregatePaginationResult, AnyDocument, HttpError, KeysetPaginationResult, ObjectId, OffsetPaginationResult, PaginationConfig, PaginationEngine, PluginType, PopulateSpec, Repository, RepositoryContext, RepositoryOptions, SelectSpec, SortSpec, UpdateOptions, createRepository, Repository as default };
|
package/dist/index.js
CHANGED
|
@@ -147,6 +147,14 @@ __export(update_exports, {
|
|
|
147
147
|
updateWithConstraints: () => updateWithConstraints,
|
|
148
148
|
updateWithValidation: () => updateWithValidation
|
|
149
149
|
});
|
|
150
|
+
function assertUpdatePipelineAllowed(update2, updatePipeline) {
|
|
151
|
+
if (Array.isArray(update2) && updatePipeline !== true) {
|
|
152
|
+
throw createError(
|
|
153
|
+
400,
|
|
154
|
+
"Update pipelines (array updates) are disabled by default; pass `{ updatePipeline: true }` to explicitly allow pipeline-style updates."
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
150
158
|
function parsePopulate2(populate) {
|
|
151
159
|
if (!populate) return [];
|
|
152
160
|
if (typeof populate === "string") {
|
|
@@ -158,6 +166,7 @@ function parsePopulate2(populate) {
|
|
|
158
166
|
return [populate];
|
|
159
167
|
}
|
|
160
168
|
async function update(Model, id, data, options = {}) {
|
|
169
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
161
170
|
const document = await Model.findByIdAndUpdate(id, data, {
|
|
162
171
|
new: true,
|
|
163
172
|
runValidators: true,
|
|
@@ -170,6 +179,7 @@ async function update(Model, id, data, options = {}) {
|
|
|
170
179
|
return document;
|
|
171
180
|
}
|
|
172
181
|
async function updateWithConstraints(Model, id, data, constraints = {}, options = {}) {
|
|
182
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
173
183
|
const query = { _id: id, ...constraints };
|
|
174
184
|
const document = await Model.findOneAndUpdate(query, data, {
|
|
175
185
|
new: true,
|
|
@@ -181,6 +191,7 @@ async function updateWithConstraints(Model, id, data, constraints = {}, options
|
|
|
181
191
|
}
|
|
182
192
|
async function updateWithValidation(Model, id, data, validationOptions = {}, options = {}) {
|
|
183
193
|
const { buildConstraints, validateUpdate } = validationOptions;
|
|
194
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
184
195
|
if (buildConstraints) {
|
|
185
196
|
const constraints = buildConstraints(data);
|
|
186
197
|
const document = await updateWithConstraints(Model, id, data, constraints, options);
|
|
@@ -215,6 +226,7 @@ async function updateWithValidation(Model, id, data, validationOptions = {}, opt
|
|
|
215
226
|
return { success: true, data: updated };
|
|
216
227
|
}
|
|
217
228
|
async function updateMany(Model, query, data, options = {}) {
|
|
229
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
218
230
|
const result = await Model.updateMany(query, data, {
|
|
219
231
|
runValidators: true,
|
|
220
232
|
session: options.session,
|
|
@@ -226,6 +238,7 @@ async function updateMany(Model, query, data, options = {}) {
|
|
|
226
238
|
};
|
|
227
239
|
}
|
|
228
240
|
async function updateByQuery(Model, query, data, options = {}) {
|
|
241
|
+
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
229
242
|
const document = await Model.findOneAndUpdate(query, data, {
|
|
230
243
|
new: true,
|
|
231
244
|
runValidators: true,
|
|
@@ -630,6 +643,7 @@ var PaginationEngine = class {
|
|
|
630
643
|
* @param Model - Mongoose model to paginate
|
|
631
644
|
* @param config - Pagination configuration
|
|
632
645
|
*/
|
|
646
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
633
647
|
constructor(Model, config = {}) {
|
|
634
648
|
this.Model = Model;
|
|
635
649
|
this.config = {
|
|
@@ -829,11 +843,13 @@ var Repository = class {
|
|
|
829
843
|
model;
|
|
830
844
|
_hooks;
|
|
831
845
|
_pagination;
|
|
832
|
-
|
|
846
|
+
_hookMode;
|
|
847
|
+
constructor(Model, plugins = [], paginationConfig = {}, options = {}) {
|
|
833
848
|
this.Model = Model;
|
|
834
849
|
this.model = Model.modelName;
|
|
835
850
|
this._hooks = /* @__PURE__ */ new Map();
|
|
836
851
|
this._pagination = new PaginationEngine(Model, paginationConfig);
|
|
852
|
+
this._hookMode = options.hooks ?? "async";
|
|
837
853
|
plugins.forEach((plugin) => this.use(plugin));
|
|
838
854
|
}
|
|
839
855
|
/**
|
|
@@ -862,7 +878,22 @@ var Repository = class {
|
|
|
862
878
|
*/
|
|
863
879
|
emit(event, data) {
|
|
864
880
|
const listeners = this._hooks.get(event) || [];
|
|
865
|
-
|
|
881
|
+
for (const listener of listeners) {
|
|
882
|
+
try {
|
|
883
|
+
const result = listener(data);
|
|
884
|
+
if (result && typeof result.then === "function") {
|
|
885
|
+
void result.catch((error) => {
|
|
886
|
+
if (event === "error:hook") return;
|
|
887
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
888
|
+
this.emit("error:hook", { event, error: err });
|
|
889
|
+
});
|
|
890
|
+
}
|
|
891
|
+
} catch (error) {
|
|
892
|
+
if (event === "error:hook") continue;
|
|
893
|
+
const err = error instanceof Error ? error : new Error(String(error));
|
|
894
|
+
this.emit("error:hook", { event, error: err });
|
|
895
|
+
}
|
|
896
|
+
}
|
|
866
897
|
}
|
|
867
898
|
/**
|
|
868
899
|
* Emit event and await all async handlers
|
|
@@ -873,6 +904,19 @@ var Repository = class {
|
|
|
873
904
|
await listener(data);
|
|
874
905
|
}
|
|
875
906
|
}
|
|
907
|
+
async _emitHook(event, data) {
|
|
908
|
+
if (this._hookMode === "async") {
|
|
909
|
+
await this.emitAsync(event, data);
|
|
910
|
+
return;
|
|
911
|
+
}
|
|
912
|
+
this.emit(event, data);
|
|
913
|
+
}
|
|
914
|
+
async _emitErrorHook(event, data) {
|
|
915
|
+
try {
|
|
916
|
+
await this._emitHook(event, data);
|
|
917
|
+
} catch {
|
|
918
|
+
}
|
|
919
|
+
}
|
|
876
920
|
/**
|
|
877
921
|
* Create single document
|
|
878
922
|
*/
|
|
@@ -880,10 +924,10 @@ var Repository = class {
|
|
|
880
924
|
const context = await this._buildContext("create", { data, ...options });
|
|
881
925
|
try {
|
|
882
926
|
const result = await create(this.Model, context.data || data, options);
|
|
883
|
-
this.
|
|
927
|
+
await this._emitHook("after:create", { context, result });
|
|
884
928
|
return result;
|
|
885
929
|
} catch (error) {
|
|
886
|
-
this.
|
|
930
|
+
await this._emitErrorHook("error:create", { context, error });
|
|
887
931
|
throw this._handleError(error);
|
|
888
932
|
}
|
|
889
933
|
}
|
|
@@ -894,10 +938,10 @@ var Repository = class {
|
|
|
894
938
|
const context = await this._buildContext("createMany", { dataArray, ...options });
|
|
895
939
|
try {
|
|
896
940
|
const result = await createMany(this.Model, context.dataArray || dataArray, options);
|
|
897
|
-
this.
|
|
941
|
+
await this._emitHook("after:createMany", { context, result });
|
|
898
942
|
return result;
|
|
899
943
|
} catch (error) {
|
|
900
|
-
this.
|
|
944
|
+
await this._emitErrorHook("error:createMany", { context, error });
|
|
901
945
|
throw this._handleError(error);
|
|
902
946
|
}
|
|
903
947
|
}
|
|
@@ -910,7 +954,7 @@ var Repository = class {
|
|
|
910
954
|
return context._cachedResult;
|
|
911
955
|
}
|
|
912
956
|
const result = await getById(this.Model, id, context);
|
|
913
|
-
this.
|
|
957
|
+
await this._emitHook("after:getById", { context, result });
|
|
914
958
|
return result;
|
|
915
959
|
}
|
|
916
960
|
/**
|
|
@@ -922,7 +966,7 @@ var Repository = class {
|
|
|
922
966
|
return context._cachedResult;
|
|
923
967
|
}
|
|
924
968
|
const result = await getByQuery(this.Model, query, context);
|
|
925
|
-
this.
|
|
969
|
+
await this._emitHook("after:getByQuery", { context, result });
|
|
926
970
|
return result;
|
|
927
971
|
}
|
|
928
972
|
/**
|
|
@@ -987,7 +1031,7 @@ var Repository = class {
|
|
|
987
1031
|
page
|
|
988
1032
|
});
|
|
989
1033
|
}
|
|
990
|
-
this.
|
|
1034
|
+
await this._emitHook("after:getAll", { context, result });
|
|
991
1035
|
return result;
|
|
992
1036
|
}
|
|
993
1037
|
/**
|
|
@@ -1015,10 +1059,10 @@ var Repository = class {
|
|
|
1015
1059
|
const context = await this._buildContext("update", { id, data, ...options });
|
|
1016
1060
|
try {
|
|
1017
1061
|
const result = await update(this.Model, id, context.data || data, context);
|
|
1018
|
-
this.
|
|
1062
|
+
await this._emitHook("after:update", { context, result });
|
|
1019
1063
|
return result;
|
|
1020
1064
|
} catch (error) {
|
|
1021
|
-
this.
|
|
1065
|
+
await this._emitErrorHook("error:update", { context, error });
|
|
1022
1066
|
throw this._handleError(error);
|
|
1023
1067
|
}
|
|
1024
1068
|
}
|
|
@@ -1030,14 +1074,14 @@ var Repository = class {
|
|
|
1030
1074
|
try {
|
|
1031
1075
|
if (context.softDeleted) {
|
|
1032
1076
|
const result2 = { success: true, message: "Soft deleted successfully" };
|
|
1033
|
-
await this.
|
|
1077
|
+
await this._emitHook("after:delete", { context, result: result2 });
|
|
1034
1078
|
return result2;
|
|
1035
1079
|
}
|
|
1036
1080
|
const result = await deleteById(this.Model, id, options);
|
|
1037
|
-
await this.
|
|
1081
|
+
await this._emitHook("after:delete", { context, result });
|
|
1038
1082
|
return result;
|
|
1039
1083
|
} catch (error) {
|
|
1040
|
-
this.
|
|
1084
|
+
await this._emitErrorHook("error:delete", { context, error });
|
|
1041
1085
|
throw this._handleError(error);
|
|
1042
1086
|
}
|
|
1043
1087
|
}
|
|
@@ -1086,10 +1130,10 @@ var Repository = class {
|
|
|
1086
1130
|
const context = await this._buildContext(operation, {});
|
|
1087
1131
|
try {
|
|
1088
1132
|
const result = await buildQuery(this.Model);
|
|
1089
|
-
this.
|
|
1133
|
+
await this._emitHook(`after:${operation}`, { context, result });
|
|
1090
1134
|
return result;
|
|
1091
1135
|
} catch (error) {
|
|
1092
|
-
this.
|
|
1136
|
+
await this._emitErrorHook(`error:${operation}`, { context, error });
|
|
1093
1137
|
throw this._handleError(error);
|
|
1094
1138
|
}
|
|
1095
1139
|
}
|
|
@@ -1570,9 +1614,16 @@ function batchOperationsPlugin() {
|
|
|
1570
1614
|
const context = await _buildContext.call(this, "updateMany", { query, data, options });
|
|
1571
1615
|
try {
|
|
1572
1616
|
this.emit("before:updateMany", context);
|
|
1617
|
+
if (Array.isArray(data) && options.updatePipeline !== true) {
|
|
1618
|
+
throw createError(
|
|
1619
|
+
400,
|
|
1620
|
+
"Update pipelines (array updates) are disabled by default; pass `{ updatePipeline: true }` to explicitly allow pipeline-style updates."
|
|
1621
|
+
);
|
|
1622
|
+
}
|
|
1573
1623
|
const result = await this.Model.updateMany(query, data, {
|
|
1574
1624
|
runValidators: true,
|
|
1575
|
-
session: options.session
|
|
1625
|
+
session: options.session,
|
|
1626
|
+
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
1576
1627
|
}).exec();
|
|
1577
1628
|
this.emit("after:updateMany", { context, result });
|
|
1578
1629
|
return result;
|
|
@@ -2239,8 +2290,8 @@ __export(actions_exports, {
|
|
|
2239
2290
|
});
|
|
2240
2291
|
|
|
2241
2292
|
// src/index.ts
|
|
2242
|
-
function createRepository(Model, plugins = []) {
|
|
2243
|
-
return new Repository(Model, plugins);
|
|
2293
|
+
function createRepository(Model, plugins = [], paginationConfig = {}, options = {}) {
|
|
2294
|
+
return new Repository(Model, plugins, paginationConfig, options);
|
|
2244
2295
|
}
|
|
2245
2296
|
var index_default = Repository;
|
|
2246
2297
|
/**
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Model } from 'mongoose';
|
|
2
|
-
import { A as AnyDocument, P as PaginationConfig, O as OffsetPaginationOptions, a as OffsetPaginationResult, K as KeysetPaginationOptions, b as KeysetPaginationResult, c as AggregatePaginationOptions, d as AggregatePaginationResult } from '../types-
|
|
2
|
+
import { A as AnyDocument, P as PaginationConfig, O as OffsetPaginationOptions, a as OffsetPaginationResult, K as KeysetPaginationOptions, b as KeysetPaginationResult, c as AggregatePaginationOptions, d as AggregatePaginationResult } from '../types-B3dPUKjs.js';
|
|
3
3
|
|
|
4
4
|
/**
|
|
5
5
|
* Pagination Engine
|
|
@@ -50,7 +50,7 @@ declare class PaginationEngine<TDoc = AnyDocument> {
|
|
|
50
50
|
* @param Model - Mongoose model to paginate
|
|
51
51
|
* @param config - Pagination configuration
|
|
52
52
|
*/
|
|
53
|
-
constructor(Model: Model<TDoc>, config?: PaginationConfig);
|
|
53
|
+
constructor(Model: Model<TDoc, any, any, any>, config?: PaginationConfig);
|
|
54
54
|
/**
|
|
55
55
|
* Offset-based pagination using skip/limit
|
|
56
56
|
* Best for small datasets and when users need random page access
|
|
@@ -171,6 +171,7 @@ var PaginationEngine = class {
|
|
|
171
171
|
* @param Model - Mongoose model to paginate
|
|
172
172
|
* @param config - Pagination configuration
|
|
173
173
|
*/
|
|
174
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
174
175
|
constructor(Model, config = {}) {
|
|
175
176
|
this.Model = Model;
|
|
176
177
|
this.config = {
|
package/dist/plugins/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { F as FieldPreset,
|
|
1
|
+
import { F as FieldPreset, r as Plugin, L as Logger, I as SoftDeleteOptions, t as RepositoryInstance, B as ValidatorDefinition, G as ValidationChainOptions, i as RepositoryContext, W as CacheOptions, _ as CascadeOptions } from '../types-B3dPUKjs.js';
|
|
2
2
|
import 'mongoose';
|
|
3
3
|
|
|
4
4
|
/**
|
package/dist/plugins/index.js
CHANGED
|
@@ -422,9 +422,16 @@ function batchOperationsPlugin() {
|
|
|
422
422
|
const context = await _buildContext.call(this, "updateMany", { query, data, options });
|
|
423
423
|
try {
|
|
424
424
|
this.emit("before:updateMany", context);
|
|
425
|
+
if (Array.isArray(data) && options.updatePipeline !== true) {
|
|
426
|
+
throw createError(
|
|
427
|
+
400,
|
|
428
|
+
"Update pipelines (array updates) are disabled by default; pass `{ updatePipeline: true }` to explicitly allow pipeline-style updates."
|
|
429
|
+
);
|
|
430
|
+
}
|
|
425
431
|
const result = await this.Model.updateMany(query, data, {
|
|
426
432
|
runValidators: true,
|
|
427
|
-
session: options.session
|
|
433
|
+
session: options.session,
|
|
434
|
+
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
428
435
|
}).exec();
|
|
429
436
|
this.emit("after:updateMany", { context, result });
|
|
430
437
|
return result;
|
|
@@ -24,6 +24,13 @@ type PopulateSpec = string | string[] | PopulateOptions | PopulateOptions[];
|
|
|
24
24
|
type SelectSpec = string | string[] | Record<string, 0 | 1>;
|
|
25
25
|
/** Filter query type for MongoDB queries (compatible with Mongoose 8 & 9) */
|
|
26
26
|
type FilterQuery<T> = Record<string, unknown>;
|
|
27
|
+
/** Hook execution mode */
|
|
28
|
+
type HookMode = 'sync' | 'async';
|
|
29
|
+
/** Repository options */
|
|
30
|
+
interface RepositoryOptions {
|
|
31
|
+
/** Whether repository event hooks are awaited */
|
|
32
|
+
hooks?: HookMode;
|
|
33
|
+
}
|
|
27
34
|
/** Pagination configuration */
|
|
28
35
|
interface PaginationConfig {
|
|
29
36
|
/** Default number of documents per page (default: 10) */
|
|
@@ -253,12 +260,13 @@ interface RepositoryInstance {
|
|
|
253
260
|
use(plugin: PluginType): this;
|
|
254
261
|
on(event: string, listener: (data: any) => void | Promise<void>): this;
|
|
255
262
|
emit(event: string, data: unknown): void;
|
|
263
|
+
emitAsync(event: string, data: unknown): Promise<void>;
|
|
256
264
|
registerMethod?(name: string, fn: Function): void;
|
|
257
265
|
hasMethod?(name: string): boolean;
|
|
258
266
|
[key: string]: unknown;
|
|
259
267
|
}
|
|
260
268
|
/** Repository event names */
|
|
261
|
-
type RepositoryEvent = 'before:create' | 'after:create' | 'error:create' | 'before:createMany' | 'after:createMany' | 'error:createMany' | 'before:update' | 'after:update' | 'error:update' | 'before:updateMany' | 'after:updateMany' | 'error:updateMany' | 'before:delete' | 'after:delete' | 'error:delete' | 'before:deleteMany' | 'after:deleteMany' | 'error:deleteMany' | 'before:getById' | 'after:getById' | 'before:getByQuery' | 'after:getByQuery' | 'before:getAll' | 'after:getAll' | 'before:aggregatePaginate' | 'method:registered';
|
|
269
|
+
type RepositoryEvent = 'before:create' | 'after:create' | 'error:create' | 'before:createMany' | 'after:createMany' | 'error:createMany' | 'before:update' | 'after:update' | 'error:update' | 'before:updateMany' | 'after:updateMany' | 'error:updateMany' | 'before:delete' | 'after:delete' | 'error:delete' | 'before:deleteMany' | 'after:deleteMany' | 'error:deleteMany' | 'before:getById' | 'after:getById' | 'before:getByQuery' | 'after:getByQuery' | 'before:getAll' | 'after:getAll' | 'before:aggregatePaginate' | 'method:registered' | 'error:hook';
|
|
262
270
|
/** Event payload */
|
|
263
271
|
interface EventPayload {
|
|
264
272
|
context: RepositoryContext;
|
|
@@ -525,4 +533,4 @@ interface HttpError extends Error {
|
|
|
525
533
|
}>;
|
|
526
534
|
}
|
|
527
535
|
|
|
528
|
-
export type { AnyDocument as A,
|
|
536
|
+
export type { AnyDocument as A, ValidatorDefinition as B, CreateOptions as C, DeleteResult as D, EventPayload as E, FieldPreset as F, ValidationChainOptions as G, HttpError as H, SoftDeleteOptions as I, JsonSchema as J, KeysetPaginationOptions as K, Logger as L, LookupOptions as M, GroupResult as N, OffsetPaginationOptions as O, PaginationConfig as P, MinMaxResult as Q, RepositoryOptions as R, SelectSpec as S, CacheAdapter as T, UpdateOptions as U, ValidationResult as V, CacheOptions as W, CacheOperationOptions as X, CacheStats as Y, CascadeRelation as Z, CascadeOptions as _, OffsetPaginationResult as a, KeysetPaginationResult as b, AggregatePaginationOptions as c, AggregatePaginationResult as d, PluginType as e, ObjectId as f, PopulateSpec as g, SortSpec as h, RepositoryContext as i, AnyModel as j, SortDirection as k, HookMode as l, PaginationResult as m, OperationOptions as n, UpdateManyResult as o, UpdateWithValidationResult as p, UserContext as q, Plugin as r, PluginFunction as s, RepositoryInstance as t, RepositoryEvent as u, ParsedQuery as v, FieldRules as w, SchemaBuilderOptions as x, CrudSchemas as y, DecodedCursor as z };
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export { b as createError, c as createFieldPreset, d as createMemoryCache, f as filterResponseData, g as getFieldsForUser, a as getMongooseProjection } from '../memory-cache-
|
|
2
|
-
import {
|
|
1
|
+
export { b as createError, c as createFieldPreset, d as createMemoryCache, f as filterResponseData, g as getFieldsForUser, a as getMongooseProjection } from '../memory-cache-Bn_-Kk-0.js';
|
|
2
|
+
import { v as ParsedQuery, x as SchemaBuilderOptions, y as CrudSchemas, V as ValidationResult, S as SelectSpec, g as PopulateSpec, h as SortSpec } from '../types-B3dPUKjs.js';
|
|
3
3
|
import mongoose__default, { Schema } from 'mongoose';
|
|
4
4
|
|
|
5
5
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@classytic/mongokit",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.3",
|
|
4
4
|
"description": "Production-grade MongoDB repositories with zero dependencies - smart pagination, events, and plugins",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -91,6 +91,7 @@
|
|
|
91
91
|
"devDependencies": {
|
|
92
92
|
"@types/node": "^22.0.0",
|
|
93
93
|
"@vitest/coverage-v8": "^3.2.4",
|
|
94
|
+
"mongodb-memory-server": "^10.2.3",
|
|
94
95
|
"mongoose": "^9.0.0",
|
|
95
96
|
"tsup": "^8.0.0",
|
|
96
97
|
"typescript": "^5.7.0",
|