key-rotation-manager 1.0.10 → 1.0.11

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
@@ -521,13 +521,13 @@ const cloned = original.clone({
521
521
 
522
522
  ## 📖 API Reference
523
523
 
524
- ### `create(options?, only?)`
524
+ ### `create(options?, singleton?)`
525
525
 
526
526
  Creates a new KeyManager instance.
527
527
 
528
528
  **Parameters:**
529
529
  - `options` (optional): Partial `TModuleOptions`
530
- - `only` (optional): `boolean` - If `false`, returns a singleton instance
530
+ - `singleton` (optional): `boolean` - If `true`, returns a shared singleton instance (default: `false`)
531
531
 
532
532
  **Returns:** `KM` instance
533
533
 
@@ -535,7 +535,7 @@ Creates a new KeyManager instance.
535
535
  ```typescript
536
536
  const km = create({ versionGenerator: () => 'v1' });
537
537
  // or
538
- const km = create({}, false); // Singleton instance
538
+ const km = create({}, true); // Singleton instance
539
539
  ```
540
540
 
541
541
  ### `newKey(options, variables?)`
package/dist/index.cjs CHANGED
@@ -1,14 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var EventEmitter = require('events');
4
3
  var promises = require('fs/promises');
5
4
  var path = require('path');
6
5
  var CryptoJS = require('crypto-js');
6
+ var EventEmitter = require('events');
7
7
 
8
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
9
9
 
10
- var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
11
10
  var CryptoJS__default = /*#__PURE__*/_interopDefault(CryptoJS);
11
+ var EventEmitter__default = /*#__PURE__*/_interopDefault(EventEmitter);
12
12
 
13
13
  // src/constants/default.constant.ts
14
14
  var DEFAULT_CRYPTO_OPTIONS = {
@@ -59,99 +59,6 @@ var EEvent = /* @__PURE__ */ ((EEvent2) => {
59
59
  return EEvent2;
60
60
  })(EEvent || {});
61
61
 
62
- // src/types/module.types.ts
63
- var EError = /* @__PURE__ */ ((EError2) => {
64
- return EError2;
65
- })(EError || {});
66
-
67
- // src/core/base.core.ts
68
- var Base = class {
69
- logger;
70
- bOptions;
71
- hooks = /* @__PURE__ */ new Map();
72
- constructor(options) {
73
- this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };
74
- this.logger = DEFAULT_BASE_LOGGER;
75
- }
76
- getLogger() {
77
- return this.logger;
78
- }
79
- setLogger(logger) {
80
- this.logger = logger;
81
- return this;
82
- }
83
- async sysLog(...args) {
84
- if (!this.bOptions.quiet) await this.logger(...args);
85
- return this;
86
- }
87
- async customLog(logger, ...args) {
88
- await logger(...args);
89
- return this;
90
- }
91
- setHooks(hooks) {
92
- Object.entries(hooks).forEach(([name, handler]) => {
93
- if (this.hooks.has(name)) {
94
- this.hooks.get("onHookOverriding")?.call(this, name);
95
- }
96
- this.hooks.set(name, handler);
97
- });
98
- return this;
99
- }
100
- runHook(name, ...args) {
101
- if (!this.hooks.has(name)) {
102
- this.hooks.get("onHookNotFound")?.call(this, name);
103
- return void 0;
104
- }
105
- return this.hooks.get(name).call(this, ...args);
106
- }
107
- getHooks() {
108
- return Object.fromEntries(this.hooks.entries());
109
- }
110
- };
111
-
112
- // src/core/events.core.ts
113
- var Events = class extends Base {
114
- events;
115
- eOptions;
116
- constructor(options) {
117
- super(options);
118
- this.eOptions = {
119
- ...DEFAULT_EVENTS_OPTIONS,
120
- ...options
121
- };
122
- if (this.eOptions.useEvent) {
123
- this.events = new EventEmitter__default.default();
124
- }
125
- }
126
- emit(event, args) {
127
- if (!this.events) return this;
128
- this.events.emit(event, args);
129
- return this;
130
- }
131
- on(event, listener) {
132
- if (!this.events) return this;
133
- this.events.on(event, listener);
134
- return this;
135
- }
136
- once(event, listener) {
137
- if (!this.events) return this;
138
- this.events.once(event, listener);
139
- return this;
140
- }
141
- off(event, listener) {
142
- if (!this.events) return this;
143
- this.events.off(event, listener);
144
- return this;
145
- }
146
- };
147
-
148
- // src/core/config-events.core.ts
149
- var ConfigEvents = class extends Events {
150
- constructor(options) {
151
- super(options);
152
- }
153
- };
154
-
155
62
  // src/utils/promise.util.ts
156
63
  var executePromisably = (promiseOrFn) => {
157
64
  try {
@@ -161,35 +68,45 @@ var executePromisably = (promiseOrFn) => {
161
68
  return Promise.reject(error);
162
69
  }
163
70
  };
71
+ var FileUtilError = class extends Error {
72
+ constructor(message, path, operation, cause) {
73
+ super(message);
74
+ this.path = path;
75
+ this.operation = operation;
76
+ this.cause = cause;
77
+ this.name = "FileUtilError";
78
+ }
79
+ };
164
80
  var FileUtil = class {
165
81
  async getFolder(path) {
166
82
  try {
83
+ await promises.access(path);
84
+ return path;
85
+ } catch {
167
86
  try {
168
- await promises.access(path);
169
- } catch {
170
87
  await promises.mkdir(path, { recursive: true });
88
+ return path;
89
+ } catch (error) {
90
+ throw new FileUtilError(`Failed to create folder: ${path}`, path, "mkdir", error);
171
91
  }
172
- return path;
173
- } catch {
174
- throw new Error(`Failed to get folder: ${path}`);
175
92
  }
176
93
  }
177
- async read(path, fallback = "") {
94
+ async read(path, fallback) {
178
95
  try {
179
96
  const data = await promises.readFile(path, { encoding: "utf8" });
180
97
  return data;
181
98
  } catch (error) {
182
- if (fallback) return fallback;
183
- throw error;
99
+ if (fallback !== void 0) return fallback;
100
+ throw new FileUtilError(`Failed to read file: ${path}`, path, "read", error);
184
101
  }
185
102
  }
186
103
  async write(path$1, data, flag = "w") {
104
+ const dir = path.dirname(path$1);
105
+ await this.getFolder(dir);
187
106
  try {
188
- const dir = path.dirname(path$1);
189
- await this.getFolder(dir);
190
107
  await promises.writeFile(path$1, data, { encoding: "utf8", flag });
191
108
  } catch (error) {
192
- throw new Error(`Failed to write file: ${path$1}`);
109
+ throw new FileUtilError(`Failed to write file: ${path$1}`, path$1, "write", error);
193
110
  }
194
111
  }
195
112
  async checkExists(path) {
@@ -197,14 +114,14 @@ var FileUtil = class {
197
114
  await promises.access(path);
198
115
  return true;
199
116
  } catch {
200
- throw new Error(`Failed to check existence of file: ${path}`);
117
+ return false;
201
118
  }
202
119
  }
203
120
  async delete(path) {
204
121
  try {
205
122
  await promises.unlink(path);
206
- } catch {
207
- throw new Error(`Failed to delete file: ${path}`);
123
+ } catch (error) {
124
+ throw new FileUtilError(`Failed to delete file: ${path}`, path, "delete", error);
208
125
  }
209
126
  }
210
127
  };
@@ -476,7 +393,96 @@ var CryptoService = class {
476
393
  return hashStr === expectedHashStr;
477
394
  }
478
395
  };
479
- var Store = class extends ConfigEvents {
396
+
397
+ // src/core/base.core.ts
398
+ var Base = class {
399
+ logger;
400
+ bOptions;
401
+ hooks = /* @__PURE__ */ new Map();
402
+ constructor(options) {
403
+ this.bOptions = { ...DEFAULT_BASE_OPTIONS, ...options };
404
+ this.logger = DEFAULT_BASE_LOGGER;
405
+ }
406
+ getLogger() {
407
+ return this.logger;
408
+ }
409
+ setLogger(logger) {
410
+ this.logger = logger;
411
+ return this;
412
+ }
413
+ sysLog(...args) {
414
+ if (!this.bOptions.quiet) {
415
+ const result = this.logger(...args);
416
+ if (result && typeof result === "object" && "catch" in result) {
417
+ result.catch(() => {
418
+ });
419
+ }
420
+ }
421
+ return this;
422
+ }
423
+ async customLog(logger, ...args) {
424
+ await logger(...args);
425
+ return this;
426
+ }
427
+ setHooks(hooks) {
428
+ Object.entries(hooks).forEach(([name, handler]) => {
429
+ if (this.hooks.has(name)) {
430
+ this.hooks.get("onHookOverriding")?.call(this, name);
431
+ }
432
+ this.hooks.set(name, handler);
433
+ });
434
+ return this;
435
+ }
436
+ runHook(name, ...args) {
437
+ if (!this.hooks.has(name)) {
438
+ this.hooks.get("onHookNotFound")?.call(this, name);
439
+ return void 0;
440
+ }
441
+ return this.hooks.get(name).call(this, ...args);
442
+ }
443
+ getHooks() {
444
+ return Object.fromEntries(this.hooks.entries());
445
+ }
446
+ };
447
+
448
+ // src/core/events.core.ts
449
+ var Events = class extends Base {
450
+ events;
451
+ eOptions;
452
+ constructor(options) {
453
+ super(options);
454
+ this.eOptions = {
455
+ ...DEFAULT_EVENTS_OPTIONS,
456
+ ...options
457
+ };
458
+ if (this.eOptions.useEvent) {
459
+ this.events = new EventEmitter__default.default();
460
+ }
461
+ }
462
+ emit(event, args) {
463
+ if (!this.events) return this;
464
+ this.events.emit(event, args);
465
+ return this;
466
+ }
467
+ on(event, listener) {
468
+ if (!this.events) return this;
469
+ this.events.on(event, listener);
470
+ return this;
471
+ }
472
+ once(event, listener) {
473
+ if (!this.events) return this;
474
+ this.events.once(event, listener);
475
+ return this;
476
+ }
477
+ off(event, listener) {
478
+ if (!this.events) return this;
479
+ this.events.off(event, listener);
480
+ return this;
481
+ }
482
+ };
483
+
484
+ // src/core/store.core.ts
485
+ var Store = class extends Events {
480
486
  sOptions;
481
487
  fileUtil;
482
488
  storePath;
@@ -663,21 +669,21 @@ var KeyManager = class extends Store {
663
669
  * console.log('Key was rotated from version:', expired.version);
664
670
  * }
665
671
  *
666
- * // Use expired.originKey ?? ready.originKey safely
672
+ * // Use expired?.key ?? ready?.key safely
667
673
  * ```
668
674
  */
669
675
  async getKey(options) {
670
676
  const { path, version } = options;
671
677
  const key = await this.getKeyByStore(path, String(version));
672
678
  if (!key) {
673
- await this.runKeyHook("onKeyNotFound", path, version);
679
+ this.runKeyHook("onKeyNotFound", path, version);
674
680
  this.sysLog(`Key not found!`, { path, version });
675
681
  return { expired: null, ready: null };
676
682
  }
677
683
  const { ok, message, isExpired, isRenewable, errorOn } = this.validateKey(key);
678
684
  if (!ok && isExpired && isRenewable && key) {
679
685
  if (!options.onRotate) {
680
- await this.runKeyHook("onKeyMissingRotateOption", key, options);
686
+ this.runKeyHook("onKeyMissingRotateOption", key, options);
681
687
  this.sysLog(`Key missing rotate option!`, { path, version });
682
688
  return { expired: null, ready: null };
683
689
  }
@@ -686,17 +692,17 @@ var KeyManager = class extends Store {
686
692
  ...options.onRotate
687
693
  });
688
694
  const resGetKey = { expired: key, ready: renew.key };
689
- await this.runKeyHook("onKeyRenewed", resGetKey, options);
695
+ this.runKeyHook("onKeyRenewed", resGetKey, options);
690
696
  this.sysLog(`Key renewed!`, { path, version });
691
697
  return resGetKey;
692
698
  }
693
699
  if (!ok && isExpired && !isRenewable && key) {
694
- await this.runKeyHook("onKeyExpired", path, key);
700
+ this.runKeyHook("onKeyExpired", path, key);
695
701
  this.sysLog(`Key expired!`, { path, version });
696
702
  return { expired: key, ready: null };
697
703
  }
698
704
  if (!ok) {
699
- await this.runKeyHook("onKeyInvalid", key, message, errorOn);
705
+ this.runKeyHook("onKeyInvalid", key, message, errorOn);
700
706
  this.sysLog(`Key invalid!`, { path, version });
701
707
  return { expired: null, ready: null };
702
708
  }
@@ -743,7 +749,7 @@ var KeyManager = class extends Store {
743
749
  const { rotate, duration, type, unit, merge, keyLength } = options;
744
750
  const { key, length: kLength } = this.cryptoService.generateKey(keyLength);
745
751
  const { salt } = this.cryptoService.generateSalt();
746
- await this.sysLog(`Key generated
752
+ this.sysLog(`Key generated
747
753
  Options:`, options);
748
754
  const hashedKey = this.cryptoService.hash(key, salt);
749
755
  const now = /* @__PURE__ */ new Date();
@@ -758,7 +764,7 @@ Options:`, options);
758
764
  rotate: !!rotate
759
765
  };
760
766
  const path = await this.saveKeyToStore(keyGenerated, !!merge, variables);
761
- await this.sysLog(`Key saved!`, {
767
+ this.sysLog(`Key saved!`, {
762
768
  path,
763
769
  version: keyGenerated.version,
764
770
  type: keyGenerated.type
@@ -788,7 +794,7 @@ Options:`, options);
788
794
  hashed: "string",
789
795
  rotate: "boolean",
790
796
  type: "string",
791
- version: "string",
797
+ version: "stringNumber",
792
798
  hashedBytes: "number"
793
799
  };
794
800
  for (const [field, type] of Object.entries(typeChecks)) {
@@ -883,8 +889,8 @@ var KM = class _KM extends KeyManager {
883
889
 
884
890
  // src/index.ts
885
891
  var instance = null;
886
- var create = (options = {}, only = true) => {
887
- if (only) return new KM(options);
892
+ var create = (options = {}, singleton = false) => {
893
+ if (!singleton) return new KM(options);
888
894
  if (!instance) {
889
895
  instance = new KM(options);
890
896
  }
@@ -892,7 +898,6 @@ var create = (options = {}, only = true) => {
892
898
  };
893
899
  var km = create;
894
900
 
895
- exports.EError = EError;
896
901
  exports.EEvent = EEvent;
897
902
  exports.create = create;
898
903
  exports.km = km;