@catbee/utils 0.0.4 → 0.0.6
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/LICENSE +21 -201
- package/README.md +911 -242
- package/build/esm/config.d.ts +108 -8
- package/build/esm/config.js +122 -6
- package/build/esm/config.js.map +1 -1
- package/build/esm/index.d.ts +6 -0
- package/build/esm/index.js +29 -0
- package/build/esm/index.js.map +1 -1
- package/build/esm/servers/server.builder.d.ts +625 -0
- package/build/esm/servers/server.builder.js +722 -0
- package/build/esm/servers/server.builder.js.map +1 -0
- package/build/esm/servers/server.d.ts +256 -0
- package/build/esm/servers/server.js +1211 -0
- package/build/esm/servers/server.js.map +1 -0
- package/build/esm/types/api-response.d.ts +5 -7
- package/build/esm/types/api-response.js +23 -0
- package/build/esm/types/api-response.js.map +1 -1
- package/build/esm/types/index.d.ts +125 -0
- package/build/esm/types/index.js +25 -0
- package/build/esm/types/index.js.map +1 -0
- package/build/esm/types/server.d.ts +285 -0
- package/build/esm/types/server.js +25 -0
- package/build/esm/types/server.js.map +1 -0
- package/build/esm/utils/array.utils.js +23 -0
- package/build/esm/utils/array.utils.js.map +1 -1
- package/build/esm/utils/async.utils.js +23 -0
- package/build/esm/utils/async.utils.js.map +1 -1
- package/build/esm/utils/cache.utils.js +39 -16
- package/build/esm/utils/cache.utils.js.map +1 -1
- package/build/esm/utils/context-store.utils.d.ts +1 -1
- package/build/esm/utils/context-store.utils.js +24 -1
- package/build/esm/utils/context-store.utils.js.map +1 -1
- package/build/esm/utils/crypto.utils.js +26 -2
- package/build/esm/utils/crypto.utils.js.map +1 -1
- package/build/esm/utils/decorators.utils.d.ts +291 -0
- package/build/esm/utils/decorators.utils.js +395 -41
- package/build/esm/utils/decorators.utils.js.map +1 -1
- package/build/esm/utils/dir.utils.js +23 -0
- package/build/esm/utils/dir.utils.js.map +1 -1
- package/build/esm/utils/env.utils.d.ts +186 -23
- package/build/esm/utils/env.utils.js +517 -91
- package/build/esm/utils/env.utils.js.map +1 -1
- package/build/esm/utils/exception.utils.js +31 -8
- package/build/esm/utils/exception.utils.js.map +1 -1
- package/build/esm/utils/fs.utils.js +23 -0
- package/build/esm/utils/fs.utils.js.map +1 -1
- package/build/esm/utils/http-status-codes.js +23 -0
- package/build/esm/utils/http-status-codes.js.map +1 -1
- package/build/esm/utils/id.utils.js +23 -0
- package/build/esm/utils/id.utils.js.map +1 -1
- package/build/esm/utils/logger.utils.d.ts +118 -0
- package/build/esm/utils/logger.utils.js +251 -15
- package/build/esm/utils/logger.utils.js.map +1 -1
- package/build/esm/utils/middleware.utils.d.ts +29 -7
- package/build/esm/utils/middleware.utils.js +81 -55
- package/build/esm/utils/middleware.utils.js.map +1 -1
- package/build/esm/utils/obj.utils.d.ts +10 -3
- package/build/esm/utils/obj.utils.js +225 -15
- package/build/esm/utils/obj.utils.js.map +1 -1
- package/build/esm/utils/request.utils.d.ts +77 -0
- package/build/esm/utils/request.utils.js +196 -0
- package/build/esm/utils/request.utils.js.map +1 -0
- package/build/esm/utils/response.utils.d.ts +15 -1
- package/build/esm/utils/response.utils.js +55 -4
- package/build/esm/utils/response.utils.js.map +1 -1
- package/build/esm/utils/string.utils.js +23 -0
- package/build/esm/utils/string.utils.js.map +1 -1
- package/build/esm/utils/url.utils.js +23 -0
- package/build/esm/utils/url.utils.js.map +1 -1
- package/build/esm/utils/validate.utils.d.ts +7 -0
- package/build/esm/utils/validate.utils.js +35 -2
- package/build/esm/utils/validate.utils.js.map +1 -1
- package/build/esnext/config.d.ts +108 -8
- package/build/esnext/config.js +122 -6
- package/build/esnext/config.js.map +1 -1
- package/build/esnext/index.d.ts +6 -0
- package/build/esnext/index.js +29 -0
- package/build/esnext/index.js.map +1 -1
- package/build/esnext/servers/server.builder.d.ts +625 -0
- package/build/esnext/servers/server.builder.js +677 -0
- package/build/esnext/servers/server.builder.js.map +1 -0
- package/build/esnext/servers/server.d.ts +256 -0
- package/build/esnext/servers/server.js +918 -0
- package/build/esnext/servers/server.js.map +1 -0
- package/build/esnext/types/api-response.d.ts +5 -7
- package/build/esnext/types/api-response.js +23 -0
- package/build/esnext/types/api-response.js.map +1 -1
- package/build/esnext/types/index.d.ts +125 -0
- package/build/esnext/types/index.js +25 -0
- package/build/esnext/types/index.js.map +1 -0
- package/build/esnext/types/server.d.ts +285 -0
- package/build/esnext/types/server.js +25 -0
- package/build/esnext/types/server.js.map +1 -0
- package/build/esnext/utils/array.utils.js +23 -0
- package/build/esnext/utils/array.utils.js.map +1 -1
- package/build/esnext/utils/async.utils.js +23 -0
- package/build/esnext/utils/async.utils.js.map +1 -1
- package/build/esnext/utils/cache.utils.js +39 -16
- package/build/esnext/utils/cache.utils.js.map +1 -1
- package/build/esnext/utils/context-store.utils.d.ts +1 -1
- package/build/esnext/utils/context-store.utils.js +24 -1
- package/build/esnext/utils/context-store.utils.js.map +1 -1
- package/build/esnext/utils/crypto.utils.js +26 -2
- package/build/esnext/utils/crypto.utils.js.map +1 -1
- package/build/esnext/utils/decorators.utils.d.ts +291 -0
- package/build/esnext/utils/decorators.utils.js +371 -22
- package/build/esnext/utils/decorators.utils.js.map +1 -1
- package/build/esnext/utils/dir.utils.js +23 -0
- package/build/esnext/utils/dir.utils.js.map +1 -1
- package/build/esnext/utils/env.utils.d.ts +186 -23
- package/build/esnext/utils/env.utils.js +468 -77
- package/build/esnext/utils/env.utils.js.map +1 -1
- package/build/esnext/utils/exception.utils.js +30 -7
- package/build/esnext/utils/exception.utils.js.map +1 -1
- package/build/esnext/utils/fs.utils.js +23 -0
- package/build/esnext/utils/fs.utils.js.map +1 -1
- package/build/esnext/utils/http-status-codes.js +23 -0
- package/build/esnext/utils/http-status-codes.js.map +1 -1
- package/build/esnext/utils/id.utils.js +23 -0
- package/build/esnext/utils/id.utils.js.map +1 -1
- package/build/esnext/utils/logger.utils.d.ts +118 -0
- package/build/esnext/utils/logger.utils.js +222 -15
- package/build/esnext/utils/logger.utils.js.map +1 -1
- package/build/esnext/utils/middleware.utils.d.ts +29 -7
- package/build/esnext/utils/middleware.utils.js +77 -55
- package/build/esnext/utils/middleware.utils.js.map +1 -1
- package/build/esnext/utils/obj.utils.d.ts +10 -3
- package/build/esnext/utils/obj.utils.js +176 -12
- package/build/esnext/utils/obj.utils.js.map +1 -1
- package/build/esnext/utils/request.utils.d.ts +77 -0
- package/build/esnext/utils/request.utils.js +168 -0
- package/build/esnext/utils/request.utils.js.map +1 -0
- package/build/esnext/utils/response.utils.d.ts +15 -1
- package/build/esnext/utils/response.utils.js +55 -4
- package/build/esnext/utils/response.utils.js.map +1 -1
- package/build/esnext/utils/string.utils.js +23 -0
- package/build/esnext/utils/string.utils.js.map +1 -1
- package/build/esnext/utils/url.utils.js +23 -0
- package/build/esnext/utils/url.utils.js.map +1 -1
- package/build/esnext/utils/validate.utils.d.ts +7 -0
- package/build/esnext/utils/validate.utils.js +33 -0
- package/build/esnext/utils/validate.utils.js.map +1 -1
- package/build/src/config.d.ts +108 -8
- package/build/src/config.js +125 -7
- package/build/src/config.js.map +1 -1
- package/build/src/index.d.ts +6 -0
- package/build/src/index.js +32 -0
- package/build/src/index.js.map +1 -1
- package/build/src/servers/server.builder.d.ts +625 -0
- package/build/src/servers/server.builder.js +681 -0
- package/build/src/servers/server.builder.js.map +1 -0
- package/build/src/servers/server.d.ts +256 -0
- package/build/src/servers/server.js +958 -0
- package/build/src/servers/server.js.map +1 -0
- package/build/src/types/api-response.d.ts +5 -7
- package/build/src/types/api-response.js +23 -0
- package/build/src/types/api-response.js.map +1 -1
- package/build/src/types/index.d.ts +125 -0
- package/build/src/types/index.js +26 -0
- package/build/src/types/index.js.map +1 -0
- package/build/src/types/server.d.ts +285 -0
- package/build/src/types/server.js +26 -0
- package/build/src/types/server.js.map +1 -0
- package/build/src/utils/array.utils.js +23 -0
- package/build/src/utils/array.utils.js.map +1 -1
- package/build/src/utils/async.utils.js +23 -0
- package/build/src/utils/async.utils.js.map +1 -1
- package/build/src/utils/cache.utils.js +38 -15
- package/build/src/utils/cache.utils.js.map +1 -1
- package/build/src/utils/context-store.utils.d.ts +1 -1
- package/build/src/utils/context-store.utils.js +24 -1
- package/build/src/utils/context-store.utils.js.map +1 -1
- package/build/src/utils/crypto.utils.js +25 -1
- package/build/src/utils/crypto.utils.js.map +1 -1
- package/build/src/utils/decorators.utils.d.ts +291 -0
- package/build/src/utils/decorators.utils.js +373 -22
- package/build/src/utils/decorators.utils.js.map +1 -1
- package/build/src/utils/dir.utils.js +23 -0
- package/build/src/utils/dir.utils.js.map +1 -1
- package/build/src/utils/env.utils.d.ts +186 -23
- package/build/src/utils/env.utils.js +467 -76
- package/build/src/utils/env.utils.js.map +1 -1
- package/build/src/utils/exception.utils.js +30 -7
- package/build/src/utils/exception.utils.js.map +1 -1
- package/build/src/utils/fs.utils.js +23 -0
- package/build/src/utils/fs.utils.js.map +1 -1
- package/build/src/utils/http-status-codes.js +23 -0
- package/build/src/utils/http-status-codes.js.map +1 -1
- package/build/src/utils/id.utils.js +23 -0
- package/build/src/utils/id.utils.js.map +1 -1
- package/build/src/utils/logger.utils.d.ts +118 -0
- package/build/src/utils/logger.utils.js +228 -15
- package/build/src/utils/logger.utils.js.map +1 -1
- package/build/src/utils/middleware.utils.d.ts +29 -7
- package/build/src/utils/middleware.utils.js +76 -54
- package/build/src/utils/middleware.utils.js.map +1 -1
- package/build/src/utils/obj.utils.d.ts +10 -3
- package/build/src/utils/obj.utils.js +177 -12
- package/build/src/utils/obj.utils.js.map +1 -1
- package/build/src/utils/request.utils.d.ts +77 -0
- package/build/src/utils/request.utils.js +175 -0
- package/build/src/utils/request.utils.js.map +1 -0
- package/build/src/utils/response.utils.d.ts +15 -1
- package/build/src/utils/response.utils.js +56 -4
- package/build/src/utils/response.utils.js.map +1 -1
- package/build/src/utils/string.utils.js +23 -0
- package/build/src/utils/string.utils.js.map +1 -1
- package/build/src/utils/url.utils.js +23 -0
- package/build/src/utils/url.utils.js.map +1 -1
- package/build/src/utils/validate.utils.d.ts +7 -0
- package/build/src/utils/validate.utils.js +36 -2
- package/build/src/utils/validate.utils.js.map +1 -1
- package/package.json +40 -9
|
@@ -1,14 +1,26 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
/*
|
|
2
|
+
* The MIT License
|
|
3
|
+
*
|
|
4
|
+
* Copyright (c) 2025 Catbee Technologies
|
|
5
|
+
*
|
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
* furnished to do so, subject to the following conditions:
|
|
12
|
+
*
|
|
13
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
* copies or substantial portions of the Software.
|
|
15
|
+
*
|
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
* SOFTWARE.
|
|
23
|
+
*/
|
|
12
24
|
var __read = (this && this.__read) || function (o, n) {
|
|
13
25
|
var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
14
26
|
if (!m) return o;
|
|
@@ -25,8 +37,28 @@ var __read = (this && this.__read) || function (o, n) {
|
|
|
25
37
|
}
|
|
26
38
|
return ar;
|
|
27
39
|
};
|
|
40
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
41
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
42
|
+
if (ar || !(i in from)) {
|
|
43
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
44
|
+
ar[i] = from[i];
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
48
|
+
};
|
|
49
|
+
var __values = (this && this.__values) || function(o) {
|
|
50
|
+
var s = typeof Symbol === "function" && Symbol.iterator, m = s && o[s], i = 0;
|
|
51
|
+
if (m) return m.call(o);
|
|
52
|
+
if (o && typeof o.length === "number") return {
|
|
53
|
+
next: function () {
|
|
54
|
+
if (o && i >= o.length) o = void 0;
|
|
55
|
+
return { value: o && o[i++], done: !o };
|
|
56
|
+
}
|
|
57
|
+
};
|
|
58
|
+
throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
59
|
+
};
|
|
28
60
|
/* eslint-disable n/no-process-env */
|
|
29
|
-
import { existsSync } from 'fs';
|
|
61
|
+
import { existsSync, readFileSync } from 'fs';
|
|
30
62
|
import { isAbsolute, resolve } from 'path';
|
|
31
63
|
/**
|
|
32
64
|
* Enum representing valid application environments.
|
|
@@ -59,7 +91,7 @@ var Env = /** @class */ (function () {
|
|
|
59
91
|
* @returns {boolean} `true` if NODE_ENV is 'production', else `false`.
|
|
60
92
|
*/
|
|
61
93
|
Env.isProd = function () {
|
|
62
|
-
return Env.get('NODE_ENV') === Environment.PRODUCTION;
|
|
94
|
+
return Env.get('NODE_ENV', Environment.DEVELOPMENT) === Environment.PRODUCTION;
|
|
63
95
|
};
|
|
64
96
|
/**
|
|
65
97
|
* Checks if the current NODE_ENV is 'testing'.
|
|
@@ -67,7 +99,7 @@ var Env = /** @class */ (function () {
|
|
|
67
99
|
* @returns {boolean} `true` if NODE_ENV is 'testing', else `false`.
|
|
68
100
|
*/
|
|
69
101
|
Env.isTest = function () {
|
|
70
|
-
return Env.get('NODE_ENV') === Environment.TESTING;
|
|
102
|
+
return Env.get('NODE_ENV', Environment.DEVELOPMENT) === Environment.TESTING;
|
|
71
103
|
};
|
|
72
104
|
/**
|
|
73
105
|
* Checks if the current NODE_ENV is 'staging'.
|
|
@@ -75,7 +107,7 @@ var Env = /** @class */ (function () {
|
|
|
75
107
|
* @returns {boolean} `true` if NODE_ENV is 'staging', else `false`.
|
|
76
108
|
*/
|
|
77
109
|
Env.isStaging = function () {
|
|
78
|
-
return Env.get('NODE_ENV') === Environment.STAGING;
|
|
110
|
+
return Env.get('NODE_ENV', Environment.DEVELOPMENT) === Environment.STAGING;
|
|
79
111
|
};
|
|
80
112
|
/**
|
|
81
113
|
* Sets an environment variable (only affects runtime memory).
|
|
@@ -84,7 +116,25 @@ var Env = /** @class */ (function () {
|
|
|
84
116
|
* @param {string} value - The value to set.
|
|
85
117
|
*/
|
|
86
118
|
Env.set = function (key, value) {
|
|
119
|
+
var e_1, _a;
|
|
87
120
|
process.env[key] = value;
|
|
121
|
+
// Clear all cached values for this key with any prefix
|
|
122
|
+
this.cache.delete(key);
|
|
123
|
+
try {
|
|
124
|
+
for (var _b = __values(__spreadArray([], __read(this.cache.keys()), false)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
125
|
+
var cacheKey = _c.value;
|
|
126
|
+
if (cacheKey.includes(":".concat(key))) {
|
|
127
|
+
this.cache.delete(cacheKey);
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
132
|
+
finally {
|
|
133
|
+
try {
|
|
134
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
135
|
+
}
|
|
136
|
+
finally { if (e_1) throw e_1.error; }
|
|
137
|
+
}
|
|
88
138
|
};
|
|
89
139
|
/**
|
|
90
140
|
* Returns all environment variables as an object.
|
|
@@ -96,14 +146,28 @@ var Env = /** @class */ (function () {
|
|
|
96
146
|
};
|
|
97
147
|
/**
|
|
98
148
|
* Retrieves a string environment variable with a fallback default.
|
|
149
|
+
* Supports variable expansion with ${VAR_NAME} syntax.
|
|
99
150
|
*
|
|
100
151
|
* @param {string} key - The environment variable key.
|
|
101
152
|
* @param {string} [defaultValue] - Value to return if the key is missing.
|
|
102
|
-
* @returns {string
|
|
153
|
+
* @returns {string} The env value or the fallback.
|
|
154
|
+
*
|
|
155
|
+
* @example
|
|
156
|
+
* // If DATABASE_URL is "postgres://localhost:5432/${DB_NAME}"
|
|
157
|
+
* // and DB_NAME is "myapp"
|
|
158
|
+
* const url = Env.get('DATABASE_URL', ''); // "postgres://localhost:5432/myapp"
|
|
103
159
|
*/
|
|
104
160
|
Env.get = function (key, defaultValue) {
|
|
105
161
|
var _a;
|
|
106
|
-
|
|
162
|
+
var value = (_a = process.env[key]) !== null && _a !== void 0 ? _a : defaultValue;
|
|
163
|
+
// Expand ${VAR} references
|
|
164
|
+
if (value && value.includes('${')) {
|
|
165
|
+
value = value.replace(/\${([A-Za-z0-9_]+)}/g, function (_, varName) {
|
|
166
|
+
var _a;
|
|
167
|
+
return (_a = process.env[varName]) !== null && _a !== void 0 ? _a : '';
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
return value;
|
|
107
171
|
};
|
|
108
172
|
/**
|
|
109
173
|
* Retrieves a string environment variable and throws if it's missing.
|
|
@@ -115,9 +179,29 @@ var Env = /** @class */ (function () {
|
|
|
115
179
|
Env.getRequired = function (key) {
|
|
116
180
|
var value = process.env[key];
|
|
117
181
|
if (value === undefined) {
|
|
118
|
-
throw new Error("Required
|
|
182
|
+
throw new Error("Required environment variable '".concat(key, "' is missing"));
|
|
119
183
|
}
|
|
120
|
-
return
|
|
184
|
+
return Env.get(key, ''); // Use get to handle variable expansion
|
|
185
|
+
};
|
|
186
|
+
/**
|
|
187
|
+
* Retrieves a value using a default generating function if the key doesn't exist.
|
|
188
|
+
* Useful for expensive default calculations.
|
|
189
|
+
*
|
|
190
|
+
* @param {string} key - The environment variable key.
|
|
191
|
+
* @param {() => string} defaultFn - Function that generates default value.
|
|
192
|
+
* @returns {string} The environment value or generated default.
|
|
193
|
+
*
|
|
194
|
+
* @example
|
|
195
|
+
* const hostname = Env.getWithDefault('HOSTNAME', () => {
|
|
196
|
+
* // Only called if HOSTNAME is not set
|
|
197
|
+
* return require('os').hostname();
|
|
198
|
+
* });
|
|
199
|
+
*/
|
|
200
|
+
Env.getWithDefault = function (key, defaultFn) {
|
|
201
|
+
if (Env.has(key)) {
|
|
202
|
+
return Env.get(key, '');
|
|
203
|
+
}
|
|
204
|
+
return defaultFn();
|
|
121
205
|
};
|
|
122
206
|
/**
|
|
123
207
|
* Retrieves an environment variable as a number, or returns a default.
|
|
@@ -128,12 +212,18 @@ var Env = /** @class */ (function () {
|
|
|
128
212
|
* @throws {Error} If the value is not a valid number.
|
|
129
213
|
*/
|
|
130
214
|
Env.getNumber = function (key, defaultValue) {
|
|
131
|
-
|
|
132
|
-
|
|
215
|
+
if (this.cache.has("number:".concat(key))) {
|
|
216
|
+
return this.cache.get("number:".concat(key));
|
|
217
|
+
}
|
|
218
|
+
var value = process.env[key];
|
|
219
|
+
if (value === undefined) {
|
|
220
|
+
return defaultValue;
|
|
221
|
+
}
|
|
133
222
|
var numberValue = Number(value);
|
|
134
223
|
if (isNaN(numberValue)) {
|
|
135
|
-
throw new Error("
|
|
224
|
+
throw new Error("Environment variable '".concat(key, "' is not a valid number, got: \"").concat(value, "\""));
|
|
136
225
|
}
|
|
226
|
+
this.cache.set("number:".concat(key), numberValue);
|
|
137
227
|
return numberValue;
|
|
138
228
|
};
|
|
139
229
|
/**
|
|
@@ -146,13 +236,38 @@ var Env = /** @class */ (function () {
|
|
|
146
236
|
Env.getNumberRequired = function (key) {
|
|
147
237
|
var value = process.env[key];
|
|
148
238
|
if (value === undefined) {
|
|
149
|
-
throw new Error("Required
|
|
239
|
+
throw new Error("Required environment variable '".concat(key, "' is missing"));
|
|
150
240
|
}
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
241
|
+
return Env.getNumber(key, 0); // The default is ignored since we know the key exists
|
|
242
|
+
};
|
|
243
|
+
/**
|
|
244
|
+
* Retrieves an integer environment variable and validates it.
|
|
245
|
+
*
|
|
246
|
+
* @param {string} key - The environment variable key.
|
|
247
|
+
* @param {number} defaultValue - Fallback number if key is not present.
|
|
248
|
+
* @param {object} [options] - Validation options.
|
|
249
|
+
* @param {number} [options.min] - Minimum allowed value.
|
|
250
|
+
* @param {number} [options.max] - Maximum allowed value.
|
|
251
|
+
* @returns {number} The parsed integer.
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* // Require PORT to be between 1000 and 9999
|
|
255
|
+
* const port = Env.getInteger('PORT', 3000, { min: 1000, max: 9999 });
|
|
256
|
+
*/
|
|
257
|
+
Env.getInteger = function (key, defaultValue, options) {
|
|
258
|
+
if (options === void 0) { options = {}; }
|
|
259
|
+
var num = Env.getNumber(key, defaultValue);
|
|
260
|
+
var intValue = Math.floor(num);
|
|
261
|
+
if (intValue !== num) {
|
|
262
|
+
throw new Error("Environment variable '".concat(key, "' must be an integer, got: ").concat(num));
|
|
154
263
|
}
|
|
155
|
-
|
|
264
|
+
if (options.min !== undefined && intValue < options.min) {
|
|
265
|
+
throw new Error("Environment variable '".concat(key, "' must be at least ").concat(options.min, ", got: ").concat(intValue));
|
|
266
|
+
}
|
|
267
|
+
if (options.max !== undefined && intValue > options.max) {
|
|
268
|
+
throw new Error("Environment variable '".concat(key, "' must be at most ").concat(options.max, ", got: ").concat(intValue));
|
|
269
|
+
}
|
|
270
|
+
return intValue;
|
|
156
271
|
};
|
|
157
272
|
/**
|
|
158
273
|
* Retrieves an environment variable as a boolean.
|
|
@@ -162,16 +277,30 @@ var Env = /** @class */ (function () {
|
|
|
162
277
|
* @param {boolean} [defaultValue=false] - Optional fallback value if key is missing.
|
|
163
278
|
* @returns {boolean} Parsed boolean.
|
|
164
279
|
* @throws {Error} If the value is not a recognized boolean string.
|
|
280
|
+
*
|
|
281
|
+
* @example
|
|
282
|
+
* // If DEBUG=yes
|
|
283
|
+
* const isDebug = Env.getBoolean('DEBUG', false); // true
|
|
165
284
|
*/
|
|
166
285
|
Env.getBoolean = function (key, defaultValue) {
|
|
167
|
-
var _a;
|
|
168
286
|
if (defaultValue === void 0) { defaultValue = false; }
|
|
169
|
-
|
|
170
|
-
|
|
287
|
+
if (this.cache.has("bool:".concat(key))) {
|
|
288
|
+
return this.cache.get("bool:".concat(key));
|
|
289
|
+
}
|
|
290
|
+
var value = process.env[key];
|
|
291
|
+
if (value === undefined) {
|
|
292
|
+
return defaultValue;
|
|
293
|
+
}
|
|
294
|
+
var lowerValue = value.toLowerCase();
|
|
295
|
+
if (['true', '1', 'yes', 'on'].includes(lowerValue)) {
|
|
296
|
+
this.cache.set("bool:".concat(key), true);
|
|
171
297
|
return true;
|
|
172
|
-
|
|
298
|
+
}
|
|
299
|
+
if (['false', '0', 'no', 'off'].includes(lowerValue)) {
|
|
300
|
+
this.cache.set("bool:".concat(key), false);
|
|
173
301
|
return false;
|
|
174
|
-
|
|
302
|
+
}
|
|
303
|
+
throw new Error("Environment variable '".concat(key, "' is not a valid boolean, got: \"").concat(value, "\". Use true/false, yes/no, 1/0, or on/off."));
|
|
175
304
|
};
|
|
176
305
|
/**
|
|
177
306
|
* Retrieves a required environment variable as a boolean.
|
|
@@ -183,9 +312,9 @@ var Env = /** @class */ (function () {
|
|
|
183
312
|
Env.getBooleanRequired = function (key) {
|
|
184
313
|
var value = process.env[key];
|
|
185
314
|
if (value === undefined) {
|
|
186
|
-
throw new Error("Required
|
|
315
|
+
throw new Error("Required environment variable '".concat(key, "' is missing"));
|
|
187
316
|
}
|
|
188
|
-
return
|
|
317
|
+
return Env.getBoolean(key);
|
|
189
318
|
};
|
|
190
319
|
/**
|
|
191
320
|
* Parses a stringified JSON object from an environment variable.
|
|
@@ -195,18 +324,28 @@ var Env = /** @class */ (function () {
|
|
|
195
324
|
* @param {T} defaultValue - Value to return if key is missing.
|
|
196
325
|
* @returns {T} Parsed object or default.
|
|
197
326
|
* @throws {Error} If the value is not valid JSON.
|
|
327
|
+
*
|
|
328
|
+
* @example
|
|
329
|
+
* // If CONFIG='{"debug":true,"api":{"url":"https://api.example.com"}}'
|
|
330
|
+
* const config = Env.getJSON('CONFIG', { debug: false });
|
|
331
|
+
* // { debug: true, api: { url: "https://api.example.com" }}
|
|
198
332
|
*/
|
|
199
333
|
Env.getJSON = function (key, defaultValue) {
|
|
334
|
+
if (this.cache.has("json:".concat(key))) {
|
|
335
|
+
return this.cache.get("json:".concat(key));
|
|
336
|
+
}
|
|
200
337
|
var v = process.env[key];
|
|
201
|
-
if (v
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
338
|
+
if (v === undefined) {
|
|
339
|
+
return defaultValue;
|
|
340
|
+
}
|
|
341
|
+
try {
|
|
342
|
+
var parsed = JSON.parse(v);
|
|
343
|
+
this.cache.set("json:".concat(key), parsed);
|
|
344
|
+
return parsed;
|
|
345
|
+
}
|
|
346
|
+
catch (error) {
|
|
347
|
+
throw new Error("Environment variable '".concat(key, "' is not valid JSON: ").concat(error.message));
|
|
208
348
|
}
|
|
209
|
-
return defaultValue;
|
|
210
349
|
};
|
|
211
350
|
/**
|
|
212
351
|
* Parses a comma-separated string as an array.
|
|
@@ -215,19 +354,69 @@ var Env = /** @class */ (function () {
|
|
|
215
354
|
* @param {string} key - The environment variable key.
|
|
216
355
|
* @param {T[]} [defaultValue=[]] - Array to return if value is empty or missing.
|
|
217
356
|
* @param {string} [splitter=','] - Delimiter to split on.
|
|
218
|
-
* @
|
|
357
|
+
* @param {(item: string) => T} [transform] - Optional function to transform each item.
|
|
358
|
+
* @returns {T[]} An array of items.
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* // If ALLOWED_IPS=127.0.0.1,192.168.1.1,10.0.0.1
|
|
362
|
+
* const ips = Env.getArray('ALLOWED_IPS');
|
|
363
|
+
* // ["127.0.0.1", "192.168.1.1", "10.0.0.1"]
|
|
364
|
+
*
|
|
365
|
+
* // With transformation function
|
|
366
|
+
* const ports = Env.getArray('PORTS', [], ',', (p) => parseInt(p, 10));
|
|
219
367
|
*/
|
|
220
|
-
Env.getArray = function (key, defaultValue, splitter) {
|
|
368
|
+
Env.getArray = function (key, defaultValue, splitter, transform) {
|
|
221
369
|
if (defaultValue === void 0) { defaultValue = []; }
|
|
222
370
|
if (splitter === void 0) { splitter = ','; }
|
|
371
|
+
var cacheKey = "array:".concat(key, ":").concat(splitter, ":").concat(transform ? 'transformed' : 'raw');
|
|
372
|
+
if (this.cache.has(cacheKey)) {
|
|
373
|
+
return this.cache.get(cacheKey);
|
|
374
|
+
}
|
|
223
375
|
var value = process.env[key];
|
|
224
376
|
if (!value || value.trim() === '') {
|
|
225
377
|
return defaultValue;
|
|
226
378
|
}
|
|
227
|
-
|
|
379
|
+
var items = value
|
|
228
380
|
.split(splitter)
|
|
229
381
|
.map(function (item) { return item.trim(); })
|
|
230
382
|
.filter(function (item) { return item.length > 0; });
|
|
383
|
+
if (transform) {
|
|
384
|
+
try {
|
|
385
|
+
var result_1 = items.map(transform);
|
|
386
|
+
this.cache.set(cacheKey, result_1);
|
|
387
|
+
return result_1;
|
|
388
|
+
}
|
|
389
|
+
catch (error) {
|
|
390
|
+
throw new Error("Failed to transform items in '".concat(key, "': ").concat(error.message));
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
var result = items;
|
|
394
|
+
this.cache.set(cacheKey, result);
|
|
395
|
+
return result;
|
|
396
|
+
};
|
|
397
|
+
/**
|
|
398
|
+
* Parses a comma-separated list of numbers.
|
|
399
|
+
*
|
|
400
|
+
* @param {string} key - The environment variable key.
|
|
401
|
+
* @param {number[]} [defaultValue=[]] - Default value if not present.
|
|
402
|
+
* @param {string} [splitter=','] - Delimiter to split on.
|
|
403
|
+
* @returns {number[]} Array of parsed numbers.
|
|
404
|
+
*
|
|
405
|
+
* @example
|
|
406
|
+
* // If ALLOWED_PORTS=80,443,3000,8080
|
|
407
|
+
* const ports = Env.getNumberArray('ALLOWED_PORTS');
|
|
408
|
+
* // [80, 443, 3000, 8080]
|
|
409
|
+
*/
|
|
410
|
+
Env.getNumberArray = function (key, defaultValue, splitter) {
|
|
411
|
+
if (defaultValue === void 0) { defaultValue = []; }
|
|
412
|
+
if (splitter === void 0) { splitter = ','; }
|
|
413
|
+
return Env.getArray(key, defaultValue, splitter, function (item) {
|
|
414
|
+
var num = Number(item);
|
|
415
|
+
if (isNaN(num)) {
|
|
416
|
+
throw new Error("Value \"".concat(item, "\" in array '").concat(key, "' is not a valid number"));
|
|
417
|
+
}
|
|
418
|
+
return num;
|
|
419
|
+
});
|
|
231
420
|
};
|
|
232
421
|
/**
|
|
233
422
|
* Retrieves an enum-like environment variable value, validating against allowed values.
|
|
@@ -238,12 +427,38 @@ var Env = /** @class */ (function () {
|
|
|
238
427
|
* @param {T} [defaultValue] - Optional fallback value.
|
|
239
428
|
* @returns {T} The validated environment value.
|
|
240
429
|
* @throws {Error} If missing or invalid.
|
|
430
|
+
*
|
|
431
|
+
* @example
|
|
432
|
+
* // If LOG_LEVEL=debug
|
|
433
|
+
* const level = Env.getEnum('LOG_LEVEL', ['debug', 'info', 'warn', 'error'] as const, 'info');
|
|
434
|
+
* // 'debug' (typed as 'debug' | 'info' | 'warn' | 'error')
|
|
241
435
|
*/
|
|
242
436
|
Env.getEnum = function (key, allowedValues, defaultValue) {
|
|
243
|
-
var
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
437
|
+
var value = process.env[key];
|
|
438
|
+
if (!value) {
|
|
439
|
+
return defaultValue;
|
|
440
|
+
}
|
|
441
|
+
if (!allowedValues.includes(value)) {
|
|
442
|
+
throw new Error("Environment variable '".concat(key, "' must be one of: ").concat(allowedValues.join(', '), ". Received: \"").concat(value, "\""));
|
|
443
|
+
}
|
|
444
|
+
return value;
|
|
445
|
+
};
|
|
446
|
+
/**
|
|
447
|
+
* Retrieves an enum-like numeric environment variable.
|
|
448
|
+
*
|
|
449
|
+
* @param {string} key - The environment variable key.
|
|
450
|
+
* @param {number[]} allowedValues - Array of accepted values.
|
|
451
|
+
* @param {number} defaultValue - Default value if not present.
|
|
452
|
+
* @returns {number} The validated value.
|
|
453
|
+
*
|
|
454
|
+
* @example
|
|
455
|
+
* // If NODE_VERSION=16
|
|
456
|
+
* const version = Env.getNumberEnum('NODE_VERSION', [14, 16, 18], 16);
|
|
457
|
+
*/
|
|
458
|
+
Env.getNumberEnum = function (key, allowedValues, defaultValue) {
|
|
459
|
+
var value = Env.getNumber(key, defaultValue);
|
|
460
|
+
if (!allowedValues.includes(value)) {
|
|
461
|
+
throw new Error("Environment variable '".concat(key, "' must be one of: ").concat(allowedValues.join(', '), ". Received: ").concat(value));
|
|
247
462
|
}
|
|
248
463
|
return value;
|
|
249
464
|
};
|
|
@@ -252,42 +467,67 @@ var Env = /** @class */ (function () {
|
|
|
252
467
|
*
|
|
253
468
|
* @param {string} key - The environment variable key.
|
|
254
469
|
* @param {string} [defaultValue] - Optional fallback value.
|
|
255
|
-
* @param {
|
|
256
|
-
* @param {string[]} [options.protocols] - Allowed protocols.
|
|
257
|
-
* @param {boolean} [options.requireTld=true] - Whether TLD is required.
|
|
470
|
+
* @param {UrlOptions} [options] - Validation options.
|
|
258
471
|
* @returns {string} The validated URL.
|
|
259
472
|
* @throws {Error} If URL is invalid.
|
|
473
|
+
*
|
|
474
|
+
* @example
|
|
475
|
+
* // Validate API URL requires HTTPS
|
|
476
|
+
* const apiUrl = Env.getUrl('API_URL', 'https://api.example.com', {
|
|
477
|
+
* protocols: ['https'],
|
|
478
|
+
* requireTld: true,
|
|
479
|
+
* allowIp: false
|
|
480
|
+
* });
|
|
260
481
|
*/
|
|
261
482
|
Env.getUrl = function (key, defaultValue, options) {
|
|
262
483
|
if (options === void 0) { options = {}; }
|
|
484
|
+
var cacheKey = "url:".concat(key, ":").concat(JSON.stringify(options));
|
|
485
|
+
if (this.cache.has(cacheKey)) {
|
|
486
|
+
return this.cache.get(cacheKey);
|
|
487
|
+
}
|
|
263
488
|
var value = Env.get(key, defaultValue);
|
|
264
489
|
if (!value) {
|
|
265
|
-
throw new Error("
|
|
490
|
+
throw new Error("URL environment variable '".concat(key, "' is missing or empty"));
|
|
266
491
|
}
|
|
267
492
|
var url;
|
|
268
493
|
try {
|
|
269
494
|
url = new URL(value);
|
|
270
495
|
}
|
|
271
496
|
catch (_a) {
|
|
272
|
-
throw new Error("
|
|
497
|
+
throw new Error("Environment variable '".concat(key, "' is not a valid URL: \"").concat(value, "\""));
|
|
273
498
|
}
|
|
499
|
+
// Validate protocol
|
|
274
500
|
if (options.protocols && options.protocols.length > 0) {
|
|
275
501
|
var protocol = url.protocol.replace(':', '');
|
|
276
502
|
if (!options.protocols.includes(protocol)) {
|
|
277
|
-
throw new Error("
|
|
503
|
+
throw new Error("Environment variable '".concat(key, "' must use one of the protocols: ").concat(options.protocols.join(', '), ". Got: ").concat(protocol));
|
|
278
504
|
}
|
|
279
505
|
}
|
|
506
|
+
// Validate hostname
|
|
507
|
+
var hostname = url.hostname;
|
|
508
|
+
var isIp = /^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$/.test(hostname);
|
|
509
|
+
var isLocalhost = hostname === 'localhost';
|
|
510
|
+
// Check if hostname is an IP address when not allowed
|
|
511
|
+
if (isIp && options.allowIp === false) {
|
|
512
|
+
throw new Error("Environment variable '".concat(key, "' cannot be an IP address: \"").concat(hostname, "\""));
|
|
513
|
+
}
|
|
514
|
+
// Check if hostname is localhost when not allowed
|
|
515
|
+
if (isLocalhost && options.allowLocalhost === false) {
|
|
516
|
+
throw new Error("Environment variable '".concat(key, "' cannot be localhost"));
|
|
517
|
+
}
|
|
518
|
+
// Check for TLD requirement - include localhost in check if requireTld is true and allowLocalhost is false
|
|
280
519
|
if (options.requireTld === true) {
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
if (
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
throw new Error("
|
|
520
|
+
if (isLocalhost && options.allowLocalhost !== false) {
|
|
521
|
+
// Localhost is allowed, so no TLD check needed for it
|
|
522
|
+
}
|
|
523
|
+
else if (isIp && options.allowIp !== false) {
|
|
524
|
+
// IP is allowed, so no TLD check needed for it
|
|
525
|
+
}
|
|
526
|
+
else if (!hostname.includes('.') || hostname.endsWith('.')) {
|
|
527
|
+
throw new Error("Environment variable '".concat(key, "' must have a valid host with TLD: \"").concat(hostname, "\""));
|
|
289
528
|
}
|
|
290
529
|
}
|
|
530
|
+
this.cache.set(cacheKey, value);
|
|
291
531
|
return value;
|
|
292
532
|
};
|
|
293
533
|
/**
|
|
@@ -297,20 +537,27 @@ var Env = /** @class */ (function () {
|
|
|
297
537
|
* @param {string} [defaultValue] - Optional fallback value.
|
|
298
538
|
* @returns {string} The validated email address.
|
|
299
539
|
* @throws {Error} If email is invalid.
|
|
540
|
+
*
|
|
541
|
+
* @example
|
|
542
|
+
* const supportEmail = Env.getEmail('SUPPORT_EMAIL', 'support@example.com');
|
|
300
543
|
*/
|
|
301
544
|
Env.getEmail = function (key, defaultValue) {
|
|
545
|
+
if (this.cache.has("email:".concat(key))) {
|
|
546
|
+
return this.cache.get("email:".concat(key));
|
|
547
|
+
}
|
|
302
548
|
var value = Env.get(key, defaultValue);
|
|
303
549
|
if (!value) {
|
|
304
550
|
if (defaultValue === undefined) {
|
|
305
|
-
throw new Error("Email
|
|
551
|
+
throw new Error("Email environment variable '".concat(key, "' is missing"));
|
|
306
552
|
}
|
|
307
553
|
return defaultValue;
|
|
308
554
|
}
|
|
309
|
-
//
|
|
310
|
-
var emailRegex = /^[a-zA-Z0-9
|
|
555
|
+
// More comprehensive email validation regex
|
|
556
|
+
var emailRegex = /^[a-zA-Z0-9.!#$%&'*+/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/;
|
|
311
557
|
if (!emailRegex.test(value)) {
|
|
312
|
-
throw new Error("
|
|
558
|
+
throw new Error("Environment variable '".concat(key, "' is not a valid email address: \"").concat(value, "\""));
|
|
313
559
|
}
|
|
560
|
+
this.cache.set("email:".concat(key), value);
|
|
314
561
|
return value;
|
|
315
562
|
};
|
|
316
563
|
/**
|
|
@@ -318,78 +565,143 @@ var Env = /** @class */ (function () {
|
|
|
318
565
|
*
|
|
319
566
|
* @param {string} key - The environment variable key.
|
|
320
567
|
* @param {string} [defaultValue] - Optional fallback value.
|
|
321
|
-
* @param {
|
|
322
|
-
* @param {boolean} [options.mustExist=false] - Whether path must exist.
|
|
323
|
-
* @param {boolean} [options.makeAbsolute=true] - Convert relative paths to absolute.
|
|
568
|
+
* @param {PathOptions} [options] - Validation options.
|
|
324
569
|
* @returns {string} The validated path.
|
|
325
570
|
* @throws {Error} If path is invalid.
|
|
571
|
+
*
|
|
572
|
+
* @example
|
|
573
|
+
* // Require that the path exists and is a .json file
|
|
574
|
+
* const configPath = Env.getPath('CONFIG_PATH', './config.json', {
|
|
575
|
+
* mustExist: true,
|
|
576
|
+
* allowedExtensions: ['.json', '.yaml']
|
|
577
|
+
* });
|
|
326
578
|
*/
|
|
327
579
|
Env.getPath = function (key, defaultValue, options) {
|
|
328
580
|
if (options === void 0) { options = {}; }
|
|
581
|
+
var cacheKey = "path:".concat(key, ":").concat(JSON.stringify(options));
|
|
582
|
+
if (this.cache.has(cacheKey)) {
|
|
583
|
+
return this.cache.get(cacheKey);
|
|
584
|
+
}
|
|
329
585
|
var value = Env.get(key, defaultValue);
|
|
330
586
|
if (!value) {
|
|
331
587
|
if (defaultValue === undefined) {
|
|
332
|
-
throw new Error("Path
|
|
588
|
+
throw new Error("Path environment variable '".concat(key, "' is missing"));
|
|
333
589
|
}
|
|
334
590
|
return defaultValue;
|
|
335
591
|
}
|
|
336
592
|
var path = options.makeAbsolute !== false && !isAbsolute(value) ? resolve(process.cwd(), value) : value;
|
|
593
|
+
// Validate path exists if required
|
|
337
594
|
if (options.mustExist && !existsSync(path)) {
|
|
338
|
-
throw new Error("Path in
|
|
595
|
+
throw new Error("Path in environment variable '".concat(key, "' does not exist: \"").concat(path, "\""));
|
|
596
|
+
}
|
|
597
|
+
// Validate file extension if specified
|
|
598
|
+
if (options.allowedExtensions && options.allowedExtensions.length > 0) {
|
|
599
|
+
var hasValidExtension = options.allowedExtensions.some(function (ext) { return path.toLowerCase().endsWith(ext.toLowerCase()); });
|
|
600
|
+
if (!hasValidExtension) {
|
|
601
|
+
throw new Error("Path in environment variable '".concat(key, "' must have one of these extensions: ").concat(options.allowedExtensions.join(', '), ". Got: \"").concat(path, "\""));
|
|
602
|
+
}
|
|
339
603
|
}
|
|
604
|
+
this.cache.set(cacheKey, path);
|
|
340
605
|
return path;
|
|
341
606
|
};
|
|
342
607
|
/**
|
|
343
608
|
* Retrieves a port environment variable and validates it.
|
|
344
609
|
*
|
|
345
610
|
* @param {string} key - The environment variable key.
|
|
346
|
-
* @param {number} [defaultValue
|
|
611
|
+
* @param {number} [defaultValue] - Optional fallback value.
|
|
347
612
|
* @returns {number} The validated port number.
|
|
348
613
|
* @throws {Error} If port is invalid.
|
|
614
|
+
*
|
|
615
|
+
* @example
|
|
616
|
+
* const serverPort = Env.getPort('PORT', 3000);
|
|
349
617
|
*/
|
|
350
618
|
Env.getPort = function (key, defaultValue) {
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
619
|
+
try {
|
|
620
|
+
return Env.getInteger(key, defaultValue, { min: 0, max: 65535 });
|
|
621
|
+
}
|
|
622
|
+
catch (error) {
|
|
623
|
+
// Rewrite the error message to match the expected pattern
|
|
624
|
+
if (error.message.includes('must be at most 65535')) {
|
|
625
|
+
throw new Error("Environment variable '".concat(key, "' must be a valid port number (0-65535)"));
|
|
626
|
+
}
|
|
627
|
+
throw error;
|
|
628
|
+
}
|
|
629
|
+
};
|
|
630
|
+
/**
|
|
631
|
+
* Retrieves an ISO date string and converts it to a Date object.
|
|
632
|
+
*
|
|
633
|
+
* @param {string} key - The environment variable key.
|
|
634
|
+
* @param {string|Date} [defaultValue] - Optional fallback value.
|
|
635
|
+
* @returns {Date} The parsed Date object.
|
|
636
|
+
*
|
|
637
|
+
* @example
|
|
638
|
+
* // If EXPIRY_DATE=2023-12-31T23:59:59Z
|
|
639
|
+
* const expiryDate = Env.getDate('EXPIRY_DATE', new Date());
|
|
640
|
+
*/
|
|
641
|
+
Env.getDate = function (key, defaultValue) {
|
|
642
|
+
if (defaultValue === void 0) { defaultValue = new Date(); }
|
|
643
|
+
var value = Env.get(key, defaultValue instanceof Date ? defaultValue.toISOString() : defaultValue);
|
|
644
|
+
if (!value) {
|
|
645
|
+
return defaultValue instanceof Date ? defaultValue : new Date();
|
|
646
|
+
}
|
|
647
|
+
var date = new Date(value);
|
|
648
|
+
if (isNaN(date.getTime())) {
|
|
649
|
+
throw new Error("Environment variable '".concat(key, "' is not a valid date: \"").concat(value, "\""));
|
|
355
650
|
}
|
|
356
|
-
return
|
|
651
|
+
return date;
|
|
357
652
|
};
|
|
358
653
|
/**
|
|
359
|
-
* Retrieves a duration string and converts to milliseconds.
|
|
654
|
+
* Retrieves a duration string and converts it to milliseconds.
|
|
360
655
|
* Supports formats like "1d", "2h", "30m", "45s", "100ms" or combinations like "1h30m".
|
|
361
656
|
*
|
|
362
657
|
* @param {string} key - The environment variable key.
|
|
363
658
|
* @param {string|number} [defaultValue='0'] - Optional fallback value.
|
|
364
659
|
* @returns {number} The duration in milliseconds.
|
|
365
660
|
* @throws {Error} If duration format is invalid.
|
|
661
|
+
*
|
|
662
|
+
* @example
|
|
663
|
+
* // If CACHE_TTL=2h30m
|
|
664
|
+
* const cacheTtlMs = Env.getDuration('CACHE_TTL', '1h');
|
|
665
|
+
* // 9000000 (2.5 hours in milliseconds)
|
|
366
666
|
*/
|
|
367
667
|
Env.getDuration = function (key, defaultValue) {
|
|
368
668
|
if (defaultValue === void 0) { defaultValue = '0'; }
|
|
669
|
+
var cacheKey = "duration:".concat(key);
|
|
670
|
+
if (this.cache.has(cacheKey)) {
|
|
671
|
+
return this.cache.get(cacheKey);
|
|
672
|
+
}
|
|
369
673
|
var value = Env.get(key, String(defaultValue));
|
|
370
674
|
if (!value)
|
|
371
675
|
return 0;
|
|
372
676
|
// Handle plain number input (assume milliseconds)
|
|
373
677
|
if (/^\d+$/.test(value)) {
|
|
374
|
-
|
|
678
|
+
var ms_1 = parseInt(value, 10);
|
|
679
|
+
this.cache.set(cacheKey, ms_1);
|
|
680
|
+
return ms_1;
|
|
375
681
|
}
|
|
376
|
-
//
|
|
377
|
-
var durationRegex =
|
|
682
|
+
// Enhanced duration parsing with more precise regex
|
|
683
|
+
var durationRegex = /^(?:(\d+)y)?(?:(\d+)w)?(?:(\d+)d)?(?:(\d+)h)?(?:(\d+)m)?(?:(\d+)s)?(?:(\d+)ms)?$/;
|
|
378
684
|
var matches = value.match(durationRegex);
|
|
379
685
|
if (!matches || matches[0] === '') {
|
|
380
|
-
throw new Error("
|
|
686
|
+
throw new Error("Environment variable '".concat(key, "' has invalid duration format: \"").concat(value, "\". ") +
|
|
687
|
+
"Use formats like 1y, 2w, 3d, 4h, 5m, 6s, or 7ms.");
|
|
381
688
|
}
|
|
382
689
|
var ms = 0;
|
|
383
690
|
if (matches[1])
|
|
384
|
-
ms += parseInt(matches[1], 10) *
|
|
691
|
+
ms += parseInt(matches[1], 10) * 31536000000; // years (approximate)
|
|
385
692
|
if (matches[2])
|
|
386
|
-
ms += parseInt(matches[2], 10) *
|
|
693
|
+
ms += parseInt(matches[2], 10) * 604800000; // weeks
|
|
387
694
|
if (matches[3])
|
|
388
|
-
ms += parseInt(matches[3], 10) *
|
|
695
|
+
ms += parseInt(matches[3], 10) * 86400000; // days
|
|
389
696
|
if (matches[4])
|
|
390
|
-
ms += parseInt(matches[4], 10) *
|
|
697
|
+
ms += parseInt(matches[4], 10) * 3600000; // hours
|
|
391
698
|
if (matches[5])
|
|
392
|
-
ms += parseInt(matches[5], 10); //
|
|
699
|
+
ms += parseInt(matches[5], 10) * 60000; // minutes
|
|
700
|
+
if (matches[6])
|
|
701
|
+
ms += parseInt(matches[6], 10) * 1000; // seconds
|
|
702
|
+
if (matches[7])
|
|
703
|
+
ms += parseInt(matches[7], 10); // milliseconds
|
|
704
|
+
this.cache.set(cacheKey, ms);
|
|
393
705
|
return ms;
|
|
394
706
|
};
|
|
395
707
|
/**
|
|
@@ -397,9 +709,13 @@ var Env = /** @class */ (function () {
|
|
|
397
709
|
*
|
|
398
710
|
* @param {string[]} [sensitiveKeys=['password', 'secret', 'key', 'token', 'auth']] - Keys to mask.
|
|
399
711
|
* @returns {Record<string, string>} Environment variables with sensitive values masked.
|
|
712
|
+
*
|
|
713
|
+
* @example
|
|
714
|
+
* console.log(Env.getSafeEnv(['password', 'secret', 'key']));
|
|
715
|
+
* // { DATABASE_URL: "postgres://...", API_KEY: "******", ... }
|
|
400
716
|
*/
|
|
401
717
|
Env.getSafeEnv = function (sensitiveKeys) {
|
|
402
|
-
var
|
|
718
|
+
var e_2, _a;
|
|
403
719
|
if (sensitiveKeys === void 0) { sensitiveKeys = ['password', 'secret', 'key', 'token', 'auth']; }
|
|
404
720
|
var safeEnv = {};
|
|
405
721
|
var _loop_1 = function (key, value) {
|
|
@@ -414,15 +730,98 @@ var Env = /** @class */ (function () {
|
|
|
414
730
|
_loop_1(key, value);
|
|
415
731
|
}
|
|
416
732
|
}
|
|
417
|
-
catch (
|
|
733
|
+
catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
418
734
|
finally {
|
|
419
735
|
try {
|
|
420
736
|
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
421
737
|
}
|
|
422
|
-
finally { if (
|
|
738
|
+
finally { if (e_2) throw e_2.error; }
|
|
423
739
|
}
|
|
424
740
|
return safeEnv;
|
|
425
741
|
};
|
|
742
|
+
/**
|
|
743
|
+
* Loads environment variables from a .env file.
|
|
744
|
+
* Does not override existing variables.
|
|
745
|
+
*
|
|
746
|
+
* @param {string} [path='.env'] - Path to the .env file.
|
|
747
|
+
* @returns {Record<string, string>} Loaded environment variables.
|
|
748
|
+
*
|
|
749
|
+
* @example
|
|
750
|
+
* // Load variables from .env.development
|
|
751
|
+
* Env.loadFromFile('.env.development');
|
|
752
|
+
*/
|
|
753
|
+
Env.loadFromFile = function (path) {
|
|
754
|
+
if (path === void 0) { path = '.env'; }
|
|
755
|
+
if (!existsSync(path)) {
|
|
756
|
+
throw new Error("Environment file not found: \"".concat(path, "\""));
|
|
757
|
+
}
|
|
758
|
+
var content = readFileSync(path, 'utf8');
|
|
759
|
+
var variables = {};
|
|
760
|
+
var lines = content.split(/\r?\n/);
|
|
761
|
+
var i = 0;
|
|
762
|
+
while (i < lines.length) {
|
|
763
|
+
var line = lines[i].trim();
|
|
764
|
+
// Skip empty lines or comment-only lines
|
|
765
|
+
if (!line || line.startsWith('#')) {
|
|
766
|
+
i++;
|
|
767
|
+
continue;
|
|
768
|
+
}
|
|
769
|
+
var match = line.match(/^([^=]+)=(.*)$/);
|
|
770
|
+
if (!match) {
|
|
771
|
+
i++;
|
|
772
|
+
continue;
|
|
773
|
+
}
|
|
774
|
+
var key = match[1].trim();
|
|
775
|
+
var value = match[2].trim();
|
|
776
|
+
// Remove inline comment for unquoted values
|
|
777
|
+
if (!/^['"]/.test(value)) {
|
|
778
|
+
var hashIndex = value.indexOf(' #');
|
|
779
|
+
if (hashIndex !== -1) {
|
|
780
|
+
value = value.slice(0, hashIndex).trim();
|
|
781
|
+
}
|
|
782
|
+
}
|
|
783
|
+
// Handle quoted values
|
|
784
|
+
if ((value.startsWith('"') || value.startsWith("'")) && value.length > 1) {
|
|
785
|
+
var quote = value[0];
|
|
786
|
+
if (!value.endsWith(quote) || value.length === 1) {
|
|
787
|
+
// multiline quoted
|
|
788
|
+
var multilineValue = value.slice(1);
|
|
789
|
+
i++;
|
|
790
|
+
while (i < lines.length) {
|
|
791
|
+
var nextLine = lines[i];
|
|
792
|
+
if (nextLine.endsWith(quote)) {
|
|
793
|
+
multilineValue += '\n' + nextLine.slice(0, -1);
|
|
794
|
+
break;
|
|
795
|
+
}
|
|
796
|
+
else {
|
|
797
|
+
multilineValue += '\n' + nextLine;
|
|
798
|
+
}
|
|
799
|
+
i++;
|
|
800
|
+
}
|
|
801
|
+
value = multilineValue;
|
|
802
|
+
}
|
|
803
|
+
else {
|
|
804
|
+
// single-line quoted
|
|
805
|
+
value = value.slice(1, -1);
|
|
806
|
+
}
|
|
807
|
+
}
|
|
808
|
+
else {
|
|
809
|
+
// Handle unquoted multiline: continue collecting until next key=value or empty line
|
|
810
|
+
i++;
|
|
811
|
+
while (i < lines.length && !lines[i].includes('=') && lines[i].trim() !== '') {
|
|
812
|
+
value += '\n' + lines[i];
|
|
813
|
+
i++;
|
|
814
|
+
}
|
|
815
|
+
i--; // adjust for outer loop
|
|
816
|
+
}
|
|
817
|
+
if (!process.env[key]) {
|
|
818
|
+
process.env[key] = value;
|
|
819
|
+
variables[key] = value;
|
|
820
|
+
}
|
|
821
|
+
i++;
|
|
822
|
+
}
|
|
823
|
+
return variables;
|
|
824
|
+
};
|
|
426
825
|
/**
|
|
427
826
|
* Checks whether the specified environment variable exists.
|
|
428
827
|
*
|
|
@@ -439,8 +838,35 @@ var Env = /** @class */ (function () {
|
|
|
439
838
|
* @returns {void}
|
|
440
839
|
*/
|
|
441
840
|
Env.delete = function (key) {
|
|
841
|
+
var e_3, _a;
|
|
442
842
|
delete process.env[key];
|
|
843
|
+
this.cache.delete(key);
|
|
844
|
+
try {
|
|
845
|
+
// Also clear all cached variations of this key
|
|
846
|
+
for (var _b = __values(this.cache.keys()), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
847
|
+
var cacheKey = _c.value;
|
|
848
|
+
if (cacheKey.includes(":".concat(key))) {
|
|
849
|
+
this.cache.delete(cacheKey);
|
|
850
|
+
}
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
854
|
+
finally {
|
|
855
|
+
try {
|
|
856
|
+
if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
857
|
+
}
|
|
858
|
+
finally { if (e_3) throw e_3.error; }
|
|
859
|
+
}
|
|
860
|
+
};
|
|
861
|
+
/**
|
|
862
|
+
* Clears the internal cache of parsed environment values.
|
|
863
|
+
* Useful for testing or when environment variables might change.
|
|
864
|
+
*/
|
|
865
|
+
Env.clearCache = function () {
|
|
866
|
+
this.cache.clear();
|
|
443
867
|
};
|
|
868
|
+
// Cache for parsed values to avoid repeated parsing of complex values
|
|
869
|
+
Env.cache = new Map();
|
|
444
870
|
return Env;
|
|
445
871
|
}());
|
|
446
872
|
export { Env };
|