@opra/sqb 1.0.0-alpha.9 → 1.0.0-beta.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.
@@ -3,7 +3,9 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SqbEntityService = void 0;
4
4
  const common_1 = require("@opra/common");
5
5
  const core_1 = require("@opra/core");
6
+ const builder_1 = require("@sqb/builder");
6
7
  const connect_1 = require("@sqb/connect");
8
+ const valgen_1 = require("valgen");
7
9
  const sqb_adapter_js_1 = require("./sqb-adapter.js");
8
10
  /**
9
11
  * @class SqbEntityService
@@ -23,9 +25,9 @@ class SqbEntityService extends core_1.ServiceBase {
23
25
  this._outputCodecs = {};
24
26
  this._dataType_ = dataType;
25
27
  this.db = options?.db;
26
- this.$resourceName = options?.resourceName;
27
- this.$commonFilter = this.$commonFilter || options?.commonFilter;
28
- this.$interceptor = this.$interceptor || options?.interceptor;
28
+ this.resourceName = options?.resourceName;
29
+ this.commonFilter = options?.commonFilter;
30
+ this.interceptor = options?.interceptor;
29
31
  }
30
32
  /**
31
33
  * Retrieves the OPRA data type
@@ -62,6 +64,17 @@ class SqbEntityService extends core_1.ServiceBase {
62
64
  }
63
65
  return this._entityMetadata;
64
66
  }
67
+ for(context, overwriteProperties, overwriteContext) {
68
+ if (overwriteProperties?.commonFilter && this.commonFilter) {
69
+ overwriteProperties.commonFilter = [
70
+ ...(Array.isArray(this.commonFilter) ? this.commonFilter : [this.commonFilter]),
71
+ ...(Array.isArray(overwriteProperties?.commonFilter)
72
+ ? overwriteProperties?.commonFilter
73
+ : [overwriteProperties?.commonFilter]),
74
+ ];
75
+ }
76
+ return super.for(context, overwriteProperties, overwriteContext);
77
+ }
65
78
  /**
66
79
  * Retrieves the resource name.
67
80
  *
@@ -69,7 +82,7 @@ class SqbEntityService extends core_1.ServiceBase {
69
82
  * @throws {Error} If the collection name is not defined.
70
83
  */
