envapt 2.2.0 → 2.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +92 -32
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -3,8 +3,8 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
A TypeScript environment configuration library that eliminates the boilerplate of transforming parsed <code>.env</code><br/>
|
|
7
|
-
Get environment variables with correct runtime typing
|
|
6
|
+
A JavaScript/TypeScript environment configuration library that eliminates the boilerplate of transforming parsed <code>.env</code><br/>
|
|
7
|
+
Get environment variables with correct runtime typing & fallbacks, template support, automatic, built-in, & custom transformations, and a tagged template resolver.<br/>
|
|
8
8
|
<strong>No more <code>process.env.PORT || '3000'</code> everywhere!</strong>
|
|
9
9
|
</p>
|
|
10
10
|
<div align="center">
|
|
@@ -27,12 +27,12 @@
|
|
|
27
27
|
|
|
28
28
|
- 🔧 **Automatic Type Detection** - Runtime types inferred from fallback values
|
|
29
29
|
- 🔗 **Template Variables** - `${VAR}` syntax with circular reference protection
|
|
30
|
-
- 🎯 **Class Properties** - Functional and Decorator-based configuration for class members
|
|
30
|
+
- 🎯 **Class Properties** - Functional and Decorator-based configuration for class members _(Decorators: TypeScript only)_
|
|
31
31
|
- 🏷️ **Built-in & Custom Converters** - Ready-to-use converters for common patterns + custom transformations
|
|
32
32
|
- 🔖 **Tagged Template Resolver** - Tagged template literals with environment variable resolution
|
|
33
33
|
- 🌍 **Environment Detection** - Built-in development/staging/production handling
|
|
34
34
|
- 💪 **Edge Case Handling** - Robust validation and parsing for all scenarios
|
|
35
|
-
- 🛡️ **Type Safety** - Full TypeScript support with proper type inference
|
|
35
|
+
- 🛡️ **Type Safety** - Full TypeScript support with proper type inference _(TypeScript optional)_
|
|
36
36
|
- 📂 **Multiple .env Files** - Load from multiple sources
|
|
37
37
|
- ⚡ **Lightweight** - Minimal overhead with [`dotenv`](https://www.npmjs.com/package/dotenv) bundled
|
|
38
38
|
|
|
@@ -81,7 +81,8 @@
|
|
|
81
81
|
### 🚀 Examples
|
|
82
82
|
|
|
83
83
|
- [Advanced Examples](#advanced-examples)
|
|
84
|
-
- [
|
|
84
|
+
- [JavaScript](#javascript)
|
|
85
|
+
- [TypeScript](#typescript)
|
|
85
86
|
|
|
86
87
|
---
|
|
87
88
|
|
|
@@ -92,16 +93,16 @@
|
|
|
92
93
|
- **Node.js**: `>=22.0.0`
|
|
93
94
|
_Recommended for full ESM and `nodenext` support_
|
|
94
95
|
|
|
95
|
-
- **TypeScript**: `>=5.8`
|
|
96
|
-
|
|
97
96
|
#### 📦 Runtime Dependency
|
|
98
97
|
|
|
99
98
|
- **dotenv**: _(bundled at runtime)_
|
|
100
99
|
|
|
101
|
-
#### 🛠️ TypeScript
|
|
100
|
+
#### 🛠️ TypeScript Users Only
|
|
101
|
+
|
|
102
|
+
- **TypeScript**: `>=5.8` _(Only required for decorator API)_
|
|
102
103
|
|
|
103
104
|
```jsonc
|
|
104
|
-
// tsconfig.json (required settings)
|
|
105
|
+
// tsconfig.json (required settings for decorators)
|
|
105
106
|
{
|
|
106
107
|
"experimentalDecorators": true,
|
|
107
108
|
"module": "esnext", // or "nodenext"
|
|
@@ -111,6 +112,9 @@
|
|
|
111
112
|
}
|
|
112
113
|
```
|
|
113
114
|
|
|
115
|
+
> [!NOTE]
|
|
116
|
+
> **JavaScript users** can use all features except the `@Envapt` decorator API. The [Functional API](#functional-api), [Tagged Template Resolver](#tagged-template-resolver), and all converters work perfectly in plain JavaScript.
|
|
117
|
+
|
|
114
118
|
## Quick Start
|
|
115
119
|
|
|
116
120
|
### Installation
|
|
@@ -134,7 +138,29 @@ MAX_CONNECTIONS=100
|
|
|
134
138
|
ALLOWED_ORIGINS=https://app.com,https://admin.com
|
|
135
139
|
```
|
|
136
140
|
|
|
137
|
-
|
|
141
|
+
**JavaScript Example (Functional API):**
|
|
142
|
+
|
|
143
|
+
```js
|
|
144
|
+
import { Envapter, Converters } from 'envapt';
|
|
145
|
+
|
|
146
|
+
// Basic usage
|
|
147
|
+
const port = Envapter.getNumber('APP_PORT', 3000);
|
|
148
|
+
const url = Envapter.get('APP_URL', 'http://localhost:3000');
|
|
149
|
+
const isProduction = Envapter.isProduction;
|
|
150
|
+
|
|
151
|
+
console.log(`Server running on port ${port}`); // 8443
|
|
152
|
+
console.log(`URL: ${url}`); // "http://localhost:8443"
|
|
153
|
+
|
|
154
|
+
// Advanced converters
|
|
155
|
+
const corsOrigins = Envapter.getUsing('ALLOWED_ORIGINS', Converters.Array, []);
|
|
156
|
+
const dbConfig = Envapter.getUsing('DATABASE_CONFIG', Converters.Json, {});
|
|
157
|
+
|
|
158
|
+
// Tagged template literals
|
|
159
|
+
const message = Envapter.resolve`Server ${'APP_URL'} is ready!`;
|
|
160
|
+
console.log(message); // "Server http://localhost:8443 is ready!"
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
**TypeScript Example (Decorator API):**
|
|
138
164
|
|
|
139
165
|
```ts
|
|
140
166
|
import { Envapt, Envapter, Converters } from 'envapt';
|
|
@@ -173,30 +199,23 @@ class DatabaseService {
|
|
|
173
199
|
|
|
174
200
|
// Usage
|
|
175
201
|
console.log(AppConfig.port); // 8443 (number)
|
|
176
|
-
console.log(AppConfig.url.href); // "http://localhost:8443"
|
|
202
|
+
console.log(AppConfig.url.href); // "http://localhost:8443"
|
|
177
203
|
|
|
178
204
|
const dbService = new DatabaseService();
|
|
179
205
|
await dbService.connect();
|
|
180
206
|
```
|
|
181
207
|
|
|
182
|
-
Or use functionally:
|
|
183
|
-
|
|
184
|
-
```ts
|
|
185
|
-
import { Envapter } from 'envapt';
|
|
186
|
-
|
|
187
|
-
const port = Envapter.getNumber('APP_PORT', 3000);
|
|
188
|
-
const url = Envapter.get('APP_URL', 'http://localhost:3000');
|
|
189
|
-
const isProduction = Envapter.getBoolean('IS_PRODUCTION', false);
|
|
190
|
-
```
|
|
191
|
-
|
|
192
208
|
## API Reference
|
|
193
209
|
|
|
194
210
|
### Decorator API
|
|
195
211
|
|
|
212
|
+
> [!IMPORTANT]
|
|
213
|
+
> **TypeScript Only**: The `@Envapt` decorator API requires TypeScript with `experimentalDecorators: true`. JavaScript users should use the [Functional API](#functional-api) instead.
|
|
214
|
+
|
|
196
215
|
The `@Envapt` decorator can be used on both **static** and **instance** class properties:
|
|
197
216
|
|
|
198
|
-
- **Static properties**:
|
|
199
|
-
- **Instance properties**:
|
|
217
|
+
- **Static properties**: Can use for global configuration that's shared across your entire application (e.g., app port, global features, environment settings)
|
|
218
|
+
- **Instance properties**: Can use for service-specific configuration that may vary per service or when you want the configuration tied to a specific class instance (e.g., database connections, service endpoints, per-service settings)
|
|
200
219
|
|
|
201
220
|
**Important**: Instance properties must be declared with `declare` keyword or `!` assertion since they're populated by the decorator rather than set in a constructor.
|
|
202
221
|
|
|
@@ -473,9 +492,9 @@ class Config extends Envapter {
|
|
|
473
492
|
|
|
474
493
|
### Functional API
|
|
475
494
|
|
|
476
|
-
For functional-style environment variable on primitive types:
|
|
495
|
+
For functional-style environment variable access on primitive types:
|
|
477
496
|
|
|
478
|
-
```
|
|
497
|
+
```js
|
|
479
498
|
import { Envapter, Converters } from 'envapt';
|
|
480
499
|
|
|
481
500
|
// Basic type-specific getters
|
|
@@ -498,12 +517,14 @@ const processed = envapter.getUsing('DATA', Converters.Array);
|
|
|
498
517
|
|
|
499
518
|
For functional-style environment variable access with converters:
|
|
500
519
|
|
|
501
|
-
```
|
|
520
|
+
```js
|
|
502
521
|
import { Envapter, Converters } from 'envapt';
|
|
503
522
|
|
|
504
523
|
// Use built-in converters directly
|
|
505
524
|
const config = Envapter.getUsing('API_CONFIG', Converters.Json, { default: 'value' });
|
|
506
525
|
const urls = Envapter.getUsing('SERVICE_URLS', { delimiter: '|', type: Converters.Url });
|
|
526
|
+
|
|
527
|
+
// TypeScript: Use type override for better type inference
|
|
507
528
|
const typedConfig = Envapter.getUsing<{ host: string; port: number; ssl: boolean }>('DATABASE_CONFIG', Converters.Json);
|
|
508
529
|
// typedConfig is now typed as { host: string; port: number; ssl: boolean } instead of JsonValue | undefined
|
|
509
530
|
|
|
@@ -563,7 +584,7 @@ const result = envapter.getUsing('DATABASE_CONFIG', Converters.Json);
|
|
|
563
584
|
|
|
564
585
|
Envapt provides a convenient tagged template literal syntax for resolving environment variables directly in template strings:
|
|
565
586
|
|
|
566
|
-
```
|
|
587
|
+
```js
|
|
567
588
|
import { Envapter } from 'envapt';
|
|
568
589
|
|
|
569
590
|
// Given these environment variables:
|
|
@@ -615,7 +636,7 @@ Supported values: `development`, `staging`, `production` (case-sensitive)
|
|
|
615
636
|
|
|
616
637
|
### Environment Management
|
|
617
638
|
|
|
618
|
-
```
|
|
639
|
+
```js
|
|
619
640
|
import { Envapter, EnvaptEnvironment } from 'envapt';
|
|
620
641
|
|
|
621
642
|
// Check current environment
|
|
@@ -633,7 +654,7 @@ Envapter.environment = 'staging'; // string also works
|
|
|
633
654
|
|
|
634
655
|
### Multiple .env Files
|
|
635
656
|
|
|
636
|
-
```
|
|
657
|
+
```js
|
|
637
658
|
import { resolve } from 'node:path';
|
|
638
659
|
import { Envapter } from 'envapt';
|
|
639
660
|
|
|
@@ -650,7 +671,7 @@ Envapter.envPaths = resolve(__dirname, '.env.production');
|
|
|
650
671
|
|
|
651
672
|
Envapt allows you to customize dotenv behavior by setting configuration options:
|
|
652
673
|
|
|
653
|
-
```
|
|
674
|
+
```js
|
|
654
675
|
import { Envapter } from 'envapt';
|
|
655
676
|
|
|
656
677
|
// Set dotenv configuration options
|
|
@@ -696,7 +717,7 @@ Circular references are detected and preserved as-is rather than causing infinit
|
|
|
696
717
|
|
|
697
718
|
Envapt provides detailed error codes for better debugging and error handling:
|
|
698
719
|
|
|
699
|
-
```
|
|
720
|
+
```js
|
|
700
721
|
import { EnvaptError, EnvaptErrorCodes } from 'envapt';
|
|
701
722
|
|
|
702
723
|
try {
|
|
@@ -754,7 +775,46 @@ try {
|
|
|
754
775
|
|
|
755
776
|
## Advanced Examples
|
|
756
777
|
|
|
757
|
-
###
|
|
778
|
+
### JavaScript
|
|
779
|
+
|
|
780
|
+
```js
|
|
781
|
+
import { Envapter, Converters } from 'envapt';
|
|
782
|
+
|
|
783
|
+
// Global configuration
|
|
784
|
+
const config = {
|
|
785
|
+
port: Envapter.getNumber('PORT', 3000),
|
|
786
|
+
requestTimeout: Envapter.getUsing('REQUEST_TIMEOUT', Converters.Time, 10000), // "5s" -> 5000ms
|
|
787
|
+
featureFlags: Envapter.getWith(
|
|
788
|
+
'FEATURE_FLAGS',
|
|
789
|
+
(raw, fallback) => {
|
|
790
|
+
if (!raw) return fallback;
|
|
791
|
+
return new Set(raw.split(',').map((s) => s.trim()));
|
|
792
|
+
},
|
|
793
|
+
new Set(['basic'])
|
|
794
|
+
)
|
|
795
|
+
};
|
|
796
|
+
|
|
797
|
+
// Service configuration
|
|
798
|
+
class DatabaseService {
|
|
799
|
+
constructor() {
|
|
800
|
+
this.databaseUrl = Envapter.get('DB_URL', 'sqlite://memory');
|
|
801
|
+
this.cacheTtl = Envapter.getUsing('CACHE_TTL', Converters.Time, 3600000); // "1h" -> 3600000ms
|
|
802
|
+
this.redisUrls = Envapter.getWith(
|
|
803
|
+
'REDIS_URLS',
|
|
804
|
+
(raw, fallback) => (raw ? raw.split(',').map((s) => new URL(s)) : fallback),
|
|
805
|
+
[new URL('redis://localhost:6379')]
|
|
806
|
+
);
|
|
807
|
+
}
|
|
808
|
+
|
|
809
|
+
async initialize() {
|
|
810
|
+
console.log(`App running on port ${config.port}`);
|
|
811
|
+
console.log(`Database: ${this.databaseUrl}`);
|
|
812
|
+
console.log(`Cache TTL: ${this.cacheTtl}ms`);
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
```
|
|
816
|
+
|
|
817
|
+
### TypeScript
|
|
758
818
|
|
|
759
819
|
```ts
|
|
760
820
|
import { Envapt, Envapter, Converters } from 'envapt';
|