@opra/mongodb 0.32.6 → 0.33.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -33,11 +33,11 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
33
33
  * @param {AnyId} id - The ID of the resource to assert.
34
34
  * @param {MongoCollectionService.ExistsOptions} [options] - Optional options for checking the existence.
35
35
  * @returns {Promise<void>} - A Promise that resolves when the resource exists.
36
- * @throws {ResourceNotFoundError} - If the resource does not exist.
36
+ * @throws {ResourceNotAvailableError} - If the resource does not exist.
37
37
  */
38
38
  async assert(id, options) {
39
39
  if (!(await this.exists(id, options)))
40
- throw new common_1.ResourceNotFoundError(this.getResourceName(), id);
40
+ throw new common_1.ResourceNotAvailableError(this.getResourceName(), id);
41
41
  }
42
42
  /**
43
43
  * Creates a new document in the MongoDB collection.
@@ -48,14 +48,16 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
48
48
  * @throws {Error} if an unknown error occurs while creating the document.
49
49
  */
50
50
  async create(input, options) {
51
- if (this.$interceptor && !options?.__interceptor__)
52
- return this.$interceptor(() => this.create(input, { ...options, __interceptor__: true }), {
53
- crud: 'create',
54
- method: 'create',
55
- documentId: input._id,
56
- input,
57
- options
58
- }, this);
51
+ const info = {
52
+ crud: 'create',
53
+ method: 'create',
54
+ documentId: input._id,
55
+ input,
56
+ options
57
+ };
58
+ return this._intercept(() => this._create(input, options), info);
59
+ }
60
+ async _create(input, options) {
59
61
  const encode = this.getEncoder('create');
60
62
  const doc = encode(input, { coerce: true });
61
63
  doc._id = doc._id || this._generateId();
@@ -63,16 +65,16 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
63
65
  if (r.insertedId) {
64
66
  if (!options)
65
67
  return doc;
66
- try {
67
- return this.get(doc._id, options);
68
- }
69
- catch (e) {
70
- Error.captureStackTrace(e);
71
- throw e;
72
- }
68
+ const out = await this._findById(doc._id, {
69
+ ...options,
70
+ filter: undefined,
71
+ skip: undefined
72
+ });
73
+ if (out)
74
+ return out;
73
75
  }
74
76
  /* istanbul ignore next */
75
- throw new Error('Unknown error while creating document');
77
+ throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
76
78
  }
77
79
  /**
78
80
  * Returns the count of documents in the collection based on the provided options.
@@ -81,13 +83,21 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
81
83
  * @return {Promise<number>} - A promise that resolves to the count of documents in the collection.
82
84
  */
83
85
  async count(options) {
84
- if (this.$interceptor && !options?.__interceptor__)
85
- return this.$interceptor(() => this.count({ ...options, __interceptor__: true }), {
86
- crud: 'read',
87
- method: 'count',
88
- options
89
- }, this);
90
- const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([options?.filter, await this._getDocumentFilter()]);
86
+ const info = {
87
+ crud: 'read',
88
+ method: 'count',
89
+ options
90
+ };
91
+ return this._intercept(async () => {
92
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
93
+ await this._getDocumentFilter(info),
94
+ options?.filter
95
+ ]);
96
+ return this._count({ ...options, filter });
97
+ }, info);
98
+ }
99
+ async _count(options) {
100
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
91
101
  return this.__countDocuments(filter, (0, lodash_omit_1.default)(options, 'filter'));
92
102
  }
93
103
  /**
@@ -98,17 +108,24 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
98
108
  * @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
99
109
  */
100
110
  async delete(id, options) {
101
- if (this.$interceptor && !options?.__interceptor__)
102
- return this.$interceptor(() => this.delete(id, { ...options, __interceptor__: true }), {
103
- crud: 'delete',
104
- method: 'delete',
105
- documentId: id,
106
- options
107
- }, this);
111
+ const info = {
112
+ crud: 'delete',
113
+ method: 'delete',
114
+ documentId: id,
115
+ options
116
+ };
117
+ return this._intercept(async () => {
118
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
119
+ await this._getDocumentFilter(info),
120
+ options?.filter
121
+ ]);
122
+ return this._delete(id, { ...options, filter });
123
+ }, info);
124
+ }
125
+ async _delete(id, options) {
108
126
  const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
109
127
  mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
110
- options?.filter,
111
- await this._getDocumentFilter(),
128
+ options?.filter
112
129
  ]);
113
130
  const r = await this.__deleteOne(filter, options);