71
84
  getResourceName() {
72
- const out = typeof this.$resourceName === 'function' ? this.$resourceName(this) : this.$resourceName || this.dataType.name;
85
+ const out = typeof this.resourceName === 'function' ? this.resourceName(this) : this.resourceName || this.dataType.name;
73
86
  if (out)
74
87
  return out;
75
88
  throw new Error('resourceName is not defined');
@@ -107,108 +120,125 @@ class SqbEntityService extends core_1.ServiceBase {
107
120
  /**
108
121
  * Insert a new record into database
109
122
  *
110
- * @param {PartialDTO<T>} input - The input data
111
- * @param {SqbEntityService.CreateOptions} [options] - The options object
112
- * @returns {Promise<PartialDTO<T>>} A promise that resolves to the created resource
113
- * @throws {InternalServerError} if an unknown error occurs while creating the resource
123
+ * @param command
124
+ * @returns - A promise that resolves to the created resource
114
125
  * @protected
115
126
  */
116
- async _create(input, options) {
127
+ async _create(command) {
128
+ const { input, options } = command;
129
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
117
130
  const inputCodec = this.getInputCodec('create');
118
131
  const outputCodec = this.getOutputCodec('create');
119
132
  const data = inputCodec(input);
120
- const out = await this._dbCreate(data, options);
133
+ const conn = await this.getConnection();
134
+ const repo = conn.getRepository(this.dataTypeClass);
135
+ const out = await repo.create(data, options);
121
136
  if (out)
122
137
  return outputCodec(out);
123
138
  throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
124
139
  }
140
+ /**
141
+ * Insert a new record into database
142
+ *
143
+ * @param command
144
+ * @returns - A promise that resolves to the created resource
145
+ * @protected
146
+ */
147
+ async _createOnly(command) {
148
+ const { input, options } = command;
149
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
150
+ const inputCodec = this.getInputCodec('create');
151
+ const data = inputCodec(input);
152
+ const conn = await this.getConnection();
153
+ const repo = conn.getRepository(this.dataTypeClass);
154
+ return await repo.createOnly(data, options);
155
+ }
125
156
  /**
126
157
  * Returns the count of records based on the provided options
127
158
  *
128
- * @param {SqbEntityService.CountOptions} options - The options for the count operation.
129
- * @return {Promise<number>} - A promise that resolves to the count of records
159
+ * @param command
160
+ * @return - A promise that resolves to the count of records
130
161
  * @protected
131
162
  */
132
- async _count(options) {
133
- return this._dbCount(options);
163
+ async _count(command) {
164
+ return this._dbCount(command.options);
134
165
  }
135
166
  /**
136
167
  * Deletes a record from the collection.
137
168
  *
138
- * @param {SQBAdapter.IdOrIds} id - The ID of the document to delete.
139
- * @param {SqbEntityService.DeleteOptions} [options] - Optional delete options.
140
- * @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
169
+ * @param command
170
+ * @return - A Promise that resolves to the number of documents deleted.
141
171
  * @protected
142
172
  */
143
- async _delete(id, options) {
144
- return this._dbDelete(id, options);
173
+ async _delete(command) {
174
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
175
+ return this._dbDelete(command.documentId, command.options);
145
176
  }
146
177
  /**
147
178
  * Deletes multiple documents from the collection that meet the specified filter criteria.
148
179
  *
149
- * @param {SqbEntityService.DeleteManyOptions} options - The options for the delete operation.
150
- * @return {Promise<number>} - A promise that resolves to the number of documents deleted.
180
+ * @param command
181
+ * @return - A promise that resolves to the number of documents deleted.
151
182
  * @protected
152
183
  */
153
- async _deleteMany(options) {
154
- return await this._dbDeleteMany(options);
184
+ async _deleteMany(command) {
185
+ return await this._dbDeleteMany(command.options);
155
186
  }
156
187
  /**
157
188
  * Checks if a record with the given id exists.
158
189
  *
159
- * @param {SQBAdapter.IdOrIds} id - The id of the object to check.
160
- * @param {SqbEntityService.ExistsOptions} [options] - The options for the query (optional).
161
- * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
190
+ * @param command
162
191
  * @protected
163
192
  */
164
- async _exists(id, options) {
165
- return await this._dbExists(id, options);
193
+ async _exists(command) {
194
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
195
+ return await this._dbExists(command.documentId, command.options);
166
196
  }
167
197
  /**
168
198
  * Checks if a record with the given arguments exists.
169
199
  *
170
- * @param {SqbEntityService.ExistsOneOptions} [options] - The options for the query (optional).
171
- * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
200
+ * @param command
201
+ * @return - A Promise that resolves to a boolean indicating whether the record exists or not.
172
202
  * @protected
173
203
  */
174
- async _existsOne(options) {
175
- return await this._dbExistsOne(options);
204
+ async _existsOne(command) {
205
+ return await this._dbExistsOne(command.options);
176
206
  }
177
207
  /**
178
208
  * Finds a record by ID.
179
209
  *
180
- * @param {SQBAdapter.Id} id - The ID of the record.
181
- * @param {SqbEntityService.FindOneOptions} [options] - The options for the find query.
182
- * @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
210
+ * @param command
211
+ * @return - A promise resolving to the found document, or undefined if not found.
183
212
  * @protected
184
213
  */
185
- async _findById(id, options) {
214
+ async _findById(command) {
215
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
186
216
  const decode = this.getOutputCodec('find');
187
- const out = await this._dbFindById(id, options);
217
+ const out = await this._dbFindById(command.documentId, command.options);
188
218
  return out ? decode(out) : undefined;
189
219
  }
190
220
  /**
191
221
  * Finds a record in the collection that matches the specified options.
192
222
  *
193
- * @param {SqbEntityService.FindOneOptions} [options] - The options for the query.
194
- * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
223
+ * @param command
224
+ * @return - A promise that resolves with the found document or undefined if no document is found.
195
225
  * @protected
196
226
  */
197
- async _findOne(options) {
227
+ async _findOne(command) {
198
228
  const decode = this.getOutputCodec('find');
199
- const out = await this._dbFindOne(options);
229
+ const out = await this._dbFindOne(command.options);
200
230
  return out ? decode(out) : undefined;
201
231
  }
202
232
  /**
203
233
  * Finds multiple records in collection.
204
234
  *
205
- * @param {SqbEntityService.FindManyOptions} [options] - The options for the find operation.
206
- * @return A Promise that resolves to an array of partial outputs of type T.
235
+ * @param command
236
+ * @return - A Promise that resolves to an array of partial outputs of type T.
207
237
  * @protected
208
238
  */
209
- async _findMany(options) {
239
+ async _findMany(command) {
210
240
  const decode = this.getOutputCodec('find');
211
- const out = await this._dbFindMany(options);
241
+ const out = await this._dbFindMany(command.options);
212
242
  if (out?.length) {
213
243
  return out.map(x => decode(x));
214
244
  }
@@ -217,17 +247,17 @@ class SqbEntityService extends core_1.ServiceBase {
217
247
  /**
218
248
  * Updates a record with the given id in the collection.
219
249
  *
220
- * @param {SQBAdapter.IdOrIds} id - The id of the document to update.
221
- * @param {PatchDTO<T>} input - The partial input object containing the fields to update.
222
- * @param {SqbEntityService.UpdateOptions} [options] - The options for the update operation.
223
- * @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
224
- * undefined if the document was not found.
250
+ * @param command
251
+ * @returns A promise that resolves to the updated document or undefined if the document was not found.
225
252
  * @protected
226
253
  */
227
- async _update(id, input, options) {
254
+ async _update(command) {
255
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
256
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
257
+ const { documentId, input, options } = command;
228
258
  const inputCodec = this.getInputCodec('update');
229
259
  const data = inputCodec(input);
230
- const out = await this._dbUpdate(id, data, options);
260
+ const out = await this._dbUpdate(documentId, data, options);
231
261
  const outputCodec = this.getOutputCodec('update');
232
262
  if (out)
233
263
  return outputCodec(out);
@@ -235,29 +265,30 @@ class SqbEntityService extends core_1.ServiceBase {
235
265
  /**
236
266
  * Updates a record in the collection with the specified ID and returns updated record count
237
267
  *
238
- * @param {any} id - The ID of the document to update.
239
- * @param {PatchDTO<T>} input - The partial input data to update the document with.
240
- * @param {SqbEntityService.UpdateOptions} options - The options for updating the document.
241
- * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
268
+ * @param command
269
+ * @returns - A promise that resolves to the number of documents modified.
242
270
  * @protected
243
271
  */
244
- async _updateOnly(id, input, options) {
245
- const inputCodec = this.getInputCodec('create');
272
+ async _updateOnly(command) {
273
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
274
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
275
+ const { documentId, input, options } = command;
276
+ const inputCodec = this.getInputCodec('update');
246
277
  const data = inputCodec(input);
247
- return await this._dbUpdateOnly(id, data, options);
278
+ return await this._dbUpdateOnly(documentId, data, options);
248
279
  }
249
280
  /**
250
281
  * Updates multiple records in the collection based on the specified input and options.
251
282
  *
252
- * @param {PatchDTO<T>} input - The partial input to update the documents with.
253
- * @param {SqbEntityService.UpdateManyOptions} options - The options for updating the documents.
254
- * @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
283
+ * @param command
284
+ * @return - A promise that resolves to the number of documents matched and modified.
255
285
  * @protected
256
286
  */
257
- async _updateMany(input, options) {
287
+ async _updateMany(command) {
288
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
258
289
  const inputCodec = this.getInputCodec('update');
259
- const data = inputCodec(input);
260
- return await this._dbUpdateMany(data, options);
290
+ const data = inputCodec(command.input);
291
+ return await this._dbUpdateMany(data, command.options);
261
292
  }
262
293
  /**
263
294
  * Acquires a connection and performs Repository.create operation
@@ -443,20 +474,105 @@ class SqbEntityService extends core_1.ServiceBase {
443
474
  * @returns {FilterInput | Promise<FilterInput> | undefined} The common filter or a Promise
444
475
  * that resolves to the common filter, or undefined if not available.
445
476
  */
446
- _getCommonFilter(args) {
447
- return typeof this.$commonFilter === 'function' ? this.$commonFilter(args, this) : this.$commonFilter;
448
- }
449
- async _intercept(callback, args) {
477
+ _getCommonFilter(command) {
478
+ const commonFilter = Array.isArray(this.commonFilter) ? this.commonFilter : [this.commonFilter];
479
+ const mapped = commonFilter.map(f => (typeof f === 'function' ? f(command, this) : f));
480
+ return mapped.length > 1 ? builder_1.op.and(...mapped) : mapped[0];
481
+ }
482
+ async _executeCommand(command, commandFn) {
483
+ let proto;
484
+ const next = async () => {
485
+ proto = proto ? Object.getPrototypeOf(proto) : this;
486
+ while (proto) {
487
+ if (proto.interceptor && Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
488
+ return await proto.interceptor.call(this, next, command, this);
489
+ }
490
+ proto = Object.getPrototypeOf(proto);
491
+ if (!(proto instanceof SqbEntityService))
492
+ break;
493
+ }
494
+ /** Call before[X] hooks */
495
+ if (command.crud === 'create')
496
+ await this._beforeCreate(command);
497
+ else if (command.crud === 'update' && command.byId) {
498
+ await this._beforeUpdate(command);
499
+ }
500
+ else if (command.crud === 'update' && !command.byId) {
501
+ await this._beforeUpdateMany(command);
502
+ }
503
+ else if (command.crud === 'delete' && command.byId) {
504
+ await this._beforeDelete(command);
505
+ }
506
+ else if (command.crud === 'delete' && !command.byId) {
507
+ await this._beforeDeleteMany(command);
508
+ }
509
+ /** Call command function */
510
+ return commandFn();
511
+ };
450
512
  try {
451
- if (this.$interceptor)
452
- return this.$interceptor(callback, args, this);
453
- return callback();
513
+ const result = await next();
514
+ /** Call after[X] hooks */
515
+ if (command.crud === 'create')
516
+ await this._afterCreate(command, result);
517
+ else if (command.crud === 'update' && command.byId) {
518
+ await this._afterUpdate(command, result);
519
+ }
520
+ else if (command.crud === 'update' && !command.byId) {
521
+ await this._afterUpdateMany(command, result);
522
+ }
523
+ else if (command.crud === 'delete' && command.byId) {
524
+ await this._afterDelete(command, result);
525
+ }
526
+ else if (command.crud === 'delete' && !command.byId) {
527
+ await this._afterDeleteMany(command, result);
528
+ }
529
+ return result;
454
530
  }
455
531
  catch (e) {
456
- Error.captureStackTrace(e, this._intercept);
457
- await this.$onError?.(e, this);
532
+ Error.captureStackTrace(e, this._executeCommand);
533
+ await this.onError?.(e, this);
458
534
  throw e;
459
535
  }
460
536
  }
537
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
538
+ async _beforeCreate(command) {
539
+ // Do nothing
540
+ }
541
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
542
+ async _beforeUpdate(command) {
543
+ // Do nothing
544
+ }
545
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
546
+ async _beforeUpdateMany(command) {
547
+ // Do nothing
548
+ }
549
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
550
+ async _beforeDelete(command) {
551
+ // Do nothing
552
+ }
553
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
554
+ async _beforeDeleteMany(command) {
555
+ // Do nothing
556
+ }
557
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
558
+ async _afterCreate(command, result) {
559
+ // Do nothing
560
+ }
561
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
562
+ async _afterUpdate(command, result) {
563
+ // Do nothing
564
+ }
565
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
566
+ async _afterUpdateMany(command, affected) {
567
+ // Do nothing
568
+ }
569
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
570
+ async _afterDelete(command, affected) {
571
+ // Do nothing
572
+ }
573
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
574
+ async _afterDeleteMany(command, affected) {
575
+ // Do nothing
576
+ }
461
577
  }
462
578
  exports.SqbEntityService = SqbEntityService;
@@ -19,7 +19,7 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
19
19
  */
20
20
  constructor(dataType, options) {
21
21
  super(dataType, options);
22
- this.id = this.id || options?.id || 1;
22
+ this.id = options?.id || 1;
23
23
  }
24
24
  /**
25
25
  * Asserts the existence of a resource based on the given options.
@@ -31,25 +31,17 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
31
31
  if (!(await this.exists(options)))
32
32
  throw new common_1.ResourceNotAvailableError(this.getResourceName());
33
33
  }
34
- /**
35
- * Inserts a single record into the database.
36
- *
37
- * @param {PartialDTO<T>} input - The input data
38
- * @param {SqbSingletonService.CreateOptions} [options] - The options object
39
- * @returns {Promise<PartialDTO<T>>} A promise that resolves to the created resource
40
- * @throws {Error} if an unknown error occurs while creating the resource
41
- */
42
34
  async create(input, options) {
43
- const info = {
35
+ const command = {
44
36
  crud: 'create',
45
37
  method: 'create',
46
38
  byId: false,
47
39
  input,
48
40
  options,
49
41
  };
50
- return this._intercept(async () => {
42
+ return this._executeCommand(command, async () => {
51
43
  const primaryFields = connect_1.EntityMetadata.getPrimaryIndexColumns(this.entityMetadata);
52
- const data = { ...input };
44
+ const data = { ...command.input };
53
45
  if (primaryFields.length > 1) {
54
46
  if (typeof primaryFields !== 'object') {
55
47
  throw new TypeError(`"${this.entityMetadata.name}" should has multiple primary key fields. So you should provide and object that contains key fields`);
@@ -60,8 +52,9 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
60
52
  }
61
53
  else
62
54
  data[primaryFields[0].name] = this.id;
63
- return await this._create(data, options);
64
- }, info);
55
+ command.input = data;
56
+ return await this._create(command);
57
+ });
65
58
  }
66
59
  /**
67
60
  * Deletes the singleton record
@@ -70,17 +63,18 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
70
63
  * @return {Promise<number>} - A Promise that resolves to the number of records deleted
71
64
  */
72
65
  async delete(options) {
73
- const info = {
66
+ const command = {
74
67
  crud: 'delete',
75
68
  method: 'delete',
76
69
  byId: true,
77
70
  documentId: this.id,
78
71
  options,
79
72
  };
80
- return this._intercept(async () => {
81
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
82
- return this._delete(this.id, { ...options, filter });
83
- }, info);
73
+ return this._executeCommand(command, async () => {
74
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
75
+ command.options = { ...command.options, filter };
76
+ return this._delete(command);
77
+ });
84
78
  }
85
79
  /**
86
80
  * Checks if the singleton record exists.
@@ -89,61 +83,41 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
89
83
  * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
90
84
  */
91
85
  async exists(options) {
92
- const info = {
86
+ const command = {
93
87
  crud: 'read',
94
88
  method: 'exists',
95
89
  byId: true,
96
90
  documentId: this.id,
97
91
  options,
98
92
  };
99
- return this._intercept(async () => {
100
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
101
- return this._exists(this.id, { ...options, filter });
102
- }, info);
93
+ return this._executeCommand(command, async () => {
94
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
95
+ command.options = { ...command.options, filter };
96
+ return this._exists(command);
97
+ });
103
98
  }
104
- /**
105
- * Finds the singleton record. Returns `undefined` if not found
106
- *
107
- * @param {SqbSingletonService.FindOneOptions} options - The options for the query.
108
- * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
109
- */
110
99
  async find(options) {
111
- const info = {
100
+ const command = {
112
101
  crud: 'read',
113
102
  method: 'findById',
114
103
  byId: true,
115
104
  documentId: this.id,
116
105
  options,
117
106
  };
118
- return this._intercept(async () => {
119
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
120
- return this._findById(this.id, { ...options, filter });
121
- }, info);
107
+ return this._executeCommand(command, async () => {
108
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
109
+ command.options = { ...command.options, filter };
110
+ return this._findById(command);
111
+ });
122
112
  }
123
- /**
124
- * Retrieves the singleton record. Throws error if not found.
125
- *
126
- * @param {SqbSingletonService.FindOptions} [options] - Optional options for the `find` operation.
127
- * @returns {Promise<PartialDTO<T>>} - A promise that resolves to the retrieved document,
128
- * or rejects with a ResourceNotFoundError if the document does not exist.
129
- * @throws {ResourceNotAvailableError} - If the document does not exist.
130
- */
131
113
  async get(options) {
132
114
  const out = await this.find(options);
133
115
  if (!out)
134
116
  throw new common_1.ResourceNotAvailableError(this.getResourceName());
135
117
  return out;
136
118
  }
137
- /**
138
- * Updates the singleton.
139
- *
140
- * @param {PatchDTO<T>} input - The partial input object containing the fields to update.
141
- * @param {SqbSingletonService.UpdateOptions} [options] - The options for the update operation.
142
- * @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
143
- * undefined if the document was not found.
144
- */
145
119
  async update(input, options) {
146
- const info = {
120
+ const command = {
147
121
  crud: 'update',
148
122
  method: 'update',
149
123
  documentId: this.id,
@@ -151,10 +125,11 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
151
125
  input,
152
126
  options,
153
127
  };
154
- return this._intercept(async () => {
155
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
156
- return this._update(this.id, input, { ...options, filter });
157
- }, info);
128
+ return this._executeCommand(command, async () => {
129
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
130
+ command.options = { ...command.options, filter };
131
+ return this._update(command);
132
+ });
158
133
  }
159
134
  /**
160
135
  * Updates the singleton and returns updated record count
@@ -164,7 +139,7 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
164
139
  * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
165
140
  */
166
141
  async updateOnly(input, options) {
167
- const info = {
142
+ const command = {
168
143
  crud: 'update',
169
144
  method: 'update',
170
145
  documentId: this.id,
@@ -172,10 +147,11 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
172
147
  input,
173
148
  options,
174
149
  };
175
- return this._intercept(async () => {
176
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
177
- return this._updateOnly(this.id, input, { ...options, filter });
178
- }, info);
150
+ return this._executeCommand(command, async () => {
151
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
152
+ command.options = { ...command.options, filter };
153
+ return this._updateOnly(command);
154
+ });
179
155
  }
180
156
  }
181
157
  exports.SqbSingletonService = SqbSingletonService;
@@ -75,13 +75,13 @@ function prepareFilterAst(ast) {
75
75
  case '!in':
76
76
  return sqb.Nin(left, right);
77
77
  case 'like':
78
- return sqb.Like(left, String(right).replace(/\*/, '%'));
78
+ return sqb.Like(left, String(right).replace(/\*/g, '%'));
79
79
  case 'ilike':
80
- return sqb.Ilike(left, String(right).replace(/\*/, '%'));
80
+ return sqb.Ilike(left, String(right).replace(/\*/g, '%'));
81
81
  case '!like':
82
- return sqb.NotLike(left, String(right).replace(/\*/, '%'));
82
+ return sqb.NotLike(left, String(right).replace(/\*/g, '%'));
83
83
  case '!ilike':
84
- return sqb.NotILike(left, String(right).replace(/\*/, '%'));
84
+ return sqb.NotILike(left, String(right).replace(/\*/g, '%'));
85
85
  default:
86
86
  throw new Error(`ComparisonExpression operator (${ast.op}) not implemented yet`);
87
87
  }
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "module"
3
+ }
@@ -5,7 +5,7 @@ export var SQBAdapter;
5
5
  SQBAdapter.parseFilter = _parseFilter;
6
6
  async function parseRequest(context) {
7
7
  const { operation } = context;
8
- if (operation.composition?.startsWith('Entity.') && operation.compositionOptions?.type) {
8
+ if (operation?.composition?.startsWith('Entity.') && operation.compositionOptions?.type) {
9
9
  const dataType = context.document.node.getComplexType(operation.compositionOptions?.type);
10
10
  const entityMetadata = EntityMetadata.get(dataType.ctor);
11
11
  if (!entityMetadata)
@@ -37,10 +37,10 @@ export var SQBAdapter;
37
37
  const options = {
38
38
  count: context.queryParams.count,
39
39
  filter: SQBAdapter.parseFilter(context.queryParams.filter),
40
- limit: context.queryParams.limit,
40
+ projection: context.queryParams.projection || operation.compositionOptions.defaultProjection,
41
+ limit: context.queryParams.limit || operation.compositionOptions.defaultLimit,
41
42
  offset: context.queryParams.skip,
42
- projection: context.queryParams.projection,
43
- sort: context.queryParams.sort,
43
+ sort: context.queryParams.sort || operation.compositionOptions.defaultSort,
44
44
  };
45
45
  return { method: 'findMany', options };
46
46
  }