@opra/mongodb 1.21.0 → 1.22.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/package.json +12 -29
- package/{esm/services → services}/mongo-collection-service.js +6 -0
- package/{esm/services → services}/mongo-nested-service.js +24 -0
- package/{esm/services → services}/mongo-service.js +44 -2
- package/{esm/services → services}/mongo-singleton-service.js +5 -0
- package/cjs/adapter/mongo-adapter.js +0 -127
- package/cjs/adapter/mongo-patch-generator.js +0 -215
- package/cjs/adapter/prepare-filter.js +0 -190
- package/cjs/adapter/prepare-key-values.js +0 -21
- package/cjs/adapter/prepare-projection.js +0 -58
- package/cjs/adapter/prepare-sort.js +0 -17
- package/cjs/index.js +0 -11
- package/cjs/package.json +0 -3
- package/cjs/services/mongo-collection-service.js +0 -401
- package/cjs/services/mongo-entity-service.js +0 -578
- package/cjs/services/mongo-nested-service.js +0 -913
- package/cjs/services/mongo-service.js +0 -282
- package/cjs/services/mongo-singleton-service.js +0 -213
- package/cjs/types.js +0 -2
- package/esm/package.json +0 -3
- package/types/index.d.cts +0 -8
- /package/{types/adapter → adapter}/mongo-adapter.d.ts +0 -0
- /package/{esm/adapter → adapter}/mongo-adapter.js +0 -0
- /package/{types/adapter → adapter}/mongo-patch-generator.d.ts +0 -0
- /package/{esm/adapter → adapter}/mongo-patch-generator.js +0 -0
- /package/{types/adapter → adapter}/prepare-filter.d.ts +0 -0
- /package/{esm/adapter → adapter}/prepare-filter.js +0 -0
- /package/{types/adapter → adapter}/prepare-key-values.d.ts +0 -0
- /package/{esm/adapter → adapter}/prepare-key-values.js +0 -0
- /package/{types/adapter → adapter}/prepare-projection.d.ts +0 -0
- /package/{esm/adapter → adapter}/prepare-projection.js +0 -0
- /package/{types/adapter → adapter}/prepare-sort.d.ts +0 -0
- /package/{esm/adapter → adapter}/prepare-sort.js +0 -0
- /package/{types/index.d.ts → index.d.ts} +0 -0
- /package/{esm/index.js → index.js} +0 -0
- /package/{types/services → services}/mongo-collection-service.d.ts +0 -0
- /package/{types/services → services}/mongo-entity-service.d.ts +0 -0
- /package/{esm/services → services}/mongo-entity-service.js +0 -0
- /package/{types/services → services}/mongo-nested-service.d.ts +0 -0
- /package/{types/services → services}/mongo-service.d.ts +0 -0
- /package/{types/services → services}/mongo-singleton-service.d.ts +0 -0
- /package/{types/types.d.ts → types.d.ts} +0 -0
- /package/{esm/types.js → types.js} +0 -0
|
@@ -1,578 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MongoEntityService = void 0;
|
|
4
|
-
const objects_1 = require("@jsopen/objects");
|
|
5
|
-
const common_1 = require("@opra/common");
|
|
6
|
-
const valgen_1 = require("valgen");
|
|
7
|
-
const mongo_adapter_js_1 = require("../adapter/mongo-adapter.js");
|
|
8
|
-
const mongo_patch_generator_js_1 = require("../adapter/mongo-patch-generator.js");
|
|
9
|
-
const mongo_service_js_1 = require("./mongo-service.js");
|
|
10
|
-
/**
|
|
11
|
-
* @class MongoEntityService
|
|
12
|
-
* @template T - The type of the documents in the collection
|
|
13
|
-
*/
|
|
14
|
-
class MongoEntityService extends mongo_service_js_1.MongoService {
|
|
15
|
-
/**
|
|
16
|
-
* Constructs a new instance
|
|
17
|
-
*
|
|
18
|
-
* @param {Type | string} dataType - The data type of the array elements.
|
|
19
|
-
* @param {MongoEntityService.Options} [options] - The options for the array service.
|
|
20
|
-
* @constructor
|
|
21
|
-
*/
|
|
22
|
-
constructor(dataType, options) {
|
|
23
|
-
super(dataType, options);
|
|
24
|
-
}
|
|
25
|
-
/**
|
|
26
|
-
* Creates a new document in the MongoDB collection
|
|
27
|
-
*
|
|
28
|
-
* @param {MongoEntityService.CreateCommand} command
|
|
29
|
-
* @protected
|
|
30
|
-
*/
|
|
31
|
-
async _create(command) {
|
|
32
|
-
const input = command.input;
|
|
33
|
-
(0, valgen_1.isNotNullish)(input, { label: 'input' });
|
|
34
|
-
(0, valgen_1.isNotNullish)(input._id, { label: 'input._id' });
|
|
35
|
-
const inputCodec = this._getInputCodec('create');
|
|
36
|
-
const document = inputCodec(input);
|
|
37
|
-
const { options } = command;
|
|
38
|
-
const db = this.getDatabase();
|
|
39
|
-
const collection = await this.getCollection(db);
|
|
40
|
-
const r = await collection.insertOne(document, {
|
|
41
|
-
...options,
|
|
42
|
-
session: options?.session ?? this.getSession(),
|
|
43
|
-
});
|
|
44
|
-
/* istanbul ignore next */
|
|
45
|
-
if (!r.insertedId) {
|
|
46
|
-
throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
|
|
47
|
-
}
|
|
48
|
-
return document;
|
|
49
|
-
}
|
|
50
|
-
/**
|
|
51
|
-
* Returns the count of documents in the collection based on the provided options.
|
|
52
|
-
*
|
|
53
|
-
* @param {MongoEntityService.CountCommand<T>} command
|
|
54
|
-
* @protected
|
|
55
|
-
*/
|
|
56
|
-
async _count(command) {
|
|
57
|
-
const { options } = command;
|
|
58
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
59
|
-
const db = this.getDatabase();
|
|
60
|
-
const collection = await this.getCollection(db);
|
|
61
|
-
return ((await collection.countDocuments(filter || {}, {
|
|
62
|
-
...options,
|
|
63
|
-
limit: undefined,
|
|
64
|
-
session: options?.session ?? this.getSession(),
|
|
65
|
-
})) || 0);
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Deletes a document from the collection
|
|
69
|
-
*
|
|
70
|
-
* @param {MongoEntityService.DeleteCommand<T>} command
|
|
71
|
-
* @protected
|
|
72
|
-
*/
|
|
73
|
-
async _delete(command) {
|
|
74
|
-
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
75
|
-
const { options } = command;
|
|
76
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
77
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
|
|
78
|
-
options?.filter,
|
|
79
|
-
]);
|
|
80
|
-
const db = this.getDatabase();
|
|
81
|
-
const collection = await this.getCollection(db);
|
|
82
|
-
const session = options?.session ?? this.getSession();
|
|
83
|
-
return (await collection.deleteOne(filter || {}, {
|
|
84
|
-
...options,
|
|
85
|
-
session,
|
|
86
|
-
})).deletedCount;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Deletes multiple documents from the collection that meet the specified filter criteria.
|
|
90
|
-
*
|
|
91
|
-
* @param {MongoEntityService.DeleteCommand<T>} command
|
|
92
|
-
* @protected
|
|
93
|
-
*/
|
|
94
|
-
async _deleteMany(command) {
|
|
95
|
-
const { options } = command;
|
|
96
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
97
|
-
const db = this.getDatabase();
|
|
98
|
-
const collection = await this.getCollection(db);
|
|
99
|
-
return (await collection.deleteMany(filter || {}, {
|
|
100
|
-
...options,
|
|
101
|
-
session: options?.session ?? this.getSession(),
|
|
102
|
-
})).deletedCount;
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* The distinct command returns a list of distinct values for the given key across a collection
|
|
106
|
-
*
|
|
107
|
-
* @param {MongoEntityService.DistinctCommand<T>} command
|
|
108
|
-
* @protected
|
|
109
|
-
*/
|
|
110
|
-
async _distinct(command) {
|
|
111
|
-
const { options, field } = command;
|
|
112
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
113
|
-
const db = this.getDatabase();
|
|
114
|
-
const collection = await this.getCollection(db);
|
|
115
|
-
return await collection.distinct(field, filter || {}, {
|
|
116
|
-
...options,
|
|
117
|
-
session: options?.session ?? this.getSession(),
|
|
118
|
-
});
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* Finds a document by its ID.
|
|
122
|
-
*
|
|
123
|
-
* @param { MongoEntityService.FindOneCommand<T>} command
|
|
124
|
-
*/
|
|
125
|
-
async _findById(command) {
|
|
126
|
-
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
127
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
128
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
|
|
129
|
-
command.options?.filter,
|
|
130
|
-
]);
|
|
131
|
-
const { options } = command;
|
|
132
|
-
const findManyCommand = {
|
|
133
|
-
...command,
|
|
134
|
-
options: {
|
|
135
|
-
...options,
|
|
136
|
-
filter,
|
|
137
|
-
limit: 1,
|
|
138
|
-
skip: undefined,
|
|
139
|
-
},
|
|
140
|
-
};
|
|
141
|
-
const rows = await this._findMany(findManyCommand);
|
|
142
|
-
return rows?.[0];
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Finds a document in the collection that matches the specified options.
|
|
146
|
-
*
|
|
147
|
-
* @param {MongoEntityService.FindOneCommand<T>} command
|
|
148
|
-
*/
|
|
149
|
-
async _findOne(command) {
|
|
150
|
-
const { options } = command;
|
|
151
|
-
const findManyCommand = {
|
|
152
|
-
...command,
|
|
153
|
-
options: {
|
|
154
|
-
...options,
|
|
155
|
-
limit: 1,
|
|
156
|
-
},
|
|
157
|
-
};
|
|
158
|
-
const rows = await this._findMany(findManyCommand);
|
|
159
|
-
return rows?.[0];
|
|
160
|
-
}
|
|
161
|
-
/**
|
|
162
|
-
* Finds multiple documents in the MongoDB collection
|
|
163
|
-
*
|
|
164
|
-
* @param {MongoEntityService.FindManyCommand<T>} command
|
|
165
|
-
*/
|
|
166
|
-
async _findMany(command) {
|
|
167
|
-
const { options } = command;
|
|
168
|
-
const stages = [];
|
|
169
|
-
/** Pre-Stages */
|
|
170
|
-
if (options?.preStages)
|
|
171
|
-
stages.push(...options.preStages);
|
|
172
|
-
/** "Filter" stage */
|
|
173
|
-
let filter;
|
|
174
|
-
if (options?.filter)
|
|
175
|
-
filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
176
|
-
if (filter)
|
|
177
|
-
stages.push({ $match: filter });
|
|
178
|
-
/** "Skip" stage */
|
|
179
|
-
if (options?.skip)
|
|
180
|
-
stages.push({ $skip: options.skip });
|
|
181
|
-
/** "Sort" stage */
|
|
182
|
-
if (options?.sort) {
|
|
183
|
-
const sort = mongo_adapter_js_1.MongoAdapter.prepareSort(options.sort);
|
|
184
|
-
if (sort)
|
|
185
|
-
stages.push({ $sort: sort });
|
|
186
|
-
}
|
|
187
|
-
/** "Limit" stage */
|
|
188
|
-
stages.push({ $limit: options?.limit || 10 });
|
|
189
|
-
/** Post-Stages */
|
|
190
|
-
if (options?.postStages)
|
|
191
|
-
stages.push(...options.postStages);
|
|
192
|
-
const dataType = this.dataType;
|
|
193
|
-
const projection = mongo_adapter_js_1.MongoAdapter.prepareProjection(dataType, options?.projection, this._dataTypeScope);
|
|
194
|
-
if (projection)
|
|
195
|
-
stages.push({ $project: projection });
|
|
196
|
-
const db = this.getDatabase();
|
|
197
|
-
const collection = await this.getCollection(db);
|
|
198
|
-
const cursor = collection.aggregate(stages, {
|
|
199
|
-
...(0, objects_1.omit)(options, ['projection', 'sort', 'skip', 'limit', 'filter']),
|
|
200
|
-
session: options?.session ?? this.getSession(),
|
|
201
|
-
});
|
|
202
|
-
/** Execute db command */
|
|
203
|
-
try {
|
|
204
|
-
/** Fetch the cursor */
|
|
205
|
-
if (options?.noDecode)
|
|
206
|
-
return cursor.toArray();
|
|
207
|
-
/** Decode result objects */
|
|
208
|
-
const outputCodec = this._getOutputCodec('find');
|
|
209
|
-
return (await cursor.toArray()).map((r) => outputCodec(r));
|
|
210
|
-
}
|
|
211
|
-
finally {
|
|
212
|
-
if (!cursor.closed)
|
|
213
|
-
await cursor.close();
|
|
214
|
-
}
|
|
215
|
-
}
|
|
216
|
-
/**
|
|
217
|
-
* Finds multiple documents in the collection and returns both records (max limit)
|
|
218
|
-
* and total count that matched the given criteria
|
|
219
|
-
*
|
|
220
|
-
* @param {MongoEntityService.FindManyCommand<T>} command
|
|
221
|
-
*/
|
|
222
|
-
async _findManyWithCount(command) {
|
|
223
|
-
const { options } = command;
|
|
224
|
-
const limit = options?.limit || 10;
|
|
225
|
-
let filter;
|
|
226
|
-
if (options?.filter)
|
|
227
|
-
filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
228
|
-
const dataStages = [];
|
|
229
|
-
const countStages = [];
|
|
230
|
-
const stages = [
|
|
231
|
-
{
|
|
232
|
-
$facet: {
|
|
233
|
-
data: dataStages,
|
|
234
|
-
count: countStages,
|
|
235
|
-
},
|
|
236
|
-
},
|
|
237
|
-
];
|
|
238
|
-
/** Pre-Stages */
|
|
239
|
-
if (options?.preStages)
|
|
240
|
-
dataStages.push(...options.preStages);
|
|
241
|
-
/** Filter */
|
|
242
|
-
if (filter) {
|
|
243
|
-
countStages.push({ $match: filter });
|
|
244
|
-
dataStages.push({ $match: filter });
|
|
245
|
-
}
|
|
246
|
-
countStages.push({ $count: 'totalMatches' });
|
|
247
|
-
/** Sort */
|
|
248
|
-
if (options?.sort) {
|
|
249
|
-
const sort = mongo_adapter_js_1.MongoAdapter.prepareSort(options.sort);
|
|
250
|
-
if (sort)
|
|
251
|
-
dataStages.push({ $sort: sort });
|
|
252
|
-
}
|
|
253
|
-
/** Skip */
|
|
254
|
-
if (options?.skip)
|
|
255
|
-
dataStages.push({ $skip: options.skip });
|
|
256
|
-
/** Limit */
|
|
257
|
-
dataStages.push({ $limit: limit });
|
|
258
|
-
const dataType = this.dataType;
|
|
259
|
-
const projection = mongo_adapter_js_1.MongoAdapter.prepareProjection(dataType, options?.projection, this._dataTypeScope);
|
|
260
|
-
if (projection)
|
|
261
|
-
dataStages.push({ $project: projection });
|
|
262
|
-
const outputCodec = this._getOutputCodec('find');
|
|
263
|
-
/** Execute db command */
|
|
264
|
-
const db = this.getDatabase();
|
|
265
|
-
const collection = await this.getCollection(db);
|
|
266
|
-
const cursor = collection.aggregate(stages, {
|
|
267
|
-
...(0, objects_1.omit)(options, ['projection', 'sort', 'skip', 'limit', 'filter']),
|
|
268
|
-
session: options?.session ?? this.getSession(),
|
|
269
|
-
});
|
|
270
|
-
/** Fetch the cursor and decode the result objects */
|
|
271
|
-
try {
|
|
272
|
-
const facetResult = await cursor.toArray();
|
|
273
|
-
return {
|
|
274
|
-
count: facetResult[0].count[0]?.totalMatches || 0,
|
|
275
|
-
items: options?.noDecode
|
|
276
|
-
? facetResult[0].data
|
|
277
|
-
: facetResult[0].data?.map((r) => outputCodec(r)),
|
|
278
|
-
};
|
|
279
|
-
}
|
|
280
|
-
finally {
|
|
281
|
-
if (!cursor.closed)
|
|
282
|
-
await cursor.close();
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
/**
|
|
286
|
-
* Updates a document with the given id in the collection
|
|
287
|
-
*
|
|
288
|
-
* @param {MongoEntityService.UpdateOneCommand<T>} command
|
|
289
|
-
*/
|
|
290
|
-
async _update(command) {
|
|
291
|
-
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
292
|
-
const { input, inputRaw } = command;
|
|
293
|
-
(0, valgen_1.isNotNullish)(input || inputRaw, { label: 'input' });
|
|
294
|
-
if (input && inputRaw) {
|
|
295
|
-
throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
|
|
296
|
-
}
|
|
297
|
-
const update = this._prepareUpdate(command);
|
|
298
|
-
const options = command.options;
|
|
299
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
300
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
|
|
301
|
-
options?.filter,
|
|
302
|
-
]);
|
|
303
|
-
const db = this.getDatabase();
|
|
304
|
-
const collection = await this.getCollection(db);
|
|
305
|
-
const out = await collection.findOneAndUpdate(filter || {}, update, {
|
|
306
|
-
upsert: undefined,
|
|
307
|
-
...options,
|
|
308
|
-
returnDocument: 'after',
|
|
309
|
-
includeResultMetadata: false,
|
|
310
|
-
session: options?.session ?? this.getSession(),
|
|
311
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.dataType, options?.projection, this._dataTypeScope),
|
|
312
|
-
});
|
|
313
|
-
const outputCodec = this._getOutputCodec('update');
|
|
314
|
-
if (out)
|
|
315
|
-
return outputCodec(out);
|
|
316
|
-
}
|
|
317
|
-
/**
|
|
318
|
-
* Updates a document in the collection with the specified ID.
|
|
319
|
-
*
|
|
320
|
-
* @param {MongoEntityService.UpdateOneCommand<T>} command
|
|
321
|
-
*/
|
|
322
|
-
async _updateOnly(command) {
|
|
323
|
-
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
324
|
-
const { input, inputRaw } = command;
|
|
325
|
-
(0, valgen_1.isNotNullish)(input || inputRaw, { label: 'input' });
|
|
326
|
-
if (input && inputRaw) {
|
|
327
|
-
throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
|
|
328
|
-
}
|
|
329
|
-
const update = this._prepareUpdate(command);
|
|
330
|
-
const options = command.options;
|
|
331
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
332
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
|
|
333
|
-
options?.filter,
|
|
334
|
-
]);
|
|
335
|
-
const db = this.getDatabase();
|
|
336
|
-
const collection = await this.getCollection(db);
|
|
337
|
-
/** Create array fields if not exists */
|
|
338
|
-
if (options?.initArrayFields) {
|
|
339
|
-
const $set = options.initArrayFields.reduce((a, k) => {
|
|
340
|
-
a[k] = { $ifNull: ['$' + k, []] };
|
|
341
|
-
return a;
|
|
342
|
-
}, {});
|
|
343
|
-
await collection.updateOne(filter || {}, [{ $set }], {
|
|
344
|
-
...options,
|
|
345
|
-
session: options?.session ?? this.getSession(),
|
|
346
|
-
arrayFilters: undefined,
|
|
347
|
-
upsert: false,
|
|
348
|
-
});
|
|
349
|
-
delete options.initArrayFields;
|
|
350
|
-
}
|
|
351
|
-
/** Execute update operation */
|
|
352
|
-
return (await collection.updateOne(filter || {}, update, {
|
|
353
|
-
...options,
|
|
354
|
-
session: options?.session ?? this.getSession(),
|
|
355
|
-
upsert: undefined,
|
|
356
|
-
})).matchedCount;
|
|
357
|
-
}
|
|
358
|
-
/**
|
|
359
|
-
* Updates multiple documents in the collection based on the specified input and options.
|
|
360
|
-
*
|
|
361
|
-
* @param {MongoEntityService.UpdateManyCommand<T>} command
|
|
362
|
-
*/
|
|
363
|
-
async _updateMany(command) {
|
|
364
|
-
(0, valgen_1.isNotNullish)(command.input, { label: 'input' });
|
|
365
|
-
const { input, inputRaw } = command;
|
|
366
|
-
(0, valgen_1.isNotNullish)(input || inputRaw, { label: 'input' });
|
|
367
|
-
if (input && inputRaw) {
|
|
368
|
-
throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
|
|
369
|
-
}
|
|
370
|
-
const update = this._prepareUpdate(command);
|
|
371
|
-
const options = command.options;
|
|
372
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
373
|
-
const db = this.getDatabase();
|
|
374
|
-
const collection = await this.getCollection(db);
|
|
375
|
-
/** Create array fields if not exists */
|
|
376
|
-
if (options?.initArrayFields) {
|
|
377
|
-
const $set = options.initArrayFields.reduce((a, k) => {
|
|
378
|
-
a[k] = { $ifNull: ['$' + k, []] };
|
|
379
|
-
return a;
|
|
380
|
-
}, {});
|
|
381
|
-
await collection.updateMany(filter || {}, [{ $set }], {
|
|
382
|
-
...(0, objects_1.omit)(options, ['filter']),
|
|
383
|
-
session: options?.session ?? this.getSession(),
|
|
384
|
-
arrayFilters: undefined,
|
|
385
|
-
upsert: false,
|
|
386
|
-
});
|
|
387
|
-
delete options.initArrayFields;
|
|
388
|
-
}
|
|
389
|
-
/** Execute update operation */
|
|
390
|
-
return (await collection.updateMany(filter || {}, update, {
|
|
391
|
-
...(0, objects_1.omit)(options, ['filter']),
|
|
392
|
-
session: options?.session ?? this.getSession(),
|
|
393
|
-
upsert: false,
|
|
394
|
-
})).matchedCount;
|
|
395
|
-
}
|
|
396
|
-
/**
|
|
397
|
-
* Replaces a document with the given id in the collection
|
|
398
|
-
*
|
|
399
|
-
* @param {MongoEntityService.ReplaceCommand<T>} command
|
|
400
|
-
*/
|
|
401
|
-
async _replace(command) {
|
|
402
|
-
const input = command.input;
|
|
403
|
-
(0, valgen_1.isNotNullish)(input, { label: 'input' });
|
|
404
|
-
(0, valgen_1.isNotNullish)(input._id, { label: 'input._id' });
|
|
405
|
-
const inputCodec = this._getInputCodec('replace');
|
|
406
|
-
const document = inputCodec(input);
|
|
407
|
-
const { options } = command;
|
|
408
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
409
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
|
|
410
|
-
options?.filter,
|
|
411
|
-
]);
|
|
412
|
-
const db = this.getDatabase();
|
|
413
|
-
const collection = await this.getCollection(db);
|
|
414
|
-
const out = await collection.findOneAndReplace(filter || {}, document, {
|
|
415
|
-
upsert: undefined,
|
|
416
|
-
...options,
|
|
417
|
-
returnDocument: 'after',
|
|
418
|
-
includeResultMetadata: false,
|
|
419
|
-
session: options?.session ?? this.getSession(),
|
|
420
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.dataType, options?.projection, this._dataTypeScope),
|
|
421
|
-
});
|
|
422
|
-
const outputCodec = this._getOutputCodec('replace');
|
|
423
|
-
if (out)
|
|
424
|
-
return outputCodec(out);
|
|
425
|
-
}
|
|
426
|
-
_prepareUpdate(command) {
|
|
427
|
-
const { input, inputRaw } = command;
|
|
428
|
-
(0, valgen_1.isNotNullish)(input || inputRaw, { label: 'input' });
|
|
429
|
-
if (input && inputRaw) {
|
|
430
|
-
throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
|
|
431
|
-
}
|
|
432
|
-
if (inputRaw)
|
|
433
|
-
return inputRaw;
|
|
434
|
-
const inputCodec = this._getInputCodec('update');
|
|
435
|
-
const doc = inputCodec(input);
|
|
436
|
-
delete doc._id;
|
|
437
|
-
if (doc._$push) {
|
|
438
|
-
doc._$push = inputCodec(doc._$push);
|
|
439
|
-
}
|
|
440
|
-
return this._generatePatch(command, doc);
|
|
441
|
-
}
|
|
442
|
-
_generatePatch(command, doc) {
|
|
443
|
-
const patchGenerator = new mongo_patch_generator_js_1.MongoPatchGenerator();
|
|
444
|
-
const { update, arrayFilters, initArrayFields } = patchGenerator.generatePatch(this.dataType, doc, {
|
|
445
|
-
scope: this._dataTypeScope,
|
|
446
|
-
});
|
|
447
|
-
command.options = command.options || {};
|
|
448
|
-
if (arrayFilters) {
|
|
449
|
-
command.options.arrayFilters = command.options.arrayFilters || [];
|
|
450
|
-
command.options.arrayFilters.push(...arrayFilters);
|
|
451
|
-
command.options.initArrayFields = initArrayFields;
|
|
452
|
-
}
|
|
453
|
-
return update;
|
|
454
|
-
}
|
|
455
|
-
async _executeCommand(command, commandFn) {
|
|
456
|
-
try {
|
|
457
|
-
const result = await super._executeCommand(command, async () => {
|
|
458
|
-
/** Call before[X] hooks */
|
|
459
|
-
if (command.crud === 'create')
|
|
460
|
-
await this._beforeCreate(command);
|
|
461
|
-
else if (command.crud === 'delete' && command.byId) {
|
|
462
|
-
await this._beforeDelete(command);
|
|
463
|
-
}
|
|
464
|
-
else if (command.crud === 'delete' && !command.byId) {
|
|
465
|
-
await this._beforeDeleteMany(command);
|
|
466
|
-
}
|
|
467
|
-
else if (command.crud === 'replace') {
|
|
468
|
-
await this._beforeReplace(command);
|
|
469
|
-
}
|
|
470
|
-
else if (command.crud === 'update' && command.byId) {
|
|
471
|
-
await this._beforeUpdate(command);
|
|
472
|
-
}
|
|
473
|
-
else if (command.crud === 'update' && !command.byId) {
|
|
474
|
-
await this._beforeUpdateMany(command);
|
|
475
|
-
}
|
|
476
|
-
/** Call command function */
|
|
477
|
-
return commandFn();
|
|
478
|
-
});
|
|
479
|
-
/** Call after[X] hooks */
|
|
480
|
-
if (command.crud === 'create')
|
|
481
|
-
await this._afterCreate(command, result);
|
|
482
|
-
else if (command.crud === 'delete' && command.byId) {
|
|
483
|
-
await this._afterDelete(command, result);
|
|
484
|
-
}
|
|
485
|
-
else if (command.crud === 'delete' && !command.byId) {
|
|
486
|
-
await this._afterDeleteMany(command, result);
|
|
487
|
-
}
|
|
488
|
-
else if (command.crud === 'replace') {
|
|
489
|
-
await this._afterReplace(command, result);
|
|
490
|
-
}
|
|
491
|
-
else if (command.crud === 'update' && command.byId) {
|
|
492
|
-
await this._afterUpdate(command, result);
|
|
493
|
-
}
|
|
494
|
-
else if (command.crud === 'update' && !command.byId) {
|
|
495
|
-
await this._afterUpdateMany(command, result);
|
|
496
|
-
}
|
|
497
|
-
return result;
|
|
498
|
-
}
|
|
499
|
-
catch (e) {
|
|
500
|
-
Error.captureStackTrace(e, this._executeCommand);
|
|
501
|
-
await this.onError?.(e, this);
|
|
502
|
-
throw e;
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
async _beforeCreate(
|
|
506
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
507
|
-
command) {
|
|
508
|
-
// Do nothing
|
|
509
|
-
}
|
|
510
|
-
async _beforeDelete(
|
|
511
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
512
|
-
command) {
|
|
513
|
-
// Do nothing
|
|
514
|
-
}
|
|
515
|
-
async _beforeDeleteMany(
|
|
516
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
517
|
-
command) {
|
|
518
|
-
// Do nothing
|
|
519
|
-
}
|
|
520
|
-
async _beforeReplace(
|
|
521
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
522
|
-
command) {
|
|
523
|
-
// Do nothing
|
|
524
|
-
}
|
|
525
|
-
async _beforeUpdate(
|
|
526
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
527
|
-
command) {
|
|
528
|
-
// Do nothing
|
|
529
|
-
}
|
|
530
|
-
async _beforeUpdateMany(
|
|
531
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
532
|
-
command) {
|
|
533
|
-
// Do nothing
|
|
534
|
-
}
|
|
535
|
-
async _afterCreate(
|
|
536
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
537
|
-
command,
|
|
538
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
539
|
-
result) {
|
|
540
|
-
// Do nothing
|
|
541
|
-
}
|
|
542
|
-
async _afterReplace(
|
|
543
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
544
|
-
command,
|
|
545
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
546
|
-
result) {
|
|
547
|
-
// Do nothing
|
|
548
|
-
}
|
|
549
|
-
async _afterDelete(
|
|
550
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
551
|
-
command,
|
|
552
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
553
|
-
affected) {
|
|
554
|
-
// Do nothing
|
|
555
|
-
}
|
|
556
|
-
async _afterDeleteMany(
|
|
557
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
558
|
-
command,
|
|
559
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
560
|
-
affected) {
|
|
561
|
-
// Do nothing
|
|
562
|
-
}
|
|
563
|
-
async _afterUpdate(
|
|
564
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
565
|
-
command,
|
|
566
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
567
|
-
result) {
|
|
568
|
-
// Do nothing
|
|
569
|
-
}
|
|
570
|
-
async _afterUpdateMany(
|
|
571
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
572
|
-
command,
|
|
573
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
574
|
-
affected) {
|
|
575
|
-
// Do nothing
|
|
576
|
-
}
|
|
577
|
-
}
|
|
578
|
-
exports.MongoEntityService = MongoEntityService;
|