key-rotation-manager 1.0.11 → 1.1.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/README.md +3 -2
- package/dist/index.cjs +75 -113
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +75 -112
- package/dist/index.js.map +1 -1
- package/package.json +1 -5
package/README.md
CHANGED
|
@@ -615,7 +615,8 @@ Sets a single hook.
|
|
|
615
615
|
|
|
616
616
|
See the full changelog for each version:
|
|
617
617
|
|
|
618
|
-
- **[v1.
|
|
618
|
+
- **[v1.1.1](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.1.1.md)** - Native crypto, zero dependencies, bug fixes
|
|
619
|
+
- **[v1.0.10](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.0.10.md)** - Hooks system, enhanced gitIgnore configuration
|
|
619
620
|
|
|
620
621
|
---
|
|
621
622
|
|
|
@@ -648,7 +649,7 @@ Contributions are welcome! Please feel free to submit a Pull Request.
|
|
|
648
649
|
|
|
649
650
|
## 📄 License
|
|
650
651
|
|
|
651
|
-
This project is licensed under the MIT License - see the [LICENSE](LICENSE) file for details.
|
|
652
|
+
This project is licensed under the MIT License - see the [LICENSE](https://github.com/DucAnh2611/key-rotation-manager/blob/master/LICENSE) file for details.
|
|
652
653
|
|
|
653
654
|
---
|
|
654
655
|
|
package/dist/index.cjs
CHANGED
|
@@ -2,12 +2,11 @@
|
|
|
2
2
|
|
|
3
3
|
var promises = require('fs/promises');
|
|
4
4
|
var path = require('path');
|
|
5
|
-
var
|
|
5
|
+
var crypto = require('crypto');
|
|
6
6
|
var EventEmitter = require('events');
|
|
7
7
|
|
|
8
8
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
9
9
|
|
|
10
|
-
var CryptoJS__default = /*#__PURE__*/_interopDefault(CryptoJS);
|
|
11
10
|
var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
|
|
12
11
|
|
|
13
12
|
// src/constants/default.constant.ts
|
|
@@ -185,7 +184,7 @@ var isType = (data) => {
|
|
|
185
184
|
return {
|
|
186
185
|
number: typeof data === "number" && !Number.isNaN(Number(data)),
|
|
187
186
|
string: typeof data === "string",
|
|
188
|
-
stringNumber: typeof data === "string"
|
|
187
|
+
stringNumber: typeof data === "string" || typeof data === "number",
|
|
189
188
|
boolean: typeof data === "boolean",
|
|
190
189
|
null: data === null,
|
|
191
190
|
undefined: data === void 0
|
|
@@ -196,97 +195,77 @@ var CryptoService = class {
|
|
|
196
195
|
constructor(options = {}) {
|
|
197
196
|
this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };
|
|
198
197
|
}
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
198
|
+
/**
|
|
199
|
+
* Generate random bytes and encode them
|
|
200
|
+
*/
|
|
202
201
|
generateRandom(length = 32) {
|
|
203
|
-
const
|
|
204
|
-
return this.
|
|
202
|
+
const buffer = crypto.randomBytes(length);
|
|
203
|
+
return this.encodeBuffer(buffer);
|
|
205
204
|
}
|
|
206
|
-
|
|
205
|
+
/**
|
|
207
206
|
* Generate a random key
|
|
208
|
-
* @param length Length of the key
|
|
207
|
+
* @param length Length of the key in bytes
|
|
209
208
|
* @default cryptoOptions.keyLength
|
|
210
|
-
* @returns { key: string, length: number }
|
|
211
209
|
*/
|
|
212
210
|
generateKey(length = this.options.keyLength) {
|
|
213
211
|
return { key: this.generateRandom(length), length };
|
|
214
212
|
}
|
|
215
|
-
|
|
213
|
+
/**
|
|
216
214
|
* Generate a random salt
|
|
217
|
-
* @param length Length of the salt
|
|
215
|
+
* @param length Length of the salt in bytes
|
|
218
216
|
* @default cryptoOptions.saltLength
|
|
219
|
-
* @returns { salt: string, length: number }
|
|
220
217
|
*/
|
|
221
218
|
generateSalt(length = this.options.saltLength) {
|
|
222
219
|
return { salt: this.generateRandom(length), length };
|
|
223
220
|
}
|
|
224
|
-
|
|
221
|
+
/**
|
|
225
222
|
* Generate a random IV
|
|
226
|
-
* @param length Length of the IV
|
|
223
|
+
* @param length Length of the IV in bytes
|
|
227
224
|
* @default cryptoOptions.ivLength
|
|
228
|
-
* @returns { iv: string, length: number }
|
|
229
225
|
*/
|
|
230
226
|
generateIV(length = this.options.ivLength) {
|
|
231
227
|
return { iv: this.generateRandom(length), length };
|
|
232
228
|
}
|
|
233
|
-
|
|
229
|
+
encodeBuffer(buffer) {
|
|
234
230
|
switch (this.options.encoding) {
|
|
235
231
|
case "hex":
|
|
236
|
-
return
|
|
232
|
+
return buffer.toString("hex");
|
|
237
233
|
case "base64url":
|
|
238
|
-
return
|
|
234
|
+
return buffer.toString("base64url");
|
|
239
235
|
case "base64":
|
|
240
236
|
default:
|
|
241
|
-
return
|
|
237
|
+
return buffer.toString("base64");
|
|
242
238
|
}
|
|
243
239
|
}
|
|
244
|
-
|
|
240
|
+
decodeToBuffer(encoded) {
|
|
245
241
|
switch (this.options.encoding) {
|
|
246
242
|
case "hex":
|
|
247
|
-
return
|
|
243
|
+
return Buffer.from(encoded, "hex");
|
|
248
244
|
case "base64url":
|
|
249
|
-
|
|
250
|
-
const padding = "=".repeat((4 - base64.length % 4) % 4);
|
|
251
|
-
return CryptoJS__default.default.enc.Base64.parse(base64 + padding);
|
|
245
|
+
return Buffer.from(encoded, "base64url");
|
|
252
246
|
case "base64":
|
|
253
247
|
default:
|
|
254
|
-
return
|
|
248
|
+
return Buffer.from(encoded, "base64");
|
|
255
249
|
}
|
|
256
250
|
}
|
|
257
251
|
deriveKey(password, salt, keyLength) {
|
|
258
252
|
if (this.options.kdf === "none") {
|
|
259
|
-
return
|
|
253
|
+
return Buffer.from(password, "hex");
|
|
260
254
|
}
|
|
261
255
|
const actualKeyLength = keyLength ?? this.options.keyLength;
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
getHasher() {
|
|
270
|
-
switch (this.options.hashAlgorithm) {
|
|
271
|
-
case "sha512":
|
|
272
|
-
return CryptoJS__default.default.algo.SHA512;
|
|
273
|
-
case "sha384":
|
|
274
|
-
return CryptoJS__default.default.algo.SHA384;
|
|
275
|
-
case "sha256":
|
|
276
|
-
default:
|
|
277
|
-
return CryptoJS__default.default.algo.SHA256;
|
|
278
|
-
}
|
|
279
|
-
}
|
|
280
|
-
getAESMode() {
|
|
281
|
-
return CryptoJS__default.default.mode.CBC;
|
|
282
|
-
}
|
|
283
|
-
getPadding() {
|
|
284
|
-
return CryptoJS__default.default.pad.Pkcs7;
|
|
256
|
+
return crypto.pbkdf2Sync(
|
|
257
|
+
password,
|
|
258
|
+
salt,
|
|
259
|
+
this.options.iterations,
|
|
260
|
+
actualKeyLength,
|
|
261
|
+
this.options.hashAlgorithm
|
|
262
|
+
);
|
|
285
263
|
}
|
|
286
264
|
/**
|
|
287
|
-
* Encrypt data
|
|
265
|
+
* Encrypt data using AES-CBC
|
|
288
266
|
* @param plainText Text to encrypt
|
|
289
|
-
* @param secret Secret key for encryption
|
|
267
|
+
* @param secret Secret key for encryption
|
|
268
|
+
* @param options Optional lengths for key, salt, and IV
|
|
290
269
|
*/
|
|
291
270
|
encrypt(plainText, secret, {
|
|
292
271
|
keyLength,
|
|
@@ -296,61 +275,48 @@ var CryptoService = class {
|
|
|
296
275
|
keyLength = keyLength ?? this.options.keyLength;
|
|
297
276
|
saltLength = saltLength ?? this.options.saltLength;
|
|
298
277
|
ivLength = ivLength ?? this.options.ivLength;
|
|
299
|
-
const salt = this.options.kdf !== "none" ?
|
|
300
|
-
const iv =
|
|
278
|
+
const salt = this.options.kdf !== "none" ? crypto.randomBytes(saltLength) : Buffer.alloc(0);
|
|
279
|
+
const iv = crypto.randomBytes(ivLength);
|
|
301
280
|
const key = this.deriveKey(secret, salt, keyLength);
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
const
|
|
309
|
-
|
|
310
|
-
const
|
|
311
|
-
|
|
312
|
-
const ivHex = iv.toString(CryptoJS__default.default.enc.Hex);
|
|
313
|
-
const encryptedHex = encrypted.ciphertext.toString(CryptoJS__default.default.enc.Hex);
|
|
314
|
-
const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;
|
|
315
|
-
return this.encode(CryptoJS__default.default.enc.Hex.parse(combined));
|
|
281
|
+
const cipher = crypto.createCipheriv(this.options.algorithm, key, iv);
|
|
282
|
+
const encrypted = Buffer.concat([cipher.update(plainText, "utf8"), cipher.final()]);
|
|
283
|
+
const keyLengthBuf = Buffer.alloc(2);
|
|
284
|
+
keyLengthBuf.writeUInt16BE(keyLength);
|
|
285
|
+
const saltLengthBuf = Buffer.alloc(2);
|
|
286
|
+
saltLengthBuf.writeUInt16BE(salt.length);
|
|
287
|
+
const ivLengthBuf = Buffer.alloc(2);
|
|
288
|
+
ivLengthBuf.writeUInt16BE(ivLength);
|
|
289
|
+
const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);
|
|
290
|
+
return this.encodeBuffer(combined);
|
|
316
291
|
}
|
|
317
292
|
/**
|
|
318
293
|
* Decrypt data
|
|
319
294
|
* @param encryptedData Encrypted data to decrypt
|
|
320
295
|
* @param secret Secret key for decryption
|
|
296
|
+
* @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)
|
|
321
297
|
*/
|
|
322
298
|
decrypt(encryptedData, secret) {
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
const encrypted = CryptoJS__default.default.lib.CipherParams.create({
|
|
345
|
-
ciphertext: CryptoJS__default.default.enc.Hex.parse(encryptedHex)
|
|
346
|
-
});
|
|
347
|
-
const key = this.deriveKey(secret, salt, keyLength);
|
|
348
|
-
const decrypted = CryptoJS__default.default.AES.decrypt(encrypted, key, {
|
|
349
|
-
iv,
|
|
350
|
-
mode: this.getAESMode(),
|
|
351
|
-
padding: this.getPadding()
|
|
352
|
-
});
|
|
353
|
-
return decrypted.toString(CryptoJS__default.default.enc.Utf8);
|
|
299
|
+
try {
|
|
300
|
+
const combined = this.decodeToBuffer(encryptedData);
|
|
301
|
+
let offset = 0;
|
|
302
|
+
const keyLength = combined.readUInt16BE(offset);
|
|
303
|
+
offset += 2;
|
|
304
|
+
const saltLength = combined.readUInt16BE(offset);
|
|
305
|
+
offset += 2;
|
|
306
|
+
const ivLength = combined.readUInt16BE(offset);
|
|
307
|
+
offset += 2;
|
|
308
|
+
const salt = combined.subarray(offset, offset + saltLength);
|
|
309
|
+
offset += saltLength;
|
|
310
|
+
const iv = combined.subarray(offset, offset + ivLength);
|
|
311
|
+
offset += ivLength;
|
|
312
|
+
const encrypted = combined.subarray(offset);
|
|
313
|
+
const key = this.deriveKey(secret, salt, keyLength);
|
|
314
|
+
const decipher = crypto.createDecipheriv(this.options.algorithm, key, iv);
|
|
315
|
+
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
316
|
+
return decrypted.toString("utf8");
|
|
317
|
+
} catch {
|
|
318
|
+
return "";
|
|
319
|
+
}
|
|
354
320
|
}
|
|
355
321
|
/**
|
|
356
322
|
* Hash data (one-way)
|
|
@@ -359,19 +325,17 @@ var CryptoService = class {
|
|
|
359
325
|
* @param salt Optional encoded salt string for deterministic hashing
|
|
360
326
|
*/
|
|
361
327
|
hash(data, secret, salt) {
|
|
362
|
-
|
|
363
|
-
const hasher = this.getHasher();
|
|
364
|
-
let saltWordArray;
|
|
328
|
+
let saltBuffer;
|
|
365
329
|
let saltStr;
|
|
366
330
|
if (salt) {
|
|
367
|
-
|
|
331
|
+
saltBuffer = this.decodeToBuffer(salt);
|
|
368
332
|
saltStr = salt;
|
|
369
333
|
} else {
|
|
370
|
-
|
|
371
|
-
saltStr = this.
|
|
334
|
+
saltBuffer = crypto.randomBytes(this.options.saltLength);
|
|
335
|
+
saltStr = this.encodeBuffer(saltBuffer);
|
|
372
336
|
}
|
|
373
|
-
const hash =
|
|
374
|
-
const hashStr = this.
|
|
337
|
+
const hash = crypto.createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
|
|
338
|
+
const hashStr = this.encodeBuffer(hash);
|
|
375
339
|
return `${saltStr}:${hashStr}`;
|
|
376
340
|
}
|
|
377
341
|
/**
|
|
@@ -385,11 +349,9 @@ var CryptoService = class {
|
|
|
385
349
|
if (!saltStr || !expectedHashStr) {
|
|
386
350
|
return false;
|
|
387
351
|
}
|
|
388
|
-
const
|
|
389
|
-
const
|
|
390
|
-
const
|
|
391
|
-
const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();
|
|
392
|
-
const hashStr = this.encode(hash);
|
|
352
|
+
const saltBuffer = this.decodeToBuffer(saltStr);
|
|
353
|
+
const hash = crypto.createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
|
|
354
|
+
const hashStr = this.encodeBuffer(hash);
|
|
393
355
|
return hashStr === expectedHashStr;
|
|
394
356
|
}
|
|
395
357
|
};
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent","access","mkdir","readFile","path","dirname","writeFile","unlink","CryptoJS","EventEmitter","join"],"mappings":"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","file":"index.cjs","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber:\n (typeof data === 'string' && !Number.isNaN(Number(data))) || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import CryptoJS from 'crypto-js';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: TCryptoOptions;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n private generateRandomWordArray(length: number): CryptoJS.lib.WordArray {\n return CryptoJS.lib.WordArray.random(length);\n }\n\n generateRandom(length: number = 32): string {\n const wordArray = this.generateRandomWordArray(length);\n return this.encode(wordArray);\n }\n\n /*\n * Generate a random key\n * @param length Length of the key\n * @default cryptoOptions.keyLength\n * @returns { key: string, length: number }\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random salt\n * @param length Length of the salt\n * @default cryptoOptions.saltLength\n * @returns { salt: string, length: number }\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random IV\n * @param length Length of the IV\n * @default cryptoOptions.ivLength\n * @returns { iv: string, length: number }\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encode(wordArray: CryptoJS.lib.WordArray): string {\n switch (this.options.encoding) {\n case 'hex':\n return wordArray.toString(CryptoJS.enc.Hex);\n case 'base64url':\n return wordArray\n .toString(CryptoJS.enc.Base64)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n case 'base64':\n default:\n return wordArray.toString(CryptoJS.enc.Base64);\n }\n }\n\n private decode(encoded: string): CryptoJS.lib.WordArray {\n switch (this.options.encoding) {\n case 'hex':\n return CryptoJS.enc.Hex.parse(encoded);\n case 'base64url':\n // Convert base64url to base64\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padding = '='.repeat((4 - (base64.length % 4)) % 4);\n return CryptoJS.enc.Base64.parse(base64 + padding);\n case 'base64':\n default:\n return CryptoJS.enc.Base64.parse(encoded);\n }\n }\n\n private deriveKey(\n password: string,\n salt: CryptoJS.lib.WordArray,\n keyLength?: number\n ): CryptoJS.lib.WordArray {\n if (this.options.kdf === 'none') {\n return CryptoJS.enc.Hex.parse(password);\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n const keySize = actualKeyLength / 4;\n return CryptoJS.PBKDF2(password, salt, {\n keySize,\n iterations: this.options.iterations,\n hasher: this.getHasher(),\n });\n }\n\n private getHasher(): typeof CryptoJS.algo.SHA256 {\n switch (this.options.hashAlgorithm) {\n case 'sha512':\n return CryptoJS.algo.SHA512;\n case 'sha384':\n return CryptoJS.algo.SHA384;\n case 'sha256':\n default:\n return CryptoJS.algo.SHA256;\n }\n }\n\n private getAESMode(): typeof CryptoJS.mode.CBC {\n return CryptoJS.mode.CBC;\n }\n\n private getPadding(): typeof CryptoJS.pad.Pkcs7 {\n return CryptoJS.pad.Pkcs7;\n }\n\n /**\n * Encrypt data\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption Key length, salt, and IV will be randomly generated within configured range\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt =\n this.options.kdf !== 'none'\n ? this.generateRandomWordArray(saltLength)\n : CryptoJS.lib.WordArray.create();\n const iv = this.generateRandomWordArray(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const encrypted = CryptoJS.AES.encrypt(plainText, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n const actualSaltLength = salt.sigBytes;\n const keyLengthHex = keyLength.toString(16).padStart(4, '0');\n const saltLengthHex = actualSaltLength.toString(16).padStart(4, '0');\n const ivLengthHex = ivLength.toString(16).padStart(4, '0');\n const saltHex = salt.toString(CryptoJS.enc.Hex);\n const ivHex = iv.toString(CryptoJS.enc.Hex);\n const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);\n\n const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;\n return this.encode(CryptoJS.enc.Hex.parse(combined));\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n */\n decrypt(encryptedData: string, secret: string): string {\n const combined = this.decode(encryptedData);\n const combinedHex = combined.toString(CryptoJS.enc.Hex);\n\n let offset = 0;\n\n // Read key, salt and IV lengths (4 hex chars = 2 bytes each)\n const keyLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const saltLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const ivLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n\n const keyLength = parseInt(keyLengthHex, 16);\n const saltLength = parseInt(saltLengthHex, 16);\n const ivLength = parseInt(ivLengthHex, 16);\n\n // Read salt and IV based on their lengths stored in the encrypted data\n const saltHexLength = saltLength * 2; // hex is 2 chars per byte\n const ivHexLength = ivLength * 2;\n\n const saltHex = saltHexLength > 0 ? combinedHex.substring(offset, offset + saltHexLength) : '';\n offset += saltHexLength;\n\n const ivHex = combinedHex.substring(offset, offset + ivHexLength);\n offset += ivHexLength;\n\n const encryptedHex = combinedHex.substring(offset);\n\n const salt = saltHex ? CryptoJS.enc.Hex.parse(saltHex) : CryptoJS.lib.WordArray.create();\n const iv = CryptoJS.enc.Hex.parse(ivHex);\n const encrypted = CryptoJS.lib.CipherParams.create({\n ciphertext: CryptoJS.enc.Hex.parse(encryptedHex),\n });\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decrypted = CryptoJS.AES.decrypt(encrypted, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n return decrypted.toString(CryptoJS.enc.Utf8);\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n let saltWordArray: CryptoJS.lib.WordArray;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltWordArray = this.decode(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltWordArray = this.generateRandomWordArray(this.options.saltLength);\n saltStr = this.encode(saltWordArray);\n }\n\n const hash = hasher\n .create()\n .update(data)\n .update(secretWordArray)\n .update(saltWordArray)\n .finalize();\n\n const hashStr = this.encode(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const salt = this.decode(saltStr);\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();\n\n const hashStr = this.encode(hash);\n\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent","access","mkdir","readFile","path","dirname","writeFile","unlink","randomBytes","pbkdf2Sync","createCipheriv","createDecipheriv","createHash","EventEmitter","join"],"mappings":";;;;;;;;;;;;AAKO,IAAM,sBAAA,GAAmD;AAAA,EAC9D,SAAA,EAAW,aAAA;AAAA,EACX,GAAA,EAAK,QAAA;AAAA,EACL,aAAA,EAAe,QAAA;AAAA,EACf,SAAA,EAAW,EAAA;AAAA,EACX,QAAA,EAAU,EAAA;AAAA,EACV,UAAA,EAAY,EAAA;AAAA,EACZ,SAAA,EAAW,EAAA;AAAA,EACX,UAAA,EAAY,GAAA;AAAA,EACZ,QAAA,EAAU;AACZ,CAAA;AAEO,IAAM,oBAAA,GAA+C;AAAA,EAC1D,KAAA,EAAO;AACT,CAAA;AAEO,IAAM,sBAAsB,CAAA,GAAI,IAAA,KAAgB,OAAA,CAAQ,GAAA,CAAI,GAAG,IAAI,CAAA;AAEnE,IAAM,sBAAA,GAAmD;AAAA,EAC9D,GAAG,oBAAA;AAAA;AAAA,EAGH,QAAA,EAAU;AACZ,CAAA;AAEO,IAAM,qBAAA,GAAiD;AAAA,EAC5D,IAAA,EAAM,CAAC,MAAA,EAAQ,UAAU,CAAA;AAAA,EACzB,IAAA,EAAM,CAAC,GAAA,EAAK,aAAa,CAAA;AAAA,EACzB,WAAA,EAAa,GAAA;AAAA,EACb,OAAA,EAAS,MAAA;AAAA,EACT,SAAA,EAAW,IAAA;AAAA,EAEX,GAAG,sBAAA;AAAA;AAAA,EAGH,MAAA,EAAQ;AACV,CAAA;AAEO,IAAM,2BAAA,GAA4D;AAAA;AAAA,EAEvE,GAAG,qBAAA;AAAA,EAEH,gBAAA,EAAkB,MAAA,iBAAM,IAAI,IAAA,IAAO,OAAA;AACrC,CAAA;AAEO,IAAM,sBAAA,GAAmD;AAAA,EAC9D,GAAG,2BAAA;AAAA;AAAA,EAGH,KAAA,EAAO;AACT,CAAA;;;ACpDO,IAAK,MAAA,qBAAAA,OAAAA,KAAL;AACL,EAAAA,QAAA,mBAAA,CAAA,GAAoB,mBAAA;AACpB,EAAAA,QAAA,kBAAA,CAAA,GAAmB,gBAAA;AAFT,EAAA,OAAAA,OAAAA;AAAA,CAAA,EAAA,MAAA,IAAA,EAAA;;;ACHL,IAAM,iBAAA,GAAoB,CAC/B,WAAA,KACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GACJ,OAAO,WAAA,KAAgB,UAAA,IAAc,EAAE,WAAA,YAAuB,OAAA,CAAA,GACzD,aAAuD,GACxD,WAAA;AACN,IAAA,OAAO,OAAA,CAAQ,QAAQ,KAAK,CAAA;AAAA,EAC9B,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,EAC7B;AACF,CAAA;ACTO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,WAAA,CACE,OAAA,EACgB,IAAA,EACA,SAAA,EACA,KAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJG,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,WAAN,MAAe;AAAA,EACpB,MAAM,UAAU,IAAA,EAA+B;AAC7C,IAAA,IAAI;AACF,MAAA,MAAMC,gBAAO,IAAI,CAAA;AACjB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,IAAI;AACF,QAAA,MAAMC,cAAA,CAAM,IAAA,EAAM,EAAE,SAAA,EAAW,MAAM,CAAA;AACrC,QAAA,OAAO,IAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,IAAI,aAAA,CAAc,CAAA,yBAAA,EAA4B,IAAI,CAAA,CAAA,EAAI,IAAA,EAAM,SAAS,KAAK,CAAA;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,IAAA,EAAc,QAAA,EAAoC;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAMC,iBAAA,CAAS,MAAM,EAAE,QAAA,EAAU,QAAQ,CAAA;AACtD,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AACnC,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,qBAAA,EAAwB,IAAI,CAAA,CAAA,EAAI,IAAA,EAAM,QAAQ,KAAK,CAAA;AAAA,IAC7E;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CAAMC,MAAA,EAAc,IAAA,EAAc,OAAkB,GAAA,EAAoB;AAC5E,IAAA,MAAM,GAAA,GAAMC,aAAQD,MAAI,CAAA;AACxB,IAAA,MAAM,IAAA,CAAK,UAAU,GAAG,CAAA;AAExB,IAAA,IAAI;AACF,MAAA,MAAME,mBAAUF,MAAA,EAAM,IAAA,EAAM,EAAE,QAAA,EAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,IACxD,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,sBAAA,EAAyBA,MAAI,CAAA,CAAA,EAAIA,MAAA,EAAM,SAAS,KAAK,CAAA;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,IAAA,EAAgC;AAChD,IAAA,IAAI;AACF,MAAA,MAAMH,gBAAO,IAAI,CAAA;AACjB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,IAAA,EAA6B;AACxC,IAAA,IAAI;AACF,MAAA,MAAMM,gBAAO,IAAI,CAAA;AAAA,IACnB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAA,EAAI,IAAA,EAAM,UAAU,KAAK,CAAA;AAAA,IACjF;AAAA,EACF;AACF,CAAA;;;ACjEA,IAAM,SAAA,GAAY,CAAC,GAAA,EAA0B,IAAA,KAC3C,KAAK,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,EAAM,GAAA,KAAQ,IAAA,GAAO,GAAG,GAAG,GAAG,CAAA;AAExD,IAAM,OAAA,GAAU,CAAC,GAAA,EAA0B,MAAA,GAAS,OAClD,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAAE,OAAO,CAAC,GAAA,EAAK,CAAC,GAAA,EAAK,GAAG,CAAA,KAAM;AAC9C,EAAA,MAAM,SAAS,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,GAAA;AAC7C,EAAA,OAAO,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,CAAC,MAAM,OAAA,CAAQ,GAAG,CAAA,GACvD,EAAE,GAAG,GAAA,EAAK,GAAG,OAAA,CAAQ,GAAA,EAAK,MAAM,CAAA,EAAE,GAClC,EAAE,GAAG,GAAA,EAAK,CAAC,MAAM,GAAG,GAAA,EAAI;AAC9B,CAAA,EAAG,EAAE,CAAA;AAEP,IAAM,SAAA,GAAY,CAAC,GAAA,KAAqB;AACtC,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,MAAA,EAAW,OAAO,EAAA;AAC9C,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,IAAA,CAAK,UAAU,GAAG,CAAA;AACtD,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB,CAAA;AAEO,IAAM,UAAA,GAAa,CAAC,MAAA,EAAgB,UAAA,KAA4C;AACrF,EAAA,OAAO,MAAA,CACJ,OAAA,CAAQ,wBAAA,EAA0B,CAAC,OAAO,IAAA,KAAS;AAClD,IAAA,MAAM,WAAA,GAAc,KAAK,IAAA,EAAK;AAC9B,IAAA,MAAM,GAAA,GAAM,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA,GAChC,UAAU,UAAA,EAAY,WAAW,CAAA,GACjC,UAAA,CAAW,WAAW,CAAA;AAE1B,IAAA,OAAO,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GACvD,KAAK,SAAA,CAAU,OAAA,CAAQ,GAAA,EAAK,WAAW,CAAC,CAAA,GACxC,KAAA;AAAA,EACN,CAAC,CAAA,CACA,OAAA,CAAQ,kBAAA,EAAoB,CAAC,OAAO,IAAA,KAAS;AAC5C,IAAA,MAAM,WAAA,GAAc,KAAK,IAAA,EAAK;AAG9B,IAAA,IAAI,WAAA,CAAY,UAAA,CAAW,KAAK,CAAA,EAAG;AACjC,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,GAAA,GAAM,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA,GAChC,UAAU,UAAA,EAAY,WAAW,CAAA,GACjC,UAAA,CAAW,WAAW,CAAA;AAC1B,IAAA,OAAO,UAAU,GAAG,CAAA;AAAA,EACtB,CAAC,CAAA;AACL,CAAA;AACO,IAAM,MAAA,GAAS,CAAC,IAAA,KAA0B;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,IAAI,CAAA;AAC1B,IAAA,OAAO,CAAC,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,CAAA;AAAA,EAC9B,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA;AAEO,IAAM,WAAA,GAAc,CAAC,IAAA,EAAY,QAAA,EAAkB,IAAA,KAAiC;AACzF,EAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA;AAEtC,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,SAAA;AACH,MAAA,MAAA,CAAO,UAAA,CAAW,MAAA,CAAO,UAAA,EAAW,GAAI,QAAQ,CAAA;AAChD,MAAA;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,MAAA,CAAO,UAAA,CAAW,MAAA,CAAO,UAAA,EAAW,GAAI,QAAQ,CAAA;AAChD,MAAA;AAAA,IAEF,KAAK,OAAA;AACH,MAAA,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,QAAA,EAAS,GAAI,QAAQ,CAAA;AAC5C,MAAA;AAAA,IAEF,KAAK,MAAA;AACH,MAAA,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAQ,GAAI,QAAQ,CAAA;AAC1C,MAAA;AAAA,IAEF,SAAS;AACP,MAAA,MAAM,gBAAA,GAA0B,IAAA;AAChC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,gBAAgB,CAAA,CAAE,CAAA;AAAA,IAClE;AAAA;AAGF,EAAA,OAAO,MAAA;AACT,CAAA;AAEO,IAAM,MAAA,GAAS,CAAC,IAAA,KAAmB;AACxC,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,IAC9D,MAAA,EAAQ,OAAO,IAAA,KAAS,QAAA;AAAA,IACxB,YAAA,EAAc,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,IAAA,KAAS,QAAA;AAAA,IAC1D,OAAA,EAAS,OAAO,IAAA,KAAS,SAAA;AAAA,IACzB,MAAM,IAAA,KAAS,IAAA;AAAA,IACf,WAAW,IAAA,KAAS;AAAA,GACtB;AACF,CAAA;ACxFO,IAAM,gBAAN,MAAoB;AAAA,EACjB,OAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,IAAA,CAAK,OAAA,GAAU,EAAE,GAAG,sBAAA,EAAwB,GAAG,OAAA,EAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CAAe,SAAiB,EAAA,EAAY;AAC1C,IAAA,MAAM,MAAA,GAASC,mBAAY,MAAM,CAAA;AACjC,IAAA,OAAO,IAAA,CAAK,aAAa,MAAM,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAA,CAAY,MAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW;AACnD,IAAA,OAAO,EAAE,GAAA,EAAK,IAAA,CAAK,cAAA,CAAe,MAAM,GAAG,MAAA,EAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAA,CAAa,MAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY;AACrD,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,cAAA,CAAe,MAAM,GAAG,MAAA,EAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAA,CAAW,MAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU;AACjD,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,CAAK,cAAA,CAAe,MAAM,GAAG,MAAA,EAAO;AAAA,EACnD;AAAA,EAEQ,aAAa,MAAA,EAAwB;AAC3C,IAAA,QAAQ,IAAA,CAAK,QAAQ,QAAA;AAAU,MAC7B,KAAK,KAAA;AACH,QAAA,OAAO,MAAA,CAAO,SAAS,KAAK,CAAA;AAAA,MAC9B,KAAK,WAAA;AACH,QAAA,OAAO,MAAA,CAAO,SAAS,WAAW,CAAA;AAAA,MACpC,KAAK,QAAA;AAAA,MACL;AACE,QAAA,OAAO,MAAA,CAAO,SAAS,QAAQ,CAAA;AAAA;AACnC,EACF;AAAA,EAEQ,eAAe,OAAA,EAAyB;AAC9C,IAAA,QAAQ,IAAA,CAAK,QAAQ,QAAA;AAAU,MAC7B,KAAK,KAAA;AACH,QAAA,OAAO,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,KAAK,CAAA;AAAA,MACnC,KAAK,WAAA;AACH,QAAA,OAAO,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,WAAW,CAAA;AAAA,MACzC,KAAK,QAAA;AAAA,MACL;AACE,QAAA,OAAO,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AAAA;AACxC,EACF;AAAA,EAEQ,SAAA,CAAU,QAAA,EAAkB,IAAA,EAAc,SAAA,EAA4B;AAC5E,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,KAAQ,MAAA,EAAQ;AAC/B,MAAA,OAAO,MAAA,CAAO,IAAA,CAAK,QAAA,EAAU,KAAK,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,eAAA,GAAkB,SAAA,IAAa,IAAA,CAAK,OAAA,CAAQ,SAAA;AAClD,IAAA,OAAOC,iBAAA;AAAA,MACL,QAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAK,OAAA,CAAQ,UAAA;AAAA,MACb,eAAA;AAAA,MACA,KAAK,OAAA,CAAQ;AAAA,KACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAA,CACE,WACA,MAAA,EACA;AAAA,IACE,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAoE,EAAC,EAC7D;AACR,IAAA,SAAA,GAAY,SAAA,IAAa,KAAK,OAAA,CAAQ,SAAA;AACtC,IAAA,UAAA,GAAa,UAAA,IAAc,KAAK,OAAA,CAAQ,UAAA;AACxC,IAAA,QAAA,GAAW,QAAA,IAAY,KAAK,OAAA,CAAQ,QAAA;AAEpC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,KAAQ,MAAA,GAASD,mBAAY,UAAU,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AACnF,IAAA,MAAM,EAAA,GAAKA,mBAAY,QAAQ,CAAA;AAC/B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,MAAM,SAAS,CAAA;AAElD,IAAA,MAAM,SAASE,qBAAA,CAAe,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,KAAK,EAAE,CAAA;AAC7D,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,CAAC,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,MAAM,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,CAAC,CAAA;AAGlF,IAAA,MAAM,YAAA,GAAe,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AACnC,IAAA,YAAA,CAAa,cAAc,SAAS,CAAA;AAEpC,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AACpC,IAAA,aAAA,CAAc,aAAA,CAAc,KAAK,MAAM,CAAA;AAEvC,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AAClC,IAAA,WAAA,CAAY,cAAc,QAAQ,CAAA;AAElC,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,CAAC,YAAA,EAAc,eAAe,WAAA,EAAa,IAAA,EAAM,EAAA,EAAI,SAAS,CAAC,CAAA;AAE9F,IAAA,OAAO,IAAA,CAAK,aAAa,QAAQ,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAA,CAAQ,eAAuB,MAAA,EAAwB;AACrD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,cAAA,CAAe,aAAa,CAAA;AAClD,MAAA,IAAI,MAAA,GAAS,CAAA;AAGb,MAAA,MAAM,SAAA,GAAY,QAAA,CAAS,YAAA,CAAa,MAAM,CAAA;AAC9C,MAAA,MAAA,IAAU,CAAA;AACV,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,YAAA,CAAa,MAAM,CAAA;AAC/C,MAAA,MAAA,IAAU,CAAA;AACV,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,YAAA,CAAa,MAAM,CAAA;AAC7C,MAAA,MAAA,IAAU,CAAA;AAGV,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ,SAAS,UAAU,CAAA;AAC1D,MAAA,MAAA,IAAU,UAAA;AAEV,MAAA,MAAM,EAAA,GAAK,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ,SAAS,QAAQ,CAAA;AACtD,MAAA,MAAA,IAAU,QAAA;AAEV,MAAA,MAAM,SAAA,GAAY,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA;AAE1C,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,MAAM,SAAS,CAAA;AAElD,MAAA,MAAM,WAAWC,uBAAA,CAAiB,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,KAAK,EAAE,CAAA;AACjE,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,CAAC,QAAA,CAAS,MAAA,CAAO,SAAS,CAAA,EAAG,QAAA,CAAS,KAAA,EAAO,CAAC,CAAA;AAE9E,MAAA,OAAO,SAAA,CAAU,SAAS,MAAM,CAAA;AAAA,IAClC,CAAA,CAAA,MAAQ;AAGN,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAA,CAAK,IAAA,EAAc,MAAA,EAAgB,IAAA,EAAuB;AACxD,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,OAAA;AAEJ,IAAA,IAAI,IAAA,EAAM;AAER,MAAA,UAAA,GAAa,IAAA,CAAK,eAAe,IAAI,CAAA;AACrC,MAAA,OAAA,GAAU,IAAA;AAAA,IACZ,CAAA,MAAO;AAEL,MAAA,UAAA,GAAaH,kBAAA,CAAY,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AAChD,MAAA,OAAA,GAAU,IAAA,CAAK,aAAa,UAAU,CAAA;AAAA,IACxC;AAEA,IAAA,MAAM,IAAA,GAAOI,iBAAA,CAAW,IAAA,CAAK,OAAA,CAAQ,aAAa,CAAA,CAC/C,MAAA,CAAO,IAAI,CAAA,CACX,OAAO,MAAM,CAAA,CACb,MAAA,CAAO,UAAU,EACjB,MAAA,EAAO;AAEV,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,IAAI,CAAA;AAEtC,IAAA,OAAO,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAA,CAAW,IAAA,EAAc,UAAA,EAAoB,MAAA,EAAyB;AACpE,IAAA,MAAM,CAAC,OAAA,EAAS,eAAe,CAAA,GAAI,UAAA,CAAW,MAAM,GAAG,CAAA;AACvD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,eAAA,EAAiB;AAChC,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AAE9C,IAAA,MAAM,IAAA,GAAOA,iBAAA,CAAW,IAAA,CAAK,OAAA,CAAQ,aAAa,CAAA,CAC/C,MAAA,CAAO,IAAI,CAAA,CACX,OAAO,MAAM,CAAA,CACb,MAAA,CAAO,UAAU,EACjB,MAAA,EAAO;AAEV,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,IAAI,CAAA;AAGtC,IAAA,OAAO,OAAA,KAAY,eAAA;AAAA,EACrB;AACF,CAAA;;;AC1NO,IAAM,OAAN,MAAoE;AAAA,EACjE,MAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA,uBAAgC,GAAA,EAAI;AAAA,EAE5C,YAAY,OAAA,EAAgC;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,oBAAA,EAAsB,GAAG,OAAA,EAAQ;AACtD,IAAA,IAAA,CAAK,MAAA,GAAS,mBAAA;AAAA,EAChB;AAAA,EAEU,SAAA,GAAkC;AAC1C,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEO,UAAU,MAAA,EAAoC;AACnD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEO,UAAU,IAAA,EAAiC;AAChD,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO;AACxB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAG,IAAI,CAAA;AAClC,MAAA,IAAI,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,WAAW,MAAA,EAAQ;AAC7D,QAAC,MAAA,CAA4B,MAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AAAA,MAC7C;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAa,SAAA,CACX,MAAA,EAAA,GACG,IAAA,EACH;AACA,IAAA,MAAM,MAAA,CAAO,GAAG,IAAI,CAAA;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEU,SAA+C,KAAA,EAAU;AACjE,IAAA,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,IAAA,EAAM,OAAO,CAAA,KAAM;AACjD,MAAA,IAAI,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,EAAG;AACxB,QAAA,IAAA,CAAK,MAAM,GAAA,CAAI,kBAAkB,CAAA,EAAG,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MACrD;AAEA,MAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AAAA,IAC9B,CAAC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEU,OAAA,CACR,SACG,IAAA,EACmB;AACtB,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAc,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,MAAM,GAAA,CAAI,gBAAgB,CAAA,EAAG,IAAA,CAAK,MAAM,IAAc,CAAA;AAC3D,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA,CAAK,MAAM,GAAA,CAAI,IAAc,EAAG,IAAA,CAAK,IAAA,EAAM,GAAG,IAAI,CAAA;AAAA,EAC3D;AAAA,EAEU,QAAA,GAAkC;AAC1C,IAAA,OAAO,MAAA,CAAO,WAAA,CAAY,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AAAA,EAChD;AACF,CAAA;;;AC/DO,IAAM,MAAA,GAAN,cAAqB,IAAA,CAAK;AAAA,EACvB,MAAA;AAAA,EACA,QAAA;AAAA,EAER,YAAY,OAAA,EAAyB;AACnC,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,QAAA,GAAW;AAAA,MACd,GAAG,sBAAA;AAAA,MACH,GAAG;AAAA,KACL;AAEA,IAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,MAAA,IAAA,CAAK,MAAA,GAAS,IAAIC,6BAAA,EAAa;AAAA,IACjC;AAAA,EACF;AAAA,EAEU,IAAA,CAA8B,OAAU,IAAA,EAAkB;AAClE,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,EAAA,CAA4B,OAAU,QAAA,EAAsC;AAC1E,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,QAAQ,CAAA;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,IAAA,CAA8B,OAAU,QAAA,EAAsC;AAC5E,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,QAAQ,CAAA;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,GAAA,CAA6B,OAAU,QAAA,EAAsC;AAC3E,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA;AAC/B,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;AC1CO,IAAM,KAAA,GAAN,cAAoB,MAAA,CAAO;AAAA,EACxB,QAAA;AAAA,EACA,QAAA;AAAA,EACE,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EAEV,YAAY,OAAA,EAAiC;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,qBAAA,EAAuB,GAAG,OAAA,EAAQ;AACvD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,QAAA,EAAS;AAE7B,IAAA,IAAA,CAAK,SAAA,EAAU;AAAA,EACjB;AAAA,EAEU,OAAA,CAAQ,MAAyB,OAAA,EAAyB;AAClE,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACnD,MAAA,OAAO,IAAA,CAAK,KAAK,OAAO,CAAA;AAAA,IAC1B;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAc,iBAAA,GAAqC;AACjD,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,OAAO,IAAA,CAAK,SAAA;AAEhC,IAAA,MAAM,QAAET,MAAA,EAAK,GAAI,IAAA,CAAK,QAAA;AAEtB,IAAA,MAAM,KAAA,GACJ,OAAOA,MAAA,KAAS,QAAA,IAAY,MAAM,OAAA,CAAQA,MAAI,IAC1CA,MAAA,CAAK,CAAC,IACN,OAAOA,MAAA,KAAS,WACbA,MAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,KAAK,EAAA,GACvB,EAAA;AAER,IAAA,IAAI,MAAA,GAAS,MAAM,IAAA,CAAK,QAAA,CAAS,SAAA,CAAUU,UAAK,OAAA,CAAQ,GAAA,EAAI,EAAG,KAAK,CAAC,CAAA;AAErE,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAgB,eAAe,QAAA,EAA0D;AACvF,IAAA,MAAM,eAAe,MAAM,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,UAAU,IAAI,CAAA;AAC5D,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,YAAY,CAAA;AAE/C,IAAA,OAAO,SAAA;AAAA,EACT;AAAA,EAEA,MAAgB,WAAA,CACd,IAAA,EACA,IAAA,EACA,QAAiB,KAAA,EACA;AACjB,IAAA,IAAI,SAAA,GAAY,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA;AAE9C,IAAA,IAAI,WAA0C,EAAC;AAE/C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,QAAA,GAAW,EAAE,GAAG,SAAA,EAAU;AAAA,IAC5B;AAEA,IAAA,QAAA,GAAW,EAAE,GAAG,QAAA,EAAU,CAAC,IAAA,CAAK,OAAO,GAAG,IAAA,EAAK;AAE/C,IAAA,MAAM,IAAA,CAAK,SAAS,KAAA,CAAM,IAAA,EAAM,KAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAC,CAAA;AAEjE,IAAA,IAAA,CAAK,IAAA,CAAA,gBAAA,yBAA8B,EAAE,IAAA,EAAM,IAAA,EAAM,UAAU,CAAA;AAE3D,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAa,SAAA,EAAyB;AAC3C,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAW,SAAA,EAA6B;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAU,QAAA,EAA2B;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAc,SAAA,GAA2B;AACvC,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,iBAAA,EAAkB;AAE/C,IAAA,IAAI,gBAAA,GAAsD;AAAA,MACxD;AAAA,KACF;AAEA,IAAA,IAAI,IAAA,CAAK,SAAS,SAAA,EAAW;AAC3B,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,uBAAA,EAAwB;AACrD,MAAA,gBAAA,GAAmB,EAAE,GAAG,gBAAA,EAAkB,GAAG,SAAA,EAAU;AAAA,IACzD;AAEA,IAAA,IAAA,CAAK,kDAA+B,gBAAgB,CAAA;AAAA,EACtD;AAAA,EAEQ,YAAY,UAAA,EAAmD;AACrE,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,UAAA,EAAY,OAAO,EAAC;AACzB,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AAExC,MAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC/D,QAAA,MAAM,IAAI,MAAM,4DAA4D,CAAA;AAAA,MAC9E;AAEA,MAAA,OAAO,UAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2DAAA,EAA8D,UAAU,CAAA,CAAE,CAAA;AAAA,IAC5F;AAAA,EACF;AAAA,EAEA,MAAc,uBAAA,GAEZ;AACA,IAAA,MAAM,aAAA,GAAgBA,SAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,YAAY,CAAA;AACtD,IAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,QAAA,CAAS,KAAK,aAAa,CAAA;AAE/D,IAAA,MAAM,MAAA,GAAS,KAAK,uBAAA,EAAwB;AAC5C,IAAA,MAAM,cAAA,GAAiB,gBAAA,CAAiB,KAAA,CAAM,OAAO,CAAA,CAAE,IAAI,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,CAAA;AAChF,IAAA,MAAM,eAAe,cAAA,CAAe,IAAA,CAAK,CAAC,IAAA,KAAS,SAAS,MAAM,CAAA;AAElE,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,aAAA,EAAe,CAAA,EAAG,gBAAA,GAAmB,MAAA,GAAS,EAAE,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA;AAE1F,MAAA,OAAO;AAAA,QACL,kBAAA,EAAoB,MAAA;AAAA,QACpB,aAAA,EAAe,aAAA;AAAA,QACf,kBAAA,EAAoB;AAAA,OACtB;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,kBAAA,EAAoB,MAAA;AAAA,MACpB,aAAA,EAAe,aAAA;AAAA,MACf,kBAAA,EAAoB;AAAA,KACtB;AAAA,EACF;AAAA,EAEQ,uBAAA,GAA0B;AAChC,IAAA,IAAI,MAAA,GAAS,EAAA;AACb,IAAA,MAAM,YAAY,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,MAAM,GAAG,CAAA;AAEtD,IAAA,IAAI,OAAO,IAAA,CAAK,QAAA,CAAS,SAAA,KAAc,SAAA,EAAW;AAChD,MAAA,MAAA,GAAS,IAAA,CAAK,iCAAiC,SAAS,CAAA;AAAA,IAC1D,CAAA,MAAO;AACL,MAAA,MAAA,GAAS,IAAA,CAAK,+BAAA,CAAgC,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAAA,IACvE;AAEA,IAAA,OAAO,IAAA,CAAK,sBAAsB,MAAM,CAAA;AAAA,EAC1C;AAAA,EAEQ,iCAAiC,SAAA,EAAmB;AAC1D,IAAA,MAAM,QAAA,GAAW,KAAK,OAAA,CAAQ,IAAA,CAAK,SAAS,IAAA,EAAM,IAAA,CAAK,SAAS,WAAW,CAAA;AAE3E,IAAA,MAAM,MAAA,GAAmB,CAAC,SAAS,CAAA;AACnC,IAAA,MAAA,CAAO,KAAK,CAAA,EAAG,QAAQ,IAAI,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,CAAE,CAAA;AAElD,IAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,EACxB;AAAA,EAEQ,gCAAgC,UAAA,EAA2B;AACjE,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY,GAAG,CAAA;AAAA,EACrC;AAAA,EAEQ,sBAAsB,IAAA,EAAsB;AAClD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,cAAA,EAAgB,GAAG,CAAA;AAAA,EACzC;AACF,CAAA;;;AC3KO,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EAC5B,aAAA;AAAA,EACA,QAAA;AAAA,EAER,YAAY,OAAA,EAAsC;AAChD,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,2BAAA,EAA6B,GAAG,OAAA,EAAQ;AAC7D,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,aAAA,CAAc,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkDA,MAAa,OAAO,OAAA,EAA2C;AAC7D,IAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAQ,GAAI,OAAA;AAE1B,IAAA,MAAM,MAAM,MAAM,IAAA,CAAK,cAAc,IAAA,EAAM,MAAA,CAAO,OAAO,CAAC,CAAA;AAE1D,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,IAAA,CAAK,UAAA,CAAW,eAAA,EAAiB,IAAA,EAAM,OAAO,CAAA;AAC9C,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,cAAA,CAAA,EAAkB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC/C,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,IACtC;AAEA,IAAA,MAAM,EAAE,IAAI,OAAA,EAAS,SAAA,EAAW,aAAa,OAAA,EAAQ,GAAI,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AAE7E,IAAA,IAAI,CAAC,EAAA,IAAM,SAAA,IAAa,WAAA,IAAe,GAAA,EAAK;AAC1C,MAAA,IAAI,CAAC,QAAQ,QAAA,EAAU;AACrB,QAAA,IAAA,CAAK,UAAA,CAAW,0BAAA,EAA4B,GAAA,EAAK,OAAO,CAAA;AACxD,QAAA,IAAA,CAAK,MAAA,CAAO,CAAA,0BAAA,CAAA,EAA8B,EAAE,IAAA,EAAM,SAAS,CAAA;AAC3D,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,MACtC;AAEA,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,MAAA,CAAO;AAAA,QAC9B,MAAM,GAAA,CAAI,IAAA;AAAA,QACV,GAAG,OAAA,CAAQ;AAAA,OACZ,CAAA;AAED,MAAA,MAAM,YAAY,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,MAAM,GAAA,EAAI;AAEnD,MAAA,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,SAAA,EAAW,OAAO,CAAA;AAClD,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,YAAA,CAAA,EAAgB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC7C,MAAA,OAAO,SAAA;AAAA,IACT;AAEA,IAAA,IAAI,CAAC,EAAA,IAAM,SAAA,IAAa,CAAC,eAAe,GAAA,EAAK;AAC3C,MAAA,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,IAAA,EAAM,GAAG,CAAA;AACzC,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,YAAA,CAAA,EAAgB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC7C,MAAA,OAAO,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,IAAA,EAAK;AAAA,IACrC;AAEA,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,GAAA,EAAK,OAAA,EAAS,OAAO,CAAA;AACrD,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,YAAA,CAAA,EAAgB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC7C,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,IACtC;AAEA,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,GAAA,EAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCA,MAAa,MAAA,CACX,OAAA,EACA,SAAA,GAA2B,EAAC,EACmB;AAC/C,IAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAM,IAAA,EAAM,KAAA,EAAO,WAAU,GAAI,OAAA;AAE3D,IAAA,MAAM,EAAE,KAAK,MAAA,EAAQ,OAAA,KAAY,IAAA,CAAK,aAAA,CAAc,YAAY,SAAS,CAAA;AACzE,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,IAAA,CAAK,cAAc,YAAA,EAAa;AAEjD,IAAA,IAAA,CAAK,MAAA,CAAO,CAAA;AAAA,QAAA,CAAA,EAA2B,OAAO,CAAA;AAE9C,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,KAAK,IAAI,CAAA;AACnD,IAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AAErB,IAAA,MAAM,YAAA,GAA8B;AAAA,MAClC,IAAA,EAAM,IAAI,WAAA,EAAY;AAAA,MACtB,EAAA,EAAI,YAAY,IAAA,GAAO,WAAA,CAAY,KAAK,QAAA,EAAU,IAAI,CAAA,CAAE,WAAA,EAAY,GAAI,aAAA;AAAA,MACxE,GAAA;AAAA,MACA,MAAA,EAAQ,SAAA;AAAA,MACR,WAAA,EAAa,OAAA;AAAA,MACb,IAAA;AAAA,MACA,SAAS,MAAM,iBAAA,CAAkB,IAAA,CAAK,QAAA,CAAS,kBAAkB,CAAA;AAAA,MACjE,MAAA,EAAQ,CAAC,CAAC;AAAA,KACZ;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,cAAA,CAAe,cAAc,CAAC,CAAC,OAAO,SAAS,CAAA;AACvE,IAAA,IAAA,CAAK,OAAO,CAAA,UAAA,CAAA,EAAc;AAAA,MACxB,IAAA;AAAA,MACA,SAAS,YAAA,CAAa,OAAA;AAAA,MACtB,MAAM,YAAA,CAAa;AAAA,KACpB,CAAA;AAED,IAAA,OAAO,EAAE,GAAA,EAAK,YAAA,EAAc,IAAA,EAAK;AAAA,EACnC;AAAA,EAEA,MAAc,aAAA,CAAc,IAAA,EAAc,OAAA,EAAgD;AACxF,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,OAAO,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA;AAChD,IAAA,OAAO,SAAA,CAAU,OAAO,CAAA,IAAK,IAAA;AAAA,EAC/B;AAAA,EAEA,MAAc,cAAA,CACZ,GAAA,EACA,KAAA,EACA,SAAA,EACiB;AACjB,IAAA,OAAA,CAAQ,IAAA,CAAK,WAAW,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,WAAA,CAAY,KAAK,IAAI,CAAA;AAAA,MAC9D,IAAA,CAAK,WAAA,CAAY,EAAE,GAAG,SAAA,EAAW,OAAA,EAAS,GAAA,CAAI,OAAA,EAAS,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,CAAA;AAAA,MACvE,GAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA,EAEQ,YAAY,YAAA,EAMlB;AACA,IAAA,MAAM,oBAAA,GAAuB,YAAA;AAE7B,IAAA,MAAM,UAAA,GAA2E;AAAA,MAC/E,IAAA,EAAM,QAAA;AAAA,MACN,EAAA,EAAI,QAAA;AAAA,MACJ,GAAA,EAAK,QAAA;AAAA,MACL,MAAA,EAAQ,QAAA;AAAA,MACR,MAAA,EAAQ,SAAA;AAAA,MACR,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS,cAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf;AAEA,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAElD;AACD,MAAA,IAAI,CAAC,MAAA,CAAO,oBAAA,CAAqB,KAAK,CAAC,EAAE,IAAI,CAAA;AAC3C,QAAA,OAAO,EAAE,IAAI,KAAA,EAAO,OAAA,EAAS,GAAG,KAAK,CAAA,aAAA,CAAA,EAAiB,SAAS,KAAA,EAAM;AAAA,IACzE;AAEA,IAAA,IAAI,CAAC,MAAA,CAAO,oBAAA,CAAqB,IAAI,CAAA,EAAG;AACtC,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,yBAAA,EAA2B,SAAS,MAAA,EAAO;AAAA,IAC1E,CAAA,MAAA,IAAW,IAAI,IAAA,CAAK,oBAAA,CAAqB,IAAI,CAAA,mBAAI,IAAI,MAAK,EAAG;AAC3D,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,qBAAA,EAAsB;AAAA,IACrD;AAEA,IAAA,IAAI,CAAC,MAAA,CAAO,oBAAA,CAAqB,EAAE,CAAA,EAAG;AACpC,MAAA,IAAI,oBAAA,CAAqB,OAAO,aAAA,EAAe;AAC7C,QAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,2BAAA,EAA6B,SAAS,IAAA,EAAK;AAAA,MAC1E;AAAA,IACF,CAAA,MAAA,IAAW,IAAI,IAAA,CAAK,oBAAA,CAAqB,EAAE,CAAA,mBAAI,IAAI,MAAK,EAAG;AACzD,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,OAAA,EAAS,gBAAA;AAAA,QACT,OAAA,EAAS,IAAA;AAAA,QACT,SAAA,EAAW,IAAA;AAAA,QACX,WAAA,EAAa,CAAC,CAAC,oBAAA,CAAqB;AAAA,OACtC;AAAA,IACF;AAEA,IAAA,IAAI,qBAAqB,WAAA,GAAc,CAAA;AACrC,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,OAAA,EAAS,2BAAA;AAAA,QACT,OAAA,EAAS;AAAA,OACX;AAEF,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,EAAA,EAAG;AAAA,EACjC;AAAA,EAEQ,YAAY,SAAA,EAA0B;AAC5C,IAAA,OAAO,UAAA;AAAA,MACL,WAAW,CAAA,6BAAA,CAAA,EAAiC;AAAA,QAC1C,MAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,MAAM,GAAG,CAAA;AAAA,QAC1C,QAAA,EAAU,KAAK,OAAA,CAAQ,IAAA,CAAK,SAAS,IAAA,EAAM,IAAA,CAAK,SAAS,WAAW,CAAA;AAAA,QACpE,GAAA,EAAK,KAAK,QAAA,CAAS;AAAA,OACpB,CAAA;AAAA,MACD;AAAA,KACF;AAAA,EACF;AAAA,EAEQ,UAAA,CACN,SACG,IAAA,EAC8B;AACjC,IAAA,OAAO,IAAA,CAAK,OAAA,CAA6B,IAAA,EAAM,GAAG,IAAI,CAAA;AAAA,EACxD;AACF,CAAA;;;ACjSO,IAAM,EAAA,GAAN,MAAM,GAAA,SAAW,UAAA,CAAW;AAAA,EACzB,OAAA;AAAA,EAER,YAAY,OAAA,EAAkC;AAC5C,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,sBAAA;AAAA,MACH,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEO,WAAW,OAAA,EAA+B;AAC/C,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,sBAAA;AAAA,MACH,GAAG;AAAA,KACL;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEO,UAAA,GAAyC;AAC9C,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,KAAA,CAAM,MAAA,GAAkC,EAAC,EAAO;AACrD,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAG,EAAE,GAAG,KAAK,UAAA,EAAW,EAAG,GAAG,MAAA,EAAQ,CAAA;AAEzD,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,MAAA,CAAO,UAAA,CAAW,KAAK,SAAS,CAAA;AACpD,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,MAAA,CAAO,SAAA,CAAU,KAAK,QAAQ,CAAA;AACjD,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,MAAA,CAAO,YAAA,CAAa,KAAK,SAAS,CAAA;AAEtD,IAAA,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,QAAA,EAAU,CAAA;AAC/B,IAAA,MAAA,CAAO,SAAA,CAAU,IAAA,CAAK,SAAA,EAAW,CAAA;AAEjC,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEO,SAAS,KAAA,EAAgE;AAC9E,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEO,OAAA,CACL,MACA,OAAA,EACA;AACA,IAAA,IAAA,CAAK,SAAS,EAAE,CAAC,IAAI,GAAG,SAAS,CAAA;AACjC,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;ACvDA,IAAI,QAAA,GAAsB,IAAA;AAQnB,IAAM,SAAS,CACpB,OAAA,GAAyC,EAAC,EAC1C,YAAqB,KAAA,KACd;AACP,EAAA,IAAI,CAAC,SAAA,EAAW,OAAO,IAAI,GAAG,OAAO,CAAA;AAErC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,QAAA,GAAW,IAAI,GAAG,OAAO,CAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,QAAA;AACT;AAKO,IAAM,EAAA,GAAK","file":"index.cjs","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber: typeof data === 'string' || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import { randomBytes, pbkdf2Sync, createCipheriv, createDecipheriv, createHash } from 'node:crypto';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: Required<TCryptoOptions>;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n /**\n * Generate random bytes and encode them\n */\n generateRandom(length: number = 32): string {\n const buffer = randomBytes(length);\n return this.encodeBuffer(buffer);\n }\n\n /**\n * Generate a random key\n * @param length Length of the key in bytes\n * @default cryptoOptions.keyLength\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random salt\n * @param length Length of the salt in bytes\n * @default cryptoOptions.saltLength\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random IV\n * @param length Length of the IV in bytes\n * @default cryptoOptions.ivLength\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encodeBuffer(buffer: Buffer): string {\n switch (this.options.encoding) {\n case 'hex':\n return buffer.toString('hex');\n case 'base64url':\n return buffer.toString('base64url');\n case 'base64':\n default:\n return buffer.toString('base64');\n }\n }\n\n private decodeToBuffer(encoded: string): Buffer {\n switch (this.options.encoding) {\n case 'hex':\n return Buffer.from(encoded, 'hex');\n case 'base64url':\n return Buffer.from(encoded, 'base64url');\n case 'base64':\n default:\n return Buffer.from(encoded, 'base64');\n }\n }\n\n private deriveKey(password: string, salt: Buffer, keyLength?: number): Buffer {\n if (this.options.kdf === 'none') {\n return Buffer.from(password, 'hex');\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n return pbkdf2Sync(\n password,\n salt,\n this.options.iterations,\n actualKeyLength,\n this.options.hashAlgorithm\n );\n }\n\n /**\n * Encrypt data using AES-CBC\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption\n * @param options Optional lengths for key, salt, and IV\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt = this.options.kdf !== 'none' ? randomBytes(saltLength) : Buffer.alloc(0);\n const iv = randomBytes(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const cipher = createCipheriv(this.options.algorithm, key, iv);\n const encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);\n\n // Pack: keyLength(2) + saltLength(2) + ivLength(2) + salt + iv + encrypted\n const keyLengthBuf = Buffer.alloc(2);\n keyLengthBuf.writeUInt16BE(keyLength);\n\n const saltLengthBuf = Buffer.alloc(2);\n saltLengthBuf.writeUInt16BE(salt.length);\n\n const ivLengthBuf = Buffer.alloc(2);\n ivLengthBuf.writeUInt16BE(ivLength);\n\n const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);\n\n return this.encodeBuffer(combined);\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n * @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)\n */\n decrypt(encryptedData: string, secret: string): string {\n try {\n const combined = this.decodeToBuffer(encryptedData);\n let offset = 0;\n\n // Read lengths (2 bytes each)\n const keyLength = combined.readUInt16BE(offset);\n offset += 2;\n const saltLength = combined.readUInt16BE(offset);\n offset += 2;\n const ivLength = combined.readUInt16BE(offset);\n offset += 2;\n\n // Read salt, iv, and encrypted data\n const salt = combined.subarray(offset, offset + saltLength);\n offset += saltLength;\n\n const iv = combined.subarray(offset, offset + ivLength);\n offset += ivLength;\n\n const encrypted = combined.subarray(offset);\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decipher = createDecipheriv(this.options.algorithm, key, iv);\n const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n\n return decrypted.toString('utf8');\n } catch {\n // Return empty string on decryption failure (wrong password, corrupted data, etc.)\n // This matches the behavior of crypto-js\n return '';\n }\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n let saltBuffer: Buffer;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltBuffer = this.decodeToBuffer(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltBuffer = randomBytes(this.options.saltLength);\n saltStr = this.encodeBuffer(saltBuffer);\n }\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const saltBuffer = this.decodeToBuffer(saltStr);\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n // Use timing-safe comparison\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { access, mkdir, readFile, writeFile, unlink } from 'fs/promises';
|
|
2
2
|
import { join, dirname } from 'path';
|
|
3
|
-
import
|
|
3
|
+
import { randomBytes, pbkdf2Sync, createCipheriv, createDecipheriv, createHash } from 'crypto';
|
|
4
4
|
import EventEmitter from 'events';
|
|
5
5
|
|
|
6
6
|
// src/constants/default.constant.ts
|
|
@@ -178,7 +178,7 @@ var isType = (data) => {
|
|
|
178
178
|
return {
|
|
179
179
|
number: typeof data === "number" && !Number.isNaN(Number(data)),
|
|
180
180
|
string: typeof data === "string",
|
|
181
|
-
stringNumber: typeof data === "string"
|
|
181
|
+
stringNumber: typeof data === "string" || typeof data === "number",
|
|
182
182
|
boolean: typeof data === "boolean",
|
|
183
183
|
null: data === null,
|
|
184
184
|
undefined: data === void 0
|
|
@@ -189,97 +189,77 @@ var CryptoService = class {
|
|
|
189
189
|
constructor(options = {}) {
|
|
190
190
|
this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };
|
|
191
191
|
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
192
|
+
/**
|
|
193
|
+
* Generate random bytes and encode them
|
|
194
|
+
*/
|
|
195
195
|
generateRandom(length = 32) {
|
|
196
|
-
const
|
|
197
|
-
return this.
|
|
196
|
+
const buffer = randomBytes(length);
|
|
197
|
+
return this.encodeBuffer(buffer);
|
|
198
198
|
}
|
|
199
|
-
|
|
199
|
+
/**
|
|
200
200
|
* Generate a random key
|
|
201
|
-
* @param length Length of the key
|
|
201
|
+
* @param length Length of the key in bytes
|
|
202
202
|
* @default cryptoOptions.keyLength
|
|
203
|
-
* @returns { key: string, length: number }
|
|
204
203
|
*/
|
|
205
204
|
generateKey(length = this.options.keyLength) {
|
|
206
205
|
return { key: this.generateRandom(length), length };
|
|
207
206
|
}
|
|
208
|
-
|
|
207
|
+
/**
|
|
209
208
|
* Generate a random salt
|
|
210
|
-
* @param length Length of the salt
|
|
209
|
+
* @param length Length of the salt in bytes
|
|
211
210
|
* @default cryptoOptions.saltLength
|
|
212
|
-
* @returns { salt: string, length: number }
|
|
213
211
|
*/
|
|
214
212
|
generateSalt(length = this.options.saltLength) {
|
|
215
213
|
return { salt: this.generateRandom(length), length };
|
|
216
214
|
}
|
|
217
|
-
|
|
215
|
+
/**
|
|
218
216
|
* Generate a random IV
|
|
219
|
-
* @param length Length of the IV
|
|
217
|
+
* @param length Length of the IV in bytes
|
|
220
218
|
* @default cryptoOptions.ivLength
|
|
221
|
-
* @returns { iv: string, length: number }
|
|
222
219
|
*/
|
|
223
220
|
generateIV(length = this.options.ivLength) {
|
|
224
221
|
return { iv: this.generateRandom(length), length };
|
|
225
222
|
}
|
|
226
|
-
|
|
223
|
+
encodeBuffer(buffer) {
|
|
227
224
|
switch (this.options.encoding) {
|
|
228
225
|
case "hex":
|
|
229
|
-
return
|
|
226
|
+
return buffer.toString("hex");
|
|
230
227
|
case "base64url":
|
|
231
|
-
return
|
|
228
|
+
return buffer.toString("base64url");
|
|
232
229
|
case "base64":
|
|
233
230
|
default:
|
|
234
|
-
return
|
|
231
|
+
return buffer.toString("base64");
|
|
235
232
|
}
|
|
236
233
|
}
|
|
237
|
-
|
|
234
|
+
decodeToBuffer(encoded) {
|
|
238
235
|
switch (this.options.encoding) {
|
|
239
236
|
case "hex":
|
|
240
|
-
return
|
|
237
|
+
return Buffer.from(encoded, "hex");
|
|
241
238
|
case "base64url":
|
|
242
|
-
|
|
243
|
-
const padding = "=".repeat((4 - base64.length % 4) % 4);
|
|
244
|
-
return CryptoJS.enc.Base64.parse(base64 + padding);
|
|
239
|
+
return Buffer.from(encoded, "base64url");
|
|
245
240
|
case "base64":
|
|
246
241
|
default:
|
|
247
|
-
return
|
|
242
|
+
return Buffer.from(encoded, "base64");
|
|
248
243
|
}
|
|
249
244
|
}
|
|
250
245
|
deriveKey(password, salt, keyLength) {
|
|
251
246
|
if (this.options.kdf === "none") {
|
|
252
|
-
return
|
|
247
|
+
return Buffer.from(password, "hex");
|
|
253
248
|
}
|
|
254
249
|
const actualKeyLength = keyLength ?? this.options.keyLength;
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
getHasher() {
|
|
263
|
-
switch (this.options.hashAlgorithm) {
|
|
264
|
-
case "sha512":
|
|
265
|
-
return CryptoJS.algo.SHA512;
|
|
266
|
-
case "sha384":
|
|
267
|
-
return CryptoJS.algo.SHA384;
|
|
268
|
-
case "sha256":
|
|
269
|
-
default:
|
|
270
|
-
return CryptoJS.algo.SHA256;
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
getAESMode() {
|
|
274
|
-
return CryptoJS.mode.CBC;
|
|
275
|
-
}
|
|
276
|
-
getPadding() {
|
|
277
|
-
return CryptoJS.pad.Pkcs7;
|
|
250
|
+
return pbkdf2Sync(
|
|
251
|
+
password,
|
|
252
|
+
salt,
|
|
253
|
+
this.options.iterations,
|
|
254
|
+
actualKeyLength,
|
|
255
|
+
this.options.hashAlgorithm
|
|
256
|
+
);
|
|
278
257
|
}
|
|
279
258
|
/**
|
|
280
|
-
* Encrypt data
|
|
259
|
+
* Encrypt data using AES-CBC
|
|
281
260
|
* @param plainText Text to encrypt
|
|
282
|
-
* @param secret Secret key for encryption
|
|
261
|
+
* @param secret Secret key for encryption
|
|
262
|
+
* @param options Optional lengths for key, salt, and IV
|
|
283
263
|
*/
|
|
284
264
|
encrypt(plainText, secret, {
|
|
285
265
|
keyLength,
|
|
@@ -289,61 +269,48 @@ var CryptoService = class {
|
|
|
289
269
|
keyLength = keyLength ?? this.options.keyLength;
|
|
290
270
|
saltLength = saltLength ?? this.options.saltLength;
|
|
291
271
|
ivLength = ivLength ?? this.options.ivLength;
|
|
292
|
-
const salt = this.options.kdf !== "none" ?
|
|
293
|
-
const iv =
|
|
272
|
+
const salt = this.options.kdf !== "none" ? randomBytes(saltLength) : Buffer.alloc(0);
|
|
273
|
+
const iv = randomBytes(ivLength);
|
|
294
274
|
const key = this.deriveKey(secret, salt, keyLength);
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
const
|
|
304
|
-
|
|
305
|
-
const ivHex = iv.toString(CryptoJS.enc.Hex);
|
|
306
|
-
const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);
|
|
307
|
-
const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;
|
|
308
|
-
return this.encode(CryptoJS.enc.Hex.parse(combined));
|
|
275
|
+
const cipher = createCipheriv(this.options.algorithm, key, iv);
|
|
276
|
+
const encrypted = Buffer.concat([cipher.update(plainText, "utf8"), cipher.final()]);
|
|
277
|
+
const keyLengthBuf = Buffer.alloc(2);
|
|
278
|
+
keyLengthBuf.writeUInt16BE(keyLength);
|
|
279
|
+
const saltLengthBuf = Buffer.alloc(2);
|
|
280
|
+
saltLengthBuf.writeUInt16BE(salt.length);
|
|
281
|
+
const ivLengthBuf = Buffer.alloc(2);
|
|
282
|
+
ivLengthBuf.writeUInt16BE(ivLength);
|
|
283
|
+
const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);
|
|
284
|
+
return this.encodeBuffer(combined);
|
|
309
285
|
}
|
|
310
286
|
/**
|
|
311
287
|
* Decrypt data
|
|
312
288
|
* @param encryptedData Encrypted data to decrypt
|
|
313
289
|
* @param secret Secret key for decryption
|
|
290
|
+
* @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)
|
|
314
291
|
*/
|
|
315
292
|
decrypt(encryptedData, secret) {
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
const encrypted = CryptoJS.lib.CipherParams.create({
|
|
338
|
-
ciphertext: CryptoJS.enc.Hex.parse(encryptedHex)
|
|
339
|
-
});
|
|
340
|
-
const key = this.deriveKey(secret, salt, keyLength);
|
|
341
|
-
const decrypted = CryptoJS.AES.decrypt(encrypted, key, {
|
|
342
|
-
iv,
|
|
343
|
-
mode: this.getAESMode(),
|
|
344
|
-
padding: this.getPadding()
|
|
345
|
-
});
|
|
346
|
-
return decrypted.toString(CryptoJS.enc.Utf8);
|
|
293
|
+
try {
|
|
294
|
+
const combined = this.decodeToBuffer(encryptedData);
|
|
295
|
+
let offset = 0;
|
|
296
|
+
const keyLength = combined.readUInt16BE(offset);
|
|
297
|
+
offset += 2;
|
|
298
|
+
const saltLength = combined.readUInt16BE(offset);
|
|
299
|
+
offset += 2;
|
|
300
|
+
const ivLength = combined.readUInt16BE(offset);
|
|
301
|
+
offset += 2;
|
|
302
|
+
const salt = combined.subarray(offset, offset + saltLength);
|
|
303
|
+
offset += saltLength;
|
|
304
|
+
const iv = combined.subarray(offset, offset + ivLength);
|
|
305
|
+
offset += ivLength;
|
|
306
|
+
const encrypted = combined.subarray(offset);
|
|
307
|
+
const key = this.deriveKey(secret, salt, keyLength);
|
|
308
|
+
const decipher = createDecipheriv(this.options.algorithm, key, iv);
|
|
309
|
+
const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
|
|
310
|
+
return decrypted.toString("utf8");
|
|
311
|
+
} catch {
|
|
312
|
+
return "";
|
|
313
|
+
}
|
|
347
314
|
}
|
|
348
315
|
/**
|
|
349
316
|
* Hash data (one-way)
|
|
@@ -352,19 +319,17 @@ var CryptoService = class {
|
|
|
352
319
|
* @param salt Optional encoded salt string for deterministic hashing
|
|
353
320
|
*/
|
|
354
321
|
hash(data, secret, salt) {
|
|
355
|
-
|
|
356
|
-
const hasher = this.getHasher();
|
|
357
|
-
let saltWordArray;
|
|
322
|
+
let saltBuffer;
|
|
358
323
|
let saltStr;
|
|
359
324
|
if (salt) {
|
|
360
|
-
|
|
325
|
+
saltBuffer = this.decodeToBuffer(salt);
|
|
361
326
|
saltStr = salt;
|
|
362
327
|
} else {
|
|
363
|
-
|
|
364
|
-
saltStr = this.
|
|
328
|
+
saltBuffer = randomBytes(this.options.saltLength);
|
|
329
|
+
saltStr = this.encodeBuffer(saltBuffer);
|
|
365
330
|
}
|
|
366
|
-
const hash =
|
|
367
|
-
const hashStr = this.
|
|
331
|
+
const hash = createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
|
|
332
|
+
const hashStr = this.encodeBuffer(hash);
|
|
368
333
|
return `${saltStr}:${hashStr}`;
|
|
369
334
|
}
|
|
370
335
|
/**
|
|
@@ -378,11 +343,9 @@ var CryptoService = class {
|
|
|
378
343
|
if (!saltStr || !expectedHashStr) {
|
|
379
344
|
return false;
|
|
380
345
|
}
|
|
381
|
-
const
|
|
382
|
-
const
|
|
383
|
-
const
|
|
384
|
-
const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();
|
|
385
|
-
const hashStr = this.encode(hash);
|
|
346
|
+
const saltBuffer = this.decodeToBuffer(saltStr);
|
|
347
|
+
const hash = createHash(this.options.hashAlgorithm).update(data).update(secret).update(saltBuffer).digest();
|
|
348
|
+
const hashStr = this.encodeBuffer(hash);
|
|
386
349
|
return hashStr === expectedHashStr;
|
|
387
350
|
}
|
|
388
351
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent"],"mappings":"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","file":"index.js","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber:\n (typeof data === 'string' && !Number.isNaN(Number(data))) || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import CryptoJS from 'crypto-js';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: TCryptoOptions;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n private generateRandomWordArray(length: number): CryptoJS.lib.WordArray {\n return CryptoJS.lib.WordArray.random(length);\n }\n\n generateRandom(length: number = 32): string {\n const wordArray = this.generateRandomWordArray(length);\n return this.encode(wordArray);\n }\n\n /*\n * Generate a random key\n * @param length Length of the key\n * @default cryptoOptions.keyLength\n * @returns { key: string, length: number }\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random salt\n * @param length Length of the salt\n * @default cryptoOptions.saltLength\n * @returns { salt: string, length: number }\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /*\n * Generate a random IV\n * @param length Length of the IV\n * @default cryptoOptions.ivLength\n * @returns { iv: string, length: number }\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encode(wordArray: CryptoJS.lib.WordArray): string {\n switch (this.options.encoding) {\n case 'hex':\n return wordArray.toString(CryptoJS.enc.Hex);\n case 'base64url':\n return wordArray\n .toString(CryptoJS.enc.Base64)\n .replace(/\\+/g, '-')\n .replace(/\\//g, '_')\n .replace(/=/g, '');\n case 'base64':\n default:\n return wordArray.toString(CryptoJS.enc.Base64);\n }\n }\n\n private decode(encoded: string): CryptoJS.lib.WordArray {\n switch (this.options.encoding) {\n case 'hex':\n return CryptoJS.enc.Hex.parse(encoded);\n case 'base64url':\n // Convert base64url to base64\n const base64 = encoded.replace(/-/g, '+').replace(/_/g, '/');\n const padding = '='.repeat((4 - (base64.length % 4)) % 4);\n return CryptoJS.enc.Base64.parse(base64 + padding);\n case 'base64':\n default:\n return CryptoJS.enc.Base64.parse(encoded);\n }\n }\n\n private deriveKey(\n password: string,\n salt: CryptoJS.lib.WordArray,\n keyLength?: number\n ): CryptoJS.lib.WordArray {\n if (this.options.kdf === 'none') {\n return CryptoJS.enc.Hex.parse(password);\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n const keySize = actualKeyLength / 4;\n return CryptoJS.PBKDF2(password, salt, {\n keySize,\n iterations: this.options.iterations,\n hasher: this.getHasher(),\n });\n }\n\n private getHasher(): typeof CryptoJS.algo.SHA256 {\n switch (this.options.hashAlgorithm) {\n case 'sha512':\n return CryptoJS.algo.SHA512;\n case 'sha384':\n return CryptoJS.algo.SHA384;\n case 'sha256':\n default:\n return CryptoJS.algo.SHA256;\n }\n }\n\n private getAESMode(): typeof CryptoJS.mode.CBC {\n return CryptoJS.mode.CBC;\n }\n\n private getPadding(): typeof CryptoJS.pad.Pkcs7 {\n return CryptoJS.pad.Pkcs7;\n }\n\n /**\n * Encrypt data\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption Key length, salt, and IV will be randomly generated within configured range\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt =\n this.options.kdf !== 'none'\n ? this.generateRandomWordArray(saltLength)\n : CryptoJS.lib.WordArray.create();\n const iv = this.generateRandomWordArray(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const encrypted = CryptoJS.AES.encrypt(plainText, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n const actualSaltLength = salt.sigBytes;\n const keyLengthHex = keyLength.toString(16).padStart(4, '0');\n const saltLengthHex = actualSaltLength.toString(16).padStart(4, '0');\n const ivLengthHex = ivLength.toString(16).padStart(4, '0');\n const saltHex = salt.toString(CryptoJS.enc.Hex);\n const ivHex = iv.toString(CryptoJS.enc.Hex);\n const encryptedHex = encrypted.ciphertext.toString(CryptoJS.enc.Hex);\n\n const combined = keyLengthHex + saltLengthHex + ivLengthHex + saltHex + ivHex + encryptedHex;\n return this.encode(CryptoJS.enc.Hex.parse(combined));\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n */\n decrypt(encryptedData: string, secret: string): string {\n const combined = this.decode(encryptedData);\n const combinedHex = combined.toString(CryptoJS.enc.Hex);\n\n let offset = 0;\n\n // Read key, salt and IV lengths (4 hex chars = 2 bytes each)\n const keyLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const saltLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n const ivLengthHex = combinedHex.substring(offset, offset + 4);\n offset += 4;\n\n const keyLength = parseInt(keyLengthHex, 16);\n const saltLength = parseInt(saltLengthHex, 16);\n const ivLength = parseInt(ivLengthHex, 16);\n\n // Read salt and IV based on their lengths stored in the encrypted data\n const saltHexLength = saltLength * 2; // hex is 2 chars per byte\n const ivHexLength = ivLength * 2;\n\n const saltHex = saltHexLength > 0 ? combinedHex.substring(offset, offset + saltHexLength) : '';\n offset += saltHexLength;\n\n const ivHex = combinedHex.substring(offset, offset + ivHexLength);\n offset += ivHexLength;\n\n const encryptedHex = combinedHex.substring(offset);\n\n const salt = saltHex ? CryptoJS.enc.Hex.parse(saltHex) : CryptoJS.lib.WordArray.create();\n const iv = CryptoJS.enc.Hex.parse(ivHex);\n const encrypted = CryptoJS.lib.CipherParams.create({\n ciphertext: CryptoJS.enc.Hex.parse(encryptedHex),\n });\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decrypted = CryptoJS.AES.decrypt(encrypted, key, {\n iv,\n mode: this.getAESMode(),\n padding: this.getPadding(),\n });\n\n return decrypted.toString(CryptoJS.enc.Utf8);\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n let saltWordArray: CryptoJS.lib.WordArray;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltWordArray = this.decode(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltWordArray = this.generateRandomWordArray(this.options.saltLength);\n saltStr = this.encode(saltWordArray);\n }\n\n const hash = hasher\n .create()\n .update(data)\n .update(secretWordArray)\n .update(saltWordArray)\n .finalize();\n\n const hashStr = this.encode(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const salt = this.decode(saltStr);\n const secretWordArray = CryptoJS.enc.Utf8.parse(secret);\n const hasher = this.getHasher();\n\n const hash = hasher.create().update(data).update(secretWordArray).update(salt).finalize();\n\n const hashStr = this.encode(hash);\n\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/constants/default.constant.ts","../src/types/events.types.ts","../src/utils/promise.util.ts","../src/utils/file.util.ts","../src/utils/string.util.ts","../src/utils/crypto.util.ts","../src/core/base.core.ts","../src/core/events.core.ts","../src/core/store.core.ts","../src/core/key-manager.core.ts","../src/core/module.core.ts","../src/index.ts"],"names":["EEvent"],"mappings":";;;;;;AAKO,IAAM,sBAAA,GAAmD;AAAA,EAC9D,SAAA,EAAW,aAAA;AAAA,EACX,GAAA,EAAK,QAAA;AAAA,EACL,aAAA,EAAe,QAAA;AAAA,EACf,SAAA,EAAW,EAAA;AAAA,EACX,QAAA,EAAU,EAAA;AAAA,EACV,UAAA,EAAY,EAAA;AAAA,EACZ,SAAA,EAAW,EAAA;AAAA,EACX,UAAA,EAAY,GAAA;AAAA,EACZ,QAAA,EAAU;AACZ,CAAA;AAEO,IAAM,oBAAA,GAA+C;AAAA,EAC1D,KAAA,EAAO;AACT,CAAA;AAEO,IAAM,sBAAsB,CAAA,GAAI,IAAA,KAAgB,OAAA,CAAQ,GAAA,CAAI,GAAG,IAAI,CAAA;AAEnE,IAAM,sBAAA,GAAmD;AAAA,EAC9D,GAAG,oBAAA;AAAA;AAAA,EAGH,QAAA,EAAU;AACZ,CAAA;AAEO,IAAM,qBAAA,GAAiD;AAAA,EAC5D,IAAA,EAAM,CAAC,MAAA,EAAQ,UAAU,CAAA;AAAA,EACzB,IAAA,EAAM,CAAC,GAAA,EAAK,aAAa,CAAA;AAAA,EACzB,WAAA,EAAa,GAAA;AAAA,EACb,OAAA,EAAS,MAAA;AAAA,EACT,SAAA,EAAW,IAAA;AAAA,EAEX,GAAG,sBAAA;AAAA;AAAA,EAGH,MAAA,EAAQ;AACV,CAAA;AAEO,IAAM,2BAAA,GAA4D;AAAA;AAAA,EAEvE,GAAG,qBAAA;AAAA,EAEH,gBAAA,EAAkB,MAAA,iBAAM,IAAI,IAAA,IAAO,OAAA;AACrC,CAAA;AAEO,IAAM,sBAAA,GAAmD;AAAA,EAC9D,GAAG,2BAAA;AAAA;AAAA,EAGH,KAAA,EAAO;AACT,CAAA;;;ACpDO,IAAK,MAAA,qBAAAA,OAAAA,KAAL;AACL,EAAAA,QAAA,mBAAA,CAAA,GAAoB,mBAAA;AACpB,EAAAA,QAAA,kBAAA,CAAA,GAAmB,gBAAA;AAFT,EAAA,OAAAA,OAAAA;AAAA,CAAA,EAAA,MAAA,IAAA,EAAA;;;ACHL,IAAM,iBAAA,GAAoB,CAC/B,WAAA,KACe;AACf,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GACJ,OAAO,WAAA,KAAgB,UAAA,IAAc,EAAE,WAAA,YAAuB,OAAA,CAAA,GACzD,aAAuD,GACxD,WAAA;AACN,IAAA,OAAO,OAAA,CAAQ,QAAQ,KAAK,CAAA;AAAA,EAC9B,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,OAAA,CAAQ,OAAO,KAAK,CAAA;AAAA,EAC7B;AACF,CAAA;ACTO,IAAM,aAAA,GAAN,cAA4B,KAAA,CAAM;AAAA,EACvC,WAAA,CACE,OAAA,EACgB,IAAA,EACA,SAAA,EACA,KAAA,EAChB;AACA,IAAA,KAAA,CAAM,OAAO,CAAA;AAJG,IAAA,IAAA,CAAA,IAAA,GAAA,IAAA;AACA,IAAA,IAAA,CAAA,SAAA,GAAA,SAAA;AACA,IAAA,IAAA,CAAA,KAAA,GAAA,KAAA;AAGhB,IAAA,IAAA,CAAK,IAAA,GAAO,eAAA;AAAA,EACd;AACF,CAAA;AAEO,IAAM,WAAN,MAAe;AAAA,EACpB,MAAM,UAAU,IAAA,EAA+B;AAC7C,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,IAAI,CAAA;AACjB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,IAAI;AACF,QAAA,MAAM,KAAA,CAAM,IAAA,EAAM,EAAE,SAAA,EAAW,MAAM,CAAA;AACrC,QAAA,OAAO,IAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,MAAM,IAAI,aAAA,CAAc,CAAA,yBAAA,EAA4B,IAAI,CAAA,CAAA,EAAI,IAAA,EAAM,SAAS,KAAK,CAAA;AAAA,MAClF;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,CAAK,IAAA,EAAc,QAAA,EAAoC;AAC3D,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAM,EAAE,QAAA,EAAU,QAAQ,CAAA;AACtD,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAI,QAAA,KAAa,QAAW,OAAO,QAAA;AACnC,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,qBAAA,EAAwB,IAAI,CAAA,CAAA,EAAI,IAAA,EAAM,QAAQ,KAAK,CAAA;AAAA,IAC7E;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CAAM,IAAA,EAAc,IAAA,EAAc,OAAkB,GAAA,EAAoB;AAC5E,IAAA,MAAM,GAAA,GAAM,QAAQ,IAAI,CAAA;AACxB,IAAA,MAAM,IAAA,CAAK,UAAU,GAAG,CAAA;AAExB,IAAA,IAAI;AACF,MAAA,MAAM,UAAU,IAAA,EAAM,IAAA,EAAM,EAAE,QAAA,EAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,IACxD,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,sBAAA,EAAyB,IAAI,CAAA,CAAA,EAAI,IAAA,EAAM,SAAS,KAAK,CAAA;AAAA,IAC/E;AAAA,EACF;AAAA,EAEA,MAAM,YAAY,IAAA,EAAgC;AAChD,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,IAAI,CAAA;AACjB,MAAA,OAAO,IAAA;AAAA,IACT,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,OAAO,IAAA,EAA6B;AACxC,IAAA,IAAI;AACF,MAAA,MAAM,OAAO,IAAI,CAAA;AAAA,IACnB,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,aAAA,CAAc,CAAA,uBAAA,EAA0B,IAAI,CAAA,CAAA,EAAI,IAAA,EAAM,UAAU,KAAK,CAAA;AAAA,IACjF;AAAA,EACF;AACF,CAAA;;;ACjEA,IAAM,SAAA,GAAY,CAAC,GAAA,EAA0B,IAAA,KAC3C,KAAK,KAAA,CAAM,GAAG,CAAA,CAAE,MAAA,CAAO,CAAC,IAAA,EAAM,GAAA,KAAQ,IAAA,GAAO,GAAG,GAAG,GAAG,CAAA;AAExD,IAAM,OAAA,GAAU,CAAC,GAAA,EAA0B,MAAA,GAAS,OAClD,MAAA,CAAO,OAAA,CAAQ,GAAG,CAAA,CAAE,OAAO,CAAC,GAAA,EAAK,CAAC,GAAA,EAAK,GAAG,CAAA,KAAM;AAC9C,EAAA,MAAM,SAAS,MAAA,GAAS,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA,CAAA,GAAK,GAAA;AAC7C,EAAA,OAAO,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,CAAC,MAAM,OAAA,CAAQ,GAAG,CAAA,GACvD,EAAE,GAAG,GAAA,EAAK,GAAG,OAAA,CAAQ,GAAA,EAAK,MAAM,CAAA,EAAE,GAClC,EAAE,GAAG,GAAA,EAAK,CAAC,MAAM,GAAG,GAAA,EAAI;AAC9B,CAAA,EAAG,EAAE,CAAA;AAEP,IAAM,SAAA,GAAY,CAAC,GAAA,KAAqB;AACtC,EAAA,IAAI,GAAA,KAAQ,IAAA,IAAQ,GAAA,KAAQ,MAAA,EAAW,OAAO,EAAA;AAC9C,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,EAAU,OAAO,IAAA,CAAK,UAAU,GAAG,CAAA;AACtD,EAAA,OAAO,OAAO,GAAG,CAAA;AACnB,CAAA;AAEO,IAAM,UAAA,GAAa,CAAC,MAAA,EAAgB,UAAA,KAA4C;AACrF,EAAA,OAAO,MAAA,CACJ,OAAA,CAAQ,wBAAA,EAA0B,CAAC,OAAO,IAAA,KAAS;AAClD,IAAA,MAAM,WAAA,GAAc,KAAK,IAAA,EAAK;AAC9B,IAAA,MAAM,GAAA,GAAM,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA,GAChC,UAAU,UAAA,EAAY,WAAW,CAAA,GACjC,UAAA,CAAW,WAAW,CAAA;AAE1B,IAAA,OAAO,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA,GACvD,KAAK,SAAA,CAAU,OAAA,CAAQ,GAAA,EAAK,WAAW,CAAC,CAAA,GACxC,KAAA;AAAA,EACN,CAAC,CAAA,CACA,OAAA,CAAQ,kBAAA,EAAoB,CAAC,OAAO,IAAA,KAAS;AAC5C,IAAA,MAAM,WAAA,GAAc,KAAK,IAAA,EAAK;AAG9B,IAAA,IAAI,WAAA,CAAY,UAAA,CAAW,KAAK,CAAA,EAAG;AACjC,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,GAAA,GAAM,WAAA,CAAY,QAAA,CAAS,GAAG,CAAA,GAChC,UAAU,UAAA,EAAY,WAAW,CAAA,GACjC,UAAA,CAAW,WAAW,CAAA;AAC1B,IAAA,OAAO,UAAU,GAAG,CAAA;AAAA,EACtB,CAAC,CAAA;AACL,CAAA;AACO,IAAM,MAAA,GAAS,CAAC,IAAA,KAA0B;AAC/C,EAAA,IAAI;AACF,IAAA,MAAM,IAAA,GAAO,IAAI,IAAA,CAAK,IAAI,CAAA;AAC1B,IAAA,OAAO,CAAC,KAAA,CAAM,IAAA,CAAK,OAAA,EAAS,CAAA;AAAA,EAC9B,SAAS,KAAA,EAAO;AACd,IAAA,OAAO,KAAA;AAAA,EACT;AACF,CAAA;AAEO,IAAM,WAAA,GAAc,CAAC,IAAA,EAAY,QAAA,EAAkB,IAAA,KAAiC;AACzF,EAAA,MAAM,MAAA,GAAS,IAAI,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA;AAEtC,EAAA,QAAQ,IAAA;AAAM,IACZ,KAAK,SAAA;AACH,MAAA,MAAA,CAAO,UAAA,CAAW,MAAA,CAAO,UAAA,EAAW,GAAI,QAAQ,CAAA;AAChD,MAAA;AAAA,IAEF,KAAK,SAAA;AACH,MAAA,MAAA,CAAO,UAAA,CAAW,MAAA,CAAO,UAAA,EAAW,GAAI,QAAQ,CAAA;AAChD,MAAA;AAAA,IAEF,KAAK,OAAA;AACH,MAAA,MAAA,CAAO,QAAA,CAAS,MAAA,CAAO,QAAA,EAAS,GAAI,QAAQ,CAAA;AAC5C,MAAA;AAAA,IAEF,KAAK,MAAA;AACH,MAAA,MAAA,CAAO,OAAA,CAAQ,MAAA,CAAO,OAAA,EAAQ,GAAI,QAAQ,CAAA;AAC1C,MAAA;AAAA,IAEF,SAAS;AACP,MAAA,MAAM,gBAAA,GAA0B,IAAA;AAChC,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2BAAA,EAA8B,gBAAgB,CAAA,CAAE,CAAA;AAAA,IAClE;AAAA;AAGF,EAAA,OAAO,MAAA;AACT,CAAA;AAEO,IAAM,MAAA,GAAS,CAAC,IAAA,KAAmB;AACxC,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,MAAA,CAAO,KAAA,CAAM,MAAA,CAAO,IAAI,CAAC,CAAA;AAAA,IAC9D,MAAA,EAAQ,OAAO,IAAA,KAAS,QAAA;AAAA,IACxB,YAAA,EAAc,OAAO,IAAA,KAAS,QAAA,IAAY,OAAO,IAAA,KAAS,QAAA;AAAA,IAC1D,OAAA,EAAS,OAAO,IAAA,KAAS,SAAA;AAAA,IACzB,MAAM,IAAA,KAAS,IAAA;AAAA,IACf,WAAW,IAAA,KAAS;AAAA,GACtB;AACF,CAAA;ACxFO,IAAM,gBAAN,MAAoB;AAAA,EACjB,OAAA;AAAA,EAER,WAAA,CAAY,OAAA,GAAmC,EAAC,EAAG;AACjD,IAAA,IAAA,CAAK,OAAA,GAAU,EAAE,GAAG,sBAAA,EAAwB,GAAG,OAAA,EAAQ;AAAA,EACzD;AAAA;AAAA;AAAA;AAAA,EAKA,cAAA,CAAe,SAAiB,EAAA,EAAY;AAC1C,IAAA,MAAM,MAAA,GAAS,YAAY,MAAM,CAAA;AACjC,IAAA,OAAO,IAAA,CAAK,aAAa,MAAM,CAAA;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,WAAA,CAAY,MAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW;AACnD,IAAA,OAAO,EAAE,GAAA,EAAK,IAAA,CAAK,cAAA,CAAe,MAAM,GAAG,MAAA,EAAO;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,YAAA,CAAa,MAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY;AACrD,IAAA,OAAO,EAAE,IAAA,EAAM,IAAA,CAAK,cAAA,CAAe,MAAM,GAAG,MAAA,EAAO;AAAA,EACrD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,UAAA,CAAW,MAAA,GAAiB,IAAA,CAAK,OAAA,CAAQ,QAAA,EAAU;AACjD,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,CAAK,cAAA,CAAe,MAAM,GAAG,MAAA,EAAO;AAAA,EACnD;AAAA,EAEQ,aAAa,MAAA,EAAwB;AAC3C,IAAA,QAAQ,IAAA,CAAK,QAAQ,QAAA;AAAU,MAC7B,KAAK,KAAA;AACH,QAAA,OAAO,MAAA,CAAO,SAAS,KAAK,CAAA;AAAA,MAC9B,KAAK,WAAA;AACH,QAAA,OAAO,MAAA,CAAO,SAAS,WAAW,CAAA;AAAA,MACpC,KAAK,QAAA;AAAA,MACL;AACE,QAAA,OAAO,MAAA,CAAO,SAAS,QAAQ,CAAA;AAAA;AACnC,EACF;AAAA,EAEQ,eAAe,OAAA,EAAyB;AAC9C,IAAA,QAAQ,IAAA,CAAK,QAAQ,QAAA;AAAU,MAC7B,KAAK,KAAA;AACH,QAAA,OAAO,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,KAAK,CAAA;AAAA,MACnC,KAAK,WAAA;AACH,QAAA,OAAO,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,WAAW,CAAA;AAAA,MACzC,KAAK,QAAA;AAAA,MACL;AACE,QAAA,OAAO,MAAA,CAAO,IAAA,CAAK,OAAA,EAAS,QAAQ,CAAA;AAAA;AACxC,EACF;AAAA,EAEQ,SAAA,CAAU,QAAA,EAAkB,IAAA,EAAc,SAAA,EAA4B;AAC5E,IAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,KAAQ,MAAA,EAAQ;AAC/B,MAAA,OAAO,MAAA,CAAO,IAAA,CAAK,QAAA,EAAU,KAAK,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,eAAA,GAAkB,SAAA,IAAa,IAAA,CAAK,OAAA,CAAQ,SAAA;AAClD,IAAA,OAAO,UAAA;AAAA,MACL,QAAA;AAAA,MACA,IAAA;AAAA,MACA,KAAK,OAAA,CAAQ,UAAA;AAAA,MACb,eAAA;AAAA,MACA,KAAK,OAAA,CAAQ;AAAA,KACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAA,CACE,WACA,MAAA,EACA;AAAA,IACE,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF,GAAoE,EAAC,EAC7D;AACR,IAAA,SAAA,GAAY,SAAA,IAAa,KAAK,OAAA,CAAQ,SAAA;AACtC,IAAA,UAAA,GAAa,UAAA,IAAc,KAAK,OAAA,CAAQ,UAAA;AACxC,IAAA,QAAA,GAAW,QAAA,IAAY,KAAK,OAAA,CAAQ,QAAA;AAEpC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,OAAA,CAAQ,GAAA,KAAQ,MAAA,GAAS,YAAY,UAAU,CAAA,GAAI,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AACnF,IAAA,MAAM,EAAA,GAAK,YAAY,QAAQ,CAAA;AAC/B,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,MAAM,SAAS,CAAA;AAElD,IAAA,MAAM,SAAS,cAAA,CAAe,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,KAAK,EAAE,CAAA;AAC7D,IAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,CAAC,MAAA,CAAO,MAAA,CAAO,SAAA,EAAW,MAAM,CAAA,EAAG,MAAA,CAAO,KAAA,EAAO,CAAC,CAAA;AAGlF,IAAA,MAAM,YAAA,GAAe,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AACnC,IAAA,YAAA,CAAa,cAAc,SAAS,CAAA;AAEpC,IAAA,MAAM,aAAA,GAAgB,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AACpC,IAAA,aAAA,CAAc,aAAA,CAAc,KAAK,MAAM,CAAA;AAEvC,IAAA,MAAM,WAAA,GAAc,MAAA,CAAO,KAAA,CAAM,CAAC,CAAA;AAClC,IAAA,WAAA,CAAY,cAAc,QAAQ,CAAA;AAElC,IAAA,MAAM,QAAA,GAAW,MAAA,CAAO,MAAA,CAAO,CAAC,YAAA,EAAc,eAAe,WAAA,EAAa,IAAA,EAAM,EAAA,EAAI,SAAS,CAAC,CAAA;AAE9F,IAAA,OAAO,IAAA,CAAK,aAAa,QAAQ,CAAA;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAA,CAAQ,eAAuB,MAAA,EAAwB;AACrD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,IAAA,CAAK,cAAA,CAAe,aAAa,CAAA;AAClD,MAAA,IAAI,MAAA,GAAS,CAAA;AAGb,MAAA,MAAM,SAAA,GAAY,QAAA,CAAS,YAAA,CAAa,MAAM,CAAA;AAC9C,MAAA,MAAA,IAAU,CAAA;AACV,MAAA,MAAM,UAAA,GAAa,QAAA,CAAS,YAAA,CAAa,MAAM,CAAA;AAC/C,MAAA,MAAA,IAAU,CAAA;AACV,MAAA,MAAM,QAAA,GAAW,QAAA,CAAS,YAAA,CAAa,MAAM,CAAA;AAC7C,MAAA,MAAA,IAAU,CAAA;AAGV,MAAA,MAAM,IAAA,GAAO,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ,SAAS,UAAU,CAAA;AAC1D,MAAA,MAAA,IAAU,UAAA;AAEV,MAAA,MAAM,EAAA,GAAK,QAAA,CAAS,QAAA,CAAS,MAAA,EAAQ,SAAS,QAAQ,CAAA;AACtD,MAAA,MAAA,IAAU,QAAA;AAEV,MAAA,MAAM,SAAA,GAAY,QAAA,CAAS,QAAA,CAAS,MAAM,CAAA;AAE1C,MAAA,MAAM,GAAA,GAAM,IAAA,CAAK,SAAA,CAAU,MAAA,EAAQ,MAAM,SAAS,CAAA;AAElD,MAAA,MAAM,WAAW,gBAAA,CAAiB,IAAA,CAAK,OAAA,CAAQ,SAAA,EAAW,KAAK,EAAE,CAAA;AACjE,MAAA,MAAM,SAAA,GAAY,MAAA,CAAO,MAAA,CAAO,CAAC,QAAA,CAAS,MAAA,CAAO,SAAS,CAAA,EAAG,QAAA,CAAS,KAAA,EAAO,CAAC,CAAA;AAE9E,MAAA,OAAO,SAAA,CAAU,SAAS,MAAM,CAAA;AAAA,IAClC,CAAA,CAAA,MAAQ;AAGN,MAAA,OAAO,EAAA;AAAA,IACT;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,IAAA,CAAK,IAAA,EAAc,MAAA,EAAgB,IAAA,EAAuB;AACxD,IAAA,IAAI,UAAA;AACJ,IAAA,IAAI,OAAA;AAEJ,IAAA,IAAI,IAAA,EAAM;AAER,MAAA,UAAA,GAAa,IAAA,CAAK,eAAe,IAAI,CAAA;AACrC,MAAA,OAAA,GAAU,IAAA;AAAA,IACZ,CAAA,MAAO;AAEL,MAAA,UAAA,GAAa,WAAA,CAAY,IAAA,CAAK,OAAA,CAAQ,UAAU,CAAA;AAChD,MAAA,OAAA,GAAU,IAAA,CAAK,aAAa,UAAU,CAAA;AAAA,IACxC;AAEA,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,IAAA,CAAK,OAAA,CAAQ,aAAa,CAAA,CAC/C,MAAA,CAAO,IAAI,CAAA,CACX,OAAO,MAAM,CAAA,CACb,MAAA,CAAO,UAAU,EACjB,MAAA,EAAO;AAEV,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,IAAI,CAAA;AAEtC,IAAA,OAAO,CAAA,EAAG,OAAO,CAAA,CAAA,EAAI,OAAO,CAAA,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,UAAA,CAAW,IAAA,EAAc,UAAA,EAAoB,MAAA,EAAyB;AACpE,IAAA,MAAM,CAAC,OAAA,EAAS,eAAe,CAAA,GAAI,UAAA,CAAW,MAAM,GAAG,CAAA;AACvD,IAAA,IAAI,CAAC,OAAA,IAAW,CAAC,eAAA,EAAiB;AAChC,MAAA,OAAO,KAAA;AAAA,IACT;AAEA,IAAA,MAAM,UAAA,GAAa,IAAA,CAAK,cAAA,CAAe,OAAO,CAAA;AAE9C,IAAA,MAAM,IAAA,GAAO,UAAA,CAAW,IAAA,CAAK,OAAA,CAAQ,aAAa,CAAA,CAC/C,MAAA,CAAO,IAAI,CAAA,CACX,OAAO,MAAM,CAAA,CACb,MAAA,CAAO,UAAU,EACjB,MAAA,EAAO;AAEV,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,YAAA,CAAa,IAAI,CAAA;AAGtC,IAAA,OAAO,OAAA,KAAY,eAAA;AAAA,EACrB;AACF,CAAA;;;AC1NO,IAAM,OAAN,MAAoE;AAAA,EACjE,MAAA;AAAA,EACA,QAAA;AAAA,EACA,KAAA,uBAAgC,GAAA,EAAI;AAAA,EAE5C,YAAY,OAAA,EAAgC;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,oBAAA,EAAsB,GAAG,OAAA,EAAQ;AACtD,IAAA,IAAA,CAAK,MAAA,GAAS,mBAAA;AAAA,EAChB;AAAA,EAEU,SAAA,GAAkC;AAC1C,IAAA,OAAO,IAAA,CAAK,MAAA;AAAA,EACd;AAAA,EAEO,UAAU,MAAA,EAAoC;AACnD,IAAA,IAAA,CAAK,MAAA,GAAS,MAAA;AACd,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEO,UAAU,IAAA,EAAiC;AAChD,IAAA,IAAI,CAAC,IAAA,CAAK,QAAA,CAAS,KAAA,EAAO;AACxB,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,MAAA,CAAO,GAAG,IAAI,CAAA;AAClC,MAAA,IAAI,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,WAAW,MAAA,EAAQ;AAC7D,QAAC,MAAA,CAA4B,MAAM,MAAM;AAAA,QAAC,CAAC,CAAA;AAAA,MAC7C;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAa,SAAA,CACX,MAAA,EAAA,GACG,IAAA,EACH;AACA,IAAA,MAAM,MAAA,CAAO,GAAG,IAAI,CAAA;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEU,SAA+C,KAAA,EAAU;AACjE,IAAA,MAAA,CAAO,OAAA,CAAQ,KAAK,CAAA,CAAE,OAAA,CAAQ,CAAC,CAAC,IAAA,EAAM,OAAO,CAAA,KAAM;AACjD,MAAA,IAAI,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAI,CAAA,EAAG;AACxB,QAAA,IAAA,CAAK,MAAM,GAAA,CAAI,kBAAkB,CAAA,EAAG,IAAA,CAAK,MAAM,IAAI,CAAA;AAAA,MACrD;AAEA,MAAA,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAA,EAAM,OAAO,CAAA;AAAA,IAC9B,CAAC,CAAA;AACD,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEU,OAAA,CACR,SACG,IAAA,EACmB;AACtB,IAAA,IAAI,CAAC,IAAA,CAAK,KAAA,CAAM,GAAA,CAAI,IAAc,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,MAAM,GAAA,CAAI,gBAAgB,CAAA,EAAG,IAAA,CAAK,MAAM,IAAc,CAAA;AAC3D,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,OAAO,IAAA,CAAK,MAAM,GAAA,CAAI,IAAc,EAAG,IAAA,CAAK,IAAA,EAAM,GAAG,IAAI,CAAA;AAAA,EAC3D;AAAA,EAEU,QAAA,GAAkC;AAC1C,IAAA,OAAO,MAAA,CAAO,WAAA,CAAY,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AAAA,EAChD;AACF,CAAA;;;AC/DO,IAAM,MAAA,GAAN,cAAqB,IAAA,CAAK;AAAA,EACvB,MAAA;AAAA,EACA,QAAA;AAAA,EAER,YAAY,OAAA,EAAyB;AACnC,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,QAAA,GAAW;AAAA,MACd,GAAG,sBAAA;AAAA,MACH,GAAG;AAAA,KACL;AAEA,IAAA,IAAI,IAAA,CAAK,SAAS,QAAA,EAAU;AAC1B,MAAA,IAAA,CAAK,MAAA,GAAS,IAAI,YAAA,EAAa;AAAA,IACjC;AAAA,EACF;AAAA,EAEU,IAAA,CAA8B,OAAU,IAAA,EAAkB;AAClE,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,IAAI,CAAA;AAC5B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,EAAA,CAA4B,OAAU,QAAA,EAAsC;AAC1E,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,EAAA,CAAG,KAAA,EAAO,QAAQ,CAAA;AAC9B,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,IAAA,CAA8B,OAAU,QAAA,EAAsC;AAC5E,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,IAAA,CAAK,KAAA,EAAO,QAAQ,CAAA;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,GAAA,CAA6B,OAAU,QAAA,EAAsC;AAC3E,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,EAAQ,OAAO,IAAA;AAEzB,IAAA,IAAA,CAAK,MAAA,CAAO,GAAA,CAAI,KAAA,EAAO,QAAQ,CAAA;AAC/B,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;AC1CO,IAAM,KAAA,GAAN,cAAoB,MAAA,CAAO;AAAA,EACxB,QAAA;AAAA,EACA,QAAA;AAAA,EACE,SAAA;AAAA,EACA,SAAA;AAAA,EACA,QAAA;AAAA,EAEV,YAAY,OAAA,EAAiC;AAC3C,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,qBAAA,EAAuB,GAAG,OAAA,EAAQ;AACvD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,QAAA,EAAS;AAE7B,IAAA,IAAA,CAAK,SAAA,EAAU;AAAA,EACjB;AAAA,EAEU,OAAA,CAAQ,MAAyB,OAAA,EAAyB;AAClE,IAAA,IAAI,OAAO,IAAA,KAAS,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,IAAI,CAAA,EAAG;AACnD,MAAA,OAAO,IAAA,CAAK,KAAK,OAAO,CAAA;AAAA,IAC1B;AAEA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAc,iBAAA,GAAqC;AACjD,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,OAAO,IAAA,CAAK,SAAA;AAEhC,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,IAAA,CAAK,QAAA;AAEtB,IAAA,MAAM,KAAA,GACJ,OAAO,IAAA,KAAS,QAAA,IAAY,MAAM,OAAA,CAAQ,IAAI,IAC1C,IAAA,CAAK,CAAC,IACN,OAAO,IAAA,KAAS,WACb,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA,CAAE,CAAC,KAAK,EAAA,GACvB,EAAA;AAER,IAAA,IAAI,MAAA,GAAS,MAAM,IAAA,CAAK,QAAA,CAAS,SAAA,CAAU,KAAK,OAAA,CAAQ,GAAA,EAAI,EAAG,KAAK,CAAC,CAAA;AAErE,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEA,MAAgB,eAAe,QAAA,EAA0D;AACvF,IAAA,MAAM,eAAe,MAAM,IAAA,CAAK,QAAA,CAAS,IAAA,CAAK,UAAU,IAAI,CAAA;AAC5D,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,WAAA,CAAY,YAAY,CAAA;AAE/C,IAAA,OAAO,SAAA;AAAA,EACT;AAAA,EAEA,MAAgB,WAAA,CACd,IAAA,EACA,IAAA,EACA,QAAiB,KAAA,EACA;AACjB,IAAA,IAAI,SAAA,GAAY,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA;AAE9C,IAAA,IAAI,WAA0C,EAAC;AAE/C,IAAA,IAAI,KAAA,EAAO;AACT,MAAA,QAAA,GAAW,EAAE,GAAG,SAAA,EAAU;AAAA,IAC5B;AAEA,IAAA,QAAA,GAAW,EAAE,GAAG,QAAA,EAAU,CAAC,IAAA,CAAK,OAAO,GAAG,IAAA,EAAK;AAE/C,IAAA,MAAM,IAAA,CAAK,SAAS,KAAA,CAAM,IAAA,EAAM,KAAK,SAAA,CAAU,QAAA,EAAU,IAAA,EAAM,CAAC,CAAC,CAAA;AAEjE,IAAA,IAAA,CAAK,IAAA,CAAA,gBAAA,yBAA8B,EAAE,IAAA,EAAM,IAAA,EAAM,UAAU,CAAA;AAE3D,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOO,aAAa,SAAA,EAAyB;AAC3C,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,WAAW,SAAA,EAA6B;AAC7C,IAAA,IAAA,CAAK,SAAA,GAAY,SAAA;AACjB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA,EAMO,UAAU,QAAA,EAA2B;AAC1C,IAAA,IAAA,CAAK,QAAA,GAAW,QAAA;AAChB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAc,SAAA,GAA2B;AACvC,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,iBAAA,EAAkB;AAE/C,IAAA,IAAI,gBAAA,GAAsD;AAAA,MACxD;AAAA,KACF;AAEA,IAAA,IAAI,IAAA,CAAK,SAAS,SAAA,EAAW;AAC3B,MAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,uBAAA,EAAwB;AACrD,MAAA,gBAAA,GAAmB,EAAE,GAAG,gBAAA,EAAkB,GAAG,SAAA,EAAU;AAAA,IACzD;AAEA,IAAA,IAAA,CAAK,kDAA+B,gBAAgB,CAAA;AAAA,EACtD;AAAA,EAEQ,YAAY,UAAA,EAAmD;AACrE,IAAA,IAAI;AACF,MAAA,IAAI,CAAC,UAAA,EAAY,OAAO,EAAC;AACzB,MAAA,MAAM,UAAA,GAAa,IAAA,CAAK,KAAA,CAAM,UAAU,CAAA;AAExC,MAAA,IAAI,OAAO,UAAA,KAAe,QAAA,IAAY,KAAA,CAAM,OAAA,CAAQ,UAAU,CAAA,EAAG;AAC/D,QAAA,MAAM,IAAI,MAAM,4DAA4D,CAAA;AAAA,MAC9E;AAEA,MAAA,OAAO,UAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,2DAAA,EAA8D,UAAU,CAAA,CAAE,CAAA;AAAA,IAC5F;AAAA,EACF;AAAA,EAEA,MAAc,uBAAA,GAEZ;AACA,IAAA,MAAM,aAAA,GAAgB,IAAA,CAAK,OAAA,CAAQ,GAAA,IAAO,YAAY,CAAA;AACtD,IAAA,MAAM,gBAAA,GAAmB,MAAM,IAAA,CAAK,QAAA,CAAS,KAAK,aAAa,CAAA;AAE/D,IAAA,MAAM,MAAA,GAAS,KAAK,uBAAA,EAAwB;AAC5C,IAAA,MAAM,cAAA,GAAiB,gBAAA,CAAiB,KAAA,CAAM,OAAO,CAAA,CAAE,IAAI,CAAC,IAAA,KAAS,IAAA,CAAK,IAAA,EAAM,CAAA;AAChF,IAAA,MAAM,eAAe,cAAA,CAAe,IAAA,CAAK,CAAC,IAAA,KAAS,SAAS,MAAM,CAAA;AAElE,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,MAAM,IAAA,CAAK,QAAA,CAAS,KAAA,CAAM,aAAA,EAAe,CAAA,EAAG,gBAAA,GAAmB,MAAA,GAAS,EAAE,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,GAAG,CAAA;AAE1F,MAAA,OAAO;AAAA,QACL,kBAAA,EAAoB,MAAA;AAAA,QACpB,aAAA,EAAe,aAAA;AAAA,QACf,kBAAA,EAAoB;AAAA,OACtB;AAAA,IACF;AAEA,IAAA,OAAO;AAAA,MACL,kBAAA,EAAoB,MAAA;AAAA,MACpB,aAAA,EAAe,aAAA;AAAA,MACf,kBAAA,EAAoB;AAAA,KACtB;AAAA,EACF;AAAA,EAEQ,uBAAA,GAA0B;AAChC,IAAA,IAAI,MAAA,GAAS,EAAA;AACb,IAAA,MAAM,YAAY,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,MAAM,GAAG,CAAA;AAEtD,IAAA,IAAI,OAAO,IAAA,CAAK,QAAA,CAAS,SAAA,KAAc,SAAA,EAAW;AAChD,MAAA,MAAA,GAAS,IAAA,CAAK,iCAAiC,SAAS,CAAA;AAAA,IAC1D,CAAA,MAAO;AACL,MAAA,MAAA,GAAS,IAAA,CAAK,+BAAA,CAAgC,IAAA,CAAK,QAAA,CAAS,SAAS,CAAA;AAAA,IACvE;AAEA,IAAA,OAAO,IAAA,CAAK,sBAAsB,MAAM,CAAA;AAAA,EAC1C;AAAA,EAEQ,iCAAiC,SAAA,EAAmB;AAC1D,IAAA,MAAM,QAAA,GAAW,KAAK,OAAA,CAAQ,IAAA,CAAK,SAAS,IAAA,EAAM,IAAA,CAAK,SAAS,WAAW,CAAA;AAE3E,IAAA,MAAM,MAAA,GAAmB,CAAC,SAAS,CAAA;AACnC,IAAA,MAAA,CAAO,KAAK,CAAA,EAAG,QAAQ,IAAI,IAAA,CAAK,QAAA,CAAS,OAAO,CAAA,CAAE,CAAA;AAElD,IAAA,OAAO,MAAA,CAAO,KAAK,GAAG,CAAA;AAAA,EACxB;AAAA,EAEQ,gCAAgC,UAAA,EAA2B;AACjE,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,UAAA,EAAY,GAAG,CAAA;AAAA,EACrC;AAAA,EAEQ,sBAAsB,IAAA,EAAsB;AAClD,IAAA,OAAO,IAAA,CAAK,OAAA,CAAQ,cAAA,EAAgB,GAAG,CAAA;AAAA,EACzC;AACF,CAAA;;;AC3KO,IAAM,UAAA,GAAN,cAAyB,KAAA,CAAM;AAAA,EAC5B,aAAA;AAAA,EACA,QAAA;AAAA,EAER,YAAY,OAAA,EAAsC;AAChD,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,QAAA,GAAW,EAAE,GAAG,2BAAA,EAA6B,GAAG,OAAA,EAAQ;AAC7D,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAI,aAAA,CAAc,IAAA,CAAK,SAAS,MAAM,CAAA;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAkDA,MAAa,OAAO,OAAA,EAA2C;AAC7D,IAAA,MAAM,EAAE,IAAA,EAAM,OAAA,EAAQ,GAAI,OAAA;AAE1B,IAAA,MAAM,MAAM,MAAM,IAAA,CAAK,cAAc,IAAA,EAAM,MAAA,CAAO,OAAO,CAAC,CAAA;AAE1D,IAAA,IAAI,CAAC,GAAA,EAAK;AACR,MAAA,IAAA,CAAK,UAAA,CAAW,eAAA,EAAiB,IAAA,EAAM,OAAO,CAAA;AAC9C,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,cAAA,CAAA,EAAkB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC/C,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,IACtC;AAEA,IAAA,MAAM,EAAE,IAAI,OAAA,EAAS,SAAA,EAAW,aAAa,OAAA,EAAQ,GAAI,IAAA,CAAK,WAAA,CAAY,GAAG,CAAA;AAE7E,IAAA,IAAI,CAAC,EAAA,IAAM,SAAA,IAAa,WAAA,IAAe,GAAA,EAAK;AAC1C,MAAA,IAAI,CAAC,QAAQ,QAAA,EAAU;AACrB,QAAA,IAAA,CAAK,UAAA,CAAW,0BAAA,EAA4B,GAAA,EAAK,OAAO,CAAA;AACxD,QAAA,IAAA,CAAK,MAAA,CAAO,CAAA,0BAAA,CAAA,EAA8B,EAAE,IAAA,EAAM,SAAS,CAAA;AAC3D,QAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,MACtC;AAEA,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,MAAA,CAAO;AAAA,QAC9B,MAAM,GAAA,CAAI,IAAA;AAAA,QACV,GAAG,OAAA,CAAQ;AAAA,OACZ,CAAA;AAED,MAAA,MAAM,YAAY,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,MAAM,GAAA,EAAI;AAEnD,MAAA,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,SAAA,EAAW,OAAO,CAAA;AAClD,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,YAAA,CAAA,EAAgB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC7C,MAAA,OAAO,SAAA;AAAA,IACT;AAEA,IAAA,IAAI,CAAC,EAAA,IAAM,SAAA,IAAa,CAAC,eAAe,GAAA,EAAK;AAC3C,MAAA,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,IAAA,EAAM,GAAG,CAAA;AACzC,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,YAAA,CAAA,EAAgB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC7C,MAAA,OAAO,EAAE,OAAA,EAAS,GAAA,EAAK,KAAA,EAAO,IAAA,EAAK;AAAA,IACrC;AAEA,IAAA,IAAI,CAAC,EAAA,EAAI;AACP,MAAA,IAAA,CAAK,UAAA,CAAW,cAAA,EAAgB,GAAA,EAAK,OAAA,EAAS,OAAO,CAAA;AACrD,MAAA,IAAA,CAAK,MAAA,CAAO,CAAA,YAAA,CAAA,EAAgB,EAAE,IAAA,EAAM,SAAS,CAAA;AAC7C,MAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,IAAA,EAAK;AAAA,IACtC;AAEA,IAAA,OAAO,EAAE,OAAA,EAAS,IAAA,EAAM,KAAA,EAAO,GAAA,EAAI;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAuCA,MAAa,MAAA,CACX,OAAA,EACA,SAAA,GAA2B,EAAC,EACmB;AAC/C,IAAA,MAAM,EAAE,MAAA,EAAQ,QAAA,EAAU,MAAM,IAAA,EAAM,KAAA,EAAO,WAAU,GAAI,OAAA;AAE3D,IAAA,MAAM,EAAE,KAAK,MAAA,EAAQ,OAAA,KAAY,IAAA,CAAK,aAAA,CAAc,YAAY,SAAS,CAAA;AACzE,IAAA,MAAM,EAAE,IAAA,EAAK,GAAI,IAAA,CAAK,cAAc,YAAA,EAAa;AAEjD,IAAA,IAAA,CAAK,MAAA,CAAO,CAAA;AAAA,QAAA,CAAA,EAA2B,OAAO,CAAA;AAE9C,IAAA,MAAM,SAAA,GAAY,IAAA,CAAK,aAAA,CAAc,IAAA,CAAK,KAAK,IAAI,CAAA;AACnD,IAAA,MAAM,GAAA,uBAAU,IAAA,EAAK;AAErB,IAAA,MAAM,YAAA,GAA8B;AAAA,MAClC,IAAA,EAAM,IAAI,WAAA,EAAY;AAAA,MACtB,EAAA,EAAI,YAAY,IAAA,GAAO,WAAA,CAAY,KAAK,QAAA,EAAU,IAAI,CAAA,CAAE,WAAA,EAAY,GAAI,aAAA;AAAA,MACxE,GAAA;AAAA,MACA,MAAA,EAAQ,SAAA;AAAA,MACR,WAAA,EAAa,OAAA;AAAA,MACb,IAAA;AAAA,MACA,SAAS,MAAM,iBAAA,CAAkB,IAAA,CAAK,QAAA,CAAS,kBAAkB,CAAA;AAAA,MACjE,MAAA,EAAQ,CAAC,CAAC;AAAA,KACZ;AAEA,IAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,cAAA,CAAe,cAAc,CAAC,CAAC,OAAO,SAAS,CAAA;AACvE,IAAA,IAAA,CAAK,OAAO,CAAA,UAAA,CAAA,EAAc;AAAA,MACxB,IAAA;AAAA,MACA,SAAS,YAAA,CAAa,OAAA;AAAA,MACtB,MAAM,YAAA,CAAa;AAAA,KACpB,CAAA;AAED,IAAA,OAAO,EAAE,GAAA,EAAK,YAAA,EAAc,IAAA,EAAK;AAAA,EACnC;AAAA,EAEA,MAAc,aAAA,CAAc,IAAA,EAAc,OAAA,EAAgD;AACxF,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAO,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,OAAO,CAAA;AAAA,IACpC;AAEA,IAAA,MAAM,SAAA,GAAY,MAAM,IAAA,CAAK,cAAA,CAAe,IAAI,CAAA;AAChD,IAAA,OAAO,SAAA,CAAU,OAAO,CAAA,IAAK,IAAA;AAAA,EAC/B;AAAA,EAEA,MAAc,cAAA,CACZ,GAAA,EACA,KAAA,EACA,SAAA,EACiB;AACjB,IAAA,OAAA,CAAQ,IAAA,CAAK,WAAW,IAAA,CAAK,IAAI,KAAK,IAAA,CAAK,WAAA,CAAY,KAAK,IAAI,CAAA;AAAA,MAC9D,IAAA,CAAK,WAAA,CAAY,EAAE,GAAG,SAAA,EAAW,OAAA,EAAS,GAAA,CAAI,OAAA,EAAS,IAAA,EAAM,GAAA,CAAI,IAAA,EAAM,CAAA;AAAA,MACvE,GAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF;AAAA,EAEQ,YAAY,YAAA,EAMlB;AACA,IAAA,MAAM,oBAAA,GAAuB,YAAA;AAE7B,IAAA,MAAM,UAAA,GAA2E;AAAA,MAC/E,IAAA,EAAM,QAAA;AAAA,MACN,EAAA,EAAI,QAAA;AAAA,MACJ,GAAA,EAAK,QAAA;AAAA,MACL,MAAA,EAAQ,QAAA;AAAA,MACR,MAAA,EAAQ,SAAA;AAAA,MACR,IAAA,EAAM,QAAA;AAAA,MACN,OAAA,EAAS,cAAA;AAAA,MACT,WAAA,EAAa;AAAA,KACf;AAEA,IAAA,KAAA,MAAW,CAAC,KAAA,EAAO,IAAI,KAAK,MAAA,CAAO,OAAA,CAAQ,UAAU,CAAA,EAElD;AACD,MAAA,IAAI,CAAC,MAAA,CAAO,oBAAA,CAAqB,KAAK,CAAC,EAAE,IAAI,CAAA;AAC3C,QAAA,OAAO,EAAE,IAAI,KAAA,EAAO,OAAA,EAAS,GAAG,KAAK,CAAA,aAAA,CAAA,EAAiB,SAAS,KAAA,EAAM;AAAA,IACzE;AAEA,IAAA,IAAI,CAAC,MAAA,CAAO,oBAAA,CAAqB,IAAI,CAAA,EAAG;AACtC,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,yBAAA,EAA2B,SAAS,MAAA,EAAO;AAAA,IAC1E,CAAA,MAAA,IAAW,IAAI,IAAA,CAAK,oBAAA,CAAqB,IAAI,CAAA,mBAAI,IAAI,MAAK,EAAG;AAC3D,MAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,qBAAA,EAAsB;AAAA,IACrD;AAEA,IAAA,IAAI,CAAC,MAAA,CAAO,oBAAA,CAAqB,EAAE,CAAA,EAAG;AACpC,MAAA,IAAI,oBAAA,CAAqB,OAAO,aAAA,EAAe;AAC7C,QAAA,OAAO,EAAE,EAAA,EAAI,KAAA,EAAO,OAAA,EAAS,2BAAA,EAA6B,SAAS,IAAA,EAAK;AAAA,MAC1E;AAAA,IACF,CAAA,MAAA,IAAW,IAAI,IAAA,CAAK,oBAAA,CAAqB,EAAE,CAAA,mBAAI,IAAI,MAAK,EAAG;AACzD,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,OAAA,EAAS,gBAAA;AAAA,QACT,OAAA,EAAS,IAAA;AAAA,QACT,SAAA,EAAW,IAAA;AAAA,QACX,WAAA,EAAa,CAAC,CAAC,oBAAA,CAAqB;AAAA,OACtC;AAAA,IACF;AAEA,IAAA,IAAI,qBAAqB,WAAA,GAAc,CAAA;AACrC,MAAA,OAAO;AAAA,QACL,EAAA,EAAI,KAAA;AAAA,QACJ,OAAA,EAAS,2BAAA;AAAA,QACT,OAAA,EAAS;AAAA,OACX;AAEF,IAAA,OAAO,EAAE,EAAA,EAAI,IAAA,EAAM,OAAA,EAAS,EAAA,EAAG;AAAA,EACjC;AAAA,EAEQ,YAAY,SAAA,EAA0B;AAC5C,IAAA,OAAO,UAAA;AAAA,MACL,WAAW,CAAA,6BAAA,CAAA,EAAiC;AAAA,QAC1C,MAAM,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,QAAA,CAAS,MAAM,GAAG,CAAA;AAAA,QAC1C,QAAA,EAAU,KAAK,OAAA,CAAQ,IAAA,CAAK,SAAS,IAAA,EAAM,IAAA,CAAK,SAAS,WAAW,CAAA;AAAA,QACpE,GAAA,EAAK,KAAK,QAAA,CAAS;AAAA,OACpB,CAAA;AAAA,MACD;AAAA,KACF;AAAA,EACF;AAAA,EAEQ,UAAA,CACN,SACG,IAAA,EAC8B;AACjC,IAAA,OAAO,IAAA,CAAK,OAAA,CAA6B,IAAA,EAAM,GAAG,IAAI,CAAA;AAAA,EACxD;AACF,CAAA;;;ACjSO,IAAM,EAAA,GAAN,MAAM,GAAA,SAAW,UAAA,CAAW;AAAA,EACzB,OAAA;AAAA,EAER,YAAY,OAAA,EAAkC;AAC5C,IAAA,KAAA,CAAM,OAAO,CAAA;AAEb,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,sBAAA;AAAA,MACH,GAAG;AAAA,KACL;AAAA,EACF;AAAA,EAEO,WAAW,OAAA,EAA+B;AAC/C,IAAA,IAAA,CAAK,OAAA,GAAU;AAAA,MACb,GAAG,sBAAA;AAAA,MACH,GAAG;AAAA,KACL;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEO,UAAA,GAAyC;AAC9C,IAAA,OAAO,IAAA,CAAK,OAAA;AAAA,EACd;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQO,KAAA,CAAM,MAAA,GAAkC,EAAC,EAAO;AACrD,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAG,EAAE,GAAG,KAAK,UAAA,EAAW,EAAG,GAAG,MAAA,EAAQ,CAAA;AAEzD,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,MAAA,CAAO,UAAA,CAAW,KAAK,SAAS,CAAA;AACpD,IAAA,IAAI,IAAA,CAAK,QAAA,EAAU,MAAA,CAAO,SAAA,CAAU,KAAK,QAAQ,CAAA;AACjD,IAAA,IAAI,IAAA,CAAK,SAAA,EAAW,MAAA,CAAO,YAAA,CAAa,KAAK,SAAS,CAAA;AAEtD,IAAA,MAAA,CAAO,QAAA,CAAS,IAAA,CAAK,QAAA,EAAU,CAAA;AAC/B,IAAA,MAAA,CAAO,SAAA,CAAU,IAAA,CAAK,SAAA,EAAW,CAAA;AAEjC,IAAA,OAAO,MAAA;AAAA,EACT;AAAA,EAEO,SAAS,KAAA,EAAgE;AAC9E,IAAA,IAAA,CAAK,SAAS,KAAK,CAAA;AACnB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEO,OAAA,CACL,MACA,OAAA,EACA;AACA,IAAA,IAAA,CAAK,SAAS,EAAE,CAAC,IAAI,GAAG,SAAS,CAAA;AACjC,IAAA,OAAO,IAAA;AAAA,EACT;AACF,CAAA;;;ACvDA,IAAI,QAAA,GAAsB,IAAA;AAQnB,IAAM,SAAS,CACpB,OAAA,GAAyC,EAAC,EAC1C,YAAqB,KAAA,KACd;AACP,EAAA,IAAI,CAAC,SAAA,EAAW,OAAO,IAAI,GAAG,OAAO,CAAA;AAErC,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,QAAA,GAAW,IAAI,GAAG,OAAO,CAAA;AAAA,EAC3B;AAEA,EAAA,OAAO,QAAA;AACT;AAKO,IAAM,EAAA,GAAK","file":"index.js","sourcesContent":["import { TEventsOptions, TModuleOptions, TStoreOptions } from 'src/types';\nimport { TBaseOptions } from 'src/types/base.type';\nimport { TCryptoOptions } from 'src/types/crypto.type';\nimport { TKeyManagerOptions } from 'src/types/key-manager.types';\n\nexport const DEFAULT_CRYPTO_OPTIONS: Required<TCryptoOptions> = {\n algorithm: 'aes-256-cbc',\n kdf: 'pbkdf2',\n hashAlgorithm: 'sha256',\n keyLength: 32,\n ivLength: 16,\n saltLength: 32,\n tagLength: 16,\n iterations: 100000,\n encoding: 'base64',\n};\n\nexport const DEFAULT_BASE_OPTIONS: Required<TBaseOptions> = {\n quiet: false,\n};\n\nexport const DEFAULT_BASE_LOGGER = (...args: any[]) => console.log(...args);\n\nexport const DEFAULT_EVENTS_OPTIONS: Required<TEventsOptions> = {\n ...DEFAULT_BASE_OPTIONS,\n\n // Event\n useEvent: true,\n};\n\nexport const DEFAULT_STORE_OPTIONS: Required<TStoreOptions> = {\n path: ['keys', '{{type}}'],\n file: ['v', '{{version}}'],\n fileSplitor: '_',\n fileExt: 'json',\n gitIgnore: true,\n\n ...DEFAULT_EVENTS_OPTIONS,\n\n // Key manager\n crypto: DEFAULT_CRYPTO_OPTIONS,\n};\n\nexport const DEFAULT_KEY_MANAGER_OPTIONS: Required<TKeyManagerOptions> = {\n // Store\n ...DEFAULT_STORE_OPTIONS,\n\n versionGenerator: () => new Date().getTime(),\n};\n\nexport const DEFAULT_MODULE_OPTIONS: Required<TModuleOptions> = {\n ...DEFAULT_KEY_MANAGER_OPTIONS,\n\n // Module\n quiet: false,\n};\n","import { TBaseOptions } from './base.type';\nimport { TKeyGenerated } from './key-manager.types';\n\nexport enum EEvent {\n STORE_INIT_FOLDER = 'store-init-folder',\n STORE_FILE_SAVED = 'saved-key-file',\n}\n\nexport type TEvents = {\n [EEvent.STORE_INIT_FOLDER]: {\n gitIgnoreStorePath?: string;\n gitIgnorePath?: string;\n gitIgnoreAddStatus?: 'already' | 'added';\n storePath: string;\n };\n [EEvent.STORE_FILE_SAVED]: { path: string; data: Record<string, TKeyGenerated> };\n};\n\nexport type TEventsOptions = Partial<TBaseOptions> & {\n /**\n * Is use event emitter\n * @default true\n */\n useEvent?: boolean;\n};\n","export const executePromisably = <T>(\n promiseOrFn: T | Promise<T> | ((...args: unknown[]) => T | Promise<T>)\n): Promise<T> => {\n try {\n const value =\n typeof promiseOrFn === 'function' && !(promiseOrFn instanceof Promise)\n ? (promiseOrFn as (...args: unknown[]) => T | Promise<T>)()\n : promiseOrFn;\n return Promise.resolve(value);\n } catch (error) {\n return Promise.reject(error);\n }\n};\n\nexport const promiseAll = <T extends readonly unknown[]>(\n ...fns: T\n): Promise<{ [K in keyof T]: Awaited<T[K]> }> => {\n return Promise.all(fns);\n};\n","import { access, mkdir, readFile, unlink, writeFile } from 'fs/promises';\nimport { dirname } from 'path';\n\nexport class FileUtilError extends Error {\n constructor(\n message: string,\n public readonly path: string,\n public readonly operation: 'read' | 'write' | 'delete' | 'access' | 'mkdir',\n public readonly cause?: unknown\n ) {\n super(message);\n this.name = 'FileUtilError';\n }\n}\n\nexport class FileUtil {\n async getFolder(path: string): Promise<string> {\n try {\n await access(path);\n return path;\n } catch {\n try {\n await mkdir(path, { recursive: true });\n return path;\n } catch (error) {\n throw new FileUtilError(`Failed to create folder: ${path}`, path, 'mkdir', error);\n }\n }\n }\n\n async read(path: string, fallback?: string): Promise<string> {\n try {\n const data = await readFile(path, { encoding: 'utf8' });\n return data;\n } catch (error) {\n if (fallback !== undefined) return fallback;\n throw new FileUtilError(`Failed to read file: ${path}`, path, 'read', error);\n }\n }\n\n async write(path: string, data: string, flag: 'w' | 'a' = 'w'): Promise<void> {\n const dir = dirname(path);\n await this.getFolder(dir);\n\n try {\n await writeFile(path, data, { encoding: 'utf8', flag });\n } catch (error) {\n throw new FileUtilError(`Failed to write file: ${path}`, path, 'write', error);\n }\n }\n\n async checkExists(path: string): Promise<boolean> {\n try {\n await access(path);\n return true;\n } catch {\n return false;\n }\n }\n\n async delete(path: string): Promise<void> {\n try {\n await unlink(path);\n } catch (error) {\n throw new FileUtilError(`Failed to delete file: ${path}`, path, 'delete', error);\n }\n }\n}\n","import { TKeyDurationUnit } from 'src/types/key-manager.types';\n\nconst getNested = (obj: Record<string, any>, path: string): any =>\n path.split('.').reduce((curr, key) => curr?.[key], obj);\n\nconst flatten = (obj: Record<string, any>, prefix = ''): Record<string, any> =>\n Object.entries(obj).reduce((acc, [key, val]) => {\n const newKey = prefix ? `${prefix}.${key}` : key;\n return val && typeof val === 'object' && !Array.isArray(val)\n ? { ...acc, ...flatten(val, newKey) }\n : { ...acc, [newKey]: val };\n }, {});\n\nconst stringify = (val: any): string => {\n if (val === null || val === undefined) return '';\n if (typeof val === 'object') return JSON.stringify(val);\n return String(val);\n};\n\nexport const bindString = (format: string, bindValues: Record<string, any>): string => {\n return format\n .replace(/\\{\\{\\.\\.\\.([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n\n return val && typeof val === 'object' && !Array.isArray(val)\n ? JSON.stringify(flatten(val, trimmedPath))\n : match;\n })\n .replace(/\\{\\{([^}]+)\\}\\}/g, (match, path) => {\n const trimmedPath = path.trim();\n\n // Skip if it's a spread syntax (already handled)\n if (trimmedPath.startsWith('...')) {\n return match;\n }\n\n const val = trimmedPath.includes('.')\n ? getNested(bindValues, trimmedPath)\n : bindValues[trimmedPath];\n return stringify(val);\n });\n};\nexport const isDate = (data: string): boolean => {\n try {\n const date = new Date(data);\n return !isNaN(date.getTime());\n } catch (error) {\n return false;\n }\n};\n\nexport const addDuration = (date: Date, duration: number, unit: TKeyDurationUnit): Date => {\n const result = new Date(date.getTime());\n\n switch (unit) {\n case 'seconds':\n result.setSeconds(result.getSeconds() + duration);\n break;\n\n case 'minutes':\n result.setMinutes(result.getMinutes() + duration);\n break;\n\n case 'hours':\n result.setHours(result.getHours() + duration);\n break;\n\n case 'days':\n result.setDate(result.getDate() + duration);\n break;\n\n default: {\n const _exhaustiveCheck: never = unit;\n throw new Error(`Unsupported duration unit: ${_exhaustiveCheck}`);\n }\n }\n\n return result;\n};\n\nexport const isType = (data?: unknown) => {\n return {\n number: typeof data === 'number' && !Number.isNaN(Number(data)),\n string: typeof data === 'string',\n stringNumber: typeof data === 'string' || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n };\n};\n","import { randomBytes, pbkdf2Sync, createCipheriv, createDecipheriv, createHash } from 'node:crypto';\nimport { DEFAULT_CRYPTO_OPTIONS } from 'src/constants/default.constant';\nimport { TCryptoOptions } from 'src/types/crypto.type';\n\nexport class CryptoService {\n private options: Required<TCryptoOptions>;\n\n constructor(options: Partial<TCryptoOptions> = {}) {\n this.options = { ...DEFAULT_CRYPTO_OPTIONS, ...options };\n }\n\n /**\n * Generate random bytes and encode them\n */\n generateRandom(length: number = 32): string {\n const buffer = randomBytes(length);\n return this.encodeBuffer(buffer);\n }\n\n /**\n * Generate a random key\n * @param length Length of the key in bytes\n * @default cryptoOptions.keyLength\n */\n generateKey(length: number = this.options.keyLength) {\n return { key: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random salt\n * @param length Length of the salt in bytes\n * @default cryptoOptions.saltLength\n */\n generateSalt(length: number = this.options.saltLength) {\n return { salt: this.generateRandom(length), length } as const;\n }\n\n /**\n * Generate a random IV\n * @param length Length of the IV in bytes\n * @default cryptoOptions.ivLength\n */\n generateIV(length: number = this.options.ivLength) {\n return { iv: this.generateRandom(length), length } as const;\n }\n\n private encodeBuffer(buffer: Buffer): string {\n switch (this.options.encoding) {\n case 'hex':\n return buffer.toString('hex');\n case 'base64url':\n return buffer.toString('base64url');\n case 'base64':\n default:\n return buffer.toString('base64');\n }\n }\n\n private decodeToBuffer(encoded: string): Buffer {\n switch (this.options.encoding) {\n case 'hex':\n return Buffer.from(encoded, 'hex');\n case 'base64url':\n return Buffer.from(encoded, 'base64url');\n case 'base64':\n default:\n return Buffer.from(encoded, 'base64');\n }\n }\n\n private deriveKey(password: string, salt: Buffer, keyLength?: number): Buffer {\n if (this.options.kdf === 'none') {\n return Buffer.from(password, 'hex');\n }\n\n const actualKeyLength = keyLength ?? this.options.keyLength;\n return pbkdf2Sync(\n password,\n salt,\n this.options.iterations,\n actualKeyLength,\n this.options.hashAlgorithm\n );\n }\n\n /**\n * Encrypt data using AES-CBC\n * @param plainText Text to encrypt\n * @param secret Secret key for encryption\n * @param options Optional lengths for key, salt, and IV\n */\n encrypt(\n plainText: string,\n secret: string,\n {\n keyLength,\n saltLength,\n ivLength,\n }: { keyLength?: number; saltLength?: number; ivLength?: number } = {}\n ): string {\n keyLength = keyLength ?? this.options.keyLength;\n saltLength = saltLength ?? this.options.saltLength;\n ivLength = ivLength ?? this.options.ivLength;\n\n const salt = this.options.kdf !== 'none' ? randomBytes(saltLength) : Buffer.alloc(0);\n const iv = randomBytes(ivLength);\n const key = this.deriveKey(secret, salt, keyLength);\n\n const cipher = createCipheriv(this.options.algorithm, key, iv);\n const encrypted = Buffer.concat([cipher.update(plainText, 'utf8'), cipher.final()]);\n\n // Pack: keyLength(2) + saltLength(2) + ivLength(2) + salt + iv + encrypted\n const keyLengthBuf = Buffer.alloc(2);\n keyLengthBuf.writeUInt16BE(keyLength);\n\n const saltLengthBuf = Buffer.alloc(2);\n saltLengthBuf.writeUInt16BE(salt.length);\n\n const ivLengthBuf = Buffer.alloc(2);\n ivLengthBuf.writeUInt16BE(ivLength);\n\n const combined = Buffer.concat([keyLengthBuf, saltLengthBuf, ivLengthBuf, salt, iv, encrypted]);\n\n return this.encodeBuffer(combined);\n }\n\n /**\n * Decrypt data\n * @param encryptedData Encrypted data to decrypt\n * @param secret Secret key for decryption\n * @returns Decrypted string, or empty string if decryption fails (wrong password/corrupted data)\n */\n decrypt(encryptedData: string, secret: string): string {\n try {\n const combined = this.decodeToBuffer(encryptedData);\n let offset = 0;\n\n // Read lengths (2 bytes each)\n const keyLength = combined.readUInt16BE(offset);\n offset += 2;\n const saltLength = combined.readUInt16BE(offset);\n offset += 2;\n const ivLength = combined.readUInt16BE(offset);\n offset += 2;\n\n // Read salt, iv, and encrypted data\n const salt = combined.subarray(offset, offset + saltLength);\n offset += saltLength;\n\n const iv = combined.subarray(offset, offset + ivLength);\n offset += ivLength;\n\n const encrypted = combined.subarray(offset);\n\n const key = this.deriveKey(secret, salt, keyLength);\n\n const decipher = createDecipheriv(this.options.algorithm, key, iv);\n const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);\n\n return decrypted.toString('utf8');\n } catch {\n // Return empty string on decryption failure (wrong password, corrupted data, etc.)\n // This matches the behavior of crypto-js\n return '';\n }\n }\n\n /**\n * Hash data (one-way)\n * @param data Data to hash\n * @param secret Secret key used in hashing\n * @param salt Optional encoded salt string for deterministic hashing\n */\n hash(data: string, secret: string, salt?: string): string {\n let saltBuffer: Buffer;\n let saltStr: string;\n\n if (salt) {\n // Deterministic mode: use provided salt\n saltBuffer = this.decodeToBuffer(salt);\n saltStr = salt;\n } else {\n // Non-deterministic mode: generate random salt\n saltBuffer = randomBytes(this.options.saltLength);\n saltStr = this.encodeBuffer(saltBuffer);\n }\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n return `${saltStr}:${hashStr}`;\n }\n\n /**\n * Verify hashed data\n * @param data Data to verify\n * @param hashedData Previously hashed data (format: salt:hash)\n * @param secret Secret key used during hashing\n */\n verifyHash(data: string, hashedData: string, secret: string): boolean {\n const [saltStr, expectedHashStr] = hashedData.split(':');\n if (!saltStr || !expectedHashStr) {\n return false;\n }\n\n const saltBuffer = this.decodeToBuffer(saltStr);\n\n const hash = createHash(this.options.hashAlgorithm)\n .update(data)\n .update(secret)\n .update(saltBuffer)\n .digest();\n\n const hashStr = this.encodeBuffer(hash);\n\n // Use timing-safe comparison\n return hashStr === expectedHashStr;\n }\n}\n","import { DEFAULT_BASE_LOGGER, DEFAULT_BASE_OPTIONS } from 'src/constants/default.constant';\nimport { TBaseLogger, TBaseOptions, THook } from 'src/types/base.type';\n\ntype DefaultLogger = typeof DEFAULT_BASE_LOGGER;\n\nexport class Base<TLogger extends (...args: any[]) => any = DefaultLogger> {\n private logger: TBaseLogger<TLogger>;\n private bOptions: Required<TBaseOptions>;\n private hooks: Map<string, THook> = new Map();\n\n constructor(options: Partial<TBaseOptions>) {\n this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };\n this.logger = DEFAULT_BASE_LOGGER as TBaseLogger<TLogger>;\n }\n\n protected getLogger(): TBaseLogger<TLogger> {\n return this.logger;\n }\n\n public setLogger(logger: TBaseLogger<TLogger>): this {\n this.logger = logger;\n return this;\n }\n\n public sysLog(...args: Parameters<TLogger>): this {\n if (!this.bOptions.quiet) {\n const result = this.logger(...args);\n if (result && typeof result === 'object' && 'catch' in result) {\n (result as Promise<unknown>).catch(() => {});\n }\n }\n return this;\n }\n\n public async customLog<T extends (...args: any[]) => any>(\n logger: TBaseLogger<T>,\n ...args: Parameters<T>\n ) {\n await logger(...args);\n return this;\n }\n\n protected setHooks<T extends Record<string, THook> = {}>(hooks: T) {\n Object.entries(hooks).forEach(([name, handler]) => {\n if (this.hooks.has(name)) {\n this.hooks.get('onHookOverriding')?.call(this, name);\n }\n\n this.hooks.set(name, handler);\n });\n return this;\n }\n\n protected runHook<Hooks extends Record<string, THook>, K extends keyof Hooks>(\n name: K,\n ...args: Parameters<Hooks[K]>\n ): ReturnType<Hooks[K]> {\n if (!this.hooks.has(name as string)) {\n this.hooks.get('onHookNotFound')?.call(this, name as string);\n return undefined as any;\n }\n\n return this.hooks.get(name as string)!.call(this, ...args);\n }\n\n protected getHooks(): Record<string, THook> {\n return Object.fromEntries(this.hooks.entries()) as Record<string, THook>;\n }\n}\n","import EventEmitter from 'node:events';\nimport { Base } from './base.core';\nimport { TEvents, TEventsOptions } from 'src/types';\nimport { DEFAULT_EVENTS_OPTIONS } from 'src/constants/default.constant';\n\nexport class Events extends Base {\n private events?: EventEmitter;\n private eOptions: Required<TEventsOptions>;\n\n constructor(options: TEventsOptions) {\n super(options);\n\n this.eOptions = {\n ...DEFAULT_EVENTS_OPTIONS,\n ...options,\n };\n\n if (this.eOptions.useEvent) {\n this.events = new EventEmitter();\n }\n }\n\n protected emit<K extends keyof TEvents>(event: K, args: TEvents[K]) {\n if (!this.events) return this;\n\n this.events.emit(event, args);\n return this;\n }\n\n on<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.on(event, listener);\n return this;\n }\n\n once<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.once(event, listener);\n return this;\n }\n\n off<K extends keyof TEvents>(event: K, listener: (args: TEvents[K]) => void) {\n if (!this.events) return this;\n\n this.events.off(event, listener);\n return this;\n }\n}\n","import { EEvent, TEvents, TFormatUsable, TGetKeyFn, TSaveKeyFn, TStoreOptions } from 'src/types';\nimport { FileUtil } from 'src/utils';\nimport { DEFAULT_STORE_OPTIONS } from 'src/constants/default.constant';\nimport { join } from 'path';\nimport { TKeyGenerated } from 'src/types/key-manager.types';\nimport { Events } from './events.core';\n\nexport class Store extends Events {\n private sOptions: Required<Omit<TStoreOptions, 'useEvent' | 'crypto'>>;\n private fileUtil: FileUtil;\n protected storePath?: string;\n protected saveKeyFn?: TSaveKeyFn;\n protected getKeyFn?: TGetKeyFn;\n\n constructor(options: Partial<TStoreOptions>) {\n super(options);\n\n this.sOptions = { ...DEFAULT_STORE_OPTIONS, ...options };\n this.fileUtil = new FileUtil();\n\n this.initStore();\n }\n\n protected getPath(path: string | string[], splitor: string): string {\n if (typeof path === 'object' && Array.isArray(path)) {\n return path.join(splitor);\n }\n\n return path;\n }\n\n private async getKeyStoreFolder(): Promise<string> {\n if (this.storePath) return this.storePath;\n\n const { path } = this.sOptions;\n\n const first =\n typeof path === 'object' && Array.isArray(path)\n ? path[0]\n : typeof path === 'string'\n ? (path.split('/')[0] ?? '')\n : '';\n\n let folder = await this.fileUtil.getFolder(join(process.cwd(), first));\n\n return folder;\n }\n\n protected async getKeyFileData(filePath: string): Promise<Record<string, TKeyGenerated>> {\n const existingData = await this.fileUtil.read(filePath, '{}');\n const savedData = this.toSavedData(existingData);\n\n return savedData;\n }\n\n protected async saveKeyFile(\n path: string,\n data: TKeyGenerated,\n merge: boolean = false\n ): Promise<string> {\n let savedData = await this.getKeyFileData(path);\n\n let saveData: Record<string, TKeyGenerated> = {};\n\n if (merge) {\n saveData = { ...savedData };\n }\n\n saveData = { ...saveData, [data.version]: data };\n\n await this.fileUtil.write(path, JSON.stringify(saveData, null, 2));\n\n this.emit(EEvent.STORE_FILE_SAVED, { path, data: saveData });\n\n return path;\n }\n\n /**\n * @param storePath custom store path\n * root folder of store\n * @returns this\n */\n public useStorePath(storePath: string): this {\n this.storePath = storePath;\n return this;\n }\n\n /**\n * @param saveKeyFn custom save key function\n * @returns this\n */\n public useSaveKey(saveKeyFn: TSaveKeyFn): this {\n this.saveKeyFn = saveKeyFn;\n return this;\n }\n\n /**\n * @param saveKeyFn custom get key function\n * @returns this\n */\n public useGetKey(getKeyFn: TGetKeyFn): this {\n this.getKeyFn = getKeyFn;\n return this;\n }\n\n private async initStore(): Promise<void> {\n const storePath = await this.getKeyStoreFolder();\n\n let eventEmitPayload: TEvents[EEvent.STORE_INIT_FOLDER] = {\n storePath,\n };\n\n if (this.sOptions.gitIgnore) {\n const gitignore = await this.addStoreFolderGitignore();\n eventEmitPayload = { ...eventEmitPayload, ...gitignore };\n }\n\n this.emit(EEvent.STORE_INIT_FOLDER, eventEmitPayload);\n }\n\n private toSavedData(dataString: string): Record<string, TKeyGenerated> {\n try {\n if (!dataString) return {};\n const parsedData = JSON.parse(dataString) as Record<string, TKeyGenerated>;\n\n if (typeof parsedData !== 'object' || Array.isArray(parsedData)) {\n throw new Error('Invalid JSON data (must be Record<version, TKeyGenerated>)');\n }\n\n return parsedData;\n } catch (error) {\n throw new Error(`Invalid JSON data (must be Record<version, TKeyGenerated>) ${dataString}`);\n }\n }\n\n private async addStoreFolderGitignore(): Promise<\n Omit<TEvents[EEvent.STORE_INIT_FOLDER], 'storePath'>\n > {\n const gitignorePath = join(process.cwd(), '.gitignore');\n const gitignoreContent = await this.fileUtil.read(gitignorePath);\n\n const folder = this.getStoreFolderGitignore();\n const gitignoreLines = gitignoreContent.split(/\\r?\\n/).map((line) => line.trim());\n const hasExactLine = gitignoreLines.some((line) => line === folder);\n\n if (!hasExactLine) {\n await this.fileUtil.write(gitignorePath, `${gitignoreContent ? '\\r\\n' : ''}${folder}`, 'a');\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'added',\n };\n }\n\n return {\n gitIgnoreStorePath: folder,\n gitIgnorePath: gitignorePath,\n gitIgnoreAddStatus: 'already',\n };\n }\n\n private getStoreFolderGitignore() {\n let folder = '';\n const storePath = this.getPath(this.sOptions.path, '/');\n\n if (typeof this.sOptions.gitIgnore === 'boolean') {\n folder = this.getStoreFolderGitignoreByDefault(storePath);\n } else {\n folder = this.addStoreFolderGitignoreByCustom(this.sOptions.gitIgnore);\n }\n\n return this.replaceVariableToStar(folder);\n }\n\n private getStoreFolderGitignoreByDefault(storePath: string) {\n const filePath = this.getPath(this.sOptions.file, this.sOptions.fileSplitor);\n\n const folder: string[] = [storePath];\n folder.push(`${filePath}.${this.sOptions.fileExt}`);\n\n return folder.join('/');\n }\n\n private addStoreFolderGitignoreByCustom(ignorePath: TFormatUsable) {\n return this.getPath(ignorePath, '/');\n }\n\n private replaceVariableToStar(path: string): string {\n return path.replace(/\\{\\{.*?\\}\\}/g, '*');\n }\n}\n","import {\n TGenerateKeyOptions,\n TGetKey,\n TGetKeyOptions,\n TKeyGenerated,\n TKeyManagerHooks,\n TKeyManagerOptions,\n TKeyVariables,\n} from 'src/types/key-manager.types';\nimport { Store } from './store.core';\nimport {\n CryptoService,\n executePromisably,\n addDuration,\n bindString,\n isDate,\n isType,\n} from 'src/utils';\nimport { DEFAULT_KEY_MANAGER_OPTIONS } from 'src/constants/default.constant';\n\nexport class KeyManager extends Store {\n private cryptoService: CryptoService;\n private kOptions: Required<TKeyManagerOptions>;\n\n constructor(options: Partial<TKeyManagerOptions>) {\n super(options);\n\n this.kOptions = { ...DEFAULT_KEY_MANAGER_OPTIONS, ...options };\n this.cryptoService = new CryptoService(this.kOptions.crypto);\n }\n\n /**\n * Retrieve and validate a stored key by path and version.\n *\n * This method:\n * - Loads a key from the configured store\n * - Validates structure, type safety, and time constraints\n * - Detects expiration and rotation eligibility\n * - Optionally auto-rotates an expired key if rotation options are provided\n *\n * If the key is expired and marked as rotatable, a new key will be generated\n * automatically using the provided `onRotate` options.\n *\n * @param options Configuration for key retrieval\n * @param options.path Storage path of the key\n * @param options.version Specific key version to retrieve\n * @param options.onRotate Optional rotation configuration used when the key\n * is expired and renewable\n *\n * @returns An object containing:\n * - `ready`: The valid (usable) key, or the newly generated key after rotation\n * - `expired`: The expired key if rotation occurred, otherwise `null`\n *\n * @throws Error if:\n * - The key does not exist\n * - The key structure or fields are invalid\n * - The key is expired but rotation options are missing\n * - The key is not yet valid or otherwise unusable\n *\n * @example\n * ```ts\n * const { ready, expired } = await keyManager.getKey({\n * path: '/keys/api',\n * version: 'v1',\n * // This define the new key attributes: is it rotate? Durations and unit?\n * onRotate: {\n * duration: 30,\n * unit: 'days',\n * rotate: true,\n * },\n * });\n *\n * if (expired) {\n * console.log('Key was rotated from version:', expired.version);\n * }\n *\n * // Use expired?.key ?? ready?.key safely\n * ```\n */\n public async getKey(options: TGetKeyOptions): Promise<TGetKey> {\n const { path, version } = options;\n\n const key = await this.getKeyByStore(path, String(version));\n\n if (!key) {\n this.runKeyHook('onKeyNotFound', path, version);\n this.sysLog(`Key not found!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);\n\n if (!ok && isExpired && isRenewable && key) {\n if (!options.onRotate) {\n this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: null, ready: null };\n }\n\n const renew = await this.newKey({\n type: key.type,\n ...options.onRotate,\n });\n\n const resGetKey = { expired: key, ready: renew.key };\n\n this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n this.runKeyHook('onKeyInvalid', key, message, errorOn);\n this.sysLog(`Key invalid!`, { path, version });\n return { expired: null, ready: null };\n }\n\n return { expired: null, ready: key };\n }\n\n /**\n * Generate a new cryptographic key and persist it to the configured store.\n *\n * This method:\n * - Generates a random origin key\n * - Hashes the key using the configured crypto options\n * - Calculates an expiration time (if provided)\n * - Assigns versioning and rotation metadata\n * - Saves the generated key to storage\n * - The hashed key will follow this format: `salt-buffer:hashed`\n *\n * @param options Configuration for key generation\n * @param options.type Logical key type (e.g. api, session, encryption, etc.)\n * @param options.duration Optional lifetime value for the key\n * @param options.unit Time unit for the duration (seconds | minutes | hours | days)\n * @param options.rotate Whether this key should participate in key rotation\n * @param options.merge Whether to merge with an existing stored key (if supported)\n *\n * @param variables Optional variables used for dynamic path or filename resolution\n *\n * @returns An object containing:\n * - `key`: The generated key metadata and raw key value\n * - `path`: The storage path where the key was saved\n *\n * @example\n * ```ts\n * const { key, path } = await keyManager.newKey(\n * {\n * type: 'api',\n * duration: 30, <- Optional\n * unit: 'days', <- Optional\n * rotate: true, <- Optional\n * },\n * { env: 'production', ... }\n * );\n * ```\n */\n public async newKey(\n options: TGenerateKeyOptions,\n variables: TKeyVariables = {}\n ): Promise<{ key: TKeyGenerated; path: string }> {\n const { rotate, duration, type, unit, merge, keyLength } = options;\n\n const { key, length: kLength } = this.cryptoService.generateKey(keyLength);\n const { salt } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, salt);\n const now = new Date();\n\n const keyGenerated: TKeyGenerated = {\n from: now.toISOString(),\n to: duration && unit ? addDuration(now, duration, unit).toISOString() : 'NON_EXPIRED',\n key: key,\n hashed: hashedKey,\n hashedBytes: kLength,\n type,\n version: await executePromisably(this.kOptions.versionGenerator()),\n rotate: !!rotate,\n };\n\n const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);\n this.sysLog(`Key saved!`, {\n path,\n version: keyGenerated.version,\n type: keyGenerated.type,\n });\n\n return { key: keyGenerated, path };\n }\n\n private async getKeyByStore(path: string, version: string): Promise<TKeyGenerated | null> {\n if (this.getKeyFn) {\n return this.getKeyFn(path, version);\n }\n\n const savedData = await this.getKeyFileData(path);\n return savedData[version] ?? null;\n }\n\n private async saveKeyToStore(\n key: TKeyGenerated,\n merge: boolean,\n variables: TKeyVariables\n ): Promise<string> {\n return (this.saveKeyFn?.bind(this) ?? this.saveKeyFile.bind(this))(\n this.getFilename({ ...variables, version: key.version, type: key.type }),\n key,\n merge\n );\n }\n\n private validateKey(keyGenerated: Partial<TKeyGenerated>): {\n ok: boolean;\n message: string;\n errorOn?: keyof TKeyGenerated;\n isExpired?: boolean;\n isRenewable?: boolean;\n } {\n const requiredKeyGenerated = keyGenerated as TKeyGenerated;\n\n const typeChecks: Record<keyof TKeyGenerated, keyof ReturnType<typeof isType>> = {\n from: 'string',\n to: 'string',\n key: 'string',\n hashed: 'string',\n rotate: 'boolean',\n type: 'string',\n version: 'stringNumber',\n hashedBytes: 'number',\n };\n\n for (const [field, type] of Object.entries(typeChecks) as Array<\n [field: keyof TKeyGenerated, type: keyof ReturnType<typeof isType>]\n >) {\n if (!isType(requiredKeyGenerated[field])[type])\n return { ok: false, message: `${field} is not valid`, errorOn: field };\n }\n\n if (!isDate(requiredKeyGenerated.from)) {\n return { ok: false, message: 'From date is not valid!', errorOn: 'from' };\n } else if (new Date(requiredKeyGenerated.from) > new Date()) {\n return { ok: false, message: 'Key is not started!' };\n }\n\n if (!isDate(requiredKeyGenerated.to)) {\n if (requiredKeyGenerated.to !== 'NON_EXPIRED') {\n return { ok: false, message: 'Expire date is not valid!', errorOn: 'to' };\n }\n } else if (new Date(requiredKeyGenerated.to) < new Date()) {\n return {\n ok: false,\n message: 'Key is expired',\n errorOn: 'to',\n isExpired: true,\n isRenewable: !!requiredKeyGenerated.rotate,\n };\n }\n\n if (requiredKeyGenerated.hashedBytes < 0)\n return {\n ok: false,\n message: 'Invalid hashedBytes range',\n errorOn: 'hashedBytes',\n };\n\n return { ok: true, message: '' };\n }\n\n private getFilename(variables: TKeyVariables) {\n return bindString(\n bindString(`{{root}}/{{filename}}.{{ext}}`, {\n root: this.getPath(this.kOptions.path, '/'),\n filename: this.getPath(this.kOptions.file, this.kOptions.fileSplitor),\n ext: this.kOptions.fileExt,\n }),\n variables\n );\n }\n\n private runKeyHook<K extends keyof TKeyManagerHooks>(\n name: K,\n ...args: Parameters<TKeyManagerHooks[K]>\n ): ReturnType<TKeyManagerHooks[K]> {\n return this.runHook<TKeyManagerHooks, K>(name, ...args);\n }\n}\n","import { TModuleHooks, TModuleOptions } from 'src/types';\nimport { DEFAULT_MODULE_OPTIONS } from 'src/constants/default.constant';\nimport { KeyManager } from './key-manager.core';\n\nexport class KM extends KeyManager {\n private options: Required<TModuleOptions>;\n\n constructor(options: Partial<TModuleOptions>) {\n super(options);\n\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n }\n\n public setOptions(options: TModuleOptions): this {\n this.options = {\n ...DEFAULT_MODULE_OPTIONS,\n ...options,\n };\n return this;\n }\n\n public getOptions(): TModuleOptions | undefined {\n return this.options;\n }\n\n /**\n *\n * @param instance: use instance options to create new instance\n * @param extend: overide options\n * @returns new instance\n */\n public clone(extend: Partial<TModuleOptions> = {}): KM {\n const module = new KM({ ...this.getOptions(), ...extend });\n\n if (this.saveKeyFn) module.useSaveKey(this.saveKeyFn);\n if (this.getKeyFn) module.useGetKey(this.getKeyFn);\n if (this.storePath) module.useStorePath(this.storePath);\n\n module.setHooks(this.getHooks());\n module.setLogger(this.getLogger());\n\n return module;\n }\n\n public useHooks(hooks: Partial<{ [x in keyof TModuleHooks]: TModuleHooks[x] }>) {\n this.setHooks(hooks);\n return this;\n }\n\n public setHook<HookName extends keyof TModuleHooks>(\n name: HookName,\n handler: TModuleHooks[HookName]\n ) {\n this.setHooks({ [name]: handler });\n return this;\n }\n}\n","import { KM } from './core/module.core';\nimport * as types from './types';\nexport * from './types';\n\nlet instance: KM | null = null;\n\n/**\n * Create a new KeyManager instance\n * @param options - Options to configure the instance\n * @param singleton - If true, returns a shared singleton instance; if false, creates a new instance\n * @returns KM instance\n */\nexport const create = (\n options: Partial<types.TModuleOptions> = {},\n singleton: boolean = false\n): KM => {\n if (!singleton) return new KM(options);\n\n if (!instance) {\n instance = new KM(options);\n }\n\n return instance;\n};\n\n/**\n * @alias create()\n */\nexport const km = create;\nexport type { KM };\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "key-rotation-manager",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.1",
|
|
4
4
|
"description": "Simple, secure key rotation for Node.js",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -36,7 +36,6 @@
|
|
|
36
36
|
"node": ">=18.0.0"
|
|
37
37
|
},
|
|
38
38
|
"devDependencies": {
|
|
39
|
-
"@types/crypto-js": "^4.2.2",
|
|
40
39
|
"@types/node": "^18.19.74",
|
|
41
40
|
"@typescript-eslint/eslint-plugin": "^8.28.0",
|
|
42
41
|
"@typescript-eslint/parser": "^8.28.0",
|
|
@@ -45,8 +44,5 @@
|
|
|
45
44
|
"tsup": "^8.5.1",
|
|
46
45
|
"tsx": "^4.19.2",
|
|
47
46
|
"typescript": "^5.4.5"
|
|
48
|
-
},
|
|
49
|
-
"dependencies": {
|
|
50
|
-
"crypto-js": "^4.2.0"
|
|
51
47
|
}
|
|
52
48
|
}
|