nestjs-env-getter 0.0.0-beta2

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 ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2023 Ivan Baha
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,2 @@
1
+ # nestjs-env-getter
2
+ The Nestjs Module for getting environment variables at app start
@@ -0,0 +1,2 @@
1
+ export declare class EnvGetterModule {
2
+ }
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.EnvGetterModule = void 0;
10
+ const common_1 = require("@nestjs/common");
11
+ const env_getter_service_1 = require("./env-getter.service");
12
+ let EnvGetterModule = class EnvGetterModule {
13
+ };
14
+ exports.EnvGetterModule = EnvGetterModule;
15
+ exports.EnvGetterModule = EnvGetterModule = __decorate([
16
+ (0, common_1.Module)({
17
+ providers: [env_getter_service_1.EnvGetterService],
18
+ exports: [env_getter_service_1.EnvGetterService],
19
+ })
20
+ ], EnvGetterModule);
@@ -0,0 +1,226 @@
1
+ import { type ClassConstructor, type TimeMarker } from "../shared";
2
+ import { type ArrayValidatorType } from "./types";
3
+ export declare class EnvGetterService {
4
+ constructor();
5
+ /**
6
+ * Logs an error message in red and terminates the process.
7
+ * @param message - The error message to display before exiting.
8
+ * @throws Never returns; always exits the process.
9
+ * @private
10
+ */
11
+ private stopProcess;
12
+ /**
13
+ * Checks if an environment variable exists.
14
+ * - If the variable is missing, the process is terminated.
15
+ * - If the variable exists, returns `true`.
16
+ * @param envName - The name of the environment variable to check.
17
+ * @returns `true` if the environment variable exists.
18
+ * @throws Terminates the process if the variable is missing.
19
+ * @private
20
+ */
21
+ private checkEnvExisting;
22
+ /**
23
+ * Validates whether an environment variable contains an allowed value.
24
+ * - If the variable's value is not in the allowed list, the process is terminated.
25
+ * @param envName - The name of the environment variable.
26
+ * @param envVal - The current value of the environment variable.
27
+ * @param allowedValues - An array of allowed values for the variable.
28
+ * @throws Terminates the process if `envVal` is not in the allowed list.
29
+ * @private
30
+ */
31
+ private checkIfEnvHasAllowedValue;
32
+ /**
33
+ * Checks whether an environment variable is set.
34
+ * @param envName - The name of the environment variable.
35
+ * @returns `true` if the environment variable exists, otherwise `false`.
36
+ */
37
+ isEnvSet(envName: string): boolean;
38
+ /**
39
+ * Retrieves the value of a required environment variable.
40
+ * - Ensures that the variable exists; otherwise, the process is terminated.
41
+ * - If `allowedValues` is provided, checks whether the variable contains an allowed value.
42
+ * @param envName - The name of the required environment variable.
43
+ * @param allowedValues - (Optional) A list of allowed values for validation.
44
+ * @returns The environment variable value as a string.
45
+ * @throws Terminates the process if the variable is missing or contains an invalid value.
46
+ */
47
+ getRequiredEnv(envName: string): string;
48
+ getRequiredEnv(envName: string, allowedValues: string[]): string;
49
+ /**
50
+ * Retrieves the value of an optional environment variable.
51
+ * - If the variable is set, returns its value.
52
+ * - If `defaultValue` is provided and the variable is not set, returns the default value.
53
+ * - If `allowedValues` is provided, validates that the variable (or default value) is within the allowed list.
54
+ * @param envName - The name of the environment variable.
55
+ * @param defaultValue - (Optional) The default value to return if the environment variable is not set.
56
+ * @param allowedValues - (Optional) An array of allowed values for validation.
57
+ * @returns The environment variable value, the default value, or `undefined` if not set.
58
+ * @throws Terminates the process if the value is not in `allowedValues` (if provided).
59
+ */
60
+ getOptionalEnv(envName: string): string | undefined;
61
+ getOptionalEnv(envName: string, defaultValue: string): string;
62
+ getOptionalEnv(envName: string, allowedValues: string[]): string | undefined;
63
+ getOptionalEnv(envName: string, defaultValue: string, allowedValues: string[]): string | undefined;
64
+ /**
65
+ * Retrieves and validates a required numeric environment variable.
66
+ * - Ensures the variable is set and contains only numeric characters (or underscores).
67
+ * - Converts the value to a number.
68
+ * - Terminates the process if the value is not numeric.
69
+ * @param envName - The name of the environment variable.
70
+ * @returns The numeric value of the environment variable.
71
+ * @throws Terminates the process if the variable is missing or not numeric.
72
+ */
73
+ getRequiredNumericEnv(envName: string): number;
74
+ /**
75
+ * Retrieves an optional numeric environment variable.
76
+ * - If the variable is set and numeric, returns its numeric value.
77
+ * - If `defaultValue` is provided and the variable is not set or invalid, returns the default value.
78
+ * @param envName - The name of the environment variable.
79
+ * @param defaultValue - (Optional) The default numeric value to return if the variable is not set.
80
+ * @returns The numeric value of the environment variable or the default value.
81
+ */
82
+ getOptionalNumericEnv(envName: string): number | undefined;
83
+ getOptionalNumericEnv(envName: string, defaultValue: number): number;
84
+ /**
85
+ * Retrieves and validates a required boolean environment variable.
86
+ * - Ensures the variable is set and contains either `"true"` or `"false"`.
87
+ * - Converts the value to a boolean.
88
+ * - Terminates the process if the value is not a valid boolean.
89
+ * @param envName - The name of the environment variable.
90
+ * @returns The boolean value of the environment variable.
91
+ * @throws Terminates the process if the variable is missing or not `"true"`/`"false"`.
92
+ */
93
+ getRequiredBooleanEnv(envName: string): boolean;
94
+ /**
95
+ * Retrieves an optional boolean environment variable.
96
+ * - If the variable is set, returns `true` for `"true"` and `false` for `"false"`.
97
+ * - If `defaultValue` is provided and the variable is not set, returns the default value.
98
+ * @param envName - The name of the environment variable.
99
+ * @param defaultValue - (Optional) The default boolean value if the variable is not set.
100
+ * @returns The boolean value of the environment variable or the default value.
101
+ */
102
+ getOptionalBooleanEnv(envName: string): boolean | undefined;
103
+ getOptionalBooleanEnv(envName: string, defaultValue: boolean): boolean;
104
+ /**
105
+ * Retrieves and validates a required environment variable as a URL.
106
+ * - Ensures the variable is set and contains a valid URL.
107
+ * - Terminates the process if the value is not a valid URL.
108
+ * @param envName - The name of the environment variable.
109
+ * @returns A `URL` object representing the value of the environment variable.
110
+ * @throws Terminates the process if the variable is missing or not a valid URL.
111
+ */
112
+ getRequiredURL(envName: string): URL;
113
+ /**
114
+ * Retrieves an optional environment variable as a URL.
115
+ * - If the variable is set and a valid URL, returns a `URL` object.
116
+ * - If `defaultValue` is provided and the variable is not set, returns the default `URL`.
117
+ * - Terminates the process if the variable is set but not a valid URL.
118
+ * @param envName - The name of the environment variable.
119
+ * @param defaultValue - (Optional) The default URL value to return if the variable is not set.
120
+ * @returns A `URL` object representing the value of the environment variable or the default value.
121
+ * @throws Terminates the process if the variable is set but not a valid URL.
122
+ */
123
+ getOptionalURL(envName: string): URL | undefined;
124
+ getOptionalURL(envName: string, defaultValue: URL): URL;
125
+ /**
126
+ * Retrieves and parses a required time period from an environment variable.
127
+ * - Ensures the environment variable is set and retrieves its value.
128
+ * - Validates that the value follows the format: `<number><"ms"|"s"|"m"|"h"|"d">`.
129
+ * - Converts the value to the specified time format.
130
+ * - Terminates the process if the value is missing or invalid.
131
+ * @param envName - The name of the required environment variable.
132
+ * @param resultIn - The desired time unit for the result (default is `"ms"`).
133
+ * @returns The parsed time period converted to the specified unit.
134
+ * @throws Will stop the process if the environment variable is missing or has an invalid format.
135
+ */
136
+ getRequiredTimePeriod(envName: string, resultIn?: TimeMarker): number;
137
+ /**
138
+ * Retrieves and parses an optional time period from an environment variable.
139
+ * - If the environment variable is not set, it falls back to the provided default value.
140
+ * - Validates that the value is in the acceptable format: `<number><"ms"|"s"|"m"|"h"|"d">`.
141
+ * - Converts the value to the specified time format.
142
+ * - Terminates the process if the value is invalid.
143
+ * @param envName - The name of the environment variable to retrieve.
144
+ * @param defaultValue - The default time period to use if the environment variable is not set.
145
+ * @param resultIn - The desired time unit for the result (default is `"ms"`).
146
+ * @returns The parsed time period converted to the specified unit.
147
+ * @throws Will stop the process if the environment variable or default value is invalid.
148
+ */
149
+ getOptionalTimePeriod(envName: string, defaultValue: string, resultIn?: TimeMarker): number;
150
+ /**
151
+ * Retrieves and parses a required environment variable as an object.
152
+ * - Ensures the environment variable is set.
153
+ * - Parses the value from a JSON string into an object.
154
+ * - Optionally validates and instantiates the object using a provided class.
155
+ * - Terminates the process if parsing fails or if instantiation using the class fails.
156
+ * @template R - The expected type of the parsed object.
157
+ * @param envName - The name of the environment variable.
158
+ * @param cls - (Optional) A class constructor to validate and instantiate the parsed object.
159
+ * @returns The parsed object, optionally instantiated as an instance of `cls`.
160
+ * @throws Terminates the process if the environment variable is missing, cannot be parsed, or fails validation.
161
+ * @example
162
+ * // Define a class for validation
163
+ * class Config {
164
+ * apiKey: string;
165
+ * timeout: number;
166
+ *
167
+ * constructor(data: { apiKey: string; timeout: number }) {
168
+ * if (!data.apiKey) throw new Error("apiKey is required");
169
+ * if (typeof data.timeout !== "number") throw new Error("timeout must be a number");
170
+ * this.apiKey = data.apiKey;
171
+ * this.timeout = data.timeout;
172
+ * }
173
+ * }
174
+ *
175
+ * // Set the environment variable (e.g., process.env.CONFIG = '{"apiKey": "123", "timeout": 5000"}')
176
+ * const config = getRequiredObject<Config>("CONFIG", Config);
177
+ * console.log(config.apiKey); // "123"
178
+ * console.log(config.timeout); // 5000
179
+ */
180
+ getRequiredObject<R = any, C extends ClassConstructor<any> | undefined = undefined>(envName: string, cls?: C): C extends ClassConstructor<infer T> ? T : R;
181
+ /**
182
+ * Retrieves and parses an environment variable as an array.
183
+ * @template R - The expected type of array elements.
184
+ * @param envName - The name of the environment variable to retrieve.
185
+ * @param validationOptions - Optional validation settings.
186
+ * @param validationOptions.optional - If `true`, allows the environment variable to be absent.
187
+ * @param validationOptions.validate - A function to validate each array element.
188
+ * @returns The parsed array or `undefined` if optional.
189
+ * @throws If the environment variable is missing, cannot be parsed, is not an array, or fails validation.
190
+ * @example
191
+ * this.forwardHeaders = this.envService.parseArrayFromEnv<string>('FORWARD_HEADERS');
192
+ * @example
193
+ * this.forwardHeaders = this.envService.parseArrayFromEnv<string>('FORWARD_HEADERS', {
194
+ * optional: true,
195
+ * validate: (el) => typeof el === 'string'
196
+ * });
197
+ * @example
198
+ * this.forwardHeaders = this.envService.parseArrayFromEnv<[string, number]>('FORWARD_HEADERS', {
199
+ * optional: true,
200
+ * validate: (el, i, arr) => {
201
+ * if (arr?.length !== 2) return 'FORWARD_HEADERS must be an array of 2 valid items';
202
+ * if (i === 0 && typeof el === 'string') return true;
203
+ * if (i === 1 && typeof el === 'number') return true;
204
+ * return false;
205
+ * }
206
+ * });
207
+ * @example
208
+ * this.forwardHeaders = this.envService.parseArrayFromEnv<[string, number]>('FORWARD_HEADERS', {
209
+ * optional: true,
210
+ * validate: (el, i) => {
211
+ * if (i === 0 && typeof el !== 'string') return 'FORWARD_HEADERS[0] must be a string';
212
+ * if (i === 1 && typeof el !== 'number') return 'FORWARD_HEADERS[1] must be a number';
213
+ * return true;
214
+ * }
215
+ * });
216
+ */
217
+ getRequiredArray<R = any>(envName: string): R extends any[] ? R : R[];
218
+ getRequiredArray<R = any>(envName: string, validationOptions: {
219
+ optional: true;
220
+ validate?: ArrayValidatorType<R>;
221
+ }): (R extends any[] ? R : R[]) | undefined;
222
+ getRequiredArray<R = any>(envName: string, validationOptions: {
223
+ optional?: false | undefined;
224
+ validate?: ArrayValidatorType<R>;
225
+ }): R extends any[] ? R : R[];
226
+ }
@@ -0,0 +1,272 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ var __metadata = (this && this.__metadata) || function (k, v) {
9
+ if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.EnvGetterService = void 0;
13
+ const common_1 = require("@nestjs/common");
14
+ const dotenv_1 = require("dotenv");
15
+ const shared_1 = require("../shared");
16
+ let EnvGetterService = class EnvGetterService {
17
+ constructor() {
18
+ (0, dotenv_1.config)();
19
+ }
20
+ /**
21
+ * Logs an error message in red and terminates the process.
22
+ * @param message - The error message to display before exiting.
23
+ * @throws Never returns; always exits the process.
24
+ * @private
25
+ */
26
+ stopProcess(message) {
27
+ // eslint-disable-next-line no-console
28
+ console.log("\x1b[31m%s\x1b[0m", message);
29
+ process.exit(1);
30
+ }
31
+ /**
32
+ * Checks if an environment variable exists.
33
+ * - If the variable is missing, the process is terminated.
34
+ * - If the variable exists, returns `true`.
35
+ * @param envName - The name of the environment variable to check.
36
+ * @returns `true` if the environment variable exists.
37
+ * @throws Terminates the process if the variable is missing.
38
+ * @private
39
+ */
40
+ checkEnvExisting(envName) {
41
+ if (!process.env.hasOwnProperty(envName))
42
+ this.stopProcess(`Missing '${envName}' environment variable`);
43
+ return true;
44
+ }
45
+ /**
46
+ * Validates whether an environment variable contains an allowed value.
47
+ * - If the variable's value is not in the allowed list, the process is terminated.
48
+ * @param envName - The name of the environment variable.
49
+ * @param envVal - The current value of the environment variable.
50
+ * @param allowedValues - An array of allowed values for the variable.
51
+ * @throws Terminates the process if `envVal` is not in the allowed list.
52
+ * @private
53
+ */
54
+ checkIfEnvHasAllowedValue(envName, envVal, allowedValues) {
55
+ if (!envVal || !allowedValues.includes(envVal))
56
+ this.stopProcess(`Variable '${envName}' can be only one of: [${allowedValues}], but received '${envVal}'`);
57
+ }
58
+ /**
59
+ * Checks whether an environment variable is set.
60
+ * @param envName - The name of the environment variable.
61
+ * @returns `true` if the environment variable exists, otherwise `false`.
62
+ */
63
+ isEnvSet(envName) {
64
+ return process.env.hasOwnProperty(envName);
65
+ }
66
+ getRequiredEnv(envName, allowedValues) {
67
+ var _a;
68
+ this.checkEnvExisting(envName);
69
+ if (allowedValues === null || allowedValues === void 0 ? void 0 : allowedValues.length)
70
+ this.checkIfEnvHasAllowedValue(envName, (_a = process.env[envName]) !== null && _a !== void 0 ? _a : null, allowedValues);
71
+ return String(process.env[envName]);
72
+ }
73
+ getOptionalEnv(envName, defaultValueOrAllowedValues, allowedValues) {
74
+ if (Array.isArray(defaultValueOrAllowedValues)) {
75
+ const envValue = process.env[envName];
76
+ this.checkIfEnvHasAllowedValue(envName, envValue !== null && envValue !== void 0 ? envValue : null, defaultValueOrAllowedValues);
77
+ return envValue;
78
+ }
79
+ else {
80
+ const envValue = process.env[envName] || defaultValueOrAllowedValues;
81
+ if (allowedValues === null || allowedValues === void 0 ? void 0 : allowedValues.length)
82
+ this.checkIfEnvHasAllowedValue(envName, envValue !== null && envValue !== void 0 ? envValue : null, allowedValues);
83
+ return envValue;
84
+ }
85
+ }
86
+ /**
87
+ * Retrieves and validates a required numeric environment variable.
88
+ * - Ensures the variable is set and contains only numeric characters (or underscores).
89
+ * - Converts the value to a number.
90
+ * - Terminates the process if the value is not numeric.
91
+ * @param envName - The name of the environment variable.
92
+ * @returns The numeric value of the environment variable.
93
+ * @throws Terminates the process if the variable is missing or not numeric.
94
+ */
95
+ getRequiredNumericEnv(envName) {
96
+ const envVal = this.getRequiredEnv(envName);
97
+ if (!/^[0-9_]+$/.test(envVal))
98
+ this.stopProcess(`Variable '${envName}' is not of number type.`);
99
+ return Number(envVal.replace(/_/g, ""));
100
+ }
101
+ getOptionalNumericEnv(envName, defaultValue) {
102
+ const envVal = String(process.env[envName]);
103
+ return /^[0-9_]+$/.test(envVal) ? Number(envVal.replace(/_/g, "")) : defaultValue;
104
+ }
105
+ /**
106
+ * Retrieves and validates a required boolean environment variable.
107
+ * - Ensures the variable is set and contains either `"true"` or `"false"`.
108
+ * - Converts the value to a boolean.
109
+ * - Terminates the process if the value is not a valid boolean.
110
+ * @param envName - The name of the environment variable.
111
+ * @returns The boolean value of the environment variable.
112
+ * @throws Terminates the process if the variable is missing or not `"true"`/`"false"`.
113
+ */
114
+ getRequiredBooleanEnv(envName) {
115
+ const envVal = this.getRequiredEnv(envName);
116
+ if (!/true|false/.test(envVal))
117
+ this.stopProcess(`Variable '${envName}' is not of boolean type.`);
118
+ return envVal === "true";
119
+ }
120
+ getOptionalBooleanEnv(envName, defaultValue) {
121
+ return process.env[envName] ? process.env[envName] === "true" : defaultValue;
122
+ }
123
+ /**
124
+ * Retrieves and validates a required environment variable as a URL.
125
+ * - Ensures the variable is set and contains a valid URL.
126
+ * - Terminates the process if the value is not a valid URL.
127
+ * @param envName - The name of the environment variable.
128
+ * @returns A `URL` object representing the value of the environment variable.
129
+ * @throws Terminates the process if the variable is missing or not a valid URL.
130
+ */
131
+ getRequiredURL(envName) {
132
+ const envVal = this.getRequiredEnv(envName);
133
+ try {
134
+ return new URL(envVal);
135
+ }
136
+ catch (err) {
137
+ this.stopProcess(`Variable '${envName}' must be a valid URL. Error: ${err instanceof Error ? err.message : JSON.stringify(err)}`);
138
+ }
139
+ }
140
+ getOptionalURL(envName, defaultValue) {
141
+ const envVal = this.getOptionalEnv(envName);
142
+ try {
143
+ return envVal ? new URL(envVal) : defaultValue;
144
+ }
145
+ catch (err) {
146
+ this.stopProcess(`Variable '${envName}' must be a valid URL. Error: ${err instanceof Error ? err.message : JSON.stringify(err)}`);
147
+ }
148
+ }
149
+ /**
150
+ * Retrieves and parses a required time period from an environment variable.
151
+ * - Ensures the environment variable is set and retrieves its value.
152
+ * - Validates that the value follows the format: `<number><"ms"|"s"|"m"|"h"|"d">`.
153
+ * - Converts the value to the specified time format.
154
+ * - Terminates the process if the value is missing or invalid.
155
+ * @param envName - The name of the required environment variable.
156
+ * @param resultIn - The desired time unit for the result (default is `"ms"`).
157
+ * @returns The parsed time period converted to the specified unit.
158
+ * @throws Will stop the process if the environment variable is missing or has an invalid format.
159
+ */
160
+ getRequiredTimePeriod(envName, resultIn = "ms") {
161
+ const envVal = this.getRequiredEnv(envName);
162
+ // validating the ENV value
163
+ if (!(0, shared_1.isTimePeriod)(envVal))
164
+ this.stopProcess(`Variable '${envName}' is not in the acceptable format. It must be: <number><"ms"|"s"|"m"|"h"|"d">. Ex.: '12h', '2d', '2D', '2 d'`);
165
+ return (0, shared_1.parseTimePeriod)(envVal, resultIn);
166
+ }
167
+ /**
168
+ * Retrieves and parses an optional time period from an environment variable.
169
+ * - If the environment variable is not set, it falls back to the provided default value.
170
+ * - Validates that the value is in the acceptable format: `<number><"ms"|"s"|"m"|"h"|"d">`.
171
+ * - Converts the value to the specified time format.
172
+ * - Terminates the process if the value is invalid.
173
+ * @param envName - The name of the environment variable to retrieve.
174
+ * @param defaultValue - The default time period to use if the environment variable is not set.
175
+ * @param resultIn - The desired time unit for the result (default is `"ms"`).
176
+ * @returns The parsed time period converted to the specified unit.
177
+ * @throws Will stop the process if the environment variable or default value is invalid.
178
+ */
179
+ getOptionalTimePeriod(envName, defaultValue, resultIn = "ms") {
180
+ const baseErrorMessage = `'${envName}' is not in the acceptable format. It must be: <number><"ms"|"s"|"m"|"h"|"d">. Ex.: '12h', '2d', '2D', '2 d'`;
181
+ // validating the default value
182
+ if (!(0, shared_1.isTimePeriod)(defaultValue))
183
+ this.stopProcess(`The default value for the environment variable ${baseErrorMessage}`);
184
+ const envVal = process.env[envName];
185
+ // validating the ENV value
186
+ if (envVal && !(0, shared_1.isTimePeriod)(envVal))
187
+ this.stopProcess(`Variable ${baseErrorMessage}`);
188
+ return (0, shared_1.parseTimePeriod)(envVal !== null && envVal !== void 0 ? envVal : defaultValue, resultIn);
189
+ }
190
+ /**
191
+ * Retrieves and parses a required environment variable as an object.
192
+ * - Ensures the environment variable is set.
193
+ * - Parses the value from a JSON string into an object.
194
+ * - Optionally validates and instantiates the object using a provided class.
195
+ * - Terminates the process if parsing fails or if instantiation using the class fails.
196
+ * @template R - The expected type of the parsed object.
197
+ * @param envName - The name of the environment variable.
198
+ * @param cls - (Optional) A class constructor to validate and instantiate the parsed object.
199
+ * @returns The parsed object, optionally instantiated as an instance of `cls`.
200
+ * @throws Terminates the process if the environment variable is missing, cannot be parsed, or fails validation.
201
+ * @example
202
+ * // Define a class for validation
203
+ * class Config {
204
+ * apiKey: string;
205
+ * timeout: number;
206
+ *
207
+ * constructor(data: { apiKey: string; timeout: number }) {
208
+ * if (!data.apiKey) throw new Error("apiKey is required");
209
+ * if (typeof data.timeout !== "number") throw new Error("timeout must be a number");
210
+ * this.apiKey = data.apiKey;
211
+ * this.timeout = data.timeout;
212
+ * }
213
+ * }
214
+ *
215
+ * // Set the environment variable (e.g., process.env.CONFIG = '{"apiKey": "123", "timeout": 5000"}')
216
+ * const config = getRequiredObject<Config>("CONFIG", Config);
217
+ * console.log(config.apiKey); // "123"
218
+ * console.log(config.timeout); // 5000
219
+ */
220
+ getRequiredObject(envName, cls) {
221
+ const envVal = this.getRequiredEnv(envName);
222
+ const baseErrorMessage = `Cannot parse object from variable '${envName}'. Error:`;
223
+ let parsedObj;
224
+ try {
225
+ parsedObj = JSON.parse(envVal);
226
+ }
227
+ catch (error) {
228
+ this.stopProcess(`${baseErrorMessage} ${error.message}`);
229
+ }
230
+ if (!cls)
231
+ return parsedObj;
232
+ try {
233
+ return new cls(parsedObj);
234
+ }
235
+ catch (error) {
236
+ this.stopProcess(`${baseErrorMessage} ${error.message}`);
237
+ }
238
+ }
239
+ getRequiredArray(envName, validationOptions) {
240
+ if ((validationOptions === null || validationOptions === void 0 ? void 0 : validationOptions.optional) && !this.isEnvSet(envName))
241
+ return;
242
+ const envVal = this.getRequiredEnv(envName);
243
+ const baseErrorMessage = `Cannot parse object from variable '${envName}'. Error:`;
244
+ let parsedArray;
245
+ try {
246
+ parsedArray = JSON.parse(envVal);
247
+ }
248
+ catch (error) {
249
+ this.stopProcess(`${baseErrorMessage} ${error.message}`);
250
+ }
251
+ if (!Array.isArray(parsedArray))
252
+ this.stopProcess(`'${envName}' must be a stringified array`);
253
+ if (typeof (validationOptions === null || validationOptions === void 0 ? void 0 : validationOptions.validate) === "function") {
254
+ // validate each element of parsed array
255
+ parsedArray.forEach((el, i) => {
256
+ const result = validationOptions.validate(el, i, parsedArray);
257
+ // check if validator works correct
258
+ if (!["boolean", "string"].includes(typeof result) || result === "")
259
+ this.stopProcess(`The validation func of EnvGetterService.getRequiredArray('${envName}') must return either boolean or string\nTrace ${new Error().stack}`);
260
+ // validate element
261
+ if (result === false || (typeof result === "string" && result))
262
+ this.stopProcess(typeof result === "string" ? result : `'${envName}[${i}]' failed validation`);
263
+ });
264
+ }
265
+ return parsedArray;
266
+ }
267
+ };
268
+ exports.EnvGetterService = EnvGetterService;
269
+ exports.EnvGetterService = EnvGetterService = __decorate([
270
+ (0, common_1.Injectable)(),
271
+ __metadata("design:paramtypes", [])
272
+ ], EnvGetterService);
@@ -0,0 +1 @@
1
+ export type ArrayValidatorType<R = any> = (el: unknown, index?: number, array?: R extends any[] ? R : R[]) => boolean | string;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export { ArrayValidatorType } from "./array-validator.type";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,3 @@
1
+ export { EnvGetterModule } from "./env-getter/env-getter.module";
2
+ export { EnvGetterService } from "./env-getter/env-getter.service";
3
+ export * from "./shared/types";
package/dist/index.js ADDED
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.EnvGetterService = exports.EnvGetterModule = void 0;
18
+ var env_getter_module_1 = require("./env-getter/env-getter.module");
19
+ Object.defineProperty(exports, "EnvGetterModule", { enumerable: true, get: function () { return env_getter_module_1.EnvGetterModule; } });
20
+ var env_getter_service_1 = require("./env-getter/env-getter.service");
21
+ Object.defineProperty(exports, "EnvGetterService", { enumerable: true, get: function () { return env_getter_service_1.EnvGetterService; } });
22
+ __exportStar(require("./shared/types"), exports);
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export * from "./utils";
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./types"), exports);
18
+ __exportStar(require("./utils"), exports);
@@ -0,0 +1,3 @@
1
+ export type ClassConstructor<T = unknown> = {
2
+ new (...args: any[]): T;
3
+ };
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,2 @@
1
+ export { ClassConstructor } from "./class-constructor.type";
2
+ export { TimeMarker } from "./time-marker.type";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export type TimeMarker = "ms" | "s" | "m" | "h" | "d";
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1 @@
1
+ export { isTimePeriod, parseTimePeriod } from "./time-period.utils";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.parseTimePeriod = exports.isTimePeriod = void 0;
4
+ var time_period_utils_1 = require("./time-period.utils");
5
+ Object.defineProperty(exports, "isTimePeriod", { enumerable: true, get: function () { return time_period_utils_1.isTimePeriod; } });
6
+ Object.defineProperty(exports, "parseTimePeriod", { enumerable: true, get: function () { return time_period_utils_1.parseTimePeriod; } });
@@ -0,0 +1,21 @@
1
+ import { type TimeMarker } from "../types";
2
+ /**
3
+ * Checks if the given value represents a valid time period.
4
+ *
5
+ * A valid time period can be:
6
+ * - A number (interpreted as milliseconds).
7
+ * - A string containing digits optionally followed by a time unit (`s`, `m`, `h`, or `d`).
8
+ * @param value - The value to check.
9
+ * @returns `true` if the value is a valid time period, otherwise `false`.
10
+ */
11
+ export declare function isTimePeriod(value: string | number): boolean;
12
+ /**
13
+ * Parses a time period value and converts it to the specified unit.
14
+ * - If the input is a number, it is returned as is.
15
+ * - If the input is a string, it extracts the numeric value and optional time unit (`s`, `m`, `h`, `d`).
16
+ * - Converts the extracted value to the desired unit using predefined multipliers.
17
+ * @param value - The time period to parse, either a number or a string with an optional time unit.
18
+ * @param resultIn - The unit to convert the result into, defaults to milliseconds.
19
+ * @returns The parsed time value converted to the specified unit, or `NaN` if the input is invalid.
20
+ */
21
+ export declare function parseTimePeriod(value: string | number, resultIn?: TimeMarker): number;
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.isTimePeriod = isTimePeriod;
4
+ exports.parseTimePeriod = parseTimePeriod;
5
+ const timeMarkersMapper = {
6
+ ms: 1,
7
+ s: 1000,
8
+ m: 60000,
9
+ h: 3600000,
10
+ d: 86400000,
11
+ };
12
+ const timePeriodStringRegex = /^(\d+)\s*(ms|s|m|h|d)?$/i;
13
+ /**
14
+ * Checks if the given value represents a valid time period.
15
+ *
16
+ * A valid time period can be:
17
+ * - A number (interpreted as milliseconds).
18
+ * - A string containing digits optionally followed by a time unit (`s`, `m`, `h`, or `d`).
19
+ * @param value - The value to check.
20
+ * @returns `true` if the value is a valid time period, otherwise `false`.
21
+ */
22
+ function isTimePeriod(value) {
23
+ if (typeof value === "number")
24
+ return true;
25
+ if (typeof value === "string")
26
+ return timePeriodStringRegex.test(value.replace(/_/g, ""));
27
+ return false;
28
+ }
29
+ /**
30
+ * Parses a time period value and converts it to the specified unit.
31
+ * - If the input is a number, it is returned as is.
32
+ * - If the input is a string, it extracts the numeric value and optional time unit (`s`, `m`, `h`, `d`).
33
+ * - Converts the extracted value to the desired unit using predefined multipliers.
34
+ * @param value - The time period to parse, either a number or a string with an optional time unit.
35
+ * @param resultIn - The unit to convert the result into, defaults to milliseconds.
36
+ * @returns The parsed time value converted to the specified unit, or `NaN` if the input is invalid.
37
+ */
38
+ function parseTimePeriod(value, resultIn = "ms") {
39
+ var _a;
40
+ if (typeof value === "number")
41
+ return value;
42
+ if (typeof value === "string") {
43
+ const [, numb, pointer] = (_a = timePeriodStringRegex.exec(value.replace(/_/g, ""))) !== null && _a !== void 0 ? _a : [];
44
+ const timePointer = ((pointer === null || pointer === void 0 ? void 0 : pointer.toLowerCase()) || "ms");
45
+ const multiplier = resultIn === timePointer ? 1 : timeMarkersMapper[timePointer] / timeMarkersMapper[resultIn];
46
+ return Math.ceil(Number(numb) * multiplier);
47
+ }
48
+ return NaN;
49
+ }
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "nestjs-env-getter",
3
+ "version": "0.0.0-beta2",
4
+ "description": "Environment variables getter for Nestjs applications",
5
+ "author": "Ivan Baha",
6
+ "private": false,
7
+ "main": "dist/index.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist"
11
+ ],
12
+ "publishConfig": {
13
+ "access": "public",
14
+ "registry": "https://registry.npmjs.org"
15
+ },
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/Foboss6/nestjs-env-getter.git"
19
+ },
20
+ "license": "MIT",
21
+ "scripts": {
22
+ "prebuild": "rm -rf dist",
23
+ "build": "tsc --p tsconfig.build.json",
24
+ "format": "prettier --write \"src/**/*.ts\" \"test/**/*.ts\"",
25
+ "lint": "eslint --fix",
26
+ "lint:report": "eslint",
27
+ "test": "jest",
28
+ "test:report": "jest --ci --coverage --runInBand",
29
+ "typecheck": "tsc --noEmit"
30
+ },
31
+ "peerDependencies": {
32
+ "@nestjs/common": ">=9"
33
+ },
34
+ "dependencies": {
35
+ "dotenv": "16.5.0"
36
+ },
37
+ "devDependencies": {
38
+ "@eslint/js": "^9.26.0",
39
+ "@nestjs/common": "11.1.0",
40
+ "@nestjs/core": "11.1.0",
41
+ "@nestjs/testing": "11.1.0",
42
+ "@types/jest": "^29.5.14",
43
+ "@types/node": "^22.15.16",
44
+ "eslint": "^9.26.0",
45
+ "eslint-config-prettier": "^10.0.3",
46
+ "eslint-plugin-jsdoc": "^50.6.11",
47
+ "eslint-plugin-prettier": "^5.4.0",
48
+ "globals": "^16.1.0",
49
+ "jest": "^29.7.0",
50
+ "prettier": "^3.5.3",
51
+ "reflect-metadata": "^0.2.2",
52
+ "rxjs": "^7.8.2",
53
+ "ts-jest": "^29.3.2",
54
+ "typescript": "^5.8.3",
55
+ "typescript-eslint": "^8.32.0"
56
+ }
57
+ }