key-rotation-manager 1.1.1 → 1.1.2

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 CHANGED
@@ -4,6 +4,8 @@
4
4
 
5
5
  A production-ready library for generating, storing, rotating, and retrieving cryptographic keys with support for expiration, versioning, merge strategies, custom storage logic, and lifecycle hooks.
6
6
 
7
+ **Key Rotation Manager** is a comprehensive Node.js library for secure cryptographic key management. It provides automatic key rotation, expiration handling, versioning, and flexible storage options. Perfect for API key management, token rotation, secret management, and credential handling in production applications.
8
+
7
9
  [![npm version](https://img.shields.io/npm/v/key-rotation-manager)](https://www.npmjs.com/package/key-rotation-manager)
8
10
  [![Node.js](https://img.shields.io/badge/node-%3E%3D18.0.0-brightgreen)](https://nodejs.org/)
9
11
  [![License](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
@@ -44,6 +46,8 @@ A production-ready library for generating, storing, rotating, and retrieving cry
44
46
  - 📡 **Event-Driven** - Lifecycle hooks for key events
45
47
  - 📁 **Git Integration** - Automatic `.gitignore` management
46
48
  - 🎯 **TypeScript** - Full TypeScript support with comprehensive types
49
+ - ⚡ **Zero Dependencies** - Uses native Node.js crypto module
50
+ - 🚀 **Production Ready** - Battle-tested for enterprise applications
47
51
 
48
52
  ---
49
53
 
@@ -55,6 +59,8 @@ npm install key-rotation-manager
55
59
 
56
60
  **Requirements:** Node.js >= 18.0.0
57
61
 
62
+ **Package:** [npmjs.com/package/key-rotation-manager](https://www.npmjs.com/package/key-rotation-manager)
63
+
58
64
  ---
59
65
 
60
66
  ## 🚀 Quick Start
@@ -562,6 +568,7 @@ Retrieves a key by path and version.
562
568
  - `options`: `TGetKeyOptions`
563
569
  - `path`: `string` - Storage path
564
570
  - `version`: `string` - Key version
571
+ - `disableHooks?`: `boolean` - Skip hook execution (default: `false`)
565
572
  - `onRotate?`: Rotation options (if key is expired and rotatable)
566
573
 
567
574
  **Returns:** `Promise<TGetKey>`
@@ -577,8 +584,45 @@ const result = await keyManager.getKey({
577
584
  rotate: true,
578
585
  },
579
586
  });
587
+
588
+ // With disabled hooks for performance
589
+ const result = await keyManager.getKey({
590
+ path: '/keys/api',
591
+ version: 'v1',
592
+ disableHooks: true,
593
+ });
594
+ ```
595
+
596
+ ### `verifyKey(hashedKey, path, version, disableGetKeyHooks?)`
597
+
598
+ Verifies a hashed key against a stored key.
599
+
600
+ **Parameters:**
601
+ - `hashedKey`: `string` - The hashed key to verify
602
+ - `path`: `string` - Storage path
603
+ - `version`: `string | number` - Key version
604
+ - `disableGetKeyHooks?`: `boolean` - Disable hooks in getKey call (default: `true`)
605
+
606
+ **Returns:** `Promise<boolean>`
607
+
608
+ **Example:**
609
+ ```typescript
610
+ const isValid = await keyManager.verifyKey(hashedKey, '/keys/api', 'v1');
611
+ if (isValid) {
612
+ console.log('Key is valid!');
613
+ } else {
614
+ console.log('Key is invalid!');
615
+ }
616
+
617
+ // Verification with hooks enabled
618
+ const isValid = await keyManager.verifyKey(hashedKey, '/keys/api', 'v1', false);
580
619
  ```
581
620
 
621
+ **Notes:**
622
+ - Uses PBKDF2 verification if the key has a `secret` field
623
+ - Falls back to direct hash comparison otherwise
624
+ - Verifies against expired keys if no ready key is available
625
+
582
626
  ### `useHooks(hooks)`
583
627
 
584
628
  Sets multiple hooks at once.
@@ -602,12 +646,16 @@ Sets a single hook.
602
646
 
603
647
  ## 🎯 Use Cases
604
648
 
605
- - **API Key Management** - Secure storage and rotation of API keys
606
- - **Token Rotation** - Automatic credential rotation for services
607
- - **Secret Management** - File-based secret storage with expiration
608
- - **Multi-Version Keys** - Support for multiple key versions simultaneously
609
- - **Custom Persistence** - Integrate with databases or cloud storage
610
- - **Backend Services** - Production-ready key management for Node.js applications
649
+ - **API Key Management** - Secure storage and rotation of API keys for third-party services
650
+ - **Token Rotation** - Automatic credential rotation for OAuth tokens, JWT secrets, and access tokens
651
+ - **Secret Management** - File-based secret storage with expiration for application secrets
652
+ - **Multi-Version Keys** - Support for multiple key versions simultaneously during rotation periods
653
+ - **Custom Persistence** - Integrate with databases, cloud storage, or key management services
654
+ - **Backend Services** - Production-ready key management for Node.js applications and microservices
655
+ - **Encryption Keys** - Manage encryption keys for data protection with automatic rotation
656
+ - **Session Keys** - Rotate session encryption keys periodically for enhanced security
657
+ - **Database Credentials** - Rotate database passwords and connection strings securely
658
+ - **Service-to-Service Authentication** - Manage keys for inter-service communication
611
659
 
612
660
  ---
613
661
 
@@ -615,6 +663,7 @@ Sets a single hook.
615
663
 
616
664
  See the full changelog for each version:
617
665
 
666
+ - **[v1.1.2](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.1.2.md)** - Key verification, hook control, enhanced documentation
618
667
  - **[v1.1.1](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.1.1.md)** - Native crypto, zero dependencies, bug fixes
619
668
  - **[v1.0.10](https://github.com/DucAnh2611/key-rotation-manager/tree/master/changelogs/1.0.10.md)** - Hooks system, enhanced gitIgnore configuration
620
669
 
@@ -653,4 +702,24 @@ This project is licensed under the MIT License - see the [LICENSE](https://githu
653
702
 
654
703
  ---
655
704
 
705
+ ## 🔍 Search Keywords
706
+
707
+ This package is optimized for searches related to:
708
+ - key rotation
709
+ - key management
710
+ - cryptographic key storage
711
+ - API key rotation
712
+ - secret rotation
713
+ - credential management
714
+ - token rotation
715
+ - key versioning
716
+ - automatic key rotation
717
+ - secure key storage
718
+ - Node.js key management
719
+ - TypeScript key management
720
+ - production key rotation
721
+ - enterprise key management
722
+
723
+ ---
724
+
656
725
  **Made with ❤️ for secure key management**
package/dist/index.cjs CHANGED
@@ -187,7 +187,10 @@ var isType = (data) => {
187
187
  stringNumber: typeof data === "string" || typeof data === "number",
188
188
  boolean: typeof data === "boolean",
189
189
  null: data === null,
190
- undefined: data === void 0
190
+ undefined: data === void 0,
191
+ optionalNumber: typeof data === "undefined" || typeof data === "number" && !Number.isNaN(Number(data)),
192
+ optionalString: typeof data === "undefined" || typeof data === "string",
193
+ optionalStringNumber: typeof data === "undefined" || typeof data === "string" || typeof data === "number"
191
194
  };
192
195
  };
193
196
  var CryptoService = class {
@@ -638,33 +641,33 @@ var KeyManager = class extends Store {
638
641
  const { path, version } = options;
639
642
  const key = await this.getKeyByStore(path, String(version));
640
643
  if (!key) {
641
- this.runKeyHook("onKeyNotFound", path, version);
644
+ if (!options.disableHooks) this.runKeyHook("onKeyNotFound", path, version);
642
645
  this.sysLog(`Key not found!`, { path, version });
643
646
  return { expired: null, ready: null };
644
647
  }
645
648
  const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);
646
649
  if (!ok && isExpired && isRenewable && key) {
647
650
  if (!options.onRotate) {
648
- this.runKeyHook("onKeyMissingRotateOption", key, options);
651
+ if (!options.disableHooks) this.runKeyHook("onKeyMissingRotateOption", key, options);
649
652
  this.sysLog(`Key missing rotate option!`, { path, version });
650
- return { expired: null, ready: null };
653
+ return { expired: key, ready: null };
651
654
  }
652
655
  const renew = await this.newKey({
653
656
  type: key.type,
654
657
  ...options.onRotate
655
658
  });
656
659
  const resGetKey = { expired: key, ready: renew.key };
657
- this.runKeyHook("onKeyRenewed", resGetKey, options);
660
+ if (!options.disableHooks) this.runKeyHook("onKeyRenewed", resGetKey, options);
658
661
  this.sysLog(`Key renewed!`, { path, version });
659
662
  return resGetKey;
660
663
  }
661
664
  if (!ok && isExpired && !isRenewable && key) {
662
- this.runKeyHook("onKeyExpired", path, key);
665
+ if (!options.disableHooks) this.runKeyHook("onKeyExpired", path, key);
663
666
  this.sysLog(`Key expired!`, { path, version });
664
667
  return { expired: key, ready: null };
665
668
  }
666
669
  if (!ok) {
667
- this.runKeyHook("onKeyInvalid", key, message, errorOn);
670
+ if (!options.disableHooks) this.runKeyHook("onKeyInvalid", key, message, errorOn);
668
671
  this.sysLog(`Key invalid!`, { path, version });
669
672
  return { expired: null, ready: null };
670
673
  }
@@ -710,15 +713,16 @@ var KeyManager = class extends Store {
710
713
  async newKey(options, variables = {}) {
711
714
  const { rotate, duration, type, unit, merge, keyLength } = options;
712
715
  const { key, length: kLength } = this.cryptoService.generateKey(keyLength);
713
- const { salt } = this.cryptoService.generateSalt();
716
+ const { salt: secret } = this.cryptoService.generateSalt();
714
717
  this.sysLog(`Key generated
715
718
  Options:`, options);
716
- const hashedKey = this.cryptoService.hash(key, salt);
719
+ const hashedKey = this.cryptoService.hash(key, secret);
717
720
  const now = /* @__PURE__ */ new Date();
718
721
  const keyGenerated = {
719
722
  from: now.toISOString(),
720
723
  to: duration && unit ? addDuration(now, duration, unit).toISOString() : "NON_EXPIRED",
721
724
  key,
725
+ secret,
722
726
  hashed: hashedKey,
723
727
  hashedBytes: kLength,
724
728
  type,
@@ -733,6 +737,49 @@ Options:`, options);
733
737
  });
734
738
  return { key: keyGenerated, path };
735
739
  }
740
+ /**
741
+ * Verify a key by hashed key and path and version
742
+ * @param hashedKey Hashed key to verify
743
+ * @param path Path to the key
744
+ * @param version Version of the key
745
+ * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
746
+ * @returns True if the key is valid, false otherwise
747
+ *
748
+ * @example
749
+ * ```ts
750
+ * const isValid = await keyManager.verifyKey(hashedKey, path, version);
751
+ * if (isValid) {
752
+ * console.log('Key is valid!');
753
+ * } else {
754
+ * console.log('Key is invalid!');
755
+ * }
756
+ * ```
757
+ *
758
+ * @note
759
+ * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
760
+ *
761
+ * 2. Get key from store
762
+ * - If the key is expired, the expired key will be used to verify the key
763
+ * - If the key is not expired, the ready key will be used to verify the key
764
+ *
765
+ * 3. If the key is not found, the function will return false
766
+ *
767
+ * 4. Verify key strategy
768
+ * - If the key is found and secret is provided, compare original key with hashed key using secret
769
+ * - If the key is found and secret is not provided, compare original key with hashed key
770
+ *
771
+ */
772
+ async verifyKey(hashedKey, path, version, disableGetKeyHooks = true) {
773
+ const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });
774
+ if (!ready && !expired) {
775
+ this.sysLog(`Key not found to verify!`, { path, version });
776
+ return false;
777
+ }
778
+ const key = expired ?? ready;
779
+ this.sysLog("Verifying key...", { hashedKey, path, version, validateMethod: key.secret ? "verifyHash(key, hashedKey, secret)" : "hashedKey === key.hashed" });
780
+ if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);
781
+ return hashedKey === key.hashed;
782
+ }
736
783
  async getKeyByStore(path, version) {
737
784
  if (this.getKeyFn) {
738
785
  return this.getKeyFn(path, version);
@@ -757,7 +804,8 @@ Options:`, options);
757
804
  rotate: "boolean",
758
805
  type: "string",
759
806
  version: "stringNumber",
760
- hashedBytes: "number"
807
+ hashedBytes: "number",
808
+ secret: "optionalString"
761
809
  };
762
810
  for (const [field, type] of Object.entries(typeChecks)) {
763
811
  if (!isType(requiredKeyGenerated[field])[type])
@@ -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","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"]}
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":"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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: typeof data === 'string' || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n optionalNumber: typeof data === \"undefined\" || (typeof data === 'number' && !Number.isNaN(Number(data))),\n optionalString: typeof data === \"undefined\" || typeof data === 'string',\n optionalStringNumber: typeof data === \"undefined\" || typeof data === 'string' || typeof data === 'number',\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 if (!options.disableHooks) 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 if (!options.disableHooks) this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: key, 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 if (!options.disableHooks) this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n if (!options.disableHooks) this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n if (!options.disableHooks) 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: secret } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, secret);\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 secret: secret,\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 /**\n * Verify a key by hashed key and path and version\n * @param hashedKey Hashed key to verify\n * @param path Path to the key\n * @param version Version of the key\n * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method\n * @returns True if the key is valid, false otherwise\n * \n * @example\n * ```ts\n * const isValid = await keyManager.verifyKey(hashedKey, path, version);\n * if (isValid) {\n * console.log('Key is valid!');\n * } else {\n * console.log('Key is invalid!');\n * }\n * ```\n * \n * @note\n * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true \n * \n * 2. Get key from store\n * - If the key is expired, the expired key will be used to verify the key\n * - If the key is not expired, the ready key will be used to verify the key\n * \n * 3. If the key is not found, the function will return false\n * \n * 4. Verify key strategy\n * - If the key is found and secret is provided, compare original key with hashed key using secret\n * - If the key is found and secret is not provided, compare original key with hashed key\n * \n */\n public async verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks: boolean = true): Promise<boolean> {\n const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });\n\n if (!ready && !expired) {\n this.sysLog(`Key not found to verify!`, { path, version });\n return false;\n }\n\n // if expire -> expired key, if not expire -> ready key\n // case both key appear when onRotate options is set\n const key = (expired ?? ready) as TKeyGenerated;\n\n this.sysLog('Verifying key...', { hashedKey, path, version, validateMethod: key.secret ? 'verifyHash(key, hashedKey, secret)' : 'hashedKey === key.hashed' });\n if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);\n\n return hashedKey === key.hashed;\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 secret: 'optionalString',\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.d.cts CHANGED
@@ -169,6 +169,7 @@ type TGetKey = {
169
169
  type TGetKeyOptions = {
170
170
  path: string;
171
171
  version: string;
172
+ disableHooks?: boolean;
172
173
  onRotate?: Omit<Required<TGenerateKeyOptions>, 'type' | 'keyLength' | 'merge'> & Pick<TGenerateKeyOptions, 'keyLength' | 'merge'>;
173
174
  };
174
175
  type TKeyManagerHooks = {
@@ -250,6 +251,10 @@ type TKeyGenerated = {
250
251
  * Auto renew on expired
251
252
  */
252
253
  rotate: boolean;
254
+ /**
255
+ * Secret used to hash the key
256
+ */
257
+ secret?: string;
253
258
  };
254
259
  type TKeyPrimitive = string | number;
255
260
  type TKeyVariablesData = TKeyPrimitive | TKeyPrimitive[];
@@ -450,6 +455,39 @@ declare class KeyManager extends Store {
450
455
  key: TKeyGenerated;
451
456
  path: string;
452
457
  }>;
458
+ /**
459
+ * Verify a key by hashed key and path and version
460
+ * @param hashedKey Hashed key to verify
461
+ * @param path Path to the key
462
+ * @param version Version of the key
463
+ * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
464
+ * @returns True if the key is valid, false otherwise
465
+ *
466
+ * @example
467
+ * ```ts
468
+ * const isValid = await keyManager.verifyKey(hashedKey, path, version);
469
+ * if (isValid) {
470
+ * console.log('Key is valid!');
471
+ * } else {
472
+ * console.log('Key is invalid!');
473
+ * }
474
+ * ```
475
+ *
476
+ * @note
477
+ * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
478
+ *
479
+ * 2. Get key from store
480
+ * - If the key is expired, the expired key will be used to verify the key
481
+ * - If the key is not expired, the ready key will be used to verify the key
482
+ *
483
+ * 3. If the key is not found, the function will return false
484
+ *
485
+ * 4. Verify key strategy
486
+ * - If the key is found and secret is provided, compare original key with hashed key using secret
487
+ * - If the key is found and secret is not provided, compare original key with hashed key
488
+ *
489
+ */
490
+ verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks?: boolean): Promise<boolean>;
453
491
  private getKeyByStore;
454
492
  private saveKeyToStore;
455
493
  private validateKey;
package/dist/index.d.ts CHANGED
@@ -169,6 +169,7 @@ type TGetKey = {
169
169
  type TGetKeyOptions = {
170
170
  path: string;
171
171
  version: string;
172
+ disableHooks?: boolean;
172
173
  onRotate?: Omit<Required<TGenerateKeyOptions>, 'type' | 'keyLength' | 'merge'> & Pick<TGenerateKeyOptions, 'keyLength' | 'merge'>;
173
174
  };
174
175
  type TKeyManagerHooks = {
@@ -250,6 +251,10 @@ type TKeyGenerated = {
250
251
  * Auto renew on expired
251
252
  */
252
253
  rotate: boolean;
254
+ /**
255
+ * Secret used to hash the key
256
+ */
257
+ secret?: string;
253
258
  };
254
259
  type TKeyPrimitive = string | number;
255
260
  type TKeyVariablesData = TKeyPrimitive | TKeyPrimitive[];
@@ -450,6 +455,39 @@ declare class KeyManager extends Store {
450
455
  key: TKeyGenerated;
451
456
  path: string;
452
457
  }>;
458
+ /**
459
+ * Verify a key by hashed key and path and version
460
+ * @param hashedKey Hashed key to verify
461
+ * @param path Path to the key
462
+ * @param version Version of the key
463
+ * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
464
+ * @returns True if the key is valid, false otherwise
465
+ *
466
+ * @example
467
+ * ```ts
468
+ * const isValid = await keyManager.verifyKey(hashedKey, path, version);
469
+ * if (isValid) {
470
+ * console.log('Key is valid!');
471
+ * } else {
472
+ * console.log('Key is invalid!');
473
+ * }
474
+ * ```
475
+ *
476
+ * @note
477
+ * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
478
+ *
479
+ * 2. Get key from store
480
+ * - If the key is expired, the expired key will be used to verify the key
481
+ * - If the key is not expired, the ready key will be used to verify the key
482
+ *
483
+ * 3. If the key is not found, the function will return false
484
+ *
485
+ * 4. Verify key strategy
486
+ * - If the key is found and secret is provided, compare original key with hashed key using secret
487
+ * - If the key is found and secret is not provided, compare original key with hashed key
488
+ *
489
+ */
490
+ verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks?: boolean): Promise<boolean>;
453
491
  private getKeyByStore;
454
492
  private saveKeyToStore;
455
493
  private validateKey;
package/dist/index.js CHANGED
@@ -181,7 +181,10 @@ var isType = (data) => {
181
181
  stringNumber: typeof data === "string" || typeof data === "number",
182
182
  boolean: typeof data === "boolean",
183
183
  null: data === null,
184
- undefined: data === void 0
184
+ undefined: data === void 0,
185
+ optionalNumber: typeof data === "undefined" || typeof data === "number" && !Number.isNaN(Number(data)),
186
+ optionalString: typeof data === "undefined" || typeof data === "string",
187
+ optionalStringNumber: typeof data === "undefined" || typeof data === "string" || typeof data === "number"
185
188
  };
186
189
  };
187
190
  var CryptoService = class {
@@ -632,33 +635,33 @@ var KeyManager = class extends Store {
632
635
  const { path, version } = options;
633
636
  const key = await this.getKeyByStore(path, String(version));
634
637
  if (!key) {
635
- this.runKeyHook("onKeyNotFound", path, version);
638
+ if (!options.disableHooks) this.runKeyHook("onKeyNotFound", path, version);
636
639
  this.sysLog(`Key not found!`, { path, version });
637
640
  return { expired: null, ready: null };
638
641
  }
639
642
  const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);
640
643
  if (!ok && isExpired && isRenewable && key) {
641
644
  if (!options.onRotate) {
642
- this.runKeyHook("onKeyMissingRotateOption", key, options);
645
+ if (!options.disableHooks) this.runKeyHook("onKeyMissingRotateOption", key, options);
643
646
  this.sysLog(`Key missing rotate option!`, { path, version });
644
- return { expired: null, ready: null };
647
+ return { expired: key, ready: null };
645
648
  }
646
649
  const renew = await this.newKey({
647
650
  type: key.type,
648
651
  ...options.onRotate
649
652
  });
650
653
  const resGetKey = { expired: key, ready: renew.key };
651
- this.runKeyHook("onKeyRenewed", resGetKey, options);
654
+ if (!options.disableHooks) this.runKeyHook("onKeyRenewed", resGetKey, options);
652
655
  this.sysLog(`Key renewed!`, { path, version });
653
656
  return resGetKey;
654
657
  }
655
658
  if (!ok && isExpired && !isRenewable && key) {
656
- this.runKeyHook("onKeyExpired", path, key);
659
+ if (!options.disableHooks) this.runKeyHook("onKeyExpired", path, key);
657
660
  this.sysLog(`Key expired!`, { path, version });
658
661
  return { expired: key, ready: null };
659
662
  }
660
663
  if (!ok) {
661
- this.runKeyHook("onKeyInvalid", key, message, errorOn);
664
+ if (!options.disableHooks) this.runKeyHook("onKeyInvalid", key, message, errorOn);
662
665
  this.sysLog(`Key invalid!`, { path, version });
663
666
  return { expired: null, ready: null };
664
667
  }
@@ -704,15 +707,16 @@ var KeyManager = class extends Store {
704
707
  async newKey(options, variables = {}) {
705
708
  const { rotate, duration, type, unit, merge, keyLength } = options;
706
709
  const { key, length: kLength } = this.cryptoService.generateKey(keyLength);
707
- const { salt } = this.cryptoService.generateSalt();
710
+ const { salt: secret } = this.cryptoService.generateSalt();
708
711
  this.sysLog(`Key generated
709
712
  Options:`, options);
710
- const hashedKey = this.cryptoService.hash(key, salt);
713
+ const hashedKey = this.cryptoService.hash(key, secret);
711
714
  const now = /* @__PURE__ */ new Date();
712
715
  const keyGenerated = {
713
716
  from: now.toISOString(),
714
717
  to: duration && unit ? addDuration(now, duration, unit).toISOString() : "NON_EXPIRED",
715
718
  key,
719
+ secret,
716
720
  hashed: hashedKey,
717
721
  hashedBytes: kLength,
718
722
  type,
@@ -727,6 +731,49 @@ Options:`, options);
727
731
  });
