@opra/elastic 1.0.0-alpha.32 → 1.0.0-beta.2
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.
- package/cjs/adapter-utils/prepare-filter.js +88 -80
- package/cjs/adapter-utils/prepare-patch.js +35 -0
- package/cjs/adapter-utils/prepare-projection.js +65 -108
- package/cjs/adapter-utils/prepare-sort.js +5 -6
- package/cjs/elastic-adapter.js +4 -7
- package/cjs/elastic-collection-service.js +365 -0
- package/cjs/elastic-entity-service.js +392 -0
- package/cjs/elastic-service.js +20 -103
- package/cjs/index.js +3 -0
- package/esm/adapter-utils/prepare-filter.js +88 -80
- package/esm/adapter-utils/prepare-patch.js +32 -0
- package/esm/adapter-utils/prepare-projection.js +62 -109
- package/esm/adapter-utils/prepare-sort.js +5 -6
- package/esm/elastic-adapter.js +4 -7
- package/esm/elastic-collection-service.js +361 -0
- package/esm/elastic-entity-service.js +388 -0
- package/esm/elastic-service.js +20 -103
- package/esm/index.js +3 -0
- package/esm/package.json +3 -0
- package/package.json +27 -35
- package/types/adapter-utils/prepare-filter.d.ts +3 -2
- package/types/adapter-utils/prepare-patch.d.ts +2 -0
- package/types/adapter-utils/prepare-projection.d.ts +7 -0
- package/types/elastic-adapter.d.ts +7 -2
- package/types/elastic-collection-service.d.ts +217 -0
- package/types/elastic-entity-service.d.ts +262 -0
- package/types/elastic-service.d.ts +20 -99
- package/types/index.d.cts +4 -0
- package/types/index.d.ts +3 -0
- package/cjs/adapter-utils/prepare-key-values.js +0 -22
- package/esm/adapter-utils/prepare-key-values.js +0 -18
- package/types/adapter-utils/prepare-key-values.d.ts +0 -1
|
@@ -0,0 +1,392 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ElasticEntityService = void 0;
|
|
4
|
+
const common_1 = require("@opra/common");
|
|
5
|
+
const valgen_1 = require("valgen");
|
|
6
|
+
const elastic_adapter_js_1 = require("./elastic-adapter.js");
|
|
7
|
+
const elastic_service_js_1 = require("./elastic-service.js");
|
|
8
|
+
/**
|
|
9
|
+
* @class ElasticEntityService
|
|
10
|
+
* @template T - The type of the documents in the collection.
|
|
11
|
+
*/
|
|
12
|
+
class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
13
|
+
/**
|
|
14
|
+
* Constructs a new instance
|
|
15
|
+
*
|
|
16
|
+
* @param {Type | string} dataType - The data type of the array elements.
|
|
17
|
+
* @param {ElasticEntityService.Options} [options] - The options for the array service.
|
|
18
|
+
* @constructor
|
|
19
|
+
*/
|
|
20
|
+
constructor(dataType, options) {
|
|
21
|
+
super(options);
|
|
22
|
+
this._inputCodecs = {};
|
|
23
|
+
this._outputCodecs = {};
|
|
24
|
+
this._dataType_ = dataType;
|
|
25
|
+
if (options?.indexName)
|
|
26
|
+
this.indexName = options?.indexName;
|
|
27
|
+
else {
|
|
28
|
+
if (typeof dataType === 'string')
|
|
29
|
+
this.indexName = dataType;
|
|
30
|
+
if (typeof dataType === 'function') {
|
|
31
|
+
const metadata = Reflect.getMetadata(common_1.DATATYPE_METADATA, dataType);
|
|
32
|
+
if (metadata)
|
|
33
|
+
this.indexName = metadata.name;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
this.resourceName = options?.resourceName;
|
|
37
|
+
this.idGenerator = options?.idGenerator;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Retrieves the index name.
|
|
41
|
+
*
|
|
42
|
+
* @protected
|
|
43
|
+
* @returns The index name.
|
|
44
|
+
* @throws {Error} If the index name is not defined.
|
|
45
|
+
*/
|
|
46
|
+
getIndexName() {
|
|
47
|
+
const out = typeof this.indexName === 'function' ? this.indexName(this) : this.indexName;
|
|
48
|
+
if (out)
|
|
49
|
+
return out;
|
|
50
|
+
throw new Error('indexName is not defined');
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Retrieves the resource name.
|
|
54
|
+
*
|
|
55
|
+
* @protected
|
|
56
|
+
* @returns {string} The resource name.
|
|
57
|
+
* @throws {Error} If the resource name is not defined.
|
|
58
|
+
*/
|
|
59
|
+
getResourceName() {
|
|
60
|
+
const out = typeof this.resourceName === 'function' ? this.resourceName(this) : this.resourceName || this.getIndexName();
|
|
61
|
+
if (out)
|
|
62
|
+
return out;
|
|
63
|
+
throw new Error('resourceName is not defined');
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Retrieves the OPRA data type
|
|
67
|
+
*
|
|
68
|
+
* @throws {NotAcceptableError} If the data type is not a ComplexType.
|
|
69
|
+
*/
|
|
70
|
+
get dataType() {
|
|
71
|
+
if (!this._dataType)
|
|
72
|
+
this._dataType = this.context.document.node.getComplexType(this._dataType_);
|
|
73
|
+
return this._dataType;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Adds a JSON document to the specified data stream or index and makes it searchable.
|
|
77
|
+
* If the target is an index and the document already exists,
|
|
78
|
+
* the request updates the document and increments its version.
|
|
79
|
+
*
|
|
80
|
+
* @param {ElasticEntityService.CreateCommand} command
|
|
81
|
+
* @protected
|
|
82
|
+
*/
|
|
83
|
+
async _create(command) {
|
|
84
|
+
const input = command.input;
|
|
85
|
+
(0, valgen_1.isNotNullish)(input, { label: 'input' });
|
|
86
|
+
(0, valgen_1.isNotNullish)(input._id, { label: 'input._id' });
|
|
87
|
+
const inputCodec = this._getInputCodec('create');
|
|
88
|
+
const doc = inputCodec(input);
|
|
89
|
+
const { options } = command;
|
|
90
|
+
const request = {
|
|
91
|
+
...options?.request,
|
|
92
|
+
index: this.getIndexName(),
|
|
93
|
+
id: input._id,
|
|
94
|
+
document: doc,
|
|
95
|
+
};
|
|
96
|
+
const client = this.getClient();
|
|
97
|
+
const r = await client.create(request, options?.transport);
|
|
98
|
+
/* istanbul ignore next */
|
|
99
|
+
if (!(r._id && (r.result === 'created' || r.result === 'updated'))) {
|
|
100
|
+
throw new common_1.InternalServerError(`Unknown error while creating document for "${this.getResourceName()}"`);
|
|
101
|
+
}
|
|
102
|
+
return r;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Returns the count of documents in the collection based on the provided options.
|
|
106
|
+
*
|
|
107
|
+
* @param {ElasticEntityService.CountCommand} command
|
|
108
|
+
* @protected
|
|
109
|
+
*/
|
|
110
|
+
async _count(command) {
|
|
111
|
+
const { options } = command;
|
|
112
|
+
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([options?.filter, options?.request?.query]);
|
|
113
|
+
let query = {
|
|
114
|
+
...options?.request?.query,
|
|
115
|
+
...filterQuery,
|
|
116
|
+
};
|
|
117
|
+
if (!Object.keys(query).length)
|
|
118
|
+
query = undefined;
|
|
119
|
+
const request = {
|
|
120
|
+
index: this.getIndexName(),
|
|
121
|
+
...options?.request,
|
|
122
|
+
query,
|
|
123
|
+
};
|
|
124
|
+
const client = this.getClient();
|
|
125
|
+
return client.count(request, options?.transport);
|
|
126
|
+
}
|
|
127
|
+
/**
|
|
128
|
+
* Deletes a document from the collection.
|
|
129
|
+
*
|
|
130
|
+
* @param {ElasticEntityService.DeleteCommand} command
|
|
131
|
+
* @protected
|
|
132
|
+
*/
|
|
133
|
+
async _delete(command) {
|
|
134
|
+
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
135
|
+
const { options } = command;
|
|
136
|
+
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
137
|
+
{ ids: { values: [command.documentId] } },
|
|
138
|
+
options?.filter,
|
|
139
|
+
options?.request?.query,
|
|
140
|
+
]);
|
|
141
|
+
let query = {
|
|
142
|
+
...options?.request?.query,
|
|
143
|
+
...filterQuery,
|
|
144
|
+
};
|
|
145
|
+
if (!Object.keys(query).length)
|
|
146
|
+
query = { match_all: {} };
|
|
147
|
+
const request = {
|
|
148
|
+
index: this.getIndexName(),
|
|
149
|
+
...options?.request,
|
|
150
|
+
query,
|
|
151
|
+
};
|
|
152
|
+
const client = this.getClient();
|
|
153
|
+
return client.deleteByQuery(request, options?.transport);
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* Deletes multiple documents from the collection that meet the specified filter criteria.
|
|
157
|
+
*
|
|
158
|
+
* @param {ElasticEntityService.DeleteManyCommand} command
|
|
159
|
+
* @protected
|
|
160
|
+
*/
|
|
161
|
+
async _deleteMany(command) {
|
|
162
|
+
const { options } = command;
|
|
163
|
+
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([options?.filter, options?.request?.query]);
|
|
164
|
+
let query = {
|
|
165
|
+
...options?.request?.query,
|
|
166
|
+
...filterQuery,
|
|
167
|
+
};
|
|
168
|
+
if (!Object.keys(query).length)
|
|
169
|
+
query = { match_all: {} };
|
|
170
|
+
const request = {
|
|
171
|
+
...options?.request,
|
|
172
|
+
index: this.getIndexName(),
|
|
173
|
+
query,
|
|
174
|
+
};
|
|
175
|
+
const client = this.getClient();
|
|
176
|
+
return client.deleteByQuery(request, options?.transport);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* Returns search hits that match the query defined in the request
|
|
180
|
+
*
|
|
181
|
+
* @param {ElasticEntityService.SearchCommand} command
|
|
182
|
+
*/
|
|
183
|
+
async _search(command) {
|
|
184
|
+
const { options } = command;
|
|
185
|
+
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
186
|
+
command.documentId ? { ids: { values: [command.documentId] } } : undefined,
|
|
187
|
+
options?.filter,
|
|
188
|
+
options?.request?.query,
|
|
189
|
+
]);
|
|
190
|
+
let query = {
|
|
191
|
+
...options?.request?.query,
|
|
192
|
+
...filterQuery,
|
|
193
|
+
};
|
|
194
|
+
if (!Object.keys(query).length)
|
|
195
|
+
query = { match_all: {} };
|
|
196
|
+
const request = {
|
|
197
|
+
from: options?.skip,
|
|
198
|
+
size: options?.limit,
|
|
199
|
+
sort: options?.sort ? elastic_adapter_js_1.ElasticAdapter.prepareSort(options?.sort) : undefined,
|
|
200
|
+
_source: elastic_adapter_js_1.ElasticAdapter.prepareProjection(this.dataType, options?.projection),
|
|
201
|
+
index: this.getIndexName(),
|
|
202
|
+
...options?.request,
|
|
203
|
+
query,
|
|
204
|
+
};
|
|
205
|
+
const client = this.getClient();
|
|
206
|
+
return client.search(request, options?.transport);
|
|
207
|
+
}
|
|
208
|
+
/**
|
|
209
|
+
* Updates multiple documents in the collection based on the specified input and options.
|
|
210
|
+
*
|
|
211
|
+
* @param {ElasticEntityService.UpdateCommand<T>} command
|
|
212
|
+
*/
|
|
213
|
+
async _updateMany(command) {
|
|
214
|
+
if (command.byId)
|
|
215
|
+
(0, valgen_1.isNotNullish)(command.documentId, { label: 'documentId' });
|
|
216
|
+
const { options } = command;
|
|
217
|
+
const input = command.input;
|
|
218
|
+
const requestScript = command.options?.request?.script;
|
|
219
|
+
let script;
|
|
220
|
+
const inputKeysLen = Object.keys(input).length;
|
|
221
|
+
(0, valgen_1.isNotNullish)(inputKeysLen || script, { label: 'input' });
|
|
222
|
+
if (requestScript) {
|
|
223
|
+
script = typeof requestScript === 'string' ? { source: requestScript } : { ...requestScript };
|
|
224
|
+
script.lang = script.lang || 'painless';
|
|
225
|
+
if (inputKeysLen > 0 && script.lang !== 'painless') {
|
|
226
|
+
throw new TypeError(`You cannot provide 'input' and 'script' arguments at the same time unless the script lang is 'painless'`);
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if (inputKeysLen) {
|
|
230
|
+
delete input._id;
|
|
231
|
+
const inputCodec = this._getInputCodec('update');
|
|
232
|
+
const doc = inputCodec(input);
|
|
233
|
+
const scr = elastic_adapter_js_1.ElasticAdapter.preparePatch(doc);
|
|
234
|
+
if (script) {
|
|
235
|
+
script.source = (script.source ? script.source + '\n' + script.source : '') + scr.source;
|
|
236
|
+
script.params = { ...script.params, ...scr.params };
|
|
237
|
+
}
|
|
238
|
+
else
|
|
239
|
+
script = scr;
|
|
240
|
+
}
|
|
241
|
+
script.source = script?.source || 'return;';
|
|
242
|
+
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
243
|
+
command.byId ? { ids: { values: [command.documentId] } } : undefined,
|
|
244
|
+
options?.filter,
|
|
245
|
+
options?.request?.query,
|
|
246
|
+
]);
|
|
247
|
+
let query = {
|
|
248
|
+
...options?.request?.query,
|
|
249
|
+
...filterQuery,
|
|
250
|
+
};
|
|
251
|
+
if (!Object.keys(query).length)
|
|
252
|
+
query = { match_all: {} };
|
|
253
|
+
const request = {
|
|
254
|
+
...options?.request,
|
|
255
|
+
index: this.getIndexName(),
|
|
256
|
+
script,
|
|
257
|
+
query,
|
|
258
|
+
};
|
|
259
|
+
const client = this.getClient();
|
|
260
|
+
return client.updateByQuery(request, options?.transport);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Generates an ID.
|
|
264
|
+
*
|
|
265
|
+
* @protected
|
|
266
|
+
* @returns The generated ID.
|
|
267
|
+
*/
|
|
268
|
+
_generateId(command) {
|
|
269
|
+
return typeof this.idGenerator === 'function' ? this.idGenerator(command, this) : undefined;
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Retrieves the codec for the specified operation.
|
|
273
|
+
*
|
|
274
|
+
* @param operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
|
|
275
|
+
*/
|
|
276
|
+
_getInputCodec(operation) {
|
|
277
|
+
let validator = this._inputCodecs[operation];
|
|
278
|
+
if (validator)
|
|
279
|
+
return validator;
|
|
280
|
+
const options = { projection: '*' };
|
|
281
|
+
if (operation === 'update')
|
|
282
|
+
options.partial = 'deep';
|
|
283
|
+
const dataType = this.dataType;
|
|
284
|
+
validator = dataType.generateCodec('decode', options);
|
|
285
|
+
this._inputCodecs[operation] = validator;
|
|
286
|
+
return validator;
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Retrieves the codec.
|
|
290
|
+
*/
|
|
291
|
+
_getOutputCodec(operation) {
|
|
292
|
+
let validator = this._outputCodecs[operation];
|
|
293
|
+
if (validator)
|
|
294
|
+
return validator;
|
|
295
|
+
const options = { projection: '*', partial: 'deep' };
|
|
296
|
+
const dataType = this.dataType;
|
|
297
|
+
validator = dataType.generateCodec('decode', options);
|
|
298
|
+
this._outputCodecs[operation] = validator;
|
|
299
|
+
return validator;
|
|
300
|
+
}
|
|
301
|
+
async _executeCommand(command, commandFn) {
|
|
302
|
+
try {
|
|
303
|
+
const result = await super._executeCommand(command, async () => {
|
|
304
|
+
/** Call before[X] hooks */
|
|
305
|
+
if (command.crud === 'create')
|
|
306
|
+
await this._beforeCreate(command);
|
|
307
|
+
else if (command.crud === 'update' && command.byId) {
|
|
308
|
+
await this._beforeUpdate(command);
|
|
309
|
+
}
|
|
310
|
+
else if (command.crud === 'update' && !command.byId) {
|
|
311
|
+
await this._beforeUpdateMany(command);
|
|
312
|
+
}
|
|
313
|
+
else if (command.crud === 'delete' && command.byId) {
|
|
314
|
+
await this._beforeDelete(command);
|
|
315
|
+
}
|
|
316
|
+
else if (command.crud === 'delete' && !command.byId) {
|
|
317
|
+
await this._beforeDeleteMany(command);
|
|
318
|
+
}
|
|
319
|
+
/** Call command function */
|
|
320
|
+
return commandFn();
|
|
321
|
+
});
|
|
322
|
+
/** Call after[X] hooks */
|
|
323
|
+
if (command.crud === 'create')
|
|
324
|
+
await this._afterCreate(command, result);
|
|
325
|
+
else if (command.crud === 'update' && command.byId) {
|
|
326
|
+
await this._afterUpdate(command, result);
|
|
327
|
+
}
|
|
328
|
+
else if (command.crud === 'update' && !command.byId) {
|
|
329
|
+
await this._afterUpdateMany(command, result);
|
|
330
|
+
}
|
|
331
|
+
else if (command.crud === 'delete' && command.byId) {
|
|
332
|
+
await this._afterDelete(command, result);
|
|
333
|
+
}
|
|
334
|
+
else if (command.crud === 'delete' && !command.byId) {
|
|
335
|
+
await this._afterDeleteMany(command, result);
|
|
336
|
+
}
|
|
337
|
+
return result;
|
|
338
|
+
}
|
|
339
|
+
catch (e) {
|
|
340
|
+
Error.captureStackTrace(e, this._executeCommand);
|
|
341
|
+
await this.onError?.(e, this);
|
|
342
|
+
throw e;
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
346
|
+
async _beforeCreate(command) {
|
|
347
|
+
// Do nothing
|
|
348
|
+
}
|
|
349
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
350
|
+
async _beforeUpdate(command) {
|
|
351
|
+
// Do nothing
|
|
352
|
+
}
|
|
353
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
354
|
+
async _beforeUpdateMany(command) {
|
|
355
|
+
// Do nothing
|
|
356
|
+
}
|
|
357
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
358
|
+
async _beforeDelete(command) {
|
|
359
|
+
// Do nothing
|
|
360
|
+
}
|
|
361
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
362
|
+
async _beforeDeleteMany(command) {
|
|
363
|
+
// Do nothing
|
|
364
|
+
}
|
|
365
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
366
|
+
async _afterCreate(command, result) {
|
|
367
|
+
// Do nothing
|
|
368
|
+
}
|
|
369
|
+
async _afterUpdate(
|
|
370
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
371
|
+
command,
|
|
372
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
373
|
+
result) {
|
|
374
|
+
// Do nothing
|
|
375
|
+
}
|
|
376
|
+
async _afterUpdateMany(
|
|
377
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
378
|
+
command,
|
|
379
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
380
|
+
affected) {
|
|
381
|
+
// Do nothing
|
|
382
|
+
}
|
|
383
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
384
|
+
async _afterDelete(command, affected) {
|
|
385
|
+
// Do nothing
|
|
386
|
+
}
|
|
387
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
388
|
+
async _afterDeleteMany(command, affected) {
|
|
389
|
+
// Do nothing
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
exports.ElasticEntityService = ElasticEntityService;
|
package/cjs/elastic-service.js
CHANGED
|
@@ -11,88 +11,14 @@ class ElasticService extends core_1.ServiceBase {
|
|
|
11
11
|
/**
|
|
12
12
|
* Constructs a new instance
|
|
13
13
|
*
|
|
14
|
-
* @param dataType - The data type of the returning results
|
|
15
|
-
* @param indexName - The name of the index, or a function that returns the index name
|
|
16
14
|
* @param [options] - The options for the service
|
|
17
15
|
* @constructor
|
|
18
16
|
*/
|
|
19
|
-
constructor(
|
|
17
|
+
constructor(options) {
|
|
20
18
|
super();
|
|
21
|
-
this.
|
|
22
|
-
this._outputCodecs = {};
|
|
23
|
-
this._dataType_ = dataType;
|
|
19
|
+
this.interceptor = options?.interceptor;
|
|
24
20
|
this.client = options?.client;
|
|
25
|
-
this
|
|
26
|
-
this.$interceptor = this.$interceptor || options?.interceptor;
|
|
27
|
-
this.$indexName = indexName;
|
|
28
|
-
this.$resourceName = options?.resourceName;
|
|
29
|
-
this.$idGenerator = options?.idGenerator;
|
|
30
|
-
}
|
|
31
|
-
/**
|
|
32
|
-
* Retrieves the index name.
|
|
33
|
-
*
|
|
34
|
-
* @protected
|
|
35
|
-
* @returns The index name.
|
|
36
|
-
* @throws {Error} If the index name is not defined.
|
|
37
|
-
*/
|
|
38
|
-
getIndexName() {
|
|
39
|
-
const out = typeof this.$indexName === 'function' ? this.$indexName(this) : this.$indexName;
|
|
40
|
-
if (out)
|
|
41
|
-
return out;
|
|
42
|
-
throw new Error('indexName is not defined');
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Retrieves the resource name.
|
|
46
|
-
*
|
|
47
|
-
* @protected
|
|
48
|
-
* @returns {string} The resource name.
|
|
49
|
-
* @throws {Error} If the resource name is not defined.
|
|
50
|
-
*/
|
|
51
|
-
getResourceName() {
|
|
52
|
-
const out = typeof this.$resourceName === 'function' ? this.$resourceName(this) : this.$resourceName || this.getIndexName();
|
|
53
|
-
if (out)
|
|
54
|
-
return out;
|
|
55
|
-
throw new Error('resourceName is not defined');
|
|
56
|
-
}
|
|
57
|
-
/**
|
|
58
|
-
* Retrieves the OPRA data type
|
|
59
|
-
*
|
|
60
|
-
* @throws {NotAcceptableError} If the data type is not a ComplexType.
|
|
61
|
-
*/
|
|
62
|
-
get dataType() {
|
|
63
|
-
if (!this._dataType)
|
|
64
|
-
this._dataType = this.context.document.node.getComplexType(this._dataType_);
|
|
65
|
-
return this._dataType;
|
|
66
|
-
}
|
|
67
|
-
/**
|
|
68
|
-
* Retrieves the codec for the specified operation.
|
|
69
|
-
*
|
|
70
|
-
* @param operation - The operation to retrieve the encoder for. Valid values are 'create' and 'update'.
|
|
71
|
-
*/
|
|
72
|
-
getInputCodec(operation) {
|
|
73
|
-
let validator = this._inputCodecs[operation];
|
|
74
|
-
if (validator)
|
|
75
|
-
return validator;
|
|
76
|
-
const options = { projection: '*' };
|
|
77
|
-
if (operation === 'update')
|
|
78
|
-
options.partial = 'deep';
|
|
79
|
-
const dataType = this.dataType;
|
|
80
|
-
validator = dataType.generateCodec('decode', options);
|
|
81
|
-
this._inputCodecs[operation] = validator;
|
|
82
|
-
return validator;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Retrieves the codec.
|
|
86
|
-
*/
|
|
87
|
-
getOutputCodec(operation) {
|
|
88
|
-
let validator = this._outputCodecs[operation];
|
|
89
|
-
if (validator)
|
|
90
|
-
return validator;
|
|
91
|
-
const options = { projection: '*', partial: 'deep' };
|
|
92
|
-
const dataType = this.dataType;
|
|
93
|
-
validator = dataType.generateCodec('decode', options);
|
|
94
|
-
this._outputCodecs[operation] = validator;
|
|
95
|
-
return validator;
|
|
21
|
+
this.onError = options?.onError;
|
|
96
22
|
}
|
|
97
23
|
/**
|
|
98
24
|
* Retrieves the ElasticSearch client.
|
|
@@ -108,35 +34,26 @@ class ElasticService extends core_1.ServiceBase {
|
|
|
108
34
|
throw new Error(`Client not set!`);
|
|
109
35
|
return db;
|
|
110
36
|
}
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
* @returns {QueryDslQueryContainer | Promise<QueryDslQueryContainer> | undefined} The common filter or a Promise
|
|
126
|
-
* that resolves to the common filter, or undefined if not available.
|
|
127
|
-
*/
|
|
128
|
-
_getCommonFilter(info) {
|
|
129
|
-
return typeof this.$commonFilter === 'function' ? this.$commonFilter(info, this) : this.$commonFilter;
|
|
130
|
-
}
|
|
131
|
-
async _intercept(callback, info) {
|
|
37
|
+
async _executeCommand(command, commandFn) {
|
|
38
|
+
let proto;
|
|
39
|
+
const next = async () => {
|
|
40
|
+
proto = proto ? Object.getPrototypeOf(proto) : this;
|
|
41
|
+
while (proto) {
|
|
42
|
+
if (proto.interceptor && Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
|
|
43
|
+
return await proto.interceptor.call(this, next, command, this);
|
|
44
|
+
}
|
|
45
|
+
proto = Object.getPrototypeOf(proto);
|
|
46
|
+
if (!(proto instanceof ElasticService))
|
|
47
|
+
break;
|
|
48
|
+
}
|
|
49
|
+
return commandFn();
|
|
50
|
+
};
|
|
132
51
|
try {
|
|
133
|
-
|
|
134
|
-
return this.$interceptor(callback, info, this);
|
|
135
|
-
return callback();
|
|
52
|
+
return await next();
|
|
136
53
|
}
|
|
137
54
|
catch (e) {
|
|
138
|
-
Error.captureStackTrace(e, this.
|
|
139
|
-
await this
|
|
55
|
+
Error.captureStackTrace(e, this._executeCommand);
|
|
56
|
+
await this.onError?.(e, this);
|
|
140
57
|
throw e;
|
|
141
58
|
}
|
|
142
59
|
}
|
package/cjs/index.js
CHANGED
|
@@ -2,3 +2,6 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const tslib_1 = require("tslib");
|
|
4
4
|
tslib_1.__exportStar(require("./elastic-adapter.js"), exports);
|
|
5
|
+
tslib_1.__exportStar(require("./elastic-collection-service.js"), exports);
|
|
6
|
+
tslib_1.__exportStar(require("./elastic-entity-service.js"), exports);
|
|
7
|
+
tslib_1.__exportStar(require("./elastic-service.js"), exports);
|