@classytic/mongokit 3.1.0 → 3.1.1
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 +625 -465
- package/dist/actions/index.d.ts +2 -2
- package/dist/actions/index.js +3 -515
- package/dist/chunks/chunk-2ZN65ZOP.js +93 -0
- package/dist/chunks/chunk-CF6FLC2G.js +46 -0
- package/dist/chunks/chunk-CSLJ2PL2.js +1092 -0
- package/dist/chunks/chunk-IT7DCOKR.js +299 -0
- package/dist/chunks/chunk-M2XHQGZB.js +361 -0
- package/dist/chunks/chunk-SAKSLT47.js +470 -0
- package/dist/chunks/chunk-VJXDGP3C.js +14 -0
- package/dist/{index-3Nkm_Brq.d.ts → index-C2NCVxJK.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +49 -2387
- package/dist/{mongooseToJsonSchema-CUQma8QK.d.ts → mongooseToJsonSchema-BKMxPbPp.d.ts} +1 -1
- package/dist/pagination/PaginationEngine.d.ts +1 -1
- package/dist/pagination/PaginationEngine.js +2 -368
- package/dist/plugins/index.d.ts +1 -1
- package/dist/plugins/index.js +4 -1170
- package/dist/{types-CrSoCuWu.d.ts → types-DA0rs2Jh.d.ts} +99 -5
- package/dist/utils/index.d.ts +2 -2
- package/dist/utils/index.js +3 -398
- package/package.json +8 -3
package/dist/actions/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export { b as aggregate, c as create, _ as deleteActions, r as read, u as update } from '../index-
|
|
1
|
+
export { b as aggregate, c as create, _ as deleteActions, r as read, u as update } from '../index-C2NCVxJK.js';
|
|
2
2
|
import 'mongoose';
|
|
3
|
-
import '../types-
|
|
3
|
+
import '../types-DA0rs2Jh.js';
|
package/dist/actions/index.js
CHANGED
|
@@ -1,515 +1,3 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
5
|
-
};
|
|
6
|
-
|
|
7
|
-
// src/actions/create.ts
|
|
8
|
-
var create_exports = {};
|
|
9
|
-
__export(create_exports, {
|
|
10
|
-
create: () => create,
|
|
11
|
-
createDefault: () => createDefault,
|
|
12
|
-
createMany: () => createMany,
|
|
13
|
-
upsert: () => upsert
|
|
14
|
-
});
|
|
15
|
-
async function create(Model, data, options = {}) {
|
|
16
|
-
const document = new Model(data);
|
|
17
|
-
await document.save({ session: options.session });
|
|
18
|
-
return document;
|
|
19
|
-
}
|
|
20
|
-
async function createMany(Model, dataArray, options = {}) {
|
|
21
|
-
return Model.insertMany(dataArray, {
|
|
22
|
-
session: options.session,
|
|
23
|
-
ordered: options.ordered !== false
|
|
24
|
-
});
|
|
25
|
-
}
|
|
26
|
-
async function createDefault(Model, overrides = {}, options = {}) {
|
|
27
|
-
const defaults = {};
|
|
28
|
-
Model.schema.eachPath((path, schemaType) => {
|
|
29
|
-
const schemaOptions = schemaType.options;
|
|
30
|
-
if (schemaOptions.default !== void 0 && path !== "_id") {
|
|
31
|
-
defaults[path] = typeof schemaOptions.default === "function" ? schemaOptions.default() : schemaOptions.default;
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
return create(Model, { ...defaults, ...overrides }, options);
|
|
35
|
-
}
|
|
36
|
-
async function upsert(Model, query, data, options = {}) {
|
|
37
|
-
return Model.findOneAndUpdate(
|
|
38
|
-
query,
|
|
39
|
-
{ $setOnInsert: data },
|
|
40
|
-
{
|
|
41
|
-
upsert: true,
|
|
42
|
-
new: true,
|
|
43
|
-
runValidators: true,
|
|
44
|
-
session: options.session,
|
|
45
|
-
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
46
|
-
}
|
|
47
|
-
);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
// src/actions/read.ts
|
|
51
|
-
var read_exports = {};
|
|
52
|
-
__export(read_exports, {
|
|
53
|
-
count: () => count,
|
|
54
|
-
exists: () => exists,
|
|
55
|
-
getAll: () => getAll,
|
|
56
|
-
getById: () => getById,
|
|
57
|
-
getByQuery: () => getByQuery,
|
|
58
|
-
getOrCreate: () => getOrCreate,
|
|
59
|
-
tryGetByQuery: () => tryGetByQuery
|
|
60
|
-
});
|
|
61
|
-
|
|
62
|
-
// src/utils/error.ts
|
|
63
|
-
function createError(status, message) {
|
|
64
|
-
const error = new Error(message);
|
|
65
|
-
error.status = status;
|
|
66
|
-
return error;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// src/actions/read.ts
|
|
70
|
-
function parsePopulate(populate) {
|
|
71
|
-
if (!populate) return [];
|
|
72
|
-
if (typeof populate === "string") {
|
|
73
|
-
return populate.split(",").map((p) => p.trim());
|
|
74
|
-
}
|
|
75
|
-
if (Array.isArray(populate)) {
|
|
76
|
-
return populate.map((p) => typeof p === "string" ? p.trim() : p);
|
|
77
|
-
}
|
|
78
|
-
return [populate];
|
|
79
|
-
}
|
|
80
|
-
async function getById(Model, id, options = {}) {
|
|
81
|
-
const query = options.query ? Model.findOne({ _id: id, ...options.query }) : Model.findById(id);
|
|
82
|
-
if (options.select) query.select(options.select);
|
|
83
|
-
if (options.populate) query.populate(parsePopulate(options.populate));
|
|
84
|
-
if (options.lean) query.lean();
|
|
85
|
-
if (options.session) query.session(options.session);
|
|
86
|
-
const document = await query.exec();
|
|
87
|
-
if (!document && options.throwOnNotFound !== false) {
|
|
88
|
-
throw createError(404, "Document not found");
|
|
89
|
-
}
|
|
90
|
-
return document;
|
|
91
|
-
}
|
|
92
|
-
async function getByQuery(Model, query, options = {}) {
|
|
93
|
-
const mongoQuery = Model.findOne(query);
|
|
94
|
-
if (options.select) mongoQuery.select(options.select);
|
|
95
|
-
if (options.populate) mongoQuery.populate(parsePopulate(options.populate));
|
|
96
|
-
if (options.lean) mongoQuery.lean();
|
|
97
|
-
if (options.session) mongoQuery.session(options.session);
|
|
98
|
-
const document = await mongoQuery.exec();
|
|
99
|
-
if (!document && options.throwOnNotFound !== false) {
|
|
100
|
-
throw createError(404, "Document not found");
|
|
101
|
-
}
|
|
102
|
-
return document;
|
|
103
|
-
}
|
|
104
|
-
async function tryGetByQuery(Model, query, options = {}) {
|
|
105
|
-
return getByQuery(Model, query, { ...options, throwOnNotFound: false });
|
|
106
|
-
}
|
|
107
|
-
async function getAll(Model, query = {}, options = {}) {
|
|
108
|
-
let mongoQuery = Model.find(query);
|
|
109
|
-
if (options.select) mongoQuery = mongoQuery.select(options.select);
|
|
110
|
-
if (options.populate) mongoQuery = mongoQuery.populate(parsePopulate(options.populate));
|
|
111
|
-
if (options.sort) mongoQuery = mongoQuery.sort(options.sort);
|
|
112
|
-
if (options.limit) mongoQuery = mongoQuery.limit(options.limit);
|
|
113
|
-
if (options.skip) mongoQuery = mongoQuery.skip(options.skip);
|
|
114
|
-
mongoQuery = mongoQuery.lean(options.lean !== false);
|
|
115
|
-
if (options.session) mongoQuery = mongoQuery.session(options.session);
|
|
116
|
-
return mongoQuery.exec();
|
|
117
|
-
}
|
|
118
|
-
async function getOrCreate(Model, query, createData, options = {}) {
|
|
119
|
-
return Model.findOneAndUpdate(
|
|
120
|
-
query,
|
|
121
|
-
{ $setOnInsert: createData },
|
|
122
|
-
{
|
|
123
|
-
upsert: true,
|
|
124
|
-
new: true,
|
|
125
|
-
runValidators: true,
|
|
126
|
-
session: options.session,
|
|
127
|
-
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
128
|
-
}
|
|
129
|
-
);
|
|
130
|
-
}
|
|
131
|
-
async function count(Model, query = {}, options = {}) {
|
|
132
|
-
return Model.countDocuments(query).session(options.session ?? null);
|
|
133
|
-
}
|
|
134
|
-
async function exists(Model, query, options = {}) {
|
|
135
|
-
return Model.exists(query).session(options.session ?? null);
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// src/actions/update.ts
|
|
139
|
-
var update_exports = {};
|
|
140
|
-
__export(update_exports, {
|
|
141
|
-
increment: () => increment,
|
|
142
|
-
pullFromArray: () => pullFromArray,
|
|
143
|
-
pushToArray: () => pushToArray,
|
|
144
|
-
update: () => update,
|
|
145
|
-
updateByQuery: () => updateByQuery,
|
|
146
|
-
updateMany: () => updateMany,
|
|
147
|
-
updateWithConstraints: () => updateWithConstraints,
|
|
148
|
-
updateWithValidation: () => updateWithValidation
|
|
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
|
-
}
|
|
158
|
-
function parsePopulate2(populate) {
|
|
159
|
-
if (!populate) return [];
|
|
160
|
-
if (typeof populate === "string") {
|
|
161
|
-
return populate.split(",").map((p) => p.trim());
|
|
162
|
-
}
|
|
163
|
-
if (Array.isArray(populate)) {
|
|
164
|
-
return populate.map((p) => typeof p === "string" ? p.trim() : p);
|
|
165
|
-
}
|
|
166
|
-
return [populate];
|
|
167
|
-
}
|
|
168
|
-
async function update(Model, id, data, options = {}) {
|
|
169
|
-
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
170
|
-
const document = await Model.findByIdAndUpdate(id, data, {
|
|
171
|
-
new: true,
|
|
172
|
-
runValidators: true,
|
|
173
|
-
session: options.session,
|
|
174
|
-
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
175
|
-
}).select(options.select || "").populate(parsePopulate2(options.populate)).lean(options.lean ?? false);
|
|
176
|
-
if (!document) {
|
|
177
|
-
throw createError(404, "Document not found");
|
|
178
|
-
}
|
|
179
|
-
return document;
|
|
180
|
-
}
|
|
181
|
-
async function updateWithConstraints(Model, id, data, constraints = {}, options = {}) {
|
|
182
|
-
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
183
|
-
const query = { _id: id, ...constraints };
|
|
184
|
-
const document = await Model.findOneAndUpdate(query, data, {
|
|
185
|
-
new: true,
|
|
186
|
-
runValidators: true,
|
|
187
|
-
session: options.session,
|
|
188
|
-
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
189
|
-
}).select(options.select || "").populate(parsePopulate2(options.populate)).lean(options.lean ?? false);
|
|
190
|
-
return document;
|
|
191
|
-
}
|
|
192
|
-
async function updateWithValidation(Model, id, data, validationOptions = {}, options = {}) {
|
|
193
|
-
const { buildConstraints, validateUpdate } = validationOptions;
|
|
194
|
-
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
195
|
-
if (buildConstraints) {
|
|
196
|
-
const constraints = buildConstraints(data);
|
|
197
|
-
const document = await updateWithConstraints(Model, id, data, constraints, options);
|
|
198
|
-
if (document) {
|
|
199
|
-
return { success: true, data: document };
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
const existing = await Model.findById(id).select(options.select || "").lean();
|
|
203
|
-
if (!existing) {
|
|
204
|
-
return {
|
|
205
|
-
success: false,
|
|
206
|
-
error: {
|
|
207
|
-
code: 404,
|
|
208
|
-
message: "Document not found"
|
|
209
|
-
}
|
|
210
|
-
};
|
|
211
|
-
}
|
|
212
|
-
if (validateUpdate) {
|
|
213
|
-
const validation = validateUpdate(existing, data);
|
|
214
|
-
if (!validation.valid) {
|
|
215
|
-
return {
|
|
216
|
-
success: false,
|
|
217
|
-
error: {
|
|
218
|
-
code: 403,
|
|
219
|
-
message: validation.message || "Update not allowed",
|
|
220
|
-
violations: validation.violations
|
|
221
|
-
}
|
|
222
|
-
};
|
|
223
|
-
}
|
|
224
|
-
}
|
|
225
|
-
const updated = await update(Model, id, data, options);
|
|
226
|
-
return { success: true, data: updated };
|
|
227
|
-
}
|
|
228
|
-
async function updateMany(Model, query, data, options = {}) {
|
|
229
|
-
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
230
|
-
const result = await Model.updateMany(query, data, {
|
|
231
|
-
runValidators: true,
|
|
232
|
-
session: options.session,
|
|
233
|
-
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
234
|
-
});
|
|
235
|
-
return {
|
|
236
|
-
matchedCount: result.matchedCount,
|
|
237
|
-
modifiedCount: result.modifiedCount
|
|
238
|
-
};
|
|
239
|
-
}
|
|
240
|
-
async function updateByQuery(Model, query, data, options = {}) {
|
|
241
|
-
assertUpdatePipelineAllowed(data, options.updatePipeline);
|
|
242
|
-
const document = await Model.findOneAndUpdate(query, data, {
|
|
243
|
-
new: true,
|
|
244
|
-
runValidators: true,
|
|
245
|
-
session: options.session,
|
|
246
|
-
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
247
|
-
}).select(options.select || "").populate(parsePopulate2(options.populate)).lean(options.lean ?? false);
|
|
248
|
-
if (!document && options.throwOnNotFound !== false) {
|
|
249
|
-
throw createError(404, "Document not found");
|
|
250
|
-
}
|
|
251
|
-
return document;
|
|
252
|
-
}
|
|
253
|
-
async function increment(Model, id, field, value = 1, options = {}) {
|
|
254
|
-
return update(Model, id, { $inc: { [field]: value } }, options);
|
|
255
|
-
}
|
|
256
|
-
async function pushToArray(Model, id, field, value, options = {}) {
|
|
257
|
-
return update(Model, id, { $push: { [field]: value } }, options);
|
|
258
|
-
}
|
|
259
|
-
async function pullFromArray(Model, id, field, value, options = {}) {
|
|
260
|
-
return update(Model, id, { $pull: { [field]: value } }, options);
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// src/actions/delete.ts
|
|
264
|
-
var delete_exports = {};
|
|
265
|
-
__export(delete_exports, {
|
|
266
|
-
deleteById: () => deleteById,
|
|
267
|
-
deleteByQuery: () => deleteByQuery,
|
|
268
|
-
deleteMany: () => deleteMany,
|
|
269
|
-
restore: () => restore,
|
|
270
|
-
softDelete: () => softDelete
|
|
271
|
-
});
|
|
272
|
-
async function deleteById(Model, id, options = {}) {
|
|
273
|
-
const document = await Model.findByIdAndDelete(id).session(options.session ?? null);
|
|
274
|
-
if (!document) {
|
|
275
|
-
throw createError(404, "Document not found");
|
|
276
|
-
}
|
|
277
|
-
return { success: true, message: "Deleted successfully" };
|
|
278
|
-
}
|
|
279
|
-
async function deleteMany(Model, query, options = {}) {
|
|
280
|
-
const result = await Model.deleteMany(query).session(options.session ?? null);
|
|
281
|
-
return {
|
|
282
|
-
success: true,
|
|
283
|
-
count: result.deletedCount,
|
|
284
|
-
message: "Deleted successfully"
|
|
285
|
-
};
|
|
286
|
-
}
|
|
287
|
-
async function deleteByQuery(Model, query, options = {}) {
|
|
288
|
-
const document = await Model.findOneAndDelete(query).session(options.session ?? null);
|
|
289
|
-
if (!document && options.throwOnNotFound !== false) {
|
|
290
|
-
throw createError(404, "Document not found");
|
|
291
|
-
}
|
|
292
|
-
return { success: true, message: "Deleted successfully" };
|
|
293
|
-
}
|
|
294
|
-
async function softDelete(Model, id, options = {}) {
|
|
295
|
-
const document = await Model.findByIdAndUpdate(
|
|
296
|
-
id,
|
|
297
|
-
{
|
|
298
|
-
deleted: true,
|
|
299
|
-
deletedAt: /* @__PURE__ */ new Date(),
|
|
300
|
-
deletedBy: options.userId
|
|
301
|
-
},
|
|
302
|
-
{ new: true, session: options.session }
|
|
303
|
-
);
|
|
304
|
-
if (!document) {
|
|
305
|
-
throw createError(404, "Document not found");
|
|
306
|
-
}
|
|
307
|
-
return { success: true, message: "Soft deleted successfully" };
|
|
308
|
-
}
|
|
309
|
-
async function restore(Model, id, options = {}) {
|
|
310
|
-
const document = await Model.findByIdAndUpdate(
|
|
311
|
-
id,
|
|
312
|
-
{
|
|
313
|
-
deleted: false,
|
|
314
|
-
deletedAt: null,
|
|
315
|
-
deletedBy: null
|
|
316
|
-
},
|
|
317
|
-
{ new: true, session: options.session }
|
|
318
|
-
);
|
|
319
|
-
if (!document) {
|
|
320
|
-
throw createError(404, "Document not found");
|
|
321
|
-
}
|
|
322
|
-
return { success: true, message: "Restored successfully" };
|
|
323
|
-
}
|
|
324
|
-
|
|
325
|
-
// src/actions/aggregate.ts
|
|
326
|
-
var aggregate_exports = {};
|
|
327
|
-
__export(aggregate_exports, {
|
|
328
|
-
aggregate: () => aggregate,
|
|
329
|
-
aggregatePaginate: () => aggregatePaginate,
|
|
330
|
-
average: () => average,
|
|
331
|
-
countBy: () => countBy,
|
|
332
|
-
distinct: () => distinct,
|
|
333
|
-
facet: () => facet,
|
|
334
|
-
groupBy: () => groupBy,
|
|
335
|
-
lookup: () => lookup,
|
|
336
|
-
minMax: () => minMax,
|
|
337
|
-
sum: () => sum,
|
|
338
|
-
unwind: () => unwind
|
|
339
|
-
});
|
|
340
|
-
async function aggregate(Model, pipeline, options = {}) {
|
|
341
|
-
const aggregation = Model.aggregate(pipeline);
|
|
342
|
-
if (options.session) {
|
|
343
|
-
aggregation.session(options.session);
|
|
344
|
-
}
|
|
345
|
-
return aggregation.exec();
|
|
346
|
-
}
|
|
347
|
-
async function aggregatePaginate(Model, pipeline, options = {}) {
|
|
348
|
-
const page = parseInt(String(options.page || 1), 10);
|
|
349
|
-
const limit = parseInt(String(options.limit || 10), 10);
|
|
350
|
-
const skip = (page - 1) * limit;
|
|
351
|
-
const SAFE_LIMIT = 1e3;
|
|
352
|
-
if (limit > SAFE_LIMIT) {
|
|
353
|
-
console.warn(
|
|
354
|
-
`[mongokit] Large aggregation limit (${limit}). $facet results must be <16MB. Consider using Repository.aggregatePaginate() for safer handling of large datasets.`
|
|
355
|
-
);
|
|
356
|
-
}
|
|
357
|
-
const facetPipeline = [
|
|
358
|
-
...pipeline,
|
|
359
|
-
{
|
|
360
|
-
$facet: {
|
|
361
|
-
docs: [{ $skip: skip }, { $limit: limit }],
|
|
362
|
-
total: [{ $count: "count" }]
|
|
363
|
-
}
|
|
364
|
-
}
|
|
365
|
-
];
|
|
366
|
-
const aggregation = Model.aggregate(facetPipeline);
|
|
367
|
-
if (options.session) {
|
|
368
|
-
aggregation.session(options.session);
|
|
369
|
-
}
|
|
370
|
-
const [result] = await aggregation.exec();
|
|
371
|
-
const docs = result.docs || [];
|
|
372
|
-
const total = result.total[0]?.count || 0;
|
|
373
|
-
const pages = Math.ceil(total / limit);
|
|
374
|
-
return {
|
|
375
|
-
docs,
|
|
376
|
-
total,
|
|
377
|
-
page,
|
|
378
|
-
limit,
|
|
379
|
-
pages,
|
|
380
|
-
hasNext: page < pages,
|
|
381
|
-
hasPrev: page > 1
|
|
382
|
-
};
|
|
383
|
-
}
|
|
384
|
-
async function groupBy(Model, field, options = {}) {
|
|
385
|
-
const pipeline = [
|
|
386
|
-
{ $group: { _id: `$${field}`, count: { $sum: 1 } } },
|
|
387
|
-
{ $sort: { count: -1 } }
|
|
388
|
-
];
|
|
389
|
-
if (options.limit) {
|
|
390
|
-
pipeline.push({ $limit: options.limit });
|
|
391
|
-
}
|
|
392
|
-
return aggregate(Model, pipeline, options);
|
|
393
|
-
}
|
|
394
|
-
async function countBy(Model, field, query = {}, options = {}) {
|
|
395
|
-
const pipeline = [];
|
|
396
|
-
if (Object.keys(query).length > 0) {
|
|
397
|
-
pipeline.push({ $match: query });
|
|
398
|
-
}
|
|
399
|
-
pipeline.push(
|
|
400
|
-
{ $group: { _id: `$${field}`, count: { $sum: 1 } } },
|
|
401
|
-
{ $sort: { count: -1 } }
|
|
402
|
-
);
|
|
403
|
-
return aggregate(Model, pipeline, options);
|
|
404
|
-
}
|
|
405
|
-
async function lookup(Model, lookupOptions) {
|
|
406
|
-
const { from, localField, foreignField, as, pipeline = [], let: letVars, query = {}, options = {} } = lookupOptions;
|
|
407
|
-
const aggPipeline = [];
|
|
408
|
-
if (Object.keys(query).length > 0) {
|
|
409
|
-
aggPipeline.push({ $match: query });
|
|
410
|
-
}
|
|
411
|
-
const usePipelineForm = pipeline.length > 0 || letVars;
|
|
412
|
-
if (usePipelineForm) {
|
|
413
|
-
if (pipeline.length === 0 && localField && foreignField) {
|
|
414
|
-
const autoPipeline = [
|
|
415
|
-
{
|
|
416
|
-
$match: {
|
|
417
|
-
$expr: {
|
|
418
|
-
$eq: [`$${foreignField}`, `$$${localField}`]
|
|
419
|
-
}
|
|
420
|
-
}
|
|
421
|
-
}
|
|
422
|
-
];
|
|
423
|
-
aggPipeline.push({
|
|
424
|
-
$lookup: {
|
|
425
|
-
from,
|
|
426
|
-
let: { [localField]: `$${localField}`, ...letVars || {} },
|
|
427
|
-
pipeline: autoPipeline,
|
|
428
|
-
as
|
|
429
|
-
}
|
|
430
|
-
});
|
|
431
|
-
} else {
|
|
432
|
-
aggPipeline.push({
|
|
433
|
-
$lookup: {
|
|
434
|
-
from,
|
|
435
|
-
...letVars && { let: letVars },
|
|
436
|
-
pipeline,
|
|
437
|
-
as
|
|
438
|
-
}
|
|
439
|
-
});
|
|
440
|
-
}
|
|
441
|
-
} else {
|
|
442
|
-
aggPipeline.push({
|
|
443
|
-
$lookup: {
|
|
444
|
-
from,
|
|
445
|
-
localField,
|
|
446
|
-
foreignField,
|
|
447
|
-
as
|
|
448
|
-
}
|
|
449
|
-
});
|
|
450
|
-
}
|
|
451
|
-
return aggregate(Model, aggPipeline, options);
|
|
452
|
-
}
|
|
453
|
-
async function unwind(Model, field, options = {}) {
|
|
454
|
-
const pipeline = [
|
|
455
|
-
{
|
|
456
|
-
$unwind: {
|
|
457
|
-
path: `$${field}`,
|
|
458
|
-
preserveNullAndEmptyArrays: options.preserveEmpty !== false
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
];
|
|
462
|
-
return aggregate(Model, pipeline, { session: options.session });
|
|
463
|
-
}
|
|
464
|
-
async function facet(Model, facets, options = {}) {
|
|
465
|
-
const pipeline = [{ $facet: facets }];
|
|
466
|
-
return aggregate(Model, pipeline, options);
|
|
467
|
-
}
|
|
468
|
-
async function distinct(Model, field, query = {}, options = {}) {
|
|
469
|
-
return Model.distinct(field, query).session(options.session ?? null);
|
|
470
|
-
}
|
|
471
|
-
async function sum(Model, field, query = {}, options = {}) {
|
|
472
|
-
const pipeline = [];
|
|
473
|
-
if (Object.keys(query).length > 0) {
|
|
474
|
-
pipeline.push({ $match: query });
|
|
475
|
-
}
|
|
476
|
-
pipeline.push({
|
|
477
|
-
$group: {
|
|
478
|
-
_id: null,
|
|
479
|
-
total: { $sum: `$${field}` }
|
|
480
|
-
}
|
|
481
|
-
});
|
|
482
|
-
const result = await aggregate(Model, pipeline, options);
|
|
483
|
-
return result[0]?.total || 0;
|
|
484
|
-
}
|
|
485
|
-
async function average(Model, field, query = {}, options = {}) {
|
|
486
|
-
const pipeline = [];
|
|
487
|
-
if (Object.keys(query).length > 0) {
|
|
488
|
-
pipeline.push({ $match: query });
|
|
489
|
-
}
|
|
490
|
-
pipeline.push({
|
|
491
|
-
$group: {
|
|
492
|
-
_id: null,
|
|
493
|
-
average: { $avg: `$${field}` }
|
|
494
|
-
}
|
|
495
|
-
});
|
|
496
|
-
const result = await aggregate(Model, pipeline, options);
|
|
497
|
-
return result[0]?.average || 0;
|
|
498
|
-
}
|
|
499
|
-
async function minMax(Model, field, query = {}, options = {}) {
|
|
500
|
-
const pipeline = [];
|
|
501
|
-
if (Object.keys(query).length > 0) {
|
|
502
|
-
pipeline.push({ $match: query });
|
|
503
|
-
}
|
|
504
|
-
pipeline.push({
|
|
505
|
-
$group: {
|
|
506
|
-
_id: null,
|
|
507
|
-
min: { $min: `$${field}` },
|
|
508
|
-
max: { $max: `$${field}` }
|
|
509
|
-
}
|
|
510
|
-
});
|
|
511
|
-
const result = await aggregate(Model, pipeline, options);
|
|
512
|
-
return result[0] || { min: null, max: null };
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
export { aggregate_exports as aggregate, create_exports as create, delete_exports as deleteActions, read_exports as read, update_exports as update };
|
|
1
|
+
export { aggregate_exports as aggregate, delete_exports as deleteActions, read_exports as read, update_exports as update } from '../chunks/chunk-SAKSLT47.js';
|
|
2
|
+
export { create_exports as create } from '../chunks/chunk-CF6FLC2G.js';
|
|
3
|
+
import '../chunks/chunk-VJXDGP3C.js';
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
// src/utils/field-selection.ts
|
|
2
|
+
function getFieldsForUser(user, preset) {
|
|
3
|
+
if (!preset) {
|
|
4
|
+
throw new Error("Field preset is required");
|
|
5
|
+
}
|
|
6
|
+
const fields = [...preset.public || []];
|
|
7
|
+
if (user) {
|
|
8
|
+
fields.push(...preset.authenticated || []);
|
|
9
|
+
const roles = Array.isArray(user.roles) ? user.roles : user.roles ? [user.roles] : [];
|
|
10
|
+
if (roles.includes("admin") || roles.includes("superadmin")) {
|
|
11
|
+
fields.push(...preset.admin || []);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return [...new Set(fields)];
|
|
15
|
+
}
|
|
16
|
+
function getMongooseProjection(user, preset) {
|
|
17
|
+
const fields = getFieldsForUser(user, preset);
|
|
18
|
+
return fields.join(" ");
|
|
19
|
+
}
|
|
20
|
+
function filterObject(obj, allowedFields) {
|
|
21
|
+
if (!obj || typeof obj !== "object" || Array.isArray(obj)) {
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
24
|
+
const filtered = {};
|
|
25
|
+
for (const field of allowedFields) {
|
|
26
|
+
if (field in obj) {
|
|
27
|
+
filtered[field] = obj[field];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return filtered;
|
|
31
|
+
}
|
|
32
|
+
function filterResponseData(data, preset, user = null) {
|
|
33
|
+
const allowedFields = getFieldsForUser(user, preset);
|
|
34
|
+
if (Array.isArray(data)) {
|
|
35
|
+
return data.map((item) => filterObject(item, allowedFields));
|
|
36
|
+
}
|
|
37
|
+
return filterObject(data, allowedFields);
|
|
38
|
+
}
|
|
39
|
+
function createFieldPreset(config) {
|
|
40
|
+
return {
|
|
41
|
+
public: config.public || [],
|
|
42
|
+
authenticated: config.authenticated || [],
|
|
43
|
+
admin: config.admin || []
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// src/utils/cache-keys.ts
|
|
48
|
+
function hashString(str) {
|
|
49
|
+
let hash = 5381;
|
|
50
|
+
for (let i = 0; i < str.length; i++) {
|
|
51
|
+
hash = (hash << 5) + hash ^ str.charCodeAt(i);
|
|
52
|
+
}
|
|
53
|
+
return (hash >>> 0).toString(16);
|
|
54
|
+
}
|
|
55
|
+
function stableStringify(obj) {
|
|
56
|
+
if (obj === null || obj === void 0) return "";
|
|
57
|
+
if (typeof obj !== "object") return String(obj);
|
|
58
|
+
if (Array.isArray(obj)) {
|
|
59
|
+
return "[" + obj.map(stableStringify).join(",") + "]";
|
|
60
|
+
}
|
|
61
|
+
const sorted = Object.keys(obj).sort().map((key) => `${key}:${stableStringify(obj[key])}`);
|
|
62
|
+
return "{" + sorted.join(",") + "}";
|
|
63
|
+
}
|
|
64
|
+
function byIdKey(prefix, model, id) {
|
|
65
|
+
return `${prefix}:id:${model}:${id}`;
|
|
66
|
+
}
|
|
67
|
+
function byQueryKey(prefix, model, query, options) {
|
|
68
|
+
const hashInput = stableStringify({ q: query, s: options?.select, p: options?.populate });
|
|
69
|
+
return `${prefix}:one:${model}:${hashString(hashInput)}`;
|
|
70
|
+
}
|
|
71
|
+
function listQueryKey(prefix, model, version, params) {
|
|
72
|
+
const hashInput = stableStringify({
|
|
73
|
+
f: params.filters,
|
|
74
|
+
s: params.sort,
|
|
75
|
+
pg: params.page,
|
|
76
|
+
lm: params.limit,
|
|
77
|
+
af: params.after,
|
|
78
|
+
sl: params.select,
|
|
79
|
+
pp: params.populate
|
|
80
|
+
});
|
|
81
|
+
return `${prefix}:list:${model}:${version}:${hashString(hashInput)}`;
|
|
82
|
+
}
|
|
83
|
+
function versionKey(prefix, model) {
|
|
84
|
+
return `${prefix}:ver:${model}`;
|
|
85
|
+
}
|
|
86
|
+
function modelPattern(prefix, model) {
|
|
87
|
+
return `${prefix}:*:${model}:*`;
|
|
88
|
+
}
|
|
89
|
+
function listPattern(prefix, model) {
|
|
90
|
+
return `${prefix}:list:${model}:*`;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export { byIdKey, byQueryKey, createFieldPreset, filterResponseData, getFieldsForUser, getMongooseProjection, listPattern, listQueryKey, modelPattern, versionKey };
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { __export } from './chunk-VJXDGP3C.js';
|
|
2
|
+
|
|
3
|
+
// src/actions/create.ts
|
|
4
|
+
var create_exports = {};
|
|
5
|
+
__export(create_exports, {
|
|
6
|
+
create: () => create,
|
|
7
|
+
createDefault: () => createDefault,
|
|
8
|
+
createMany: () => createMany,
|
|
9
|
+
upsert: () => upsert
|
|
10
|
+
});
|
|
11
|
+
async function create(Model, data, options = {}) {
|
|
12
|
+
const document = new Model(data);
|
|
13
|
+
await document.save({ session: options.session });
|
|
14
|
+
return document;
|
|
15
|
+
}
|
|
16
|
+
async function createMany(Model, dataArray, options = {}) {
|
|
17
|
+
return Model.insertMany(dataArray, {
|
|
18
|
+
session: options.session,
|
|
19
|
+
ordered: options.ordered !== false
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
async function createDefault(Model, overrides = {}, options = {}) {
|
|
23
|
+
const defaults = {};
|
|
24
|
+
Model.schema.eachPath((path, schemaType) => {
|
|
25
|
+
const schemaOptions = schemaType.options;
|
|
26
|
+
if (schemaOptions.default !== void 0 && path !== "_id") {
|
|
27
|
+
defaults[path] = typeof schemaOptions.default === "function" ? schemaOptions.default() : schemaOptions.default;
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
return create(Model, { ...defaults, ...overrides }, options);
|
|
31
|
+
}
|
|
32
|
+
async function upsert(Model, query, data, options = {}) {
|
|
33
|
+
return Model.findOneAndUpdate(
|
|
34
|
+
query,
|
|
35
|
+
{ $setOnInsert: data },
|
|
36
|
+
{
|
|
37
|
+
upsert: true,
|
|
38
|
+
new: true,
|
|
39
|
+
runValidators: true,
|
|
40
|
+
session: options.session,
|
|
41
|
+
...options.updatePipeline !== void 0 ? { updatePipeline: options.updatePipeline } : {}
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export { create, createMany, create_exports, upsert };
|