@farming-labs/orm-mongoose 0.0.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/dist/index.cjs +657 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +74 -0
- package/dist/index.d.ts +74 -0
- package/dist/index.js +634 -0
- package/dist/index.js.map +1 -0
- package/package.json +37 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,657 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __export = (target, all) => {
|
|
7
|
+
for (var name in all)
|
|
8
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
+
};
|
|
10
|
+
var __copyProps = (to, from, except, desc) => {
|
|
11
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
+
for (let key of __getOwnPropNames(from))
|
|
13
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
+
}
|
|
16
|
+
return to;
|
|
17
|
+
};
|
|
18
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
+
|
|
20
|
+
// src/index.ts
|
|
21
|
+
var index_exports = {};
|
|
22
|
+
__export(index_exports, {
|
|
23
|
+
createMongooseDriver: () => createMongooseDriver
|
|
24
|
+
});
|
|
25
|
+
module.exports = __toCommonJS(index_exports);
|
|
26
|
+
var import_node_crypto = require("crypto");
|
|
27
|
+
var import_orm = require("@farming-labs/orm");
|
|
28
|
+
var manifestCache = /* @__PURE__ */ new WeakMap();
|
|
29
|
+
function getManifest(schema) {
|
|
30
|
+
const cached = manifestCache.get(schema);
|
|
31
|
+
if (cached) return cached;
|
|
32
|
+
const next = (0, import_orm.createManifest)(schema);
|
|
33
|
+
manifestCache.set(schema, next);
|
|
34
|
+
return next;
|
|
35
|
+
}
|
|
36
|
+
function identityField(model) {
|
|
37
|
+
if (model.fields.id) return model.fields.id;
|
|
38
|
+
const uniqueField = Object.values(model.fields).find((field) => field.unique);
|
|
39
|
+
if (uniqueField) return uniqueField;
|
|
40
|
+
throw new Error(
|
|
41
|
+
`Model "${model.name}" requires an "id" field or a unique field for the Mongoose runtime.`
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
function applyDefault(value, field) {
|
|
45
|
+
if (value !== void 0) return value;
|
|
46
|
+
if (field.generated === "id") return (0, import_node_crypto.randomUUID)();
|
|
47
|
+
if (field.generated === "now") return /* @__PURE__ */ new Date();
|
|
48
|
+
if (typeof field.defaultValue === "function") {
|
|
49
|
+
return field.defaultValue();
|
|
50
|
+
}
|
|
51
|
+
return field.defaultValue;
|
|
52
|
+
}
|
|
53
|
+
function isFilterObject(value) {
|
|
54
|
+
return !!value && typeof value === "object" && !(value instanceof Date) && !Array.isArray(value);
|
|
55
|
+
}
|
|
56
|
+
function escapeRegex(value) {
|
|
57
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
58
|
+
}
|
|
59
|
+
function mergeWhere(...clauses) {
|
|
60
|
+
const defined = clauses.filter(Boolean);
|
|
61
|
+
if (!defined.length) return void 0;
|
|
62
|
+
if (defined.length === 1) return defined[0];
|
|
63
|
+
return {
|
|
64
|
+
AND: defined
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
function parseReference(reference) {
|
|
68
|
+
if (!reference) return null;
|
|
69
|
+
const [model, field] = reference.split(".");
|
|
70
|
+
if (!model || !field) return null;
|
|
71
|
+
return { model, field };
|
|
72
|
+
}
|
|
73
|
+
function extractEqualityValue(filter) {
|
|
74
|
+
if (!isFilterObject(filter)) {
|
|
75
|
+
return {
|
|
76
|
+
supported: true,
|
|
77
|
+
value: filter
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
const keys = Object.keys(filter);
|
|
81
|
+
if (keys.length === 1 && "eq" in filter) {
|
|
82
|
+
return {
|
|
83
|
+
supported: true,
|
|
84
|
+
value: filter.eq
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
return {
|
|
88
|
+
supported: false,
|
|
89
|
+
value: void 0
|
|
90
|
+
};
|
|
91
|
+
}
|
|
92
|
+
function extractUpsertConflict(model, where) {
|
|
93
|
+
const keys = Object.keys(where).filter((key) => key !== "AND" && key !== "OR" && key !== "NOT");
|
|
94
|
+
if ("AND" in where || "OR" in where || "NOT" in where || keys.length !== 1) {
|
|
95
|
+
throw new Error(
|
|
96
|
+
`Upsert on model "${model.name}" requires a single unique equality filter in "where".`
|
|
97
|
+
);
|
|
98
|
+
}
|
|
99
|
+
const fieldName = keys[0];
|
|
100
|
+
const field = model.fields[fieldName];
|
|
101
|
+
if (!field) {
|
|
102
|
+
throw new Error(`Unknown field "${fieldName}" on model "${model.name}".`);
|
|
103
|
+
}
|
|
104
|
+
if (!(field.kind === "id" || field.unique)) {
|
|
105
|
+
throw new Error(
|
|
106
|
+
`Upsert on model "${model.name}" requires the "where" field "${fieldName}" to be unique or an id field.`
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
const { supported, value } = extractEqualityValue(where[fieldName]);
|
|
110
|
+
if (!supported || value === void 0 || value === null) {
|
|
111
|
+
throw new Error(
|
|
112
|
+
`Upsert on model "${model.name}" requires the "where" field "${fieldName}" to use a single non-null equality value.`
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
return {
|
|
116
|
+
field,
|
|
117
|
+
value
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
function mergeUpsertCreateData(model, createData, conflict) {
|
|
121
|
+
const currentValue = createData[conflict.field.name];
|
|
122
|
+
if (currentValue !== void 0 && currentValue !== conflict.value) {
|
|
123
|
+
throw new Error(
|
|
124
|
+
`Upsert on model "${model.name}" requires create.${conflict.field.name} to match where.${conflict.field.name}.`
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
return {
|
|
128
|
+
...createData,
|
|
129
|
+
[conflict.field.name]: currentValue ?? conflict.value
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
function validateUpsertUpdateData(model, updateData, conflict) {
|
|
133
|
+
const nextValue = updateData[conflict.field.name];
|
|
134
|
+
if (nextValue !== void 0 && nextValue !== conflict.value) {
|
|
135
|
+
throw new Error(
|
|
136
|
+
`Upsert on model "${model.name}" cannot change the conflict field "${conflict.field.name}".`
|
|
137
|
+
);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
function isExecLike(value) {
|
|
141
|
+
return !!value && typeof value === "object" && "exec" in value;
|
|
142
|
+
}
|
|
143
|
+
async function execute(operation, session) {
|
|
144
|
+
if (isExecLike(operation)) {
|
|
145
|
+
const query = session && typeof operation.session === "function" ? operation.session(session) : operation;
|
|
146
|
+
return query.exec();
|
|
147
|
+
}
|
|
148
|
+
return operation;
|
|
149
|
+
}
|
|
150
|
+
async function normalizeCreated(doc) {
|
|
151
|
+
const result = await doc;
|
|
152
|
+
return Array.isArray(result) ? result[0] ?? null : result;
|
|
153
|
+
}
|
|
154
|
+
function createMongooseDriverInternal(config, state = {}) {
|
|
155
|
+
function getModel(modelName) {
|
|
156
|
+
const model = config.models[modelName];
|
|
157
|
+
if (!model) {
|
|
158
|
+
throw new Error(`No Mongoose model was provided for schema model "${modelName}".`);
|
|
159
|
+
}
|
|
160
|
+
return model;
|
|
161
|
+
}
|
|
162
|
+
function fieldTransform(modelName, fieldName) {
|
|
163
|
+
return config.transforms?.[modelName]?.[fieldName];
|
|
164
|
+
}
|
|
165
|
+
function encodeValue(modelName, field, value) {
|
|
166
|
+
if (value === void 0) return value;
|
|
167
|
+
if (value === null) return null;
|
|
168
|
+
let next = value;
|
|
169
|
+
if (field.kind === "boolean") {
|
|
170
|
+
next = Boolean(next);
|
|
171
|
+
} else if (field.kind === "datetime") {
|
|
172
|
+
next = next instanceof Date ? next : new Date(String(next));
|
|
173
|
+
}
|
|
174
|
+
const transform = fieldTransform(modelName, field.name);
|
|
175
|
+
return transform?.encode ? transform.encode(next) : next;
|
|
176
|
+
}
|
|
177
|
+
function decodeValue(modelName, field, value) {
|
|
178
|
+
if (value === void 0) return value;
|
|
179
|
+
if (value === null) return null;
|
|
180
|
+
const transform = fieldTransform(modelName, field.name);
|
|
181
|
+
let next = transform?.decode ? transform.decode(value) : value;
|
|
182
|
+
if (field.kind === "boolean") {
|
|
183
|
+
return Boolean(next);
|
|
184
|
+
}
|
|
185
|
+
if (field.kind === "datetime") {
|
|
186
|
+
return next instanceof Date ? next : new Date(String(next));
|
|
187
|
+
}
|
|
188
|
+
if (field.kind === "id") {
|
|
189
|
+
return typeof next === "string" ? next : String(next);
|
|
190
|
+
}
|
|
191
|
+
return next;
|
|
192
|
+
}
|
|
193
|
+
function buildDocument(model, data) {
|
|
194
|
+
const doc = {};
|
|
195
|
+
for (const field of Object.values(model.fields)) {
|
|
196
|
+
const value = applyDefault(data[field.name], field);
|
|
197
|
+
if (value !== void 0) {
|
|
198
|
+
doc[field.column] = encodeValue(model.name, field, value);
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
return doc;
|
|
202
|
+
}
|
|
203
|
+
function buildUpdate(model, data) {
|
|
204
|
+
const update = {};
|
|
205
|
+
for (const [fieldName, value] of Object.entries(data)) {
|
|
206
|
+
if (value === void 0) continue;
|
|
207
|
+
const field = model.fields[fieldName];
|
|
208
|
+
if (!field) {
|
|
209
|
+
throw new Error(`Unknown field "${fieldName}" on model "${model.name}".`);
|
|
210
|
+
}
|
|
211
|
+
update[field.column] = encodeValue(model.name, field, value);
|
|
212
|
+
}
|
|
213
|
+
return update;
|
|
214
|
+
}
|
|
215
|
+
function decodeRow(model, doc) {
|
|
216
|
+
const output = {};
|
|
217
|
+
for (const field of Object.values(model.fields)) {
|
|
218
|
+
output[field.name] = decodeValue(model.name, field, doc[field.column]);
|
|
219
|
+
}
|
|
220
|
+
return output;
|
|
221
|
+
}
|
|
222
|
+
function compileFieldFilter(model, fieldName, filter) {
|
|
223
|
+
const field = model.fields[fieldName];
|
|
224
|
+
if (!field) {
|
|
225
|
+
throw new Error(`Unknown field "${fieldName}" on model "${model.name}".`);
|
|
226
|
+
}
|
|
227
|
+
if (!isFilterObject(filter)) {
|
|
228
|
+
return {
|
|
229
|
+
[field.column]: encodeValue(model.name, field, filter)
|
|
230
|
+
};
|
|
231
|
+
}
|
|
232
|
+
const operations = {};
|
|
233
|
+
if ("eq" in filter) {
|
|
234
|
+
operations.$eq = encodeValue(model.name, field, filter.eq);
|
|
235
|
+
}
|
|
236
|
+
if ("not" in filter) {
|
|
237
|
+
operations.$ne = encodeValue(model.name, field, filter.not);
|
|
238
|
+
}
|
|
239
|
+
if ("in" in filter) {
|
|
240
|
+
const values = Array.isArray(filter.in) ? filter.in : [];
|
|
241
|
+
operations.$in = values.map((value) => encodeValue(model.name, field, value));
|
|
242
|
+
}
|
|
243
|
+
if ("contains" in filter) {
|
|
244
|
+
operations.$regex = new RegExp(escapeRegex(String(filter.contains ?? "")));
|
|
245
|
+
}
|
|
246
|
+
if ("gt" in filter) {
|
|
247
|
+
operations.$gt = encodeValue(model.name, field, filter.gt);
|
|
248
|
+
}
|
|
249
|
+
if ("gte" in filter) {
|
|
250
|
+
operations.$gte = encodeValue(model.name, field, filter.gte);
|
|
251
|
+
}
|
|
252
|
+
if ("lt" in filter) {
|
|
253
|
+
operations.$lt = encodeValue(model.name, field, filter.lt);
|
|
254
|
+
}
|
|
255
|
+
if ("lte" in filter) {
|
|
256
|
+
operations.$lte = encodeValue(model.name, field, filter.lte);
|
|
257
|
+
}
|
|
258
|
+
return {
|
|
259
|
+
[field.column]: operations
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
function compileWhere(model, where) {
|
|
263
|
+
if (!where) return {};
|
|
264
|
+
const clauses = [];
|
|
265
|
+
for (const [key, value] of Object.entries(where)) {
|
|
266
|
+
if (key === "AND") {
|
|
267
|
+
const nested = (Array.isArray(value) ? value : []).map((item) => compileWhere(model, item)).filter((item) => Object.keys(item).length > 0);
|
|
268
|
+
if (nested.length) clauses.push({ $and: nested });
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (key === "OR") {
|
|
272
|
+
const nested = (Array.isArray(value) ? value : []).map((item) => compileWhere(model, item)).filter((item) => Object.keys(item).length > 0);
|
|
273
|
+
if (nested.length) clauses.push({ $or: nested });
|
|
274
|
+
continue;
|
|
275
|
+
}
|
|
276
|
+
if (key === "NOT") {
|
|
277
|
+
const nested = compileWhere(model, value);
|
|
278
|
+
if (Object.keys(nested).length) clauses.push({ $nor: [nested] });
|
|
279
|
+
continue;
|
|
280
|
+
}
|
|
281
|
+
clauses.push(compileFieldFilter(model, key, value));
|
|
282
|
+
}
|
|
283
|
+
if (!clauses.length) return {};
|
|
284
|
+
if (clauses.length === 1) return clauses[0];
|
|
285
|
+
return {
|
|
286
|
+
$and: clauses
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
function compileOrderBy(model, orderBy) {
|
|
290
|
+
if (!orderBy) return void 0;
|
|
291
|
+
const output = {};
|
|
292
|
+
for (const [fieldName, direction] of Object.entries(orderBy)) {
|
|
293
|
+
const field = model.fields[fieldName];
|
|
294
|
+
if (!field) continue;
|
|
295
|
+
output[field.column] = direction === "desc" ? -1 : 1;
|
|
296
|
+
}
|
|
297
|
+
return Object.keys(output).length ? output : void 0;
|
|
298
|
+
}
|
|
299
|
+
async function runFindMany(model, args) {
|
|
300
|
+
const query = getModel(model.name).find(compileWhere(model, args.where));
|
|
301
|
+
const orderBy = compileOrderBy(model, args.orderBy);
|
|
302
|
+
if (orderBy) query.sort(orderBy);
|
|
303
|
+
if (args.skip !== void 0) query.skip(args.skip);
|
|
304
|
+
if (args.take !== void 0) query.limit(args.take);
|
|
305
|
+
if (state.session) query.session(state.session);
|
|
306
|
+
query.lean();
|
|
307
|
+
return query.exec();
|
|
308
|
+
}
|
|
309
|
+
async function runFindOne(model, args) {
|
|
310
|
+
const orderBy = compileOrderBy(model, args.orderBy);
|
|
311
|
+
if (orderBy) {
|
|
312
|
+
const rows = await runFindMany(model, {
|
|
313
|
+
...args,
|
|
314
|
+
take: 1
|
|
315
|
+
});
|
|
316
|
+
return rows[0] ?? null;
|
|
317
|
+
}
|
|
318
|
+
const query = getModel(model.name).findOne(compileWhere(model, args.where));
|
|
319
|
+
if (state.session) query.session(state.session);
|
|
320
|
+
query.lean();
|
|
321
|
+
return query.exec();
|
|
322
|
+
}
|
|
323
|
+
async function loadRows(schema, modelName, args) {
|
|
324
|
+
const manifest = getManifest(schema);
|
|
325
|
+
const model = manifest.models[modelName];
|
|
326
|
+
const docs = await runFindMany(model, args);
|
|
327
|
+
const rows = docs.map((doc) => decodeRow(model, doc));
|
|
328
|
+
return Promise.all(rows.map((row) => projectRow(schema, modelName, row, args.select)));
|
|
329
|
+
}
|
|
330
|
+
async function loadOneRow(schema, modelName, args) {
|
|
331
|
+
const rows = await loadRows(schema, modelName, {
|
|
332
|
+
...args,
|
|
333
|
+
take: 1
|
|
334
|
+
});
|
|
335
|
+
return rows[0] ?? null;
|
|
336
|
+
}
|
|
337
|
+
async function loadRawOneRow(schema, modelName, args) {
|
|
338
|
+
const manifest = getManifest(schema);
|
|
339
|
+
const model = manifest.models[modelName];
|
|
340
|
+
const doc = await runFindOne(model, args);
|
|
341
|
+
return doc ? decodeRow(model, doc) : null;
|
|
342
|
+
}
|
|
343
|
+
async function projectRow(schema, modelName, row, select) {
|
|
344
|
+
const manifest = getManifest(schema);
|
|
345
|
+
const model = manifest.models[modelName];
|
|
346
|
+
const output = {};
|
|
347
|
+
if (!select) {
|
|
348
|
+
for (const fieldName of Object.keys(model.fields)) {
|
|
349
|
+
output[fieldName] = row[fieldName];
|
|
350
|
+
}
|
|
351
|
+
return output;
|
|
352
|
+
}
|
|
353
|
+
for (const [key, value] of Object.entries(select)) {
|
|
354
|
+
if (value === void 0) continue;
|
|
355
|
+
if (key in model.fields && value === true) {
|
|
356
|
+
output[key] = row[key];
|
|
357
|
+
continue;
|
|
358
|
+
}
|
|
359
|
+
if (key in schema.models[modelName].relations) {
|
|
360
|
+
output[key] = await resolveRelation(
|
|
361
|
+
schema,
|
|
362
|
+
modelName,
|
|
363
|
+
key,
|
|
364
|
+
row,
|
|
365
|
+
value
|
|
366
|
+
);
|
|
367
|
+
}
|
|
368
|
+
}
|
|
369
|
+
return output;
|
|
370
|
+
}
|
|
371
|
+
async function resolveRelation(schema, modelName, relationName, row, value) {
|
|
372
|
+
const manifest = getManifest(schema);
|
|
373
|
+
const relation = schema.models[modelName].relations[relationName];
|
|
374
|
+
const relationArgs = value === true ? {} : value;
|
|
375
|
+
if (relation.kind === "belongsTo") {
|
|
376
|
+
const foreignField = manifest.models[modelName].fields[relation.foreignKey];
|
|
377
|
+
const targetReference = parseReference(foreignField?.references);
|
|
378
|
+
const targetField2 = targetReference?.field ?? identityField(manifest.models[relation.target]).name;
|
|
379
|
+
const foreignValue = row[relation.foreignKey];
|
|
380
|
+
if (foreignValue == null) return null;
|
|
381
|
+
return loadOneRow(schema, relation.target, {
|
|
382
|
+
where: mergeWhere(
|
|
383
|
+
relationArgs.where,
|
|
384
|
+
{
|
|
385
|
+
[targetField2]: foreignValue
|
|
386
|
+
}
|
|
387
|
+
),
|
|
388
|
+
orderBy: relationArgs.orderBy,
|
|
389
|
+
select: relationArgs.select
|
|
390
|
+
});
|
|
391
|
+
}
|
|
392
|
+
if (relation.kind === "hasOne") {
|
|
393
|
+
const targetModel = manifest.models[relation.target];
|
|
394
|
+
const foreignField = targetModel.fields[relation.foreignKey];
|
|
395
|
+
const sourceReference = parseReference(foreignField?.references);
|
|
396
|
+
const sourceField2 = sourceReference?.field ?? identityField(manifest.models[modelName]).name;
|
|
397
|
+
const sourceValue2 = row[sourceField2];
|
|
398
|
+
if (sourceValue2 == null) return null;
|
|
399
|
+
return loadOneRow(schema, relation.target, {
|
|
400
|
+
where: mergeWhere(
|
|
401
|
+
relationArgs.where,
|
|
402
|
+
{
|
|
403
|
+
[relation.foreignKey]: sourceValue2
|
|
404
|
+
}
|
|
405
|
+
),
|
|
406
|
+
orderBy: relationArgs.orderBy,
|
|
407
|
+
select: relationArgs.select
|
|
408
|
+
});
|
|
409
|
+
}
|
|
410
|
+
if (relation.kind === "hasMany") {
|
|
411
|
+
const targetModel = manifest.models[relation.target];
|
|
412
|
+
const foreignField = targetModel.fields[relation.foreignKey];
|
|
413
|
+
const sourceReference = parseReference(foreignField?.references);
|
|
414
|
+
const sourceField2 = sourceReference?.field ?? identityField(manifest.models[modelName]).name;
|
|
415
|
+
const sourceValue2 = row[sourceField2];
|
|
416
|
+
if (sourceValue2 == null) return [];
|
|
417
|
+
return loadRows(schema, relation.target, {
|
|
418
|
+
where: mergeWhere(
|
|
419
|
+
relationArgs.where,
|
|
420
|
+
{
|
|
421
|
+
[relation.foreignKey]: sourceValue2
|
|
422
|
+
}
|
|
423
|
+
),
|
|
424
|
+
orderBy: relationArgs.orderBy,
|
|
425
|
+
take: relationArgs.take,
|
|
426
|
+
skip: relationArgs.skip,
|
|
427
|
+
select: relationArgs.select
|
|
428
|
+
});
|
|
429
|
+
}
|
|
430
|
+
const throughModel = manifest.models[relation.through];
|
|
431
|
+
const throughFromReference = parseReference(throughModel.fields[relation.from]?.references);
|
|
432
|
+
const throughToReference = parseReference(throughModel.fields[relation.to]?.references);
|
|
433
|
+
const sourceField = throughFromReference?.field ?? identityField(manifest.models[modelName]).name;
|
|
434
|
+
const targetField = throughToReference?.field ?? identityField(manifest.models[relation.target]).name;
|
|
435
|
+
const sourceValue = row[sourceField];
|
|
436
|
+
if (sourceValue == null) return [];
|
|
437
|
+
const throughRows = await loadRows(schema, relation.through, {
|
|
438
|
+
where: {
|
|
439
|
+
[relation.from]: sourceValue
|
|
440
|
+
}
|
|
441
|
+
});
|
|
442
|
+
const targetIds = throughRows.map((item) => item[relation.to]).filter((item) => item != null);
|
|
443
|
+
if (!targetIds.length) return [];
|
|
444
|
+
return loadRows(schema, relation.target, {
|
|
445
|
+
where: mergeWhere(
|
|
446
|
+
relationArgs.where,
|
|
447
|
+
{
|
|
448
|
+
[targetField]: {
|
|
449
|
+
in: targetIds
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
),
|
|
453
|
+
orderBy: relationArgs.orderBy,
|
|
454
|
+
take: relationArgs.take,
|
|
455
|
+
skip: relationArgs.skip,
|
|
456
|
+
select: relationArgs.select
|
|
457
|
+
});
|
|
458
|
+
}
|
|
459
|
+
async function runTransaction(run) {
|
|
460
|
+
if (state.session) {
|
|
461
|
+
return run(createMongooseDriverInternal(config, state));
|
|
462
|
+
}
|
|
463
|
+
const startSession = config.startSession ?? config.connection?.startSession.bind(config.connection);
|
|
464
|
+
if (!startSession) {
|
|
465
|
+
return run(createMongooseDriverInternal(config, state));
|
|
466
|
+
}
|
|
467
|
+
const session = await startSession();
|
|
468
|
+
try {
|
|
469
|
+
if (session.withTransaction) {
|
|
470
|
+
return await session.withTransaction(
|
|
471
|
+
() => run(
|
|
472
|
+
createMongooseDriverInternal(config, {
|
|
473
|
+
session
|
|
474
|
+
})
|
|
475
|
+
)
|
|
476
|
+
);
|
|
477
|
+
}
|
|
478
|
+
if (session.startTransaction && session.commitTransaction && session.abortTransaction) {
|
|
479
|
+
session.startTransaction();
|
|
480
|
+
try {
|
|
481
|
+
const result = await run(
|
|
482
|
+
createMongooseDriverInternal(config, {
|
|
483
|
+
session
|
|
484
|
+
})
|
|
485
|
+
);
|
|
486
|
+
await session.commitTransaction();
|
|
487
|
+
return result;
|
|
488
|
+
} catch (error) {
|
|
489
|
+
await session.abortTransaction();
|
|
490
|
+
throw error;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
return run(
|
|
494
|
+
createMongooseDriverInternal(config, {
|
|
495
|
+
session
|
|
496
|
+
})
|
|
497
|
+
);
|
|
498
|
+
} finally {
|
|
499
|
+
await session.endSession?.();
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
const driver = {
|
|
503
|
+
async findMany(schema, model, args) {
|
|
504
|
+
return loadRows(schema, model, args);
|
|
505
|
+
},
|
|
506
|
+
async findFirst(schema, model, args) {
|
|
507
|
+
return loadOneRow(schema, model, args);
|
|
508
|
+
},
|
|
509
|
+
async findUnique(schema, model, args) {
|
|
510
|
+
return loadOneRow(schema, model, args);
|
|
511
|
+
},
|
|
512
|
+
async count(schema, model, args) {
|
|
513
|
+
const manifest = getManifest(schema);
|
|
514
|
+
const result = await execute(
|
|
515
|
+
getModel(model).countDocuments(
|
|
516
|
+
compileWhere(manifest.models[model], args?.where)
|
|
517
|
+
),
|
|
518
|
+
state.session
|
|
519
|
+
);
|
|
520
|
+
return Number(result);
|
|
521
|
+
},
|
|
522
|
+
async create(schema, model, args) {
|
|
523
|
+
const manifest = getManifest(schema);
|
|
524
|
+
const created = await normalizeCreated(
|
|
525
|
+
getModel(model).create(
|
|
526
|
+
buildDocument(manifest.models[model], args.data),
|
|
527
|
+
state.session ? { session: state.session } : void 0
|
|
528
|
+
)
|
|
529
|
+
);
|
|
530
|
+
if (!created) {
|
|
531
|
+
throw new Error(`Create on model "${String(model)}" did not return a document.`);
|
|
532
|
+
}
|
|
533
|
+
const row = decodeRow(manifest.models[model], created);
|
|
534
|
+
return projectRow(schema, model, row, args.select);
|
|
535
|
+
},
|
|
536
|
+
async createMany(schema, model, args) {
|
|
537
|
+
const results = [];
|
|
538
|
+
for (const entry of args.data) {
|
|
539
|
+
results.push(
|
|
540
|
+
await driver.create(schema, model, {
|
|
541
|
+
data: entry,
|
|
542
|
+
select: args.select
|
|
543
|
+
})
|
|
544
|
+
);
|
|
545
|
+
}
|
|
546
|
+
return results;
|
|
547
|
+
},
|
|
548
|
+
async update(schema, model, args) {
|
|
549
|
+
const manifest = getManifest(schema);
|
|
550
|
+
const updated = await getModel(model).findOneAndUpdate(
|
|
551
|
+
compileWhere(manifest.models[model], args.where),
|
|
552
|
+
{
|
|
553
|
+
$set: buildUpdate(manifest.models[model], args.data)
|
|
554
|
+
},
|
|
555
|
+
{
|
|
556
|
+
new: true,
|
|
557
|
+
returnDocument: "after",
|
|
558
|
+
session: state.session
|
|
559
|
+
}
|
|
560
|
+
).lean().exec();
|
|
561
|
+
if (!updated) return null;
|
|
562
|
+
return projectRow(
|
|
563
|
+
schema,
|
|
564
|
+
model,
|
|
565
|
+
decodeRow(manifest.models[model], updated),
|
|
566
|
+
args.select
|
|
567
|
+
);
|
|
568
|
+
},
|
|
569
|
+
async updateMany(schema, model, args) {
|
|
570
|
+
const manifest = getManifest(schema);
|
|
571
|
+
const update = buildUpdate(manifest.models[model], args.data);
|
|
572
|
+
if (!Object.keys(update).length) return 0;
|
|
573
|
+
const result = await execute(
|
|
574
|
+
getModel(model).updateMany(
|
|
575
|
+
compileWhere(manifest.models[model], args.where),
|
|
576
|
+
{
|
|
577
|
+
$set: update
|
|
578
|
+
},
|
|
579
|
+
state.session ? { session: state.session } : void 0
|
|
580
|
+
),
|
|
581
|
+
state.session
|
|
582
|
+
);
|
|
583
|
+
return Number(result.modifiedCount ?? result.matchedCount ?? 0);
|
|
584
|
+
},
|
|
585
|
+
async upsert(schema, model, args) {
|
|
586
|
+
const manifest = getManifest(schema);
|
|
587
|
+
const modelManifest = manifest.models[model];
|
|
588
|
+
const conflict = extractUpsertConflict(modelManifest, args.where);
|
|
589
|
+
validateUpsertUpdateData(
|
|
590
|
+
modelManifest,
|
|
591
|
+
args.update,
|
|
592
|
+
conflict
|
|
593
|
+
);
|
|
594
|
+
const created = buildDocument(
|
|
595
|
+
modelManifest,
|
|
596
|
+
mergeUpsertCreateData(
|
|
597
|
+
modelManifest,
|
|
598
|
+
args.create,
|
|
599
|
+
conflict
|
|
600
|
+
)
|
|
601
|
+
);
|
|
602
|
+
const updated = await getModel(model).findOneAndUpdate(
|
|
603
|
+
compileWhere(modelManifest, args.where),
|
|
604
|
+
{
|
|
605
|
+
$set: buildUpdate(modelManifest, args.update),
|
|
606
|
+
$setOnInsert: created
|
|
607
|
+
},
|
|
608
|
+
{
|
|
609
|
+
upsert: true,
|
|
610
|
+
new: true,
|
|
611
|
+
returnDocument: "after",
|
|
612
|
+
session: state.session
|
|
613
|
+
}
|
|
614
|
+
).lean().exec();
|
|
615
|
+
if (!updated) {
|
|
616
|
+
throw new Error(`Upsert on model "${String(model)}" did not return a document.`);
|
|
617
|
+
}
|
|
618
|
+
return projectRow(
|
|
619
|
+
schema,
|
|
620
|
+
model,
|
|
621
|
+
decodeRow(modelManifest, updated),
|
|
622
|
+
args.select
|
|
623
|
+
);
|
|
624
|
+
},
|
|
625
|
+
async delete(schema, model, args) {
|
|
626
|
+
const manifest = getManifest(schema);
|
|
627
|
+
const deleted = await getModel(model).findOneAndDelete(
|
|
628
|
+
compileWhere(manifest.models[model], args.where),
|
|
629
|
+
state.session ? { session: state.session } : void 0
|
|
630
|
+
).lean().exec();
|
|
631
|
+
return deleted ? 1 : 0;
|
|
632
|
+
},
|
|
633
|
+
async deleteMany(schema, model, args) {
|
|
634
|
+
const manifest = getManifest(schema);
|
|
635
|
+
const result = await execute(
|
|
636
|
+
getModel(model).deleteMany(
|
|
637
|
+
compileWhere(manifest.models[model], args.where),
|
|
638
|
+
state.session ? { session: state.session } : void 0
|
|
639
|
+
),
|
|
640
|
+
state.session
|
|
641
|
+
);
|
|
642
|
+
return Number(result.deletedCount ?? 0);
|
|
643
|
+
},
|
|
644
|
+
async transaction(_schema, run) {
|
|
645
|
+
return runTransaction(run);
|
|
646
|
+
}
|
|
647
|
+
};
|
|
648
|
+
return driver;
|
|
649
|
+
}
|
|
650
|
+
function createMongooseDriver(config) {
|
|
651
|
+
return createMongooseDriverInternal(config);
|
|
652
|
+
}
|
|
653
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
654
|
+
0 && (module.exports = {
|
|
655
|
+
createMongooseDriver
|
|
656
|
+
});
|
|
657
|
+
//# sourceMappingURL=index.cjs.map
|