@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.
@@ -4,6 +4,7 @@ exports.SqbEntityService = void 0;
4
4
  const common_1 = require("@opra/common");
5
5
  const core_1 = require("@opra/core");
6
6
  const connect_1 = require("@sqb/connect");
7
+ const valgen_1 = require("valgen");
7
8
  const sqb_adapter_js_1 = require("./sqb-adapter.js");
8
9
  /**
9
10
  * @class SqbEntityService
@@ -19,12 +20,13 @@ class SqbEntityService extends core_1.ServiceBase {
19
20
  */
20
21
  constructor(dataType, options) {
21
22
  super();
22
- this._encoders = {};
23
+ this._inputCodecs = {};
24
+ this._outputCodecs = {};
23
25
  this._dataType_ = dataType;
24
26
  this.db = options?.db;
25
- this.$resourceName = options?.resourceName;
26
- this.$commonFilter = this.$commonFilter || options?.commonFilter;
27
- this.$interceptor = this.$interceptor || options?.interceptor;
27
+ this.resourceName = options?.resourceName;
28
+ this.commonFilter = options?.commonFilter;
29
+ this.interceptor = options?.interceptor;
28
30
  }
29
31
  /**
30
32
  * Retrieves the OPRA data type
@@ -68,145 +70,145 @@ class SqbEntityService extends core_1.ServiceBase {
68
70
  * @throws {Error} If the collection name is not defined.
69
71
  */
70
72
  getResourceName() {
71
- const out = typeof this.$resourceName === 'function' ? this.$resourceName(this) : this.$resourceName || this.dataType.name;
73
+ const out = typeof this.resourceName === 'function' ? this.resourceName(this) : this.resourceName || this.dataType.name;
72
74
  if (out)
73
75
  return out;
74
76
  throw new Error('resourceName is not defined');
75
77
  }
76
78
  /**
77
- * Retrieves the encoder for the specified operation.
79
+ * Retrieves the codec for the specified operation.
78
80
  *
79
81
  * @param operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
80
82
  */
