envapt 1.1.0 → 2.1.0

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/dist/index.js DELETED
@@ -1,621 +0,0 @@
1
- import { config } from 'dotenv';
2
-
3
- var __defProp = Object.defineProperty;
4
- var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
5
-
6
- // src/Error.ts
7
- var EnvaptErrorCodes = {
8
- InvalidFallback: 617404,
9
- MissingDelimiter: 967308,
10
- InvalidArrayConverterType: 193159,
11
- InvalidBuiltInConverter: 337271,
12
- InvalidConverterType: 453217,
13
- InvalidCustomConverter: 789432
14
- };
15
- var ReversedEnvaptErrorCodes = Object.fromEntries(
16
- Object.entries(EnvaptErrorCodes).map(([key, value]) => [value, key])
17
- );
18
- var EnvaptError = class _EnvaptError extends Error {
19
- static {
20
- __name(this, "EnvaptError");
21
- }
22
- code;
23
- constructor(code, message) {
24
- super(message);
25
- this.name = `${ReversedEnvaptErrorCodes[code]} [${code}]`;
26
- this.code = code;
27
- Error.captureStackTrace(this, _EnvaptError);
28
- }
29
- };
30
-
31
- // src/ListOfBuiltInConverters.ts
32
- var ListOfBuiltInConverters = [
33
- "string",
34
- "number",
35
- "boolean",
36
- "bigint",
37
- "symbol",
38
- "integer",
39
- "float",
40
- "json",
41
- "array",
42
- "url",
43
- "regexp",
44
- "date",
45
- "time"
46
- ];
47
-
48
- // src/Validators.ts
49
- var Validator = class {
50
- static {
51
- __name(this, "Validator");
52
- }
53
- /**
54
- * Check if a value is a built-in converter type
55
- */
56
- static isBuiltInConverter(value) {
57
- if (typeof value === "string") return ListOfBuiltInConverters.includes(value);
58
- return false;
59
- }
60
- /**
61
- * Check if a value is an ArrayConverter configuration object
62
- */
63
- static isArrayConverter(value) {
64
- return typeof value === "object" && value !== null && "delimiter" in value && typeof value.delimiter === "string";
65
- }
66
- /**
67
- * Check if a value is a valid ArrayConverter type
68
- */
69
- static isValidArrayConverterType(value) {
70
- if (typeof value !== "string") return false;
71
- const invalidTypes = ["array", "json", "regexp"];
72
- if (invalidTypes.includes(value)) return false;
73
- const validTypes = ListOfBuiltInConverters.filter(
74
- (type) => !invalidTypes.includes(type)
75
- );
76
- return validTypes.includes(value);
77
- }
78
- /**
79
- * Check if a value is a valid custom converter function
80
- */
81
- static isValidConverterFunction(converter) {
82
- return typeof converter === "function";
83
- }
84
- static customConvertor(converter) {
85
- if (typeof converter !== "function") {
86
- throw new EnvaptError(
87
- EnvaptErrorCodes.InvalidCustomConverter,
88
- `Custom converter must be a function, got ${typeof converter}.`
89
- );
90
- }
91
- }
92
- /**
93
- * Validate ArrayConverter configuration with runtime checks
94
- */
95
- static arrayConverter(value) {
96
- if (!this.isArrayConverter(value)) {
97
- throw new EnvaptError(EnvaptErrorCodes.MissingDelimiter, "Must have delimiter property");
98
- }
99
- if (value.type !== void 0 && !this.isValidArrayConverterType(value.type)) {
100
- throw new EnvaptError(
101
- EnvaptErrorCodes.InvalidArrayConverterType,
102
- `"${value.type}" is not a valid converter type`
103
- );
104
- }
105
- }
106
- /**
107
- * Validate that a string is a valid built-in converter type
108
- */
109
- static builtInConverter(value) {
110
- if (typeof value !== "string") {
111
- throw new EnvaptError(EnvaptErrorCodes.InvalidConverterType, `Expected string, got ${typeof value}`);
112
- }
113
- if (!ListOfBuiltInConverters.includes(value)) {
114
- throw new EnvaptError(
115
- EnvaptErrorCodes.InvalidBuiltInConverter,
116
- `"${value}" is not a valid converter type. Valid types are: ${ListOfBuiltInConverters.join(",")}`
117
- );
118
- }
119
- }
120
- };
121
-
122
- // src/BuiltInConverters.ts
123
- var BuiltInConverters = class _BuiltInConverters {
124
- static {
125
- __name(this, "BuiltInConverters");
126
- }
127
- static string(raw, fallback) {
128
- return raw ?? fallback;
129
- }
130
- static number(raw, fallback) {
131
- if (raw === void 0) return fallback;
132
- const parsed = Number(raw);
133
- return Number.isNaN(parsed) ? fallback : parsed;
134
- }
135
- static boolean(raw, fallback) {
136
- if (raw === void 0) return fallback;
137
- const lower = raw.toLowerCase().trim();
138
- const truthyValues = ["1", "yes", "true", "on"];
139
- const falsyValues = ["0", "no", "false", "off"];
140
- if (truthyValues.includes(lower)) return true;
141
- if (falsyValues.includes(lower)) return false;
142
- return fallback;
143
- }
144
- static bigint(raw, fallback) {
145
- if (raw === void 0) return fallback;
146
- try {
147
- return BigInt(raw);
148
- } catch {
149
- return fallback;
150
- }
151
- }
152
- static symbol(raw, fallback) {
153
- return raw ? Symbol(raw) : fallback;
154
- }
155
- static integer(raw, fallback) {
156
- if (raw === void 0) return fallback;
157
- const parsed = parseInt(raw, 10);
158
- return Number.isNaN(parsed) ? fallback : parsed;
159
- }
160
- static float(raw, fallback) {
161
- if (raw === void 0) return fallback;
162
- const parsed = parseFloat(raw);
163
- return Number.isNaN(parsed) ? fallback : parsed;
164
- }
165
- static json(raw, fallback) {
166
- if (raw === void 0) return fallback;
167
- try {
168
- return JSON.parse(raw);
169
- } catch {
170
- return fallback;
171
- }
172
- }
173
- static array(raw, fallback, delimiter = ",") {
174
- if (raw === void 0) return fallback;
175
- if (raw.trim() === "") return [];
176
- return raw.split(delimiter).map((item) => item.trim()).filter((item) => item.length > 0);
177
- }
178
- static url(raw, fallback) {
179
- if (raw === void 0) return fallback;
180
- try {
181
- return new URL(raw);
182
- } catch {
183
- return fallback;
184
- }
185
- }
186
- static regexp(raw, fallback) {
187
- if (raw === void 0) return fallback;
188
- try {
189
- const match = raw.match(/^\/(.+)\/([gimsuvy]*)$/);
190
- if (match) return new RegExp(match[1], match[2]);
191
- return new RegExp(raw);
192
- } catch {
193
- return fallback;
194
- }
195
- }
196
- static date(raw, fallback) {
197
- if (raw === void 0) return fallback;
198
- if (/^\d+$/.test(raw)) {
199
- const timestamp = parseInt(raw, 10);
200
- const parsed2 = new Date(timestamp);
201
- return Number.isNaN(parsed2.getTime()) ? fallback : parsed2;
202
- }
203
- const parsed = new Date(raw);
204
- return Number.isNaN(parsed.getTime()) ? fallback : parsed;
205
- }
206
- static time(raw, fallback) {
207
- if (raw === void 0) return fallback;
208
- const match = raw.match(/^(\d+(?:\.\d+)?)(ms|s|m|h)?$/u);
209
- if (!match) return fallback;
210
- const [, numStr, unit = "ms"] = match;
211
- if (!numStr) return fallback;
212
- const value = Number.parseFloat(numStr);
213
- if (Number.isNaN(value)) return fallback;
214
- const SECONDS_TO_MS = 1e3;
215
- const SECONDS_PER_MINUTE = 60;
216
- const MINUTES_PER_HOUR = 60;
217
- const MINUTES_TO_MS = SECONDS_PER_MINUTE * SECONDS_TO_MS;
218
- const HOURS_TO_MS = MINUTES_PER_HOUR * MINUTES_TO_MS;
219
- if (unit === "ms") return value;
220
- if (unit === "s") return value * SECONDS_TO_MS;
221
- if (unit === "m") return value * MINUTES_TO_MS;
222
- if (unit === "h") return value * HOURS_TO_MS;
223
- return fallback;
224
- }
225
- /**
226
- * Process array with custom converter config
227
- */
228
- static processArrayConverter(raw, fallback, config2) {
229
- if (raw === void 0) {
230
- if (Array.isArray(fallback)) return fallback;
231
- throw new EnvaptError(
232
- EnvaptErrorCodes.InvalidFallback,
233
- `ArrayConverter requires that the fallback be an array, got ${typeof fallback}`
234
- );
235
- }
236
- if (raw.trim() === "") return [];
237
- const items = raw.split(config2.delimiter).map((item) => String(item).trim()).filter(Boolean);
238
- if (!config2.type) return items;
239
- const converter = _BuiltInConverters.getConverter(config2.type);
240
- return items.map((item) => {
241
- const converted = converter(item, void 0);
242
- return converted ?? item;
243
- });
244
- }
245
- /**
246
- * Get the converter function for a built-in converter type
247
- */
248
- static getConverter(type) {
249
- const converters = {
250
- string: _BuiltInConverters.string,
251
- number: _BuiltInConverters.number,
252
- boolean: _BuiltInConverters.boolean,
253
- integer: _BuiltInConverters.integer,
254
- bigint: _BuiltInConverters.bigint,
255
- symbol: _BuiltInConverters.symbol,
256
- float: _BuiltInConverters.float,
257
- json: _BuiltInConverters.json,
258
- array: _BuiltInConverters.array,
259
- url: _BuiltInConverters.url,
260
- regexp: _BuiltInConverters.regexp,
261
- date: _BuiltInConverters.date,
262
- time: _BuiltInConverters.time
263
- };
264
- const converter = converters[type];
265
- if (!Validator.isValidConverterFunction(converter)) {
266
- throw new EnvaptError(EnvaptErrorCodes.InvalidBuiltInConverter, `Unknown built-in converter: ${type}`);
267
- }
268
- return converter;
269
- }
270
- };
271
-
272
- // src/Parser.ts
273
- var Parser = class {
274
- constructor(envService) {
275
- this.envService = envService;
276
- }
277
- static {
278
- __name(this, "Parser");
279
- }
280
- TEMPLATE_REGEX = /\${\w*}/g;
281
- resolveTemplate(key, value, stack = /* @__PURE__ */ new Set()) {
282
- if (stack.has(key)) return value;
283
- stack.add(key);
284
- const out = value.replace(this.TEMPLATE_REGEX, (template) => {
285
- const variable = template.slice(2, -1);
286
- if (!variable) return template;
287
- if (stack.has(variable)) return template;
288
- const raw = this.envService.getRaw(variable);
289
- if (!raw || raw === "") return template;
290
- const resolved = this.resolveTemplate(variable, raw, new Set(stack));
291
- if (resolved.includes(`\${${key}}`)) return template;
292
- if (resolved === raw && /\$\{[^}]*\}/.test(resolved)) return template;
293
- return resolved;
294
- });
295
- stack.delete(key);
296
- return out;
297
- }
298
- convertValue(key, fallback, converter, hasFallback = true) {
299
- let resolvedConverter = this.resolveConverter(converter, fallback);
300
- if (resolvedConverter === Number) resolvedConverter = "number";
301
- else if (resolvedConverter === Boolean) resolvedConverter = "boolean";
302
- else if (resolvedConverter === String) resolvedConverter = "string";
303
- else if (resolvedConverter === BigInt) resolvedConverter = "bigint";
304
- else if (resolvedConverter === Symbol) resolvedConverter = "symbol";
305
- if (Validator.isArrayConverter(resolvedConverter)) {
306
- Validator.arrayConverter(resolvedConverter);
307
- const parsed = this.envService.get(key, void 0);
308
- if (parsed === void 0) return hasFallback ? fallback : null;
309
- return BuiltInConverters.processArrayConverter(parsed, fallback, resolvedConverter);
310
- }
311
- if (Validator.isBuiltInConverter(resolvedConverter)) {
312
- Validator.builtInConverter(resolvedConverter);
313
- const parsed = this.envService.get(key, void 0);
314
- if (parsed === void 0) return hasFallback ? fallback : null;
315
- const converterFn = BuiltInConverters.getConverter(resolvedConverter);
316
- const result = converterFn(parsed, fallback);
317
- return result;
318
- }
319
- Validator.customConvertor(resolvedConverter);
320
- const raw = this.envService.get(key, void 0);
321
- if (raw === void 0) return hasFallback ? fallback : null;
322
- return resolvedConverter(raw, fallback);
323
- }
324
- resolveConverter(converter, fallback) {
325
- if (converter) return converter;
326
- const fallbackType = typeof fallback;
327
- if (fallbackType === "number") return "number";
328
- if (fallbackType === "boolean") return "boolean";
329
- if (fallbackType === "bigint") return "bigint";
330
- if (fallbackType === "symbol") return "symbol";
331
- return "string";
332
- }
333
- };
334
-
335
- // src/Envapter.ts
336
- var EnvaptCache = /* @__PURE__ */ new Map();
337
- var Environment = /* @__PURE__ */ ((Environment2) => {
338
- Environment2[Environment2["Development"] = 0] = "Development";
339
- Environment2[Environment2["Staging"] = 1] = "Staging";
340
- Environment2[Environment2["Production"] = 2] = "Production";
341
- return Environment2;
342
- })(Environment || {});
343
- var Envapter = class _Envapter {
344
- static {
345
- __name(this, "Envapter");
346
- }
347
- static parser = new Parser(new _Envapter());
348
- static _envPaths = [".env"];
349
- // default path
350
- // Environment handling
351
- static internalEnvironment = this.determineEnvironment(
352
- this.get("ENVIRONMENT", this.get("ENV", this.get("NODE_ENV", "development")))
353
- );
354
- /**
355
- * Set custom .env file paths. Accepts either a single path or array of paths.
356
- * Setting new paths clears the cache and reloads environment variables.
357
- *
358
- * @param paths - Single file path or array of file paths to load
359
- *
360
- * @example
361
- * ```ts
362
- * // Single file
363
- * Envapter.envPaths = '.env.production';
364
- *
365
- * // Multiple files (loaded in order)
366
- * Envapter.envPaths = ['.env', '.env.local', '.env.production'];
367
- * ```
368
- */
369
- static set envPaths(paths) {
370
- this._envPaths = Array.isArray(paths) ? paths : [paths];
371
- EnvaptCache.clear();
372
- void this.config;
373
- this.internalEnvironment = this.determineEnvironment(
374
- this.get("ENVIRONMENT", this.get("ENV", this.get("NODE_ENV", "development")))
375
- );
376
- }
377
- /**
378
- * Get currently configured .env file paths
379
- * @returns Array of file paths being loaded
380
- */
381
- static get envPaths() {
382
- return this._envPaths;
383
- }
384
- static determineEnvironment(env) {
385
- if (typeof env === "string") {
386
- switch (env.toLowerCase()) {
387
- case "production":
388
- return 2 /* Production */;
389
- case "staging":
390
- return 1 /* Staging */;
391
- default:
392
- return 0 /* Development */;
393
- }
394
- }
395
- return env;
396
- }
397
- /**
398
- * Set the application environment. Accepts either Environment enum or string value.
399
- *
400
- * @param env - Environment value ('development', 'staging', 'production') or Environment enum
401
- *
402
- * @example
403
- * ```ts
404
- * Envapter.environment = Environment.Production;
405
- * Envapter.environment = 'staging';
406
- * ```
407
- */
408
- static set environment(env) {
409
- this.internalEnvironment = this.determineEnvironment(env);
410
- }
411
- /**
412
- * Get the current application environment
413
- * @returns Current environment enum value
414
- */
415
- static get environment() {
416
- return this.internalEnvironment;
417
- }
418
- /**
419
- * Check if the current environment is production
420
- * @returns true if environment is production
421
- */
422
- static get isProduction() {
423
- return this.internalEnvironment === 2 /* Production */;
424
- }
425
- /**
426
- * Check if the current environment is staging
427
- * @returns true if environment is staging
428
- */
429
- static get isStaging() {
430
- return this.internalEnvironment === 1 /* Staging */;
431
- }
432
- /**
433
- * Check if the current environment is development
434
- * @returns true if environment is development
435
- */
436
- static get isDevelopment() {
437
- return this.internalEnvironment === 0 /* Development */;
438
- }
439
- static get config() {
440
- if (EnvaptCache.size === 0) {
441
- const isolatedEnv = { ...process.env };
442
- try {
443
- config({ path: this._envPaths, quiet: true, processEnv: isolatedEnv });
444
- } catch {
445
- }
446
- for (const [key, value] of Object.entries(isolatedEnv)) EnvaptCache.set(key, value);
447
- }
448
- return EnvaptCache;
449
- }
450
- static _get(key, type = 0 /* String */, def) {
451
- const rawVal = this.config.get(key);
452
- if (!rawVal) return def;
453
- const parsed = this.parser.resolveTemplate(key, String(rawVal));
454
- switch (type) {
455
- case 0 /* String */: {
456
- return BuiltInConverters.string(parsed, def);
457
- }
458
- case 1 /* Number */: {
459
- return BuiltInConverters.number(parsed, def);
460
- }
461
- case 2 /* Boolean */: {
462
- return BuiltInConverters.boolean(parsed, def);
463
- }
464
- case 3 /* BigInt */: {
465
- return BuiltInConverters.bigint(parsed, def);
466
- }
467
- case 4 /* Symbol */: {
468
- return BuiltInConverters.symbol(parsed, def);
469
- }
470
- default: {
471
- return BuiltInConverters.string(parsed, def);
472
- }
473
- }
474
- }
475
- /**
476
- * Get a string environment variable with optional fallback.
477
- * Supports template variable resolution using ${VAR} syntax.
478
- *
479
- * @param key - Environment variable name
480
- * @param def - Default value if variable is not found
481
- * @returns The environment variable value or default
482
- *
483
- * @example
484
- * ```ts
485
- * const apiUrl = Envapter.get('API_URL', 'http://localhost:3000');
486
- * ```
487
- */
488
- static get(key, def) {
489
- return this._get(key, 0 /* String */, def);
490
- }
491
- /**
492
- * Get a number environment variable with optional fallback.
493
- * Automatically converts string values to numbers.
494
- *
495
- * @param key - Environment variable name
496
- * @param def - Default value if variable is not found or cannot be converted
497
- * @returns The environment variable value as number or default
498
- *
499
- * @example
500
- * ```ts
501
- * const port = Envapter.getNumber('PORT', 3000);
502
- * ```
503
- */
504
- static getNumber(key, def) {
505
- return this._get(key, 1 /* Number */, def);
506
- }
507
- /**
508
- * Get a boolean environment variable with optional fallback.
509
- * Recognizes: `1`, `yes`, `true` as **true**; `0`, `no`, `false` as **false** (case-insensitive).
510
- *
511
- * @param key - Environment variable name
512
- * @param def - Default value if variable is not found or cannot be converted
513
- * @returns The environment variable value as boolean or default
514
- *
515
- * @example
516
- * ```ts
517
- * const isProduction = Envapter.getBoolean('IS_PRODUCTION', false);
518
- * ```
519
- */
520
- static getBoolean(key, def) {
521
- return this._get(key, 2 /* Boolean */, def);
522
- }
523
- /**
524
- * Get a bigint environment variable with optional fallback.
525
- * Automatically converts string values to bigint.
526
- *
527
- * @param key - Environment variable name
528
- * @param def - Default value if variable is not found or cannot be converted
529
- * @returns The environment variable value as bigint or default
530
- *
531
- * @example
532
- * ```ts
533
- * const largeNumber = Envapter.getBigInt('LARGE_NUMBER', 123456789012345678901234567890n);
534
- * ```
535
- */
536
- static getBigInt(key, def) {
537
- return this._get(key, 3 /* BigInt */, def);
538
- }
539
- /**
540
- * Get a symbol environment variable with optional fallback.
541
- * Creates a symbol from the string value.
542
- *
543
- * @param key - Environment variable name
544
- * @param def - Default value if variable is not found
545
- * @returns The environment variable value as symbol or default
546
- *
547
- * @example
548
- * ```ts
549
- * const uniqueKey = Envapter.getSymbol('UNIQUE_KEY', Symbol('default'));
550
- * ```
551
- */
552
- static getSymbol(key, def) {
553
- return this._get(key, 4 /* Symbol */, def);
554
- }
555
- get(key, def) {
556
- return _Envapter._get(key, 0 /* String */, def);
557
- }
558
- getNumber(key, def) {
559
- return _Envapter._get(key, 1 /* Number */, def);
560
- }
561
- getBoolean(key, def) {
562
- return _Envapter._get(key, 2 /* Boolean */, def);
563
- }
564
- getBigInt(key, def) {
565
- return _Envapter._get(key, 3 /* BigInt */, def);
566
- }
567
- getSymbol(key, def) {
568
- return _Envapter._get(key, 4 /* Symbol */, def);
569
- }
570
- /**
571
- * Get raw environment variable value without parsing or conversion.
572
- *
573
- * @internal
574
- */
575
- getRaw(key) {
576
- return _Envapter.config.get(key);
577
- }
578
- };
579
-
580
- // src/Envapt.ts
581
- function createPropertyDecorator(key, fallback, converter, hasFallback = true) {
582
- return function(target, prop) {
583
- const propKey = String(prop);
584
- const cacheKey = `${target.constructor.name}.${propKey}`;
585
- Object.defineProperty(target, propKey, {
586
- get: /* @__PURE__ */ __name(function() {
587
- let value = EnvaptCache.get(cacheKey);
588
- if (value === void 0) {
589
- const parser = new Parser(new Envapter());
590
- value = parser.convertValue(key, fallback, converter, hasFallback);
591
- EnvaptCache.set(cacheKey, value);
592
- }
593
- return value;
594
- }, "get"),
595
- configurable: false,
596
- enumerable: true
597
- });
598
- };
599
- }
600
- __name(createPropertyDecorator, "createPropertyDecorator");
601
- function Envapt(key, fallbackOrOptions, converter) {
602
- let fallback;
603
- let actualConverter;
604
- let hasFallback = true;
605
- if (fallbackOrOptions && typeof fallbackOrOptions === "object" && ("fallback" in fallbackOrOptions || "converter" in fallbackOrOptions)) {
606
- const options = fallbackOrOptions;
607
- fallback = options.fallback;
608
- actualConverter = options.converter;
609
- hasFallback = "fallback" in options;
610
- } else {
611
- fallback = fallbackOrOptions;
612
- actualConverter = converter;
613
- hasFallback = arguments.length > 1;
614
- }
615
- return createPropertyDecorator(key, fallback, actualConverter, hasFallback);
616
- }
617
- __name(Envapt, "Envapt");
618
-
619
- export { Envapt, Envapter, Environment };
620
- //# sourceMappingURL=index.js.map
621
- //# sourceMappingURL=index.js.map