@opra/mongodb 0.32.2 → 0.32.3
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/mongo-array-service.js +131 -127
- package/cjs/mongo-collection-service.js +96 -89
- package/cjs/mongo-service.js +86 -6
- package/cjs/mongo-singleton-service.js +66 -34
- package/esm/mongo-array-service.js +131 -127
- package/esm/mongo-collection-service.js +96 -89
- package/esm/mongo-service.js +86 -6
- package/esm/mongo-singleton-service.js +66 -34
- package/package.json +3 -3
- package/types/mongo-array-service.d.ts +167 -85
- package/types/mongo-collection-service.d.ts +129 -56
- package/types/mongo-service.d.ts +53 -6
- package/types/mongo-singleton-service.d.ts +71 -21
|
@@ -8,55 +8,70 @@ const common_1 = require("@opra/common");
|
|
|
8
8
|
const mongo_adapter_js_1 = require("./mongo-adapter.js");
|
|
9
9
|
const mongo_service_js_1 = require("./mongo-service.js");
|
|
10
10
|
/**
|
|
11
|
-
*
|
|
12
11
|
* @class MongoCollectionService
|
|
12
|
+
* @template T - The type of the documents in the collection.
|
|
13
13
|
*/
|
|
14
14
|
class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
15
15
|
constructor(dataType, options) {
|
|
16
16
|
super(dataType, options);
|
|
17
|
-
this._encoders = {};
|
|
18
17
|
this.defaultLimit = options?.defaultLimit || 10;
|
|
19
18
|
this.collectionKey = options?.collectionKey || '_id';
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
|
-
*
|
|
21
|
+
* Asserts the existence of a resource with the given ID.
|
|
22
|
+
* Throws a ResourceNotFoundError if the resource does not exist.
|
|
23
23
|
*
|
|
24
|
-
* @param id
|
|
24
|
+
* @param {AnyId} id - The ID of the resource to assert.
|
|
25
|
+
* @returns {Promise<void>} - A Promise that resolves when the resource exists.
|
|
26
|
+
* @throws {ResourceNotFoundError} - If the resource does not exist.
|
|
25
27
|
*/
|
|
26
28
|
async assert(id) {
|
|
27
29
|
if (!(await this.exists(id)))
|
|
28
30
|
throw new common_1.ResourceNotFoundError(this.resourceName || this.getCollectionName(), id);
|
|
29
31
|
}
|
|
30
32
|
/**
|
|
31
|
-
*
|
|
33
|
+
* Creates a new document in the MongoDB collection.
|
|
32
34
|
*
|
|
33
|
-
* @param input
|
|
34
|
-
* @param options
|
|
35
|
+
* @param {PartialInput<T>} input - The input data for creating the document.
|
|
36
|
+
* @param {MongoCollectionService.CreateOptions} [options] - The options for creating the document.
|
|
37
|
+
* @returns {Promise<PartialOutput<T>>} A promise that resolves to the created document.
|
|
38
|
+
* @throws {Error} if an unknown error occurs while creating the document.
|
|
35
39
|
*/
|
|
36
40
|
async create(input, options) {
|
|
37
|
-
const encode = this.
|
|
41
|
+
const encode = this.getEncoder('create');
|
|
38
42
|
const doc = encode(input);
|
|
39
43
|
doc._id = doc._id || this._generateId();
|
|
40
44
|
const r = await this.__insertOne(doc, options);
|
|
41
|
-
if (r.insertedId)
|
|
42
|
-
|
|
45
|
+
if (r.insertedId) {
|
|
46
|
+
if (!options)
|
|
47
|
+
return doc;
|
|
48
|
+
try {
|
|
49
|
+
return this.get(doc._id, options);
|
|
50
|
+
}
|
|
51
|
+
catch (e) {
|
|
52
|
+
Error.captureStackTrace(e);
|
|
53
|
+
throw e;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
43
56
|
/* istanbul ignore next */
|
|
44
57
|
throw new Error('Unknown error while creating document');
|
|
45
58
|
}
|
|
46
59
|
/**
|
|
47
|
-
*
|
|
60
|
+
* Returns the count of documents in the collection based on the provided options.
|
|
48
61
|
*
|
|
49
|
-
* @param options
|
|
62
|
+
* @param {MongoCollectionService.CountOptions<T>} options - The options for the count operation.
|
|
63
|
+
* @return {Promise<number>} - A promise that resolves to the count of documents in the collection.
|
|
50
64
|
*/
|
|
51
65
|
async count(options) {
|
|
52
66
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
53
67
|
return this.__countDocuments(filter, (0, lodash_omit_1.default)(options, 'filter'));
|
|
54
68
|
}
|
|
55
69
|
/**
|
|
56
|
-
*
|
|
70
|
+
* Deletes a document from the collection.
|
|
57
71
|
*
|
|
58
|
-
* @param id
|
|
59
|
-
* @param options
|
|
72
|
+
* @param {AnyId} id - The ID of the document to delete.
|
|
73
|
+
* @param {MongoCollectionService.DeleteOptions<T>} [options] - Optional delete options.
|
|
74
|
+
* @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
|
|
60
75
|
*/
|
|
61
76
|
async delete(id, options) {
|
|
62
77
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
@@ -67,9 +82,10 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
67
82
|
return r.deletedCount;
|
|
68
83
|
}
|
|
69
84
|
/**
|
|
70
|
-
*
|
|
85
|
+
* Deletes multiple documents from the collection that meet the specified filter criteria.
|
|
71
86
|
*
|
|
72
|
-
* @param options
|
|
87
|
+
* @param {MongoCollectionService.DeleteManyOptions<T>} options - The options for the delete operation.
|
|
88
|
+
* @return {Promise<number>} - A promise that resolves to the number of documents deleted.
|
|
73
89
|
*/
|
|
74
90
|
async deleteMany(options) {
|
|
75
91
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
@@ -77,19 +93,20 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
77
93
|
return r.deletedCount;
|
|
78
94
|
}
|
|
79
95
|
/**
|
|
80
|
-
* Checks if
|
|
81
|
-
* Returns true if document exists, false otherwise
|
|
96
|
+
* Checks if an object with the given id exists.
|
|
82
97
|
*
|
|
83
|
-
* @param id
|
|
98
|
+
* @param {AnyId} id - The id of the object to check.
|
|
99
|
+
* @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the object exists or not.
|
|
84
100
|
*/
|
|
85
101
|
async exists(id) {
|
|
86
102
|
return !!(await this.findById(id, { pick: ['_id'] }));
|
|
87
103
|
}
|
|
88
104
|
/**
|
|
89
|
-
*
|
|
105
|
+
* Finds a document by its ID.
|
|
90
106
|
*
|
|
91
|
-
* @param id
|
|
92
|
-
* @param options
|
|
107
|
+
* @param {AnyId} id - The ID of the document.
|
|
108
|
+
* @param {MongoCollectionService.FindOneOptions} [options] - The options for the find query.
|
|
109
|
+
* @return {Promise<PartialOutput<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
|
|
93
110
|
*/
|
|
94
111
|
async findById(id, options) {
|
|
95
112
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
@@ -99,10 +116,10 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
99
116
|
return await this.findOne({ ...options, filter });
|
|
100
117
|
}
|
|
101
118
|
/**
|
|
102
|
-
*
|
|
103
|
-
* Returns undefined if not found.
|
|
119
|
+
* Finds a document in the collection that matches the specified options.
|
|
104
120
|
*
|
|
105
|
-
* @param options
|
|
121
|
+
* @param {MongoCollectionService.FindOneOptions} options - The options for the query.
|
|
122
|
+
* @return {Promise<PartialOutput<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
|
|
106
123
|
*/
|
|
107
124
|
async findOne(options) {
|
|
108
125
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
|
|
@@ -112,13 +129,24 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
112
129
|
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
113
130
|
limit: undefined
|
|
114
131
|
};
|
|
132
|
+
const decoder = this.getDecoder();
|
|
115
133
|
const out = await this.__findOne(filter, mongoOptions);
|
|
116
|
-
return out
|
|
134
|
+
return out ? decoder(out) : undefined;
|
|
117
135
|
}
|
|
118
136
|
/**
|
|
119
|
-
*
|
|
137
|
+
* Finds multiple documents in the MongoDB collection.
|
|
120
138
|
*
|
|
121
|
-
* @param options
|
|
139
|
+
* @param options - The options for the find operation.
|
|
140
|
+
* - pick: string[] - An array of fields to include in the returned documents.
|
|
141
|
+
* - include: string[] - An array of fields to include in the returned documents.
|
|
142
|
+
* - omit: string[] - An array of fields to exclude from the returned documents.
|
|
143
|
+
* - sort: Record<string, number> - The sorting criteria.
|
|
144
|
+
* - skip: number - The number of documents to skip.
|
|
145
|
+
* - limit: number - The maximum number of documents to return.
|
|
146
|
+
* - filter: FilterQuery<T> - The filter conditions to apply to the find operation.
|
|
147
|
+
* - count: boolean - If set to true, returns the total count of matching documents.
|
|
148
|
+
*
|
|
149
|
+
* @return A Promise that resolves to an array of partial outputs of type T.
|
|
122
150
|
*/
|
|
123
151
|
async findMany(options) {
|
|
124
152
|
const mongoOptions = {
|
|
@@ -152,6 +180,7 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
152
180
|
const projection = mongo_adapter_js_1.MongoAdapter.prepareProjection(dataType, options);
|
|
153
181
|
if (projection)
|
|
154
182
|
dataStages.push({ $project: projection });
|
|
183
|
+
const decoder = this.getDecoder();
|
|
155
184
|
const cursor = await this.__aggregate(stages, {
|
|
156
185
|
...mongoOptions
|
|
157
186
|
});
|
|
@@ -159,7 +188,7 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
159
188
|
if (options?.count) {
|
|
160
189
|
const facetResult = await cursor.toArray();
|
|
161
190
|
this.context.response.totalMatches = facetResult[0].count[0].totalMatches || 0;
|
|
162
|
-
return facetResult[0].data;
|
|
191
|
+
return facetResult[0].data.map((r) => decoder(r));
|
|
163
192
|
}
|
|
164
193
|
else
|
|
165
194
|
return await cursor.toArray();
|
|
@@ -170,10 +199,13 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
170
199
|
}
|
|
171
200
|
}
|
|
172
201
|
/**
|
|
173
|
-
*
|
|
202
|
+
* Retrieves a document from the collection by its ID. Throws error if not found.
|
|
174
203
|
*
|
|
175
|
-
* @param id
|
|
176
|
-
* @param options
|
|
204
|
+
* @param {*} id - The ID of the document to retrieve.
|
|
205
|
+
* @param {MongoCollectionService.FindOneOptions} [options] - Optional options for the findOne operation.
|
|
206
|
+
* @returns {Promise<PartialOutput<T>>} - A promise that resolves to the retrieved document,
|
|
207
|
+
* or rejects with a ResourceNotFoundError if the document does not exist.
|
|
208
|
+
* @throws {ResourceNotFoundError} - If the document with the specified ID does not exist.
|
|
177
209
|
*/
|
|
178
210
|
async get(id, options) {
|
|
179
211
|
const out = await this.findById(id, options);
|
|
@@ -182,20 +214,17 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
182
214
|
return out;
|
|
183
215
|
}
|
|
184
216
|
/**
|
|
185
|
-
* Updates a
|
|
186
|
-
* Returns updated document
|
|
217
|
+
* Updates a document with the given id in the collection.
|
|
187
218
|
*
|
|
188
|
-
* @param id
|
|
189
|
-
* @param input
|
|
190
|
-
* @param options
|
|
219
|
+
* @param {any} id - The id of the document to update.
|
|
220
|
+
* @param {PartialInput<T>} input - The partial input object containing the fields to update.
|
|
221
|
+
* @param {MongoCollectionService.UpdateOptions<T>} [options] - The options for the update operation.
|
|
222
|
+
* @returns {Promise<PartialOutput<T> | undefined>} A promise that resolves to the updated document or
|
|
223
|
+
* undefined if the document was not found.
|
|
191
224
|
*/
|
|
192
225
|
async update(id, input, options) {
|
|
193
|
-
const encode = this.
|
|
226
|
+
const encode = this.getEncoder('update');
|
|
194
227
|
const doc = encode(input);
|
|
195
|
-
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
196
|
-
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
197
|
-
options?.filter
|
|
198
|
-
]);
|
|
199
228
|
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
200
229
|
const mongoOptions = {
|
|
201
230
|
...options,
|
|
@@ -203,24 +232,31 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
203
232
|
upsert: undefined,
|
|
204
233
|
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
205
234
|
};
|
|
235
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
236
|
+
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
237
|
+
options?.filter
|
|
238
|
+
]);
|
|
239
|
+
const decoder = this.getDecoder();
|
|
206
240
|
const out = await this.__findOneAndUpdate(filter, patch, mongoOptions);
|
|
207
|
-
return out
|
|
241
|
+
return out ? decoder(out) : undefined;
|
|
208
242
|
}
|
|
209
243
|
/**
|
|
210
|
-
* Updates a
|
|
211
|
-
* Returns number of updated documents
|
|
244
|
+
* Updates a document in the collection with the specified ID.
|
|
212
245
|
*
|
|
213
|
-
* @param id
|
|
214
|
-
* @param input
|
|
215
|
-
* @param options
|
|
246
|
+
* @param {any} id - The ID of the document to update.
|
|
247
|
+
* @param {PartialInput<T>} input - The partial input data to update the document with.
|
|
248
|
+
* @param {MongoCollectionService.UpdateOptions<T>} options - The options for updating the document.
|
|
249
|
+
* @returns {Promise<number>} - A promise that resolves to the number of documents modified.
|
|
216
250
|
*/
|
|
217
251
|
async updateOnly(id, input, options) {
|
|
218
252
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
219
253
|
mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
|
|
220
254
|
options?.filter
|
|
221
255
|
]);
|
|
222
|
-
const encode = this.
|
|
256
|
+
const encode = this.getEncoder('update');
|
|
223
257
|
const doc = encode(input);
|
|
258
|
+
if (!Object.keys(doc).length)
|
|
259
|
+
return 0;
|
|
224
260
|
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
225
261
|
const mongoOptions = {
|
|
226
262
|
...options,
|
|
@@ -229,17 +265,20 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
229
265
|
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
230
266
|
};
|
|
231
267
|
const out = await this.__updateOne(filter, patch, mongoOptions);
|
|
232
|
-
return out.
|
|
268
|
+
return out.matchedCount;
|
|
233
269
|
}
|
|
234
270
|
/**
|
|
235
|
-
*
|
|
271
|
+
* Updates multiple documents in the collection based on the specified input and options.
|
|
236
272
|
*
|
|
237
|
-
* @param input
|
|
238
|
-
* @param options
|
|
273
|
+
* @param {OpraCommon.PartialInput<T>} input - The partial input to update the documents with.
|
|
274
|
+
* @param {MongoCollectionService.UpdateManyOptions<T>} options - The options for updating the documents.
|
|
275
|
+
* @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
|
|
239
276
|
*/
|
|
240
277
|
async updateMany(input, options) {
|
|
241
|
-
const encode = this.
|
|
278
|
+
const encode = this.getEncoder('update');
|
|
242
279
|
const doc = encode(input);
|
|
280
|
+
if (!Object.keys(doc).length)
|
|
281
|
+
return 0;
|
|
243
282
|
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
244
283
|
patch.$set = patch.$set || {};
|
|
245
284
|
const mongoOptions = {
|
|
@@ -251,45 +290,13 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
|
|
|
251
290
|
return r.matchedCount;
|
|
252
291
|
}
|
|
253
292
|
/**
|
|
254
|
-
* Generates
|
|
293
|
+
* Generates a new id for new inserting Document.
|
|
255
294
|
*
|
|
256
295
|
* @protected
|
|
296
|
+
* @returns {AnyId} A new instance of AnyId.
|
|
257
297
|
*/
|
|
258
298
|
_generateId() {
|
|
259
299
|
return new mongodb_1.ObjectId();
|
|
260
300
|
}
|
|
261
|
-
/**
|
|
262
|
-
* Generates a new Validator for encoding or returns from cache if already generated before
|
|
263
|
-
* @param operation
|
|
264
|
-
* @protected
|
|
265
|
-
*/
|
|
266
|
-
_getEncoder(operation) {
|
|
267
|
-
let encoder = this._encoders[operation];
|
|
268
|
-
if (encoder)
|
|
269
|
-
return encoder;
|
|
270
|
-
encoder = this._generateEncoder(operation);
|
|
271
|
-
this._encoders[operation] = encoder;
|
|
272
|
-
return encoder;
|
|
273
|
-
}
|
|
274
|
-
/**
|
|
275
|
-
* Generates a new Valgen Validator for encode operation
|
|
276
|
-
*
|
|
277
|
-
* @param operation
|
|
278
|
-
* @protected
|
|
279
|
-
*/
|
|
280
|
-
_generateEncoder(operation) {
|
|
281
|
-
let encoder = this._encoders[operation];
|
|
282
|
-
if (encoder)
|
|
283
|
-
return encoder;
|
|
284
|
-
const dataType = this.getDataType();
|
|
285
|
-
const options = {};
|
|
286
|
-
if (operation === 'update') {
|
|
287
|
-
options.omit = ['_id'];
|
|
288
|
-
options.partial = true;
|
|
289
|
-
}
|
|
290
|
-
encoder = dataType.generateCodec('encode', options);
|
|
291
|
-
this._encoders[operation] = encoder;
|
|
292
|
-
return encoder;
|
|
293
|
-
}
|
|
294
301
|
}
|
|
295
302
|
exports.MongoCollectionService = MongoCollectionService;
|
package/cjs/mongo-service.js
CHANGED
|
@@ -3,9 +3,15 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.MongoService = void 0;
|
|
4
4
|
const common_1 = require("@opra/common");
|
|
5
5
|
const core_1 = require("@opra/core");
|
|
6
|
+
/**
|
|
7
|
+
* Class representing a MongoDB service for interacting with a collection.
|
|
8
|
+
* @extends ApiService
|
|
9
|
+
* @template T - The type of the documents in the collection.
|
|
10
|
+
*/
|
|
6
11
|
class MongoService extends core_1.ApiService {
|
|
7
12
|
constructor(dataType, options) {
|
|
8
13
|
super();
|
|
14
|
+
this._encoders = {};
|
|
9
15
|
this._dataType = dataType;
|
|
10
16
|
this.db = options?.db;
|
|
11
17
|
this.collectionName = options?.collectionName || options?.resourceName;
|
|
@@ -20,6 +26,12 @@ class MongoService extends core_1.ApiService {
|
|
|
20
26
|
}
|
|
21
27
|
this.resourceName = options?.resourceName || this.collectionName;
|
|
22
28
|
}
|
|
29
|
+
/**
|
|
30
|
+
* Retrieves the data type of the document
|
|
31
|
+
*
|
|
32
|
+
* @returns {ComplexType} The complex data type of the field.
|
|
33
|
+
* @throws {NotAcceptableError} If the data type is not a ComplexType.
|
|
34
|
+
*/
|
|
23
35
|
getDataType() {
|
|
24
36
|
return this.context.api.getComplexType(this._dataType);
|
|
25
37
|
}
|
|
@@ -161,10 +173,11 @@ class MongoService extends core_1.ApiService {
|
|
|
161
173
|
}
|
|
162
174
|
}
|
|
163
175
|
/**
|
|
164
|
-
* Creates a cursor for a filter that can be used to iterate over results from MongoDB
|
|
176
|
+
* Creates a cursor for a filter that can be used to iterate over results from MongoDB.
|
|
165
177
|
*
|
|
166
|
-
* @param filter
|
|
167
|
-
* @param options
|
|
178
|
+
* @param {mongodb.Filter<T>} filter - The filter to apply when searching for results.
|
|
179
|
+
* @param {mongodb.FindOptions} [options] - The options to customize the search behavior.
|
|
180
|
+
* @returns {mongodb.Cursor<T>} - The cursor object that can be used to iterate over the results.
|
|
168
181
|
* @protected
|
|
169
182
|
*/
|
|
170
183
|
async __find(filter, options) {
|
|
@@ -185,10 +198,11 @@ class MongoService extends core_1.ApiService {
|
|
|
185
198
|
/**
|
|
186
199
|
* Update a single document in a collection
|
|
187
200
|
*
|
|
188
|
-
* @param filter
|
|
189
|
-
* @param update
|
|
190
|
-
* @param options
|
|
201
|
+
* @param {mongodb.Filter<T>} filter - The filter to select the document(s) to update
|
|
202
|
+
* @param {mongodb.UpdateFilter<T>} update - The update operation to be applied on the selected document(s)
|
|
203
|
+
* @param {mongodb.UpdateOptions} [options] - Optional settings for the update operation
|
|
191
204
|
* @protected
|
|
205
|
+
* @returns {Promise<mongodb.UpdateResult>} A promise that resolves to the result of the update operation
|
|
192
206
|
*/
|
|
193
207
|
async __updateOne(filter, update, options) {
|
|
194
208
|
const db = await this.getDatabase();
|
|
@@ -278,5 +292,71 @@ class MongoService extends core_1.ApiService {
|
|
|
278
292
|
(!attributes?.db || service.db === attributes.db) &&
|
|
279
293
|
(!attributes?.session || this.session === attributes?.session);
|
|
280
294
|
}
|
|
295
|
+
/**
|
|
296
|
+
* Retrieves the encoder for the specified operation.
|
|
297
|
+
*
|
|
298
|
+
* @param {String} operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
|
|
299
|
+
* @returns {vg.ObjectValidator<T>} - The encoder for the specified operation.
|
|
300
|
+
*/
|
|
301
|
+
getEncoder(operation) {
|
|
302
|
+
let encoder = this._encoders[operation];
|
|
303
|
+
if (encoder)
|
|
304
|
+
return encoder;
|
|
305
|
+
encoder = this._generateEncoder(operation);
|
|
306
|
+
this._encoders[operation] = encoder;
|
|
307
|
+
return encoder;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Retrieves the decoder.
|
|
311
|
+
*
|
|
312
|
+
* @returns {vg.ObjectValidator<T>} - The encoder for the specified operation.
|
|
313
|
+
*/
|
|
314
|
+
getDecoder() {
|
|
315
|
+
let decoder = this._decoder;
|
|
316
|
+
if (decoder)
|
|
317
|
+
return decoder;
|
|
318
|
+
decoder = this._generateDecoder();
|
|
319
|
+
this._decoder = decoder;
|
|
320
|
+
return decoder;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Generates an encoder for the specified operation.
|
|
324
|
+
*
|
|
325
|
+
* @param {string} operation - The operation to generate the encoder for. Must be either 'create' or 'update'.
|
|
326
|
+
*
|
|
327
|
+
* @protected
|
|
328
|
+
*
|
|
329
|
+
* @returns {vg.Validator} - The generated encoder for the specified operation.
|
|
330
|
+
*/
|
|
331
|
+
_generateEncoder(operation) {
|
|
332
|
+
let encoder = this._encoders[operation];
|
|
333
|
+
if (encoder)
|
|
334
|
+
return encoder;
|
|
335
|
+
const dataType = this.getDataType();
|
|
336
|
+
const options = {};
|
|
337
|
+
if (operation === 'update') {
|
|
338
|
+
options.omit = ['_id'];
|
|
339
|
+
options.partial = true;
|
|
340
|
+
}
|
|
341
|
+
encoder = dataType.generateCodec('encode', options);
|
|
342
|
+
this._encoders[operation] = encoder;
|
|
343
|
+
return encoder;
|
|
344
|
+
}
|
|
345
|
+
/**
|
|
346
|
+
* Generates an encoder for the specified operation.
|
|
347
|
+
*
|
|
348
|
+
* @protected
|
|
349
|
+
*
|
|
350
|
+
* @returns {vg.Validator} - The generated encoder for the specified operation.
|
|
351
|
+
*/
|
|
352
|
+
_generateDecoder() {
|
|
353
|
+
let decoder = this._decoder;
|
|
354
|
+
if (decoder)
|
|
355
|
+
return decoder;
|
|
356
|
+
const dataType = this.getDataType();
|
|
357
|
+
const options = {};
|
|
358
|
+
decoder = this._decoder = dataType.generateCodec('decode', options);
|
|
359
|
+
return decoder;
|
|
360
|
+
}
|
|
281
361
|
}
|
|
282
362
|
exports.MongoService = MongoService;
|
|
@@ -6,8 +6,10 @@ const common_1 = require("@opra/common");
|
|
|
6
6
|
const mongo_adapter_js_1 = require("./mongo-adapter.js");
|
|
7
7
|
const mongo_service_js_1 = require("./mongo-service.js");
|
|
8
8
|
/**
|
|
9
|
-
*
|
|
9
|
+
* A class that provides access to a MongoDB collection, with support for singleton document operations.
|
|
10
10
|
* @class MongoSingletonService
|
|
11
|
+
* @extends MongoService
|
|
12
|
+
* @template T - The type of document stored in the collection
|
|
11
13
|
*/
|
|
12
14
|
class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
13
15
|
constructor(dataType, options) {
|
|
@@ -16,33 +18,47 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
16
18
|
this._id = options?._id || new mongodb_1.ObjectId('655608925cad472b75fc6485');
|
|
17
19
|
}
|
|
18
20
|
/**
|
|
19
|
-
*
|
|
21
|
+
* Asserts the existence of a resource based on the given options.
|
|
20
22
|
*
|
|
21
|
-
* @
|
|
23
|
+
* @returns {Promise<void>} A Promise that resolves when the resource exists.
|
|
24
|
+
* @throws {ResourceNotFoundError} If the resource does not exist.
|
|
22
25
|
*/
|
|
23
|
-
async assert(
|
|
24
|
-
|
|
25
|
-
if (!out)
|
|
26
|
+
async assert() {
|
|
27
|
+
if (!(await this.exists()))
|
|
26
28
|
throw new common_1.ResourceNotFoundError(this.resourceName || this.getCollectionName());
|
|
27
|
-
return out;
|
|
28
29
|
}
|
|
29
30
|
/**
|
|
30
|
-
*
|
|
31
|
+
* Creates the document in the database.
|
|
31
32
|
*
|
|
32
|
-
* @param
|
|
33
|
-
* @param options
|
|
33
|
+
* @param {PartialInput<T>} input - The partial input to create the document with.
|
|
34
|
+
* @param {MongoSingletonService.CreateOptions} [options] - The options for creating the document.
|
|
35
|
+
* @return {Promise<PartialOutput<T>>} A promise that resolves to the partial output of the created document.
|
|
36
|
+
* @throws {Error} Throws an error if an unknown error occurs while creating the document.
|
|
34
37
|
*/
|
|
35
|
-
async create(
|
|
36
|
-
const
|
|
37
|
-
|
|
38
|
-
|
|
38
|
+
async create(input, options) {
|
|
39
|
+
const encode = this.getEncoder('create');
|
|
40
|
+
const doc = encode(input);
|
|
41
|
+
doc._id = this._id;
|
|
42
|
+
const r = await this.__insertOne(doc, options);
|
|
43
|
+
if (r.insertedId) {
|
|
44
|
+
if (!options)
|
|
45
|
+
return doc;
|
|
46
|
+
try {
|
|
47
|
+
return this.get(options);
|
|
48
|
+
}
|
|
49
|
+
catch (e) {
|
|
50
|
+
Error.captureStackTrace(e);
|
|
51
|
+
throw e;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
39
54
|
/* istanbul ignore next */
|
|
40
55
|
throw new Error('Unknown error while creating document');
|
|
41
56
|
}
|
|
42
57
|
/**
|
|
43
|
-
*
|
|
58
|
+
* Deletes a record from the database
|
|
44
59
|
*
|
|
45
|
-
* @param options
|
|
60
|
+
* @param {MongoSingletonService.DeleteOptions<T>} options - The options for deleting the record
|
|
61
|
+
* @returns {Promise<number>} The number of records deleted
|
|
46
62
|
*/
|
|
47
63
|
async delete(options) {
|
|
48
64
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([{ _id: this._id }, options?.filter]);
|
|
@@ -50,19 +66,20 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
50
66
|
return r.deletedCount;
|
|
51
67
|
}
|
|
52
68
|
/**
|
|
53
|
-
* Checks if the document exists.
|
|
54
|
-
* Returns true if document exists, false otherwise
|
|
69
|
+
* Checks if the document exists in the database.
|
|
55
70
|
*
|
|
71
|
+
* @return {Promise<boolean>} - A promise that resolves to a boolean value indicating if the document exists.
|
|
56
72
|
*/
|
|
57
73
|
async exists() {
|
|
58
|
-
return !!(await this.
|
|
74
|
+
return !!(await this.findOne({ pick: ['_id'] }));
|
|
59
75
|
}
|
|
60
76
|
/**
|
|
61
|
-
* Fetches the document
|
|
77
|
+
* Fetches the document if it exists. Returns undefined if not found.
|
|
62
78
|
*
|
|
63
|
-
* @param options
|
|
79
|
+
* @param {MongoSingletonService.FindOptions<T>} [options] - The options for finding the document.
|
|
80
|
+
* @returns {Promise<PartialOutput<T> | undefined>} - A promise that resolves to the found document or undefined if not found.
|
|
64
81
|
*/
|
|
65
|
-
async
|
|
82
|
+
async findOne(options) {
|
|
66
83
|
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([{ _id: this._id }, options?.filter]);
|
|
67
84
|
const mongoOptions = {
|
|
68
85
|
...options,
|
|
@@ -74,19 +91,29 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
74
91
|
return await this.__findOne(filter, mongoOptions);
|
|
75
92
|
}
|
|
76
93
|
/**
|
|
77
|
-
*
|
|
78
|
-
* Returns updated document
|
|
94
|
+
* Fetches the document from the Mongo collection service. Throws error if not found.
|
|
79
95
|
*
|
|
80
|
-
* @param
|
|
81
|
-
* @
|
|
96
|
+
* @param {MongoCollectionService.FindOneOptions} options - The options to customize the query.
|
|
97
|
+
* @return {Promise<PartialOutput<T>>} - A promise that resolves to the fetched document.
|
|
98
|
+
* @throws {ResourceNotFoundError} - If the document is not found in the collection.
|
|
82
99
|
*/
|
|
83
|
-
async
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
100
|
+
async get(options) {
|
|
101
|
+
const out = await this.findOne(options);
|
|
102
|
+
if (!out)
|
|
103
|
+
throw new common_1.ResourceNotFoundError(this.resourceName || this.getCollectionName());
|
|
104
|
+
return out;
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Updates a document in the MongoDB collection.
|
|
108
|
+
*
|
|
109
|
+
* @param {PartialInput<T>} input - The partial input to update the document.
|
|
110
|
+
* @param {MongoSingletonService.UpdateOptions<T>} [options] - The update options.
|
|
111
|
+
*
|
|
112
|
+
* @return {Promise<PartialOutput<T> | undefined>} - A promise that resolves to the updated document or undefined if not found.
|
|
113
|
+
*/
|
|
114
|
+
async update(input, options) {
|
|
115
|
+
const encode = this.getEncoder('update');
|
|
116
|
+
const doc = encode(input);
|
|
90
117
|
const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
|
|
91
118
|
const mongoOptions = {
|
|
92
119
|
...options,
|
|
@@ -94,8 +121,13 @@ class MongoSingletonService extends mongo_service_js_1.MongoService {
|
|
|
94
121
|
upsert: undefined,
|
|
95
122
|
projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
|
|
96
123
|
};
|
|
124
|
+
const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
|
|
125
|
+
{ _id: this._id },
|
|
126
|
+
options?.filter
|
|
127
|
+
]);
|
|
128
|
+
const decoder = this.getDecoder();
|
|
97
129
|
const out = await this.__findOneAndUpdate(filter, patch, mongoOptions);
|
|
98
|
-
return out
|
|
130
|
+
return out ? decoder(out) : undefined;
|
|
99
131
|
}
|
|
100
132
|
}
|
|
101
133
|
exports.MongoSingletonService = MongoSingletonService;
|