@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.
@@ -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
- * Checks if document exists. Throws error if not.
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
- * Inserts a single document into MongoDB
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._getEncoder('create');
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
- return doc;
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
- * Gets the number of documents matching the filter.
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
- * Delete a document from a collection
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
- * Delete multiple documents from a collection
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 document exists.
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
- * Fetches the first document matches by id.
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
- * Fetches the first document that matches the filter.
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 || undefined;
134
+ return out ? decoder(out) : undefined;
117
135
  }
118
136
  /**
119
- * Fetches all document that matches the filter
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
- * Fetches the first Document that matches the id. Throws error undefined if not found.
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 single document.
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._getEncoder('update');
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 || undefined;
241
+ return out ? decoder(out) : undefined;
208
242
  }
209
243
  /**
210
- * Updates a single document
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._getEncoder('update');
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.modifiedCount;
268
+ return out.matchedCount;
233
269
  }
234
270
  /**
235
- * Update multiple documents in a collection
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._getEncoder('update');
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 Id value
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;
@@ -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
- * Fetches the Document. Throws error undefined if not found.
21
+ * Asserts the existence of a resource based on the given options.
20
22
  *
21
- * @param options
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(options) {
24
- const out = await this.get(options);
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
- * Inserts the document into MongoDB
31
+ * Creates the document in the database.
31
32
  *
32
- * @param doc
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(doc, options) {
36
- const r = await this.__insertOne({ ...doc, _id: this._id }, options);
37
- if (r.insertedId)
38
- return doc;
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
- * Delete the document from a collection
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.get({ pick: ['_id'] }));
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 get(options) {
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
- * Updates a single document.
78
- * Returns updated document
94
+ * Fetches the document from the Mongo collection service. Throws error if not found.
79
95
  *
80
- * @param doc
81
- * @param options
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 update(doc, options) {
84
- // Prevent updating _id field
85
- delete doc._id;
86
- const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
87
- { _id: this._id },
88
- options?.filter
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 || undefined;
130
+ return out ? decoder(out) : undefined;
99
131
  }
100
132
  }
101
133
  exports.MongoSingletonService = MongoSingletonService;