@opra/sqb 1.0.0-alpha.2 → 1.0.0-alpha.21

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.
@@ -39,14 +39,14 @@ export class SqbCollectionService extends SqbEntityService {
39
39
  * @throws {Error} if an unknown error occurs while creating the resource
40
40
  */
41
41
  async create(input, options) {
42
- const info = {
42
+ const command = {
43
43
  crud: 'create',
44
44
  method: 'create',
45
45
  byId: false,
46
46
  input,
47
47
  options,
48
48
  };
49
- return this._intercept(() => this._create(input, options), info);
49
+ return this._executeCommand(command, () => this._create(command));
50
50
  }
51
51
  /**
52
52
  * Returns the count of records based on the provided options
@@ -55,16 +55,17 @@ export class SqbCollectionService extends SqbEntityService {
55
55
  * @return {Promise<number>} - A promise that resolves to the count of records
56
56
  */
57
57
  async count(options) {
58
- const info = {
58
+ const command = {
59
59
  crud: 'read',
60
60
  method: 'count',
61
61
  byId: false,
62
62
  options,
63
63
  };
64
- return this._intercept(async () => {
65
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
66
- return this._count({ ...options, filter });
67
- }, info);
64
+ return this._executeCommand(command, async () => {
65
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
66
+ command.options = { ...command.options, filter };
67
+ return this._count(command);
68
+ });
68
69
  }
69
70
  /**
70
71
  * Deletes a record from the collection.
@@ -74,17 +75,18 @@ export class SqbCollectionService extends SqbEntityService {
74
75
  * @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
75
76
  */
76
77
  async delete(id, options) {
77
- const info = {
78
+ const command = {
78
79
  crud: 'delete',
79
80
  method: 'delete',
80
81
  byId: true,
81
82
  documentId: id,
82
83
  options,
83
84
  };
84
- return this._intercept(async () => {
85
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
86
- return this._delete(id, { ...options, filter });
87
- }, info);
85
+ return this._executeCommand(command, async () => {
86
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
87
+ command.options = { ...command.options, filter };
88
+ return this._delete(command);
89
+ });
88
90
  }
89
91
  /**
90
92
  * Deletes multiple documents from the collection that meet the specified filter criteria.
@@ -93,16 +95,17 @@ export class SqbCollectionService extends SqbEntityService {
93
95
  * @return {Promise<number>} - A promise that resolves to the number of documents deleted.
94
96
  */
95
97
  async deleteMany(options) {
96
- const info = {
98
+ const command = {
97
99
  crud: 'delete',
98
100
  method: 'deleteMany',
99
101
  byId: false,
100
102
  options,
101
103
  };
102
- return this._intercept(async () => {
103
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
104
- return this._deleteMany({ ...options, filter });
105
- }, info);
104
+ return this._executeCommand(command, async () => {
105
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
106
+ command.options = { ...command.options, filter };
107
+ return this._deleteMany(command);
108
+ });
106
109
  }
107
110
  /**
108
111
  * Checks if a record with the given id exists.
@@ -112,17 +115,18 @@ export class SqbCollectionService extends SqbEntityService {
112
115
  * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
113
116
  */
114
117
  async exists(id, options) {
115
- const info = {
118
+ const command = {
116
119
  crud: 'read',
117
120
  method: 'exists',
118
121
  byId: true,
119
122
  documentId: id,
120
123
  options,
121
124
  };
122
- return this._intercept(async () => {
123
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
124
- return this._exists(id, { ...options, filter });
125
- }, info);
125
+ return this._executeCommand(command, async () => {
126
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
127
+ command.options = { ...command.options, filter };
128
+ return this._exists(command);
129
+ });
126
130
  }
127
131
  /**
128
132
  * Checks if a record with the given arguments exists.
@@ -131,37 +135,39 @@ export class SqbCollectionService extends SqbEntityService {
131
135
  * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
132
136
  */
133
137
  async existsOne(options) {
134
- const info = {
138
+ const command = {
135
139
  crud: 'read',
136
140
  method: 'existsOne',
137
141
  byId: false,
138
142
  options,
139
143
  };
140
- return this._intercept(async () => {
141
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
142
- return this._existsOne({ ...options, filter });
143
- }, info);
144
+ return this._executeCommand(command, async () => {
145
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
146
+ command.options = { ...command.options, filter };
147
+ return this._existsOne(command);
148
+ });
144
149
  }
145
150
  /**
146
151
  * Finds a record by ID.
147
152
  *
148
- * @param {SQBAdapter.Id} id - The ID of the record.
153
+ * @param {SQBAdapter.IdOrIds} id - The ID of the record.
149
154
  * @param {SqbCollectionService.FindOneOptions} [options] - The options for the find query.
150
155
  * @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
151
156
  */
152
157
  async findById(id, options) {
153
- const info = {
158
+ const command = {
154
159
  crud: 'read',
155
160
  method: 'findById',
156
161
  byId: true,
157
162
  documentId: id,
158
163
  options,
159
164
  };
160
- return this._intercept(async () => {
161
- const documentFilter = await this._getCommonFilter(info);
162
- const filter = SQBAdapter.parseFilter([documentFilter, options?.filter]);
163
- return this._findById(id, { ...options, filter });
164
- }, info);
165
+ return this._executeCommand(command, async () => {
166
+ const documentFilter = await this._getCommonFilter(command);
167
+ const filter = SQBAdapter.parseFilter([documentFilter, command.options?.filter]);
168
+ command.options = { ...command.options, filter };
169
+ return this._findById(command);
170
+ });
165
171
  }
166
172
  /**
167
173
  * Finds a record in the collection that matches the specified options.
@@ -170,16 +176,17 @@ export class SqbCollectionService extends SqbEntityService {
170
176
  * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
171
177
  */
172
178
  async findOne(options) {
173
- const info = {
179
+ const command = {
174
180
  crud: 'read',
175
181
  method: 'findOne',
176
182
  byId: false,
177
183
  options,
178
184
  };
179
- return this._intercept(async () => {
180
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
181
- return this._findOne({ ...options, filter });
182
- }, info);
185
+ return this._executeCommand(command, async () => {
186
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
187
+ command.options = { ...command.options, filter };
188
+ return this._findOne(command);
189
+ });
183
190
  }
184
191
  /**
185
192
  * Finds multiple records in collection.
@@ -188,16 +195,17 @@ export class SqbCollectionService extends SqbEntityService {
188
195
  * @return A Promise that resolves to an array of partial outputs of type T.
189
196
  */
190
197
  async findMany(options) {
191
- const info = {
198
+ const command = {
192
199
  crud: 'read',
193
200
  method: 'findMany',
194
201
  byId: false,
195
202
  options,
196
203
  };
197
- return this._intercept(async () => {
198
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
199
- return this._findMany({ ...options, filter });
200
- }, info);
204
+ return this._executeCommand(command, async () => {
205
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
206
+ command.options = { ...command.options, filter };
207
+ return this._findMany(command);
208
+ });
201
209
  }
202
210
  /**
203
211
  * Finds multiple records in the collection and returns both records (max limit)
@@ -213,7 +221,7 @@ export class SqbCollectionService extends SqbEntityService {
213
221
  /**
214
222
  * Retrieves a records from the collection by its ID. Throws error if not found.
215
223
  *
216
- * @param {SQBAdapter.Id} id - The ID of the document to retrieve.
224
+ * @param {SQBAdapter.IdOrIds} id - The ID of the document to retrieve.
217
225
  * @param {SqbCollectionService.FindOneOptions} [options] - Optional options for the findOne operation.
218
226
  * @returns {Promise<PartialDTO<T>>} - A promise that resolves to the retrieved document,
219
227
  * or rejects with a ResourceNotFoundError if the document does not exist.
@@ -235,7 +243,7 @@ export class SqbCollectionService extends SqbEntityService {
235
243
  * undefined if the document was not found.
236
244
  */
237
245
  async update(id, input, options) {
238
- const info = {
246
+ const command = {
239
247
  crud: 'update',
240
248
  method: 'update',
241
249
  documentId: id,
@@ -243,10 +251,11 @@ export class SqbCollectionService extends SqbEntityService {
243
251
  input,
244
252
  options,
245
253
  };
246
- return this._intercept(async () => {
247
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
248
- return this._update(id, input, { ...options, filter });
249
- }, info);
254
+ return this._executeCommand(command, async () => {
255
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
256
+ command.options = { ...command.options, filter };
257
+ return this._update(command);
258
+ });
250
259
  }
251
260
  /**
252
261
  * Updates a record in the collection with the specified ID and returns updated record count
@@ -257,7 +266,7 @@ export class SqbCollectionService extends SqbEntityService {
257
266
  * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
258
267
  */
259
268
  async updateOnly(id, input, options) {
260
- const info = {
269
+ const command = {
261
270
  crud: 'update',
262
271
  method: 'update',
263
272
  documentId: id,
@@ -265,10 +274,11 @@ export class SqbCollectionService extends SqbEntityService {
265
274
  input,
266
275
  options,
267
276
  };
268
- return this._intercept(async () => {
269
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
270
- return this._updateOnly(id, input, { ...options, filter });
271
- }, info);
277
+ return this._executeCommand(command, async () => {
278
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
279
+ command.options = { ...command.options, filter };
280
+ return this._updateOnly(command);
281
+ });
272
282
  }
273
283
  /**
274
284
  * Updates multiple records in the collection based on the specified input and options.
@@ -278,16 +288,17 @@ export class SqbCollectionService extends SqbEntityService {
278
288
  * @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
279
289
  */
280
290
  async updateMany(input, options) {
281
- const info = {
291
+ const command = {
282
292
  crud: 'update',
283
293
  method: 'updateMany',
284
294
  byId: false,
285
295
  input,
286
296
  options,
287
297
  };
288
- return this._intercept(async () => {
289
- const filter = SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
290
- return this._updateMany(input, { ...options, filter });
291
- }, info);
298
+ return this._executeCommand(command, async () => {
299
+ const filter = SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
300
+ command.options = { ...command.options, filter };
301
+ return this._updateMany(command);
302
+ });
292
303
  }
293
304
  }
@@ -1,6 +1,7 @@
1
1
  import { InternalServerError } from '@opra/common';
2
2
  import { ServiceBase } from '@opra/core';
3
3
  import { EntityMetadata } from '@sqb/connect';
4
+ import { isNotNullish } from 'valgen';
4
5
  import { SQBAdapter } from './sqb-adapter.js';
5
6
  /**
6
7
  * @class SqbEntityService
@@ -16,12 +17,13 @@ export class SqbEntityService extends ServiceBase {
16
17
  */
17
18
  constructor(dataType, options) {
18
19
  super();
19
- this._encoders = {};
20
+ this._inputCodecs = {};
21
+ this._outputCodecs = {};
20
22
  this._dataType_ = dataType;
21
23
  this.db = options?.db;
22
- this.$resourceName = options?.resourceName;
23
- this.$commonFilter = this.$commonFilter || options?.commonFilter;
24
- this.$interceptor = this.$interceptor || options?.interceptor;
24
+ this.resourceName = options?.resourceName;
25
+ this.commonFilter = options?.commonFilter;
26
+ this.interceptor = options?.interceptor;
25
27
  }
26
28
  /**
27
29
  * Retrieves the OPRA data type
@@ -65,145 +67,145 @@ export class SqbEntityService extends ServiceBase {
65
67
  * @throws {Error} If the collection name is not defined.
66
68
  */
67
69
  getResourceName() {
68
- const out = typeof this.$resourceName === 'function' ? this.$resourceName(this) : this.$resourceName || this.dataType.name;
70
+ const out = typeof this.resourceName === 'function' ? this.resourceName(this) : this.resourceName || this.dataType.name;
69
71
  if (out)
70
72
  return out;
71
73
  throw new Error('resourceName is not defined');
72
74
  }
73
75
  /**
74
- * Retrieves the encoder for the specified operation.
76
+ * Retrieves the codec for the specified operation.
75
77
  *
76
78
  * @param operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
77
79
  */
78
- getEncoder(operation) {
79
- let encoder = this._encoders[operation];
80
- if (encoder)
81
- return encoder;
80
+ getInputCodec(operation) {
81
+ let validator = this._inputCodecs[operation];
82
+ if (validator)
83
+ return validator;
82
84
  const options = { projection: '*' };
83
85
  if (operation === 'update')
84
86
  options.partial = 'deep';
85
87
  const dataType = this.dataType;
86
- encoder = dataType.generateCodec('encode', options);
87
- this._encoders[operation] = encoder;
88
- return encoder;
88
+ validator = dataType.generateCodec('decode', options);
89
+ this._inputCodecs[operation] = validator;
90
+ return validator;
89
91
  }
90
92
  /**
91
- * Retrieves the decoder.
93
+ * Retrieves the codec.
92
94
  */
93
- getDecoder() {
94
- let decoder = this._decoder;
95
- if (decoder)
96
- return decoder;
95
+ getOutputCodec(operation) {
96
+ let validator = this._outputCodecs[operation];
97
+ if (validator)
98
+ return validator;
97
99
  const options = { projection: '*', partial: 'deep' };
98
100
  const dataType = this.dataType;
99
- decoder = dataType.generateCodec('decode', options);
100
- this._decoder = decoder;
101
- return decoder;
101
+ validator = dataType.generateCodec('decode', options);
102
+ this._outputCodecs[operation] = validator;
103
+ return validator;
102
104
  }
103
105
  /**
104
106
  * Insert a new record into database
105
107
  *
106
- * @param {PartialDTO<T>} input - The input data
107
- * @param {SqbEntityService.CreateOptions} [options] - The options object
108
- * @returns {Promise<PartialDTO<T>>} A promise that resolves to the created resource
109
- * @throws {InternalServerError} if an unknown error occurs while creating the resource
108
+ * @param command
109
+ * @returns - A promise that resolves to the created resource
110
110
  * @protected
111
111
  */
112
- async _create(input, options) {
113
- const encode = this.getEncoder('create');
114
- const data = encode(input);
112
+ async _create(command) {
113
+ const { input, options } = command;
114
+ isNotNullish(command.input, { label: 'input' });
115
+ const inputCodec = this.getInputCodec('create');
116
+ const outputCodec = this.getOutputCodec('create');
117
+ const data = inputCodec(input);
115
118
  const out = await this._dbCreate(data, options);
116
119
  if (out)
117
- return out;
120
+ return outputCodec(out);
118
121
  throw new InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
119
122
  }
120
123
  /**
121
124
  * Returns the count of records based on the provided options
122
125
  *
123
- * @param {SqbEntityService.CountOptions} options - The options for the count operation.
124
- * @return {Promise<number>} - A promise that resolves to the count of records
126
+ * @param command
127
+ * @return - A promise that resolves to the count of records
125
128
  * @protected
126
129
  */
127
- async _count(options) {
128
- return this._dbCount(options);
130
+ async _count(command) {
131
+ return this._dbCount(command.options);
129
132
  }
130
133
  /**
131
134
  * Deletes a record from the collection.
132
135
  *
133
- * @param {SQBAdapter.IdOrIds} id - The ID of the document to delete.
134
- * @param {SqbEntityService.DeleteOptions} [options] - Optional delete options.
135
- * @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
136
+ * @param command
137
+ * @return - A Promise that resolves to the number of documents deleted.
136
138
  * @protected
137
139
  */
138
- async _delete(id, options) {
139
- return this._dbDelete(id, options);
140
+ async _delete(command) {
141
+ isNotNullish(command.documentId, { label: 'documentId' });
142
+ return this._dbDelete(command.documentId, command.options);
140
143
  }
141
144
  /**
142
145
  * Deletes multiple documents from the collection that meet the specified filter criteria.
143
146
  *
144
- * @param {SqbEntityService.DeleteManyOptions} options - The options for the delete operation.
145
- * @return {Promise<number>} - A promise that resolves to the number of documents deleted.
147
+ * @param command
148
+ * @return - A promise that resolves to the number of documents deleted.
146
149
  * @protected
147
150
  */
148
- async _deleteMany(options) {
149
- return await this._dbDeleteMany(options);
151
+ async _deleteMany(command) {
152
+ return await this._dbDeleteMany(command.options);
150
153
  }
151
154
  /**
152
155
  * Checks if a record with the given id exists.
153
156
  *
154
- * @param {SQBAdapter.IdOrIds} id - The id of the object to check.
155
- * @param {SqbEntityService.ExistsOptions} [options] - The options for the query (optional).
156
- * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
157
+ * @param command
157
158
  * @protected
158
159
  */
159
- async _exists(id, options) {
160
- return await this._dbExists(id, options);
160
+ async _exists(command) {
161
+ isNotNullish(command.documentId, { label: 'documentId' });
162
+ return await this._dbExists(command.documentId, command.options);
161
163
  }
162
164
  /**
163
165
  * Checks if a record with the given arguments exists.
164
166
  *
165
- * @param {SqbEntityService.ExistsOneOptions} [options] - The options for the query (optional).
166
- * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
167
+ * @param command
168
+ * @return - A Promise that resolves to a boolean indicating whether the record exists or not.
167
169
  * @protected
168
170
  */
169
- async _existsOne(options) {
170
- return await this._dbExistsOne(options);
171
+ async _existsOne(command) {
172
+ return await this._dbExistsOne(command.options);
171
173
  }
172
174
  /**
173
175
  * Finds a record by ID.
174
176
  *
175
- * @param {SQBAdapter.Id} id - The ID of the record.
176
- * @param {SqbEntityService.FindOneOptions} [options] - The options for the find query.
177
- * @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
177
+ * @param command
178
+ * @return - A promise resolving to the found document, or undefined if not found.
178
179
  * @protected
179
180
  */
180
- async _findById(id, options) {
181
- const decode = this.getDecoder();
182
- const out = await this._dbFindById(id, options);
181
+ async _findById(command) {
182
+ isNotNullish(command.documentId, { label: 'documentId' });
183
+ const decode = this.getOutputCodec('find');
184
+ const out = await this._dbFindById(command.documentId, command.options);
183
185
  return out ? decode(out) : undefined;
184
186
  }
185
187
  /**
186
188
  * Finds a record in the collection that matches the specified options.
187
189
  *
188
- * @param {SqbEntityService.FindOneOptions} [options] - The options for the query.
189
- * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
190
+ * @param command
191
+ * @return - A promise that resolves with the found document or undefined if no document is found.
190
192
  * @protected
191
193
  */
192
- async _findOne(options) {
193
- const decode = this.getDecoder();
194
- const out = await this._dbFindOne(options);
194
+ async _findOne(command) {
195
+ const decode = this.getOutputCodec('find');
196
+ const out = await this._dbFindOne(command.options);
195
197
  return out ? decode(out) : undefined;
196
198
  }
197
199
  /**
198
200
  * Finds multiple records in collection.
199
201
  *
200
- * @param {SqbEntityService.FindManyOptions} [options] - The options for the find operation.
201
- * @return A Promise that resolves to an array of partial outputs of type T.
202
+ * @param command
203
+ * @return - A Promise that resolves to an array of partial outputs of type T.
202
204
  * @protected
203
205
  */
204
- async _findMany(options) {
205
- const decode = this.getDecoder();
206
- const out = await this._dbFindMany(options);
206
+ async _findMany(command) {
207
+ const decode = this.getOutputCodec('find');
208
+ const out = await this._dbFindMany(command.options);
207
209
  if (out?.length) {
208
210
  return out.map(x => decode(x));
209
211
  }
@@ -212,47 +214,48 @@ export class SqbEntityService extends ServiceBase {
212
214
  /**
213
215
  * Updates a record with the given id in the collection.
214
216
  *
215
- * @param {SQBAdapter.IdOrIds} id - The id of the document to update.
216
- * @param {PatchDTO<T>} input - The partial input object containing the fields to update.
217
- * @param {SqbEntityService.UpdateOptions} [options] - The options for the update operation.
218
- * @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
219
- * undefined if the document was not found.
217
+ * @param command
218
+ * @returns A promise that resolves to the updated document or undefined if the document was not found.
220
219
  * @protected
221
220
  */
222
- async _update(id, input, options) {
223
- const encode = this.getEncoder('update');
224
- const decode = this.getDecoder();
225
- const data = encode(input);
226
- const out = await this._dbUpdate(id, data, options);
221
+ async _update(command) {
222
+ isNotNullish(command.documentId, { label: 'documentId' });
223
+ isNotNullish(command.input, { label: 'input' });
224
+ const { documentId, input, options } = command;
225
+ const inputCodec = this.getInputCodec('update');
226
+ const data = inputCodec(input);
227
+ const out = await this._dbUpdate(documentId, data, options);
228
+ const outputCodec = this.getOutputCodec('update');
227
229
  if (out)
228
- return decode(out);
230
+ return outputCodec(out);
229
231
  }
230
232
  /**
231
233
  * Updates a record in the collection with the specified ID and returns updated record count
232
234
  *
233
- * @param {any} id - The ID of the document to update.
234
- * @param {PatchDTO<T>} input - The partial input data to update the document with.
235
- * @param {SqbEntityService.UpdateOptions} options - The options for updating the document.
236
- * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
235
+ * @param command
236
+ * @returns - A promise that resolves to the number of documents modified.
237
237
  * @protected
238
238
  */
239
- async _updateOnly(id, input, options) {
240
- const encode = this.getEncoder('create');
241
- const data = encode(input);
242
- return await this._dbUpdateOnly(id, data, options);
239
+ async _updateOnly(command) {
240
+ isNotNullish(command.documentId, { label: 'documentId' });
241
+ isNotNullish(command.input, { label: 'input' });
242
+ const { documentId, input, options } = command;
243
+ const inputCodec = this.getInputCodec('update');
244
+ const data = inputCodec(input);
245
+ return await this._dbUpdateOnly(documentId, data, options);
243
246
  }
244
247
  /**
245
248
  * Updates multiple records in the collection based on the specified input and options.
246
249
  *
247
- * @param {PatchDTO<T>} input - The partial input to update the documents with.
248
- * @param {SqbEntityService.UpdateManyOptions} options - The options for updating the documents.
249
- * @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
250
+ * @param command
251
+ * @return - A promise that resolves to the number of documents matched and modified.
250
252
  * @protected
251
253
  */
252
- async _updateMany(input, options) {
253
- const encode = this.getEncoder('update');
254
- const data = encode(input);
255
- return await this._dbUpdateMany(data, options);
254
+ async _updateMany(command) {
255
+ isNotNullish(command.input, { label: 'input' });
256
+ const inputCodec = this.getInputCodec('update');
257
+ const data = inputCodec(command.input);
258
+ return await this._dbUpdateMany(data, command.options);
256
259
  }
257
260
  /**
258
261
  * Acquires a connection and performs Repository.create operation
@@ -439,17 +442,28 @@ export class SqbEntityService extends ServiceBase {
439
442
  * that resolves to the common filter, or undefined if not available.
440
443
  */
441
444
  _getCommonFilter(args) {
442
- return typeof this.$commonFilter === 'function' ? this.$commonFilter(args, this) : this.$commonFilter;
443
- }
444
- async _intercept(callback, args) {
445
+ return typeof this.commonFilter === 'function' ? this.commonFilter(args, this) : this.commonFilter;
446
+ }
447
+ async _executeCommand(command, commandFn) {
448
+ let proto;
449
+ const next = async () => {
450
+ proto = proto ? Object.getPrototypeOf(proto) : this;
451
+ while (proto) {
452
+ if (proto.interceptor && Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
453
+ return await proto.interceptor.call(this, next, command, this);
454
+ }
455
+ proto = Object.getPrototypeOf(proto);
456
+ if (!(proto instanceof SqbEntityService))
457
+ break;
458
+ }
459
+ return commandFn();
460
+ };
445
461
  try {
446
- if (this.$interceptor)
447
- return this.$interceptor(callback, args, this);
448
- return callback();
462
+ return await next();
449
463
  }
450
464
  catch (e) {
451
- Error.captureStackTrace(e, this._intercept);
452
- await this.$onError?.(e, this);
465
+ Error.captureStackTrace(e, this._executeCommand);
466
+ await this.onError?.(e, this);
453
467
  throw e;
454
468
  }
455
469
  }