@opra/mongodb 1.0.0-alpha.16 → 1.0.0-alpha.18

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.
@@ -1,6 +1,6 @@
1
- import * as assert from 'node:assert';
2
1
  import { InternalServerError } from '@opra/common';
3
2
  import omit from 'lodash.omit';
3
+ import { isNotNullish } from 'valgen';
4
4
  import { MongoAdapter } from './mongo-adapter.js';
5
5
  import { MongoService } from './mongo-service.js';
6
6
  /**
@@ -21,19 +21,27 @@ export class MongoEntityService extends MongoService {
21
21
  /**
22
22
  * Creates a new document in the MongoDB collection.
23
23
  *
24
- * @param {PartialDTO<T>} input
25
- * @param {MongoEntityService.CreateOptions} options
24
+ * @param {MongoEntityService.CreateCommand} command
26
25
  * @protected
27
26
  */
28
- async _create(input, options) {
27
+ async _create(command) {
28
+ isNotNullish(command.input, { label: 'input' });
29
+ isNotNullish(command.input._id, { label: 'input._id' });
29
30
  const inputCodec = this.getInputCodec('create');
30
- const doc = inputCodec(input);
31
- assert.ok(doc._id, 'You must provide the "_id" field');
31
+ const doc = inputCodec(command.input);
32
+ const { options } = command;
32
33
  const r = await this._dbInsertOne(doc, options);
33
34
  if (r.insertedId) {
34
- if (!options)
35
+ if (!command.options)
35
36
  return doc;
36
- const out = await this._findById(doc._id, omit(options, 'filter'));
37
+ const findCommand = {
38
+ ...command,
39
+ crud: 'read',
40
+ byId: true,
41
+ documentId: doc._id,
42
+ options: omit(options, 'filter'),
43
+ };
44
+ const out = await this._findById(findCommand);
37
45
  if (out)
38
46
  return out;
39
47
  }
@@ -43,56 +51,65 @@ export class MongoEntityService extends MongoService {
43
51
  /**
44
52
  * Returns the count of documents in the collection based on the provided options.
45
53
  *
46
- * @param {MongoEntityService.CountOptions<T>} options - The options for the count operation.
47
- * @return {Promise<number>} - A promise that resolves to the count of documents in the collection.
54
+ * @param {MongoEntityService.CountCommand<T>} command
55
+ * @protected
48
56
  */
49
- async _count(options) {
57
+ async _count(command) {
58
+ const { options } = command;
50
59
  const filter = MongoAdapter.prepareFilter(options?.filter);
51
60
  return this._dbCountDocuments(filter, omit(options, 'filter'));
52
61
  }
53
62
  /**
54
63
  * Deletes a document from the collection.
55
64
  *
56
- * @param {MongoAdapter.AnyId} id - The ID of the document to delete.
57
- * @param {MongoEntityService.DeleteOptions<T>} [options] - Optional delete options.
58
- * @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
65
+ * @param {MongoEntityService.DeleteCommand<T>} command
66
+ * @protected
59
67
  */
60
- async _delete(id, options) {
61
- assert.ok(id, 'You must provide an id');
62
- const filter = MongoAdapter.prepareFilter([MongoAdapter.prepareKeyValues(id, ['_id']), options?.filter]);
68
+ async _delete(command) {
69
+ isNotNullish(command.documentId, { label: 'documentId' });
70
+ const { options } = command;
71
+ const filter = MongoAdapter.prepareFilter([
72
+ MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
73
+ options?.filter,
74
+ ]);
63
75
  const r = await this._dbDeleteOne(filter, options);
64
76
  return r.deletedCount;
65
77
  }
66
78
  /**
67
79
  * Deletes multiple documents from the collection that meet the specified filter criteria.
68
80
  *
69
- * @param {MongoEntityService.DeleteManyOptions<T>} options - The options for the delete operation.
70
- * @return {Promise<number>} - A promise that resolves to the number of documents deleted.
81
+ * @param {MongoEntityService.DeleteCommand<T>} command
82
+ * @protected
71
83
  */
72
- async _deleteMany(options) {
84
+ async _deleteMany(command) {
85
+ const { options } = command;
73
86
  const filter = MongoAdapter.prepareFilter(options?.filter);
74
87
  const r = await this._dbDeleteMany(filter, omit(options, 'filter'));
75
88
  return r.deletedCount;
76
89
  }
77
90
  /**
78
91
  * The distinct command returns a list of distinct values for the given key across a collection.
79
- * @param {string} field
80
- * @param {MongoEntityService.DistinctOptions<T>} options
92
+ *
93
+ * @param {MongoEntityService.DistinctCommand<T>} command
81
94
  * @protected
82
95
  */
83
- async _distinct(field, options) {
96
+ async _distinct(command) {
97
+ const { options, field } = command;
84
98
  const filter = MongoAdapter.prepareFilter(options?.filter);
85
99
  return await this._dbDistinct(field, filter, omit(options, 'filter'));
86
100
  }
87
101
  /**
88
102
  * Finds a document by its ID.
89
103
  *
90
- * @param {MongoAdapter.AnyId} id - The ID of the document.
91
- * @param {MongoEntityService.FindOneOptions<T>} [options] - The options for the find query.
92
- * @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
104
+ * @param { MongoEntityService.FindOneCommand<T>} command
93
105
  */
94
- async _findById(id, options) {
95
- const filter = MongoAdapter.prepareFilter([MongoAdapter.prepareKeyValues(id, ['_id']), options?.filter]);
106
+ async _findById(command) {
107
+ isNotNullish(command.documentId, { label: 'documentId' });
108
+ const filter = MongoAdapter.prepareFilter([
109
+ MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
110
+ command.options?.filter,
111
+ ]);
112
+ const { options } = command;
96
113
  const mongoOptions = {
97
114
  ...options,
98
115
  projection: MongoAdapter.prepareProjection(this.dataType, options?.projection),
@@ -108,10 +125,10 @@ export class MongoEntityService extends MongoService {
108
125
  /**
109
126
  * Finds a document in the collection that matches the specified options.
110
127
  *
111
- * @param {MongoEntityService.FindOneOptions} [options] - The options for the query.
112
- * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
128
+ * @param {MongoEntityService.FindOneCommand<T>} command
113
129
  */
114
- async _findOne(options) {
130
+ async _findOne(command) {
131
+ const { options } = command;
115
132
  const filter = MongoAdapter.prepareFilter(options?.filter);
116
133
  const mongoOptions = {
117
134
  ...omit(options, 'filter'),
@@ -127,10 +144,10 @@ export class MongoEntityService extends MongoService {
127
144
  /**
128
145
  * Finds multiple documents in the MongoDB collection.
129
146
  *
130
- * @param {MongoEntityService.FindManyOptions<T>} [options] - The options for the find operation.
131
- * @return A Promise that resolves to an array of partial outputs of type T.
147
+ * @param {MongoEntityService.FindManyCommand<T>} command
132
148
  */
133
- async _findMany(options) {
149
+ async _findMany(command) {
150
+ const { options } = command;
134
151
  const mongoOptions = {
135
152
  ...omit(options, ['projection', 'sort', 'skip', 'limit', 'filter']),
136
153
  };
@@ -169,10 +186,10 @@ export class MongoEntityService extends MongoService {
169
186
  * Finds multiple documents in the collection and returns both records (max limit)
170
187
  * and total count that matched the given criteria
171
188
  *
172
- * @param {MongoEntityService.FindManyOptions<T>} [options] - The options for the find operation.
173
- * @return A Promise that resolves to an array of partial outputs of type T.
189
+ * @param {MongoEntityService.FindManyCommand<T>} command
174
190
  */
175
- async _findManyWithCount(options) {
191
+ async _findManyWithCount(command) {
192
+ const { options } = command;
176
193
  const mongoOptions = {
177
194
  ...omit(options, ['projection', 'sort', 'skip', 'limit', 'filter']),
178
195
  };
@@ -226,20 +243,17 @@ export class MongoEntityService extends MongoService {
226
243
  /**
227
244
  * Updates a document with the given id in the collection.
228
245
  *
229
- * @param {AnyId} id - The id of the document to update.
230
- * @param {PatchDTO<T>|UpdateFilter<T>} input - The partial input object containing the fields to update.
231
- * @param {MongoEntityService.UpdateOptions<T>} [options] - The options for the update operation.
232
- * @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
233
- * undefined if the document was not found.
246
+ * @param {MongoEntityService.UpdateOneCommand<T>} command
234
247
  */
235
- async _update(id, input, options) {
236
- const isUpdateFilter = Array.isArray(input) || !!Object.keys(input).find(x => x.startsWith('$'));
237
- const isDocument = !Array.isArray(input) && !!Object.keys(input).find(x => !x.startsWith('$'));
238
- if (isUpdateFilter && isDocument) {
248
+ async _update(command) {
249
+ isNotNullish(command.documentId, { label: 'documentId' });
250
+ const { input, inputRaw, options } = command;
251
+ isNotNullish(input || inputRaw, { label: 'input' });
252
+ if (input && inputRaw) {
239
253
  throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
240
254
  }
241
255
  let update;
242
- if (isDocument) {
256
+ if (input) {
243
257
  const inputCodec = this.getInputCodec('update');
244
258
  const doc = inputCodec(input);
245
259
  delete doc._id;
@@ -247,8 +261,11 @@ export class MongoEntityService extends MongoService {
247
261
  update.$set = update.$set || {};
248
262
  }
249
263
  else
250
- update = input;
251
- const filter = MongoAdapter.prepareFilter([MongoAdapter.prepareKeyValues(id, ['_id']), options?.filter]);
264
+ update = inputRaw;
265
+ const filter = MongoAdapter.prepareFilter([
266
+ MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
267
+ options?.filter,
268
+ ]);
252
269
  const mongoOptions = {
253
270
  ...options,
254
271
  includeResultMetadata: false,
@@ -263,19 +280,17 @@ export class MongoEntityService extends MongoService {
263
280
  /**
264
281
  * Updates a document in the collection with the specified ID.
265
282
  *
266
- * @param {MongoAdapter.AnyId} id - The ID of the document to update.
267
- * @param {PatchDTO<T>|UpdateFilter<T>} input - The partial input data to update the document with.
268
- * @param {MongoEntityService.UpdateOptions<T>} [options] - The options for updating the document.
269
- * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
283
+ * @param {MongoEntityService.UpdateOneCommand<T>} command
270
284
  */
271
- async _updateOnly(id, input, options) {
272
- const isUpdateFilter = Array.isArray(input) || !!Object.keys(input).find(x => x.startsWith('$'));
273
- const isDocument = !Array.isArray(input) && !!Object.keys(input).find(x => !x.startsWith('$'));
274
- if (isUpdateFilter && isDocument) {
285
+ async _updateOnly(command) {
286
+ isNotNullish(command.documentId, { label: 'documentId' });
287
+ const { input, inputRaw, options } = command;
288
+ isNotNullish(input || inputRaw, { label: 'input' });
289
+ if (input && inputRaw) {
275
290
  throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
276
291
  }
277
292
  let update;
278
- if (isDocument) {
293
+ if (input) {
279
294
  const inputCodec = this.getInputCodec('update');
280
295
  const doc = inputCodec(input);
281
296
  delete doc._id;
@@ -284,8 +299,11 @@ export class MongoEntityService extends MongoService {
284
299
  return 0;
285
300
  }
286
301
  else
287
- update = input;
288
- const filter = MongoAdapter.prepareFilter([MongoAdapter.prepareKeyValues(id, ['_id']), options?.filter]);
302
+ update = inputRaw;
303
+ const filter = MongoAdapter.prepareFilter([
304
+ MongoAdapter.prepareKeyValues(command.documentId, ['_id']),
305
+ options?.filter,
306
+ ]);
289
307
  const mongoOptions = {
290
308
  ...options,
291
309
  includeResultMetadata: false,
@@ -298,18 +316,17 @@ export class MongoEntityService extends MongoService {
298
316
  /**
299
317
  * Updates multiple documents in the collection based on the specified input and options.
300
318
  *
301
- * @param {PatchDTO<T>|UpdateFilter<T>} input - The partial input to update the documents with.
302
- * @param {MongoEntityService.UpdateManyOptions<T>} [options] - The options for updating the documents.
303
- * @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
319
+ * @param {MongoEntityService.UpdateManyCommand<T>} command
304
320
  */
305
- async _updateMany(input, options) {
306
- const isUpdateFilter = Array.isArray(input) || !!Object.keys(input).find(x => x.startsWith('$'));
307
- const isDocument = !Array.isArray(input) && !!Object.keys(input).find(x => !x.startsWith('$'));
308
- if (isUpdateFilter && isDocument) {
321
+ async _updateMany(command) {
322
+ isNotNullish(command.input, { label: 'input' });
323
+ const { input, inputRaw, options } = command;
324
+ isNotNullish(input || inputRaw, { label: 'input' });
325
+ if (input && inputRaw) {
309
326
  throw new TypeError('You must pass one of MongoDB UpdateFilter or a partial document, not both');
310
327
  }
311
328
  let update;
312
- if (isDocument) {
329
+ if (input) {
313
330
  const inputCodec = this.getInputCodec('update');
314
331
  const doc = inputCodec(input);
315
332
  delete doc._id;
@@ -318,7 +335,7 @@ export class MongoEntityService extends MongoService {
318
335
  return 0;
319
336
  }
320
337
  else
321
- update = input;
338
+ update = inputRaw;
322
339
  const mongoOptions = {
323
340
  ...omit(options, 'filter'),
324
341
  upsert: undefined,