114
131
  return r.deletedCount;
@@ -120,13 +137,21 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
120
137
  * @return {Promise<number>} - A promise that resolves to the number of documents deleted.
121
138
  */
122
139
  async deleteMany(options) {
123
- if (this.$interceptor && !options?.__interceptor__)
124
- return this.$interceptor(() => this.deleteMany({ ...options, __interceptor__: true }), {
125
- crud: 'delete',
126
- method: 'deleteMany',
127
- options
128
- }, this);
129
- const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([options?.filter, await this._getDocumentFilter()]);
140
+ const info = {
141
+ crud: 'delete',
142
+ method: 'delete',
143
+ options
144
+ };
145
+ return this._intercept(async () => {
146
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
147
+ await this._getDocumentFilter(info),
148
+ options?.filter,
149
+ ]);
150
+ return this._deleteMany({ ...options, filter });
151
+ }, info);
152
+ }
153
+ async _deleteMany(options) {
154
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
130
155
  const r = await this.__deleteMany(filter, (0, lodash_omit_1.default)(options, 'filter'));
131
156
  return r.deletedCount;
132
157
  }
@@ -134,18 +159,20 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
134
159
  * Checks if an object with the given id exists.
135
160
  *
136
161
  * @param {AnyId} id - The id of the object to check.
137
- * @param {MongoCollectionService.ExistsOptions} [options] - The options for the aggregation query (optional).
162
+ * @param {MongoCollectionService.ExistsOptions} [options] - The options for the query (optional).
138
163
  * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the object exists or not.
139
164
  */
140
165
  async exists(id, options) {
141
- if (this.$interceptor && !options?.__interceptor__)
142
- return this.$interceptor(() => this.exists(id, { ...options, __interceptor__: true }), {
143
- crud: 'read',
144
- method: 'exists',
145
- documentId: id,
146
- options
147
- }, this);
148
- return !!(await this.findById(id, { ...options, pick: ['_id'] }));
166
+ return !!(await this.findById(id, { ...options, pick: ['_id'], omit: undefined, include: undefined }));
167
+ }
168
+ /**
169
+ * Checks if an object with the given arguments exists.
170
+ *
171
+ * @param {MongoCollectionService.ExistsOneOptions} [options] - The options for the query (optional).
172
+ * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the object exists or not.
173
+ */
174
+ async existsOne(options) {
175
+ return !!(await this.findOne({ ...options, pick: ['_id'], omit: undefined, include: undefined }));
149
176
  }
150
177
  /**
151
178
  * Finds a document by its ID.
@@ -155,18 +182,36 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
155
182
  * @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
156
183
  */
157
184
  async findById(id, options) {
158
- if (this.$interceptor && !options?.__interceptor__)
159
- return this.$interceptor(() => this.findById(id, { ...options, __interceptor__: true }), {
160
- crud: 'read',
161
- method: 'findById',
162
- documentId: id,
163
- options
164
- }, this);
185
+ const info = {
186
+ crud: 'read',
187
+ method: 'findById',
188
+ documentId: id,
189
+ options
190
+ };
191
+ return this._intercept(async () => {
192
+ const documentFilter = await this._getDocumentFilter(info);
193
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
194
+ documentFilter,
195
+ options?.filter,
196
+ ]);
197
+ return this._findById(id, { ...options, filter });
198
+ }, info);
199
+ }
200
+ async _findById(id, options) {
165
201
  const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
166
202
  mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
167
203
  options?.filter
168
204
  ]);
169
- return await this.findOne({ ...options, filter });
205
+ const mongoOptions = {
206
+ ...options,
207
+ limit: undefined,
208
+ skip: undefined,
209
+ sort: undefined,
210
+ projection: mongo_adapter_js_1.MongoAdapter.prepareProjection(this.getDataType(), options),
211
+ };
212
+ const decode = this.getDecoder();
213
+ const out = await this.__findOne(filter, mongoOptions);
214
+ return out ? decode(out, { coerce: true }) : undefined;
170
215
  }
171
216
  /**
172
217
  * Finds a document in the collection that matches the specified options.
@@ -175,13 +220,21 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
175
220
  * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
176
221
  */
