@naturalcycles/nodejs-lib 12.77.1 → 12.79.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/dist/index.d.ts +34 -33
- package/dist/index.js +30 -55
- package/dist/security/crypto.util.d.ts +7 -7
- package/dist/security/hash.util.d.ts +7 -12
- package/dist/security/hash.util.js +1 -7
- package/dist/security/id.util.d.ts +24 -8
- package/dist/security/id.util.js +33 -18
- package/dist/security/nanoid.d.ts +10 -0
- package/dist/security/nanoid.js +96 -0
- package/dist/security/secret.util.d.ts +3 -3
- package/dist/validation/joi/joi.shared.schemas.d.ts +6 -0
- package/dist/validation/joi/joi.shared.schemas.js +8 -2
- package/package.json +1 -2
- package/src/index.ts +33 -150
- package/src/security/crypto.util.ts +7 -7
- package/src/security/hash.util.ts +8 -13
- package/src/security/id.util.ts +34 -20
- package/src/security/nanoid.ts +105 -0
- package/src/security/secret.util.ts +3 -3
- package/src/validation/joi/joi.shared.schemas.ts +9 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,35 +1,36 @@
|
|
|
1
1
|
import Ajv from 'ajv';
|
|
2
2
|
import * as fastGlob from 'fast-glob';
|
|
3
|
-
import { Options as FastGlobOptions } from 'fast-glob';
|
|
3
|
+
import type { Options as FastGlobOptions } from 'fast-glob';
|
|
4
4
|
import * as globby from 'globby';
|
|
5
|
-
import { GlobbyOptions } from 'globby';
|
|
5
|
+
import type { GlobbyOptions } from 'globby';
|
|
6
6
|
import { RequestError, TimeoutError } from 'got';
|
|
7
7
|
import type { AfterResponseHook, BeforeErrorHook, BeforeRequestHook, Got } from 'got';
|
|
8
|
-
import { AnySchema, ValidationErrorItem } from 'joi';
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
import type { AnySchema, ValidationErrorItem } from 'joi';
|
|
9
|
+
export * from './buffer/buffer.util';
|
|
10
|
+
export * from './diff/tableDiff';
|
|
11
11
|
export * from './got/getGot';
|
|
12
|
-
|
|
12
|
+
export * from './got/got.model';
|
|
13
13
|
export * from './infra/process.util';
|
|
14
|
-
|
|
14
|
+
export * from './log/debug';
|
|
15
15
|
export * from './security/hash.util';
|
|
16
16
|
export * from './security/crypto.util';
|
|
17
17
|
export * from './security/id.util';
|
|
18
|
+
export * from './security/nanoid';
|
|
18
19
|
export * from './security/secret.util';
|
|
19
20
|
export * from './colors/colors';
|
|
20
21
|
export * from './log/log.util';
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
export * from './slack/slack.service';
|
|
23
|
+
export * from './slack/slack.service.model';
|
|
24
|
+
export * from './stream/ndjson/ndjson.model';
|
|
24
25
|
export * from './stream/ndjson/ndJsonFileRead';
|
|
25
26
|
export * from './stream/ndjson/ndJsonFileWrite';
|
|
26
27
|
export * from './stream/ndjson/ndjsonMap';
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
28
|
+
export * from './stream/ndjson/ndjsonStreamForEach';
|
|
29
|
+
export * from './stream/ndjson/pipelineFromNDJsonFile';
|
|
30
|
+
export * from './stream/ndjson/pipelineToNDJsonFile';
|
|
31
|
+
export * from './stream/ndjson/streamToNDJsonFile';
|
|
32
|
+
export * from './stream/ndjson/transformJsonParse';
|
|
33
|
+
export * from './stream/ndjson/transformToNDJson';
|
|
33
34
|
export * from './stream/pipeline/pipeline';
|
|
34
35
|
export * from './stream/readable/readableCreate';
|
|
35
36
|
export * from './stream/readable/readableForEach';
|
|
@@ -37,39 +38,39 @@ export * from './stream/readable/readableFromArray';
|
|
|
37
38
|
export * from './stream/readable/readableMap';
|
|
38
39
|
export * from './stream/readable/readableMapToArray';
|
|
39
40
|
export * from './stream/readable/readableToArray';
|
|
40
|
-
|
|
41
|
+
export * from './stream/stream.model';
|
|
41
42
|
export * from './stream/transform/transformBuffer';
|
|
42
43
|
export * from './stream/transform/transformFilter';
|
|
43
44
|
export * from './stream/transform/transformLimit';
|
|
44
45
|
export * from './stream/transform/transformLogProgress';
|
|
45
|
-
|
|
46
|
+
export * from './stream/transform/transformMap';
|
|
46
47
|
export * from './stream/transform/transformMapSimple';
|
|
47
48
|
export * from './stream/transform/transformNoOp';
|
|
48
|
-
|
|
49
|
+
export * from './stream/transform/transformMapSync';
|
|
49
50
|
export * from './stream/transform/transformSplit';
|
|
50
51
|
export * from './stream/transform/transformTap';
|
|
51
52
|
export * from './stream/transform/transformToArray';
|
|
52
53
|
export * from './stream/transform/transformToString';
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
54
|
+
export * from './stream/transform/worker/baseWorkerClass';
|
|
55
|
+
export * from './stream/transform/worker/transformMultiThreaded';
|
|
56
|
+
export * from './stream/transform/worker/transformMultiThreaded.model';
|
|
56
57
|
export * from './stream/writable/writableForEach';
|
|
57
58
|
export * from './stream/writable/writableFork';
|
|
58
59
|
export * from './stream/writable/writablePushToArray';
|
|
59
60
|
export * from './stream/writable/writableVoid';
|
|
60
|
-
|
|
61
|
+
export * from './string/inspectAny';
|
|
61
62
|
export * from './util/env.util';
|
|
62
63
|
export * from './util/lruMemoCache';
|
|
63
64
|
export * from './util/zip.util';
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
65
|
+
export * from './validation/ajv/ajv.util';
|
|
66
|
+
export * from './validation/ajv/ajvSchema';
|
|
67
|
+
export * from './validation/ajv/ajvValidationError';
|
|
67
68
|
export * from './validation/ajv/getAjv';
|
|
68
|
-
|
|
69
|
-
|
|
69
|
+
export * from './validation/joi/joi.extensions';
|
|
70
|
+
export * from './validation/joi/joi.model';
|
|
70
71
|
export * from './validation/joi/joi.shared.schemas';
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
export type { GlobbyOptions, FastGlobOptions,
|
|
75
|
-
export { globby, fastGlob,
|
|
72
|
+
export * from './validation/joi/joi.validation.error';
|
|
73
|
+
export * from './validation/joi/joi.validation.util';
|
|
74
|
+
export * from './script';
|
|
75
|
+
export type { GlobbyOptions, FastGlobOptions, ValidationErrorItem, AnySchema, Got, AfterResponseHook, BeforeErrorHook, BeforeRequestHook, };
|
|
76
|
+
export { globby, fastGlob, RequestError, TimeoutError, Ajv };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.Ajv = exports.TimeoutError = exports.RequestError = exports.fastGlob = exports.globby = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const ajv_1 = require("ajv");
|
|
6
6
|
exports.Ajv = ajv_1.default;
|
|
@@ -11,41 +11,31 @@ exports.globby = globby;
|
|
|
11
11
|
const got_1 = require("got");
|
|
12
12
|
Object.defineProperty(exports, "RequestError", { enumerable: true, get: function () { return got_1.RequestError; } });
|
|
13
13
|
Object.defineProperty(exports, "TimeoutError", { enumerable: true, get: function () { return got_1.TimeoutError; } });
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
const tableDiff_1 = require("./diff/tableDiff");
|
|
17
|
-
Object.defineProperty(exports, "tableDiff", { enumerable: true, get: function () { return tableDiff_1.tableDiff; } });
|
|
14
|
+
tslib_1.__exportStar(require("./buffer/buffer.util"), exports);
|
|
15
|
+
tslib_1.__exportStar(require("./diff/tableDiff"), exports);
|
|
18
16
|
tslib_1.__exportStar(require("./got/getGot"), exports);
|
|
17
|
+
tslib_1.__exportStar(require("./got/got.model"), exports);
|
|
19
18
|
tslib_1.__exportStar(require("./infra/process.util"), exports);
|
|
20
|
-
|
|
21
|
-
Object.defineProperty(exports, "Debug", { enumerable: true, get: function () { return debug_1.Debug; } });
|
|
19
|
+
tslib_1.__exportStar(require("./log/debug"), exports);
|
|
22
20
|
tslib_1.__exportStar(require("./security/hash.util"), exports);
|
|
23
21
|
tslib_1.__exportStar(require("./security/crypto.util"), exports);
|
|
24
22
|
tslib_1.__exportStar(require("./security/id.util"), exports);
|
|
23
|
+
tslib_1.__exportStar(require("./security/nanoid"), exports);
|
|
25
24
|
tslib_1.__exportStar(require("./security/secret.util"), exports);
|
|
26
25
|
tslib_1.__exportStar(require("./colors/colors"), exports);
|
|
27
26
|
tslib_1.__exportStar(require("./log/log.util"), exports);
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const ndjson_model_1 = require("./stream/ndjson/ndjson.model");
|
|
32
|
-
Object.defineProperty(exports, "NDJsonStats", { enumerable: true, get: function () { return ndjson_model_1.NDJsonStats; } });
|
|
27
|
+
tslib_1.__exportStar(require("./slack/slack.service"), exports);
|
|
28
|
+
tslib_1.__exportStar(require("./slack/slack.service.model"), exports);
|
|
29
|
+
tslib_1.__exportStar(require("./stream/ndjson/ndjson.model"), exports);
|
|
33
30
|
tslib_1.__exportStar(require("./stream/ndjson/ndJsonFileRead"), exports);
|
|
34
31
|
tslib_1.__exportStar(require("./stream/ndjson/ndJsonFileWrite"), exports);
|
|
35
32
|
tslib_1.__exportStar(require("./stream/ndjson/ndjsonMap"), exports);
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
const streamToNDJsonFile_1 = require("./stream/ndjson/streamToNDJsonFile");
|
|
43
|
-
Object.defineProperty(exports, "streamToNDJsonFile", { enumerable: true, get: function () { return streamToNDJsonFile_1.streamToNDJsonFile; } });
|
|
44
|
-
const transformJsonParse_1 = require("./stream/ndjson/transformJsonParse");
|
|
45
|
-
Object.defineProperty(exports, "bufferReviver", { enumerable: true, get: function () { return transformJsonParse_1.bufferReviver; } });
|
|
46
|
-
Object.defineProperty(exports, "transformJsonParse", { enumerable: true, get: function () { return transformJsonParse_1.transformJsonParse; } });
|
|
47
|
-
const transformToNDJson_1 = require("./stream/ndjson/transformToNDJson");
|
|
48
|
-
Object.defineProperty(exports, "transformToNDJson", { enumerable: true, get: function () { return transformToNDJson_1.transformToNDJson; } });
|
|
33
|
+
tslib_1.__exportStar(require("./stream/ndjson/ndjsonStreamForEach"), exports);
|
|
34
|
+
tslib_1.__exportStar(require("./stream/ndjson/pipelineFromNDJsonFile"), exports);
|
|
35
|
+
tslib_1.__exportStar(require("./stream/ndjson/pipelineToNDJsonFile"), exports);
|
|
36
|
+
tslib_1.__exportStar(require("./stream/ndjson/streamToNDJsonFile"), exports);
|
|
37
|
+
tslib_1.__exportStar(require("./stream/ndjson/transformJsonParse"), exports);
|
|
38
|
+
tslib_1.__exportStar(require("./stream/ndjson/transformToNDJson"), exports);
|
|
49
39
|
tslib_1.__exportStar(require("./stream/pipeline/pipeline"), exports);
|
|
50
40
|
tslib_1.__exportStar(require("./stream/readable/readableCreate"), exports);
|
|
51
41
|
tslib_1.__exportStar(require("./stream/readable/readableForEach"), exports);
|
|
@@ -53,52 +43,37 @@ tslib_1.__exportStar(require("./stream/readable/readableFromArray"), exports);
|
|
|
53
43
|
tslib_1.__exportStar(require("./stream/readable/readableMap"), exports);
|
|
54
44
|
tslib_1.__exportStar(require("./stream/readable/readableMapToArray"), exports);
|
|
55
45
|
tslib_1.__exportStar(require("./stream/readable/readableToArray"), exports);
|
|
46
|
+
tslib_1.__exportStar(require("./stream/stream.model"), exports);
|
|
56
47
|
tslib_1.__exportStar(require("./stream/transform/transformBuffer"), exports);
|
|
57
48
|
tslib_1.__exportStar(require("./stream/transform/transformFilter"), exports);
|
|
58
49
|
tslib_1.__exportStar(require("./stream/transform/transformLimit"), exports);
|
|
59
50
|
tslib_1.__exportStar(require("./stream/transform/transformLogProgress"), exports);
|
|
60
|
-
|
|
61
|
-
Object.defineProperty(exports, "transformMap", { enumerable: true, get: function () { return transformMap_1.transformMap; } });
|
|
51
|
+
tslib_1.__exportStar(require("./stream/transform/transformMap"), exports);
|
|
62
52
|
tslib_1.__exportStar(require("./stream/transform/transformMapSimple"), exports);
|
|
63
53
|
tslib_1.__exportStar(require("./stream/transform/transformNoOp"), exports);
|
|
64
|
-
|
|
65
|
-
Object.defineProperty(exports, "transformMapSync", { enumerable: true, get: function () { return transformMapSync_1.transformMapSync; } });
|
|
54
|
+
tslib_1.__exportStar(require("./stream/transform/transformMapSync"), exports);
|
|
66
55
|
tslib_1.__exportStar(require("./stream/transform/transformSplit"), exports);
|
|
67
56
|
tslib_1.__exportStar(require("./stream/transform/transformTap"), exports);
|
|
68
57
|
tslib_1.__exportStar(require("./stream/transform/transformToArray"), exports);
|
|
69
58
|
tslib_1.__exportStar(require("./stream/transform/transformToString"), exports);
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
Object.defineProperty(exports, "transformMultiThreaded", { enumerable: true, get: function () { return transformMultiThreaded_1.transformMultiThreaded; } });
|
|
59
|
+
tslib_1.__exportStar(require("./stream/transform/worker/baseWorkerClass"), exports);
|
|
60
|
+
tslib_1.__exportStar(require("./stream/transform/worker/transformMultiThreaded"), exports);
|
|
61
|
+
tslib_1.__exportStar(require("./stream/transform/worker/transformMultiThreaded.model"), exports);
|
|
74
62
|
tslib_1.__exportStar(require("./stream/writable/writableForEach"), exports);
|
|
75
63
|
tslib_1.__exportStar(require("./stream/writable/writableFork"), exports);
|
|
76
64
|
tslib_1.__exportStar(require("./stream/writable/writablePushToArray"), exports);
|
|
77
65
|
tslib_1.__exportStar(require("./stream/writable/writableVoid"), exports);
|
|
78
|
-
|
|
79
|
-
Object.defineProperty(exports, "inspectAny", { enumerable: true, get: function () { return inspectAny_1.inspectAny; } });
|
|
80
|
-
Object.defineProperty(exports, "inspectAnyStringifyFn", { enumerable: true, get: function () { return inspectAny_1.inspectAnyStringifyFn; } });
|
|
66
|
+
tslib_1.__exportStar(require("./string/inspectAny"), exports);
|
|
81
67
|
tslib_1.__exportStar(require("./util/env.util"), exports);
|
|
82
68
|
tslib_1.__exportStar(require("./util/lruMemoCache"), exports);
|
|
83
69
|
tslib_1.__exportStar(require("./util/zip.util"), exports);
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
const ajvSchema_1 = require("./validation/ajv/ajvSchema");
|
|
88
|
-
Object.defineProperty(exports, "AjvSchema", { enumerable: true, get: function () { return ajvSchema_1.AjvSchema; } });
|
|
89
|
-
const ajvValidationError_1 = require("./validation/ajv/ajvValidationError");
|
|
90
|
-
Object.defineProperty(exports, "AjvValidationError", { enumerable: true, get: function () { return ajvValidationError_1.AjvValidationError; } });
|
|
70
|
+
tslib_1.__exportStar(require("./validation/ajv/ajv.util"), exports);
|
|
71
|
+
tslib_1.__exportStar(require("./validation/ajv/ajvSchema"), exports);
|
|
72
|
+
tslib_1.__exportStar(require("./validation/ajv/ajvValidationError"), exports);
|
|
91
73
|
tslib_1.__exportStar(require("./validation/ajv/getAjv"), exports);
|
|
92
|
-
|
|
93
|
-
|
|
74
|
+
tslib_1.__exportStar(require("./validation/joi/joi.extensions"), exports);
|
|
75
|
+
tslib_1.__exportStar(require("./validation/joi/joi.model"), exports);
|
|
94
76
|
tslib_1.__exportStar(require("./validation/joi/joi.shared.schemas"), exports);
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
Object.defineProperty(exports, "convert", { enumerable: true, get: function () { return joi_validation_util_1.convert; } });
|
|
99
|
-
Object.defineProperty(exports, "getValidationResult", { enumerable: true, get: function () { return joi_validation_util_1.getValidationResult; } });
|
|
100
|
-
Object.defineProperty(exports, "isValid", { enumerable: true, get: function () { return joi_validation_util_1.isValid; } });
|
|
101
|
-
Object.defineProperty(exports, "undefinedIfInvalid", { enumerable: true, get: function () { return joi_validation_util_1.undefinedIfInvalid; } });
|
|
102
|
-
Object.defineProperty(exports, "validate", { enumerable: true, get: function () { return joi_validation_util_1.validate; } });
|
|
103
|
-
const script_1 = require("./script");
|
|
104
|
-
Object.defineProperty(exports, "runScript", { enumerable: true, get: function () { return script_1.runScript; } });
|
|
77
|
+
tslib_1.__exportStar(require("./validation/joi/joi.validation.error"), exports);
|
|
78
|
+
tslib_1.__exportStar(require("./validation/joi/joi.validation.util"), exports);
|
|
79
|
+
tslib_1.__exportStar(require("./script"), exports);
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
-
import { StringMap } from '@naturalcycles/js-lib';
|
|
2
|
+
import { Base64String, StringMap } from '@naturalcycles/js-lib';
|
|
3
3
|
/**
|
|
4
4
|
* Using aes-256-cbc
|
|
5
5
|
*/
|
|
6
|
-
export declare function encryptRandomIVBuffer(input: Buffer, secretKeyBase64:
|
|
6
|
+
export declare function encryptRandomIVBuffer(input: Buffer, secretKeyBase64: Base64String): Buffer;
|
|
7
7
|
/**
|
|
8
8
|
* Using aes-256-cbc
|
|
9
9
|
*/
|
|
10
|
-
export declare function decryptRandomIVBuffer(input: Buffer, secretKeyBase64:
|
|
10
|
+
export declare function decryptRandomIVBuffer(input: Buffer, secretKeyBase64: Base64String): Buffer;
|
|
11
11
|
/**
|
|
12
12
|
* Decrypts all object values.
|
|
13
13
|
* Returns object with decrypted values.
|
|
14
14
|
*/
|
|
15
|
-
export declare function decryptObject(obj: StringMap
|
|
16
|
-
export declare function encryptObject(obj: StringMap, secretKey: string): StringMap
|
|
15
|
+
export declare function decryptObject(obj: StringMap<Base64String>, secretKey: string): StringMap;
|
|
16
|
+
export declare function encryptObject(obj: StringMap, secretKey: string): StringMap<Base64String>;
|
|
17
17
|
/**
|
|
18
18
|
* Using aes-256-cbc
|
|
19
19
|
*/
|
|
20
|
-
export declare function decryptString(str:
|
|
20
|
+
export declare function decryptString(str: Base64String, secretKey: string): string;
|
|
21
21
|
/**
|
|
22
22
|
* Using aes-256-cbc
|
|
23
23
|
*/
|
|
24
|
-
export declare function encryptString(str: string, secretKey: string):
|
|
24
|
+
export declare function encryptString(str: string, secretKey: string): Base64String;
|
|
@@ -1,20 +1,15 @@
|
|
|
1
1
|
/// <reference types="node" />
|
|
2
|
+
import { Base64String } from '@naturalcycles/js-lib';
|
|
2
3
|
export declare function md5(s: string | Buffer): string;
|
|
3
|
-
export declare function md5AsBase64(s: string | Buffer):
|
|
4
|
+
export declare function md5AsBase64(s: string | Buffer): Base64String;
|
|
4
5
|
export declare function md5AsBuffer(s: string | Buffer): Buffer;
|
|
5
6
|
export declare function sha256(s: string | Buffer): string;
|
|
6
|
-
export declare function sha256AsBase64(s: string | Buffer):
|
|
7
|
+
export declare function sha256AsBase64(s: string | Buffer): Base64String;
|
|
7
8
|
export declare function sha256AsBuffer(s: string | Buffer): Buffer;
|
|
8
9
|
export declare function hash(s: string | Buffer, algorithm: string): string;
|
|
9
10
|
export declare function hashAsBuffer(s: string | Buffer, algorithm: string): Buffer;
|
|
10
|
-
export declare function base64(s: string | Buffer):
|
|
11
|
-
export declare function base64ToString(strBase64:
|
|
11
|
+
export declare function base64(s: string | Buffer): Base64String;
|
|
12
|
+
export declare function base64ToString(strBase64: Base64String): string;
|
|
12
13
|
export declare function base64ToBuffer(strBase64: string): Buffer;
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
*/
|
|
16
|
-
export declare function stringToBase64(s: string): string;
|
|
17
|
-
/**
|
|
18
|
-
* @deprecated use `base64`
|
|
19
|
-
*/
|
|
20
|
-
export declare function bufferToBase64(b: Buffer): string;
|
|
14
|
+
export declare function stringToBase64(s: string): Base64String;
|
|
15
|
+
export declare function bufferToBase64(b: Buffer): Base64String;
|
|
@@ -35,7 +35,7 @@ function hashAsBuffer(s, algorithm) {
|
|
|
35
35
|
}
|
|
36
36
|
exports.hashAsBuffer = hashAsBuffer;
|
|
37
37
|
function base64(s) {
|
|
38
|
-
return (
|
|
38
|
+
return (typeof s === 'string' ? Buffer.from(s) : s).toString('base64');
|
|
39
39
|
}
|
|
40
40
|
exports.base64 = base64;
|
|
41
41
|
function base64ToString(strBase64) {
|
|
@@ -46,16 +46,10 @@ function base64ToBuffer(strBase64) {
|
|
|
46
46
|
return Buffer.from(strBase64, 'base64');
|
|
47
47
|
}
|
|
48
48
|
exports.base64ToBuffer = base64ToBuffer;
|
|
49
|
-
/**
|
|
50
|
-
* @deprecated use `base64`
|
|
51
|
-
*/
|
|
52
49
|
function stringToBase64(s) {
|
|
53
50
|
return Buffer.from(s, 'utf8').toString('base64');
|
|
54
51
|
}
|
|
55
52
|
exports.stringToBase64 = stringToBase64;
|
|
56
|
-
/**
|
|
57
|
-
* @deprecated use `base64`
|
|
58
|
-
*/
|
|
59
53
|
function bufferToBase64(b) {
|
|
60
54
|
return b.toString('base64');
|
|
61
55
|
}
|
|
@@ -1,13 +1,29 @@
|
|
|
1
|
-
export declare const ALPHABET_NUMBER = "0123456789";
|
|
2
|
-
export declare const ALPHABET_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
|
|
3
|
-
export declare const ALPHABET_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
4
|
-
export declare const ALPHABET_ALPHANUMERIC_LOWERCASE: string;
|
|
5
|
-
export declare const ALPHABET_ALPHANUMERIC_UPPERCASE: string;
|
|
6
|
-
export declare const ALPHABET_ALPHANUMERIC: string;
|
|
7
1
|
/**
|
|
8
2
|
* Generate cryptographically-secure string id.
|
|
9
3
|
* Powered by `nanoid`.
|
|
10
4
|
*/
|
|
11
5
|
export declare function stringId(length?: number, alphabet?: string): string;
|
|
12
|
-
|
|
13
|
-
|
|
6
|
+
/**
|
|
7
|
+
* Generate a string id of Base62 alphabet (same as "alphanumeric": A-Za-z0-9)
|
|
8
|
+
*
|
|
9
|
+
* Length is 16 (non-configurable currently).
|
|
10
|
+
*/
|
|
11
|
+
export declare const stringIdBase62: () => string;
|
|
12
|
+
/**
|
|
13
|
+
* Generate a string id of Base64 alphabet: A-Za-z0-9+/
|
|
14
|
+
*
|
|
15
|
+
* Default length is 16.
|
|
16
|
+
* Length should be dividable by 4 (otherwise unexpected length will be produced).
|
|
17
|
+
*
|
|
18
|
+
* Dividable by 4 lengths produce ids with no padding `=` characters, which is optimal.
|
|
19
|
+
*/
|
|
20
|
+
export declare function stringIdBase64(size?: number): string;
|
|
21
|
+
/**
|
|
22
|
+
* Generate a string id of Base64url alphabet: A-Za-z0-9-_
|
|
23
|
+
*
|
|
24
|
+
* Default length is 16.
|
|
25
|
+
* Length should be dividable by 4 (otherwise unexpected length will be produced).
|
|
26
|
+
*
|
|
27
|
+
* Base64url always produces strings without a padding character `=`, by design.
|
|
28
|
+
*/
|
|
29
|
+
export declare function stringIdBase64Url(size?: number): string;
|
package/dist/security/id.util.js
CHANGED
|
@@ -1,28 +1,43 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
const
|
|
6
|
-
const non_secure_1 = require("nanoid/non-secure");
|
|
7
|
-
exports.ALPHABET_NUMBER = '0123456789';
|
|
8
|
-
exports.ALPHABET_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';
|
|
9
|
-
exports.ALPHABET_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
10
|
-
exports.ALPHABET_ALPHANUMERIC_LOWERCASE = [exports.ALPHABET_NUMBER, exports.ALPHABET_LOWERCASE].join('');
|
|
11
|
-
exports.ALPHABET_ALPHANUMERIC_UPPERCASE = [exports.ALPHABET_NUMBER, exports.ALPHABET_UPPERCASE].join('');
|
|
12
|
-
exports.ALPHABET_ALPHANUMERIC = [exports.ALPHABET_NUMBER, exports.ALPHABET_LOWERCASE, exports.ALPHABET_UPPERCASE].join('');
|
|
3
|
+
exports.stringIdBase64Url = exports.stringIdBase64 = exports.stringIdBase62 = exports.stringId = void 0;
|
|
4
|
+
const crypto = require("node:crypto");
|
|
5
|
+
const nanoid_1 = require("./nanoid");
|
|
13
6
|
/**
|
|
14
7
|
* Generate cryptographically-secure string id.
|
|
15
8
|
* Powered by `nanoid`.
|
|
16
9
|
*/
|
|
17
|
-
function stringId(length = 16, alphabet =
|
|
18
|
-
return (0, nanoid_1.
|
|
10
|
+
function stringId(length = 16, alphabet = nanoid_1.ALPHABET_ALPHANUMERIC_LOWERCASE) {
|
|
11
|
+
return (0, nanoid_1.nanoIdCustomAlphabet)(alphabet, length)();
|
|
19
12
|
}
|
|
20
13
|
exports.stringId = stringId;
|
|
21
|
-
|
|
22
|
-
|
|
14
|
+
/**
|
|
15
|
+
* Generate a string id of Base62 alphabet (same as "alphanumeric": A-Za-z0-9)
|
|
16
|
+
*
|
|
17
|
+
* Length is 16 (non-configurable currently).
|
|
18
|
+
*/
|
|
19
|
+
exports.stringIdBase62 = (0, nanoid_1.nanoIdCustomAlphabet)(nanoid_1.ALPHABET_ALPHANUMERIC, 16);
|
|
20
|
+
/**
|
|
21
|
+
* Generate a string id of Base64 alphabet: A-Za-z0-9+/
|
|
22
|
+
*
|
|
23
|
+
* Default length is 16.
|
|
24
|
+
* Length should be dividable by 4 (otherwise unexpected length will be produced).
|
|
25
|
+
*
|
|
26
|
+
* Dividable by 4 lengths produce ids with no padding `=` characters, which is optimal.
|
|
27
|
+
*/
|
|
28
|
+
function stringIdBase64(size = 16) {
|
|
29
|
+
return crypto.randomBytes(size * 0.75).toString('base64');
|
|
23
30
|
}
|
|
24
|
-
exports.
|
|
25
|
-
|
|
26
|
-
|
|
31
|
+
exports.stringIdBase64 = stringIdBase64;
|
|
32
|
+
/**
|
|
33
|
+
* Generate a string id of Base64url alphabet: A-Za-z0-9-_
|
|
34
|
+
*
|
|
35
|
+
* Default length is 16.
|
|
36
|
+
* Length should be dividable by 4 (otherwise unexpected length will be produced).
|
|
37
|
+
*
|
|
38
|
+
* Base64url always produces strings without a padding character `=`, by design.
|
|
39
|
+
*/
|
|
40
|
+
function stringIdBase64Url(size = 16) {
|
|
41
|
+
return crypto.randomBytes(size * 0.75).toString('base64url');
|
|
27
42
|
}
|
|
28
|
-
exports.
|
|
43
|
+
exports.stringIdBase64Url = stringIdBase64Url;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare const ALPHABET_NUMBER = "0123456789";
|
|
2
|
+
export declare const ALPHABET_LOWERCASE = "abcdefghijklmnopqrstuvwxyz";
|
|
3
|
+
export declare const ALPHABET_UPPERCASE = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
4
|
+
export declare const ALPHABET_ALPHANUMERIC_LOWERCASE: string;
|
|
5
|
+
export declare const ALPHABET_ALPHANUMERIC_UPPERCASE: string;
|
|
6
|
+
export declare const ALPHABET_ALPHANUMERIC: string;
|
|
7
|
+
export declare const ALPHABET_BASE64: string;
|
|
8
|
+
export declare const ALPHABET_BASE64_URL: string;
|
|
9
|
+
export declare function nanoIdCustomAlphabet(alphabet: string, size?: number): (size?: number) => string;
|
|
10
|
+
export declare function nanoid(size?: number): string;
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
|
|
4
|
+
This file is "vendored" from Nanoid, all credit is to Nanoid authors:
|
|
5
|
+
https://github.com/ai/nanoid/
|
|
6
|
+
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.nanoid = exports.nanoIdCustomAlphabet = exports.ALPHABET_BASE64_URL = exports.ALPHABET_BASE64 = exports.ALPHABET_ALPHANUMERIC = exports.ALPHABET_ALPHANUMERIC_UPPERCASE = exports.ALPHABET_ALPHANUMERIC_LOWERCASE = exports.ALPHABET_UPPERCASE = exports.ALPHABET_LOWERCASE = exports.ALPHABET_NUMBER = void 0;
|
|
10
|
+
/* eslint-disable */
|
|
11
|
+
const node_crypto_1 = require("node:crypto");
|
|
12
|
+
exports.ALPHABET_NUMBER = '0123456789';
|
|
13
|
+
exports.ALPHABET_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz';
|
|
14
|
+
exports.ALPHABET_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
|
|
15
|
+
exports.ALPHABET_ALPHANUMERIC_LOWERCASE = [exports.ALPHABET_NUMBER, exports.ALPHABET_LOWERCASE].join('');
|
|
16
|
+
exports.ALPHABET_ALPHANUMERIC_UPPERCASE = [exports.ALPHABET_NUMBER, exports.ALPHABET_UPPERCASE].join('');
|
|
17
|
+
exports.ALPHABET_ALPHANUMERIC = [exports.ALPHABET_NUMBER, exports.ALPHABET_LOWERCASE, exports.ALPHABET_UPPERCASE].join('');
|
|
18
|
+
exports.ALPHABET_BASE64 = [exports.ALPHABET_ALPHANUMERIC, '+/'].join('');
|
|
19
|
+
exports.ALPHABET_BASE64_URL = [exports.ALPHABET_ALPHANUMERIC, '-_'].join('');
|
|
20
|
+
// It is best to make fewer, larger requests to the crypto module to
|
|
21
|
+
// avoid system call overhead. So, random numbers are generated in a
|
|
22
|
+
// pool. The pool is a Buffer that is larger than the initial random
|
|
23
|
+
// request size by this multiplier. The pool is enlarged if subsequent
|
|
24
|
+
// requests exceed the maximum buffer size.
|
|
25
|
+
const POOL_SIZE_MULTIPLIER = 128;
|
|
26
|
+
let pool;
|
|
27
|
+
let poolOffset;
|
|
28
|
+
function fillPool(bytes) {
|
|
29
|
+
if (!pool || pool.length < bytes) {
|
|
30
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER);
|
|
31
|
+
(0, node_crypto_1.randomFillSync)(pool);
|
|
32
|
+
poolOffset = 0;
|
|
33
|
+
}
|
|
34
|
+
else if (poolOffset + bytes > pool.length) {
|
|
35
|
+
(0, node_crypto_1.randomFillSync)(pool);
|
|
36
|
+
poolOffset = 0;
|
|
37
|
+
}
|
|
38
|
+
poolOffset += bytes;
|
|
39
|
+
}
|
|
40
|
+
function random(bytes) {
|
|
41
|
+
// `-=` convert `bytes` to number to prevent `valueOf` abusing
|
|
42
|
+
fillPool((bytes -= 0));
|
|
43
|
+
return pool.subarray(poolOffset - bytes, poolOffset);
|
|
44
|
+
}
|
|
45
|
+
function customRandom(alphabet, defaultSize, getRandom) {
|
|
46
|
+
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
|
47
|
+
// values closer to the alphabet size. The bitmask calculates the closest
|
|
48
|
+
// `2^31 - 1` number, which exceeds the alphabet size.
|
|
49
|
+
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
|
50
|
+
const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1;
|
|
51
|
+
// Though, the bitmask solution is not perfect since the bytes exceeding
|
|
52
|
+
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
|
53
|
+
// the random bytes redundancy has to be satisfied.
|
|
54
|
+
// Note: every hardware random generator call is performance expensive,
|
|
55
|
+
// because the system call for entropy collection takes a lot of time.
|
|
56
|
+
// So, to avoid additional system calls, extra bytes are requested in advance.
|
|
57
|
+
// Next, a step determines how many random bytes to generate.
|
|
58
|
+
// The number of random bytes gets decided upon the ID size, mask,
|
|
59
|
+
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
|
60
|
+
// according to benchmarks).
|
|
61
|
+
const step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length);
|
|
62
|
+
return (size = defaultSize) => {
|
|
63
|
+
let id = '';
|
|
64
|
+
while (true) {
|
|
65
|
+
const bytes = getRandom(step);
|
|
66
|
+
// A compact alternative for `for (let i = 0; i < step; i++)`.
|
|
67
|
+
let i = step;
|
|
68
|
+
while (i--) {
|
|
69
|
+
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
|
70
|
+
id += alphabet[bytes[i] & mask] || '';
|
|
71
|
+
if (id.length === size)
|
|
72
|
+
return id;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function nanoIdCustomAlphabet(alphabet, size = 21) {
|
|
78
|
+
return customRandom(alphabet, size, random);
|
|
79
|
+
}
|
|
80
|
+
exports.nanoIdCustomAlphabet = nanoIdCustomAlphabet;
|
|
81
|
+
function nanoid(size = 21) {
|
|
82
|
+
// `-=` convert `size` to number to prevent `valueOf` abusing
|
|
83
|
+
fillPool((size -= 0));
|
|
84
|
+
let id = '';
|
|
85
|
+
// We are reading directly from the random pool to avoid creating new array
|
|
86
|
+
for (let i = poolOffset - size; i < poolOffset; i++) {
|
|
87
|
+
// It is incorrect to use bytes exceeding the alphabet size.
|
|
88
|
+
// The following mask reduces the random byte in the 0-255 value
|
|
89
|
+
// range to the 0-63 value range. Therefore, adding hacks, such
|
|
90
|
+
// as empty string fallback or magic numbers, is unneccessary because
|
|
91
|
+
// the bitmask trims bytes down to the alphabet size.
|
|
92
|
+
id += exports.ALPHABET_BASE64_URL[pool[i] & 63];
|
|
93
|
+
}
|
|
94
|
+
return id;
|
|
95
|
+
}
|
|
96
|
+
exports.nanoid = nanoid;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { StringMap } from '@naturalcycles/js-lib';
|
|
1
|
+
import { Base64String, StringMap } from '@naturalcycles/js-lib';
|
|
2
2
|
/**
|
|
3
3
|
* Loads plaintext secrets from process.env, removes them, stores locally.
|
|
4
4
|
* Make sure to call this function early on server startup, so secrets are removed from process.env
|
|
@@ -18,12 +18,12 @@ export declare function removeSecretsFromEnv(): void;
|
|
|
18
18
|
* Whole file is encrypted.
|
|
19
19
|
* For "json-values encrypted" style - use `loadSecretsFromEncryptedJsonFileValues`
|
|
20
20
|
*/
|
|
21
|
-
export declare function loadSecretsFromEncryptedJsonFile(filePath: string, secretEncryptionKey?:
|
|
21
|
+
export declare function loadSecretsFromEncryptedJsonFile(filePath: string, secretEncryptionKey?: Base64String): void;
|
|
22
22
|
/**
|
|
23
23
|
* Whole file is NOT encrypted, but instead individual json values ARE encrypted..
|
|
24
24
|
* For whole-file encryption - use `loadSecretsFromEncryptedJsonFile`
|
|
25
25
|
*/
|
|
26
|
-
export declare function loadSecretsFromEncryptedJsonFileValues(filePath: string, secretEncryptionKey?:
|
|
26
|
+
export declare function loadSecretsFromEncryptedJsonFileValues(filePath: string, secretEncryptionKey?: Base64String): void;
|
|
27
27
|
/**
|
|
28
28
|
* json secrets are always base64'd
|
|
29
29
|
*/
|
|
@@ -21,6 +21,12 @@ export declare const anyObjectSchema: import("joi").ObjectSchema<any>;
|
|
|
21
21
|
* 6-64 length
|
|
22
22
|
*/
|
|
23
23
|
export declare const idSchema: import("./string.extensions").ExtendedStringSchema;
|
|
24
|
+
export declare const idBase62Schema: import("./string.extensions").ExtendedStringSchema;
|
|
25
|
+
export declare const idBase64Schema: import("./string.extensions").ExtendedStringSchema;
|
|
26
|
+
export declare const idBase64UrlSchema: import("./string.extensions").ExtendedStringSchema;
|
|
27
|
+
export declare const base62Schema: import("./string.extensions").ExtendedStringSchema;
|
|
28
|
+
export declare const base64Schema: import("./string.extensions").ExtendedStringSchema;
|
|
29
|
+
export declare const base64UrlSchema: import("./string.extensions").ExtendedStringSchema;
|
|
24
30
|
/**
|
|
25
31
|
* `_` should NOT be allowed to be able to use slug-ids as part of natural ids with `_` separator.
|
|
26
32
|
*/
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.savedDBEntitySchema = exports.baseDBEntitySchema = exports.ipAddressSchema = exports.utcOffsetSchema = exports.userAgentSchema = exports.semVerSchema = exports.SEM_VER_PATTERN = exports.emailSchema = exports.verSchema = exports.unixTimestampMillis2000Schema = exports.unixTimestampMillisSchema = exports.unixTimestamp2000Schema = exports.unixTimestampSchema = exports.slugSchema = exports.SLUG_PATTERN = exports.idSchema = exports.anyObjectSchema = exports.anySchema = exports.oneOfSchema = exports.objectSchema = exports.arraySchema = exports.urlSchema = exports.binarySchema = exports.dateStringSchema = exports.percentageSchema = exports.integerSchema = exports.numberSchema = exports.stringSchema = exports.booleanDefaultToFalseSchema = exports.booleanSchema = void 0;
|
|
3
|
+
exports.savedDBEntitySchema = exports.baseDBEntitySchema = exports.ipAddressSchema = exports.utcOffsetSchema = exports.userAgentSchema = exports.semVerSchema = exports.SEM_VER_PATTERN = exports.emailSchema = exports.verSchema = exports.unixTimestampMillis2000Schema = exports.unixTimestampMillisSchema = exports.unixTimestamp2000Schema = exports.unixTimestampSchema = exports.slugSchema = exports.SLUG_PATTERN = exports.base64UrlSchema = exports.base64Schema = exports.base62Schema = exports.idBase64UrlSchema = exports.idBase64Schema = exports.idBase62Schema = exports.idSchema = exports.anyObjectSchema = exports.anySchema = exports.oneOfSchema = exports.objectSchema = exports.arraySchema = exports.urlSchema = exports.binarySchema = exports.dateStringSchema = exports.percentageSchema = exports.integerSchema = exports.numberSchema = exports.stringSchema = exports.booleanDefaultToFalseSchema = exports.booleanSchema = void 0;
|
|
4
4
|
const joi_extensions_1 = require("./joi.extensions");
|
|
5
5
|
exports.booleanSchema = joi_extensions_1.Joi.boolean();
|
|
6
6
|
exports.booleanDefaultToFalseSchema = joi_extensions_1.Joi.boolean().default(false);
|
|
@@ -32,6 +32,12 @@ exports.anyObjectSchema = joi_extensions_1.Joi.object().options({ stripUnknown:
|
|
|
32
32
|
* 6-64 length
|
|
33
33
|
*/
|
|
34
34
|
exports.idSchema = exports.stringSchema.regex(/^[a-zA-Z0-9_]{6,64}$/);
|
|
35
|
+
exports.idBase62Schema = exports.stringSchema.regex(/^[a-zA-Z0-9]{8,64}$/);
|
|
36
|
+
exports.idBase64Schema = exports.stringSchema.regex(/^[a-zA-Z0-9+/]{8,64}$/);
|
|
37
|
+
exports.idBase64UrlSchema = exports.stringSchema.regex(/^[a-zA-Z0-9-_]{8,64}$/);
|
|
38
|
+
exports.base62Schema = exports.stringSchema.regex(/^[a-zA-Z0-9]+$/);
|
|
39
|
+
exports.base64Schema = exports.stringSchema.regex(/^[a-zA-Z0-9+/]+$/);
|
|
40
|
+
exports.base64UrlSchema = exports.stringSchema.regex(/^[a-zA-Z0-9-_]+$/);
|
|
35
41
|
/**
|
|
36
42
|
* `_` should NOT be allowed to be able to use slug-ids as part of natural ids with `_` separator.
|
|
37
43
|
*/
|
|
@@ -39,7 +45,7 @@ exports.SLUG_PATTERN = /^[a-z0-9-]*$/;
|
|
|
39
45
|
/**
|
|
40
46
|
* "Slug" - a valid URL, filename, etc.
|
|
41
47
|
*/
|
|
42
|
-
exports.slugSchema = exports.stringSchema.regex(/^[a-z0-9-]{1,255}$/);
|
|
48
|
+
exports.slugSchema = exports.stringSchema.regex(/^[a-z0-9-_]{1,255}$/);
|
|
43
49
|
const TS_2500 = 16725225600; // 2500-01-01
|
|
44
50
|
const TS_2000 = 946684800; // 2000-01-01
|
|
45
51
|
/**
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@naturalcycles/nodejs-lib",
|
|
3
|
-
"version": "12.
|
|
3
|
+
"version": "12.79.0",
|
|
4
4
|
"scripts": {
|
|
5
5
|
"prepare": "husky install",
|
|
6
6
|
"docs-serve": "vuepress dev docs",
|
|
@@ -33,7 +33,6 @@
|
|
|
33
33
|
"joi": "17.4.2",
|
|
34
34
|
"lru-cache": "^7.4.0",
|
|
35
35
|
"move-file": "^2.0.0",
|
|
36
|
-
"nanoid": "^3.0.0",
|
|
37
36
|
"through2-concurrent": "^2.0.0",
|
|
38
37
|
"yargs": "^17.0.0"
|
|
39
38
|
},
|
package/src/index.ts
CHANGED
|
@@ -1,54 +1,36 @@
|
|
|
1
1
|
import Ajv from 'ajv'
|
|
2
2
|
import * as fastGlob from 'fast-glob'
|
|
3
|
-
import { Options as FastGlobOptions } from 'fast-glob'
|
|
3
|
+
import type { Options as FastGlobOptions } from 'fast-glob'
|
|
4
4
|
import * as globby from 'globby'
|
|
5
|
-
import { GlobbyOptions } from 'globby'
|
|
5
|
+
import type { GlobbyOptions } from 'globby'
|
|
6
6
|
import { RequestError, TimeoutError } from 'got'
|
|
7
7
|
import type { AfterResponseHook, BeforeErrorHook, BeforeRequestHook, Got } from 'got'
|
|
8
|
-
import { AnySchema, ValidationErrorItem } from 'joi'
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
import type { AnySchema, ValidationErrorItem } from 'joi'
|
|
9
|
+
export * from './buffer/buffer.util'
|
|
10
|
+
export * from './diff/tableDiff'
|
|
11
11
|
export * from './got/getGot'
|
|
12
|
-
|
|
12
|
+
export * from './got/got.model'
|
|
13
13
|
export * from './infra/process.util'
|
|
14
|
-
|
|
14
|
+
export * from './log/debug'
|
|
15
15
|
export * from './security/hash.util'
|
|
16
16
|
export * from './security/crypto.util'
|
|
17
17
|
export * from './security/id.util'
|
|
18
|
+
export * from './security/nanoid'
|
|
18
19
|
export * from './security/secret.util'
|
|
19
20
|
export * from './colors/colors'
|
|
20
21
|
export * from './log/log.util'
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
SlackMessage,
|
|
25
|
-
SlackMessagePrefixHook,
|
|
26
|
-
SlackMessageProps,
|
|
27
|
-
SlackServiceCfg,
|
|
28
|
-
} from './slack/slack.service.model'
|
|
29
|
-
import { NDJsonStats } from './stream/ndjson/ndjson.model'
|
|
22
|
+
export * from './slack/slack.service'
|
|
23
|
+
export * from './slack/slack.service.model'
|
|
24
|
+
export * from './stream/ndjson/ndjson.model'
|
|
30
25
|
export * from './stream/ndjson/ndJsonFileRead'
|
|
31
26
|
export * from './stream/ndjson/ndJsonFileWrite'
|
|
32
27
|
export * from './stream/ndjson/ndjsonMap'
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
PipelineFromNDJsonFileOptions,
|
|
40
|
-
} from './stream/ndjson/pipelineFromNDJsonFile'
|
|
41
|
-
import {
|
|
42
|
-
pipelineToNDJsonFile,
|
|
43
|
-
PipelineToNDJsonFileOptions,
|
|
44
|
-
} from './stream/ndjson/pipelineToNDJsonFile'
|
|
45
|
-
import { streamToNDJsonFile } from './stream/ndjson/streamToNDJsonFile'
|
|
46
|
-
import {
|
|
47
|
-
bufferReviver,
|
|
48
|
-
transformJsonParse,
|
|
49
|
-
TransformJsonParseOptions,
|
|
50
|
-
} from './stream/ndjson/transformJsonParse'
|
|
51
|
-
import { transformToNDJson, TransformToNDJsonOptions } from './stream/ndjson/transformToNDJson'
|
|
28
|
+
export * from './stream/ndjson/ndjsonStreamForEach'
|
|
29
|
+
export * from './stream/ndjson/pipelineFromNDJsonFile'
|
|
30
|
+
export * from './stream/ndjson/pipelineToNDJsonFile'
|
|
31
|
+
export * from './stream/ndjson/streamToNDJsonFile'
|
|
32
|
+
export * from './stream/ndjson/transformJsonParse'
|
|
33
|
+
export * from './stream/ndjson/transformToNDJson'
|
|
52
34
|
export * from './stream/pipeline/pipeline'
|
|
53
35
|
export * from './stream/readable/readableCreate'
|
|
54
36
|
export * from './stream/readable/readableForEach'
|
|
@@ -56,149 +38,50 @@ export * from './stream/readable/readableFromArray'
|
|
|
56
38
|
export * from './stream/readable/readableMap'
|
|
57
39
|
export * from './stream/readable/readableMapToArray'
|
|
58
40
|
export * from './stream/readable/readableToArray'
|
|
59
|
-
|
|
60
|
-
ReadableTyped,
|
|
61
|
-
TransformOptions,
|
|
62
|
-
TransformTyped,
|
|
63
|
-
WritableTyped,
|
|
64
|
-
} from './stream/stream.model'
|
|
41
|
+
export * from './stream/stream.model'
|
|
65
42
|
export * from './stream/transform/transformBuffer'
|
|
66
43
|
export * from './stream/transform/transformFilter'
|
|
67
44
|
export * from './stream/transform/transformLimit'
|
|
68
45
|
export * from './stream/transform/transformLogProgress'
|
|
69
|
-
|
|
46
|
+
export * from './stream/transform/transformMap'
|
|
70
47
|
export * from './stream/transform/transformMapSimple'
|
|
71
48
|
export * from './stream/transform/transformNoOp'
|
|
72
|
-
|
|
49
|
+
export * from './stream/transform/transformMapSync'
|
|
73
50
|
export * from './stream/transform/transformSplit'
|
|
74
51
|
export * from './stream/transform/transformTap'
|
|
75
52
|
export * from './stream/transform/transformToArray'
|
|
76
53
|
export * from './stream/transform/transformToString'
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
TransformMultiThreadedOptions,
|
|
81
|
-
} from './stream/transform/worker/transformMultiThreaded'
|
|
82
|
-
import { WorkerInput, WorkerOutput } from './stream/transform/worker/transformMultiThreaded.model'
|
|
54
|
+
export * from './stream/transform/worker/baseWorkerClass'
|
|
55
|
+
export * from './stream/transform/worker/transformMultiThreaded'
|
|
56
|
+
export * from './stream/transform/worker/transformMultiThreaded.model'
|
|
83
57
|
export * from './stream/writable/writableForEach'
|
|
84
58
|
export * from './stream/writable/writableFork'
|
|
85
59
|
export * from './stream/writable/writablePushToArray'
|
|
86
60
|
export * from './stream/writable/writableVoid'
|
|
87
|
-
|
|
61
|
+
export * from './string/inspectAny'
|
|
88
62
|
export * from './util/env.util'
|
|
89
63
|
export * from './util/lruMemoCache'
|
|
90
64
|
export * from './util/zip.util'
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
65
|
+
export * from './validation/ajv/ajv.util'
|
|
66
|
+
export * from './validation/ajv/ajvSchema'
|
|
67
|
+
export * from './validation/ajv/ajvValidationError'
|
|
94
68
|
export * from './validation/ajv/getAjv'
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
AnySchemaTyped,
|
|
98
|
-
ArraySchemaTyped,
|
|
99
|
-
BooleanSchemaTyped,
|
|
100
|
-
NumberSchemaTyped,
|
|
101
|
-
ObjectSchemaTyped,
|
|
102
|
-
SchemaTyped,
|
|
103
|
-
StringSchemaTyped,
|
|
104
|
-
} from './validation/joi/joi.model'
|
|
69
|
+
export * from './validation/joi/joi.extensions'
|
|
70
|
+
export * from './validation/joi/joi.model'
|
|
105
71
|
export * from './validation/joi/joi.shared.schemas'
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
getValidationResult,
|
|
110
|
-
isValid,
|
|
111
|
-
JoiValidationResult,
|
|
112
|
-
undefinedIfInvalid,
|
|
113
|
-
validate,
|
|
114
|
-
} from './validation/joi/joi.validation.util'
|
|
115
|
-
import { runScript, RunScriptOptions } from './script'
|
|
72
|
+
export * from './validation/joi/joi.validation.error'
|
|
73
|
+
export * from './validation/joi/joi.validation.util'
|
|
74
|
+
export * from './script'
|
|
116
75
|
|
|
117
76
|
export type {
|
|
118
77
|
GlobbyOptions,
|
|
119
78
|
FastGlobOptions,
|
|
120
|
-
RunScriptOptions,
|
|
121
|
-
JoiValidationErrorData,
|
|
122
|
-
JoiValidationResult,
|
|
123
79
|
ValidationErrorItem,
|
|
124
|
-
ExtendedJoi,
|
|
125
|
-
SchemaTyped,
|
|
126
80
|
AnySchema,
|
|
127
|
-
AnySchemaTyped,
|
|
128
|
-
ArraySchemaTyped,
|
|
129
|
-
BooleanSchemaTyped,
|
|
130
|
-
NumberSchemaTyped,
|
|
131
|
-
ObjectSchemaTyped,
|
|
132
|
-
StringSchemaTyped,
|
|
133
|
-
IDebug,
|
|
134
|
-
IDebugger,
|
|
135
|
-
SlackServiceCfg,
|
|
136
|
-
SlackMessage,
|
|
137
|
-
SlackMessageProps,
|
|
138
|
-
SlackApiBody,
|
|
139
|
-
SlackMessagePrefixHook,
|
|
140
|
-
ReadableTyped,
|
|
141
|
-
WritableTyped,
|
|
142
|
-
TransformTyped,
|
|
143
|
-
PipelineFromNDJsonFileOptions,
|
|
144
|
-
PipelineToNDJsonFileOptions,
|
|
145
|
-
TransformJsonParseOptions,
|
|
146
|
-
TransformToNDJsonOptions,
|
|
147
|
-
TransformMapOptions,
|
|
148
|
-
TransformMapSyncOptions,
|
|
149
|
-
NDJSONStreamForEachOptions,
|
|
150
|
-
TransformOptions,
|
|
151
|
-
TransformMultiThreadedOptions,
|
|
152
|
-
WorkerClassInterface,
|
|
153
|
-
WorkerInput,
|
|
154
|
-
WorkerOutput,
|
|
155
|
-
TableDiffOptions,
|
|
156
|
-
InspectAnyOptions,
|
|
157
81
|
Got,
|
|
158
|
-
GetGotOptions,
|
|
159
82
|
AfterResponseHook,
|
|
160
83
|
BeforeErrorHook,
|
|
161
84
|
BeforeRequestHook,
|
|
162
|
-
AjvValidationOptions,
|
|
163
|
-
AjvSchemaCfg,
|
|
164
|
-
AjvValidationErrorData,
|
|
165
85
|
}
|
|
166
86
|
|
|
167
|
-
export {
|
|
168
|
-
globby,
|
|
169
|
-
fastGlob,
|
|
170
|
-
JoiValidationError,
|
|
171
|
-
validate,
|
|
172
|
-
getValidationResult,
|
|
173
|
-
isValid,
|
|
174
|
-
undefinedIfInvalid,
|
|
175
|
-
convert,
|
|
176
|
-
Joi,
|
|
177
|
-
Debug,
|
|
178
|
-
SlackService,
|
|
179
|
-
slackDefaultMessagePrefixHook,
|
|
180
|
-
ndjsonStreamForEach,
|
|
181
|
-
pipelineFromNDJsonFile,
|
|
182
|
-
pipelineToNDJsonFile,
|
|
183
|
-
NDJsonStats,
|
|
184
|
-
streamToNDJsonFile,
|
|
185
|
-
transformJsonParse,
|
|
186
|
-
bufferReviver,
|
|
187
|
-
transformToNDJson,
|
|
188
|
-
transformMap,
|
|
189
|
-
transformMapSync,
|
|
190
|
-
transformMultiThreaded,
|
|
191
|
-
BaseWorkerClass,
|
|
192
|
-
tableDiff,
|
|
193
|
-
inspectAny,
|
|
194
|
-
inspectAnyStringifyFn,
|
|
195
|
-
RequestError,
|
|
196
|
-
TimeoutError,
|
|
197
|
-
_chunkBuffer,
|
|
198
|
-
Ajv,
|
|
199
|
-
AjvSchema,
|
|
200
|
-
AjvValidationError,
|
|
201
|
-
readJsonSchemas,
|
|
202
|
-
readAjvSchemas,
|
|
203
|
-
runScript,
|
|
204
|
-
}
|
|
87
|
+
export { globby, fastGlob, RequestError, TimeoutError, Ajv }
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as crypto from 'node:crypto'
|
|
2
|
-
import { _stringMapEntries, StringMap } from '@naturalcycles/js-lib'
|
|
2
|
+
import { _stringMapEntries, Base64String, StringMap } from '@naturalcycles/js-lib'
|
|
3
3
|
import { md5 } from './hash.util'
|
|
4
4
|
|
|
5
5
|
const algorithm = 'aes-256-cbc'
|
|
@@ -7,7 +7,7 @@ const algorithm = 'aes-256-cbc'
|
|
|
7
7
|
/**
|
|
8
8
|
* Using aes-256-cbc
|
|
9
9
|
*/
|
|
10
|
-
export function encryptRandomIVBuffer(input: Buffer, secretKeyBase64:
|
|
10
|
+
export function encryptRandomIVBuffer(input: Buffer, secretKeyBase64: Base64String): Buffer {
|
|
11
11
|
// md5 to match aes-256 key length of 32 bytes
|
|
12
12
|
const key = md5(Buffer.from(secretKeyBase64, 'base64'))
|
|
13
13
|
|
|
@@ -21,7 +21,7 @@ export function encryptRandomIVBuffer(input: Buffer, secretKeyBase64: string): B
|
|
|
21
21
|
/**
|
|
22
22
|
* Using aes-256-cbc
|
|
23
23
|
*/
|
|
24
|
-
export function decryptRandomIVBuffer(input: Buffer, secretKeyBase64:
|
|
24
|
+
export function decryptRandomIVBuffer(input: Buffer, secretKeyBase64: Base64String): Buffer {
|
|
25
25
|
// md5 to match aes-256 key length of 32 bytes
|
|
26
26
|
const key = md5(Buffer.from(secretKeyBase64, 'base64'))
|
|
27
27
|
|
|
@@ -38,7 +38,7 @@ export function decryptRandomIVBuffer(input: Buffer, secretKeyBase64: string): B
|
|
|
38
38
|
* Decrypts all object values.
|
|
39
39
|
* Returns object with decrypted values.
|
|
40
40
|
*/
|
|
41
|
-
export function decryptObject(obj: StringMap
|
|
41
|
+
export function decryptObject(obj: StringMap<Base64String>, secretKey: string): StringMap {
|
|
42
42
|
const { key, iv } = getCryptoParams(secretKey)
|
|
43
43
|
|
|
44
44
|
const r: StringMap = {}
|
|
@@ -49,7 +49,7 @@ export function decryptObject(obj: StringMap, secretKey: string): StringMap {
|
|
|
49
49
|
return r
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
export function encryptObject(obj: StringMap, secretKey: string): StringMap {
|
|
52
|
+
export function encryptObject(obj: StringMap, secretKey: string): StringMap<Base64String> {
|
|
53
53
|
const { key, iv } = getCryptoParams(secretKey)
|
|
54
54
|
|
|
55
55
|
const r: StringMap = {}
|
|
@@ -63,7 +63,7 @@ export function encryptObject(obj: StringMap, secretKey: string): StringMap {
|
|
|
63
63
|
/**
|
|
64
64
|
* Using aes-256-cbc
|
|
65
65
|
*/
|
|
66
|
-
export function decryptString(str:
|
|
66
|
+
export function decryptString(str: Base64String, secretKey: string): string {
|
|
67
67
|
const { key, iv } = getCryptoParams(secretKey)
|
|
68
68
|
const decipher = crypto.createDecipheriv(algorithm, key, iv)
|
|
69
69
|
return decipher.update(str, 'base64', 'utf8') + decipher.final('utf8')
|
|
@@ -72,7 +72,7 @@ export function decryptString(str: string, secretKey: string): string {
|
|
|
72
72
|
/**
|
|
73
73
|
* Using aes-256-cbc
|
|
74
74
|
*/
|
|
75
|
-
export function encryptString(str: string, secretKey: string):
|
|
75
|
+
export function encryptString(str: string, secretKey: string): Base64String {
|
|
76
76
|
const { key, iv } = getCryptoParams(secretKey)
|
|
77
77
|
const cipher = crypto.createCipheriv(algorithm, key, iv)
|
|
78
78
|
return cipher.update(str, 'utf8', 'base64') + cipher.final('base64')
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import * as crypto from 'node:crypto'
|
|
2
|
+
import { Base64String } from '@naturalcycles/js-lib'
|
|
2
3
|
|
|
3
4
|
export function md5(s: string | Buffer): string {
|
|
4
5
|
return hash(s, 'md5')
|
|
5
6
|
}
|
|
6
7
|
|
|
7
|
-
export function md5AsBase64(s: string | Buffer):
|
|
8
|
+
export function md5AsBase64(s: string | Buffer): Base64String {
|
|
8
9
|
return hashAsBuffer(s, 'md5').toString('base64')
|
|
9
10
|
}
|
|
10
11
|
|
|
@@ -16,7 +17,7 @@ export function sha256(s: string | Buffer): string {
|
|
|
16
17
|
return hash(s, 'sha256')
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
export function sha256AsBase64(s: string | Buffer):
|
|
20
|
+
export function sha256AsBase64(s: string | Buffer): Base64String {
|
|
20
21
|
return hashAsBuffer(s, 'sha256').toString('base64')
|
|
21
22
|
}
|
|
22
23
|
|
|
@@ -32,11 +33,11 @@ export function hashAsBuffer(s: string | Buffer, algorithm: string): Buffer {
|
|
|
32
33
|
return crypto.createHash(algorithm).update(s).digest()
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
export function base64(s: string | Buffer):
|
|
36
|
-
return (
|
|
36
|
+
export function base64(s: string | Buffer): Base64String {
|
|
37
|
+
return (typeof s === 'string' ? Buffer.from(s) : s).toString('base64')
|
|
37
38
|
}
|
|
38
39
|
|
|
39
|
-
export function base64ToString(strBase64:
|
|
40
|
+
export function base64ToString(strBase64: Base64String): string {
|
|
40
41
|
return Buffer.from(strBase64, 'base64').toString('utf8')
|
|
41
42
|
}
|
|
42
43
|
|
|
@@ -44,16 +45,10 @@ export function base64ToBuffer(strBase64: string): Buffer {
|
|
|
44
45
|
return Buffer.from(strBase64, 'base64')
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
|
|
48
|
-
* @deprecated use `base64`
|
|
49
|
-
*/
|
|
50
|
-
export function stringToBase64(s: string): string {
|
|
48
|
+
export function stringToBase64(s: string): Base64String {
|
|
51
49
|
return Buffer.from(s, 'utf8').toString('base64')
|
|
52
50
|
}
|
|
53
51
|
|
|
54
|
-
|
|
55
|
-
* @deprecated use `base64`
|
|
56
|
-
*/
|
|
57
|
-
export function bufferToBase64(b: Buffer): string {
|
|
52
|
+
export function bufferToBase64(b: Buffer): Base64String {
|
|
58
53
|
return b.toString('base64')
|
|
59
54
|
}
|
package/src/security/id.util.ts
CHANGED
|
@@ -1,31 +1,45 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export const ALPHABET_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
8
|
-
export const ALPHABET_ALPHANUMERIC_LOWERCASE = [ALPHABET_NUMBER, ALPHABET_LOWERCASE].join('')
|
|
9
|
-
export const ALPHABET_ALPHANUMERIC_UPPERCASE = [ALPHABET_NUMBER, ALPHABET_UPPERCASE].join('')
|
|
10
|
-
export const ALPHABET_ALPHANUMERIC = [ALPHABET_NUMBER, ALPHABET_LOWERCASE, ALPHABET_UPPERCASE].join(
|
|
11
|
-
'',
|
|
12
|
-
)
|
|
1
|
+
import * as crypto from 'node:crypto'
|
|
2
|
+
import {
|
|
3
|
+
ALPHABET_ALPHANUMERIC,
|
|
4
|
+
ALPHABET_ALPHANUMERIC_LOWERCASE,
|
|
5
|
+
nanoIdCustomAlphabet,
|
|
6
|
+
} from './nanoid'
|
|
13
7
|
|
|
14
8
|
/**
|
|
15
9
|
* Generate cryptographically-secure string id.
|
|
16
10
|
* Powered by `nanoid`.
|
|
17
11
|
*/
|
|
18
12
|
export function stringId(length = 16, alphabet = ALPHABET_ALPHANUMERIC_LOWERCASE): string {
|
|
19
|
-
return
|
|
13
|
+
return nanoIdCustomAlphabet(alphabet, length)()
|
|
20
14
|
}
|
|
21
15
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
16
|
+
/**
|
|
17
|
+
* Generate a string id of Base62 alphabet (same as "alphanumeric": A-Za-z0-9)
|
|
18
|
+
*
|
|
19
|
+
* Length is 16 (non-configurable currently).
|
|
20
|
+
*/
|
|
21
|
+
export const stringIdBase62: () => string = nanoIdCustomAlphabet(ALPHABET_ALPHANUMERIC, 16)
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Generate a string id of Base64 alphabet: A-Za-z0-9+/
|
|
25
|
+
*
|
|
26
|
+
* Default length is 16.
|
|
27
|
+
* Length should be dividable by 4 (otherwise unexpected length will be produced).
|
|
28
|
+
*
|
|
29
|
+
* Dividable by 4 lengths produce ids with no padding `=` characters, which is optimal.
|
|
30
|
+
*/
|
|
31
|
+
export function stringIdBase64(size = 16): string {
|
|
32
|
+
return crypto.randomBytes(size * 0.75).toString('base64')
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
|
|
30
|
-
|
|
35
|
+
/**
|
|
36
|
+
* Generate a string id of Base64url alphabet: A-Za-z0-9-_
|
|
37
|
+
*
|
|
38
|
+
* Default length is 16.
|
|
39
|
+
* Length should be dividable by 4 (otherwise unexpected length will be produced).
|
|
40
|
+
*
|
|
41
|
+
* Base64url always produces strings without a padding character `=`, by design.
|
|
42
|
+
*/
|
|
43
|
+
export function stringIdBase64Url(size = 16): string {
|
|
44
|
+
return crypto.randomBytes(size * 0.75).toString('base64url')
|
|
31
45
|
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/*
|
|
2
|
+
|
|
3
|
+
This file is "vendored" from Nanoid, all credit is to Nanoid authors:
|
|
4
|
+
https://github.com/ai/nanoid/
|
|
5
|
+
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/* eslint-disable */
|
|
9
|
+
|
|
10
|
+
import { randomFillSync } from 'node:crypto'
|
|
11
|
+
|
|
12
|
+
type RandomFn = (bytes: number) => Buffer
|
|
13
|
+
|
|
14
|
+
export const ALPHABET_NUMBER = '0123456789'
|
|
15
|
+
export const ALPHABET_LOWERCASE = 'abcdefghijklmnopqrstuvwxyz'
|
|
16
|
+
export const ALPHABET_UPPERCASE = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
|
17
|
+
export const ALPHABET_ALPHANUMERIC_LOWERCASE = [ALPHABET_NUMBER, ALPHABET_LOWERCASE].join('')
|
|
18
|
+
export const ALPHABET_ALPHANUMERIC_UPPERCASE = [ALPHABET_NUMBER, ALPHABET_UPPERCASE].join('')
|
|
19
|
+
export const ALPHABET_ALPHANUMERIC = [ALPHABET_NUMBER, ALPHABET_LOWERCASE, ALPHABET_UPPERCASE].join(
|
|
20
|
+
'',
|
|
21
|
+
)
|
|
22
|
+
export const ALPHABET_BASE64 = [ALPHABET_ALPHANUMERIC, '+/'].join('')
|
|
23
|
+
export const ALPHABET_BASE64_URL = [ALPHABET_ALPHANUMERIC, '-_'].join('')
|
|
24
|
+
|
|
25
|
+
// It is best to make fewer, larger requests to the crypto module to
|
|
26
|
+
// avoid system call overhead. So, random numbers are generated in a
|
|
27
|
+
// pool. The pool is a Buffer that is larger than the initial random
|
|
28
|
+
// request size by this multiplier. The pool is enlarged if subsequent
|
|
29
|
+
// requests exceed the maximum buffer size.
|
|
30
|
+
const POOL_SIZE_MULTIPLIER = 128
|
|
31
|
+
let pool: Buffer
|
|
32
|
+
let poolOffset: number
|
|
33
|
+
|
|
34
|
+
function fillPool(bytes: number): void {
|
|
35
|
+
if (!pool || pool.length < bytes) {
|
|
36
|
+
pool = Buffer.allocUnsafe(bytes * POOL_SIZE_MULTIPLIER)
|
|
37
|
+
randomFillSync(pool)
|
|
38
|
+
poolOffset = 0
|
|
39
|
+
} else if (poolOffset + bytes > pool.length) {
|
|
40
|
+
randomFillSync(pool)
|
|
41
|
+
poolOffset = 0
|
|
42
|
+
}
|
|
43
|
+
poolOffset += bytes
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function random(bytes: number): Buffer {
|
|
47
|
+
// `-=` convert `bytes` to number to prevent `valueOf` abusing
|
|
48
|
+
fillPool((bytes -= 0))
|
|
49
|
+
return pool.subarray(poolOffset - bytes, poolOffset)
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
function customRandom(alphabet: string, defaultSize: number, getRandom: RandomFn) {
|
|
53
|
+
// First, a bitmask is necessary to generate the ID. The bitmask makes bytes
|
|
54
|
+
// values closer to the alphabet size. The bitmask calculates the closest
|
|
55
|
+
// `2^31 - 1` number, which exceeds the alphabet size.
|
|
56
|
+
// For example, the bitmask for the alphabet size 30 is 31 (00011111).
|
|
57
|
+
const mask = (2 << (31 - Math.clz32((alphabet.length - 1) | 1))) - 1
|
|
58
|
+
// Though, the bitmask solution is not perfect since the bytes exceeding
|
|
59
|
+
// the alphabet size are refused. Therefore, to reliably generate the ID,
|
|
60
|
+
// the random bytes redundancy has to be satisfied.
|
|
61
|
+
|
|
62
|
+
// Note: every hardware random generator call is performance expensive,
|
|
63
|
+
// because the system call for entropy collection takes a lot of time.
|
|
64
|
+
// So, to avoid additional system calls, extra bytes are requested in advance.
|
|
65
|
+
|
|
66
|
+
// Next, a step determines how many random bytes to generate.
|
|
67
|
+
// The number of random bytes gets decided upon the ID size, mask,
|
|
68
|
+
// alphabet size, and magic number 1.6 (using 1.6 peaks at performance
|
|
69
|
+
// according to benchmarks).
|
|
70
|
+
const step = Math.ceil((1.6 * mask * defaultSize) / alphabet.length)
|
|
71
|
+
|
|
72
|
+
return (size = defaultSize) => {
|
|
73
|
+
let id = ''
|
|
74
|
+
while (true) {
|
|
75
|
+
const bytes = getRandom(step)
|
|
76
|
+
// A compact alternative for `for (let i = 0; i < step; i++)`.
|
|
77
|
+
let i = step
|
|
78
|
+
while (i--) {
|
|
79
|
+
// Adding `|| ''` refuses a random byte that exceeds the alphabet size.
|
|
80
|
+
id += alphabet[bytes[i]! & mask] || ''
|
|
81
|
+
if (id.length === size) return id
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function nanoIdCustomAlphabet(alphabet: string, size = 21): (size?: number) => string {
|
|
88
|
+
return customRandom(alphabet, size, random)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export function nanoid(size = 21): string {
|
|
92
|
+
// `-=` convert `size` to number to prevent `valueOf` abusing
|
|
93
|
+
fillPool((size -= 0))
|
|
94
|
+
let id = ''
|
|
95
|
+
// We are reading directly from the random pool to avoid creating new array
|
|
96
|
+
for (let i = poolOffset - size; i < poolOffset; i++) {
|
|
97
|
+
// It is incorrect to use bytes exceeding the alphabet size.
|
|
98
|
+
// The following mask reduces the random byte in the 0-255 value
|
|
99
|
+
// range to the 0-63 value range. Therefore, adding hacks, such
|
|
100
|
+
// as empty string fallback or magic numbers, is unneccessary because
|
|
101
|
+
// the bitmask trims bytes down to the alphabet size.
|
|
102
|
+
id += ALPHABET_BASE64_URL[pool[i]! & 63]
|
|
103
|
+
}
|
|
104
|
+
return id
|
|
105
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as fs from 'node:fs'
|
|
2
|
-
import { _assert, StringMap } from '@naturalcycles/js-lib'
|
|
2
|
+
import { _assert, Base64String, StringMap } from '@naturalcycles/js-lib'
|
|
3
3
|
import { base64ToString } from '..'
|
|
4
4
|
import { decryptObject, decryptRandomIVBuffer } from './crypto.util'
|
|
5
5
|
|
|
@@ -53,7 +53,7 @@ export function removeSecretsFromEnv(): void {
|
|
|
53
53
|
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
54
54
|
export function loadSecretsFromEncryptedJsonFile(
|
|
55
55
|
filePath: string,
|
|
56
|
-
secretEncryptionKey?:
|
|
56
|
+
secretEncryptionKey?: Base64String,
|
|
57
57
|
): void {
|
|
58
58
|
_assert(
|
|
59
59
|
fs.existsSync(filePath),
|
|
@@ -86,7 +86,7 @@ export function loadSecretsFromEncryptedJsonFile(
|
|
|
86
86
|
*/
|
|
87
87
|
export function loadSecretsFromEncryptedJsonFileValues(
|
|
88
88
|
filePath: string,
|
|
89
|
-
secretEncryptionKey?:
|
|
89
|
+
secretEncryptionKey?: Base64String,
|
|
90
90
|
): void {
|
|
91
91
|
_assert(
|
|
92
92
|
fs.existsSync(filePath),
|
|
@@ -47,6 +47,14 @@ export const anyObjectSchema = Joi.object().options({ stripUnknown: false })
|
|
|
47
47
|
*/
|
|
48
48
|
export const idSchema = stringSchema.regex(/^[a-zA-Z0-9_]{6,64}$/)
|
|
49
49
|
|
|
50
|
+
export const idBase62Schema = stringSchema.regex(/^[a-zA-Z0-9]{8,64}$/)
|
|
51
|
+
export const idBase64Schema = stringSchema.regex(/^[a-zA-Z0-9+/]{8,64}$/)
|
|
52
|
+
export const idBase64UrlSchema = stringSchema.regex(/^[a-zA-Z0-9-_]{8,64}$/)
|
|
53
|
+
|
|
54
|
+
export const base62Schema = stringSchema.regex(/^[a-zA-Z0-9]+$/)
|
|
55
|
+
export const base64Schema = stringSchema.regex(/^[a-zA-Z0-9+/]+$/)
|
|
56
|
+
export const base64UrlSchema = stringSchema.regex(/^[a-zA-Z0-9-_]+$/)
|
|
57
|
+
|
|
50
58
|
/**
|
|
51
59
|
* `_` should NOT be allowed to be able to use slug-ids as part of natural ids with `_` separator.
|
|
52
60
|
*/
|
|
@@ -55,7 +63,7 @@ export const SLUG_PATTERN = /^[a-z0-9-]*$/
|
|
|
55
63
|
/**
|
|
56
64
|
* "Slug" - a valid URL, filename, etc.
|
|
57
65
|
*/
|
|
58
|
-
export const slugSchema = stringSchema.regex(/^[a-z0-9-]{1,255}$/)
|
|
66
|
+
export const slugSchema = stringSchema.regex(/^[a-z0-9-_]{1,255}$/)
|
|
59
67
|
|
|
60
68
|
const TS_2500 = 16725225600 // 2500-01-01
|
|
61
69
|
const TS_2000 = 946684800 // 2000-01-01
|