@querykitjs/mongoose 1.0.0

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/dist/index.cjs ADDED
@@ -0,0 +1,514 @@
1
+ 'use strict';
2
+
3
+ var core = require('@querykitjs/core');
4
+ var async_hooks = require('async_hooks');
5
+
6
+ // src/registry.ts
7
+
8
+ // src/internal/fields.ts
9
+ function resolveField(model, key) {
10
+ const name = key === "id" ? "_id" : key;
11
+ if (name === "_id") return "_id";
12
+ return model.schema.path(name) ? name : void 0;
13
+ }
14
+ function hasPath(model, path) {
15
+ return Boolean(model.schema.path(path));
16
+ }
17
+ function castValue(model, field, value) {
18
+ const path = model.schema.path(field);
19
+ if (!path) return value;
20
+ try {
21
+ return path.cast(value);
22
+ } catch {
23
+ return value;
24
+ }
25
+ }
26
+
27
+ // src/internal/operators.ts
28
+ var esc = (s) => String(s ?? "").replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
29
+ var sqlLikeToRegex = (pattern) => {
30
+ let out = "";
31
+ for (const ch of String(pattern ?? "")) {
32
+ if (ch === "%") out += ".*";
33
+ else if (ch === "_") out += ".";
34
+ else out += ch.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
35
+ }
36
+ return `^${out}$`;
37
+ };
38
+ var asTuple = (v) => Array.isArray(v) && v.length === 2 ? [v[0], v[1]] : void 0;
39
+ var operators = {
40
+ "=": (v) => ({ $eq: v }),
41
+ eq: (v) => ({ $eq: v }),
42
+ // SQL three-valued logic: inequality/negation excludes NULL (and missing) rows,
43
+ // matching drizzle-pg. `$nin: [v, null]` = "not v AND not null".
44
+ "!=": (v) => ({ $nin: [v, null] }),
45
+ ne: (v) => ({ $nin: [v, null] }),
46
+ ">": (v) => ({ $gt: v }),
47
+ gt: (v) => ({ $gt: v }),
48
+ ">=": (v) => ({ $gte: v }),
49
+ gte: (v) => ({ $gte: v }),
50
+ "<": (v) => ({ $lt: v }),
51
+ lt: (v) => ({ $lt: v }),
52
+ "<=": (v) => ({ $lte: v }),
53
+ lte: (v) => ({ $lte: v }),
54
+ contains: (v) => ({ $regex: esc(v), $options: "i" }),
55
+ "%_%": (v) => ({ $regex: esc(v), $options: "i" }),
56
+ startsWith: (v) => ({ $regex: `^${esc(v)}`, $options: "i" }),
57
+ "%_": (v) => ({ $regex: `^${esc(v)}`, $options: "i" }),
58
+ endsWith: (v) => ({ $regex: `${esc(v)}$`, $options: "i" }),
59
+ "_%": (v) => ({ $regex: `${esc(v)}$`, $options: "i" }),
60
+ like: (v) => ({ $regex: sqlLikeToRegex(v) }),
61
+ ilike: (v) => ({ $regex: sqlLikeToRegex(v), $options: "i" }),
62
+ // negation also excludes NULL/missing (SQL `NOT LIKE` semantics).
63
+ notLike: (v) => ({ $not: { $regex: sqlLikeToRegex(v) }, $ne: null }),
64
+ in: (v) => Array.isArray(v) ? { $in: v } : void 0,
65
+ notIn: (v) => Array.isArray(v) ? { $nin: [...v, null] } : void 0,
66
+ between: (v) => {
67
+ const t = asTuple(v);
68
+ return t ? { $gte: t[0], $lte: t[1] } : void 0;
69
+ },
70
+ notBetween: (v) => {
71
+ const t = asTuple(v);
72
+ return t ? { $not: { $gte: t[0], $lte: t[1] }, $ne: null } : void 0;
73
+ },
74
+ isNull: () => ({ $eq: null }),
75
+ isNotNull: () => ({ $ne: null })
76
+ };
77
+
78
+ // src/internal/where.ts
79
+ var isObject = (n) => typeof n === "object" && n !== null;
80
+ var isFieldCondition = (n) => isObject(n) && "key" in n && !("and" in n) && !("or" in n) && !("not" in n);
81
+ function combine(kind, parts) {
82
+ const valid = parts.filter((p) => p !== void 0);
83
+ if (valid.length === 0) return void 0;
84
+ if (valid.length === 1) return valid[0];
85
+ return { [kind]: valid };
86
+ }
87
+ function buildCondition(model, cond) {
88
+ const operator = cond.operation ?? "=";
89
+ const build = operators[operator];
90
+ if (!build) throw new Error(`Unsupported filter operator: "${operator}"`);
91
+ const field = resolveField(model, cond.key);
92
+ if (!field) return void 0;
93
+ const fragment = build(cond.value);
94
+ if (fragment === void 0) return void 0;
95
+ return { [field]: fragment };
96
+ }
97
+ function buildNode(model, node) {
98
+ if (isFieldCondition(node)) return buildCondition(model, node);
99
+ if (isObject(node)) {
100
+ if ("and" in node)
101
+ return combine(
102
+ "$and",
103
+ node.and.map((n) => buildNode(model, n))
104
+ );
105
+ if ("or" in node)
106
+ return combine(
107
+ "$or",
108
+ node.or.map((n) => buildNode(model, n))
109
+ );
110
+ if ("not" in node) {
111
+ const notNode = node.not;
112
+ const inner = buildNode(model, notNode);
113
+ if (!inner) return void 0;
114
+ if (isFieldCondition(notNode)) {
115
+ const op = notNode.operation ?? "=";
116
+ if (op !== "isNull" && op !== "isNotNull") {
117
+ const field = resolveField(model, notNode.key);
118
+ if (field) return { $and: [{ [field]: { $ne: null } }, { $nor: [inner] }] };
119
+ }
120
+ }
121
+ return { $nor: [inner] };
122
+ }
123
+ return node;
124
+ }
125
+ return void 0;
126
+ }
127
+ function buildWhere(model, filter) {
128
+ if (filter === void 0) return void 0;
129
+ if (Array.isArray(filter))
130
+ return combine(
131
+ "$and",
132
+ filter.map((c) => buildNode(model, c))
133
+ );
134
+ return buildNode(model, filter);
135
+ }
136
+
137
+ // src/internal/order-by.ts
138
+ function normalize(sort) {
139
+ if (!sort) return [];
140
+ return sort.filter((item) => item && item.key).map((item) => ({ key: item.key, direction: item.direction ?? "asc" }));
141
+ }
142
+ function buildSort(model, sort) {
143
+ const spec = {};
144
+ for (const item of normalize(sort)) {
145
+ const field = resolveField(model, item.key);
146
+ if (field) spec[field] = item.direction === "desc" ? -1 : 1;
147
+ }
148
+ if (Object.keys(spec).length === 0) {
149
+ if (hasPath(model, "createdAt")) spec.createdAt = -1;
150
+ else spec._id = -1;
151
+ }
152
+ return spec;
153
+ }
154
+
155
+ // src/internal/cursor.ts
156
+ function encodeCursor(value) {
157
+ const normalized = value instanceof Date ? value.toISOString() : value;
158
+ const json = JSON.stringify({ v: normalized });
159
+ return Buffer.from(json, "utf8").toString("base64url");
160
+ }
161
+ function decodeCursor(cursor) {
162
+ if (!cursor) return void 0;
163
+ try {
164
+ const json = Buffer.from(cursor, "base64url").toString("utf8");
165
+ const payload = JSON.parse(json);
166
+ return payload.v;
167
+ } catch {
168
+ return void 0;
169
+ }
170
+ }
171
+
172
+ // src/repository.ts
173
+ function buildRepository(runtime, model, config = {}) {
174
+ const m = model;
175
+ const hasDeletedAt = hasPath(m, "deletedAt");
176
+ const timestampsOn = Boolean(m.schema.options?.timestamps);
177
+ const stampUpdatedAt = hasPath(m, "updatedAt") && !timestampsOn;
178
+ const forUpdate = (patch) => stampUpdatedAt ? { ...patch, updatedAt: /* @__PURE__ */ new Date() } : patch;
179
+ const scopeConditions = config.scope ? Object.entries(config.scope).map(([key, value]) => ({ key, operation: "=", value })) : [];
180
+ const scopeWhere = scopeConditions.length ? buildWhere(m, scopeConditions) : void 0;
181
+ const sortSpec = (sort) => buildSort(m, sort);
182
+ const composeWhere = (userFilter, withDeleted) => {
183
+ const parts = [buildWhere(m, userFilter), scopeWhere, hasDeletedAt && !withDeleted ? { deletedAt: { $eq: null } } : void 0].filter(
184
+ (p) => p !== void 0
185
+ );
186
+ if (parts.length === 0) return {};
187
+ if (parts.length === 1) return parts[0];
188
+ return { $and: parts };
189
+ };
190
+ const withId = (filter, idKey, id) => {
191
+ const idCondition = { key: idKey, operation: "=", value: id };
192
+ if (!filter) return [idCondition];
193
+ if (Array.isArray(filter)) return [...filter, idCondition];
194
+ return { and: [filter, idCondition] };
195
+ };
196
+ const projection = (columns) => {
197
+ if (!columns) return void 0;
198
+ const keys = Object.keys(columns).filter((k) => columns[k]);
199
+ if (keys.length === 0) return void 0;
200
+ const proj = {};
201
+ let includesId = false;
202
+ for (const k of keys) {
203
+ const field = resolveField(m, k);
204
+ if (!field) continue;
205
+ proj[field] = 1;
206
+ if (field === "_id") includesId = true;
207
+ }
208
+ if (Object.keys(proj).length === 0) return void 0;
209
+ if (!includesId) proj._id = 0;
210
+ return proj;
211
+ };
212
+ const applyPopulate = (q, withRel) => {
213
+ if (withRel) {
214
+ for (const key of Object.keys(withRel)) {
215
+ const value = withRel[key];
216
+ if (!value) continue;
217
+ q.populate(typeof value === "object" ? { path: key, ...value } : key);
218
+ }
219
+ }
220
+ return q;
221
+ };
222
+ const attachSession = (q) => {
223
+ const s = runtime.getSession();
224
+ if (s) q.session(s);
225
+ return q;
226
+ };
227
+ const toArr = (v) => v === void 0 ? [] : Array.isArray(v) ? v : [v];
228
+ const forInsert = (values) => ({
229
+ ...config.scope,
230
+ ...values,
231
+ ...config.scope
232
+ });
233
+ const buildUpsert = (values, options) => {
234
+ const targetKeys = toArr(options.target);
235
+ const inserted = forInsert(values);
236
+ const filter = {};
237
+ for (const key of targetKeys) {
238
+ const field = resolveField(m, key);
239
+ if (!field) throw new Error(`upsert: unknown target field "${key}".`);
240
+ filter[field] = inserted[key];
241
+ }
242
+ const set = options.set ? { ...options.set } : Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k)));
243
+ const setOnInsert = Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k) && !(k in set)));
244
+ const update = {};
245
+ if (Object.keys(set).length) update.$set = set;
246
+ if (Object.keys(setOnInsert).length) update.$setOnInsert = setOnInsert;
247
+ return { filter, update };
248
+ };
249
+ const runFind = (where, opts) => {
250
+ let q = m.find(where, projection(opts.columns));
251
+ if (opts.sort) q = q.sort(opts.sort);
252
+ if (typeof opts.skip === "number") q = q.skip(opts.skip);
253
+ if (typeof opts.limit === "number") q = q.limit(opts.limit);
254
+ q = applyPopulate(q, opts.with);
255
+ return attachSession(q).lean().exec();
256
+ };
257
+ const countWhere = (where) => attachSession(m.countDocuments(where)).exec();
258
+ const repository = {
259
+ model,
260
+ async findAll(params = {}) {
261
+ const rows = await runFind(composeWhere(params.filter, params.withDeleted), {
262
+ sort: sortSpec(params.sort),
263
+ columns: params.columns,
264
+ with: params.with
265
+ });
266
+ return rows;
267
+ },
268
+ async findOne(params = {}) {
269
+ let q = m.findOne(composeWhere(params.filter, params.withDeleted), projection(params.columns));
270
+ q = q.sort(sortSpec(params.sort));
271
+ q = applyPopulate(q, params.with);
272
+ const row = await attachSession(q).lean().exec();
273
+ return row ?? void 0;
274
+ },
275
+ async findById(id, params = {}) {
276
+ const { idKey = "id", filter, columns, with: withRel } = params;
277
+ let q = m.findOne(composeWhere(withId(filter, idKey, id), params.withDeleted), projection(columns));
278
+ q = applyPopulate(q, withRel);
279
+ const row = await attachSession(q).lean().exec();
280
+ return row ?? void 0;
281
+ },
282
+ async findList(params = {}) {
283
+ const page = Math.max(1, Math.trunc(params.page ?? 1));
284
+ const perPage = Math.max(1, Math.trunc(params.perPage ?? runtime.defaultPerPage));
285
+ const where = composeWhere(params.filter, params.withDeleted);
286
+ const [data, total_items] = await Promise.all([
287
+ runFind(where, { sort: sortSpec(params.sort), columns: params.columns, with: params.with, limit: perPage, skip: (page - 1) * perPage }),
288
+ countWhere(where)
289
+ ]);
290
+ const total_pages = Math.ceil(total_items / perPage);
291
+ return {
292
+ data,
293
+ meta: {
294
+ total_items,
295
+ total_pages,
296
+ current_page: page,
297
+ per_page: perPage,
298
+ has_next: page < total_pages,
299
+ has_prev: page > 1
300
+ }
301
+ };
302
+ },
303
+ async findInfinite(params = {}) {
304
+ const limit = Math.max(1, Math.trunc(params.limit ?? runtime.defaultLimit));
305
+ const offset = Math.max(0, Math.trunc(params.offset ?? 0));
306
+ const rows = await runFind(composeWhere(params.filter, params.withDeleted), {
307
+ sort: sortSpec(params.sort),
308
+ columns: params.columns,
309
+ with: params.with,
310
+ limit: limit + 1,
311
+ skip: offset
312
+ });
313
+ const has_more = rows.length > limit;
314
+ const data = has_more ? rows.slice(0, limit) : rows;
315
+ return {
316
+ data,
317
+ meta: { limit, offset, count: data.length, has_more, next_offset: has_more ? offset + limit : null }
318
+ };
319
+ },
320
+ async findCursor(params = {}) {
321
+ const limit = Math.max(1, Math.trunc(params.limit ?? runtime.defaultLimit));
322
+ const cursorKey = params.cursorKey ?? "id";
323
+ const order = params.order ?? "asc";
324
+ const direction = params.direction ?? "forward";
325
+ const field = resolveField(m, cursorKey);
326
+ if (!field) throw new Error(`findCursor: unknown cursorKey "${cursorKey}".`);
327
+ const decoded = decodeCursor(params.cursor);
328
+ const cursorValue = decoded !== void 0 ? castValue(m, field, decoded) : void 0;
329
+ const baseWhere = composeWhere(params.filter, params.withDeleted);
330
+ const ascInQuery = direction === "forward" ? order === "asc" : order === "desc";
331
+ const seek = cursorValue !== void 0 ? { [field]: ascInQuery ? { $gt: cursorValue } : { $lt: cursorValue } } : void 0;
332
+ const where = seek ? Object.keys(baseWhere).length ? { $and: [baseWhere, seek] } : seek : baseWhere;
333
+ const selected = projection(params.columns);
334
+ const proj = selected ? { ...selected, [field]: 1 } : void 0;
335
+ let q = m.find(where, proj).sort({ [field]: ascInQuery ? 1 : -1 }).limit(limit + 1);
336
+ q = applyPopulate(q, params.with);
337
+ const rows = await attachSession(q).lean().exec();
338
+ const hasExtra = rows.length > limit;
339
+ let pageRows = hasExtra ? rows.slice(0, limit) : rows;
340
+ if (direction === "backward") pageRows = [...pageRows].reverse();
341
+ const first = pageRows[0];
342
+ const last = pageRows[pageRows.length - 1];
343
+ const has_next = direction === "forward" ? hasExtra : cursorValue !== void 0;
344
+ const has_prev = direction === "forward" ? cursorValue !== void 0 : hasExtra;
345
+ return {
346
+ data: pageRows,
347
+ meta: {
348
+ limit,
349
+ has_next,
350
+ has_prev,
351
+ next_cursor: has_next && last ? encodeCursor(last[field]) : null,
352
+ prev_cursor: has_prev && first ? encodeCursor(first[field]) : null
353
+ }
354
+ };
355
+ },
356
+ count(filter) {
357
+ return countWhere(composeWhere(filter));
358
+ },
359
+ async exists(filter) {
360
+ return await countWhere(composeWhere(filter)) > 0;
361
+ },
362
+ /* ------------------------------- writes ------------------------------- */
363
+ async create(values) {
364
+ const [doc] = await m.create([forInsert(values)], { session: runtime.getSession() });
365
+ return doc.toObject();
366
+ },
367
+ async createMany(values) {
368
+ if (values.length === 0) return [];
369
+ const docs = await m.insertMany(values.map(forInsert), { session: runtime.getSession() });
370
+ return docs.map((d) => d.toObject());
371
+ },
372
+ async upsert(values, options) {
373
+ const { filter, update } = buildUpsert(values, options);
374
+ const q = m.findOneAndUpdate(filter, update, { returnDocument: "after", upsert: true });
375
+ return await attachSession(q).lean().exec();
376
+ },
377
+ async upsertMany(values, options) {
378
+ if (values.length === 0) return [];
379
+ const CHUNK = 1e3;
380
+ const entries = values.map((v) => buildUpsert(v, options));
381
+ for (let i = 0; i < entries.length; i += CHUNK) {
382
+ const ops = entries.slice(i, i + CHUNK).map((e) => ({ updateOne: { filter: e.filter, update: e.update, upsert: true } }));
383
+ await m.bulkWrite(ops, { session: runtime.getSession() });
384
+ }
385
+ const rows = await attachSession(m.find({ $or: entries.map((e) => e.filter) })).lean().exec();
386
+ const targetFields = toArr(options.target).map((k) => resolveField(m, k)).filter((f2) => Boolean(f2));
387
+ const keyOf = (o) => targetFields.map((f2) => String(o[f2])).join("\0");
388
+ const byKey = new Map(rows.map((r) => [keyOf(r), r]));
389
+ return entries.map((e) => byKey.get(keyOf(e.filter))).filter((r) => Boolean(r));
390
+ },
391
+ async updateById(id, patch, idKey = "id") {
392
+ const where = composeWhere(withId(void 0, idKey, id));
393
+ const q = m.findOneAndUpdate(where, forUpdate(patch), { returnDocument: "after" });
394
+ const row = await attachSession(q).lean().exec();
395
+ return row ?? void 0;
396
+ },
397
+ async updateWhere(filter, patch) {
398
+ const where = composeWhere(filter);
399
+ const found = await attachSession(m.find(where).select({ _id: 1 })).lean().exec();
400
+ if (found.length === 0) return [];
401
+ const ids = found.map((d) => d._id);
402
+ await attachSession(m.updateMany({ _id: { $in: ids } }, forUpdate(patch))).exec();
403
+ return await attachSession(m.find({ _id: { $in: ids } })).lean().exec();
404
+ },
405
+ async deleteById(id, idKey = "id") {
406
+ const where = composeWhere(withId(void 0, idKey, id));
407
+ const row = await attachSession(m.findOneAndDelete(where)).lean().exec();
408
+ return row ?? void 0;
409
+ },
410
+ async deleteWhere(filter) {
411
+ const where = composeWhere(filter);
412
+ const rows = await attachSession(m.find(where)).lean().exec();
413
+ if (rows.length === 0) return [];
414
+ await attachSession(m.deleteMany({ _id: { $in: rows.map((d) => d._id) } })).exec();
415
+ return rows;
416
+ },
417
+ async softDelete(id, idKey = "id") {
418
+ if (!hasDeletedAt) throw new Error("softDelete: schema has no deletedAt path.");
419
+ const where = composeWhere(withId(void 0, idKey, id), false);
420
+ const q = m.findOneAndUpdate(where, forUpdate({ deletedAt: /* @__PURE__ */ new Date() }), { returnDocument: "after" });
421
+ const row = await attachSession(q).lean().exec();
422
+ return row ?? void 0;
423
+ },
424
+ async restore(id, idKey = "id") {
425
+ if (!hasDeletedAt) throw new Error("restore: schema has no deletedAt path.");
426
+ const where = composeWhere(withId(void 0, idKey, id), true);
427
+ const q = m.findOneAndUpdate(where, forUpdate({ deletedAt: null }), { returnDocument: "after" });
428
+ const row = await attachSession(q).lean().exec();
429
+ return row ?? void 0;
430
+ },
431
+ async aggregate(spec) {
432
+ const groupKeys = toArr(spec.groupBy);
433
+ const rawMatch = composeWhere(spec.filter, spec.withDeleted);
434
+ let match = rawMatch;
435
+ try {
436
+ const q = m.find(rawMatch);
437
+ q.cast(m);
438
+ match = q.getFilter();
439
+ } catch {
440
+ }
441
+ const groupId = groupKeys.length ? Object.fromEntries(groupKeys.map((k) => [k, `$${resolveField(m, k) ?? k}`])) : null;
442
+ const group = { _id: groupId };
443
+ if (spec.count) group.count = { $sum: 1 };
444
+ const addAgg = (op, keys, prefix) => {
445
+ for (const k of keys) {
446
+ const field = resolveField(m, k);
447
+ if (field) group[`${prefix}_${k}`] = { [op]: `$${field}` };
448
+ }
449
+ };
450
+ addAgg("$sum", toArr(spec.sum), "sum");
451
+ addAgg("$avg", toArr(spec.avg), "avg");
452
+ addAgg("$min", toArr(spec.min), "min");
453
+ addAgg("$max", toArr(spec.max), "max");
454
+ let agg = m.aggregate([{ $match: match }, { $group: group }]);
455
+ const session = runtime.getSession();
456
+ if (session) agg = agg.session(session);
457
+ const rows = await agg.exec();
458
+ return rows.map(({ _id, ...rest }) => ({ ...typeof _id === "object" && _id ? _id : {}, ...rest }));
459
+ },
460
+ scoped(scope) {
461
+ return buildRepository(runtime, model, { ...config, scope: { ...config.scope, ...scope } });
462
+ }
463
+ };
464
+ return repository;
465
+ }
466
+ function createContextStore() {
467
+ const als = new async_hooks.AsyncLocalStorage();
468
+ return {
469
+ get: () => als.getStore(),
470
+ run: (patch, fn) => als.run({ ...als.getStore(), ...patch }, fn)
471
+ };
472
+ }
473
+
474
+ // src/registry.ts
475
+ function createRegistry(connection, options = {}) {
476
+ const ctx = createContextStore();
477
+ const runtime = {
478
+ getSession: () => ctx.get()?.session,
479
+ defaultPerPage: options.defaultPerPage ?? core.DEFAULT_PER_PAGE,
480
+ defaultLimit: options.defaultLimit ?? core.DEFAULT_LIMIT
481
+ };
482
+ function repository(model, arg2, arg3) {
483
+ const extend = typeof arg2 === "function" ? arg2 : arg3;
484
+ const base = buildRepository(runtime, model);
485
+ return extend ? { ...base, ...extend(base) } : base;
486
+ }
487
+ const transaction = async (fn) => {
488
+ if (ctx.get()?.session) return fn();
489
+ const session = await connection.startSession();
490
+ try {
491
+ let result;
492
+ await session.withTransaction(async () => {
493
+ result = await ctx.run({ session }, fn);
494
+ });
495
+ return result;
496
+ } finally {
497
+ await session.endSession();
498
+ }
499
+ };
500
+ return { repository, transaction };
501
+ }
502
+ function createFilters() {
503
+ return core.createFilters();
504
+ }
505
+
506
+ Object.defineProperty(exports, "f", {
507
+ enumerable: true,
508
+ get: function () { return core.f; }
509
+ });
510
+ exports.buildRepository = buildRepository;
511
+ exports.createFilters = createFilters;
512
+ exports.createRegistry = createRegistry;
513
+ //# sourceMappingURL=index.cjs.map
514
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/internal/fields.ts","../src/internal/operators.ts","../src/internal/where.ts","../src/internal/order-by.ts","../src/internal/cursor.ts","../src/repository.ts","../src/internal/context.ts","../src/registry.ts","../src/filters.ts"],"names":["f","AsyncLocalStorage","DEFAULT_PER_PAGE","DEFAULT_LIMIT","coreCreateFilters"],"mappings":"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","file":"index.cjs","sourcesContent":["import type { Model } from \"mongoose\";\n\n/** Any Mongoose model, regardless of its document type. */\nexport type AnyModel = Model<any>;\n\n/**\n * Map a public field key to a real Mongoose schema path. `\"id\"` is aliased to\n * `\"_id\"` so the wire contract stays identical across adapters. Unknown fields\n * return `undefined` (the caller skips them silently, like the Drizzle adapter).\n */\nexport function resolveField(model: AnyModel, key: string): string | undefined {\n const name = key === \"id\" ? \"_id\" : key;\n if (name === \"_id\") return \"_id\";\n return model.schema.path(name) ? name : undefined;\n}\n\n/** Whether the schema has a given path (e.g. `deletedAt`, `updatedAt`). */\nexport function hasPath(model: AnyModel, path: string): boolean {\n return Boolean(model.schema.path(path));\n}\n\n/**\n * Cast a raw (decoded cursor) value to the field's schema type so keyset\n * comparisons (`$gt`/`$lt`) work — e.g. a hex string → `ObjectId`, an ISO\n * string → `Date`. Falls back to the raw value if casting fails.\n */\nexport function castValue(model: AnyModel, field: string, value: unknown): unknown {\n const path = model.schema.path(field);\n if (!path) return value;\n try {\n return path.cast(value);\n } catch {\n return value;\n }\n}\n","import type { FilterOperator, FilterValue } from \"../types\";\n\n/** A field-level Mongo fragment, e.g. `{ $gte: 1, $lte: 9 }`. `undefined` = drop. */\ntype Fragment = Record<string, unknown> | undefined;\ntype Builder = (value: FilterValue | undefined) => Fragment;\n\n/** Escape a literal string for use inside a regex (contains/startsWith/endsWith). */\nconst esc = (s: unknown): string => String(s ?? \"\").replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n\n/** Translate a SQL LIKE pattern (`%` → any, `_` → one char) to an anchored regex. */\nconst sqlLikeToRegex = (pattern: unknown): string => {\n let out = \"\";\n for (const ch of String(pattern ?? \"\")) {\n if (ch === \"%\") out += \".*\";\n else if (ch === \"_\") out += \".\";\n else out += ch.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n }\n return `^${out}$`;\n};\n\nconst asTuple = (v: FilterValue | undefined): [unknown, unknown] | undefined => (Array.isArray(v) && v.length === 2 ? [v[0], v[1]] : undefined);\n\n/**\n * Operator → Mongo fragment map. Mirrors the Drizzle adapter's semantics: both\n * token (`\"%_%\"`) and name-alias (`\"contains\"`) forms are handled;\n * `contains/startsWith/endsWith` are case-insensitive; invalid values (non-array\n * `in`, non-2-tuple `between`) drop the condition (`undefined`).\n */\nexport const operators: Record<FilterOperator, Builder> = {\n \"=\": v => ({ $eq: v }),\n eq: v => ({ $eq: v }),\n // SQL three-valued logic: inequality/negation excludes NULL (and missing) rows,\n // matching drizzle-pg. `$nin: [v, null]` = \"not v AND not null\".\n \"!=\": v => ({ $nin: [v, null] }),\n ne: v => ({ $nin: [v, null] }),\n \">\": v => ({ $gt: v }),\n gt: v => ({ $gt: v }),\n \">=\": v => ({ $gte: v }),\n gte: v => ({ $gte: v }),\n \"<\": v => ({ $lt: v }),\n lt: v => ({ $lt: v }),\n \"<=\": v => ({ $lte: v }),\n lte: v => ({ $lte: v }),\n\n contains: v => ({ $regex: esc(v), $options: \"i\" }),\n \"%_%\": v => ({ $regex: esc(v), $options: \"i\" }),\n startsWith: v => ({ $regex: `^${esc(v)}`, $options: \"i\" }),\n \"%_\": v => ({ $regex: `^${esc(v)}`, $options: \"i\" }),\n endsWith: v => ({ $regex: `${esc(v)}$`, $options: \"i\" }),\n \"_%\": v => ({ $regex: `${esc(v)}$`, $options: \"i\" }),\n\n like: v => ({ $regex: sqlLikeToRegex(v) }),\n ilike: v => ({ $regex: sqlLikeToRegex(v), $options: \"i\" }),\n // negation also excludes NULL/missing (SQL `NOT LIKE` semantics).\n notLike: v => ({ $not: { $regex: sqlLikeToRegex(v) }, $ne: null }),\n\n in: v => (Array.isArray(v) ? { $in: v } : undefined),\n notIn: v => (Array.isArray(v) ? { $nin: [...v, null] } : undefined),\n\n between: v => {\n const t = asTuple(v);\n return t ? { $gte: t[0], $lte: t[1] } : undefined;\n },\n notBetween: v => {\n const t = asTuple(v);\n return t ? { $not: { $gte: t[0], $lte: t[1] }, $ne: null } : undefined;\n },\n\n isNull: () => ({ $eq: null }),\n isNotNull: () => ({ $ne: null }),\n};\n","import type { Filter, FieldCondition, FilterNode } from \"../types\";\nimport { operators } from \"./operators\";\nimport { resolveField, type AnyModel } from \"./fields\";\n\n/** A Mongo filter query object. */\nexport type Query = Record<string, unknown>;\n\nconst isObject = (n: unknown): n is Record<string, unknown> => typeof n === \"object\" && n !== null;\n\nconst isFieldCondition = (n: unknown): n is FieldCondition => isObject(n) && \"key\" in n && !(\"and\" in n) && !(\"or\" in n) && !(\"not\" in n);\n\n/** Combine parts (dropping `undefined`): 0 → undefined, 1 → the part, else `$and`/`$or`. */\nfunction combine(kind: \"$and\" | \"$or\", parts: (Query | undefined)[]): Query | undefined {\n const valid = parts.filter((p): p is Query => p !== undefined);\n if (valid.length === 0) return undefined;\n if (valid.length === 1) return valid[0];\n return { [kind]: valid };\n}\n\nfunction buildCondition(model: AnyModel, cond: FieldCondition): Query | undefined {\n const operator = cond.operation ?? \"=\";\n const build = operators[operator];\n if (!build) throw new Error(`Unsupported filter operator: \"${operator}\"`);\n const field = resolveField(model, cond.key);\n if (!field) return undefined; // unknown field → skip silently\n const fragment = build(cond.value);\n if (fragment === undefined) return undefined;\n return { [field]: fragment };\n}\n\nfunction buildNode(model: AnyModel, node: FilterNode): Query | undefined {\n if (isFieldCondition(node)) return buildCondition(model, node);\n if (isObject(node)) {\n if (\"and\" in node)\n return combine(\n \"$and\",\n (node.and as FilterNode[]).map(n => buildNode(model, n)),\n );\n if (\"or\" in node)\n return combine(\n \"$or\",\n (node.or as FilterNode[]).map(n => buildNode(model, n)),\n );\n if (\"not\" in node) {\n const notNode = node.not as FilterNode;\n const inner = buildNode(model, notNode);\n if (!inner) return undefined;\n // SQL `NOT(pred)` drops NULL rows (three-valued logic), but Mongo `$nor`\n // includes null/missing. For a single-field comparison predicate, also\n // require the field non-null so results match drizzle. `isNull`/`isNotNull`\n // are two-valued (never NULL) → no guard, else `not(isNotNull)` would\n // wrongly return nothing. Multi-field `not` groups keep bare `$nor`.\n if (isFieldCondition(notNode)) {\n const op = notNode.operation ?? \"=\";\n if (op !== \"isNull\" && op !== \"isNotNull\") {\n const field = resolveField(model, notNode.key);\n if (field) return { $and: [{ [field]: { $ne: null } }, { $nor: [inner] }] };\n }\n }\n return { $nor: [inner] };\n }\n // Raw escape hatch — a plain Mongo filter object, used as-is.\n return node as Query;\n }\n return undefined;\n}\n\n/** Translate a filter (tree / node / flat array / raw) into a single Mongo query. */\nexport function buildWhere(model: AnyModel, filter?: Filter): Query | undefined {\n if (filter === undefined) return undefined;\n // Array elements go through buildNode (not buildCondition) so a flat array may\n // also hold logical groups / raw nodes (implicit AND), matching drizzle-pg.\n if (Array.isArray(filter))\n return combine(\n \"$and\",\n filter.map(c => buildNode(model, c)),\n );\n return buildNode(model, filter);\n}\n","import type { Sort } from \"../types\";\nimport { resolveField, hasPath, type AnyModel } from \"./fields\";\n\n/** A Mongo sort spec, e.g. `{ name: 1, createdAt: -1 }`. */\nexport type SortSpec = Record<string, 1 | -1>;\n\ninterface NormalizedSort {\n key: string;\n direction: \"asc\" | \"desc\";\n}\n\n/** Sort is always a `{ key, direction }[]` array → a flat normalized list (empty keys skipped). */\nfunction normalize(sort?: Sort): NormalizedSort[] {\n if (!sort) return [];\n return sort.filter(item => item && item.key).map(item => ({ key: item.key, direction: item.direction ?? \"asc\" }));\n}\n\n/**\n * Build a Mongo sort spec from the sort input. Unknown fields are skipped; when\n * nothing valid remains, defaults to newest-first (`createdAt` desc, else `_id`).\n */\nexport function buildSort(model: AnyModel, sort?: Sort): SortSpec {\n const spec: SortSpec = {};\n for (const item of normalize(sort)) {\n const field = resolveField(model, item.key);\n if (field) spec[field] = item.direction === \"desc\" ? -1 : 1;\n }\n if (Object.keys(spec).length === 0) {\n if (hasPath(model, \"createdAt\")) spec.createdAt = -1;\n else spec._id = -1;\n }\n return spec;\n}\n","/**\n * Opaque cursor tokens for keyset pagination. A token is the base64url encoding\n * of `{ v: <cursor field value> }`. Dates/ObjectIds are preserved as strings and\n * re-cast to the field's type on decode (see `castValue`).\n */\n\ninterface CursorPayload {\n v: unknown;\n}\n\nexport function encodeCursor(value: unknown): string {\n const normalized = value instanceof Date ? value.toISOString() : value;\n const json = JSON.stringify({ v: normalized } satisfies CursorPayload);\n return Buffer.from(json, \"utf8\").toString(\"base64url\");\n}\n\nexport function decodeCursor(cursor?: string | null): unknown | undefined {\n if (!cursor) return undefined;\n try {\n const json = Buffer.from(cursor, \"base64url\").toString(\"utf8\");\n const payload = JSON.parse(json) as CursorPayload;\n return payload.v;\n } catch {\n return undefined;\n }\n}\n","import type { ClientSession, Model } from \"mongoose\";\n\nimport type {\n AggregateRow,\n AggregateSpec,\n ByIdParams,\n CursorParams,\n CursorResult,\n FieldCondition,\n FieldKey,\n Filter,\n Id,\n InfiniteParams,\n InfiniteResult,\n Insert,\n OffsetParams,\n OffsetResult,\n QueryParams,\n Repository,\n Row,\n Scope,\n Sort,\n SortDirection,\n UpsertOptions,\n} from \"./types\";\nimport { resolveField, hasPath, castValue, type AnyModel } from \"./internal/fields\";\nimport { buildWhere, type Query } from \"./internal/where\";\nimport { buildSort } from \"./internal/order-by\";\nimport { encodeCursor, decodeCursor } from \"./internal/cursor\";\n\n/** Registry-level runtime injected into every repository. */\nexport interface RepoRuntime {\n /** Active transaction session, if any. */\n getSession: () => ClientSession | undefined;\n defaultPerPage: number;\n defaultLimit: number;\n}\n\n/** Per-repository configuration (scope). */\nexport interface RepoConfig<TDoc> {\n scope?: Scope<TDoc>;\n}\n\n// Mongoose's Query generics are extremely deep; we drive queries untyped\n// internally (the public Repository surface stays fully typed) and cast results.\n\ntype AnyQuery = any;\n\n/**\n * Build a model-scoped repository. `runtime` (session getter + defaults) comes\n * from the registry, so this file never touches the connection directly.\n */\nexport function buildRepository<TDoc>(runtime: RepoRuntime, model: Model<TDoc>, config: RepoConfig<TDoc> = {}): Repository<TDoc> {\n const m = model as AnyModel;\n const hasDeletedAt = hasPath(m, \"deletedAt\");\n // Mongoose auto-bumps `updatedAt` only when the schema opts into timestamps;\n // for a manual `updatedAt` path we stamp it ourselves so every update path\n // bumps it — matching drizzle-pg's forUpdate.\n const timestampsOn = Boolean((m.schema as { options?: { timestamps?: unknown } }).options?.timestamps);\n const stampUpdatedAt = hasPath(m, \"updatedAt\") && !timestampsOn;\n const forUpdate = <T extends object>(patch: T): T => (stampUpdatedAt ? { ...patch, updatedAt: new Date() } : patch);\n\n // Scope → equality conditions applied to every query (as a flat filter).\n const scopeConditions: FieldCondition[] = config.scope\n ? Object.entries(config.scope).map(([key, value]) => ({ key, operation: \"=\", value: value as never }))\n : [];\n const scopeWhere = scopeConditions.length ? buildWhere(m, scopeConditions) : undefined;\n\n const sortSpec = (sort?: Sort<TDoc>): Record<string, 1 | -1> => buildSort(m, sort as Sort | undefined);\n\n /** Compose user filter + scope + soft-delete guard into one Mongo query. */\n const composeWhere = (userFilter?: Filter<TDoc>, withDeleted?: boolean): Query => {\n const parts = [buildWhere(m, userFilter as Filter | undefined), scopeWhere, hasDeletedAt && !withDeleted ? { deletedAt: { $eq: null } } : undefined].filter(\n (p): p is Query => p !== undefined,\n );\n if (parts.length === 0) return {};\n if (parts.length === 1) return parts[0]!;\n return { $and: parts };\n };\n\n /** Merge an id predicate into a filter as AND. */\n const withId = (filter: Filter<TDoc> | undefined, idKey: string, id: Id): Filter<TDoc> => {\n const idCondition: FieldCondition<TDoc> = { key: idKey as FieldKey<TDoc>, operation: \"=\", value: id as never };\n if (!filter) return [idCondition];\n if (Array.isArray(filter)) return [...filter, idCondition];\n return { and: [filter, idCondition] };\n };\n\n /**\n * Column selection → Mongo projection, or undefined when empty. Adds `_id: 0`\n * unless the caller selected `id`/`_id`, so the runtime shape matches the\n * inferred `Pick<...>` type (Mongo otherwise always returns `_id`). Returns\n * undefined (full doc) when no requested column resolves.\n */\n const projection = (columns?: QueryParams<TDoc>[\"columns\"]): Record<string, 0 | 1> | undefined => {\n if (!columns) return undefined;\n const keys = Object.keys(columns).filter(k => (columns as Record<string, boolean>)[k]);\n if (keys.length === 0) return undefined;\n const proj: Record<string, 0 | 1> = {};\n let includesId = false;\n for (const k of keys) {\n const field = resolveField(m, k);\n if (!field) continue;\n proj[field] = 1;\n if (field === \"_id\") includesId = true;\n }\n if (Object.keys(proj).length === 0) return undefined; // all unknown → full doc\n if (!includesId) proj._id = 0; // exclude _id unless explicitly selected (exact columns, like drizzle)\n return proj;\n };\n\n const applyPopulate = (q: AnyQuery, withRel?: QueryParams<TDoc>[\"with\"]): AnyQuery => {\n if (withRel) {\n for (const key of Object.keys(withRel)) {\n const value = (withRel as Record<string, unknown>)[key];\n if (!value) continue;\n // `true` → populate the field; an object → pass through as populate options\n // (`{ author: { select: \"name\" } }` → `.populate({ path, select })`).\n q.populate(typeof value === \"object\" ? { path: key, ...(value as object) } : key);\n }\n }\n return q;\n };\n\n const attachSession = (q: AnyQuery): AnyQuery => {\n const s = runtime.getSession();\n if (s) q.session(s);\n return q;\n };\n\n const toArr = <T>(v?: T | T[]): T[] => (v === undefined ? [] : Array.isArray(v) ? v : [v]);\n\n /** Apply scope defaults to insert values — scope wins (can't be overridden). */\n const forInsert = (values: object): Record<string, unknown> => ({\n ...(config.scope as object),\n ...values,\n ...(config.scope as object),\n });\n\n /** Build the `{filter, update}` for an upsert (target → filter, rest → $set/$setOnInsert). */\n const buildUpsert = (values: Insert<TDoc>, options: UpsertOptions<TDoc>) => {\n const targetKeys = toArr(options.target) as string[];\n const inserted = forInsert(values);\n const filter: Record<string, unknown> = {};\n for (const key of targetKeys) {\n const field = resolveField(m, key);\n if (!field) throw new Error(`upsert: unknown target field \"${key}\".`);\n filter[field] = inserted[key];\n }\n // $set (applied on insert + conflict) defaults to values minus target keys.\n const set: Record<string, unknown> = options.set\n ? { ...(options.set as Record<string, unknown>) }\n : Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k)));\n // $setOnInsert (insert only) = remaining non-target values not already in $set.\n const setOnInsert = Object.fromEntries(Object.entries(inserted).filter(([k]) => !targetKeys.includes(k) && !(k in set)));\n const update: Record<string, unknown> = {};\n if (Object.keys(set).length) update.$set = set;\n if (Object.keys(setOnInsert).length) update.$setOnInsert = setOnInsert;\n return { filter, update };\n };\n\n interface FindOpts {\n sort?: Record<string, 1 | -1>;\n columns?: QueryParams<TDoc>[\"columns\"];\n with?: QueryParams<TDoc>[\"with\"];\n limit?: number;\n skip?: number;\n }\n\n const runFind = (where: Query, opts: FindOpts): Promise<unknown[]> => {\n let q: AnyQuery = m.find(where, projection(opts.columns));\n if (opts.sort) q = q.sort(opts.sort);\n if (typeof opts.skip === \"number\") q = q.skip(opts.skip);\n if (typeof opts.limit === \"number\") q = q.limit(opts.limit);\n q = applyPopulate(q, opts.with);\n return attachSession(q).lean().exec() as Promise<unknown[]>;\n };\n\n const countWhere = (where: Query): Promise<number> => attachSession(m.countDocuments(where)).exec() as Promise<number>;\n\n const repository = {\n model,\n\n async findAll(params: QueryParams<TDoc> = {}) {\n const rows = await runFind(composeWhere(params.filter, params.withDeleted), {\n sort: sortSpec(params.sort),\n columns: params.columns,\n with: params.with,\n });\n return rows as never;\n },\n\n async findOne(params: QueryParams<TDoc> = {}) {\n let q: AnyQuery = m.findOne(composeWhere(params.filter, params.withDeleted), projection(params.columns));\n q = q.sort(sortSpec(params.sort));\n q = applyPopulate(q, params.with);\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as never;\n },\n\n async findById(id: Id, params: ByIdParams<TDoc> = {}) {\n const { idKey = \"id\", filter, columns, with: withRel } = params;\n let q: AnyQuery = m.findOne(composeWhere(withId(filter, idKey as string, id), params.withDeleted), projection(columns));\n q = applyPopulate(q, withRel);\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as never;\n },\n\n async findList(params: OffsetParams<TDoc> = {}) {\n const page = Math.max(1, Math.trunc(params.page ?? 1));\n const perPage = Math.max(1, Math.trunc(params.perPage ?? runtime.defaultPerPage));\n const where = composeWhere(params.filter, params.withDeleted);\n\n const [data, total_items] = await Promise.all([\n runFind(where, { sort: sortSpec(params.sort), columns: params.columns, with: params.with, limit: perPage, skip: (page - 1) * perPage }),\n countWhere(where),\n ]);\n\n const total_pages = Math.ceil(total_items / perPage);\n return {\n data,\n meta: {\n total_items,\n total_pages,\n current_page: page,\n per_page: perPage,\n has_next: page < total_pages,\n has_prev: page > 1,\n },\n } as OffsetResult<never>;\n },\n\n async findInfinite(params: InfiniteParams<TDoc> = {}) {\n const limit = Math.max(1, Math.trunc(params.limit ?? runtime.defaultLimit));\n const offset = Math.max(0, Math.trunc(params.offset ?? 0));\n\n const rows = await runFind(composeWhere(params.filter, params.withDeleted), {\n sort: sortSpec(params.sort),\n columns: params.columns,\n with: params.with,\n limit: limit + 1,\n skip: offset,\n });\n\n const has_more = rows.length > limit;\n const data = has_more ? rows.slice(0, limit) : rows;\n return {\n data,\n meta: { limit, offset, count: data.length, has_more, next_offset: has_more ? offset + limit : null },\n } as InfiniteResult<never>;\n },\n\n async findCursor(params: CursorParams<TDoc> = {}) {\n const limit = Math.max(1, Math.trunc(params.limit ?? runtime.defaultLimit));\n const cursorKey = (params.cursorKey ?? \"id\") as string;\n const order: SortDirection = params.order ?? \"asc\";\n const direction = params.direction ?? \"forward\";\n\n const field = resolveField(m, cursorKey);\n if (!field) throw new Error(`findCursor: unknown cursorKey \"${cursorKey}\".`);\n\n const decoded = decodeCursor(params.cursor);\n const cursorValue = decoded !== undefined ? castValue(m, field, decoded) : undefined;\n const baseWhere = composeWhere(params.filter, params.withDeleted);\n\n const ascInQuery = direction === \"forward\" ? order === \"asc\" : order === \"desc\";\n const seek: Query | undefined = cursorValue !== undefined ? { [field]: ascInQuery ? { $gt: cursorValue } : { $lt: cursorValue } } : undefined;\n const where: Query = seek ? (Object.keys(baseWhere).length ? { $and: [baseWhere, seek] } : seek) : baseWhere;\n\n // Force-include the cursor field in the projection so next/prev tokens work.\n const selected = projection(params.columns);\n const proj = selected ? { ...selected, [field]: 1 } : undefined;\n\n let q: AnyQuery = m\n .find(where, proj)\n .sort({ [field]: ascInQuery ? 1 : -1 })\n .limit(limit + 1);\n q = applyPopulate(q, params.with);\n const rows = (await attachSession(q).lean().exec()) as Record<string, unknown>[];\n\n const hasExtra = rows.length > limit;\n let pageRows = hasExtra ? rows.slice(0, limit) : rows;\n if (direction === \"backward\") pageRows = [...pageRows].reverse();\n\n const first = pageRows[0];\n const last = pageRows[pageRows.length - 1];\n\n const has_next = direction === \"forward\" ? hasExtra : cursorValue !== undefined;\n const has_prev = direction === \"forward\" ? cursorValue !== undefined : hasExtra;\n\n return {\n data: pageRows,\n meta: {\n limit,\n has_next,\n has_prev,\n next_cursor: has_next && last ? encodeCursor(last[field]) : null,\n prev_cursor: has_prev && first ? encodeCursor(first[field]) : null,\n },\n } as CursorResult<never>;\n },\n\n count(filter?: Filter<TDoc>) {\n return countWhere(composeWhere(filter));\n },\n\n async exists(filter?: Filter<TDoc>) {\n return (await countWhere(composeWhere(filter))) > 0;\n },\n\n /* ------------------------------- writes ------------------------------- */\n\n async create(values: Insert<TDoc>) {\n const [doc] = await m.create([forInsert(values)], { session: runtime.getSession() });\n return doc!.toObject() as Row<TDoc>;\n },\n\n async createMany(values: Insert<TDoc>[]) {\n if (values.length === 0) return [];\n const docs = await m.insertMany(values.map(forInsert), { session: runtime.getSession() });\n return docs.map((d: { toObject: () => unknown }) => d.toObject()) as Row<TDoc>[];\n },\n\n async upsert(values: Insert<TDoc>, options: UpsertOptions<TDoc>) {\n const { filter, update } = buildUpsert(values, options);\n const q: AnyQuery = m.findOneAndUpdate(filter, update, { returnDocument: \"after\", upsert: true });\n return (await attachSession(q).lean().exec()) as Row<TDoc>;\n },\n\n async upsertMany(values: Insert<TDoc>[], options: UpsertOptions<TDoc>) {\n if (values.length === 0) return [];\n const CHUNK = 1000;\n const entries = values.map(v => buildUpsert(v, options)); // input order preserved\n for (let i = 0; i < entries.length; i += CHUNK) {\n const ops = entries.slice(i, i + CHUNK).map(e => ({ updateOne: { filter: e.filter, update: e.update, upsert: true } }));\n await m.bulkWrite(ops, { session: runtime.getSession() });\n }\n // Re-fetch affected rows and return them in INPUT order (matches drizzle's\n // `.returning()`), keyed by the resolved target field(s).\n const rows = (await attachSession(m.find({ $or: entries.map(e => e.filter) }))\n .lean()\n .exec()) as Record<string, unknown>[];\n const targetFields = (toArr(options.target) as string[]).map(k => resolveField(m, k)).filter((f): f is string => Boolean(f));\n const keyOf = (o: Record<string, unknown>): string => targetFields.map(f => String(o[f])).join(\"\u0000\");\n const byKey = new Map(rows.map(r => [keyOf(r), r]));\n return entries.map(e => byKey.get(keyOf(e.filter))).filter((r): r is Record<string, unknown> => Boolean(r)) as Row<TDoc>[];\n },\n\n async updateById(id: Id, patch: Partial<Insert<TDoc>>, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n const where = composeWhere(withId(undefined, idKey as string, id));\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate(patch), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async updateWhere(filter: Filter<TDoc>, patch: Partial<Insert<TDoc>>) {\n const where = composeWhere(filter);\n const found = (await attachSession(m.find(where).select({ _id: 1 }))\n .lean()\n .exec()) as { _id: unknown }[];\n if (found.length === 0) return [];\n const ids = found.map(d => d._id);\n await attachSession(m.updateMany({ _id: { $in: ids } }, forUpdate(patch))).exec();\n return (await attachSession(m.find({ _id: { $in: ids } }))\n .lean()\n .exec()) as Row<TDoc>[];\n },\n\n async deleteById(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n const where = composeWhere(withId(undefined, idKey as string, id));\n const row = await attachSession(m.findOneAndDelete(where)).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async deleteWhere(filter: Filter<TDoc>) {\n const where = composeWhere(filter);\n const rows = (await attachSession(m.find(where)).lean().exec()) as { _id: unknown }[];\n if (rows.length === 0) return [];\n await attachSession(m.deleteMany({ _id: { $in: rows.map(d => d._id) } })).exec();\n return rows as Row<TDoc>[];\n },\n\n async softDelete(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n if (!hasDeletedAt) throw new Error(\"softDelete: schema has no deletedAt path.\");\n const where = composeWhere(withId(undefined, idKey as string, id), false);\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate({ deletedAt: new Date() }), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async restore(id: Id, idKey: FieldKey<TDoc> = \"id\" as FieldKey<TDoc>) {\n if (!hasDeletedAt) throw new Error(\"restore: schema has no deletedAt path.\");\n const where = composeWhere(withId(undefined, idKey as string, id), true);\n const q: AnyQuery = m.findOneAndUpdate(where, forUpdate({ deletedAt: null }), { returnDocument: \"after\" });\n const row = await attachSession(q).lean().exec();\n return (row ?? undefined) as Row<TDoc> | undefined;\n },\n\n async aggregate(spec: AggregateSpec<TDoc>) {\n const groupKeys = toArr(spec.groupBy) as string[];\n // Aggregate `$match` doesn't auto-cast values the way `find()` does; cast\n // the filter against the schema so wire strings (dates / ObjectIds) become\n // proper BSON types — keeping aggregate filters consistent with reads.\n const rawMatch = composeWhere(spec.filter, spec.withDeleted);\n let match: Record<string, unknown> = rawMatch;\n try {\n const q = m.find(rawMatch);\n q.cast(m);\n match = q.getFilter();\n } catch {\n /* fall back to the uncast filter */\n }\n const groupId = groupKeys.length ? Object.fromEntries(groupKeys.map(k => [k, `$${resolveField(m, k) ?? k}`])) : null;\n const group: Record<string, unknown> = { _id: groupId };\n if (spec.count) group.count = { $sum: 1 };\n const addAgg = (op: \"$sum\" | \"$avg\" | \"$min\" | \"$max\", keys: string[], prefix: string) => {\n for (const k of keys) {\n const field = resolveField(m, k);\n if (field) group[`${prefix}_${k}`] = { [op]: `$${field}` };\n }\n };\n addAgg(\"$sum\", toArr(spec.sum) as string[], \"sum\");\n addAgg(\"$avg\", toArr(spec.avg) as string[], \"avg\");\n addAgg(\"$min\", toArr(spec.min) as string[], \"min\");\n addAgg(\"$max\", toArr(spec.max) as string[], \"max\");\n\n let agg = m.aggregate([{ $match: match }, { $group: group }] as never);\n const session = runtime.getSession();\n if (session) agg = agg.session(session);\n const rows = (await agg.exec()) as Record<string, unknown>[];\n // Flatten the group `_id` fields back into each row (matches drizzle's shape).\n return rows.map(({ _id, ...rest }) => ({ ...(typeof _id === \"object\" && _id ? _id : {}), ...rest })) as AggregateRow[];\n },\n\n scoped(scope: Scope<TDoc>) {\n return buildRepository(runtime, model, { ...config, scope: { ...config.scope, ...scope } });\n },\n };\n\n return repository as unknown as Repository<TDoc>;\n}\n","import { AsyncLocalStorage } from \"node:async_hooks\";\n\nimport type { ClientSession } from \"mongoose\";\n\n/**\n * Per-transaction ambient state. Lets repositories pick up the active Mongo\n * `ClientSession` without threading it through every call. Set by\n * `registry.transaction`.\n */\nexport interface RepoContext {\n session?: ClientSession;\n}\n\nexport interface ContextStore {\n /** Read the current ambient context (undefined outside any `run`). */\n get(): RepoContext | undefined;\n /** Run `fn` with `patch` merged over the current context. */\n run<T>(patch: RepoContext, fn: () => T): T;\n}\n\nexport function createContextStore(): ContextStore {\n const als = new AsyncLocalStorage<RepoContext>();\n return {\n get: () => als.getStore(),\n run: (patch, fn) => als.run({ ...als.getStore(), ...patch }, fn),\n };\n}\n","import type { Connection, Model } from \"mongoose\";\nimport { DEFAULT_LIMIT, DEFAULT_PER_PAGE } from \"@querykitjs/core\";\n\nimport type { RelationDocs, RelationMap, Registry, RegistryOptions, Repository, RepositoryExtender, RepositoryOptions } from \"./types\";\nimport { buildRepository, type RepoRuntime } from \"./repository\";\nimport { createContextStore } from \"./internal/context\";\n\n/**\n * Create the DB **registry** once. It holds the Mongoose connection (for\n * transactions) and yields a {@link Repository} per model. Transactions flow\n * ambiently via AsyncLocalStorage — repositories used inside\n * `registry.transaction(...)` automatically run on that session.\n *\n * @param connection - the Mongoose `Connection` the models belong to.\n * @param options - `defaultPerPage` (findList) / `defaultLimit` (infinite/cursor);\n * defaults to `@querykitjs/core`'s `DEFAULT_PER_PAGE` / `DEFAULT_LIMIT` (20).\n * @example\n * ```ts\n * const registry = createRegistry(mongoose.connection);\n * const usersRepo = registry.repository(User);\n * ```\n */\nexport function createRegistry(connection: Connection, options: RegistryOptions = {}): Registry {\n const ctx = createContextStore();\n const runtime: RepoRuntime = {\n getSession: () => ctx.get()?.session,\n defaultPerPage: options.defaultPerPage ?? DEFAULT_PER_PAGE,\n defaultLimit: options.defaultLimit ?? DEFAULT_LIMIT,\n };\n\n function repository<TDoc>(model: Model<TDoc>): Repository<TDoc>;\n function repository<TDoc, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n extend: RepositoryExtender<TDoc, Record<never, never>, TExt>,\n ): Repository<TDoc> & TExt;\n function repository<TDoc, TRel extends RelationMap>(model: Model<TDoc>, options: RepositoryOptions<TRel>): Repository<TDoc, RelationDocs<TRel>>;\n function repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n options: RepositoryOptions<TRel>,\n extend: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n ): Repository<TDoc, RelationDocs<TRel>> & TExt;\n function repository<TDoc, TRel extends RelationMap, TExt extends Record<string, unknown>>(\n model: Model<TDoc>,\n arg2?: RepositoryOptions<TRel> | RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n arg3?: RepositoryExtender<TDoc, RelationDocs<TRel>, TExt>,\n ) {\n // 2nd arg is either the relations options object or the extender fn.\n // `relations` is type-only (drives `with` inference); runtime populate is\n // opt-in per call, so nothing to wire from it here.\n const extend = typeof arg2 === \"function\" ? arg2 : arg3;\n const base = buildRepository(runtime, model) as unknown as Repository<TDoc, RelationDocs<TRel>>;\n return extend ? { ...base, ...extend(base) } : base;\n }\n\n const transaction = async <T>(fn: () => Promise<T>): Promise<T> => {\n // Already inside a transaction (Mongo has no nested tx/savepoints) → reuse it.\n if (ctx.get()?.session) return fn();\n\n const session = await connection.startSession();\n try {\n let result!: T;\n await session.withTransaction(async () => {\n result = await ctx.run({ session }, fn);\n });\n return result;\n } finally {\n await session.endSession();\n }\n };\n\n return { repository, transaction };\n}\n","import { createFilters as coreCreateFilters, f } from \"@querykitjs/core\";\n\nimport type { FieldKey, RawFilter } from \"./types\";\n\n/**\n * Typed, ergonomic filter builders for a document type (field-name autocomplete).\n * A thin wrapper over `@querykitjs/core`'s builder — the key type is the model's\n * field key, the raw escape-hatch is a native Mongo `QueryFilter`.\n *\n * @example\n * ```ts\n * const uf = createFilters<IUser>();\n * await usersRepo.findAll({ filter: uf.and(uf.eq(\"status\", \"active\"), uf.gte(\"age\", 18)) });\n * ```\n */\nexport function createFilters<TDoc>() {\n return coreCreateFilters<FieldKey<TDoc>, RawFilter<TDoc>>();\n}\n\n/** Untyped filter helpers for quick use. */\nexport { f };\n"]}