177
222
  async findOne(options) {
178
- if (this.$interceptor && !options?.__interceptor__)
179
- return this.$interceptor(() => this.findOne({ ...options, __interceptor__: true }), {
180
- crud: 'read',
181
- method: 'findOne',
182
- options
183
- }, this);
184
- const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([options?.filter, await this._getDocumentFilter()]);
223
+ const info = {
224
+ crud: 'read',
225
+ method: 'findOne',
226
+ options
227
+ };
228
+ return this._intercept(async () => {
229
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
230
+ await this._getDocumentFilter(info),
231
+ options?.filter,
232
+ ]);
233
+ return this._findOne({ ...options, filter });
234
+ }, info);
235
+ }
236
+ async _findOne(options) {
237
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
185
238
  const mongoOptions = {
186
239
  ...options,
187
240
  sort: options?.sort ? mongo_adapter_js_1.MongoAdapter.prepareSort(options.sort) : undefined,
@@ -208,12 +261,20 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
208
261
  * @return A Promise that resolves to an array of partial outputs of type T.
209
262
  */
210
263
  async findMany(options) {
211
- if (this.$interceptor && !options?.__interceptor__)
212
- return this.$interceptor(() => this.findMany({ ...options, __interceptor__: true }), {
213
- crud: 'read',
214
- method: 'findMany',
215
- options
216
- }, this);
264
+ const info = {
265
+ crud: 'read',
266
+ method: 'findMany',
267
+ options
268
+ };
269
+ return this._intercept(async () => {
270
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
271
+ await this._getDocumentFilter(info),
272
+ options?.filter,
273
+ ]);
274
+ return this._findMany({ ...options, filter });
275
+ }, info);
276
+ }
277
+ async _findMany(options) {
217
278
  const mongoOptions = {
218
279
  ...(0, lodash_omit_1.default)(options, ['pick', 'include', 'omit', 'sort', 'skip', 'limit', 'filter', 'count'])
219
280
  };
@@ -229,10 +290,9 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
229
290
  }
230
291
  });
231
292
  }
232
- const contextFilter = await this._getDocumentFilter();
233
- if (options?.filter || contextFilter) {
234
- const optionsFilter = mongo_adapter_js_1.MongoAdapter.prepareFilter([options?.filter, contextFilter]);
235
- dataStages.push({ $match: optionsFilter });
293
+ if (options?.filter) {
294
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
295
+ dataStages.push({ $match: filter });
236
296
  }
237
297
  if (options?.skip)
238
298
  dataStages.push({ $skip: options.skip });
@@ -271,12 +331,12 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
271
331
  * @param {MongoCollectionService.FindOneOptions} [options] - Optional options for the findOne operation.
272
332
  * @returns {Promise<PartialDTO<T>>} - A promise that resolves to the retrieved document,
273
333
  * or rejects with a ResourceNotFoundError if the document does not exist.
274
- * @throws {ResourceNotFoundError} - If the document with the specified ID does not exist.
334
+ * @throws {ResourceNotAvailableError} - If the document with the specified ID does not exist.
275
335
  */
276
336
  async get(id, options) {
277
337
  const out = await this.findById(id, options);
278
338
  if (!out)
279
- throw new common_1.ResourceNotFoundError(this.getResourceName(), id);
339
+ throw new common_1.ResourceNotAvailableError(this.getResourceName(), id);
280
340
  return out;
281
341
  }
282
342
  /**
@@ -289,14 +349,22 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
289
349
  * undefined if the document was not found.
290
350
  */
291
351
  async update(id, input, options) {
292
- if (this.$interceptor && !options?.__interceptor__)
293
- return this.$interceptor(() => this.update(id, input, { ...options, __interceptor__: true }), {
294
- crud: 'update',
295
- method: 'update',
296
- documentId: id,
297
- input,
298
- options,
299
- }, this);
352
+ const info = {
353
+ crud: 'update',
354
+ method: 'update',
355
+ documentId: id,
356
+ input,
357
+ options,
358
+ };
359
+ return this._intercept(async () => {
360
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
361
+ await this._getDocumentFilter(info),
362
+ options?.filter
363
+ ]);
364
+ return this._update(id, input, { ...options, filter });
365
+ }, info);
366
+ }
367
+ async _update(id, input, options) {
300
368
  const encode = this.getEncoder('update');
301
369
  const doc = encode(input, { coerce: true });
302
370
  const patch = mongo_adapter_js_1.MongoAdapter.preparePatch(doc);
@@ -308,8 +376,7 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
308
376
  };
309
377
  const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
310
378
  mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
311
- options?.filter,
312
- await this._getDocumentFilter()
379
+ options?.filter
313
380
  ]);
314
381
  const decode = this.getDecoder();
315
382
  const out = await this.__findOneAndUpdate(filter, patch, mongoOptions);
@@ -324,18 +391,25 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
324
391
  * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
325
392
  */
