@opra/mongodb 0.33.13 → 1.0.0-alpha.2
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/cjs/adapter-utils/prepare-filter.js +20 -28
- package/cjs/adapter-utils/prepare-projection.js +40 -39
- package/cjs/index.js +1 -2
- package/cjs/mongo-adapter.js +66 -1
- package/cjs/mongo-collection-service.js +72 -313
- package/cjs/mongo-entity-service.js +329 -0
- package/cjs/{mongo-array-service.js → mongo-nested-service.js} +231 -225
- package/cjs/mongo-service.js +124 -183
- package/cjs/mongo-singleton-service.js +28 -124
- package/esm/adapter-utils/prepare-filter.js +20 -28
- package/esm/adapter-utils/prepare-projection.js +39 -38
- package/esm/index.js +1 -2
- package/esm/mongo-adapter.js +66 -1
- package/esm/mongo-collection-service.js +73 -313
- package/esm/mongo-entity-service.js +324 -0
- package/esm/mongo-nested-service.js +569 -0
- package/esm/mongo-service.js +125 -184
- package/esm/mongo-singleton-service.js +29 -125
- package/package.json +9 -8
- package/types/adapter-utils/prepare-filter.d.ts +2 -3
- package/types/adapter-utils/prepare-projection.d.ts +4 -13
- package/types/index.d.ts +1 -2
- package/types/mongo-adapter.d.ts +14 -1
- package/types/mongo-collection-service.d.ts +88 -251
- package/types/mongo-entity-service.d.ts +149 -0
- package/types/mongo-nested-service.d.ts +258 -0
- package/types/mongo-service.d.ts +208 -82
- package/types/mongo-singleton-service.d.ts +39 -148
- package/cjs/types.js +0 -2
- package/esm/mongo-array-service.js +0 -563
- package/esm/types.js +0 -1
- package/types/mongo-array-service.d.ts +0 -409
- package/types/types.d.ts +0 -3
|
@@ -1,17 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.MongoCollectionService = void 0;
|
|
4
|
-
const tslib_1 = require("tslib");
|
|
5
|
-
const lodash_omit_1 = tslib_1.__importDefault(require("lodash.omit"));
|
|
6
4
|
const mongodb_1 = require("mongodb");
|
|
7
5
|
const common_1 = require("@opra/common");
|
|
8
6
|
const mongo_adapter_js_1 = require("./mongo-adapter.js");
|
|
9
|
-
const
|
|
7
|
+
const mongo_entity_service_js_1 = require("./mongo-entity-service.js");
|
|
10
8
|
/**
|
|
11
9
|
* @class MongoCollectionService
|
|
12
10
|
* @template T - The type of the documents in the collection.
|
|
13
11
|
*/
|
|
14
|
-
class MongoCollectionService extends
|
|
12
|
+
class MongoCollectionService extends mongo_entity_service_js_1.MongoEntityService {
|
|
15
13
|
/**
|
|
16
14
|
* Constructs a new instance
|
|
17
15
|
*
|
|
@@ -21,17 +19,14 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
21
19
|
*/
|
|
22
20
|
constructor(dataType, options) {
|
|
23
21
|
super(dataType, options);
|
|
24
|
-
this.collectionKey = this.collectionKey || options?.collectionKey || '_id';
|
|
25
22
|
this.defaultLimit = this.defaultLimit || options?.defaultLimit || 10;
|
|
26
|
-
this.$documentFilter = this.$documentFilter || options?.documentFilter;
|
|
27
|
-
this.$interceptor = this.$interceptor || options?.interceptor;
|
|
28
23
|
}
|
|
29
24
|
/**
|
|
30
25
|
* Asserts the existence of a resource with the given ID.
|
|
31
26
|
* Throws a ResourceNotFoundError if the resource does not exist.
|
|
32
27
|
*
|
|
33
|
-
* @param {AnyId} id - The ID of the resource to assert.
|
|
34
|
-
* @param {MongoCollectionService.ExistsOptions} [options] - Optional options for checking the existence.
|
|
28
|
+
* @param {MongoAdapter.AnyId} id - The ID of the resource to assert.
|
|
29
|
+
* @param {MongoCollectionService.ExistsOptions<T>} [options] - Optional options for checking the existence.
|
|
35
30
|
* @returns {Promise<void>} - A Promise that resolves when the resource exists.
|
|
36
31
|
* @throws {ResourceNotAvailableError} - If the resource does not exist.
|
|
37
32
|
*/
|
|
@@ -41,42 +36,27 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
41
36
|
}
|
|
42
37
|
/**
|
|
43
38
|
* Creates a new document in the MongoDB collection.
|
|
39
|
+
* Interceptors will be called before performing db operation
|
|
44
40
|
*
|
|
45
|
-
* @param {
|
|
41
|
+
* @param {PartialDTO<T>} input - The input data for creating the document.
|
|
46
42
|
* @param {MongoCollectionService.CreateOptions} [options] - The options for creating the document.
|
|
47
43
|
* @returns {Promise<PartialDTO<T>>} A promise that resolves to the created document.
|
|
48
44
|
* @throws {Error} if an unknown error occurs while creating the document.
|
|
49
45
|
*/
|
|
50
46
|
async create(input, options) {
|
|
47
|
+
const id = input._id || this._generateId();
|
|
48
|
+
if (id != null)
|
|
49
|
+
input._id = id;
|
|
51
50
|
const info = {
|
|
52
51
|
crud: 'create',
|
|
53
52
|
method: 'create',
|
|
54
53
|
byId: false,
|
|
55
|
-
documentId:
|
|
54
|
+
documentId: id,
|
|
56
55
|
input,
|
|
57
|
-
options
|
|
56
|
+
options,
|
|
58
57
|
};
|
|
59
58
|
return this._intercept(() => this._create(input, options), info);
|
|
60
59
|
}
|
|
61
|
-
async _create(input, options) {
|
|
62
|
-
const encode = this.getEncoder('create');
|
|
63
|
-
const doc = encode(input, { coerce: true });
|
|
64
|
-
doc._id = doc._id || this._generateId();
|
|
65
|
-
const r = await this.__insertOne(doc, options);
|
|
66
|
-
if (r.insertedId) {
|
|
67
|
-
if (!options)
|
|
68
|
-
return doc;
|
|
69
|
-
const out = await this._findById(doc._id, {
|
|
70
|
-
...options,
|
|
71
|
-
filter: undefined,
|
|
72
|
-
skip: undefined
|
|
73
|
-
});
|
|
74
|
-
if (out)
|
|
75
|
-
return out;
|
|
76
|
-
}
|
|
77
|
-
/* istanbul ignore next */
|
|
78
|
-
throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
|
|
79
|
-
}
|
|
80
60
|
/**
|
|
81
61
|
* Returns the count of documents in the collection based on the provided options.
|
|
82
62
|
*
|
|
@@ -88,24 +68,17 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
88
68
|
crud: 'read',
|
|
89
69
|
method: 'count',
|
|
90
70
|
byId: false,
|
|
91
|
-
options
|
|
71
|
+
options,
|
|
92
72
|
};
|
|
93
73
|
return this._intercept(async () => {
|
|
94
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
95
|
-
await this._getDocumentFilter(info),
|
|
96
|
-
options?.filter
|
|
97
|
-
]);
|
|
74
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
98
75
|
return this._count({ ...options, filter });
|
|
99
76
|
}, info);
|
|
100
77
|
}
|
|
101
|
-
async _count(options) {
|
|
102
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
103
|
-
return this.__countDocuments(filter, (0, lodash_omit_1.default)(options, 'filter'));
|
|
104
|
-
}
|
|
105
78
|
/**
|
|
106
79
|
* Deletes a document from the collection.
|
|
107
80
|
*
|
|
108
|
-
* @param {AnyId} id - The ID of the document to delete.
|
|
81
|
+
* @param {MongoAdapter.AnyId} id - The ID of the document to delete.
|
|
109
82
|
* @param {MongoCollectionService.DeleteOptions<T>} [options] - Optional delete options.
|
|
110
83
|
* @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
|
|
111
84
|
*/
|
|
@@ -113,26 +86,15 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
113
86
|
const info = {
|
|
114
87
|
crud: 'delete',
|
|
115
88
|
method: 'delete',
|
|
116
|
-
byId:
|
|
89
|
+
byId: true,
|
|
117
90
|
documentId: id,
|
|
118
|
-
options
|
|
91
|
+
options,
|
|
119
92
|
};
|
|
120
93
|
return this._intercept(async () => {
|
|
121
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
122
|
-
await this._getDocumentFilter(info),
|
|
123
|
-
options?.filter
|
|
124
|
-
]);
|
|
94
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
125
95
|
return this._delete(id, { ...options, filter });
|
|
126
96
|
}, info);
|
|
127
97
|
}
|
|
128
|
-
async _delete(id, options) {
|
|
129
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
130
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
131
|
-
options?.filter
|
|
132
|
-
]);
|
|
133
|
-
const r = await this.__deleteOne(filter, options);
|
|
134
|
-
return r.deletedCount;
|
|
135
|
-
}
|
|
136
98
|
/**
|
|
137
99
|
* Deletes multiple documents from the collection that meet the specified filter criteria.
|
|
138
100
|
*
|
|
@@ -144,49 +106,40 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
144
106
|
crud: 'delete',
|
|
145
107
|
method: 'deleteMany',
|
|
146
108
|
byId: false,
|
|
147
|
-
options
|
|
109
|
+
options,
|
|
148
110
|
};
|
|
149
111
|
return this._intercept(async () => {
|
|
150
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
151
|
-
await this._getDocumentFilter(info),
|
|
152
|
-
options?.filter,
|
|
153
|
-
]);
|
|
112
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
154
113
|
return this._deleteMany({ ...options, filter });
|
|
155
114
|
}, info);
|
|
156
115
|
}
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
116
|
+
/**
|
|
117
|
+
* The distinct command returns a list of distinct values for the given key across a collection.
|
|
118
|
+
* @param {string} field
|
|
119
|
+
* @param {MongoCollectionService.DistinctOptions<T>} [options]
|
|
120
|
+
* @protected
|
|
121
|
+
*/
|
|
162
122
|
async distinct(field, options) {
|
|
163
123
|
const info = {
|
|
164
124
|
crud: 'read',
|
|
165
125
|
method: 'distinct',
|
|
166
126
|
byId: true,
|
|
167
|
-
options
|
|
127
|
+
options,
|
|
168
128
|
};
|
|
169
129
|
return this._intercept(async () => {
|
|
170
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
171
|
-
await this._getDocumentFilter(info),
|
|
172
|
-
options?.filter,
|
|
173
|
-
]);
|
|
130
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
174
131
|
return this._distinct(field, { ...options, filter });
|
|
175
132
|
}, info);
|
|
176
133
|
}
|
|
177
|
-
async _distinct(field, options) {
|
|
178
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
179
|
-
return await this.__distinct(field, filter, (0, lodash_omit_1.default)(options, 'filter'));
|
|
180
|
-
}
|
|
181
134
|
/**
|
|
182
135
|
* Checks if an object with the given id exists.
|
|
183
136
|
*
|
|
184
|
-
* @param {AnyId} id - The id of the object to check.
|
|
185
|
-
* @param {MongoCollectionService.ExistsOptions} [options] - The options for the query (optional).
|
|
137
|
+
* @param {MongoAdapter.AnyId} id - The id of the object to check.
|
|
138
|
+
* @param {MongoCollectionService.ExistsOptions<T>} [options] - The options for the query (optional).
|
|
186
139
|
* @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the object exists or not.
|
|
187
140
|
*/
|
|
188
141
|
async exists(id, options) {
|
|
189
|
-
return !!(await this.findById(id, { ...options,
|
|
142
|
+
return !!(await this.findById(id, { ...options, projection: ['_id'] }));
|
|
190
143
|
}
|
|
191
144
|
/**
|
|
192
145
|
* Checks if an object with the given arguments exists.
|
|
@@ -195,13 +148,13 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
195
148
|
* @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the object exists or not.
|
|
196
149
|
*/
|
|
197
150
|
async existsOne(options) {
|
|
198
|
-
return !!(await this.findOne({ ...options,
|
|
151
|
+
return !!(await this.findOne({ ...options, projection: ['_id'] }));
|
|
199
152
|
}
|
|
200
153
|
/**
|
|
201
154
|
* Finds a document by its ID.
|
|
202
155
|
*
|
|
203
|
-
* @param {AnyId} id - The ID of the document.
|
|
204
|
-
* @param {MongoCollectionService.FindOneOptions} [options] - The options for the find query.
|
|
156
|
+
* @param {MongoAdapter.AnyId} id - The ID of the document.
|
|
157
|
+
* @param {MongoCollectionService.FindOneOptions<T>} [options] - The options for the find query.
|
|
205
158
|
* @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
|
|
206
159
|
*/
|
|
207
160
|
async findById(id, options) {
|
|
@@ -210,37 +163,18 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
210
163
|
method: 'findById',
|
|
211
164
|
byId: true,
|
|
212
165
|
documentId: id,
|
|
213
|
-
options
|
|
166
|
+
options,
|
|
214
167
|
};
|
|
215
168
|
return this._intercept(async () => {
|
|
216
169
|
const documentFilter = await this._getDocumentFilter(info);
|
|
217
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
218
|
-
documentFilter,
|
|
219
|
-
options?.filter,
|
|
220
|
-
]);
|
|
170
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([documentFilter, options?.filter]);
|
|
221
171
|
return this._findById(id, { ...options, filter });
|
|
222
172
|
}, info);
|
|
223
173
|
}
|
|
224
|
-
async _findById(id, options) {
|
|
225
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
226
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
227
|
-
options?.filter
|
|
228
|
-
]);
|
|
229
|
-
const mongoOptions = {
|
|
230
|
-
...options,
|
|
231
|
-
limit: undefined,
|
|
232
|
-
skip: undefined,
|
|
233
|
-
sort: undefined,
|
|
234
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
235
|
-
};
|
|
236
|
-
const decode = this.getDecoder();
|
|
237
|
-
const out = await this.__findOne(filter, mongoOptions);
|
|
238
|
-
return out ? decode(out, { coerce: true }) : undefined;
|
|
239
|
-
}
|
|
240
174
|
/**
|
|
241
175
|
* Finds a document in the collection that matches the specified options.
|
|
242
176
|
*
|
|
243
|
-
* @param {MongoCollectionService.FindOneOptions} options - The options for the query.
|
|
177
|
+
* @param {MongoCollectionService.FindOneOptions<T>} [options] - The options for the query.
|
|
244
178
|
* @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
|
|
245
179
|
*/
|
|
246
180
|
async findOne(options) {
|
|
@@ -248,41 +182,17 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
248
182
|
crud: 'read',
|
|
249
183
|
method: 'findOne',
|
|
250
184
|
byId: false,
|
|
251
|
-
options
|
|
185
|
+
options,
|
|
252
186
|
};
|
|
253
187
|
return this._intercept(async () => {
|
|
254
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
255
|
-
await this._getDocumentFilter(info),
|
|
256
|
-
options?.filter,
|
|
257
|
-
]);
|
|
188
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
258
189
|
return this._findOne({ ...options, filter });
|
|
259
190
|
}, info);
|
|
260
191
|
}
|
|
261
|
-
async _findOne(options) {
|
|
262
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
263
|
-
const mongoOptions = {
|
|
264
|
-
...options,
|
|
265
|
-
sort: options?.sort ? mongo_adapter_js_1.MongoAdapter.prepareSort(options.sort) : undefined,
|
|
266
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
267
|
-
limit: undefined
|
|
268
|
-
};
|
|
269
|
-
const decode = this.getDecoder();
|
|
270
|
-
const out = await this.__findOne(filter, mongoOptions);
|
|
271
|
-
return out ? decode(out, { coerce: true }) : undefined;
|
|
272
|
-
}
|
|
273
192
|
/**
|
|
274
193
|
* Finds multiple documents in the MongoDB collection.
|
|
275
194
|
*
|
|
276
|
-
* @param options - The options for the find operation.
|
|
277
|
-
* - pick: string[] - An array of fields to include in the returned documents.
|
|
278
|
-
* - include: string[] - An array of fields to include in the returned documents.
|
|
279
|
-
* - omit: string[] - An array of fields to exclude from the returned documents.
|
|
280
|
-
* - sort: Record<string, number> - The sorting criteria.
|
|
281
|
-
* - skip: number - The number of documents to skip.
|
|
282
|
-
* - limit: number - The maximum number of documents to return.
|
|
283
|
-
* - filter: FilterQuery<T> - The filter conditions to apply to the find operation.
|
|
284
|
-
* - count: boolean - If set to true, returns the total count of matching documents.
|
|
285
|
-
*
|
|
195
|
+
* @param {MongoCollectionService.FindManyOptions<T>} options - The options for the find operation.
|
|
286
196
|
* @return A Promise that resolves to an array of partial outputs of type T.
|
|
287
197
|
*/
|
|
288
198
|
async findMany(options) {
|
|
@@ -290,76 +200,37 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
290
200
|
crud: 'read',
|
|
291
201
|
method: 'findMany',
|
|
292
202
|
byId: false,
|
|
293
|
-
options
|
|
203
|
+
options,
|
|
294
204
|
};
|
|
295
205
|
return this._intercept(async () => {
|
|
296
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
297
|
-
|
|
298
|
-
options?.filter,
|
|
299
|
-
]);
|
|
300
|
-
return this._findMany({ ...options, filter });
|
|
206
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
207
|
+
return this._findMany({ ...options, filter, limit: options?.limit || this.defaultLimit });
|
|
301
208
|
}, info);
|
|
302
209
|
}
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
210
|
+
/**
|
|
211
|
+
* Finds multiple documents in the collection and returns both records (max limit)
|
|
212
|
+
* and total count that matched the given criteria
|
|
213
|
+
*
|
|
214
|
+
* @param {MongoCollectionService.FindManyOptions<T>} [options] - The options for the find operation.
|
|
215
|
+
* @return A Promise that resolves to an array of partial outputs of type T.
|
|
216
|
+
*/
|
|
217
|
+
async findManyWithCount(options) {
|
|
218
|
+
const info = {
|
|
219
|
+
crud: 'read',
|
|
220
|
+
method: 'findManyWithCount',
|
|
221
|
+
byId: false,
|
|
222
|
+
options,
|
|
306
223
|
};
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
312
|
-
let dataStages = stages;
|
|
313
|
-
if (options?.count) {
|
|
314
|
-
dataStages = [];
|
|
315
|
-
const count = [];
|
|
316
|
-
if (filter)
|
|
317
|
-
count.push({ $match: filter });
|
|
318
|
-
count.push({ $count: 'totalMatches' });
|
|
319
|
-
stages.push({
|
|
320
|
-
$facet: {
|
|
321
|
-
data: dataStages,
|
|
322
|
-
count,
|
|
323
|
-
}
|
|
324
|
-
});
|
|
325
|
-
}
|
|
326
|
-
if (filter)
|
|
327
|
-
dataStages.push({ $match: filter });
|
|
328
|
-
if (options?.skip)
|
|
329
|
-
dataStages.push({ $skip: options.skip });
|
|
330
|
-
if (options?.sort) {
|
|
331
|
-
const sort = mongo_adapter_js_1.MongoAdapter.prepareSort(options.sort);
|
|
332
|
-
if (sort)
|
|
333
|
-
dataStages.push({ $sort: sort });
|
|
334
|
-
}
|
|
335
|
-
dataStages.push({ $limit: limit });
|
|
336
|
-
const dataType = this.getDataType();
|
|
337
|
-
const projection = mongo_adapter_js_1.MongoAdapter.prepareProjection(dataType, options);
|
|
338
|
-
if (projection)
|
|
339
|
-
dataStages.push({ $project: projection });
|
|
340
|
-
const decode = this.getDecoder();
|
|
341
|
-
const cursor = await this.__aggregate(stages, {
|
|
342
|
-
...mongoOptions
|
|
343
|
-
});
|
|
344
|
-
try {
|
|
345
|
-
if (options?.count) {
|
|
346
|
-
const facetResult = await cursor.toArray();
|
|
347
|
-
this.context.response.totalMatches = facetResult[0].count[0].totalMatches || 0;
|
|
348
|
-
return facetResult[0].data.map((r) => decode(r, { coerce: true }));
|
|
349
|
-
}
|
|
350
|
-
else
|
|
351
|
-
return await cursor.toArray();
|
|
352
|
-
}
|
|
353
|
-
finally {
|
|
354
|
-
if (!cursor.closed)
|
|
355
|
-
await cursor.close();
|
|
356
|
-
}
|
|
224
|
+
return this._intercept(async () => {
|
|
225
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
226
|
+
return this._findManyWithCount({ ...options, filter, limit: options?.limit || this.defaultLimit });
|
|
227
|
+
}, info);
|
|
357
228
|
}
|
|
358
229
|
/**
|
|
359
230
|
* Retrieves a document from the collection by its ID. Throws error if not found.
|
|
360
231
|
*
|
|
361
|
-
* @param {
|
|
362
|
-
* @param {MongoCollectionService.FindOneOptions} [options] - Optional options for the findOne operation.
|
|
232
|
+
* @param {MongoAdapter.AnyId} id - The ID of the document to retrieve.
|
|
233
|
+
* @param {MongoCollectionService.FindOneOptions<T>} [options] - Optional options for the findOne operation.
|
|
363
234
|
* @returns {Promise<PartialDTO<T>>} - A promise that resolves to the retrieved document,
|
|
364
235
|
* or rejects with a ResourceNotFoundError if the document does not exist.
|
|
365
236
|
* @throws {ResourceNotAvailableError} - If the document with the specified ID does not exist.
|
|
@@ -373,8 +244,8 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
373
244
|
/**
|
|
374
245
|
* Updates a document with the given id in the collection.
|
|
375
246
|
*
|
|
376
|
-
* @param {
|
|
377
|
-
* @param {PatchDTO<T>} input - The partial input object containing the fields to update.
|
|
247
|
+
* @param {MongoAdapter.AnyId} id - The id of the document to update.
|
|
248
|
+
* @param {PatchDTO<T>|UpdateFilter<T>} input - The partial input object containing the fields to update.
|
|
378
249
|
* @param {MongoCollectionService.UpdateOptions<T>} [options] - The options for the update operation.
|
|
379
250
|
* @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
|
|
380
251
|
* undefined if the document was not found.
|
|
@@ -389,49 +260,16 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
389
260
|
options,
|
|
390
261
|
};
|
|
391
262
|
return this._intercept(async () => {
|
|
392
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
393
|
-
await this._getDocumentFilter(info),
|
|
394
|
-
options?.filter
|
|
395
|
-
]);
|
|
263
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
396
264
|
return this._update(id, input, { ...options, filter });
|
|
397
265
|
}, info);
|
|
398
266
|
}
|
|
399
|
-
async _update(id, input, options) {
|
|
400
|
-
const isUpdateFilter = Array.isArray(input) ||
|
|
401
|
-
!!Object.keys(input).find(x => x.startsWith('$'));
|
|
402
|
-
const isDocument = !Array.isArray(input) &&
|
|
403
|
-
!!Object.keys(input).find(x => !x.startsWith('$'));
|
|
404
|
-
if (isUpdateFilter && isDocument)
|
|
405
|
-
throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
|
|
406
|
-
let update;
|
|
407
|
-
if (isDocument) {
|
|
408
|
-
const encode = this.getEncoder('update');
|
|
409
|
-
const doc = encode(input, { coerce: true });
|
|
410
|
-
update = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
411
|
-
update.$set = update.$set || {};
|
|
412
|
-
}
|
|
413
|
-
else
|
|
414
|
-
update = input;
|
|
415
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
416
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
417
|
-
options?.filter
|
|
418
|
-
]);
|
|
419
|
-
const mongoOptions = {
|
|
420
|
-
...options,
|
|
421
|
-
includeResultMetadata: false,
|
|
422
|
-
upsert: undefined,
|
|
423
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
424
|
-
};
|
|
425
|
-
const decode = this.getDecoder();
|
|
426
|
-
const out = await this.__findOneAndUpdate(filter, update, mongoOptions);
|
|
427
|
-
return out ? decode(out, { coerce: true }) : undefined;
|
|
428
|
-
}
|
|
429
267
|
/**
|
|
430
268
|
* Updates a document in the collection with the specified ID.
|
|
431
269
|
*
|
|
432
|
-
* @param {
|
|
433
|
-
* @param {PatchDTO<T>} input - The partial input data to update the document with.
|
|
434
|
-
* @param {MongoCollectionService.UpdateOptions<T>} options - The options for updating the document.
|
|
270
|
+
* @param {MongoAdapter.AnyId} id - The ID of the document to update.
|
|
271
|
+
* @param {PatchDTO<T>|UpdateFilter<T>} input - The partial input data to update the document with.
|
|
272
|
+
* @param {MongoCollectionService.UpdateOptions<T>} [options] - The options for updating the document.
|
|
435
273
|
* @returns {Promise<number>} - A promise that resolves to the number of documents modified.
|
|
436
274
|
*/
|
|
437
275
|
async updateOnly(id, input, options) {
|
|
@@ -444,47 +282,14 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
444
282
|
options,
|
|
445
283
|
};
|
|
446
284
|
return this._intercept(async () => {
|
|
447
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
448
|
-
await this._getDocumentFilter(info),
|
|
449
|
-
options?.filter
|
|
450
|
-
]);
|
|
285
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
451
286
|
return this._updateOnly(id, input, { ...options, filter });
|
|
452
287
|
}, info);
|
|
453
288
|
}
|
|
454
|
-
async _updateOnly(id, input, options) {
|
|
455
|
-
const isUpdateFilter = Array.isArray(input) ||
|
|
456
|
-
!!Object.keys(input).find(x => x.startsWith('$'));
|
|
457
|
-
const isDocument = !Array.isArray(input) &&
|
|
458
|
-
!!Object.keys(input).find(x => !x.startsWith('$'));
|
|
459
|
-
if (isUpdateFilter && isDocument)
|
|
460
|
-
throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
|
|
461
|
-
let update;
|
|
462
|
-
if (isDocument) {
|
|
463
|
-
const encode = this.getEncoder('update');
|
|
464
|
-
const doc = encode(input, { coerce: true });
|
|
465
|
-
update = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
466
|
-
if (!Object.keys(doc).length)
|
|
467
|
-
return 0;
|
|
468
|
-
}
|
|
469
|
-
else
|
|
470
|
-
update = input;
|
|
471
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
472
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
473
|
-
options?.filter
|
|
474
|
-
]);
|
|
475
|
-
const mongoOptions = {
|
|
476
|
-
...options,
|
|
477
|
-
includeResultMetadata: false,
|
|
478
|
-
upsert: undefined,
|
|
479
|
-
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
480
|
-
};
|
|
481
|
-
const out = await this.__updateOne(filter, update, mongoOptions);
|
|
482
|
-
return out.matchedCount;
|
|
483
|
-
}
|
|
484
289
|
/**
|
|
485
290
|
* Updates multiple documents in the collection based on the specified input and options.
|
|
486
291
|
*
|
|
487
|
-
* @param {PatchDTO<T>} input - The partial input to update the documents with.
|
|
292
|
+
* @param {PatchDTO<T>|UpdateFilter<T>} input - The partial input to update the documents with.
|
|
488
293
|
* @param {MongoCollectionService.UpdateManyOptions<T>} options - The options for updating the documents.
|
|
489
294
|
* @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
|
|
490
295
|
*/
|
|
@@ -497,64 +302,18 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
497
302
|
options,
|
|
498
303
|
};
|
|
499
304
|
return this._intercept(async () => {
|
|
500
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
501
|
-
await this._getDocumentFilter(info),
|
|
502
|
-
options?.filter
|
|
503
|
-
]);
|
|
305
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([await this._getDocumentFilter(info), options?.filter]);
|
|
504
306
|
return this._updateMany(input, { ...options, filter });
|
|
505
307
|
}, info);
|
|
506
308
|
}
|
|
507
|
-
async _updateMany(input, options) {
|
|
508
|
-
const isUpdateFilter = Array.isArray(input) ||
|
|
509
|
-
!!Object.keys(input).find(x => x.startsWith('$'));
|
|
510
|
-
const isDocument = !Array.isArray(input) &&
|
|
511
|
-
!!Object.keys(input).find(x => !x.startsWith('$'));
|
|
512
|
-
if (isUpdateFilter && isDocument)
|
|
513
|
-
throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
|
|
514
|
-
let update;
|
|
515
|
-
if (isDocument) {
|
|
516
|
-
const encode = this.getEncoder('update');
|
|
517
|
-
const doc = encode(input, { coerce: true });
|
|
518
|
-
update = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
519
|
-
if (!Object.keys(doc).length)
|
|
520
|
-
return 0;
|
|
521
|
-
}
|
|
522
|
-
else
|
|
523
|
-
update = input;
|
|
524
|
-
const mongoOptions = {
|
|
525
|
-
...(0, lodash_omit_1.default)(options, 'filter'),
|
|
526
|
-
upsert: undefined
|
|
527
|
-
};
|
|
528
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
529
|
-
const r = await this.__updateMany(filter, update, mongoOptions);
|
|
530
|
-
return r.matchedCount;
|
|
531
|
-
}
|
|
532
309
|
/**
|
|
533
310
|
* Generates an ID.
|
|
534
311
|
*
|
|
535
312
|
* @protected
|
|
536
|
-
* @returns {AnyId} The generated ID.
|
|
313
|
+
* @returns {MongoAdapter.AnyId} The generated ID.
|
|
537
314
|
*/
|
|
538
315
|
_generateId() {
|
|
539
|
-
return typeof this.$idGenerator === 'function' ?
|
|
540
|
-
this.$idGenerator(this) : new mongodb_1.ObjectId();
|
|
541
|
-
}
|
|
542
|
-
/**
|
|
543
|
-
* Retrieves the common filter used for querying documents.
|
|
544
|
-
* This method is mostly used for security issues like securing multi-tenant applications.
|
|
545
|
-
*
|
|
546
|
-
* @protected
|
|
547
|
-
* @returns {FilterInput | Promise<FilterInput> | undefined} The common filter or a Promise
|
|
548
|
-
* that resolves to the common filter, or undefined if not available.
|
|
549
|
-
*/
|
|
550
|
-
_getDocumentFilter(args) {
|
|
551
|
-
return typeof this.$documentFilter === 'function' ?
|
|
552
|
-
this.$documentFilter(args, this) : this.$documentFilter;
|
|
553
|
-
}
|
|
554
|
-
async _intercept(callback, args) {
|
|
555
|
-
if (this.$interceptor)
|
|
556
|
-
return this.$interceptor(callback, args, this);
|
|
557
|
-
return callback();
|
|
316
|
+
return typeof this.$idGenerator === 'function' ? this.$idGenerator(this) : new mongodb_1.ObjectId();
|
|
558
317
|
}
|
|
559
318
|
}
|
|
560
319
|
exports.MongoCollectionService = MongoCollectionService;
|