kuzzle 2.18.0 → 2.19.1
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 +2 -1
- 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/securityController.js +28 -22
- 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 +6 -0
- package/lib/api/request/kuzzleRequest.d.ts +37 -4
- package/lib/api/request/kuzzleRequest.js +115 -29
- 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 +1 -1
- package/lib/core/shared/sdk/embeddedSdk.js +33 -0
- package/lib/kerror/codes/0-core.json +35 -0
- package/lib/kerror/codes/2-api.json +6 -0
- package/lib/kuzzle/kuzzle.d.ts +1 -1
- package/lib/kuzzle/kuzzle.js +27 -8
- package/lib/model/storage/apiKey.js +1 -6
- package/lib/service/storage/elasticsearch.js +40 -13
- 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/util/crypto.d.ts +1 -0
- package/lib/util/crypto.js +12 -0
- 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 +4 -6
- package/lib/core/security/README.md +0 -224
- package/lib/core/shared/README.md +0 -3
- package/package-lock.json +0 -8422
package/lib/kuzzle/kuzzle.js
CHANGED
|
@@ -46,6 +46,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
46
46
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
47
47
|
};
|
|
48
48
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
49
|
+
exports.BACKEND_IMPORT_KEY = void 0;
|
|
49
50
|
const path_1 = __importDefault(require("path"));
|
|
50
51
|
const murmurhash_native_1 = require("murmurhash-native");
|
|
51
52
|
const json_stable_stringify_1 = __importDefault(require("json-stable-stringify"));
|
|
@@ -78,7 +79,8 @@ const cluster_1 = __importDefault(require("../cluster"));
|
|
|
78
79
|
const package_json_1 = require("../../package.json");
|
|
79
80
|
const name_generator_1 = require("../util/name-generator");
|
|
80
81
|
const openapi_1 = require("../api/openapi");
|
|
81
|
-
const
|
|
82
|
+
const crypto_1 = require("../util/crypto");
|
|
83
|
+
exports.BACKEND_IMPORT_KEY = 'backend:init:import';
|
|
82
84
|
let _kuzzle = null;
|
|
83
85
|
Reflect.defineProperty(global, 'kuzzle', {
|
|
84
86
|
configurable: true,
|
|
@@ -201,7 +203,7 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
201
203
|
this.log.info('[✔] Cluster initialized');
|
|
202
204
|
}
|
|
203
205
|
else {
|
|
204
|
-
id =
|
|
206
|
+
id = name_generator_1.NameGenerator.generateRandomName({ prefix: 'knode' });
|
|
205
207
|
this.log.info('[X] Cluster disabled: single node mode.');
|
|
206
208
|
}
|
|
207
209
|
return id;
|
|
@@ -368,11 +370,10 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
368
370
|
*/
|
|
369
371
|
async _waitForImportToFinish() {
|
|
370
372
|
const importTypes = Object.keys(this.importTypes);
|
|
371
|
-
|
|
373
|
+
for (const importType of importTypes) {
|
|
372
374
|
// If the import is done, we pop it from the queue to check the next one
|
|
373
|
-
if (await this.ask('core:cache:internal:get', `${BACKEND_IMPORT_KEY}:${
|
|
374
|
-
|
|
375
|
-
continue;
|
|
375
|
+
if (await this.ask('core:cache:internal:get', `${exports.BACKEND_IMPORT_KEY}:${importType}`)) {
|
|
376
|
+
return;
|
|
376
377
|
}
|
|
377
378
|
await bluebird_1.default.delay(1000);
|
|
378
379
|
}
|
|
@@ -399,8 +400,26 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
399
400
|
const lockedMutex = [];
|
|
400
401
|
try {
|
|
401
402
|
for (const [type, importMethod] of Object.entries(this.importTypes)) {
|
|
403
|
+
const importPayload = {};
|
|
404
|
+
switch (type) {
|
|
405
|
+
case 'fixtures':
|
|
406
|
+
lodash_1.default.set(importPayload, 'toSupport.fixtures', toSupport.fixtures);
|
|
407
|
+
break;
|
|
408
|
+
case 'mappings':
|
|
409
|
+
lodash_1.default.set(importPayload, 'toSupport.mappings', toSupport.mappings);
|
|
410
|
+
lodash_1.default.set(importPayload, 'toImport.mappings', toImport.mappings);
|
|
411
|
+
break;
|
|
412
|
+
case 'permissions':
|
|
413
|
+
lodash_1.default.set(importPayload, 'toSupport.securities', toSupport.securities);
|
|
414
|
+
lodash_1.default.set(importPayload, 'toImport.profiles', toImport.profiles);
|
|
415
|
+
lodash_1.default.set(importPayload, 'toImport.roles', toImport.roles);
|
|
416
|
+
lodash_1.default.set(importPayload, 'toImport.users', toImport.users);
|
|
417
|
+
break;
|
|
418
|
+
}
|
|
419
|
+
const importPayloadHash = (0, crypto_1.sha256)((0, json_stable_stringify_1.default)(importPayload));
|
|
402
420
|
const mutex = new mutex_1.Mutex(`backend:import:${type}`, { timeout: 0 });
|
|
403
|
-
const
|
|
421
|
+
const existingHash = await this.ask('core:cache:internal:get', `${exports.BACKEND_IMPORT_KEY}:${type}`);
|
|
422
|
+
const initialized = existingHash === importPayloadHash;
|
|
404
423
|
const locked = await mutex.lock();
|
|
405
424
|
await importMethod({ toImport, toSupport }, {
|
|
406
425
|
firstCall: !initialized && locked,
|
|
@@ -409,7 +428,7 @@ class Kuzzle extends kuzzleEventEmitter_1.default {
|
|
|
409
428
|
});
|
|
410
429
|
if (!initialized && locked) {
|
|
411
430
|
lockedMutex.push(mutex);
|
|
412
|
-
await this.ask('core:cache:internal:store', `${BACKEND_IMPORT_KEY}:${type}`,
|
|
431
|
+
await this.ask('core:cache:internal:store', `${exports.BACKEND_IMPORT_KEY}:${type}`, importPayloadHash);
|
|
413
432
|
}
|
|
414
433
|
}
|
|
415
434
|
await this._waitForImportToFinish();
|
|
@@ -21,16 +21,11 @@
|
|
|
21
21
|
|
|
22
22
|
'use strict';
|
|
23
23
|
|
|
24
|
-
const
|
|
25
|
-
|
|
24
|
+
const { sha256 } = require('../../util/crypto');
|
|
26
25
|
const debug = require('../../util/debug')('models:storage:apiKey');
|
|
27
26
|
const kerror = require('../../kerror');
|
|
28
27
|
const BaseModel = require('./baseModel');
|
|
29
28
|
|
|
30
|
-
function sha256 (string) {
|
|
31
|
-
return crypto.createHash('sha256').update(string).digest('hex');
|
|
32
|
-
}
|
|
33
|
-
|
|
34
29
|
class ApiKey extends BaseModel {
|
|
35
30
|
constructor (_source, _id = null) {
|
|
36
31
|
super(_source, _id);
|
|
@@ -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) {
|
|
@@ -1435,10 +1435,9 @@ class ElasticSearch extends Service {
|
|
|
1435
1435
|
// rollback the whole operation. Since mappings can't be rollback, we try to
|
|
1436
1436
|
// update the settings first, then the mappings and we rollback the settings
|
|
1437
1437
|
// if putMappings fail.
|
|
1438
|
-
let
|
|
1438
|
+
let indexSettings;
|
|
1439
1439
|
try {
|
|
1440
|
-
|
|
1441
|
-
indiceSettings = response.body[esRequest.index].settings;
|
|
1440
|
+
indexSettings = await this._getSettings(esRequest);
|
|
1442
1441
|
}
|
|
1443
1442
|
catch (error) {
|
|
1444
1443
|
throw this._esWrapper.formatESError(error);
|
|
@@ -1460,11 +1459,7 @@ class ElasticSearch extends Service {
|
|
|
1460
1459
|
}
|
|
1461
1460
|
}
|
|
1462
1461
|
catch (error) {
|
|
1463
|
-
const allowedSettings =
|
|
1464
|
-
index: _.omit(
|
|
1465
|
-
indiceSettings.index,
|
|
1466
|
-
['creation_date', 'provided_name', 'uuid', 'version'])
|
|
1467
|
-
};
|
|
1462
|
+
const allowedSettings = this.getAllowedIndexSettings(indexSettings);
|
|
1468
1463
|
|
|
1469
1464
|
// Rollback to previous settings
|
|
1470
1465
|
if (! _.isEmpty(settings)) {
|
|
@@ -1477,6 +1472,20 @@ class ElasticSearch extends Service {
|
|
|
1477
1472
|
return null;
|
|
1478
1473
|
}
|
|
1479
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
|
+
|
|
1480
1489
|
/**
|
|
1481
1490
|
* Sends an empty UpdateByQuery request to update the search index
|
|
1482
1491
|
*
|
|
@@ -1583,7 +1592,7 @@ class ElasticSearch extends Service {
|
|
|
1583
1592
|
}
|
|
1584
1593
|
|
|
1585
1594
|
/**
|
|
1586
|
-
* Empties the content of a collection. Keep the existing mapping.
|
|
1595
|
+
* Empties the content of a collection. Keep the existing mapping and settings.
|
|
1587
1596
|
*
|
|
1588
1597
|
* @param {String} index - Index name
|
|
1589
1598
|
* @param {String} collection - Collection name
|
|
@@ -1592,6 +1601,7 @@ class ElasticSearch extends Service {
|
|
|
1592
1601
|
*/
|
|
1593
1602
|
async truncateCollection (index, collection) {
|
|
1594
1603
|
let mappings;
|
|
1604
|
+
let settings;
|
|
1595
1605
|
|
|
1596
1606
|
const esRequest = {
|
|
1597
1607
|
index: await this._getIndice(index, collection)
|
|
@@ -1599,7 +1609,11 @@ class ElasticSearch extends Service {
|
|
|
1599
1609
|
|
|
1600
1610
|
try {
|
|
1601
1611
|
mappings = await this.getMapping(index, collection, { includeKuzzleMeta: true });
|
|
1602
|
-
|
|
1612
|
+
settings = await this._getSettings(esRequest);
|
|
1613
|
+
settings = {
|
|
1614
|
+
...settings,
|
|
1615
|
+
...this.getAllowedIndexSettings(settings)
|
|
1616
|
+
};
|
|
1603
1617
|
await this._client.indices.delete(esRequest);
|
|
1604
1618
|
|
|
1605
1619
|
await this._client.indices.create({
|
|
@@ -1608,7 +1622,8 @@ class ElasticSearch extends Service {
|
|
|
1608
1622
|
aliases: {
|
|
1609
1623
|
[this._getAlias(index, collection)]: {}
|
|
1610
1624
|
},
|
|
1611
|
-
mappings
|
|
1625
|
+
mappings,
|
|
1626
|
+
settings
|
|
1612
1627
|
}
|
|
1613
1628
|
});
|
|
1614
1629
|
|
|
@@ -2535,7 +2550,7 @@ class ElasticSearch extends Service {
|
|
|
2535
2550
|
*
|
|
2536
2551
|
* @param {String} index - Index name
|
|
2537
2552
|
* @param {String} collection - Collection name
|
|
2538
|
-
* @param {Array.<String>}
|
|
2553
|
+
* @param {Array.<String>} ids - Documents IDs
|
|
2539
2554
|
* @param {Object} options - timeout (undefined), refresh (undefined)
|
|
2540
2555
|
*
|
|
2541
2556
|
* @returns {Promise.<{ documents, errors }>
|
|
@@ -2857,6 +2872,18 @@ class ElasticSearch extends Service {
|
|
|
2857
2872
|
return body[0].index;
|
|
2858
2873
|
}
|
|
2859
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
|
+
|
|
2860
2887
|
/**
|
|
2861
2888
|
* Given index + collection, returns an available indice name.
|
|
2862
2889
|
* Use this function when creating the associated indice. Otherwise use `_getAlias`.
|
|
@@ -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`.
|
|
@@ -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
|
|
@@ -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;
|