326
393
  async updateOnly(id, input, options) {
327
- if (this.$interceptor && !options?.__interceptor__)
328
- return this.$interceptor(() => this.updateOnly(id, input, { ...options, __interceptor__: true }), {
329
- crud: 'update',
330
- method: 'updateOnly',
331
- documentId: id,
332
- input,
333
- options,
334
- }, this);
394
+ const info = {
395
+ crud: 'update',
396
+ method: 'update',
397
+ documentId: id,
398
+ input,
399
+ options,
400
+ };
401
+ return this._intercept(async () => {
402
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
403
+ await this._getDocumentFilter(info),
404
+ options?.filter
405
+ ]);
406
+ return this._updateOnly(id, input, { ...options, filter });
407
+ }, info);
408
+ }
409
+ async _updateOnly(id, input, options) {
335
410
  const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
336
411
  mongo_adapter_js_1.MongoAdapter.prepareKeyValues(id, [this.collectionKey]),
337
- options?.filter,
338
- await this._getDocumentFilter()
412
+ options?.filter
339
413
  ]);
340
414
  const encode = this.getEncoder('update');
341
415
  const doc = encode(input, { coerce: true });
@@ -359,13 +433,21 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
359
433
  * @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
360
434
  */
361
435
  async updateMany(input, options) {
362
- if (this.$interceptor && !options?.__interceptor__)
363
- return this.$interceptor(() => this.updateMany(input, { ...options, __interceptor__: true }), {
364
- crud: 'update',
365
- method: 'updateMany',
366
- input,
367
- options,
368
- }, this);
436
+ const info = {
437
+ crud: 'update',
438
+ method: 'updateMany',
439
+ input,
440
+ options,
441
+ };
442
+ return this._intercept(async () => {
443
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([
444
+ await this._getDocumentFilter(info),
445
+ options?.filter
446
+ ]);
447
+ return this._updateMany(input, { ...options, filter });
448
+ }, info);
449
+ }
450
+ async _updateMany(input, options) {
369
451
  const encode = this.getEncoder('update');
370
452
  const doc = encode(input, { coerce: true });
371
453
  if (!Object.keys(doc).length)
@@ -376,7 +458,7 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
376
458
  ...(0, lodash_omit_1.default)(options, 'filter'),
377
459
  upsert: undefined
378
460
  };
379
- const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter([options?.filter, await this._getDocumentFilter()]);
461
+ const filter = mongo_adapter_js_1.MongoAdapter.prepareFilter(options?.filter);
380
462
  const r = await this.__updateMany(filter, patch, mongoOptions);
381
463
  return r.matchedCount;
382
464
  }
