kuzzle 2.16.8 → 2.17.0
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/README.md +11 -0
- package/lib/api/controllers/adminController.js +7 -6
- package/lib/api/controllers/authController.js +11 -11
- package/lib/api/controllers/baseController.js +60 -3
- package/lib/api/controllers/clusterController.js +1 -1
- package/lib/api/controllers/collectionController.js +7 -5
- package/lib/api/controllers/documentController.js +130 -17
- package/lib/api/controllers/indexController.js +1 -1
- package/lib/api/controllers/memoryStorageController.js +39 -38
- package/lib/api/controllers/realtimeController.js +1 -1
- package/lib/api/controllers/securityController.js +49 -49
- package/lib/api/controllers/serverController.js +73 -27
- package/lib/api/documentExtractor.js +3 -3
- package/lib/api/funnel.js +40 -21
- package/lib/api/httpRoutes.js +9 -4
- package/lib/api/openapi/OpenApiManager.d.ts +11 -0
- package/lib/api/openapi/OpenApiManager.js +96 -0
- package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
- package/lib/api/openapi/{document → components/document}/index.js +7 -2
- package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
- package/lib/api/openapi/components/document/validate.yaml +42 -0
- package/lib/api/openapi/components/index.d.ts +2 -0
- package/lib/api/openapi/components/index.js +18 -0
- package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
- package/lib/api/openapi/index.d.ts +1 -2
- package/lib/api/openapi/index.js +1 -5
- package/lib/api/openapi/openApiGenerator.d.ts +7 -0
- package/lib/api/openapi/openApiGenerator.js +133 -0
- package/lib/api/request/kuzzleRequest.d.ts +11 -11
- package/lib/api/request/kuzzleRequest.js +38 -48
- package/lib/cluster/node.js +9 -9
- package/lib/cluster/publisher.js +1 -1
- package/lib/cluster/subscriber.js +1 -1
- package/lib/cluster/workers/IDCardRenewer.js +13 -4
- package/lib/config/default.config.js +1 -0
- package/lib/config/index.js +6 -6
- package/lib/core/auth/passportResponse.js +6 -6
- package/lib/core/auth/passportWrapper.js +5 -5
- package/lib/core/backend/backend.d.ts +5 -1
- package/lib/core/backend/backend.js +12 -8
- package/lib/core/backend/backendConfig.d.ts +5 -1
- package/lib/core/backend/backendConfig.js +4 -0
- package/lib/core/backend/backendOpenApi.d.ts +9 -0
- package/lib/core/backend/backendOpenApi.js +69 -0
- package/lib/core/backend/index.d.ts +1 -0
- package/lib/core/backend/index.js +1 -0
- package/lib/core/network/accessLogger.js +6 -6
- package/lib/core/network/clientConnection.js +1 -1
- package/lib/core/network/entryPoint.js +5 -5
- package/lib/core/network/httpRouter/index.js +5 -5
- package/lib/core/network/httpRouter/routeHandler.js +3 -3
- package/lib/core/network/httpRouter/routePart.js +5 -5
- package/lib/core/network/protocolManifest.js +1 -1
- package/lib/core/network/protocols/httpMessage.js +2 -2
- package/lib/core/network/protocols/httpwsProtocol.js +207 -46
- package/lib/core/network/protocols/mqttProtocol.js +3 -3
- package/lib/core/network/protocols/protocol.js +3 -3
- package/lib/core/network/router.js +7 -6
- package/lib/core/plugin/plugin.js +38 -64
- package/lib/core/plugin/pluginContext.d.ts +10 -1
- package/lib/core/plugin/pluginContext.js +2 -0
- package/lib/core/plugin/pluginManifest.js +3 -3
- package/lib/core/plugin/pluginRepository.js +5 -5
- package/lib/core/plugin/pluginsManager.js +29 -28
- package/lib/core/realtime/notification/server.js +1 -1
- package/lib/core/realtime/notification/user.js +1 -1
- package/lib/core/realtime/notifier.js +5 -5
- package/lib/core/security/index.js +1 -1
- package/lib/core/security/profileRepository.d.ts +176 -0
- package/lib/core/security/profileRepository.js +426 -443
- package/lib/core/security/roleRepository.js +16 -16
- package/lib/core/security/securityLoader.js +3 -3
- package/lib/core/security/tokenRepository.js +18 -21
- package/lib/core/security/userRepository.js +8 -8
- package/lib/core/shared/abstractManifest.js +4 -4
- package/lib/core/shared/repository.js +6 -6
- package/lib/core/shared/sdk/funnelProtocol.js +1 -1
- package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
- package/lib/core/shared/store.js +30 -23
- package/lib/core/statistics/statistics.js +17 -17
- package/lib/core/storage/clientAdapter.js +45 -10
- package/lib/core/validation/baseType.js +5 -5
- package/lib/core/validation/types/anything.js +1 -1
- package/lib/core/validation/types/boolean.js +2 -2
- package/lib/core/validation/types/date.js +9 -9
- package/lib/core/validation/types/email.js +5 -5
- package/lib/core/validation/types/enum.js +6 -6
- package/lib/core/validation/types/geoPoint.js +2 -2
- package/lib/core/validation/types/geoShape.js +28 -25
- package/lib/core/validation/types/integer.js +4 -4
- package/lib/core/validation/types/ipAddress.js +7 -6
- package/lib/core/validation/types/numeric.js +4 -4
- package/lib/core/validation/types/object.js +5 -5
- package/lib/core/validation/types/string.js +5 -5
- package/lib/core/validation/types/url.js +7 -6
- package/lib/core/validation/validation.js +95 -84
- package/lib/kerror/codes/1-services.json +12 -0
- package/lib/kerror/codes/2-api.json +12 -0
- package/lib/kerror/codes/3-network.json +12 -0
- package/lib/kerror/codes/4-plugin.json +6 -0
- package/lib/kerror/codes/index.js +11 -11
- package/lib/kerror/index.js +1 -1
- package/lib/kuzzle/dumpGenerator.js +3 -3
- package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
- package/lib/kuzzle/event/pipeRunner.js +1 -1
- package/lib/kuzzle/event/waterfall.js +6 -6
- package/lib/kuzzle/kuzzle.js +36 -5
- package/lib/kuzzle/log.js +3 -3
- package/lib/kuzzle/vault.js +3 -3
- package/lib/model/security/profile.d.ts +54 -0
- package/lib/model/security/profile.js +174 -233
- package/lib/model/security/rights.js +1 -1
- package/lib/model/security/role.d.ts +40 -0
- package/lib/model/security/role.js +159 -191
- package/lib/model/security/user.d.ts +29 -0
- package/lib/model/security/user.js +84 -52
- package/lib/model/storage/apiKey.js +2 -2
- package/lib/model/storage/baseModel.js +3 -3
- package/lib/service/cache/redis.js +7 -7
- package/lib/service/storage/elasticsearch.js +152 -90
- package/lib/service/storage/esWrapper.js +2 -3
- package/lib/types/ControllerDefinition.d.ts +3 -3
- package/lib/types/ControllerRights.d.ts +22 -0
- package/lib/types/ControllerRights.js +23 -0
- package/lib/types/HttpStream.d.ts +32 -0
- package/lib/types/HttpStream.js +70 -0
- package/lib/types/OpenApiDefinition.d.ts +43 -0
- package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
- package/lib/types/Policy.d.ts +25 -0
- package/lib/types/Policy.js +23 -0
- package/lib/types/PolicyRestrictions.d.ts +21 -0
- package/lib/types/PolicyRestrictions.js +23 -0
- package/lib/types/Target.d.ts +15 -0
- package/lib/types/Target.js +23 -0
- package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
- package/lib/types/config/ServicesConfiguration.d.ts +2 -2
- package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
- package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
- package/lib/types/index.d.ts +7 -1
- package/lib/types/index.js +7 -1
- package/lib/util/array.d.ts +11 -0
- package/lib/util/array.js +57 -0
- package/lib/util/assertType.js +6 -6
- package/lib/util/bufferedPassThrough.d.ts +76 -0
- package/lib/util/bufferedPassThrough.js +161 -0
- package/lib/util/deprecate.js +7 -5
- package/lib/util/didYouMean.js +1 -1
- package/lib/util/dump-collection.d.ts +3 -0
- package/lib/util/dump-collection.js +265 -0
- package/lib/util/extractFields.js +2 -2
- package/lib/util/inflector.d.ts +8 -0
- package/lib/util/inflector.js +16 -0
- package/lib/util/requestAssertions.js +7 -7
- package/lib/util/wildcard.js +55 -0
- package/package-lock.json +881 -431
- package/package.json +23 -20
- package/lib/api/openApiGenerator.d.ts +0 -7
- package/lib/api/openApiGenerator.js +0 -197
|
@@ -95,7 +95,7 @@ class ElasticSearch extends Service {
|
|
|
95
95
|
return new StorageClient({ defer, ...config });
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
constructor(config, scope = scopeEnum.PUBLIC) {
|
|
98
|
+
constructor (config, scope = scopeEnum.PUBLIC) {
|
|
99
99
|
super('elasticsearch', config);
|
|
100
100
|
|
|
101
101
|
this._scope = scope;
|
|
@@ -172,7 +172,7 @@ class ElasticSearch extends Service {
|
|
|
172
172
|
|
|
173
173
|
const { body: { version } } = await this._client.info();
|
|
174
174
|
|
|
175
|
-
if (version && !semver.satisfies(semver.coerce(version.number), '>= 7.0.0')) {
|
|
175
|
+
if (version && ! semver.satisfies(semver.coerce(version.number), '>= 7.0.0')) {
|
|
176
176
|
throw kerror.get('version_mismatch', version.number);
|
|
177
177
|
}
|
|
178
178
|
|
|
@@ -252,7 +252,7 @@ class ElasticSearch extends Service {
|
|
|
252
252
|
continue;
|
|
253
253
|
}
|
|
254
254
|
|
|
255
|
-
if (!indexes[indexName]) {
|
|
255
|
+
if (! indexes[indexName]) {
|
|
256
256
|
indexes[indexName] = {
|
|
257
257
|
collections: [],
|
|
258
258
|
name: indexName,
|
|
@@ -305,7 +305,7 @@ class ElasticSearch extends Service {
|
|
|
305
305
|
|
|
306
306
|
let fetched = await global.kuzzle.ask('core:cache:internal:get', cacheKey);
|
|
307
307
|
|
|
308
|
-
if (!fetched) {
|
|
308
|
+
if (! fetched) {
|
|
309
309
|
throw kerror.get('unknown_scroll_id');
|
|
310
310
|
}
|
|
311
311
|
|
|
@@ -333,7 +333,7 @@ class ElasticSearch extends Service {
|
|
|
333
333
|
|
|
334
334
|
body.remaining = body.hits.total.value - fetched;
|
|
335
335
|
|
|
336
|
-
return this._formatSearchResult(body);
|
|
336
|
+
return await this._formatSearchResult(body);
|
|
337
337
|
}
|
|
338
338
|
catch (error) {
|
|
339
339
|
throw this._esWrapper.formatESError(error);
|
|
@@ -351,15 +351,31 @@ class ElasticSearch extends Service {
|
|
|
351
351
|
* @returns {Promise.<{ scrollId, hits, aggregations, suggest, total }>}
|
|
352
352
|
*/
|
|
353
353
|
async search (
|
|
354
|
-
index,
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
354
|
+
{ index, collection, searchBody, targets } = {},
|
|
355
|
+
{ from, size, scroll } = {}
|
|
356
|
+
) {
|
|
357
|
+
let esIndexes;
|
|
358
|
+
|
|
359
|
+
if (targets && targets.length > 0) {
|
|
360
|
+
const indexes = new Set();
|
|
361
|
+
for (const target of targets) {
|
|
362
|
+
for (const targetCollection of target.collections) {
|
|
363
|
+
const alias = this._getAlias(target.index, targetCollection);
|
|
364
|
+
|
|
365
|
+
indexes.add(alias);
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
|
|
369
|
+
esIndexes = Array.from(indexes).join(',');
|
|
370
|
+
}
|
|
371
|
+
else {
|
|
372
|
+
esIndexes = this._getAlias(index, collection);
|
|
373
|
+
}
|
|
374
|
+
|
|
359
375
|
const esRequest = {
|
|
360
376
|
body: this._sanitizeSearchBody(searchBody),
|
|
361
377
|
from,
|
|
362
|
-
index:
|
|
378
|
+
index: esIndexes,
|
|
363
379
|
scroll,
|
|
364
380
|
size,
|
|
365
381
|
trackTotalHits: true,
|
|
@@ -391,38 +407,47 @@ class ElasticSearch extends Service {
|
|
|
391
407
|
body.remaining = body.hits.total.value - body.hits.hits.length;
|
|
392
408
|
}
|
|
393
409
|
|
|
394
|
-
return this._formatSearchResult(body);
|
|
410
|
+
return await this._formatSearchResult(body);
|
|
395
411
|
}
|
|
396
412
|
catch (error) {
|
|
397
413
|
throw this._esWrapper.formatESError(error);
|
|
398
414
|
}
|
|
399
415
|
}
|
|
400
416
|
|
|
401
|
-
_formatSearchResult (body) {
|
|
402
|
-
|
|
417
|
+
async _formatSearchResult (body) {
|
|
418
|
+
|
|
419
|
+
const formatHit = async (hit) => {
|
|
420
|
+
let alias = null;
|
|
421
|
+
|
|
422
|
+
if (hit._index) {
|
|
423
|
+
alias = await this._getAliasFromIndice(hit._index);
|
|
424
|
+
}
|
|
425
|
+
|
|
403
426
|
return {
|
|
404
427
|
_id: hit._id,
|
|
405
428
|
_score: hit._score,
|
|
406
429
|
_source: hit._source,
|
|
430
|
+
collection: alias ? this._extractCollection(alias) : undefined,
|
|
407
431
|
highlight: hit.highlight,
|
|
432
|
+
index: alias ? this._extractIndex(alias) : undefined,
|
|
408
433
|
};
|
|
409
|
-
}
|
|
434
|
+
};
|
|
410
435
|
|
|
411
|
-
function formatInnerHits (innerHits) {
|
|
436
|
+
async function formatInnerHits (innerHits) {
|
|
412
437
|
if (! innerHits) {
|
|
413
438
|
return undefined;
|
|
414
439
|
}
|
|
415
440
|
|
|
416
441
|
const formattedInnerHits = {};
|
|
417
442
|
for (const [name, innerHit] of Object.entries(innerHits)) {
|
|
418
|
-
formattedInnerHits[name] = innerHit.hits.hits
|
|
443
|
+
formattedInnerHits[name] = await Bluebird.map(innerHit.hits.hits, formatHit);
|
|
419
444
|
}
|
|
420
445
|
return formattedInnerHits;
|
|
421
446
|
}
|
|
422
447
|
|
|
423
|
-
const hits = body.hits.hits
|
|
424
|
-
inner_hits: formatInnerHits(hit.inner_hits),
|
|
425
|
-
...formatHit(hit)
|
|
448
|
+
const hits = await Bluebird.map(body.hits.hits, async hit => ({
|
|
449
|
+
inner_hits: await formatInnerHits(hit.inner_hits),
|
|
450
|
+
...await formatHit(hit)
|
|
426
451
|
}));
|
|
427
452
|
|
|
428
453
|
return {
|
|
@@ -491,7 +516,7 @@ class ElasticSearch extends Service {
|
|
|
491
516
|
|
|
492
517
|
const esRequest = {
|
|
493
518
|
body: {
|
|
494
|
-
docs: ids.map(_id => ({ _id, _index: this._getAlias(index, collection)}))
|
|
519
|
+
docs: ids.map(_id => ({ _id, _index: this._getAlias(index, collection) }))
|
|
495
520
|
}
|
|
496
521
|
};
|
|
497
522
|
|
|
@@ -569,8 +594,7 @@ class ElasticSearch extends Service {
|
|
|
569
594
|
index,
|
|
570
595
|
collection,
|
|
571
596
|
content,
|
|
572
|
-
{ id, refresh, userId=null } = {})
|
|
573
|
-
{
|
|
597
|
+
{ id, refresh, userId = null } = {}) {
|
|
574
598
|
assertIsObject(content);
|
|
575
599
|
|
|
576
600
|
const esRequest = {
|
|
@@ -624,8 +648,7 @@ class ElasticSearch extends Service {
|
|
|
624
648
|
collection,
|
|
625
649
|
id,
|
|
626
650
|
content,
|
|
627
|
-
{ refresh, userId=null, injectKuzzleMeta=true } = {})
|
|
628
|
-
{
|
|
651
|
+
{ refresh, userId = null, injectKuzzleMeta = true } = {}) {
|
|
629
652
|
const esRequest = {
|
|
630
653
|
body: content,
|
|
631
654
|
id,
|
|
@@ -679,8 +702,7 @@ class ElasticSearch extends Service {
|
|
|
679
702
|
collection,
|
|
680
703
|
id,
|
|
681
704
|
content,
|
|
682
|
-
{ refresh, userId=null, retryOnConflict } = {})
|
|
683
|
-
{
|
|
705
|
+
{ refresh, userId = null, retryOnConflict } = {}) {
|
|
684
706
|
const esRequest = {
|
|
685
707
|
_source: true,
|
|
686
708
|
body: { doc: content },
|
|
@@ -731,8 +753,7 @@ class ElasticSearch extends Service {
|
|
|
731
753
|
collection,
|
|
732
754
|
id,
|
|
733
755
|
content,
|
|
734
|
-
{ defaultValues = {}, refresh, userId=null, retryOnConflict } = {})
|
|
735
|
-
{
|
|
756
|
+
{ defaultValues = {}, refresh, userId = null, retryOnConflict } = {}) {
|
|
736
757
|
const esRequest = {
|
|
737
758
|
_source: true,
|
|
738
759
|
body: {
|
|
@@ -794,8 +815,7 @@ class ElasticSearch extends Service {
|
|
|
794
815
|
collection,
|
|
795
816
|
id,
|
|
796
817
|
content,
|
|
797
|
-
{ refresh, userId=null } = {})
|
|
798
|
-
{
|
|
818
|
+
{ refresh, userId = null } = {}) {
|
|
799
819
|
const alias = this._getAlias(index, collection);
|
|
800
820
|
const esRequest = {
|
|
801
821
|
body: content,
|
|
@@ -851,8 +871,7 @@ class ElasticSearch extends Service {
|
|
|
851
871
|
index,
|
|
852
872
|
collection,
|
|
853
873
|
id,
|
|
854
|
-
{ refresh } = {})
|
|
855
|
-
{
|
|
874
|
+
{ refresh } = {}) {
|
|
856
875
|
const esRequest = {
|
|
857
876
|
id,
|
|
858
877
|
index: this._getAlias(index, collection),
|
|
@@ -892,8 +911,7 @@ class ElasticSearch extends Service {
|
|
|
892
911
|
index,
|
|
893
912
|
collection,
|
|
894
913
|
query,
|
|
895
|
-
{ refresh, size = 1000, fetch=true } = {})
|
|
896
|
-
{
|
|
914
|
+
{ refresh, size = 1000, fetch = true } = {}) {
|
|
897
915
|
const esRequest = {
|
|
898
916
|
body: this._sanitizeSearchBody({ query }),
|
|
899
917
|
index: this._getAlias(index, collection),
|
|
@@ -901,7 +919,7 @@ class ElasticSearch extends Service {
|
|
|
901
919
|
size
|
|
902
920
|
};
|
|
903
921
|
|
|
904
|
-
if (!isPlainObject(query)) {
|
|
922
|
+
if (! isPlainObject(query)) {
|
|
905
923
|
throw kerror.get('missing_argument', 'body.query');
|
|
906
924
|
}
|
|
907
925
|
|
|
@@ -947,8 +965,7 @@ class ElasticSearch extends Service {
|
|
|
947
965
|
collection,
|
|
948
966
|
id,
|
|
949
967
|
fields,
|
|
950
|
-
{ refresh, userId=null } = {})
|
|
951
|
-
{
|
|
968
|
+
{ refresh, userId = null } = {}) {
|
|
952
969
|
const alias = this._getAlias(index, collection);
|
|
953
970
|
const esRequest = {
|
|
954
971
|
id,
|
|
@@ -988,7 +1005,8 @@ class ElasticSearch extends Service {
|
|
|
988
1005
|
_source: body._source,
|
|
989
1006
|
_version: updated._version
|
|
990
1007
|
};
|
|
991
|
-
}
|
|
1008
|
+
}
|
|
1009
|
+
catch (error) {
|
|
992
1010
|
throw this._esWrapper.formatESError(error);
|
|
993
1011
|
}
|
|
994
1012
|
}
|
|
@@ -1009,8 +1027,7 @@ class ElasticSearch extends Service {
|
|
|
1009
1027
|
collection,
|
|
1010
1028
|
query,
|
|
1011
1029
|
changes,
|
|
1012
|
-
{ refresh, size = 1000, userId=null } = {})
|
|
1013
|
-
{
|
|
1030
|
+
{ refresh, size = 1000, userId = null } = {}) {
|
|
1014
1031
|
|
|
1015
1032
|
try {
|
|
1016
1033
|
const esRequest = {
|
|
@@ -1063,8 +1080,7 @@ class ElasticSearch extends Service {
|
|
|
1063
1080
|
collection,
|
|
1064
1081
|
query,
|
|
1065
1082
|
changes,
|
|
1066
|
-
{ refresh = 'false' } = {})
|
|
1067
|
-
{
|
|
1083
|
+
{ refresh = 'false' } = {}) {
|
|
1068
1084
|
const script = {
|
|
1069
1085
|
params: {},
|
|
1070
1086
|
source: ''
|
|
@@ -1072,7 +1088,7 @@ class ElasticSearch extends Service {
|
|
|
1072
1088
|
|
|
1073
1089
|
const flatChanges = extractFields(changes, { alsoExtractValues: true });
|
|
1074
1090
|
|
|
1075
|
-
for (const {key, value} of flatChanges) {
|
|
1091
|
+
for (const { key, value } of flatChanges) {
|
|
1076
1092
|
script.source += `ctx._source.${key} = params['${key}'];`;
|
|
1077
1093
|
script.params[key] = value;
|
|
1078
1094
|
}
|
|
@@ -1125,8 +1141,7 @@ class ElasticSearch extends Service {
|
|
|
1125
1141
|
collection,
|
|
1126
1142
|
query,
|
|
1127
1143
|
callback,
|
|
1128
|
-
{ size=10, scrollTTl= '5s' } = {})
|
|
1129
|
-
{
|
|
1144
|
+
{ size = 10, scrollTTl = '5s' } = {}) {
|
|
1130
1145
|
const esRequest = {
|
|
1131
1146
|
body: this._sanitizeSearchBody({ query }),
|
|
1132
1147
|
from: 0,
|
|
@@ -1149,7 +1164,7 @@ class ElasticSearch extends Service {
|
|
|
1149
1164
|
results = await new Bluebird((resolve, reject) => {
|
|
1150
1165
|
this._client.search(
|
|
1151
1166
|
esRequest,
|
|
1152
|
-
async function getMoreUntilDone(error, { body: { hits, _scroll_id } }) {
|
|
1167
|
+
async function getMoreUntilDone (error, { body: { hits, _scroll_id } }) {
|
|
1153
1168
|
if (error) {
|
|
1154
1169
|
reject(error);
|
|
1155
1170
|
return;
|
|
@@ -1233,7 +1248,7 @@ class ElasticSearch extends Service {
|
|
|
1233
1248
|
*
|
|
1234
1249
|
* @returns {Promise}
|
|
1235
1250
|
*/
|
|
1236
|
-
async createCollection (index, collection, { mappings={}, settings={} } = {}) {
|
|
1251
|
+
async createCollection (index, collection, { mappings = {}, settings = {} } = {}) {
|
|
1237
1252
|
this._assertValidIndexAndCollection(index, collection);
|
|
1238
1253
|
|
|
1239
1254
|
if (collection === HIDDEN_COLLECTION) {
|
|
@@ -1308,7 +1323,7 @@ class ElasticSearch extends Service {
|
|
|
1308
1323
|
*
|
|
1309
1324
|
* @returns {Promise.<{ dynamic, _meta, properties }>}
|
|
1310
1325
|
*/
|
|
1311
|
-
async getMapping (index, collection, { includeKuzzleMeta=false } = {}) {
|
|
1326
|
+
async getMapping (index, collection, { includeKuzzleMeta = false } = {}) {
|
|
1312
1327
|
const
|
|
1313
1328
|
indice = await this._getIndice(index, collection),
|
|
1314
1329
|
esRequest = {
|
|
@@ -1344,7 +1359,7 @@ class ElasticSearch extends Service {
|
|
|
1344
1359
|
*
|
|
1345
1360
|
* @returns {Promise}
|
|
1346
1361
|
*/
|
|
1347
|
-
async updateCollection (index, collection, { mappings={}, settings={} } = {}) {
|
|
1362
|
+
async updateCollection (index, collection, { mappings = {}, settings = {} } = {}) {
|
|
1348
1363
|
const esRequest = {
|
|
1349
1364
|
index: await this._getIndice(index, collection)
|
|
1350
1365
|
};
|
|
@@ -1362,12 +1377,12 @@ class ElasticSearch extends Service {
|
|
|
1362
1377
|
throw this._esWrapper.formatESError(error);
|
|
1363
1378
|
}
|
|
1364
1379
|
|
|
1365
|
-
if (!_.isEmpty(settings)) {
|
|
1380
|
+
if (! _.isEmpty(settings)) {
|
|
1366
1381
|
await this.updateSettings(index, collection, settings);
|
|
1367
1382
|
}
|
|
1368
1383
|
|
|
1369
1384
|
try {
|
|
1370
|
-
if (!_.isEmpty(mappings)) {
|
|
1385
|
+
if (! _.isEmpty(mappings)) {
|
|
1371
1386
|
const previousMappings = await this.getMapping(index, collection);
|
|
1372
1387
|
|
|
1373
1388
|
await this.updateMapping(index, collection, mappings);
|
|
@@ -1385,7 +1400,7 @@ class ElasticSearch extends Service {
|
|
|
1385
1400
|
};
|
|
1386
1401
|
|
|
1387
1402
|
// Rollback to previous settings
|
|
1388
|
-
if (!_.isEmpty(settings)) {
|
|
1403
|
+
if (! _.isEmpty(settings)) {
|
|
1389
1404
|
await this.updateSettings(index, collection, allowedSettings);
|
|
1390
1405
|
}
|
|
1391
1406
|
|
|
@@ -1551,8 +1566,7 @@ class ElasticSearch extends Service {
|
|
|
1551
1566
|
index,
|
|
1552
1567
|
collection,
|
|
1553
1568
|
documents,
|
|
1554
|
-
{ refresh, timeout, userId=null } = {})
|
|
1555
|
-
{
|
|
1569
|
+
{ refresh, timeout, userId = null } = {}) {
|
|
1556
1570
|
const alias = this._getAlias(index, collection);
|
|
1557
1571
|
const actionNames = ['index', 'create', 'update', 'delete'];
|
|
1558
1572
|
const dateNow = Date.now();
|
|
@@ -1920,7 +1934,7 @@ class ElasticSearch extends Service {
|
|
|
1920
1934
|
};
|
|
1921
1935
|
|
|
1922
1936
|
try {
|
|
1923
|
-
const { body: exists} = await this._client.exists(esRequest);
|
|
1937
|
+
const { body: exists } = await this._client.exists(esRequest);
|
|
1924
1938
|
|
|
1925
1939
|
return exists;
|
|
1926
1940
|
}
|
|
@@ -1929,6 +1943,60 @@ class ElasticSearch extends Service {
|
|
|
1929
1943
|
}
|
|
1930
1944
|
}
|
|
1931
1945
|
|
|
1946
|
+
/**
|
|
1947
|
+
* Returns the list of documents existing with the ids given in the body param
|
|
1948
|
+
* NB: Due to internal Kuzzle mechanism, can only be called on a single
|
|
1949
|
+
* index/collection, using the body { ids: [.. } syntax.
|
|
1950
|
+
*
|
|
1951
|
+
* @param {String} index - Index name
|
|
1952
|
+
* @param {String} collection - Collection name
|
|
1953
|
+
* @param {Array.<String>} ids - Document IDs
|
|
1954
|
+
*
|
|
1955
|
+
* @returns {Promise.<{ items: Array<{ _id, _source, _version }>, errors }>}
|
|
1956
|
+
*/
|
|
1957
|
+
async mExists (index, collection, ids) {
|
|
1958
|
+
if (ids.length === 0) {
|
|
1959
|
+
return { errors: [], item: [] };
|
|
1960
|
+
}
|
|
1961
|
+
|
|
1962
|
+
const esRequest = {
|
|
1963
|
+
_source: false,
|
|
1964
|
+
body: {
|
|
1965
|
+
docs: ids.map(_id => ({ _id })),
|
|
1966
|
+
},
|
|
1967
|
+
index: this._getAlias(index, collection)
|
|
1968
|
+
};
|
|
1969
|
+
|
|
1970
|
+
debug('mExists: %o', esRequest);
|
|
1971
|
+
|
|
1972
|
+
let body;
|
|
1973
|
+
|
|
1974
|
+
try {
|
|
1975
|
+
({ body } = await this._client.mget(esRequest)); // NOSONAR
|
|
1976
|
+
}
|
|
1977
|
+
catch (e) {
|
|
1978
|
+
throw this._esWrapper.formatESError(e);
|
|
1979
|
+
}
|
|
1980
|
+
|
|
1981
|
+
const errors = [];
|
|
1982
|
+
const items = [];
|
|
1983
|
+
|
|
1984
|
+
for (let i = 0; i < body.docs.length; i++) {
|
|
1985
|
+
const doc = body.docs[i];
|
|
1986
|
+
|
|
1987
|
+
if (doc.found) {
|
|
1988
|
+
items.push(
|
|
1989
|
+
doc._id,
|
|
1990
|
+
);
|
|
1991
|
+
}
|
|
1992
|
+
else {
|
|
1993
|
+
errors.push(doc._id);
|
|
1994
|
+
}
|
|
1995
|
+
}
|
|
1996
|
+
|
|
1997
|
+
return { errors, items };
|
|
1998
|
+
}
|
|
1999
|
+
|
|
1932
2000
|
/**
|
|
1933
2001
|
* Returns true if the index exists
|
|
1934
2002
|
*
|
|
@@ -1985,8 +2053,7 @@ class ElasticSearch extends Service {
|
|
|
1985
2053
|
index,
|
|
1986
2054
|
collection,
|
|
1987
2055
|
documents,
|
|
1988
|
-
{ refresh, timeout, userId=null } = {})
|
|
1989
|
-
{
|
|
2056
|
+
{ refresh, timeout, userId = null } = {}) {
|
|
1990
2057
|
const
|
|
1991
2058
|
alias = this._getAlias(index, collection),
|
|
1992
2059
|
kuzzleMeta = {
|
|
@@ -2004,9 +2071,9 @@ class ElasticSearch extends Service {
|
|
|
2004
2071
|
} = this._extractMDocuments(documents, kuzzleMeta, { prepareMGet: true });
|
|
2005
2072
|
|
|
2006
2073
|
// prepare the mget request, but only for document having a specified id
|
|
2007
|
-
const {body} = documentsToGet.length > 0
|
|
2008
|
-
? await this._client.mget({body: {docs: documentsToGet}, index: alias})
|
|
2009
|
-
: {body: {docs: []}};
|
|
2074
|
+
const { body } = documentsToGet.length > 0
|
|
2075
|
+
? await this._client.mget({ body: { docs: documentsToGet }, index: alias })
|
|
2076
|
+
: { body: { docs: [] } };
|
|
2010
2077
|
|
|
2011
2078
|
const
|
|
2012
2079
|
existingDocuments = body.docs,
|
|
@@ -2080,8 +2147,7 @@ class ElasticSearch extends Service {
|
|
|
2080
2147
|
index,
|
|
2081
2148
|
collection,
|
|
2082
2149
|
documents,
|
|
2083
|
-
{ refresh, timeout, userId=null, injectKuzzleMeta=true, limits=true } = {})
|
|
2084
|
-
{
|
|
2150
|
+
{ refresh, timeout, userId = null, injectKuzzleMeta = true, limits = true } = {}) {
|
|
2085
2151
|
let kuzzleMeta = {};
|
|
2086
2152
|
|
|
2087
2153
|
if (injectKuzzleMeta) {
|
|
@@ -2144,8 +2210,7 @@ class ElasticSearch extends Service {
|
|
|
2144
2210
|
index,
|
|
2145
2211
|
collection,
|
|
2146
2212
|
documents,
|
|
2147
|
-
{ refresh, retryOnConflict = 0, timeout, userId=null } = {})
|
|
2148
|
-
{
|
|
2213
|
+
{ refresh, retryOnConflict = 0, timeout, userId = null } = {}) {
|
|
2149
2214
|
const
|
|
2150
2215
|
alias = this._getAlias(index, collection),
|
|
2151
2216
|
toImport = [],
|
|
@@ -2236,8 +2301,7 @@ class ElasticSearch extends Service {
|
|
|
2236
2301
|
index,
|
|
2237
2302
|
collection,
|
|
2238
2303
|
documents,
|
|
2239
|
-
{ refresh, retryOnConflict = 0, timeout, userId=null } = {})
|
|
2240
|
-
{
|
|
2304
|
+
{ refresh, retryOnConflict = 0, timeout, userId = null } = {}) {
|
|
2241
2305
|
const alias = this._getAlias(index, collection);
|
|
2242
2306
|
const esRequest = {
|
|
2243
2307
|
body: [],
|
|
@@ -2330,8 +2394,7 @@ class ElasticSearch extends Service {
|
|
|
2330
2394
|
index,
|
|
2331
2395
|
collection,
|
|
2332
2396
|
documents,
|
|
2333
|
-
{ refresh, timeout, userId=null } = {})
|
|
2334
|
-
{
|
|
2397
|
+
{ refresh, timeout, userId = null } = {}) {
|
|
2335
2398
|
const
|
|
2336
2399
|
alias = this._getAlias(index, collection),
|
|
2337
2400
|
kuzzleMeta = {
|
|
@@ -2355,7 +2418,7 @@ class ElasticSearch extends Service {
|
|
|
2355
2418
|
return { errors: rejected, items: [] };
|
|
2356
2419
|
}
|
|
2357
2420
|
|
|
2358
|
-
const {body} = await this._client.mget({
|
|
2421
|
+
const { body } = await this._client.mget({
|
|
2359
2422
|
body: { docs: documentsToGet },
|
|
2360
2423
|
index: alias
|
|
2361
2424
|
});
|
|
@@ -2421,8 +2484,7 @@ class ElasticSearch extends Service {
|
|
|
2421
2484
|
index,
|
|
2422
2485
|
collection,
|
|
2423
2486
|
ids,
|
|
2424
|
-
{ refresh, timeout } = {})
|
|
2425
|
-
{
|
|
2487
|
+
{ refresh, timeout } = {}) {
|
|
2426
2488
|
const
|
|
2427
2489
|
query = { ids: { values: [] } },
|
|
2428
2490
|
validIds = [],
|
|
@@ -2450,7 +2512,7 @@ class ElasticSearch extends Service {
|
|
|
2450
2512
|
/* end critical code section */
|
|
2451
2513
|
await this.refreshCollection(index, collection);
|
|
2452
2514
|
|
|
2453
|
-
const {items} = await this.mGet(index, collection, validIds);
|
|
2515
|
+
const { items } = await this.mGet(index, collection, validIds);
|
|
2454
2516
|
|
|
2455
2517
|
let idx = 0;
|
|
2456
2518
|
|
|
@@ -2501,7 +2563,7 @@ class ElasticSearch extends Service {
|
|
|
2501
2563
|
*
|
|
2502
2564
|
* @returns {Promise.<Object[]>} results
|
|
2503
2565
|
*/
|
|
2504
|
-
async _mExecute (esRequest, documents, partialErrors, { limits=true } = {}) {
|
|
2566
|
+
async _mExecute (esRequest, documents, partialErrors, { limits = true } = {}) {
|
|
2505
2567
|
assertWellFormedRefresh(esRequest);
|
|
2506
2568
|
|
|
2507
2569
|
if ( limits
|
|
@@ -2584,7 +2646,7 @@ class ElasticSearch extends Service {
|
|
|
2584
2646
|
*
|
|
2585
2647
|
* @returns {Object} { rejected, extractedDocuments, documentsToGet }
|
|
2586
2648
|
*/
|
|
2587
|
-
_extractMDocuments (documents, metadata, { prepareMGet=false, requireId=false, prepareMUpsert=false } = {}) {
|
|
2649
|
+
_extractMDocuments (documents, metadata, { prepareMGet = false, requireId = false, prepareMUpsert = false } = {}) {
|
|
2588
2650
|
const
|
|
2589
2651
|
rejected = [],
|
|
2590
2652
|
extractedDocuments = [],
|
|
@@ -2598,21 +2660,21 @@ class ElasticSearch extends Service {
|
|
|
2598
2660
|
for (let i = 0; i < documents.length; i++) {
|
|
2599
2661
|
const document = documents[i];
|
|
2600
2662
|
|
|
2601
|
-
if (!isPlainObject(document.body) && !prepareMUpsert) {
|
|
2663
|
+
if (! isPlainObject(document.body) && ! prepareMUpsert) {
|
|
2602
2664
|
rejected.push({
|
|
2603
2665
|
document,
|
|
2604
2666
|
reason: 'document body must be an object',
|
|
2605
2667
|
status: 400
|
|
2606
2668
|
});
|
|
2607
2669
|
}
|
|
2608
|
-
else if (!isPlainObject(document.changes) && prepareMUpsert) {
|
|
2670
|
+
else if (! isPlainObject(document.changes) && prepareMUpsert) {
|
|
2609
2671
|
rejected.push({
|
|
2610
2672
|
document,
|
|
2611
2673
|
reason: 'document changes must be an object',
|
|
2612
2674
|
status: 400
|
|
2613
2675
|
});
|
|
2614
2676
|
}
|
|
2615
|
-
else if (prepareMUpsert && document.default && !isPlainObject(document.default)) {
|
|
2677
|
+
else if (prepareMUpsert && document.default && ! isPlainObject(document.default)) {
|
|
2616
2678
|
rejected.push({
|
|
2617
2679
|
document,
|
|
2618
2680
|
reason: 'document default must be an object',
|
|
@@ -2678,7 +2740,7 @@ class ElasticSearch extends Service {
|
|
|
2678
2740
|
: [...ROOT_MAPPING_PROPERTIES, ...CHILD_MAPPING_PROPERTIES];
|
|
2679
2741
|
|
|
2680
2742
|
for (const property of properties) {
|
|
2681
|
-
if (check && !mappingProperties.includes(property)) {
|
|
2743
|
+
if (check && ! mappingProperties.includes(property)) {
|
|
2682
2744
|
const currentPath = [...path, property].join('.');
|
|
2683
2745
|
|
|
2684
2746
|
throw kerror.get(
|
|
@@ -2778,7 +2840,7 @@ class ElasticSearch extends Service {
|
|
|
2778
2840
|
* @throws If there is not exactly one alias associated
|
|
2779
2841
|
*/
|
|
2780
2842
|
async _getAliasFromIndice (indice) {
|
|
2781
|
-
const { body } = await this._client.indices.getAlias({ index: indice});
|
|
2843
|
+
const { body } = await this._client.indices.getAlias({ index: indice });
|
|
2782
2844
|
const aliases = Object.keys(body[indice].aliases);
|
|
2783
2845
|
|
|
2784
2846
|
if (aliases.length < 1) {
|
|
@@ -2808,9 +2870,9 @@ class ElasticSearch extends Service {
|
|
|
2808
2870
|
indice[INDEX_PREFIX_POSITION_IN_INDICE] === this._indexPrefix
|
|
2809
2871
|
&& ! aliases.some(alias => alias.indice === indice));
|
|
2810
2872
|
|
|
2811
|
-
const esRequest = { body: { actions
|
|
2873
|
+
const esRequest = { body: { actions: [] } };
|
|
2812
2874
|
for (const indice of indicesWithoutAlias) {
|
|
2813
|
-
esRequest.body.actions.push({ add
|
|
2875
|
+
esRequest.body.actions.push({ add: { alias: `${ALIAS_PREFIX}${indice}`, index: indice } });
|
|
2814
2876
|
}
|
|
2815
2877
|
|
|
2816
2878
|
if (esRequest.body.actions.length > 0) {
|
|
@@ -2829,11 +2891,11 @@ class ElasticSearch extends Service {
|
|
|
2829
2891
|
* @param {String} collection
|
|
2830
2892
|
*/
|
|
2831
2893
|
_assertValidIndexAndCollection (index, collection = null) {
|
|
2832
|
-
if (!this.isIndexNameValid(index)) {
|
|
2894
|
+
if (! this.isIndexNameValid(index)) {
|
|
2833
2895
|
throw kerror.get('invalid_index_name', index);
|
|
2834
2896
|
}
|
|
2835
2897
|
|
|
2836
|
-
if (collection !== null && !this.isCollectionNameValid(collection)) {
|
|
2898
|
+
if (collection !== null && ! this.isCollectionNameValid(collection)) {
|
|
2837
2899
|
throw kerror.get('invalid_collection_name', collection);
|
|
2838
2900
|
}
|
|
2839
2901
|
}
|
|
@@ -2848,7 +2910,7 @@ class ElasticSearch extends Service {
|
|
|
2848
2910
|
_extractIndex (alias) {
|
|
2849
2911
|
return alias.substr(
|
|
2850
2912
|
INDEX_PREFIX_POSITION_IN_ALIAS + 1,
|
|
2851
|
-
alias.indexOf(NAME_SEPARATOR) - INDEX_PREFIX_POSITION_IN_ALIAS -1 );
|
|
2913
|
+
alias.indexOf(NAME_SEPARATOR) - INDEX_PREFIX_POSITION_IN_ALIAS - 1 );
|
|
2852
2914
|
}
|
|
2853
2915
|
|
|
2854
2916
|
/**
|
|
@@ -2966,7 +3028,7 @@ class ElasticSearch extends Service {
|
|
|
2966
3028
|
_sanitizeSearchBody (searchBody) {
|
|
2967
3029
|
// Only allow a whitelist of top level properties
|
|
2968
3030
|
for (const key of Object.keys(searchBody)) {
|
|
2969
|
-
if (!this.searchBodyKeys.includes(key)) {
|
|
3031
|
+
if (searchBody[key] !== undefined && ! this.searchBodyKeys.includes(key)) {
|
|
2970
3032
|
throw kerror.get('invalid_search_query', key);
|
|
2971
3033
|
}
|
|
2972
3034
|
}
|
|
@@ -3032,7 +3094,7 @@ class ElasticSearch extends Service {
|
|
|
3032
3094
|
async clearScroll (id) {
|
|
3033
3095
|
if (id) {
|
|
3034
3096
|
debug('clearing scroll: %s', id);
|
|
3035
|
-
await this._client.clearScroll({scrollId: id});
|
|
3097
|
+
await this._client.clearScroll({ scrollId: id });
|
|
3036
3098
|
}
|
|
3037
3099
|
}
|
|
3038
3100
|
|
|
@@ -3177,7 +3239,7 @@ function findDynamic (mappings, path = [], results = {}) {
|
|
|
3177
3239
|
* @param {Object} esRequest
|
|
3178
3240
|
* @throws
|
|
3179
3241
|
*/
|
|
3180
|
-
function assertNoRouting(esRequest) {
|
|
3242
|
+
function assertNoRouting (esRequest) {
|
|
3181
3243
|
if (esRequest.body._routing) {
|
|
3182
3244
|
throw kerror.get('no_routing');
|
|
3183
3245
|
}
|
|
@@ -3189,7 +3251,7 @@ function assertNoRouting(esRequest) {
|
|
|
3189
3251
|
* @param {Object} esRequest
|
|
3190
3252
|
* @throws
|
|
3191
3253
|
*/
|
|
3192
|
-
function assertWellFormedRefresh(esRequest) {
|
|
3254
|
+
function assertWellFormedRefresh (esRequest) {
|
|
3193
3255
|
if (! ['wait_for', 'false', false, undefined].includes(esRequest.refresh)) {
|
|
3194
3256
|
throw kerror.get('invalid_argument', 'refresh', '"wait_for", false');
|
|
3195
3257
|
}
|
|
@@ -3238,7 +3300,7 @@ function _isObjectNameValid (name) {
|
|
|
3238
3300
|
let valid = true;
|
|
3239
3301
|
|
|
3240
3302
|
for (let i = 0; valid && i < FORBIDDEN_CHARS.length; i++) {
|
|
3241
|
-
valid = !name.includes(FORBIDDEN_CHARS[i]);
|
|
3303
|
+
valid = ! name.includes(FORBIDDEN_CHARS[i]);
|
|
3242
3304
|
}
|
|
3243
3305
|
|
|
3244
3306
|
return valid;
|
|
@@ -154,7 +154,7 @@ const errorMessagesMapping = [
|
|
|
154
154
|
];
|
|
155
155
|
|
|
156
156
|
class ESWrapper {
|
|
157
|
-
constructor(client) {
|
|
157
|
+
constructor (client) {
|
|
158
158
|
this.client = client;
|
|
159
159
|
}
|
|
160
160
|
|
|
@@ -257,8 +257,7 @@ class ESWrapper {
|
|
|
257
257
|
|
|
258
258
|
// empty query throws exception with ES 7
|
|
259
259
|
if ( error.meta.body.error.type === 'parsing_exception'
|
|
260
|
-
&& _.get(error, 'meta.body.error.caused_by.type') === 'illegal_argument_exception')
|
|
261
|
-
{
|
|
260
|
+
&& _.get(error, 'meta.body.error.caused_by.type') === 'illegal_argument_exception') {
|
|
262
261
|
errorMessage = error.meta.body.error.caused_by.reason;
|
|
263
262
|
}
|
|
264
263
|
}
|
|
@@ -8,7 +8,7 @@ import { KuzzleRequest } from '../api/request';
|
|
|
8
8
|
* actions: {
|
|
9
9
|
* sayHello: {
|
|
10
10
|
* handler: async request => `Hello, ${request.input.args.name}`,
|
|
11
|
-
* http: [{ verb: '
|
|
11
|
+
* http: [{ verb: 'post', path: '/greeting/hello/:name' }]
|
|
12
12
|
* }
|
|
13
13
|
* }
|
|
14
14
|
* }
|
|
@@ -22,7 +22,7 @@ export declare type ControllerDefinition = {
|
|
|
22
22
|
* sayHello: {
|
|
23
23
|
* handler: async request => `Hello, ${request.input.args.name}`,
|
|
24
24
|
* http: [{
|
|
25
|
-
* verb: '
|
|
25
|
+
* verb: 'post',
|
|
26
26
|
* path: '/greeting/hello/:name',
|
|
27
27
|
* openapi: {
|
|
28
28
|
* description: "Simply say hello",
|
|
@@ -68,7 +68,7 @@ export declare type HttpRoute = {
|
|
|
68
68
|
/**
|
|
69
69
|
* HTTP verb.
|
|
70
70
|
*/
|
|
71
|
-
verb: 'get' | 'post' | 'put' | 'delete' | '
|
|
71
|
+
verb: 'get' | 'head' | 'post' | 'put' | 'delete' | 'patch' | 'options';
|
|
72
72
|
/**
|
|
73
73
|
* Route path.
|
|
74
74
|
* A route starting with `/` will be prefixed by `/_` otherwise the route
|