kuzzle 2.17.8 → 2.19.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/index.d.ts +1 -0
- package/index.js +3 -0
- package/lib/api/controllers/adminController.js +9 -0
- package/lib/api/controllers/authController.js +8 -2
- package/lib/api/controllers/debugController.d.ts +59 -0
- package/lib/api/controllers/debugController.js +285 -0
- package/lib/api/controllers/documentController.js +49 -31
- package/lib/api/controllers/index.js +1 -0
- package/lib/api/controllers/indexController.js +10 -6
- package/lib/api/controllers/securityController.js +81 -43
- package/lib/api/controllers/serverController.js +2 -1
- package/lib/api/documentExtractor.js +51 -9
- package/lib/api/funnel.js +30 -8
- package/lib/api/httpRoutes.js +8 -1
- package/lib/api/openapi/OpenApiManager.js +3 -0
- package/lib/api/openapi/components/document/get.yaml +1 -1
- package/lib/api/openapi/components/document/update.yaml +1 -1
- package/lib/api/openapi/components/index.d.ts +1 -0
- package/lib/api/openapi/components/index.js +1 -0
- package/lib/api/openapi/components/security/index.d.ts +2 -0
- package/lib/api/openapi/components/security/index.js +10 -0
- package/lib/api/openapi/components/security/upsertUser.yaml +59 -0
- package/lib/api/request/kuzzleRequest.d.ts +58 -4
- package/lib/api/request/kuzzleRequest.js +163 -31
- package/lib/api/request/requestResponse.js +25 -0
- package/lib/cluster/idCardHandler.js +1 -1
- package/lib/config/default.config.js +3 -0
- package/lib/config/documentEventAliases.d.ts +7 -0
- package/lib/config/documentEventAliases.js +26 -12
- package/lib/core/backend/backend.d.ts +4 -0
- package/lib/core/backend/backend.js +9 -0
- package/lib/core/backend/backendController.d.ts +7 -1
- package/lib/core/backend/backendController.js +15 -3
- package/lib/core/network/protocols/httpwsProtocol.js +14 -6
- package/lib/core/plugin/plugin.js +7 -0
- package/lib/core/shared/sdk/embeddedSdk.d.ts +3 -3
- package/lib/core/shared/sdk/embeddedSdk.js +33 -0
- package/lib/core/shared/sdk/funnelProtocol.d.ts +1 -2
- package/lib/kerror/codes/0-core.json +35 -0
- package/lib/kerror/codes/1-services.json +1 -1
- package/lib/kerror/codes/2-api.json +6 -0
- package/lib/kerror/errors/kuzzleError.d.ts +1 -1
- package/lib/kuzzle/kuzzle.d.ts +1 -1
- package/lib/kuzzle/kuzzle.js +27 -8
- package/lib/model/security/user.js +5 -6
- package/lib/model/storage/apiKey.js +1 -6
- package/lib/service/storage/elasticsearch.js +143 -47
- package/lib/types/DebugModule.d.ts +23 -0
- package/lib/types/DebugModule.js +39 -0
- package/lib/types/config/SecurityConfiguration.d.ts +10 -0
- package/lib/types/index.d.ts +0 -1
- package/lib/types/index.js +0 -1
- package/lib/util/crypto.d.ts +1 -0
- package/lib/util/crypto.js +12 -0
- package/lib/util/dump-collection.d.ts +35 -0
- package/lib/util/dump-collection.js +11 -8
- package/lib/util/name-generator.d.ts +79 -0
- package/lib/util/name-generator.js +1409 -1345
- package/lib/util/time.d.ts +1 -0
- package/lib/util/time.js +9 -0
- package/package.json +19 -21
- package/lib/core/security/README.md +0 -224
- package/lib/core/shared/README.md +0 -3
- package/package-lock.json +0 -8403
|
@@ -182,7 +182,7 @@ class ElasticSearch extends Service {
|
|
|
182
182
|
/**
|
|
183
183
|
* Translate Koncorde filters to Elasticsearch query
|
|
184
184
|
*
|
|
185
|
-
* @param {Object}
|
|
185
|
+
* @param {Object} filters - Set of valid Koncorde filters
|
|
186
186
|
* @returns {Object} Equivalent Elasticsearch query
|
|
187
187
|
*/
|
|
188
188
|
translateKoncordeFilters (filters) {
|
|
@@ -243,7 +243,8 @@ class ElasticSearch extends Service {
|
|
|
243
243
|
continue;
|
|
244
244
|
}
|
|
245
245
|
|
|
246
|
-
const
|
|
246
|
+
const aliases = await this._getAliasFromIndice(indice);
|
|
247
|
+
const alias = aliases[0];
|
|
247
248
|
const indexName = this._extractIndex(alias);
|
|
248
249
|
const collectionName = this._extractCollection(alias);
|
|
249
250
|
|
|
@@ -303,20 +304,20 @@ class ElasticSearch extends Service {
|
|
|
303
304
|
}
|
|
304
305
|
}
|
|
305
306
|
|
|
306
|
-
|
|
307
|
+
const stringifiedScrollInfo = await global.kuzzle.ask('core:cache:internal:get', cacheKey);
|
|
307
308
|
|
|
308
|
-
if (!
|
|
309
|
+
if (! stringifiedScrollInfo) {
|
|
309
310
|
throw kerror.get('unknown_scroll_id');
|
|
310
311
|
}
|
|
311
312
|
|
|
312
|
-
|
|
313
|
+
const scrollInfo = JSON.parse(stringifiedScrollInfo);
|
|
313
314
|
|
|
314
315
|
try {
|
|
315
316
|
const { body } = await this._client.scroll(esRequest);
|
|
316
317
|
|
|
317
|
-
fetched += body.hits.hits.length;
|
|
318
|
+
scrollInfo.fetched += body.hits.hits.length;
|
|
318
319
|
|
|
319
|
-
if (fetched >= body.hits.total.value) {
|
|
320
|
+
if (scrollInfo.fetched >= body.hits.total.value) {
|
|
320
321
|
debug('Last scroll page fetched: deleting scroll %s', body._scroll_id);
|
|
321
322
|
await global.kuzzle.ask('core:cache:internal:del', cacheKey);
|
|
322
323
|
await this.clearScroll(body._scroll_id);
|
|
@@ -325,15 +326,15 @@ class ElasticSearch extends Service {
|
|
|
325
326
|
await global.kuzzle.ask(
|
|
326
327
|
'core:cache:internal:store',
|
|
327
328
|
cacheKey,
|
|
328
|
-
|
|
329
|
+
JSON.stringify(scrollInfo),
|
|
329
330
|
{
|
|
330
331
|
ttl: ms(_scrollTTL) || this.scrollTTL,
|
|
331
332
|
});
|
|
332
333
|
}
|
|
333
334
|
|
|
334
|
-
body.remaining = body.hits.total.value - fetched;
|
|
335
|
+
body.remaining = body.hits.total.value - scrollInfo.fetched;
|
|
335
336
|
|
|
336
|
-
return await this._formatSearchResult(body);
|
|
337
|
+
return await this._formatSearchResult(body, scrollInfo);
|
|
337
338
|
}
|
|
338
339
|
catch (error) {
|
|
339
340
|
throw this._esWrapper.formatESError(error);
|
|
@@ -401,35 +402,101 @@ class ElasticSearch extends Service {
|
|
|
401
402
|
await global.kuzzle.ask(
|
|
402
403
|
'core:cache:internal:store',
|
|
403
404
|
SCROLL_CACHE_PREFIX + global.kuzzle.hash(body._scroll_id),
|
|
404
|
-
|
|
405
|
+
JSON.stringify({
|
|
406
|
+
collection,
|
|
407
|
+
fetched: body.hits.hits.length,
|
|
408
|
+
index,
|
|
409
|
+
targets
|
|
410
|
+
}),
|
|
405
411
|
{ ttl });
|
|
406
412
|
|
|
407
413
|
body.remaining = body.hits.total.value - body.hits.hits.length;
|
|
408
414
|
}
|
|
409
415
|
|
|
410
|
-
return await this._formatSearchResult(body
|
|
416
|
+
return await this._formatSearchResult(body, {
|
|
417
|
+
collection,
|
|
418
|
+
index,
|
|
419
|
+
targets
|
|
420
|
+
});
|
|
411
421
|
}
|
|
412
422
|
catch (error) {
|
|
413
423
|
throw this._esWrapper.formatESError(error);
|
|
414
424
|
}
|
|
415
425
|
}
|
|
416
426
|
|
|
417
|
-
|
|
427
|
+
/**
|
|
428
|
+
* Generate a map that associate an alias to a pair of index and collection
|
|
429
|
+
*
|
|
430
|
+
* @param {*} targets
|
|
431
|
+
* @returns
|
|
432
|
+
*/
|
|
433
|
+
_mapTargetsToAlias (targets) {
|
|
434
|
+
const aliasToTargets = {};
|
|
435
|
+
|
|
436
|
+
for (const target of targets) {
|
|
437
|
+
for (const targetCollection of target.collections) {
|
|
438
|
+
const alias = this._getAlias(target.index, targetCollection);
|
|
439
|
+
if (! aliasToTargets[alias]) {
|
|
440
|
+
aliasToTargets[alias] = {
|
|
441
|
+
collection: targetCollection,
|
|
442
|
+
index: target.index,
|
|
443
|
+
};
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
|
|
448
|
+
return aliasToTargets;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
async _formatSearchResult (body, searchInfo = {}) {
|
|
452
|
+
let aliasToTargets = {};
|
|
453
|
+
const aliasCache = new Map();
|
|
454
|
+
|
|
455
|
+
if (searchInfo.targets) {
|
|
456
|
+
/**
|
|
457
|
+
* We need to map the alias to the target index and collection,
|
|
458
|
+
* so we can later retrieve informations about an index & collection
|
|
459
|
+
* based on its alias.
|
|
460
|
+
*/
|
|
461
|
+
aliasToTargets = this._mapTargetsToAlias(searchInfo.targets);
|
|
462
|
+
}
|
|
418
463
|
|
|
419
464
|
const formatHit = async (hit) => {
|
|
420
|
-
let
|
|
465
|
+
let index = searchInfo.index;
|
|
466
|
+
let collection = searchInfo.collection;
|
|
467
|
+
|
|
468
|
+
/**
|
|
469
|
+
* If the search has been done on multiple targets, we need to
|
|
470
|
+
* retrieve the appropriate index and collection based on the alias
|
|
471
|
+
*/
|
|
472
|
+
if (hit._index && searchInfo.targets) {
|
|
473
|
+
|
|
474
|
+
// Caching to reduce call to ES
|
|
475
|
+
let aliases = aliasCache.get(hit._index);
|
|
476
|
+
if (! aliases) {
|
|
477
|
+
// Retrieve all the alias associated to one index
|
|
478
|
+
aliases = await this._getAliasFromIndice(hit._index);
|
|
479
|
+
aliasCache.set(hit._index, aliases);
|
|
480
|
+
}
|
|
421
481
|
|
|
422
|
-
|
|
423
|
-
|
|
482
|
+
/**
|
|
483
|
+
* Since multiple alias can point to the same index in ES, we need to
|
|
484
|
+
* find the first alias that exists in the map of aliases associated
|
|
485
|
+
* to the targets.
|
|
486
|
+
*/
|
|
487
|
+
const alias = aliases.find(_alias => aliasToTargets[_alias]);
|
|
488
|
+
// Retrieve index and collection information based on the matching alias
|
|
489
|
+
index = aliasToTargets[alias].index;
|
|
490
|
+
collection = aliasToTargets[alias].collection;
|
|
424
491
|
}
|
|
425
492
|
|
|
426
493
|
return {
|
|
427
494
|
_id: hit._id,
|
|
428
495
|
_score: hit._score,
|
|
429
496
|
_source: hit._source,
|
|
430
|
-
collection
|
|
497
|
+
collection,
|
|
431
498
|
highlight: hit.highlight,
|
|
432
|
-
index
|
|
499
|
+
index,
|
|
433
500
|
};
|
|
434
501
|
};
|
|
435
502
|
|
|
@@ -1368,10 +1435,9 @@ class ElasticSearch extends Service {
|
|
|
1368
1435
|
// rollback the whole operation. Since mappings can't be rollback, we try to
|
|
1369
1436
|
// update the settings first, then the mappings and we rollback the settings
|
|
1370
1437
|
// if putMappings fail.
|
|
1371
|
-
let
|
|
1438
|
+
let indexSettings;
|
|
1372
1439
|
try {
|
|
1373
|
-
|
|
1374
|
-
indiceSettings = response.body[esRequest.index].settings;
|
|
1440
|
+
indexSettings = await this._getSettings(esRequest);
|
|
1375
1441
|
}
|
|
1376
1442
|
catch (error) {
|
|
1377
1443
|
throw this._esWrapper.formatESError(error);
|
|
@@ -1393,11 +1459,7 @@ class ElasticSearch extends Service {
|
|
|
1393
1459
|
}
|
|
1394
1460
|
}
|
|
1395
1461
|
catch (error) {
|
|
1396
|
-
const allowedSettings =
|
|
1397
|
-
index: _.omit(
|
|
1398
|
-
indiceSettings.index,
|
|
1399
|
-
['creation_date', 'provided_name', 'uuid', 'version'])
|
|
1400
|
-
};
|
|
1462
|
+
const allowedSettings = this.getAllowedIndexSettings(indexSettings);
|
|
1401
1463
|
|
|
1402
1464
|
// Rollback to previous settings
|
|
1403
1465
|
if (! _.isEmpty(settings)) {
|
|
@@ -1410,6 +1472,20 @@ class ElasticSearch extends Service {
|
|
|
1410
1472
|
return null;
|
|
1411
1473
|
}
|
|
1412
1474
|
|
|
1475
|
+
/**
|
|
1476
|
+
* Given index settings we return a new version of index settings
|
|
1477
|
+
* only with allowed settings that can be set (during update or create index).
|
|
1478
|
+
* @param indexSettings the index settings
|
|
1479
|
+
* @returns {{index: *}} a new index settings with only allowed settings.
|
|
1480
|
+
*/
|
|
1481
|
+
getAllowedIndexSettings (indexSettings) {
|
|
1482
|
+
return {
|
|
1483
|
+
index: _.omit(
|
|
1484
|
+
indexSettings.index,
|
|
1485
|
+
['creation_date', 'provided_name', 'uuid', 'version'])
|
|
1486
|
+
};
|
|
1487
|
+
}
|
|
1488
|
+
|
|
1413
1489
|
/**
|
|
1414
1490
|
* Sends an empty UpdateByQuery request to update the search index
|
|
1415
1491
|
*
|
|
@@ -1516,7 +1592,7 @@ class ElasticSearch extends Service {
|
|
|
1516
1592
|
}
|
|
1517
1593
|
|
|
1518
1594
|
/**
|
|
1519
|
-
* Empties the content of a collection. Keep the existing mapping.
|
|
1595
|
+
* Empties the content of a collection. Keep the existing mapping and settings.
|
|
1520
1596
|
*
|
|
1521
1597
|
* @param {String} index - Index name
|
|
1522
1598
|
* @param {String} collection - Collection name
|
|
@@ -1525,6 +1601,7 @@ class ElasticSearch extends Service {
|
|
|
1525
1601
|
*/
|
|
1526
1602
|
async truncateCollection (index, collection) {
|
|
1527
1603
|
let mappings;
|
|
1604
|
+
let settings;
|
|
1528
1605
|
|
|
1529
1606
|
const esRequest = {
|
|
1530
1607
|
index: await this._getIndice(index, collection)
|
|
@@ -1532,7 +1609,11 @@ class ElasticSearch extends Service {
|
|
|
1532
1609
|
|
|
1533
1610
|
try {
|
|
1534
1611
|
mappings = await this.getMapping(index, collection, { includeKuzzleMeta: true });
|
|
1535
|
-
|
|
1612
|
+
settings = await this._getSettings(esRequest);
|
|
1613
|
+
settings = {
|
|
1614
|
+
...settings,
|
|
1615
|
+
...this.getAllowedIndexSettings(settings)
|
|
1616
|
+
};
|
|
1536
1617
|
await this._client.indices.delete(esRequest);
|
|
1537
1618
|
|
|
1538
1619
|
await this._client.indices.create({
|
|
@@ -1541,7 +1622,8 @@ class ElasticSearch extends Service {
|
|
|
1541
1622
|
aliases: {
|
|
1542
1623
|
[this._getAlias(index, collection)]: {}
|
|
1543
1624
|
},
|
|
1544
|
-
mappings
|
|
1625
|
+
mappings,
|
|
1626
|
+
settings
|
|
1545
1627
|
}
|
|
1546
1628
|
});
|
|
1547
1629
|
|
|
@@ -1819,22 +1901,14 @@ class ElasticSearch extends Service {
|
|
|
1819
1901
|
index: await this._getIndice(index, collection)
|
|
1820
1902
|
};
|
|
1821
1903
|
|
|
1822
|
-
const mutex = new Mutex(`hiddenCollection/delete/${index}`);
|
|
1823
1904
|
try {
|
|
1824
1905
|
await this._client.indices.delete(esRequest);
|
|
1825
1906
|
|
|
1826
|
-
await
|
|
1827
|
-
|
|
1828
|
-
if (! await this._hasHiddenCollection(index)) {
|
|
1829
|
-
await this._createHiddenCollection(index);
|
|
1830
|
-
}
|
|
1907
|
+
await this._createHiddenCollection(index);
|
|
1831
1908
|
}
|
|
1832
1909
|
catch (e) {
|
|
1833
1910
|
throw this._esWrapper.formatESError(e);
|
|
1834
1911
|
}
|
|
1835
|
-
finally {
|
|
1836
|
-
await mutex.unlock();
|
|
1837
|
-
}
|
|
1838
1912
|
|
|
1839
1913
|
return null;
|
|
1840
1914
|
}
|
|
@@ -2476,7 +2550,7 @@ class ElasticSearch extends Service {
|
|
|
2476
2550
|
*
|
|
2477
2551
|
* @param {String} index - Index name
|
|
2478
2552
|
* @param {String} collection - Collection name
|
|
2479
|
-
* @param {Array.<String>}
|
|
2553
|
+
* @param {Array.<String>} ids - Documents IDs
|
|
2480
2554
|
* @param {Object} options - timeout (undefined), refresh (undefined)
|
|
2481
2555
|
*
|
|
2482
2556
|
* @returns {Promise.<{ documents, errors }>
|
|
@@ -2792,12 +2866,24 @@ class ElasticSearch extends Service {
|
|
|
2792
2866
|
throw kerror.get('unknown_index_collection');
|
|
2793
2867
|
}
|
|
2794
2868
|
else if (body.length > 1) {
|
|
2795
|
-
throw kerror.get('multiple_indice_alias',
|
|
2869
|
+
throw kerror.get('multiple_indice_alias', `"alias" starting with "${ALIAS_PREFIX}"`, '"indices"');
|
|
2796
2870
|
}
|
|
2797
2871
|
|
|
2798
2872
|
return body[0].index;
|
|
2799
2873
|
}
|
|
2800
2874
|
|
|
2875
|
+
/**
|
|
2876
|
+
* Given an ES Request returns the settings of the corresponding indice.
|
|
2877
|
+
*
|
|
2878
|
+
* @param esRequest the ES Request with wanted settings.
|
|
2879
|
+
* @return {Promise<*>} the settings of the indice.
|
|
2880
|
+
* @private
|
|
2881
|
+
*/
|
|
2882
|
+
async _getSettings (esRequest) {
|
|
2883
|
+
const response = await this._client.indices.getSettings(esRequest);
|
|
2884
|
+
return response.body[esRequest.index].settings;
|
|
2885
|
+
}
|
|
2886
|
+
|
|
2801
2887
|
/**
|
|
2802
2888
|
* Given index + collection, returns an available indice name.
|
|
2803
2889
|
* Use this function when creating the associated indice. Otherwise use `_getAlias`.
|
|
@@ -2838,20 +2924,19 @@ class ElasticSearch extends Service {
|
|
|
2838
2924
|
* @param {String} indice
|
|
2839
2925
|
*
|
|
2840
2926
|
* @returns {String} Alias name (eg: '@&nepali.liia')
|
|
2841
|
-
* @throws If there is not exactly one alias associated
|
|
2927
|
+
* @throws If there is not exactly one alias associated that is prefixed with @
|
|
2842
2928
|
*/
|
|
2843
2929
|
async _getAliasFromIndice (indice) {
|
|
2844
2930
|
const { body } = await this._client.indices.getAlias({ index: indice });
|
|
2845
|
-
const aliases =
|
|
2931
|
+
const aliases =
|
|
2932
|
+
Object.keys(body[indice].aliases)
|
|
2933
|
+
.filter(alias => alias.startsWith(ALIAS_PREFIX));
|
|
2846
2934
|
|
|
2847
2935
|
if (aliases.length < 1) {
|
|
2848
2936
|
throw kerror.get('unknown_index_collection');
|
|
2849
2937
|
}
|
|
2850
|
-
else if (aliases.length > 1) {
|
|
2851
|
-
throw kerror.get('multiple_indice_alias', 'indice', 'aliases');
|
|
2852
|
-
}
|
|
2853
2938
|
|
|
2854
|
-
return aliases
|
|
2939
|
+
return aliases;
|
|
2855
2940
|
}
|
|
2856
2941
|
|
|
2857
2942
|
/**
|
|
@@ -2960,13 +3045,21 @@ class ElasticSearch extends Service {
|
|
|
2960
3045
|
}
|
|
2961
3046
|
|
|
2962
3047
|
/**
|
|
2963
|
-
* Creates the hidden collection on the provided index
|
|
3048
|
+
* Creates the hidden collection on the provided index if it does not already
|
|
3049
|
+
* exists
|
|
2964
3050
|
*
|
|
2965
3051
|
* @param {String} index Index name
|
|
2966
3052
|
*/
|
|
2967
3053
|
async _createHiddenCollection (index) {
|
|
3054
|
+
const mutex = new Mutex(`hiddenCollection/${index}`);
|
|
2968
3055
|
|
|
2969
3056
|
try {
|
|
3057
|
+
await mutex.lock();
|
|
3058
|
+
|
|
3059
|
+
if (await this._hasHiddenCollection(index)) {
|
|
3060
|
+
return;
|
|
3061
|
+
}
|
|
3062
|
+
|
|
2970
3063
|
await this._client.indices.create({
|
|
2971
3064
|
body: {
|
|
2972
3065
|
aliases: {
|
|
@@ -2983,6 +3076,9 @@ class ElasticSearch extends Service {
|
|
|
2983
3076
|
catch (e) {
|
|
2984
3077
|
throw this._esWrapper.formatESError(e);
|
|
2985
3078
|
}
|
|
3079
|
+
finally {
|
|
3080
|
+
await mutex.unlock();
|
|
3081
|
+
}
|
|
2986
3082
|
}
|
|
2987
3083
|
|
|
2988
3084
|
/**
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import EventEmitter from 'events';
|
|
3
|
+
import Inspector from 'inspector';
|
|
4
|
+
export declare type DebugModuleOptions = {
|
|
5
|
+
methods?: string[];
|
|
6
|
+
events?: string[];
|
|
7
|
+
};
|
|
8
|
+
export declare abstract class DebugModule extends EventEmitter {
|
|
9
|
+
name: string;
|
|
10
|
+
methods: string[];
|
|
11
|
+
events: string[];
|
|
12
|
+
/**
|
|
13
|
+
* Called when the module is loaded, after the debugger has been enabled
|
|
14
|
+
*/
|
|
15
|
+
abstract init(inspector: Inspector.Session): Promise<void>;
|
|
16
|
+
/**
|
|
17
|
+
* Called when the module should be cleaned up.
|
|
18
|
+
* - After the Debug Controller has been disabled
|
|
19
|
+
* - Before the debugger is disconnected
|
|
20
|
+
*/
|
|
21
|
+
abstract cleanup(): Promise<void>;
|
|
22
|
+
constructor(name: string, options?: DebugModuleOptions);
|
|
23
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.DebugModule = void 0;
|
|
7
|
+
const events_1 = __importDefault(require("events"));
|
|
8
|
+
class DebugModule extends events_1.default {
|
|
9
|
+
constructor(name, options = {}) {
|
|
10
|
+
super();
|
|
11
|
+
this.name = name;
|
|
12
|
+
this.methods = options.methods || [];
|
|
13
|
+
this.events = options.events || [];
|
|
14
|
+
if (!this.name || this.name.length === 0) {
|
|
15
|
+
throw new Error('DebugModule should have a name');
|
|
16
|
+
}
|
|
17
|
+
if (this.name.charAt(0) !== this.name.charAt(0).toUpperCase()) {
|
|
18
|
+
throw new Error(`Debug Module name "${name}" should start with an uppercase letter`);
|
|
19
|
+
}
|
|
20
|
+
for (const event of this.events) {
|
|
21
|
+
if (event.length === 0) {
|
|
22
|
+
throw new Error(`Event name should not be empty for "${name}"`);
|
|
23
|
+
}
|
|
24
|
+
if (event.charAt(0) !== event.charAt(0).toLowerCase()) {
|
|
25
|
+
throw new Error(`Event name "${event}" should start with a lowercase letter for module "${name}"`);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
for (const method of this.methods) {
|
|
29
|
+
if (method.length === 0) {
|
|
30
|
+
throw new Error(`Method name should not be empty for Debug Module "${name}"`);
|
|
31
|
+
}
|
|
32
|
+
if (method.charAt(0) !== method.charAt(0).toLowerCase()) {
|
|
33
|
+
throw new Error(`Method name "${method}" should start with a lowercase letter for module "${name}"`);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.DebugModule = DebugModule;
|
|
39
|
+
//# sourceMappingURL=DebugModule.js.map
|
|
@@ -2,6 +2,16 @@
|
|
|
2
2
|
import { JSONObject } from '../../../index';
|
|
3
3
|
import { RoleDefinition, ProfileDefinition } from '../index';
|
|
4
4
|
export declare type SecurityConfiguration = {
|
|
5
|
+
/**
|
|
6
|
+
* Debugger configuration
|
|
7
|
+
*/
|
|
8
|
+
debug: {
|
|
9
|
+
/**
|
|
10
|
+
* Allow to use the Chrome DevTools Protocol directly
|
|
11
|
+
* through `debug:post`
|
|
12
|
+
*/
|
|
13
|
+
native_debug_protocol: boolean;
|
|
14
|
+
};
|
|
5
15
|
/**
|
|
6
16
|
* The profileIds applied to a user created with the API action
|
|
7
17
|
* `security:createRestrictedUser`.
|
package/lib/types/index.d.ts
CHANGED
|
@@ -2,7 +2,6 @@ export * from './Plugin';
|
|
|
2
2
|
export * from './Controller';
|
|
3
3
|
export * from './ControllerDefinition';
|
|
4
4
|
export * from './ControllerRights';
|
|
5
|
-
export * from './RequestPayload';
|
|
6
5
|
export * from './ResponsePayload';
|
|
7
6
|
export * from './Deprecation';
|
|
8
7
|
export * from './EventHandler';
|
package/lib/types/index.js
CHANGED
|
@@ -38,7 +38,6 @@ __exportStar(require("./Plugin"), exports);
|
|
|
38
38
|
__exportStar(require("./Controller"), exports);
|
|
39
39
|
__exportStar(require("./ControllerDefinition"), exports);
|
|
40
40
|
__exportStar(require("./ControllerRights"), exports);
|
|
41
|
-
__exportStar(require("./RequestPayload"), exports);
|
|
42
41
|
__exportStar(require("./ResponsePayload"), exports);
|
|
43
42
|
__exportStar(require("./Deprecation"), exports);
|
|
44
43
|
__exportStar(require("./EventHandler"), exports);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function sha256(string: string): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.sha256 = void 0;
|
|
7
|
+
const crypto_1 = __importDefault(require("crypto"));
|
|
8
|
+
function sha256(string) {
|
|
9
|
+
return crypto_1.default.createHash('sha256').update(string).digest('hex');
|
|
10
|
+
}
|
|
11
|
+
exports.sha256 = sha256;
|
|
12
|
+
//# sourceMappingURL=crypto.js.map
|
|
@@ -1,3 +1,38 @@
|
|
|
1
1
|
import { JSONObject } from '../../index';
|
|
2
2
|
import { HttpStream } from '../types';
|
|
3
|
+
/**
|
|
4
|
+
* Flatten an object transform:
|
|
5
|
+
* {
|
|
6
|
+
* title: "kuzzle",
|
|
7
|
+
* info : {
|
|
8
|
+
* tag: "news"
|
|
9
|
+
* }
|
|
10
|
+
* }
|
|
11
|
+
*
|
|
12
|
+
* Into an object like:
|
|
13
|
+
* {
|
|
14
|
+
* title: "kuzzle",
|
|
15
|
+
* info.tag: news
|
|
16
|
+
* }
|
|
17
|
+
*
|
|
18
|
+
* @param {Object} target the object we have to flatten
|
|
19
|
+
* @returns {Object} the flattened object
|
|
20
|
+
*/
|
|
21
|
+
export declare function flattenObject(target: JSONObject): JSONObject;
|
|
22
|
+
/**
|
|
23
|
+
* Extract fields from mapping by removing the properties from es mapping
|
|
24
|
+
*
|
|
25
|
+
* @param mapping
|
|
26
|
+
* @returns
|
|
27
|
+
*/
|
|
28
|
+
export declare function extractMappingFields(mapping: JSONObject): any;
|
|
29
|
+
/**
|
|
30
|
+
* An iteration-order-safe version of lodash.values
|
|
31
|
+
*
|
|
32
|
+
* @param object The object containing the values
|
|
33
|
+
* @param fields The field names to pick in the right order
|
|
34
|
+
* @returns The values in the same order as the fields
|
|
35
|
+
* @see https://lodash.com/docs/4.17.15#values
|
|
36
|
+
*/
|
|
37
|
+
export declare function pickValues(object: any, fields: string[]): any[];
|
|
3
38
|
export declare function dumpCollectionDocuments(index: string, collection: string, query?: any, format?: string, fields?: string[], options?: JSONObject): HttpStream;
|
|
@@ -26,7 +26,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
26
26
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
27
27
|
};
|
|
28
28
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
29
|
-
exports.dumpCollectionDocuments = void 0;
|
|
29
|
+
exports.dumpCollectionDocuments = exports.pickValues = exports.extractMappingFields = exports.flattenObject = void 0;
|
|
30
30
|
const ndjson_1 = __importDefault(require("ndjson"));
|
|
31
31
|
const get_1 = __importDefault(require("lodash/get"));
|
|
32
32
|
const isObject_1 = __importDefault(require("lodash/isObject"));
|
|
@@ -56,6 +56,7 @@ function flattenObject(target) {
|
|
|
56
56
|
flattenStep(output, target);
|
|
57
57
|
return output;
|
|
58
58
|
}
|
|
59
|
+
exports.flattenObject = flattenObject;
|
|
59
60
|
function flattenStep(output, object, prev = null) {
|
|
60
61
|
const keys = Object.keys(object);
|
|
61
62
|
for (let i = 0; i < keys.length; i++) {
|
|
@@ -63,8 +64,8 @@ function flattenStep(output, object, prev = null) {
|
|
|
63
64
|
const value = object[key];
|
|
64
65
|
const newKey = prev ? prev + '.' + key : key;
|
|
65
66
|
if (Object.prototype.toString.call(value) === '[object Object]') {
|
|
66
|
-
output[newKey] = value;
|
|
67
67
|
flattenStep(output, value, newKey);
|
|
68
|
+
continue;
|
|
68
69
|
}
|
|
69
70
|
output[newKey] = value;
|
|
70
71
|
}
|
|
@@ -77,19 +78,20 @@ function flattenStep(output, object, prev = null) {
|
|
|
77
78
|
*/
|
|
78
79
|
function extractMappingFields(mapping) {
|
|
79
80
|
const newMapping = {};
|
|
81
|
+
if (mapping.properties) {
|
|
82
|
+
return extractMappingFields(mapping.properties);
|
|
83
|
+
}
|
|
80
84
|
for (const key of Object.keys(mapping)) {
|
|
81
|
-
if (
|
|
82
|
-
newMapping[key] = extractMappingFields(mapping[key]);
|
|
83
|
-
}
|
|
84
|
-
else if ((0, isObject_1.default)(mapping[key]) && mapping[key].type) {
|
|
85
|
+
if ((0, isObject_1.default)(mapping[key]) && mapping[key].type) {
|
|
85
86
|
newMapping[key] = mapping[key].type;
|
|
86
87
|
}
|
|
87
|
-
else {
|
|
88
|
-
newMapping[key] = mapping[key];
|
|
88
|
+
else if ((0, isObject_1.default)(mapping[key])) {
|
|
89
|
+
newMapping[key] = extractMappingFields(mapping[key]);
|
|
89
90
|
}
|
|
90
91
|
}
|
|
91
92
|
return newMapping;
|
|
92
93
|
}
|
|
94
|
+
exports.extractMappingFields = extractMappingFields;
|
|
93
95
|
/**
|
|
94
96
|
* An iteration-order-safe version of lodash.values
|
|
95
97
|
*
|
|
@@ -101,6 +103,7 @@ function extractMappingFields(mapping) {
|
|
|
101
103
|
function pickValues(object, fields) {
|
|
102
104
|
return fields.map(f => formatValueForCSV((0, get_1.default)(object, f)));
|
|
103
105
|
}
|
|
106
|
+
exports.pickValues = pickValues;
|
|
104
107
|
/**
|
|
105
108
|
* Formats the value for correct CSV output, avoiding to return
|
|
106
109
|
* values that would badly serialize in CSV.
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
export declare type GenerateRandomNameOpts = {
|
|
2
|
+
/**
|
|
3
|
+
* Optional prefix.
|
|
4
|
+
*/
|
|
5
|
+
prefix?: string;
|
|
6
|
+
/**
|
|
7
|
+
* Optional separator. Defaults to `-`.
|
|
8
|
+
*/
|
|
9
|
+
separator?: string;
|
|
10
|
+
/**
|
|
11
|
+
* Optional postfix random number range. Set to `false` to disable postfix. Defaults to `{ min: 0, max: 100000 }`
|
|
12
|
+
*/
|
|
13
|
+
postfixRandRange?: {
|
|
14
|
+
/**
|
|
15
|
+
* Optional minimum postfix random number (inclusive). Defaults to `0`.
|
|
16
|
+
*/
|
|
17
|
+
min?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Maximum postfix random number (exclusive).
|
|
20
|
+
*/
|
|
21
|
+
max: number;
|
|
22
|
+
} | false;
|
|
23
|
+
};
|
|
24
|
+
export declare class NameGenerator {
|
|
25
|
+
/**
|
|
26
|
+
* Returns a random name.
|
|
27
|
+
*
|
|
28
|
+
* # Usage:
|
|
29
|
+
*
|
|
30
|
+
* ```js
|
|
31
|
+
* const name = NameGenerator.getRandomName(); // 'verdi'
|
|
32
|
+
* ```
|
|
33
|
+
*
|
|
34
|
+
* @returns a random name
|
|
35
|
+
*/
|
|
36
|
+
static getRandomName(): string;
|
|
37
|
+
/**
|
|
38
|
+
* Returns a random adjective.
|
|
39
|
+
*
|
|
40
|
+
* # Usage
|
|
41
|
+
*
|
|
42
|
+
* ```js
|
|
43
|
+
* const adj = NameGenerator.getRandomAdjective(); // 'absent'
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* @returns a random adjective
|
|
47
|
+
*/
|
|
48
|
+
static getRandomAdjective(): string;
|
|
49
|
+
/**
|
|
50
|
+
* Generates a random formatted name that consists of an optional prefix, a random adjective,
|
|
51
|
+
* a random name and an optional random number separated by separator (default: '-').
|
|
52
|
+
*
|
|
53
|
+
* Format: `[prefix<separator>]<adjective><separator><name>[<separator>random number]`
|
|
54
|
+
*
|
|
55
|
+
* Format example: `something-dashing-euler-1164`
|
|
56
|
+
*
|
|
57
|
+
* ## Usage
|
|
58
|
+
*
|
|
59
|
+
* ```js
|
|
60
|
+
* let name = NameGenerator.generateRandomName({
|
|
61
|
+
* prefix: 'my',
|
|
62
|
+
* separator: '_',
|
|
63
|
+
* postfixRandRange: { min: 1, max: 10 }
|
|
64
|
+
* }); // 'my_abandoned_yogi_5'
|
|
65
|
+
*
|
|
66
|
+
* name = NameGenerator.generateRandomName({
|
|
67
|
+
* separator: ' ',
|
|
68
|
+
* postfixRandRange: false
|
|
69
|
+
* }); // 'amused vampire'
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @param {GenerateRandomNameOpts} opts Optional options
|
|
73
|
+
*
|
|
74
|
+
* @returns a random formatted name
|
|
75
|
+
*/
|
|
76
|
+
static generateRandomName({ prefix, separator, postfixRandRange, }?: GenerateRandomNameOpts): string;
|
|
77
|
+
}
|
|
78
|
+
export declare function randomNumber(max: number): number;
|
|
79
|
+
export declare function randomNumber(min: number, max: number): number;
|