81
- getEncoder(operation) {
82
- let encoder = this._encoders[operation];
83
- if (encoder)
84
- return encoder;
83
+ getInputCodec(operation) {
84
+ let validator = this._inputCodecs[operation];
85
+ if (validator)
86
+ return validator;
85
87
  const options = { projection: '*' };
86
88
  if (operation === 'update')
87
89
  options.partial = 'deep';
88
90
  const dataType = this.dataType;
89
- encoder = dataType.generateCodec('encode', options);
90
- this._encoders[operation] = encoder;
91
- return encoder;
91
+ validator = dataType.generateCodec('decode', options);
92
+ this._inputCodecs[operation] = validator;
93
+ return validator;
92
94
  }
93
95
  /**
94
- * Retrieves the decoder.
96
+ * Retrieves the codec.
95
97
  */
96
- getDecoder() {
97
- let decoder = this._decoder;
98
- if (decoder)
99
- return decoder;
98
+ getOutputCodec(operation) {
99
+ let validator = this._outputCodecs[operation];
100
+ if (validator)
101
+ return validator;
100
102
  const options = { projection: '*', partial: 'deep' };
101
103
  const dataType = this.dataType;
102
- decoder = dataType.generateCodec('decode', options);
103
- this._decoder = decoder;
104
- return decoder;
104
+ validator = dataType.generateCodec('decode', options);
105
+ this._outputCodecs[operation] = validator;
106
+ return validator;
105
107
  }
106
108
  /**
107
109
  * Insert a new record into database
108
110
  *
109
- * @param {PartialDTO<T>} input - The input data
110
- * @param {SqbEntityService.CreateOptions} [options] - The options object
111
- * @returns {Promise<PartialDTO<T>>} A promise that resolves to the created resource
112
- * @throws {InternalServerError} if an unknown error occurs while creating the resource
111
+ * @param command
112
+ * @returns - A promise that resolves to the created resource
113
113
  * @protected
114
114
  */
115
- async _create(input, options) {
116
- const encode = this.getEncoder('create');
117
- const data = encode(input);
115
+ async _create(command) {
116
+ const { input, options } = command;
117
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
118
+ const inputCodec = this.getInputCodec('create');
119
+ const outputCodec = this.getOutputCodec('create');
120
+ const data = inputCodec(input);
118
121
  const out = await this._dbCreate(data, options);
119
122
  if (out)
120
- return out;
123
+ return outputCodec(out);
121
124
  throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
122
125
  }
123
126
  /**
124
127
  * Returns the count of records based on the provided options
125
128
  *
126
- * @param {SqbEntityService.CountOptions} options - The options for the count operation.
127
- * @return {Promise<number>} - A promise that resolves to the count of records
129
+ * @param command
130
+ * @return - A promise that resolves to the count of records
128
131
  * @protected
129
132
  */
130
- async _count(options) {
131
- return this._dbCount(options);
133
+ async _count(command) {
134
+ return this._dbCount(command.options);
132
135
  }
133
136
  /**
134
137
  * Deletes a record from the collection.
135
138
  *
136
- * @param {SQBAdapter.IdOrIds} id - The ID of the document to delete.
137
- * @param {SqbEntityService.DeleteOptions} [options] - Optional delete options.
138
- * @return {Promise<number>} - A Promise that resolves to the number of documents deleted.
139
+ * @param command
140
+ * @return - A Promise that resolves to the number of documents deleted.
139
141
  * @protected
140
142
  */
141
- async _delete(id, options) {
142
- return this._dbDelete(id, options);
143
+ async _delete(command) {
144
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
145
+ return this._dbDelete(command.documentId, command.options);
143
146
  }
144
147
  /**
145
148
  * Deletes multiple documents from the collection that meet the specified filter criteria.
146
149
  *
147
- * @param {SqbEntityService.DeleteManyOptions} options - The options for the delete operation.
148
- * @return {Promise<number>} - A promise that resolves to the number of documents deleted.
150
+ * @param command
151
+ * @return - A promise that resolves to the number of documents deleted.
149
152
  * @protected
150
153
  */
151
- async _deleteMany(options) {
152
- return await this._dbDeleteMany(options);
154
+ async _deleteMany(command) {
155
+ return await this._dbDeleteMany(command.options);
153
156
  }
154
157
  /**
155
158
  * Checks if a record with the given id exists.
156
159
  *
157
- * @param {SQBAdapter.IdOrIds} id - The id of the object to check.
158
- * @param {SqbEntityService.ExistsOptions} [options] - The options for the query (optional).
159
- * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
160
+ * @param command
160
161
  * @protected
161
162
  */
162
- async _exists(id, options) {
163
- return await this._dbExists(id, options);
163
+ async _exists(command) {
164
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
165
+ return await this._dbExists(command.documentId, command.options);
164
166
  }
165
167
  /**
166
168
  * Checks if a record with the given arguments exists.
167
169
  *
168
- * @param {SqbEntityService.ExistsOneOptions} [options] - The options for the query (optional).
169
- * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
170
+ * @param command
171
+ * @return - A Promise that resolves to a boolean indicating whether the record exists or not.
170
172
  * @protected
171
173
  */
172
- async _existsOne(options) {
173
- return await this._dbExistsOne(options);
174
+ async _existsOne(command) {
175
+ return await this._dbExistsOne(command.options);
174
176
  }
175
177
  /**
176
178
  * Finds a record by ID.
177
179
  *
178
- * @param {SQBAdapter.Id} id - The ID of the record.
179
- * @param {SqbEntityService.FindOneOptions} [options] - The options for the find query.
180
- * @return {Promise<PartialDTO<T | undefined>>} - A promise resolving to the found document, or undefined if not found.
180
+ * @param command
181
+ * @return - A promise resolving to the found document, or undefined if not found.
181
182
  * @protected
182
183
  */
183
- async _findById(id, options) {
184
- const decode = this.getDecoder();
185
- const out = await this._dbFindById(id, options);
184
+ async _findById(command) {
185
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
186
+ const decode = this.getOutputCodec('find');
187
+ const out = await this._dbFindById(command.documentId, command.options);
186
188
  return out ? decode(out) : undefined;
187
189
  }
188
190
  /**
189
191
  * Finds a record in the collection that matches the specified options.
190
192
  *
191
- * @param {SqbEntityService.FindOneOptions} [options] - The options for the query.
192
- * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
193
+ * @param command
194
+ * @return - A promise that resolves with the found document or undefined if no document is found.
193
195
  * @protected
194
196
  */
195
- async _findOne(options) {
196
- const decode = this.getDecoder();
197
- const out = await this._dbFindOne(options);
197
+ async _findOne(command) {
198
+ const decode = this.getOutputCodec('find');
199
+ const out = await this._dbFindOne(command.options);
198
200
  return out ? decode(out) : undefined;
199
201
  }
200
202
  /**
201
203
  * Finds multiple records in collection.
202
204
  *
203
- * @param {SqbEntityService.FindManyOptions} [options] - The options for the find operation.
204
- * @return A Promise that resolves to an array of partial outputs of type T.
205
+ * @param command
206
+ * @return - A Promise that resolves to an array of partial outputs of type T.
205
207
  * @protected
206
208
  */
207
- async _findMany(options) {
208
- const decode = this.getDecoder();
209
- const out = await this._dbFindMany(options);
209
+ async _findMany(command) {
210
+ const decode = this.getOutputCodec('find');
211
+ const out = await this._dbFindMany(command.options);
210
212
  if (out?.length) {
211
213
  return out.map(x => decode(x));
212
214
  }
@@ -215,47 +217,48 @@ class SqbEntityService extends core_1.ServiceBase {
215
217
  /**
216
218
  * Updates a record with the given id in the collection.
217
219
  *
218
- * @param {SQBAdapter.IdOrIds} id - The id of the document to update.
219
- * @param {PatchDTO<T>} input - The partial input object containing the fields to update.
220
- * @param {SqbEntityService.UpdateOptions} [options] - The options for the update operation.
221
- * @returns {Promise<PartialDTO<T> | undefined>} A promise that resolves to the updated document or
222
- * undefined if the document was not found.
220
+ * @param command
221
+ * @returns A promise that resolves to the updated document or undefined if the document was not found.
223
222
  * @protected
224
223
  */
225
- async _update(id, input, options) {
226
- const encode = this.getEncoder('update');
227
- const decode = this.getDecoder();
228
- const data = encode(input);
229
- const out = await this._dbUpdate(id, data, options);
224
+ async _update(command) {
225
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
226
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
227
+ const { documentId, input, options } = command;
228
+ const inputCodec = this.getInputCodec('update');
229
+ const data = inputCodec(input);
230
+ const out = await this._dbUpdate(documentId, data, options);
231
+ const outputCodec = this.getOutputCodec('update');
230
232
  if (out)
231
- return decode(out);
233
+ return outputCodec(out);
232
234
  }
233
235
  /**
234
236
  * Updates a record in the collection with the specified ID and returns updated record count
235
237
  *
236
- * @param {any} id - The ID of the document to update.
237
- * @param {PatchDTO<T>} input - The partial input data to update the document with.
238
- * @param {SqbEntityService.UpdateOptions} options - The options for updating the document.
239
- * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
238
+ * @param command
239
+ * @returns - A promise that resolves to the number of documents modified.
240
240
  * @protected
241
241
  */
242
- async _updateOnly(id, input, options) {
243
- const encode = this.getEncoder('create');
244
- const data = encode(input);
245
- return await this._dbUpdateOnly(id, data, options);
242
+ async _updateOnly(command) {
243
+ (0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
244
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
245
+ const { documentId, input, options } = command;
246
+ const inputCodec = this.getInputCodec('update');
247
+ const data = inputCodec(input);
248
+ return await this._dbUpdateOnly(documentId, data, options);
246
249
  }
247
250
  /**
248
251
  * Updates multiple records in the collection based on the specified input and options.
249
252
  *
250
- * @param {PatchDTO<T>} input - The partial input to update the documents with.
251
- * @param {SqbEntityService.UpdateManyOptions} options - The options for updating the documents.
252
- * @return {Promise<number>} - A promise that resolves to the number of documents matched and modified.
253
+ * @param command
254
+ * @return - A promise that resolves to the number of documents matched and modified.
253
255
  * @protected
254
256
  */
255
- async _updateMany(input, options) {
256
- const encode = this.getEncoder('update');
257
- const data = encode(input);
258
- return await this._dbUpdateMany(data, options);
257
+ async _updateMany(command) {
258
+ (0, valgen_1.isNotNullish)(command.input, { label: 'input' });
259
+ const inputCodec = this.getInputCodec('update');
260
+ const data = inputCodec(command.input);
261
+ return await this._dbUpdateMany(data, command.options);
259
262
  }
260
263
  /**
261
264
  * Acquires a connection and performs Repository.create operation
@@ -442,17 +445,28 @@ class SqbEntityService extends core_1.ServiceBase {
442
445
  * that resolves to the common filter, or undefined if not available.
443
446
  */
444
447
  _getCommonFilter(args) {
445
- return typeof this.$commonFilter === 'function' ? this.$commonFilter(args, this) : this.$commonFilter;
446
- }
447
- async _intercept(callback, args) {
448
+ return typeof this.commonFilter === 'function' ? this.commonFilter(args, this) : this.commonFilter;
449
+ }
450
+ async _executeCommand(command, commandFn) {
451
+ let proto;
452
+ const next = async () => {
453
+ proto = proto ? Object.getPrototypeOf(proto) : this;
454
+ while (proto) {
455
+ if (proto.interceptor && Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
456
+ return await proto.interceptor.call(this, next, command, this);
457
+ }
458
+ proto = Object.getPrototypeOf(proto);
459
+ if (!(proto instanceof SqbEntityService))
460
+ break;
461
+ }
462
+ return commandFn();
463
+ };
448
464
  try {
449
- if (this.$interceptor)
450
- return this.$interceptor(callback, args, this);
451
- return callback();
465
+ return await next();
452
466
  }
453
467
  catch (e) {
454
- Error.captureStackTrace(e, this._intercept);
455
- await this.$onError?.(e, this);
468
+ Error.captureStackTrace(e, this._executeCommand);
469
+ await this.onError?.(e, this);
456
470
  throw e;
457
471
  }
458
472
  }
@@ -40,27 +40,29 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
40
40
  * @throws {Error} if an unknown error occurs while creating the resource
41
41
  */
42
42
  async create(input, options) {
43
- const info = {
43
+ const command = {
44
44
  crud: 'create',
45
45
  method: 'create',
46
46
  byId: false,
47
47
  input,
48
48
  options,
49
49
  };
50
- return this._intercept(async () => {
50
+ return this._executeCommand(command, async () => {
51
51
  const primaryFields = connect_1.EntityMetadata.getPrimaryIndexColumns(this.entityMetadata);
52
- const data = { ...input };
52
+ const data = { ...command.input };
53
53
  if (primaryFields.length > 1) {
54
- if (typeof primaryFields !== 'object')
54
+ if (typeof primaryFields !== 'object') {
55
55
  throw new TypeError(`"${this.entityMetadata.name}" should has multiple primary key fields. So you should provide and object that contains key fields`);
56
+ }
56
57
  for (const field of primaryFields) {
57
58
  data[field.name] = this.id[field.name];
58
59
  }
59
60
  }
60
61
  else
61
62
  data[primaryFields[0].name] = this.id;
62
- return await this._create(data, options);
63
- }, info);
63
+ command.input = data;
64
+ return await this._create(command);
65
+ });
64
66
  }
65
67
  /**
66
68
  * Deletes the singleton record
@@ -69,17 +71,18 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
69
71
  * @return {Promise<number>} - A Promise that resolves to the number of records deleted
70
72
  */
71
73
  async delete(options) {
72
- const info = {
74
+ const command = {
73
75
  crud: 'delete',
74
76
  method: 'delete',
75
77
  byId: true,
76
78
  documentId: this.id,
77
79
  options,
78
80
  };
79
- return this._intercept(async () => {
80
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
81
- return this._delete(this.id, { ...options, filter });
82
- }, info);
81
+ return this._executeCommand(command, async () => {
82
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
83
+ command.options = { ...command.options, filter };
84
+ return this._delete(command);
85
+ });
83
86
  }
84
87
  /**
85
88
  * Checks if the singleton record exists.
@@ -88,17 +91,18 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
88
91
  * @return {Promise<boolean>} - A Promise that resolves to a boolean indicating whether the record exists or not.
89
92
  */
90
93
  async exists(options) {
91
- const info = {
94
+ const command = {
92
95
  crud: 'read',
93
96
  method: 'exists',
94
97
  byId: true,
95
98
  documentId: this.id,
96
99
  options,
97
100
  };
98
- return this._intercept(async () => {
99
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
100
- return this._exists(this.id, { ...options, filter });
101
- }, info);
101
+ return this._executeCommand(command, async () => {
102
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
103
+ command.options = { ...command.options, filter };
104
+ return this._exists(command);
105
+ });
102
106
  }
103
107
  /**
104
108
  * Finds the singleton record. Returns `undefined` if not found
@@ -107,17 +111,18 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
107
111
  * @return {Promise<PartialDTO<T> | undefined>} A promise that resolves with the found document or undefined if no document is found.
108
112
  */
109
113
  async find(options) {
110
- const info = {
114
+ const command = {
111
115
  crud: 'read',
112
116
  method: 'findById',
113
117
  byId: true,
114
118
  documentId: this.id,
115
119
  options,
116
120
  };
117
- return this._intercept(async () => {
118
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
119
- return this._findById(this.id, { ...options, filter });
120
- }, info);
121
+ return this._executeCommand(command, async () => {
122
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
123
+ command.options = { ...command.options, filter };
124
+ return this._findById(command);
125
+ });
121
126
  }
122
127
  /**
123
128
  * Retrieves the singleton record. Throws error if not found.
@@ -142,7 +147,7 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
142
147
  * undefined if the document was not found.
143
148
  */
144
149
  async update(input, options) {
145
- const info = {
150
+ const command = {
146
151
  crud: 'update',
147
152
  method: 'update',
148
153
  documentId: this.id,
@@ -150,10 +155,11 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
150
155
  input,
151
156
  options,
152
157
  };
153
- return this._intercept(async () => {
154
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
155
- return this._update(this.id, input, { ...options, filter });
156
- }, info);
158
+ return this._executeCommand(command, async () => {
159
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
160
+ command.options = { ...command.options, filter };
161
+ return this._update(command);
162
+ });
157
163
  }
158
164
  /**
159
165
  * Updates the singleton and returns updated record count
@@ -163,7 +169,7 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
163
169
  * @returns {Promise<number>} - A promise that resolves to the number of documents modified.
164
170
  */
165
171
  async updateOnly(input, options) {
166
- const info = {
172
+ const command = {
167
173
  crud: 'update',
168
174
  method: 'update',
169
175
  documentId: this.id,
@@ -171,10 +177,11 @@ class SqbSingletonService extends sqb_entity_service_js_1.SqbEntityService {
171
177
  input,
172
178
  options,
173
179
  };
174
- return this._intercept(async () => {
175
- const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(info), options?.filter]);
176
- return this._updateOnly(this.id, input, { ...options, filter });
177
- }, info);
180
+ return this._executeCommand(command, async () => {
181
+ const filter = sqb_adapter_js_1.SQBAdapter.parseFilter([await this._getCommonFilter(command), command.options?.filter]);
182
+ command.options = { ...command.options, filter };
183
+ return this._updateOnly(command);
184
+ });
178
185
  }
179
186
  }
180
187
  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
  }
@@ -57,16 +57,20 @@ DataTypeFactory._prepareComplexTypeArgs = async function (context, owner, initAr
57
57
  if (hasNoType || fieldSchema.type === String)
58
58
  fieldSchema.type = 'time';
59
59
  break;
60
+ default:
61
+ break;
60
62
  }
61
63
  }
62
64
  if (isAssociationField(sqbField)) {
63
65
  if (sqbField.association.returnsMany())
64
66
  fieldSchema.isArray = true;
65
- if (!fieldSchema.hasOwnProperty('exclusive'))
67
+ if (!Object.prototype.hasOwnProperty.call(fieldSchema, 'exclusive'))
66
68
  fieldSchema.exclusive = true;
67
69
  }
68
- if (!fieldSchema.hasOwnProperty('exclusive') && sqbField.hasOwnProperty('exclusive'))
70
+ if (!Object.prototype.hasOwnProperty.call(fieldSchema, 'exclusive') &&
71
+ Object.prototype.hasOwnProperty.call(sqbField, 'exclusive')) {
69
72
  fieldSchema.exclusive = sqbField.exclusive;
73
+ }
70
74
  }
71
75
  }
72
76
  return _prepareComplexTypeArgs.apply(DataTypeFactory, [context, owner, initArgs, metadata]);
@@ -10,7 +10,7 @@ export var SQBAdapter;
10
10
  const entityMetadata = EntityMetadata.get(dataType.ctor);
11
11
  if (!entityMetadata)
12
12
  throw new Error(`Type class "${dataType.ctor}" is not an SQB entity`);
13
- const { compositionOptions } = operation;
13
+ const controller = operation.owner;
14
14
  switch (operation.composition) {
15
15
  case 'Entity.Create': {
16
16
  const data = await context.getBody();
@@ -20,7 +20,8 @@ export var SQBAdapter;
20
20
  return { method: 'create', data, options };
21
21
  }
22
22
  case 'Entity.Delete': {
23
- const key = context.pathParams[compositionOptions.keyParameter];
23
+ const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
24
+ const key = keyParam && context.pathParams[String(keyParam.name)];
24
25
  const options = {
25
26
  filter: SQBAdapter.parseFilter(context.queryParams.filter),
26
27
  };
@@ -44,7 +45,8 @@ export var SQBAdapter;
44
45
  return { method: 'findMany', options };
45
46
  }
46
47
  case 'Entity.Get': {
47
- const key = context.pathParams[compositionOptions.keyParameter];
48
+ const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
49
+ const key = keyParam && context.pathParams[String(keyParam.name)];
48
50
  const options = {
49
51
  projection: context.queryParams.projection,
50
52
  filter: SQBAdapter.parseFilter(context.queryParams.filter),
@@ -53,7 +55,8 @@ export var SQBAdapter;
53
55
  }
54
56
  case 'Entity.Update': {
55
57
  const data = await context.getBody();
56
- const key = context.pathParams[compositionOptions.keyParameter];
58
+ const keyParam = operation.parameters.find(p => p.keyParam) || controller.parameters.find(p => p.keyParam);
59
+ const key = keyParam && context.pathParams[String(keyParam.name)];
57
60
  const options = {
58
61
  projection: context.queryParams.projection,
59
62
  filter: SQBAdapter.parseFilter(context.queryParams.filter),
@@ -67,6 +70,8 @@ export var SQBAdapter;
67
70
  };
68
71
  return { method: 'updateMany', data, options };
69
72
  }
73
+ default:
74
+ break;
70
75
  }
71
76
  }
72
77
  throw new Error(`This operation is not compatible to SQB Adapter`);