@opra/elastic 1.4.3 → 1.4.4
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 +15 -5
- package/cjs/adapter-utils/prepare-projection.js +5 -2
- package/cjs/elastic-adapter.js +37 -10
- package/cjs/elastic-collection-service.js +57 -17
- package/cjs/elastic-entity-service.js +56 -18
- package/cjs/elastic-service.js +5 -2
- package/esm/adapter-utils/prepare-filter.js +15 -5
- package/esm/adapter-utils/prepare-projection.js +6 -3
- package/esm/elastic-adapter.js +37 -10
- package/esm/elastic-collection-service.js +57 -17
- package/esm/elastic-entity-service.js +57 -19
- package/esm/elastic-service.js +5 -2
- package/package.json +3 -3
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.default = prepareFilter;
|
|
4
|
-
/* eslint-disable camelcase */
|
|
5
4
|
require("@opra/core");
|
|
6
5
|
const common_1 = require("@opra/common");
|
|
7
6
|
function prepareFilter(filters) {
|
|
@@ -54,7 +53,8 @@ function prepareFilterAst(ast, negative) {
|
|
|
54
53
|
return prepareFilterAst(ast.expression, negative);
|
|
55
54
|
}
|
|
56
55
|
if (ast instanceof common_1.OpraFilter.ComparisonExpression) {
|
|
57
|
-
if (!(ast.left instanceof common_1.OpraFilter.QualifiedIdentifier ||
|
|
56
|
+
if (!(ast.left instanceof common_1.OpraFilter.QualifiedIdentifier ||
|
|
57
|
+
ast.left instanceof common_1.OpraFilter.StringLiteral)) {
|
|
58
58
|
throw new Error('Left side of ComparisonExpression must be a QualifiedIdentifier');
|
|
59
59
|
}
|
|
60
60
|
const left = prepareFilterAst(ast.left);
|
|
@@ -91,12 +91,21 @@ function prepareFilterAst(ast, negative) {
|
|
|
91
91
|
}
|
|
92
92
|
case '!like':
|
|
93
93
|
case 'like': {
|
|
94
|
-
out = {
|
|
94
|
+
out = {
|
|
95
|
+
wildcard: { [left]: { value: String(right).replace(/%/g, '*') } },
|
|
96
|
+
};
|
|
95
97
|
break;
|
|
96
98
|
}
|
|
97
99
|
case '!ilike':
|
|
98
100
|
case 'ilike': {
|
|
99
|
-
out = {
|
|
101
|
+
out = {
|
|
102
|
+
wildcard: {
|
|
103
|
+
[left]: {
|
|
104
|
+
value: String(right).replace(/%/g, '*'),
|
|
105
|
+
case_insensitive: true,
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
};
|
|
100
109
|
break;
|
|
101
110
|
}
|
|
102
111
|
default:
|
|
@@ -104,7 +113,8 @@ function prepareFilterAst(ast, negative) {
|
|
|
104
113
|
throw new TypeError(`Unknown ComparisonExpression operation (${ast.op})`);
|
|
105
114
|
}
|
|
106
115
|
}
|
|
107
|
-
if ((ast.op.startsWith('!') && !negative) ||
|
|
116
|
+
if ((ast.op.startsWith('!') && !negative) ||
|
|
117
|
+
(!ast.op.startsWith('!') && negative)) {
|
|
108
118
|
return { bool: { must_not: { ...out } } };
|
|
109
119
|
}
|
|
110
120
|
return out;
|
|
@@ -7,7 +7,9 @@ function prepareProjection(dataType, projection) {
|
|
|
7
7
|
const out = {};
|
|
8
8
|
const includes = [];
|
|
9
9
|
const excludes = [];
|
|
10
|
-
const projection_ = typeof projection === 'string' || Array.isArray(projection)
|
|
10
|
+
const projection_ = typeof projection === 'string' || Array.isArray(projection)
|
|
11
|
+
? (0, common_1.parseFieldsProjection)(projection)
|
|
12
|
+
: projection;
|
|
11
13
|
prepare(dataType, includes, excludes, '', projection_);
|
|
12
14
|
if (includes.length)
|
|
13
15
|
out.includes = includes;
|
|
@@ -47,7 +49,8 @@ function prepare(dataType, includes, excludes, curPath, projection) {
|
|
|
47
49
|
includes.push(fieldPath);
|
|
48
50
|
}
|
|
49
51
|
}
|
|
50
|
-
if (field.type instanceof common_1.ComplexType &&
|
|
52
|
+
if (field.type instanceof common_1.ComplexType &&
|
|
53
|
+
typeof p?.projection === 'object') {
|
|
51
54
|
prepare(field.type, includes, excludes, fieldPath, p.projection);
|
|
52
55
|
}
|
|
53
56
|
}
|
package/cjs/elastic-adapter.js
CHANGED
|
@@ -18,7 +18,8 @@ var ElasticAdapter;
|
|
|
18
18
|
}
|
|
19
19
|
const ctx = context;
|
|
20
20
|
const { operation } = ctx;
|
|
21
|
-
if (operation?.composition?.startsWith('Entity.') &&
|
|
21
|
+
if (operation?.composition?.startsWith('Entity.') &&
|
|
22
|
+
operation.compositionOptions?.type) {
|
|
22
23
|
const controller = operation.owner;
|
|
23
24
|
switch (operation.composition) {
|
|
24
25
|
case 'Entity.Create': {
|
|
@@ -26,15 +27,24 @@ var ElasticAdapter;
|
|
|
26
27
|
const options = {
|
|
27
28
|
projection: ctx.queryParams.projection,
|
|
28
29
|
};
|
|
29
|
-
return {
|
|
30
|
+
return {
|
|
31
|
+
method: 'create',
|
|
32
|
+
data,
|
|
33
|
+
options,
|
|
34
|
+
};
|
|
30
35
|
}
|
|
31
36
|
case 'Entity.Delete': {
|
|
32
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
37
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
38
|
+
controller.parameters.find(p => p.keyParam);
|
|
33
39
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
34
40
|
const options = {
|
|
35
41
|
filter: ctx.queryParams.filter,
|
|
36
42
|
};
|
|
37
|
-
return {
|
|
43
|
+
return {
|
|
44
|
+
method: 'delete',
|
|
45
|
+
key,
|
|
46
|
+
options,
|
|
47
|
+
};
|
|
38
48
|
}
|
|
39
49
|
case 'Entity.DeleteMany': {
|
|
40
50
|
const options = {
|
|
@@ -54,7 +64,8 @@ var ElasticAdapter;
|
|
|
54
64
|
return { method: 'findMany', options };
|
|
55
65
|
}
|
|
56
66
|
case 'Entity.Get': {
|
|
57
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
67
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
68
|
+
controller.parameters.find(p => p.keyParam);
|
|
58
69
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
59
70
|
const options = {
|
|
60
71
|
projection: ctx.queryParams.projection,
|
|
@@ -64,30 +75,46 @@ var ElasticAdapter;
|
|
|
64
75
|
}
|
|
65
76
|
case 'Entity.Replace': {
|
|
66
77
|
const data = await ctx.getBody();
|
|
67
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
78
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
79
|
+
controller.parameters.find(p => p.keyParam);
|
|
68
80
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
69
81
|
const options = {
|
|
70
82
|
projection: ctx.queryParams.projection,
|
|
71
83
|
filter: ctx.queryParams.filter,
|
|
72
84
|
};
|
|
73
|
-
return {
|
|
85
|
+
return {
|
|
86
|
+
method: 'replace',
|
|
87
|
+
key,
|
|
88
|
+
data,
|
|
89
|
+
options,
|
|
90
|
+
};
|
|
74
91
|
}
|
|
75
92
|
case 'Entity.Update': {
|
|
76
93
|
const data = await ctx.getBody();
|
|
77
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
94
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
95
|
+
controller.parameters.find(p => p.keyParam);
|
|
78
96
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
79
97
|
const options = {
|
|
80
98
|
projection: ctx.queryParams.projection,
|
|
81
99
|
filter: ctx.queryParams.filter,
|
|
82
100
|
};
|
|
83
|
-
return {
|
|
101
|
+
return {
|
|
102
|
+
method: 'update',
|
|
103
|
+
key,
|
|
104
|
+
data,
|
|
105
|
+
options,
|
|
106
|
+
};
|
|
84
107
|
}
|
|
85
108
|
case 'Entity.UpdateMany': {
|
|
86
109
|
const data = await ctx.getBody();
|
|
87
110
|
const options = {
|
|
88
111
|
filter: ctx.queryParams.filter,
|
|
89
112
|
};
|
|
90
|
-
return {
|
|
113
|
+
return {
|
|
114
|
+
method: 'updateMany',
|
|
115
|
+
data,
|
|
116
|
+
options,
|
|
117
|
+
};
|
|
91
118
|
}
|
|
92
119
|
default:
|
|
93
120
|
break;
|
|
@@ -24,10 +24,12 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
24
24
|
for(context, overwriteProperties, overwriteContext) {
|
|
25
25
|
if (overwriteProperties?.documentFilter && this.documentFilter) {
|
|
26
26
|
overwriteProperties.documentFilter = [
|
|
27
|
-
...(Array.isArray(this.documentFilter)
|
|
27
|
+
...(Array.isArray(this.documentFilter)
|
|
28
|
+
? this.documentFilter
|
|
29
|
+
: [this.documentFilter]),
|
|
28
30
|
...(Array.isArray(overwriteProperties?.documentFilter)
|
|
29
|
-
? overwriteProperties
|
|
30
|
-
: [overwriteProperties
|
|
31
|
+
? overwriteProperties.documentFilter
|
|
32
|
+
: [overwriteProperties.documentFilter]),
|
|
31
33
|
];
|
|
32
34
|
}
|
|
33
35
|
return super.for(context, overwriteProperties, overwriteContext);
|
|
@@ -62,7 +64,9 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
62
64
|
options,
|
|
63
65
|
};
|
|
64
66
|
command.input._id =
|
|
65
|
-
command.input._id == null || command.input._id === ''
|
|
67
|
+
command.input._id == null || command.input._id === ''
|
|
68
|
+
? this._generateId(command)
|
|
69
|
+
: command.input._id;
|
|
66
70
|
return this._executeCommand(command, () => this._create(command));
|
|
67
71
|
}
|
|
68
72
|
/**
|
|
@@ -79,7 +83,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
79
83
|
options,
|
|
80
84
|
};
|
|
81
85
|
return this._executeCommand(command, async () => {
|
|
82
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
86
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
87
|
+
await this._getDocumentFilter(command),
|
|
88
|
+
command.options?.filter,
|
|
89
|
+
]);
|
|
83
90
|
command.options = { ...command.options, filter };
|
|
84
91
|
const r = await this._count(command);
|
|
85
92
|
return r.count;
|
|
@@ -101,7 +108,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
101
108
|
options,
|
|
102
109
|
};
|
|
103
110
|
return this._executeCommand(command, async () => {
|
|
104
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
111
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
112
|
+
await this._getDocumentFilter(command),
|
|
113
|
+
command.options?.filter,
|
|
114
|
+
]);
|
|
105
115
|
command.options = { ...command.options, filter };
|
|
106
116
|
return this._delete(command);
|
|
107
117
|
});
|
|
@@ -120,7 +130,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
120
130
|
options,
|
|
121
131
|
};
|
|
122
132
|
return this._executeCommand(command, async () => {
|
|
123
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
133
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
134
|
+
await this._getDocumentFilter(command),
|
|
135
|
+
command.options?.filter,
|
|
136
|
+
]);
|
|
124
137
|
command.options = { ...command.options, filter };
|
|
125
138
|
return this._deleteMany(command);
|
|
126
139
|
});
|
|
@@ -146,10 +159,15 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
146
159
|
terminate_after: 1,
|
|
147
160
|
size: 0,
|
|
148
161
|
};
|
|
149
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
162
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
163
|
+
await this._getDocumentFilter(command),
|
|
164
|
+
command.options?.filter,
|
|
165
|
+
]);
|
|
150
166
|
command.options = { ...options, request, filter };
|
|
151
167
|
const r = await this._search(command);
|
|
152
|
-
return !!(typeof r.hits.total === 'number'
|
|
168
|
+
return !!(typeof r.hits.total === 'number'
|
|
169
|
+
? r.hits.total
|
|
170
|
+
: r.hits.total?.value);
|
|
153
171
|
});
|
|
154
172
|
}
|
|
155
173
|
/**
|
|
@@ -173,7 +191,9 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
173
191
|
};
|
|
174
192
|
command.options = { ...options, request };
|
|
175
193
|
const r = await this._search(command);
|
|
176
|
-
return !!(typeof r.hits.total === 'number'
|
|
194
|
+
return !!(typeof r.hits.total === 'number'
|
|
195
|
+
? r.hits.total
|
|
196
|
+
: r.hits.total?.value);
|
|
177
197
|
});
|
|
178
198
|
}
|
|
179
199
|
/**
|
|
@@ -189,7 +209,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
189
209
|
};
|
|
190
210
|
return this._executeCommand(command, async () => {
|
|
191
211
|
const documentFilter = await this._getDocumentFilter(command);
|
|
192
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
212
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
213
|
+
documentFilter,
|
|
214
|
+
command.options?.filter,
|
|
215
|
+
]);
|
|
193
216
|
const newCommand = {
|
|
194
217
|
...command,
|
|
195
218
|
limit: 1,
|
|
@@ -216,7 +239,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
216
239
|
options,
|
|
217
240
|
};
|
|
218
241
|
return this._executeCommand(command, async () => {
|
|
219
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
242
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
243
|
+
await this._getDocumentFilter(command),
|
|
244
|
+
command.options?.filter,
|
|
245
|
+
]);
|
|
220
246
|
const newCommand = {
|
|
221
247
|
...command,
|
|
222
248
|
limit: 1,
|
|
@@ -243,7 +269,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
243
269
|
options,
|
|
244
270
|
};
|
|
245
271
|
return this._executeCommand(command, async () => {
|
|
246
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
272
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
273
|
+
await this._getDocumentFilter(command),
|
|
274
|
+
command.options?.filter,
|
|
275
|
+
]);
|
|
247
276
|
const limit = command.options?.limit || this.defaultLimit;
|
|
248
277
|
command.options = { ...command.options, filter, limit };
|
|
249
278
|
const r = await this._search(command);
|
|
@@ -268,7 +297,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
268
297
|
options,
|
|
269
298
|
};
|
|
270
299
|
return this._executeCommand(command, async () => {
|
|
271
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
300
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
301
|
+
await this._getDocumentFilter(command),
|
|
302
|
+
command.options?.filter,
|
|
303
|
+
]);
|
|
272
304
|
const limit = command.options?.limit || this.defaultLimit;
|
|
273
305
|
command.options = {
|
|
274
306
|
...command.options,
|
|
@@ -323,7 +355,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
323
355
|
options,
|
|
324
356
|
};
|
|
325
357
|
return this._executeCommand(command, async () => {
|
|
326
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
358
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
359
|
+
await this._getDocumentFilter(command),
|
|
360
|
+
command.options?.filter,
|
|
361
|
+
]);
|
|
327
362
|
command.options = { ...command.options, filter };
|
|
328
363
|
return await this._updateMany(command);
|
|
329
364
|
});
|
|
@@ -344,7 +379,10 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
344
379
|
options,
|
|
345
380
|
};
|
|
346
381
|
return this._executeCommand(command, async () => {
|
|
347
|
-
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
382
|
+
const filter = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
383
|
+
await this._getDocumentFilter(command),
|
|
384
|
+
command.options?.filter,
|
|
385
|
+
]);
|
|
348
386
|
command.options = { ...command.options, filter };
|
|
349
387
|
return this._updateMany(command);
|
|
350
388
|
});
|
|
@@ -358,7 +396,9 @@ class ElasticCollectionService extends elastic_entity_service_js_1.ElasticEntity
|
|
|
358
396
|
* that resolves to the common filter, or undefined if not available.
|
|
359
397
|
*/
|
|
360
398
|
_getDocumentFilter(command) {
|
|
361
|
-
const commonFilter = Array.isArray(this.documentFilter)
|
|
399
|
+
const commonFilter = Array.isArray(this.documentFilter)
|
|
400
|
+
? this.documentFilter
|
|
401
|
+
: [this.documentFilter];
|
|
362
402
|
const mapped = commonFilter.map(f => typeof f === 'function' ? f(command, this) : f);
|
|
363
403
|
return mapped.length > 1 ? elastic_adapter_js_1.ElasticAdapter.prepareFilter(mapped) : mapped[0];
|
|
364
404
|
}
|
|
@@ -44,7 +44,9 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
44
44
|
* @throws {Error} If the index name is not defined.
|
|
45
45
|
*/
|
|
46
46
|
getIndexName() {
|
|
47
|
-
const out = typeof this.indexName === 'function'
|
|
47
|
+
const out = typeof this.indexName === 'function'
|
|
48
|
+
? this.indexName(this)
|
|
49
|
+
: this.indexName;
|
|
48
50
|
if (out)
|
|
49
51
|
return out;
|
|
50
52
|
throw new Error('indexName is not defined');
|
|
@@ -57,7 +59,9 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
57
59
|
* @throws {Error} If the resource name is not defined.
|
|
58
60
|
*/
|
|
59
61
|
getResourceName() {
|
|
60
|
-
const out = typeof this.resourceName === 'function'
|
|
62
|
+
const out = typeof this.resourceName === 'function'
|
|
63
|
+
? this.resourceName(this)
|
|
64
|
+
: this.resourceName || this.getIndexName();
|
|
61
65
|
if (out)
|
|
62
66
|
return out;
|
|
63
67
|
throw new Error('resourceName is not defined');
|
|
@@ -110,7 +114,10 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
110
114
|
*/
|
|
111
115
|
async _count(command) {
|
|
112
116
|
const { options } = command;
|
|
113
|
-
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
117
|
+
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
118
|
+
options?.filter,
|
|
119
|
+
options?.request?.query,
|
|
120
|
+
]);
|
|
114
121
|
let query = {
|
|
115
122
|
...options?.request?.query,
|
|
116
123
|
...filterQuery,
|
|
@@ -161,7 +168,10 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
161
168
|
*/
|
|
162
169
|
async _deleteMany(command) {
|
|
163
170
|
const { options } = command;
|
|
164
|
-
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
171
|
+
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
172
|
+
options?.filter,
|
|
173
|
+
options?.request?.query,
|
|
174
|
+
]);
|
|
165
175
|
let query = {
|
|
166
176
|
...options?.request?.query,
|
|
167
177
|
...filterQuery,
|
|
@@ -184,7 +194,9 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
184
194
|
async _search(command) {
|
|
185
195
|
const { options } = command;
|
|
186
196
|
const filterQuery = elastic_adapter_js_1.ElasticAdapter.prepareFilter([
|
|
187
|
-
command.documentId
|
|
197
|
+
command.documentId
|
|
198
|
+
? { ids: { values: [command.documentId] } }
|
|
199
|
+
: undefined,
|
|
188
200
|
options?.filter,
|
|
189
201
|
options?.request?.query,
|
|
190
202
|
]);
|
|
@@ -197,7 +209,9 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
197
209
|
const request = {
|
|
198
210
|
from: options?.skip,
|
|
199
211
|
size: options?.limit,
|
|
200
|
-
sort: options?.sort
|
|
212
|
+
sort: options?.sort
|
|
213
|
+
? elastic_adapter_js_1.ElasticAdapter.prepareSort(options?.sort)
|
|
214
|
+
: undefined,
|
|
201
215
|
_source: elastic_adapter_js_1.ElasticAdapter.prepareProjection(this.dataType, options?.projection),
|
|
202
216
|
index: this.getIndexName(),
|
|
203
217
|
...options?.request,
|
|
@@ -221,7 +235,10 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
221
235
|
const inputKeysLen = Object.keys(input).length;
|
|
222
236
|
(0, valgen_1.isNotNullish)(inputKeysLen || script, { label: 'input' });
|
|
223
237
|
if (requestScript) {
|
|
224
|
-
script =
|
|
238
|
+
script =
|
|
239
|
+
typeof requestScript === 'string'
|
|
240
|
+
? { source: requestScript }
|
|
241
|
+
: { ...requestScript };
|
|
225
242
|
script.lang = script.lang || 'painless';
|
|
226
243
|
if (inputKeysLen > 0 && script.lang !== 'painless') {
|
|
227
244
|
throw new TypeError(`You cannot provide 'input' and 'script' arguments at the same time unless the script lang is 'painless'`);
|
|
@@ -233,7 +250,9 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
233
250
|
const doc = inputCodec(input);
|
|
234
251
|
const scr = elastic_adapter_js_1.ElasticAdapter.preparePatch(doc);
|
|
235
252
|
if (script) {
|
|
236
|
-
script.source =
|
|
253
|
+
script.source =
|
|
254
|
+
(script.source ? script.source + '\n' + script.source : '') +
|
|
255
|
+
scr.source;
|
|
237
256
|
script.params = { ...script.params, ...scr.params };
|
|
238
257
|
}
|
|
239
258
|
else
|
|
@@ -267,7 +286,9 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
267
286
|
* @returns The generated ID.
|
|
268
287
|
*/
|
|
269
288
|
_generateId(command) {
|
|
270
|
-
return typeof this.idGenerator === 'function'
|
|
289
|
+
return typeof this.idGenerator === 'function'
|
|
290
|
+
? this.idGenerator(command, this)
|
|
291
|
+
: undefined;
|
|
271
292
|
}
|
|
272
293
|
/**
|
|
273
294
|
* Retrieves the codec for the specified operation.
|
|
@@ -293,7 +314,10 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
293
314
|
let validator = this._outputCodecs[operation];
|
|
294
315
|
if (validator)
|
|
295
316
|
return validator;
|
|
296
|
-
const options = {
|
|
317
|
+
const options = {
|
|
318
|
+
projection: '*',
|
|
319
|
+
partial: 'deep',
|
|
320
|
+
};
|
|
297
321
|
const dataType = this.dataType;
|
|
298
322
|
validator = dataType.generateCodec('decode', options);
|
|
299
323
|
this._outputCodecs[operation] = validator;
|
|
@@ -343,28 +367,36 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
343
367
|
throw e;
|
|
344
368
|
}
|
|
345
369
|
}
|
|
370
|
+
async _beforeCreate(
|
|
346
371
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
347
|
-
|
|
372
|
+
command) {
|
|
348
373
|
// Do nothing
|
|
349
374
|
}
|
|
375
|
+
async _beforeUpdate(
|
|
350
376
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
351
|
-
|
|
377
|
+
command) {
|
|
352
378
|
// Do nothing
|
|
353
379
|
}
|
|
380
|
+
async _beforeUpdateMany(
|
|
354
381
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
355
|
-
|
|
382
|
+
command) {
|
|
356
383
|
// Do nothing
|
|
357
384
|
}
|
|
385
|
+
async _beforeDelete(
|
|
358
386
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
359
|
-
|
|
387
|
+
command) {
|
|
360
388
|
// Do nothing
|
|
361
389
|
}
|
|
390
|
+
async _beforeDeleteMany(
|
|
362
391
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
363
|
-
|
|
392
|
+
command) {
|
|
364
393
|
// Do nothing
|
|
365
394
|
}
|
|
395
|
+
async _afterCreate(
|
|
366
396
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
367
|
-
|
|
397
|
+
command,
|
|
398
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
399
|
+
result) {
|
|
368
400
|
// Do nothing
|
|
369
401
|
}
|
|
370
402
|
async _afterUpdate(
|
|
@@ -381,12 +413,18 @@ class ElasticEntityService extends elastic_service_js_1.ElasticService {
|
|
|
381
413
|
affected) {
|
|
382
414
|
// Do nothing
|
|
383
415
|
}
|
|
416
|
+
async _afterDelete(
|
|
417
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
418
|
+
command,
|
|
384
419
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
385
|
-
|
|
420
|
+
affected) {
|
|
386
421
|
// Do nothing
|
|
387
422
|
}
|
|
423
|
+
async _afterDeleteMany(
|
|
424
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
425
|
+
command,
|
|
388
426
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
389
|
-
|
|
427
|
+
affected) {
|
|
390
428
|
// Do nothing
|
|
391
429
|
}
|
|
392
430
|
}
|
package/cjs/elastic-service.js
CHANGED
|
@@ -29,7 +29,9 @@ class ElasticService extends core_1.ServiceBase {
|
|
|
29
29
|
*/
|
|
30
30
|
getClient() {
|
|
31
31
|
// @ts-ignore
|
|
32
|
-
const db = typeof this.client === 'function'
|
|
32
|
+
const db = typeof this.client === 'function'
|
|
33
|
+
? this.client(this)
|
|
34
|
+
: this.client;
|
|
33
35
|
if (!db)
|
|
34
36
|
throw new Error(`Client not set!`);
|
|
35
37
|
return db;
|
|
@@ -39,7 +41,8 @@ class ElasticService extends core_1.ServiceBase {
|
|
|
39
41
|
const next = async () => {
|
|
40
42
|
proto = proto ? Object.getPrototypeOf(proto) : this;
|
|
41
43
|
while (proto) {
|
|
42
|
-
if (proto.interceptor &&
|
|
44
|
+
if (proto.interceptor &&
|
|
45
|
+
Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
|
|
43
46
|
return await proto.interceptor.call(this, next, command, this);
|
|
44
47
|
}
|
|
45
48
|
proto = Object.getPrototypeOf(proto);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/* eslint-disable camelcase */
|
|
2
1
|
import '@opra/core';
|
|
3
2
|
import { OpraFilter } from '@opra/common';
|
|
4
3
|
export default function prepareFilter(filters) {
|
|
@@ -51,7 +50,8 @@ function prepareFilterAst(ast, negative) {
|
|
|
51
50
|
return prepareFilterAst(ast.expression, negative);
|
|
52
51
|
}
|
|
53
52
|
if (ast instanceof OpraFilter.ComparisonExpression) {
|
|
54
|
-
if (!(ast.left instanceof OpraFilter.QualifiedIdentifier ||
|
|
53
|
+
if (!(ast.left instanceof OpraFilter.QualifiedIdentifier ||
|
|
54
|
+
ast.left instanceof OpraFilter.StringLiteral)) {
|
|
55
55
|
throw new Error('Left side of ComparisonExpression must be a QualifiedIdentifier');
|
|
56
56
|
}
|
|
57
57
|
const left = prepareFilterAst(ast.left);
|
|
@@ -88,12 +88,21 @@ function prepareFilterAst(ast, negative) {
|
|
|
88
88
|
}
|
|
89
89
|
case '!like':
|
|
90
90
|
case 'like': {
|
|
91
|
-
out = {
|
|
91
|
+
out = {
|
|
92
|
+
wildcard: { [left]: { value: String(right).replace(/%/g, '*') } },
|
|
93
|
+
};
|
|
92
94
|
break;
|
|
93
95
|
}
|
|
94
96
|
case '!ilike':
|
|
95
97
|
case 'ilike': {
|
|
96
|
-
out = {
|
|
98
|
+
out = {
|
|
99
|
+
wildcard: {
|
|
100
|
+
[left]: {
|
|
101
|
+
value: String(right).replace(/%/g, '*'),
|
|
102
|
+
case_insensitive: true,
|
|
103
|
+
},
|
|
104
|
+
},
|
|
105
|
+
};
|
|
97
106
|
break;
|
|
98
107
|
}
|
|
99
108
|
default:
|
|
@@ -101,7 +110,8 @@ function prepareFilterAst(ast, negative) {
|
|
|
101
110
|
throw new TypeError(`Unknown ComparisonExpression operation (${ast.op})`);
|
|
102
111
|
}
|
|
103
112
|
}
|
|
104
|
-
if ((ast.op.startsWith('!') && !negative) ||
|
|
113
|
+
if ((ast.op.startsWith('!') && !negative) ||
|
|
114
|
+
(!ast.op.startsWith('!') && negative)) {
|
|
105
115
|
return { bool: { must_not: { ...out } } };
|
|
106
116
|
}
|
|
107
117
|
return out;
|
|
@@ -1,9 +1,11 @@
|
|
|
1
|
-
import { ComplexType, parseFieldsProjection } from '@opra/common';
|
|
1
|
+
import { ComplexType, parseFieldsProjection, } from '@opra/common';
|
|
2
2
|
export default function prepareProjection(dataType, projection) {
|
|
3
3
|
const out = {};
|
|
4
4
|
const includes = [];
|
|
5
5
|
const excludes = [];
|
|
6
|
-
const projection_ = typeof projection === 'string' || Array.isArray(projection)
|
|
6
|
+
const projection_ = typeof projection === 'string' || Array.isArray(projection)
|
|
7
|
+
? parseFieldsProjection(projection)
|
|
8
|
+
: projection;
|
|
7
9
|
prepare(dataType, includes, excludes, '', projection_);
|
|
8
10
|
if (includes.length)
|
|
9
11
|
out.includes = includes;
|
|
@@ -43,7 +45,8 @@ export function prepare(dataType, includes, excludes, curPath, projection) {
|
|
|
43
45
|
includes.push(fieldPath);
|
|
44
46
|
}
|
|
45
47
|
}
|
|
46
|
-
if (field.type instanceof ComplexType &&
|
|
48
|
+
if (field.type instanceof ComplexType &&
|
|
49
|
+
typeof p?.projection === 'object') {
|
|
47
50
|
prepare(field.type, includes, excludes, fieldPath, p.projection);
|
|
48
51
|
}
|
|
49
52
|
}
|
package/esm/elastic-adapter.js
CHANGED
|
@@ -14,7 +14,8 @@ export var ElasticAdapter;
|
|
|
14
14
|
}
|
|
15
15
|
const ctx = context;
|
|
16
16
|
const { operation } = ctx;
|
|
17
|
-
if (operation?.composition?.startsWith('Entity.') &&
|
|
17
|
+
if (operation?.composition?.startsWith('Entity.') &&
|
|
18
|
+
operation.compositionOptions?.type) {
|
|
18
19
|
const controller = operation.owner;
|
|
19
20
|
switch (operation.composition) {
|
|
20
21
|
case 'Entity.Create': {
|
|
@@ -22,15 +23,24 @@ export var ElasticAdapter;
|
|
|
22
23
|
const options = {
|
|
23
24
|
projection: ctx.queryParams.projection,
|
|
24
25
|
};
|
|
25
|
-
return {
|
|
26
|
+
return {
|
|
27
|
+
method: 'create',
|
|
28
|
+
data,
|
|
29
|
+
options,
|
|
30
|
+
};
|
|
26
31
|
}
|
|
27
32
|
case 'Entity.Delete': {
|
|
28
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
33
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
34
|
+
controller.parameters.find(p => p.keyParam);
|
|
29
35
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
30
36
|
const options = {
|
|
31
37
|
filter: ctx.queryParams.filter,
|
|
32
38
|
};
|
|
33
|
-
return {
|
|
39
|
+
return {
|
|
40
|
+
method: 'delete',
|
|
41
|
+
key,
|
|
42
|
+
options,
|
|
43
|
+
};
|
|
34
44
|
}
|
|
35
45
|
case 'Entity.DeleteMany': {
|
|
36
46
|
const options = {
|
|
@@ -50,7 +60,8 @@ export var ElasticAdapter;
|
|
|
50
60
|
return { method: 'findMany', options };
|
|
51
61
|
}
|
|
52
62
|
case 'Entity.Get': {
|
|
53
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
63
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
64
|
+
controller.parameters.find(p => p.keyParam);
|
|
54
65
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
55
66
|
const options = {
|
|
56
67
|
projection: ctx.queryParams.projection,
|
|
@@ -60,30 +71,46 @@ export var ElasticAdapter;
|
|
|
60
71
|
}
|
|
61
72
|
case 'Entity.Replace': {
|
|
62
73
|
const data = await ctx.getBody();
|
|
63
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
74
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
75
|
+
controller.parameters.find(p => p.keyParam);
|
|
64
76
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
65
77
|
const options = {
|
|
66
78
|
projection: ctx.queryParams.projection,
|
|
67
79
|
filter: ctx.queryParams.filter,
|
|
68
80
|
};
|
|
69
|
-
return {
|
|
81
|
+
return {
|
|
82
|
+
method: 'replace',
|
|
83
|
+
key,
|
|
84
|
+
data,
|
|
85
|
+
options,
|
|
86
|
+
};
|
|
70
87
|
}
|
|
71
88
|
case 'Entity.Update': {
|
|
72
89
|
const data = await ctx.getBody();
|
|
73
|
-
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
90
|
+
const keyParam = operation.parameters.find(p => p.keyParam) ||
|
|
91
|
+
controller.parameters.find(p => p.keyParam);
|
|
74
92
|
const key = keyParam && ctx.pathParams[String(keyParam.name)];
|
|
75
93
|
const options = {
|
|
76
94
|
projection: ctx.queryParams.projection,
|
|
77
95
|
filter: ctx.queryParams.filter,
|
|
78
96
|
};
|
|
79
|
-
return {
|
|
97
|
+
return {
|
|
98
|
+
method: 'update',
|
|
99
|
+
key,
|
|
100
|
+
data,
|
|
101
|
+
options,
|
|
102
|
+
};
|
|
80
103
|
}
|
|
81
104
|
case 'Entity.UpdateMany': {
|
|
82
105
|
const data = await ctx.getBody();
|
|
83
106
|
const options = {
|
|
84
107
|
filter: ctx.queryParams.filter,
|
|
85
108
|
};
|
|
86
|
-
return {
|
|
109
|
+
return {
|
|
110
|
+
method: 'updateMany',
|
|
111
|
+
data,
|
|
112
|
+
options,
|
|
113
|
+
};
|
|
87
114
|
}
|
|
88
115
|
default:
|
|
89
116
|
break;
|
|
@@ -21,10 +21,12 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
21
21
|
for(context, overwriteProperties, overwriteContext) {
|
|
22
22
|
if (overwriteProperties?.documentFilter && this.documentFilter) {
|
|
23
23
|
overwriteProperties.documentFilter = [
|
|
24
|
-
...(Array.isArray(this.documentFilter)
|
|
24
|
+
...(Array.isArray(this.documentFilter)
|
|
25
|
+
? this.documentFilter
|
|
26
|
+
: [this.documentFilter]),
|
|
25
27
|
...(Array.isArray(overwriteProperties?.documentFilter)
|
|
26
|
-
? overwriteProperties
|
|
27
|
-
: [overwriteProperties
|
|
28
|
+
? overwriteProperties.documentFilter
|
|
29
|
+
: [overwriteProperties.documentFilter]),
|
|
28
30
|
];
|
|
29
31
|
}
|
|
30
32
|
return super.for(context, overwriteProperties, overwriteContext);
|
|
@@ -59,7 +61,9 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
59
61
|
options,
|
|
60
62
|
};
|
|
61
63
|
command.input._id =
|
|
62
|
-
command.input._id == null || command.input._id === ''
|
|
64
|
+
command.input._id == null || command.input._id === ''
|
|
65
|
+
? this._generateId(command)
|
|
66
|
+
: command.input._id;
|
|
63
67
|
return this._executeCommand(command, () => this._create(command));
|
|
64
68
|
}
|
|
65
69
|
/**
|
|
@@ -76,7 +80,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
76
80
|
options,
|
|
77
81
|
};
|
|
78
82
|
return this._executeCommand(command, async () => {
|
|
79
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
83
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
84
|
+
await this._getDocumentFilter(command),
|
|
85
|
+
command.options?.filter,
|
|
86
|
+
]);
|
|
80
87
|
command.options = { ...command.options, filter };
|
|
81
88
|
const r = await this._count(command);
|
|
82
89
|
return r.count;
|
|
@@ -98,7 +105,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
98
105
|
options,
|
|
99
106
|
};
|
|
100
107
|
return this._executeCommand(command, async () => {
|
|
101
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
108
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
109
|
+
await this._getDocumentFilter(command),
|
|
110
|
+
command.options?.filter,
|
|
111
|
+
]);
|
|
102
112
|
command.options = { ...command.options, filter };
|
|
103
113
|
return this._delete(command);
|
|
104
114
|
});
|
|
@@ -117,7 +127,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
117
127
|
options,
|
|
118
128
|
};
|
|
119
129
|
return this._executeCommand(command, async () => {
|
|
120
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
130
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
131
|
+
await this._getDocumentFilter(command),
|
|
132
|
+
command.options?.filter,
|
|
133
|
+
]);
|
|
121
134
|
command.options = { ...command.options, filter };
|
|
122
135
|
return this._deleteMany(command);
|
|
123
136
|
});
|
|
@@ -143,10 +156,15 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
143
156
|
terminate_after: 1,
|
|
144
157
|
size: 0,
|
|
145
158
|
};
|
|
146
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
159
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
160
|
+
await this._getDocumentFilter(command),
|
|
161
|
+
command.options?.filter,
|
|
162
|
+
]);
|
|
147
163
|
command.options = { ...options, request, filter };
|
|
148
164
|
const r = await this._search(command);
|
|
149
|
-
return !!(typeof r.hits.total === 'number'
|
|
165
|
+
return !!(typeof r.hits.total === 'number'
|
|
166
|
+
? r.hits.total
|
|
167
|
+
: r.hits.total?.value);
|
|
150
168
|
});
|
|
151
169
|
}
|
|
152
170
|
/**
|
|
@@ -170,7 +188,9 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
170
188
|
};
|
|
171
189
|
command.options = { ...options, request };
|
|
172
190
|
const r = await this._search(command);
|
|
173
|
-
return !!(typeof r.hits.total === 'number'
|
|
191
|
+
return !!(typeof r.hits.total === 'number'
|
|
192
|
+
? r.hits.total
|
|
193
|
+
: r.hits.total?.value);
|
|
174
194
|
});
|
|
175
195
|
}
|
|
176
196
|
/**
|
|
@@ -186,7 +206,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
186
206
|
};
|
|
187
207
|
return this._executeCommand(command, async () => {
|
|
188
208
|
const documentFilter = await this._getDocumentFilter(command);
|
|
189
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
209
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
210
|
+
documentFilter,
|
|
211
|
+
command.options?.filter,
|
|
212
|
+
]);
|
|
190
213
|
const newCommand = {
|
|
191
214
|
...command,
|
|
192
215
|
limit: 1,
|
|
@@ -213,7 +236,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
213
236
|
options,
|
|
214
237
|
};
|
|
215
238
|
return this._executeCommand(command, async () => {
|
|
216
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
239
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
240
|
+
await this._getDocumentFilter(command),
|
|
241
|
+
command.options?.filter,
|
|
242
|
+
]);
|
|
217
243
|
const newCommand = {
|
|
218
244
|
...command,
|
|
219
245
|
limit: 1,
|
|
@@ -240,7 +266,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
240
266
|
options,
|
|
241
267
|
};
|
|
242
268
|
return this._executeCommand(command, async () => {
|
|
243
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
269
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
270
|
+
await this._getDocumentFilter(command),
|
|
271
|
+
command.options?.filter,
|
|
272
|
+
]);
|
|
244
273
|
const limit = command.options?.limit || this.defaultLimit;
|
|
245
274
|
command.options = { ...command.options, filter, limit };
|
|
246
275
|
const r = await this._search(command);
|
|
@@ -265,7 +294,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
265
294
|
options,
|
|
266
295
|
};
|
|
267
296
|
return this._executeCommand(command, async () => {
|
|
268
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
297
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
298
|
+
await this._getDocumentFilter(command),
|
|
299
|
+
command.options?.filter,
|
|
300
|
+
]);
|
|
269
301
|
const limit = command.options?.limit || this.defaultLimit;
|
|
270
302
|
command.options = {
|
|
271
303
|
...command.options,
|
|
@@ -320,7 +352,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
320
352
|
options,
|
|
321
353
|
};
|
|
322
354
|
return this._executeCommand(command, async () => {
|
|
323
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
355
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
356
|
+
await this._getDocumentFilter(command),
|
|
357
|
+
command.options?.filter,
|
|
358
|
+
]);
|
|
324
359
|
command.options = { ...command.options, filter };
|
|
325
360
|
return await this._updateMany(command);
|
|
326
361
|
});
|
|
@@ -341,7 +376,10 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
341
376
|
options,
|
|
342
377
|
};
|
|
343
378
|
return this._executeCommand(command, async () => {
|
|
344
|
-
const filter = ElasticAdapter.prepareFilter([
|
|
379
|
+
const filter = ElasticAdapter.prepareFilter([
|
|
380
|
+
await this._getDocumentFilter(command),
|
|
381
|
+
command.options?.filter,
|
|
382
|
+
]);
|
|
345
383
|
command.options = { ...command.options, filter };
|
|
346
384
|
return this._updateMany(command);
|
|
347
385
|
});
|
|
@@ -355,7 +393,9 @@ export class ElasticCollectionService extends ElasticEntityService {
|
|
|
355
393
|
* that resolves to the common filter, or undefined if not available.
|
|
356
394
|
*/
|
|
357
395
|
_getDocumentFilter(command) {
|
|
358
|
-
const commonFilter = Array.isArray(this.documentFilter)
|
|
396
|
+
const commonFilter = Array.isArray(this.documentFilter)
|
|
397
|
+
? this.documentFilter
|
|
398
|
+
: [this.documentFilter];
|
|
359
399
|
const mapped = commonFilter.map(f => typeof f === 'function' ? f(command, this) : f);
|
|
360
400
|
return mapped.length > 1 ? ElasticAdapter.prepareFilter(mapped) : mapped[0];
|
|
361
401
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { DATATYPE_METADATA, InternalServerError } from '@opra/common';
|
|
1
|
+
import { DATATYPE_METADATA, InternalServerError, } from '@opra/common';
|
|
2
2
|
import { isNotNullish } from 'valgen';
|
|
3
3
|
import { ElasticAdapter } from './elastic-adapter.js';
|
|
4
4
|
import { ElasticService } from './elastic-service.js';
|
|
@@ -41,7 +41,9 @@ export class ElasticEntityService extends ElasticService {
|
|
|
41
41
|
* @throws {Error} If the index name is not defined.
|
|
42
42
|
*/
|
|
43
43
|
getIndexName() {
|
|
44
|
-
const out = typeof this.indexName === 'function'
|
|
44
|
+
const out = typeof this.indexName === 'function'
|
|
45
|
+
? this.indexName(this)
|
|
46
|
+
: this.indexName;
|
|
45
47
|
if (out)
|
|
46
48
|
return out;
|
|
47
49
|
throw new Error('indexName is not defined');
|
|
@@ -54,7 +56,9 @@ export class ElasticEntityService extends ElasticService {
|
|
|
54
56
|
* @throws {Error} If the resource name is not defined.
|
|
55
57
|
*/
|
|
56
58
|
getResourceName() {
|
|
57
|
-
const out = typeof this.resourceName === 'function'
|
|
59
|
+
const out = typeof this.resourceName === 'function'
|
|
60
|
+
? this.resourceName(this)
|
|
61
|
+
: this.resourceName || this.getIndexName();
|
|
58
62
|
if (out)
|
|
59
63
|
return out;
|
|
60
64
|
throw new Error('resourceName is not defined');
|
|
@@ -107,7 +111,10 @@ export class ElasticEntityService extends ElasticService {
|
|
|
107
111
|
*/
|
|
108
112
|
async _count(command) {
|
|
109
113
|
const { options } = command;
|
|
110
|
-
const filterQuery = ElasticAdapter.prepareFilter([
|
|
114
|
+
const filterQuery = ElasticAdapter.prepareFilter([
|
|
115
|
+
options?.filter,
|
|
116
|
+
options?.request?.query,
|
|
117
|
+
]);
|
|
111
118
|
let query = {
|
|
112
119
|
...options?.request?.query,
|
|
113
120
|
...filterQuery,
|
|
@@ -158,7 +165,10 @@ export class ElasticEntityService extends ElasticService {
|
|
|
158
165
|
*/
|
|
159
166
|
async _deleteMany(command) {
|
|
160
167
|
const { options } = command;
|
|
161
|
-
const filterQuery = ElasticAdapter.prepareFilter([
|
|
168
|
+
const filterQuery = ElasticAdapter.prepareFilter([
|
|
169
|
+
options?.filter,
|
|
170
|
+
options?.request?.query,
|
|
171
|
+
]);
|
|
162
172
|
let query = {
|
|
163
173
|
...options?.request?.query,
|
|
164
174
|
...filterQuery,
|
|
@@ -181,7 +191,9 @@ export class ElasticEntityService extends ElasticService {
|
|
|
181
191
|
async _search(command) {
|
|
182
192
|
const { options } = command;
|
|
183
193
|
const filterQuery = ElasticAdapter.prepareFilter([
|
|
184
|
-
command.documentId
|
|
194
|
+
command.documentId
|
|
195
|
+
? { ids: { values: [command.documentId] } }
|
|
196
|
+
: undefined,
|
|
185
197
|
options?.filter,
|
|
186
198
|
options?.request?.query,
|
|
187
199
|
]);
|
|
@@ -194,7 +206,9 @@ export class ElasticEntityService extends ElasticService {
|
|
|
194
206
|
const request = {
|
|
195
207
|
from: options?.skip,
|
|
196
208
|
size: options?.limit,
|
|
197
|
-
sort: options?.sort
|
|
209
|
+
sort: options?.sort
|
|
210
|
+
? ElasticAdapter.prepareSort(options?.sort)
|
|
211
|
+
: undefined,
|
|
198
212
|
_source: ElasticAdapter.prepareProjection(this.dataType, options?.projection),
|
|
199
213
|
index: this.getIndexName(),
|
|
200
214
|
...options?.request,
|
|
@@ -218,7 +232,10 @@ export class ElasticEntityService extends ElasticService {
|
|
|
218
232
|
const inputKeysLen = Object.keys(input).length;
|
|
219
233
|
isNotNullish(inputKeysLen || script, { label: 'input' });
|
|
220
234
|
if (requestScript) {
|
|
221
|
-
script =
|
|
235
|
+
script =
|
|
236
|
+
typeof requestScript === 'string'
|
|
237
|
+
? { source: requestScript }
|
|
238
|
+
: { ...requestScript };
|
|
222
239
|
script.lang = script.lang || 'painless';
|
|
223
240
|
if (inputKeysLen > 0 && script.lang !== 'painless') {
|
|
224
241
|
throw new TypeError(`You cannot provide 'input' and 'script' arguments at the same time unless the script lang is 'painless'`);
|
|
@@ -230,7 +247,9 @@ export class ElasticEntityService extends ElasticService {
|
|
|
230
247
|
const doc = inputCodec(input);
|
|
231
248
|
const scr = ElasticAdapter.preparePatch(doc);
|
|
232
249
|
if (script) {
|
|
233
|
-
script.source =
|
|
250
|
+
script.source =
|
|
251
|
+
(script.source ? script.source + '\n' + script.source : '') +
|
|
252
|
+
scr.source;
|
|
234
253
|
script.params = { ...script.params, ...scr.params };
|
|
235
254
|
}
|
|
236
255
|
else
|
|
@@ -264,7 +283,9 @@ export class ElasticEntityService extends ElasticService {
|
|
|
264
283
|
* @returns The generated ID.
|
|
265
284
|
*/
|
|
266
285
|
_generateId(command) {
|
|
267
|
-
return typeof this.idGenerator === 'function'
|
|
286
|
+
return typeof this.idGenerator === 'function'
|
|
287
|
+
? this.idGenerator(command, this)
|
|
288
|
+
: undefined;
|
|
268
289
|
}
|
|
269
290
|
/**
|
|
270
291
|
* Retrieves the codec for the specified operation.
|
|
@@ -290,7 +311,10 @@ export class ElasticEntityService extends ElasticService {
|
|
|
290
311
|
let validator = this._outputCodecs[operation];
|
|
291
312
|
if (validator)
|
|
292
313
|
return validator;
|
|
293
|
-
const options = {
|
|
314
|
+
const options = {
|
|
315
|
+
projection: '*',
|
|
316
|
+
partial: 'deep',
|
|
317
|
+
};
|
|
294
318
|
const dataType = this.dataType;
|
|
295
319
|
validator = dataType.generateCodec('decode', options);
|
|
296
320
|
this._outputCodecs[operation] = validator;
|
|
@@ -340,28 +364,36 @@ export class ElasticEntityService extends ElasticService {
|
|
|
340
364
|
throw e;
|
|
341
365
|
}
|
|
342
366
|
}
|
|
367
|
+
async _beforeCreate(
|
|
343
368
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
344
|
-
|
|
369
|
+
command) {
|
|
345
370
|
// Do nothing
|
|
346
371
|
}
|
|
372
|
+
async _beforeUpdate(
|
|
347
373
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
348
|
-
|
|
374
|
+
command) {
|
|
349
375
|
// Do nothing
|
|
350
376
|
}
|
|
377
|
+
async _beforeUpdateMany(
|
|
351
378
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
352
|
-
|
|
379
|
+
command) {
|
|
353
380
|
// Do nothing
|
|
354
381
|
}
|
|
382
|
+
async _beforeDelete(
|
|
355
383
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
356
|
-
|
|
384
|
+
command) {
|
|
357
385
|
// Do nothing
|
|
358
386
|
}
|
|
387
|
+
async _beforeDeleteMany(
|
|
359
388
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
360
|
-
|
|
389
|
+
command) {
|
|
361
390
|
// Do nothing
|
|
362
391
|
}
|
|
392
|
+
async _afterCreate(
|
|
363
393
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
364
|
-
|
|
394
|
+
command,
|
|
395
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
396
|
+
result) {
|
|
365
397
|
// Do nothing
|
|
366
398
|
}
|
|
367
399
|
async _afterUpdate(
|
|
@@ -378,12 +410,18 @@ export class ElasticEntityService extends ElasticService {
|
|
|
378
410
|
affected) {
|
|
379
411
|
// Do nothing
|
|
380
412
|
}
|
|
413
|
+
async _afterDelete(
|
|
414
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
415
|
+
command,
|
|
381
416
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
382
|
-
|
|
417
|
+
affected) {
|
|
383
418
|
// Do nothing
|
|
384
419
|
}
|
|
420
|
+
async _afterDeleteMany(
|
|
421
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
422
|
+
command,
|
|
385
423
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
386
|
-
|
|
424
|
+
affected) {
|
|
387
425
|
// Do nothing
|
|
388
426
|
}
|
|
389
427
|
}
|
package/esm/elastic-service.js
CHANGED
|
@@ -26,7 +26,9 @@ export class ElasticService extends ServiceBase {
|
|
|
26
26
|
*/
|
|
27
27
|
getClient() {
|
|
28
28
|
// @ts-ignore
|
|
29
|
-
const db = typeof this.client === 'function'
|
|
29
|
+
const db = typeof this.client === 'function'
|
|
30
|
+
? this.client(this)
|
|
31
|
+
: this.client;
|
|
30
32
|
if (!db)
|
|
31
33
|
throw new Error(`Client not set!`);
|
|
32
34
|
return db;
|
|
@@ -36,7 +38,8 @@ export class ElasticService extends ServiceBase {
|
|
|
36
38
|
const next = async () => {
|
|
37
39
|
proto = proto ? Object.getPrototypeOf(proto) : this;
|
|
38
40
|
while (proto) {
|
|
39
|
-
if (proto.interceptor &&
|
|
41
|
+
if (proto.interceptor &&
|
|
42
|
+
Object.prototype.hasOwnProperty.call(proto, 'interceptor')) {
|
|
40
43
|
return await proto.interceptor.call(this, next, command, this);
|
|
41
44
|
}
|
|
42
45
|
proto = Object.getPrototypeOf(proto);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opra/elastic",
|
|
3
|
-
"version": "1.4.
|
|
3
|
+
"version": "1.4.4",
|
|
4
4
|
"description": "Opra Elastic Search adapter package",
|
|
5
5
|
"author": "Panates",
|
|
6
6
|
"license": "MIT",
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
},
|
|
12
12
|
"peerDependencies": {
|
|
13
13
|
"@elastic/elasticsearch": ">=8.7.0",
|
|
14
|
-
"@opra/common": "^1.4.
|
|
15
|
-
"@opra/core": "^1.4.
|
|
14
|
+
"@opra/common": "^1.4.4",
|
|
15
|
+
"@opra/core": "^1.4.4"
|
|
16
16
|
},
|
|
17
17
|
"type": "module",
|
|
18
18
|
"exports": {
|