nestjs-env-getter 1.0.0-beta.2 → 1.0.0-beta.3
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/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,17 @@ All notable changes to this project will be documented in this file.
|
|
|
7
7
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
8
8
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
9
9
|
|
|
10
|
+
## [1.0.0-beta.3] - 2025-11-26
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- Improved file watcher resilience: re-establishes the file watcher after each successful update to handle atomic file replacements (e.g., Vault Agent credential rotations).
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- Increased default `debounceMs` from `200` to `350` ms to reduce noisy re-parses on rapid file updates.
|
|
19
|
+
- Documentation and unit tests updated to cover file replacement and re-establishment behavior.
|
|
20
|
+
|
|
10
21
|
## [1.0.0-beta.2] - 2025-10-17
|
|
11
22
|
|
|
12
23
|
### Added
|
package/README.md
CHANGED
|
@@ -272,7 +272,7 @@ Load and validate configuration from JSON files with automatic file watching and
|
|
|
272
272
|
{ enabled: false },
|
|
273
273
|
);
|
|
274
274
|
|
|
275
|
-
// Custom debounce timing (default is
|
|
275
|
+
// Custom debounce timing (default is 350ms)
|
|
276
276
|
const config = this.envGetter.getRequiredConfigFromFile(
|
|
277
277
|
"config.json",
|
|
278
278
|
undefined,
|
|
@@ -381,14 +381,14 @@ When the file watcher detects changes, it updates the **same object instance** i
|
|
|
381
381
|
**File Watcher Options:**
|
|
382
382
|
|
|
383
383
|
- `enabled` (boolean, default: `true`): Enable or disable automatic file watching
|
|
384
|
-
- `debounceMs` (number, default: `
|
|
384
|
+
- `debounceMs` (number, default: `350`): Delay in milliseconds before re-reading the file after a change
|
|
385
385
|
|
|
386
386
|
**Features:**
|
|
387
387
|
|
|
388
388
|
- ✅ Supports both absolute and relative paths (relative to `process.cwd()`)
|
|
389
389
|
- ✅ Automatic JSON parsing and validation
|
|
390
390
|
- ✅ **Hot-reload with reference preservation** - updates existing object instances in-place
|
|
391
|
-
- ✅ File watching with automatic change detection
|
|
391
|
+
- ✅ File watching with automatic change detection and file replacement support (e.g., Vault agent flow)
|
|
392
392
|
- ✅ Debouncing to prevent excessive re-reads
|
|
393
393
|
- ✅ Class-based validation with constructor pattern
|
|
394
394
|
- ✅ **Graceful error handling for optional configs** - missing files or JSON parsing errors return default values
|
|
@@ -345,6 +345,7 @@ export declare class EnvGetterService implements OnModuleDestroy {
|
|
|
345
345
|
* Sets up a file watcher for a configuration file.
|
|
346
346
|
* - Watches for file changes and automatically re-reads and updates the cached config.
|
|
347
347
|
* - Applies debouncing to avoid excessive re-reads.
|
|
348
|
+
* - Re-establishes the watcher after each successful update to handle file replacements (e.g., Vault agent flow).
|
|
348
349
|
* - Emits 'updated' or 'error' events on re-parse.
|
|
349
350
|
* @param filePath - The absolute path to the config file.
|
|
350
351
|
* @param cls - (Optional) A class constructor to validate and instantiate the parsed config.
|
|
@@ -599,6 +599,7 @@ let EnvGetterService = class EnvGetterService {
|
|
|
599
599
|
* Sets up a file watcher for a configuration file.
|
|
600
600
|
* - Watches for file changes and automatically re-reads and updates the cached config.
|
|
601
601
|
* - Applies debouncing to avoid excessive re-reads.
|
|
602
|
+
* - Re-establishes the watcher after each successful update to handle file replacements (e.g., Vault agent flow).
|
|
602
603
|
* - Emits 'updated' or 'error' events on re-parse.
|
|
603
604
|
* @param filePath - The absolute path to the config file.
|
|
604
605
|
* @param cls - (Optional) A class constructor to validate and instantiate the parsed config.
|
|
@@ -610,20 +611,43 @@ let EnvGetterService = class EnvGetterService {
|
|
|
610
611
|
var _a, _b, _c;
|
|
611
612
|
const watcherOptions = {
|
|
612
613
|
enabled: (_a = options === null || options === void 0 ? void 0 : options.enabled) !== null && _a !== void 0 ? _a : true,
|
|
613
|
-
debounceMs: (_b = options === null || options === void 0 ? void 0 : options.debounceMs) !== null && _b !== void 0 ? _b :
|
|
614
|
+
debounceMs: (_b = options === null || options === void 0 ? void 0 : options.debounceMs) !== null && _b !== void 0 ? _b : 350,
|
|
614
615
|
breakOnError: (_c = options === null || options === void 0 ? void 0 : options.breakOnError) !== null && _c !== void 0 ? _c : true,
|
|
615
616
|
};
|
|
616
|
-
if (!watcherOptions.enabled
|
|
617
|
+
if (!watcherOptions.enabled)
|
|
617
618
|
return;
|
|
619
|
+
// Close existing watcher if present (for re-establishment)
|
|
620
|
+
const existingWatcher = this.fileWatchers.get(filePath);
|
|
621
|
+
if (existingWatcher) {
|
|
622
|
+
existingWatcher.close();
|
|
623
|
+
this.fileWatchers.delete(filePath);
|
|
624
|
+
}
|
|
618
625
|
let debounceTimer = null;
|
|
619
626
|
const watcher = (0, fs_1.watch)(filePath, (eventType) => {
|
|
620
|
-
|
|
627
|
+
// Handle both "change" and "rename" events to catch file replacements
|
|
628
|
+
if (eventType === "change" || eventType === "rename") {
|
|
621
629
|
if (debounceTimer)
|
|
622
630
|
clearTimeout(debounceTimer);
|
|
623
631
|
debounceTimer = setTimeout(() => {
|
|
632
|
+
// Verify file still exists before attempting to read
|
|
633
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
634
|
+
// File was deleted, emit error event
|
|
635
|
+
const errorEvent = {
|
|
636
|
+
filePath,
|
|
637
|
+
error: new Error(`Config file '${filePath}' was deleted`),
|
|
638
|
+
timestamp: Date.now(),
|
|
639
|
+
};
|
|
640
|
+
this.events.emit(`error:${filePath}`, errorEvent);
|
|
641
|
+
return;
|
|
642
|
+
}
|
|
624
643
|
try {
|
|
625
644
|
// Re-parse the config (isInitialLoad = false, with breakOnError setting)
|
|
626
645
|
this.readAndParseConfigFile(filePath, cls, false, watcherOptions.breakOnError, isOptional);
|
|
646
|
+
// Close the old watcher
|
|
647
|
+
watcher.close();
|
|
648
|
+
this.fileWatchers.delete(filePath);
|
|
649
|
+
// Re-establish the watcher to handle file replacement scenarios (e.g., Vault agent)
|
|
650
|
+
this.setupFileWatcher(filePath, cls, options, isOptional);
|
|
627
651
|
// Emit file-specific success event
|
|
628
652
|
const event = {
|
|
629
653
|
filePath,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "nestjs-env-getter",
|
|
3
|
-
"version": "1.0.0-beta.
|
|
3
|
+
"version": "1.0.0-beta.3",
|
|
4
4
|
"description": "Environment variables getter for Nestjs applications",
|
|
5
5
|
"author": "Ivan Baha",
|
|
6
6
|
"private": false,
|
|
@@ -41,24 +41,24 @@
|
|
|
41
41
|
"dotenv": "^17.2.3"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@eslint/js": "^9.
|
|
45
|
-
"@nestjs/cli": "^11.0.
|
|
46
|
-
"@nestjs/common": "^11.1.
|
|
47
|
-
"@nestjs/core": "^11.1.
|
|
48
|
-
"@nestjs/testing": "^11.1.
|
|
44
|
+
"@eslint/js": "^9.39.1",
|
|
45
|
+
"@nestjs/cli": "^11.0.12",
|
|
46
|
+
"@nestjs/common": "^11.1.9",
|
|
47
|
+
"@nestjs/core": "^11.1.9",
|
|
48
|
+
"@nestjs/testing": "^11.1.9",
|
|
49
49
|
"@types/jest": "^30.0.0",
|
|
50
|
-
"@types/node": "^24.
|
|
51
|
-
"eslint": "^9.
|
|
50
|
+
"@types/node": "^24.10.1",
|
|
51
|
+
"eslint": "^9.39.1",
|
|
52
52
|
"eslint-config-prettier": "^10.0.3",
|
|
53
|
-
"eslint-plugin-jsdoc": "^61.
|
|
53
|
+
"eslint-plugin-jsdoc": "^61.4.1",
|
|
54
54
|
"eslint-plugin-prettier": "^5.4.0",
|
|
55
|
-
"globals": "^16.
|
|
55
|
+
"globals": "^16.5.0",
|
|
56
56
|
"jest": "^30.2.0",
|
|
57
57
|
"prettier": "^3.5.3",
|
|
58
58
|
"reflect-metadata": "^0.2.2",
|
|
59
59
|
"rxjs": "^7.8.2",
|
|
60
|
-
"ts-jest": "^29.
|
|
60
|
+
"ts-jest": "^29.4.5",
|
|
61
61
|
"typescript": "^5.8.3",
|
|
62
|
-
"typescript-eslint": "^8.
|
|
62
|
+
"typescript-eslint": "^8.48.0"
|
|
63
63
|
}
|
|
64
64
|
}
|