728
732
  return { key: keyGenerated, path };
729
733
  }
734
+ /**
735
+ * Verify a key by hashed key and path and version
736
+ * @param hashedKey Hashed key to verify
737
+ * @param path Path to the key
738
+ * @param version Version of the key
739
+ * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method
740
+ * @returns True if the key is valid, false otherwise
741
+ *
742
+ * @example
743
+ * ```ts
744
+ * const isValid = await keyManager.verifyKey(hashedKey, path, version);
745
+ * if (isValid) {
746
+ * console.log('Key is valid!');
747
+ * } else {
748
+ * console.log('Key is invalid!');
749
+ * }
750
+ * ```
751
+ *
752
+ * @note
753
+ * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true
754
+ *
755
+ * 2. Get key from store
756
+ * - If the key is expired, the expired key will be used to verify the key
757
+ * - If the key is not expired, the ready key will be used to verify the key
758
+ *
759
+ * 3. If the key is not found, the function will return false
760
+ *
761
+ * 4. Verify key strategy
762
+ * - If the key is found and secret is provided, compare original key with hashed key using secret
763
+ * - If the key is found and secret is not provided, compare original key with hashed key
764
+ *
765
+ */
766
+ async verifyKey(hashedKey, path, version, disableGetKeyHooks = true) {
767
+ const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });
768
+ if (!ready && !expired) {
769
+ this.sysLog(`Key not found to verify!`, { path, version });
770
+ return false;
771
+ }
772
+ const key = expired ?? ready;
773
+ this.sysLog("Verifying key...", { hashedKey, path, version, validateMethod: key.secret ? "verifyHash(key, hashedKey, secret)" : "hashedKey === key.hashed" });
774
+ if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);
775
+ return hashedKey === key.hashed;
776
+ }
730
777
  async getKeyByStore(path, version) {
731
778
  if (this.getKeyFn) {
732
779
  return this.getKeyFn(path, version);
@@ -751,7 +798,8 @@ Options:`, options);
751
798
  rotate: "boolean",
752
799
  type: "string",
753
800
  version: "stringNumber",
754
- hashedBytes: "number"
801
+ hashedBytes: "number",
802
+ secret: "optionalString"
755
803
  };
756
804
  for (const [field, type] of Object.entries(typeChecks)) {
757
805
  if (!isType(requiredKeyGenerated[field])[type])
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: 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"]}
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: typeof data === 'string' || typeof data === 'number',\n boolean: typeof data === 'boolean',\n null: data === null,\n undefined: data === undefined,\n optionalNumber: typeof data === \"undefined\" || (typeof data === 'number' && !Number.isNaN(Number(data))),\n optionalString: typeof data === \"undefined\" || typeof data === 'string',\n optionalStringNumber: typeof data === \"undefined\" || typeof data === 'string' || typeof data === 'number',\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 if (!options.disableHooks) 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 if (!options.disableHooks) this.runKeyHook('onKeyMissingRotateOption', key, options);\n this.sysLog(`Key missing rotate option!`, { path, version });\n return { expired: key, 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 if (!options.disableHooks) this.runKeyHook('onKeyRenewed', resGetKey, options);\n this.sysLog(`Key renewed!`, { path, version });\n return resGetKey;\n }\n\n if (!ok && isExpired && !isRenewable && key) {\n if (!options.disableHooks) this.runKeyHook('onKeyExpired', path, key);\n this.sysLog(`Key expired!`, { path, version });\n return { expired: key, ready: null };\n }\n\n if (!ok) {\n if (!options.disableHooks) 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: secret } = this.cryptoService.generateSalt();\n\n this.sysLog(`Key generated\\nOptions:`, options);\n\n const hashedKey = this.cryptoService.hash(key, secret);\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 secret: secret,\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 /**\n * Verify a key by hashed key and path and version\n * @param hashedKey Hashed key to verify\n * @param path Path to the key\n * @param version Version of the key\n * @param disableGetKeyHooks Disable getKey method hooks, should not use hooks in this method\n * @returns True if the key is valid, false otherwise\n * \n * @example\n * ```ts\n * const isValid = await keyManager.verifyKey(hashedKey, path, version);\n * if (isValid) {\n * console.log('Key is valid!');\n * } else {\n * console.log('Key is invalid!');\n * }\n * ```\n * \n * @note\n * 1. This use getKey method to get key, so disableGetKeyHooks option is set to true, if disableGetKeyHooks is not provided, it will be set to true \n * \n * 2. Get key from store\n * - If the key is expired, the expired key will be used to verify the key\n * - If the key is not expired, the ready key will be used to verify the key\n * \n * 3. If the key is not found, the function will return false\n * \n * 4. Verify key strategy\n * - If the key is found and secret is provided, compare original key with hashed key using secret\n * - If the key is found and secret is not provided, compare original key with hashed key\n * \n */\n public async verifyKey(hashedKey: string, path: string, version: string | number, disableGetKeyHooks: boolean = true): Promise<boolean> {\n const { ready, expired } = await this.getKey({ path, version: String(version), disableHooks: disableGetKeyHooks });\n\n if (!ready && !expired) {\n this.sysLog(`Key not found to verify!`, { path, version });\n return false;\n }\n\n // if expire -> expired key, if not expire -> ready key\n // case both key appear when onRotate options is set\n const key = (expired ?? ready) as TKeyGenerated;\n\n this.sysLog('Verifying key...', { hashedKey, path, version, validateMethod: key.secret ? 'verifyHash(key, hashedKey, secret)' : 'hashedKey === key.hashed' });\n if (key.secret) return this.cryptoService.verifyHash(key.key, hashedKey, key.secret);\n\n return hashedKey === key.hashed;\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 secret: 'optionalString',\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,7 +1,7 @@
1
1
  {
2
2
  "name": "key-rotation-manager",
3
- "version": "1.1.1",
4
- "description": "Simple, secure key rotation for Node.js",
3
+ "version": "1.1.2",
4
+ "description": "Production-ready cryptographic key management library for Node.js with automatic rotation, expiration, versioning, and flexible storage. Supports AES-256-CBC encryption, PBKDF2 key derivation, file-based storage, custom hooks, and TypeScript.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
7
7
  "module": "./dist/index.js",
@@ -27,11 +27,26 @@
27
27
  "prepublishOnly": "npm run build"
28
28
  },
29
29
  "keywords": [
30
+ "key-rotation",
31
+ "key-management",
32
+ "secret-management",
33
+ "api-key-rotation",
34
+ "credential-management",
35
+ "encryption",
36
+ "cryptography",
30
37
  "typescript",
31
- "module"
38
+ "nodejs"
32
39
  ],
33
40
  "author": "Duco",
34
41
  "license": "MIT",
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "https://github.com/DucAnh2611/key-rotation-manager.git"
45
+ },
46
+ "homepage": "https://github.com/DucAnh2611/key-rotation-manager#readme",
47
+ "bugs": {
48
+ "url": "https://github.com/DucAnh2611/key-rotation-manager/issues"
49
+ },
35
50
  "engines": {
36
51
  "node": ">=18.0.0"
37
52
  },