@@ -398,9 +480,14 @@ class MongoCollectionService extends mongo_service_js_1.MongoService {
398
480
  * @returns {FilterInput | Promise<FilterInput> | undefined} The common filter or a Promise
399
481
  * that resolves to the common filter, or undefined if not available.
400
482
  */
401
- _getDocumentFilter() {
483
+ _getDocumentFilter(args) {
402
484
  return typeof this.$documentFilter === 'function' ?
403
- this.$documentFilter(this) : this.$documentFilter;
485
+ this.$documentFilter(args, this) : this.$documentFilter;
486
+ }
487
+ async _intercept(callback, args) {
488
+ if (this.$interceptor)
489
+ return this.$interceptor(callback, args, this);
490
+ return callback();
404
491
  }
405
492
  }
406
493
  exports.MongoCollectionService = MongoCollectionService;
@@ -47,7 +47,7 @@ class MongoService extends core_1.ApiService {
47
47
  * Retrieves the encoder for the specified operation.
48
48
  *
49
49
  * @param {String} operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
50
- * @returns {vg.ObjectValidator<T>} - The encoder for the specified operation.
50
+ * @returns {IsObject.Validator<T>} - The encoder for the specified operation.
51
51
  */
52
52
  getEncoder(operation) {
53
53
  let encoder = this._encoders[operation];
@@ -60,7 +60,7 @@ class MongoService extends core_1.ApiService {
60
60
  /**
61
61
  * Retrieves the decoder.
62
62
  *
63
- * @returns {vg.ObjectValidator<T>} - The encoder for the specified operation.
63
+ * @returns {IsObject.Validator<T>} - The encoder for the specified operation.
64
64
  */
65
65
  getDecoder() {
66
66
  let decoder = this._decoder;
@@ -70,6 +70,48 @@ class MongoService extends core_1.ApiService {
70
70
  this._decoder = decoder;
71
71
  return decoder;
72
72
  }
73
+ /**
74
+ * Executes the provided function within a transaction.
75
+ *
76
+ * @param {WithTransactionCallback} callback - The function to be executed within the transaction.
77
+ * @param {TransactionOptions} [options] - Optional options for the transaction.
78
+ * @returns {Promise<any>} - A promise that resolves with the result of the function execution within the transaction.
79
+ */
80
+ async withTransaction(callback, options) {
81
+ let session = this.getSession();
82
+ if (session)
83
+ return callback(session);
84
+ // Backup old session property
85
+ const hasOldSession = this.hasOwnProperty('session');
86
+ const oldSessionGetter = hasOldSession ? this.session : undefined;
87
+ const db = this.getDatabase();
88
+ const client = db.client;
89
+ session = client.startSession();
90
+ this.session = session;
91
+ const oldInTransaction = session.inTransaction();
92
+ try {
93
+ if (!oldInTransaction)
94
+ session.startTransaction(options);
95
+ const out = await callback(session);
96
+ if (!oldInTransaction)
97
+ await session.commitTransaction();
98
+ return out;
99
+ }
100
+ catch (e) {
101
+ if (!oldInTransaction)
102
+ await session.abortTransaction();
103
+ throw e;
104
+ }
105
+ finally {
106
+ // Restore old session property
107
+ if (hasOldSession) {
108
+ this.session = oldSessionGetter;
109
+ await session.endSession();
110
+ }
111
+ else
112
+ delete this.session;
113
+ }
114
+ }
73
115
  /**
74
116
  * Inserts a single document into MongoDB. If documents passed in do not contain the **_id** field,
75
117
  * one will be added to each of the documents missing it by the driver, mutating the document. This behavior
@@ -379,59 +421,31 @@ class MongoService extends core_1.ApiService {
379
421
  return out;
380
422
  throw new Error('resourceName is not defined');
381
423
  }
382
- /**
383
- * Compares the current instance with the provided attributes and returns true if they match, false otherwise.
384
- * This method is protected and should only be called by subclasses.
385
- *
386
- * @param {MongoService<any>} service - The service instance to compare.
387
- * @param {RequestContext} context - The request context.
388
- * @param {Object} attributes - Optional attributes object for comparison.
389
- * @return {boolean} - True if the instance matches the provided attributes, false otherwise.
390
- * @protected
391
- */
392
- _instanceCompare(service, context, attributes) {
393
- return super._instanceCompare(service, context, attributes) &&
394
- (!attributes?.db ||
395
- (typeof service.db === 'object' && service.db === attributes.db) ||
396
- (typeof service.db === 'function' && service.getDatabase() === attributes.db)) &&
397
- (!attributes?.session ||
398
- (typeof service.session === 'object' && service.session === attributes?.session) ||
399
- (typeof service.session === 'function' && service.getSession() === attributes?.session));
400
- }
401
424
  /**
402
425
  * Generates an encoder for the specified operation.
403
426
  *
404
427
  * @param {string} operation - The operation to generate the encoder for. Must be either 'create' or 'update'.
405
428
  * @protected
406
- * @returns {vg.Validator} - The generated encoder for the specified operation.
429
+ * @returns {IsObject.Validator} - The generated encoder for the specified operation.
407
430
  */
408
431
  _generateEncoder(operation) {
409
- let encoder = this._encoders[operation];
410
- if (encoder)
411
- return encoder;
412
432
  const dataType = this.getDataType();
413
433
  const options = {};
414
434
  if (operation === 'update') {
415
435
  options.omit = ['_id'];
416
436
  options.partial = true;
417
437
  }
418
- encoder = dataType.generateCodec('encode', options);
419
- this._encoders[operation] = encoder;
420
- return encoder;
438
+ return dataType.generateCodec('encode', options);
421
439
  }
422
440
  /**
423
441
  * Generates an encoder for the specified operation.
424
442
  *
425
443
  * @protected
426
- * @returns {vg.Validator} - The generated encoder for the specified operation.
444
+ * @returns {IsObject.Validator} - The generated encoder for the specified operation.
427
445
  */
428
446
  _generateDecoder() {
429
- let decoder = this._decoder;
430
- if (decoder)
431
- return decoder;
432
447
  const dataType = this.getDataType();
433
- decoder = this._decoder = dataType.generateCodec('decode', { partial: true });
434
- return decoder;
448
+ return dataType.generateCodec('decode', { partial: true });
435
449
  }
436
450
  }
437
451
  exports.MongoService = MongoService;