node-safe-env 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +195 -194
- package/dist/cli.js +87 -6
- package/dist/cli.js.map +1 -1
- package/package.json +15 -1
package/README.md
CHANGED
|
@@ -1,10 +1,51 @@
|
|
|
1
1
|
# node-safe-env
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+

|
|
4
|
+

|
|
5
|
+

|
|
6
|
+

|
|
4
7
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
+
Schema-based environment validation for Node.js and TypeScript.
|
|
9
|
+
|
|
10
|
+
Validate environment variables at startup, parse them into runtime types, and catch configuration problems before your app boots.
|
|
11
|
+
|
|
12
|
+
## Why node-safe-env?
|
|
13
|
+
|
|
14
|
+
- Fail fast during application startup.
|
|
15
|
+
- Parse raw env strings into typed runtime values.
|
|
16
|
+
- See aggregated validation issues in one error report.
|
|
17
|
+
- Validate `.env` and `.env.example` usage from scripts or CI.
|
|
18
|
+
- Inspect where values came from with debug tracing.
|
|
19
|
+
|
|
20
|
+
## Features
|
|
21
|
+
|
|
22
|
+
- Schema-based environment validation
|
|
23
|
+
- TypeScript-friendly schema inference
|
|
24
|
+
- Automatic parsing for numbers, booleans, arrays, dates
|
|
25
|
+
- Nested schemas with flattened env keys
|
|
26
|
+
- CLI validation for env and `.env.example`
|
|
27
|
+
- Aggregated validation errors
|
|
28
|
+
- Debug tracing for env source resolution
|
|
29
|
+
|
|
30
|
+
## Try it instantly
|
|
31
|
+
|
|
32
|
+
You can run the CLI without installing the package globally. The quickest way to try `node-safe-env` is with `npx`.
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
npx node-safe-env --help
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
Validate environment variables:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
npx node-safe-env validate --schema ./env.schema.ts
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Validate `.env.example`:
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npx node-safe-env validate-example --schema ./env.schema.ts
|
|
48
|
+
```
|
|
8
49
|
|
|
9
50
|
## Install
|
|
10
51
|
|
|
@@ -12,8 +53,19 @@ issues in one error.
|
|
|
12
53
|
npm install node-safe-env
|
|
13
54
|
```
|
|
14
55
|
|
|
56
|
+
## Examples
|
|
57
|
+
|
|
58
|
+
Runnable examples are available in the repository and mirror common usage patterns.
|
|
59
|
+
|
|
60
|
+
- `examples/basic` - minimal schema validation
|
|
61
|
+
- `examples/nested` - nested schema with flattened env keys
|
|
62
|
+
- `examples/advanced` - arrays, custom parsing, debug mode, masking
|
|
63
|
+
- `examples/cli-schema` - schema module intended for CLI validation
|
|
64
|
+
|
|
15
65
|
## Quick Start
|
|
16
66
|
|
|
67
|
+
Define a schema:
|
|
68
|
+
|
|
17
69
|
```ts
|
|
18
70
|
import { createEnv, defineEnv } from "node-safe-env";
|
|
19
71
|
|
|
@@ -27,7 +79,11 @@ const schema = defineEnv({
|
|
|
27
79
|
default: "development",
|
|
28
80
|
},
|
|
29
81
|
} as const);
|
|
82
|
+
```
|
|
30
83
|
|
|
84
|
+
Use it at runtime:
|
|
85
|
+
|
|
86
|
+
```ts
|
|
31
87
|
const env = createEnv(schema);
|
|
32
88
|
|
|
33
89
|
env.APP_NAME; // string
|
|
@@ -36,9 +92,36 @@ env.DEBUG; // boolean
|
|
|
36
92
|
env.NODE_ENV; // "development" | "test" | "production"
|
|
37
93
|
```
|
|
38
94
|
|
|
39
|
-
|
|
95
|
+
What this gives you:
|
|
96
|
+
|
|
97
|
+
- `required: true` means the value must exist.
|
|
98
|
+
- `default` is used when a value is missing.
|
|
99
|
+
- `type` controls parsing and validation.
|
|
100
|
+
- The returned `env` object is strongly typed from your schema.
|
|
101
|
+
|
|
102
|
+
Example `.env`:
|
|
103
|
+
|
|
104
|
+
```env
|
|
105
|
+
APP_NAME=DemoApp
|
|
106
|
+
PORT=4000
|
|
107
|
+
DEBUG=true
|
|
108
|
+
NODE_ENV=development
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Values are read as strings from the environment and then parsed according to your schema.
|
|
112
|
+
|
|
113
|
+
## What Is a Schema in node-safe-env?
|
|
114
|
+
|
|
115
|
+
A schema is an object where each key maps to a rule object.
|
|
116
|
+
|
|
117
|
+
Each rule describes:
|
|
40
118
|
|
|
41
|
-
|
|
119
|
+
- What type the value should be with `type`
|
|
120
|
+
- Whether it must be present with `required`
|
|
121
|
+
- What to use if it is missing with `default`
|
|
122
|
+
- Any rule-specific options such as enum values, array settings, or a custom parser
|
|
123
|
+
|
|
124
|
+
Use `defineEnv()` when you want better literal type inference and a reusable exported schema module.
|
|
42
125
|
|
|
43
126
|
```ts
|
|
44
127
|
// env.schema.ts
|
|
@@ -50,145 +133,162 @@ export const schema = defineEnv({
|
|
|
50
133
|
} as const);
|
|
51
134
|
```
|
|
52
135
|
|
|
53
|
-
|
|
54
|
-
// main.ts
|
|
55
|
-
import { createEnv } from "node-safe-env";
|
|
56
|
-
import { schema } from "./env.schema.js";
|
|
136
|
+
## When to use node-safe-env
|
|
57
137
|
|
|
58
|
-
|
|
59
|
-
|
|
138
|
+
Use this library if you want to:
|
|
139
|
+
|
|
140
|
+
- validate environment variables at application startup
|
|
141
|
+
- enforce typed configuration in Node.js or TypeScript projects
|
|
142
|
+
- ensure `.env.example` stays aligned with your configuration schema
|
|
143
|
+
- detect configuration issues early in CI pipelines
|
|
144
|
+
|
|
145
|
+
## Common Use Cases
|
|
146
|
+
|
|
147
|
+
- App startup validation: load and validate env once during bootstrap.
|
|
148
|
+
- CI checks for `.env.example`: fail pull requests when required keys are missing or stale.
|
|
149
|
+
- Debugging source issues: use debug output to understand where values were loaded from.
|
|
150
|
+
|
|
151
|
+
## Value at a Glance
|
|
152
|
+
|
|
153
|
+
`node-safe-env` is a schema-based env validator with:
|
|
154
|
+
|
|
155
|
+
- TypeScript-friendly schema inference
|
|
156
|
+
- CLI commands for runtime and `.env.example` validation
|
|
157
|
+
- Structured, aggregated validation errors
|
|
158
|
+
- Source tracing and debug visibility
|
|
60
159
|
|
|
61
160
|
## Nested Schemas
|
|
62
161
|
|
|
63
|
-
Schemas can be nested
|
|
162
|
+
Schemas can be nested, but environment variable names are always flattened. Keys are generated by joining object path segments with `_` and converting each segment to uppercase. The library does not convert camelCase to snake_case, so `server.allowedHosts` becomes `SERVER_ALLOWEDHOSTS`, not `SERVER_ALLOWED_HOSTS`.
|
|
163
|
+
|
|
164
|
+
Examples:
|
|
165
|
+
|
|
166
|
+
- `server.port` -> `SERVER_PORT`
|
|
167
|
+
- `database.url` -> `DATABASE_URL`
|
|
168
|
+
- `server.allowedHosts` -> `SERVER_ALLOWEDHOSTS`
|
|
64
169
|
|
|
65
170
|
```ts
|
|
66
171
|
const env = createEnv({
|
|
67
172
|
server: {
|
|
68
173
|
port: { type: "port", default: 3000 },
|
|
174
|
+
allowedHosts: { type: "array", required: true },
|
|
69
175
|
},
|
|
70
176
|
database: {
|
|
71
177
|
url: { type: "string", required: true },
|
|
72
178
|
},
|
|
73
179
|
});
|
|
180
|
+
|
|
181
|
+
console.log(env.server.port);
|
|
74
182
|
```
|
|
75
183
|
|
|
76
184
|
```env
|
|
77
185
|
SERVER_PORT=4000
|
|
186
|
+
SERVER_ALLOWEDHOSTS=localhost,example.com
|
|
78
187
|
DATABASE_URL=postgres://localhost:5432/app
|
|
79
188
|
```
|
|
80
189
|
|
|
81
|
-
|
|
82
|
-
env.server.port; // number
|
|
83
|
-
env.database.url; // string
|
|
84
|
-
```
|
|
190
|
+
## CLI
|
|
85
191
|
|
|
86
|
-
|
|
192
|
+
`node-safe-env` includes two CLI commands:
|
|
87
193
|
|
|
88
|
-
|
|
194
|
+
- `validate`: validate current environment values against your schema
|
|
195
|
+
- `validate-example`: validate `.env.example` coverage against your schema
|
|
89
196
|
|
|
90
|
-
|
|
91
|
-
2. `.env.local`
|
|
92
|
-
3. `.env.<NODE_ENV>`
|
|
93
|
-
4. custom file from `options.envFile`
|
|
94
|
-
5. `process.env`
|
|
197
|
+
You can run the CLI without installing the package globally:
|
|
95
198
|
|
|
96
|
-
|
|
199
|
+
```bash
|
|
200
|
+
npx node-safe-env --help
|
|
201
|
+
```
|
|
97
202
|
|
|
98
|
-
|
|
99
|
-
- `number`
|
|
100
|
-
- `boolean`
|
|
101
|
-
- `enum`
|
|
102
|
-
- `url`
|
|
103
|
-
- `port`
|
|
104
|
-
- `json`
|
|
105
|
-
- `int`
|
|
106
|
-
- `float`
|
|
107
|
-
- `array`
|
|
108
|
-
- `email`
|
|
109
|
-
- `date`
|
|
110
|
-
- `custom`
|
|
203
|
+
Most common commands:
|
|
111
204
|
|
|
112
|
-
|
|
205
|
+
```bash
|
|
206
|
+
npx node-safe-env validate --schema ./env.schema.ts
|
|
207
|
+
npx node-safe-env validate-example --schema ./env.schema.ts
|
|
208
|
+
```
|
|
113
209
|
|
|
114
|
-
```
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
210
|
+
```bash
|
|
211
|
+
node-safe-env validate --schema ./env.schema.ts
|
|
212
|
+
node-safe-env validate-example --schema ./env.schema.ts
|
|
213
|
+
node-safe-env validate --schema ./dist/env.schema.js --strict
|
|
118
214
|
```
|
|
119
215
|
|
|
120
|
-
|
|
216
|
+
### CLI schema files
|
|
121
217
|
|
|
122
|
-
`
|
|
218
|
+
The `--schema` module supports both JavaScript and TypeScript files:
|
|
123
219
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
START_DATE: { type: "date", required: true },
|
|
127
|
-
});
|
|
220
|
+
- JavaScript: `.js`, `.mjs`, `.cjs`
|
|
221
|
+
- TypeScript: `.ts`, `.mts`, `.cts`
|
|
128
222
|
|
|
129
|
-
|
|
130
|
-
```
|
|
223
|
+
Accepted export shapes:
|
|
131
224
|
|
|
132
|
-
|
|
225
|
+
- Default export
|
|
226
|
+
- Named export `schema`
|
|
133
227
|
|
|
134
|
-
|
|
228
|
+
## `.env.example` Validation
|
|
135
229
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
type: "custom",
|
|
140
|
-
parse: (raw) => {
|
|
141
|
-
const n = Number(raw);
|
|
142
|
-
if (!Number.isInteger(n) || n < 0)
|
|
143
|
-
throw new Error("Must be a non-negative integer.");
|
|
144
|
-
return n;
|
|
145
|
-
},
|
|
146
|
-
},
|
|
147
|
-
});
|
|
230
|
+
`.env.example` should contain all keys defined in your schema so new environments and CI checks stay aligned with your application configuration.
|
|
231
|
+
|
|
232
|
+
Example `.env.example`:
|
|
148
233
|
|
|
149
|
-
env
|
|
234
|
+
```env
|
|
235
|
+
PORT=3000
|
|
236
|
+
DEBUG=false
|
|
237
|
+
NODE_ENV=development
|
|
150
238
|
```
|
|
151
239
|
|
|
152
|
-
|
|
240
|
+
Validate a real file:
|
|
241
|
+
|
|
242
|
+
```ts
|
|
243
|
+
import { validateExampleEnvFile } from "node-safe-env";
|
|
153
244
|
|
|
154
|
-
|
|
245
|
+
const issues = validateExampleEnvFile(schema, {
|
|
246
|
+
cwd: process.cwd(),
|
|
247
|
+
exampleFile: ".env.example",
|
|
248
|
+
});
|
|
249
|
+
```
|
|
155
250
|
|
|
156
|
-
|
|
251
|
+
Validate an in-memory object:
|
|
157
252
|
|
|
158
253
|
```ts
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
trimItems: false, // default: true
|
|
164
|
-
allowEmptyItems: true, // default: false
|
|
165
|
-
},
|
|
254
|
+
import { validateExampleEnv } from "node-safe-env";
|
|
255
|
+
|
|
256
|
+
const issues = validateExampleEnv(schema, {
|
|
257
|
+
PORT: "",
|
|
166
258
|
});
|
|
167
259
|
```
|
|
168
260
|
|
|
169
|
-
|
|
261
|
+
## Rule Types
|
|
170
262
|
|
|
171
|
-
|
|
172
|
-
- `trimItems`: `true`
|
|
173
|
-
- `allowEmptyItems`: `false`
|
|
263
|
+
Supported `type` values:
|
|
174
264
|
|
|
175
|
-
|
|
265
|
+
- `string`
|
|
266
|
+
- `number`
|
|
267
|
+
- `boolean`
|
|
268
|
+
- `enum`
|
|
269
|
+
- `url`
|
|
270
|
+
- `port`
|
|
271
|
+
- `json`
|
|
272
|
+
- `int`
|
|
273
|
+
- `float`
|
|
274
|
+
- `array`
|
|
275
|
+
- `email`
|
|
276
|
+
- `date`
|
|
277
|
+
- `custom`
|
|
176
278
|
|
|
177
|
-
|
|
279
|
+
## Loading Order
|
|
178
280
|
|
|
179
|
-
|
|
180
|
-
const env = createEnv({
|
|
181
|
-
PORT: { type: "port", default: 3000 },
|
|
182
|
-
START_DATE: { type: "date", default: () => "2026-01-01" },
|
|
183
|
-
ADMIN_EMAIL: { type: "email", default: () => "admin@example.com" },
|
|
184
|
-
});
|
|
185
|
-
```
|
|
281
|
+
When `options.source` is not provided, values are merged in this order and later sources win:
|
|
186
282
|
|
|
187
|
-
|
|
283
|
+
1. `.env`
|
|
284
|
+
2. `.env.local`
|
|
285
|
+
3. `.env.<NODE_ENV>`
|
|
286
|
+
4. Custom file from `options.envFile`
|
|
287
|
+
5. `process.env`
|
|
188
288
|
|
|
189
289
|
## Debug Mode
|
|
190
290
|
|
|
191
|
-
|
|
291
|
+
Use debug mode to inspect how values were loaded and resolved.
|
|
192
292
|
|
|
193
293
|
```ts
|
|
194
294
|
import { createEnv, type EnvDebugReport } from "node-safe-env";
|
|
@@ -202,19 +302,12 @@ createEnv(schema, {
|
|
|
202
302
|
});
|
|
203
303
|
```
|
|
204
304
|
|
|
205
|
-
|
|
305
|
+
Or log debug reports directly:
|
|
206
306
|
|
|
207
307
|
```ts
|
|
208
|
-
createEnv(schema, { debug: true });
|
|
308
|
+
createEnv(schema, { debug: true });
|
|
209
309
|
```
|
|
210
310
|
|
|
211
|
-
Debug reports include:
|
|
212
|
-
|
|
213
|
-
- loaded file metadata (`loadedFiles`)
|
|
214
|
-
- per-key entries (`keys`) with source, status, default usage, and issue details
|
|
215
|
-
|
|
216
|
-
Sensitive rules (`sensitive: true`) are masked as `"***"` in debug `raw` and `parsed` fields.
|
|
217
|
-
|
|
218
311
|
## Strict Mode
|
|
219
312
|
|
|
220
313
|
```ts
|
|
@@ -223,98 +316,6 @@ createEnv(schema, { strict: true });
|
|
|
223
316
|
|
|
224
317
|
Strict mode reports unknown environment keys as validation issues.
|
|
225
318
|
|
|
226
|
-
## Masking Sensitive Values
|
|
227
|
-
|
|
228
|
-
Use `maskEnv()` to sanitize parsed env output for logs.
|
|
229
|
-
|
|
230
|
-
```ts
|
|
231
|
-
import { createEnv, maskEnv } from "node-safe-env";
|
|
232
|
-
|
|
233
|
-
const schema = {
|
|
234
|
-
API_TOKEN: { type: "string", required: true, sensitive: true },
|
|
235
|
-
PORT: { type: "port", default: 3000 },
|
|
236
|
-
} as const;
|
|
237
|
-
|
|
238
|
-
const env = createEnv(schema);
|
|
239
|
-
const safeEnv = maskEnv(schema, env);
|
|
240
|
-
```
|
|
241
|
-
|
|
242
|
-
## Source Tracing
|
|
243
|
-
|
|
244
|
-
Use `traceEnv()` when you have a source map of raw values and origin labels.
|
|
245
|
-
|
|
246
|
-
```ts
|
|
247
|
-
import { traceEnv } from "node-safe-env";
|
|
248
|
-
|
|
249
|
-
const trace = traceEnv(
|
|
250
|
-
{
|
|
251
|
-
PORT: { type: "port" },
|
|
252
|
-
},
|
|
253
|
-
{
|
|
254
|
-
PORT: { source: "process.env", raw: "3000" },
|
|
255
|
-
},
|
|
256
|
-
{
|
|
257
|
-
PORT: 3000,
|
|
258
|
-
},
|
|
259
|
-
);
|
|
260
|
-
```
|
|
261
|
-
|
|
262
|
-
## `.env.example` Validation
|
|
263
|
-
|
|
264
|
-
Validate an example file against your schema:
|
|
265
|
-
|
|
266
|
-
```ts
|
|
267
|
-
import { validateExampleEnvFile } from "node-safe-env";
|
|
268
|
-
|
|
269
|
-
const issues = validateExampleEnvFile(schema, {
|
|
270
|
-
cwd: process.cwd(),
|
|
271
|
-
exampleFile: ".env.example",
|
|
272
|
-
});
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
Or validate an in-memory object:
|
|
276
|
-
|
|
277
|
-
```ts
|
|
278
|
-
import { validateExampleEnv } from "node-safe-env";
|
|
279
|
-
|
|
280
|
-
const issues = validateExampleEnv(schema, {
|
|
281
|
-
PORT: "",
|
|
282
|
-
});
|
|
283
|
-
```
|
|
284
|
-
|
|
285
|
-
## CLI
|
|
286
|
-
|
|
287
|
-
`node-safe-env` includes a CLI with two commands.
|
|
288
|
-
|
|
289
|
-
```bash
|
|
290
|
-
# installed locally (package.json scripts or npx)
|
|
291
|
-
node-safe-env validate --schema ./dist/env.schema.js
|
|
292
|
-
node-safe-env validate-example --schema ./dist/env.schema.js
|
|
293
|
-
|
|
294
|
-
# one-off with npx
|
|
295
|
-
npx node-safe-env validate --schema ./dist/env.schema.js
|
|
296
|
-
```
|
|
297
|
-
|
|
298
|
-
`validate` options:
|
|
299
|
-
|
|
300
|
-
- `--schema <path>` (required)
|
|
301
|
-
- `--cwd <path>`
|
|
302
|
-
- `--env-file <path>`
|
|
303
|
-
- `--node-env <value>`
|
|
304
|
-
- `--strict`
|
|
305
|
-
|
|
306
|
-
`validate-example` options:
|
|
307
|
-
|
|
308
|
-
- `--schema <path>` (required)
|
|
309
|
-
- `--cwd <path>`
|
|
310
|
-
- `--example-file <path>`
|
|
311
|
-
|
|
312
|
-
CLI schema loading note:
|
|
313
|
-
|
|
314
|
-
- the `--schema` target must be an executable JavaScript module
|
|
315
|
-
- accepted export shapes: default export or named export `schema`
|
|
316
|
-
- use built `.js`, `.mjs`, or `.cjs` files for CLI usage
|
|
317
|
-
|
|
318
319
|
## Error Handling
|
|
319
320
|
|
|
320
321
|
Validation issues are aggregated and thrown as `EnvValidationError`.
|
|
@@ -346,7 +347,7 @@ Exports:
|
|
|
346
347
|
- `readEnvFileSource`
|
|
347
348
|
- `resolveExampleEnvPath`
|
|
348
349
|
|
|
349
|
-
`createEnv(schema, options?)
|
|
350
|
+
`createEnv(schema, options?)`:
|
|
350
351
|
|
|
351
352
|
```ts
|
|
352
353
|
{
|
|
@@ -365,7 +366,7 @@ Exports:
|
|
|
365
366
|
- ESM and CommonJS builds
|
|
366
367
|
- TypeScript declarations included
|
|
367
368
|
|
|
368
|
-
## Development
|
|
369
|
+
## Development
|
|
369
370
|
|
|
370
371
|
```bash
|
|
371
372
|
npm run lint
|
package/dist/cli.js
CHANGED
|
@@ -793,16 +793,90 @@ function formatIssues(issues) {
|
|
|
793
793
|
return issues.map((issue) => `- ${issue.key}: ${issue.message}`).join("\n");
|
|
794
794
|
}
|
|
795
795
|
|
|
796
|
+
// src/cli/utils/formatCliError.ts
|
|
797
|
+
function formatCliError(error) {
|
|
798
|
+
const message = error instanceof Error ? error.message : "Unknown CLI error";
|
|
799
|
+
return `CLI error: ${message}`;
|
|
800
|
+
}
|
|
801
|
+
|
|
796
802
|
// src/cli/utils/loadSchemaModule.ts
|
|
797
803
|
import path3 from "path";
|
|
804
|
+
import fs2 from "fs";
|
|
798
805
|
import { pathToFileURL } from "url";
|
|
806
|
+
var SUPPORTED_SCHEMA_EXTENSIONS = [
|
|
807
|
+
".js",
|
|
808
|
+
".mjs",
|
|
809
|
+
".cjs",
|
|
810
|
+
".ts",
|
|
811
|
+
".mts",
|
|
812
|
+
".cts"
|
|
813
|
+
];
|
|
799
814
|
function isObject(value) {
|
|
800
815
|
return typeof value === "object" && value !== null;
|
|
801
816
|
}
|
|
817
|
+
function isTypeScriptFile(filePath) {
|
|
818
|
+
const ext = path3.extname(filePath).toLowerCase();
|
|
819
|
+
return ext === ".ts" || ext === ".mts" || ext === ".cts";
|
|
820
|
+
}
|
|
821
|
+
function isSupportedSchemaFile(filePath) {
|
|
822
|
+
const ext = path3.extname(filePath).toLowerCase();
|
|
823
|
+
return SUPPORTED_SCHEMA_EXTENSIONS.includes(
|
|
824
|
+
ext
|
|
825
|
+
);
|
|
826
|
+
}
|
|
827
|
+
function assertSchemaPathIsUsable(absolutePath, schemaPath) {
|
|
828
|
+
if (!isSupportedSchemaFile(absolutePath)) {
|
|
829
|
+
throw new Error(
|
|
830
|
+
`Unsupported schema file type for "${schemaPath}". Supported extensions: ${SUPPORTED_SCHEMA_EXTENSIONS.join(", ")}.`
|
|
831
|
+
);
|
|
832
|
+
}
|
|
833
|
+
if (!fs2.existsSync(absolutePath)) {
|
|
834
|
+
throw new Error(
|
|
835
|
+
`Schema file not found: "${schemaPath}" (resolved to "${absolutePath}").`
|
|
836
|
+
);
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
async function importTypeScriptModule(absolutePath, schemaPath) {
|
|
840
|
+
try {
|
|
841
|
+
const { register } = await import("tsx/esm/api");
|
|
842
|
+
const api = register({
|
|
843
|
+
namespace: `node-safe-env:${Date.now()}:${Math.random().toString(36).slice(2)}`
|
|
844
|
+
});
|
|
845
|
+
const loaded = await (async () => {
|
|
846
|
+
try {
|
|
847
|
+
return await api.import(
|
|
848
|
+
pathToFileURL(absolutePath).href,
|
|
849
|
+
import.meta.url
|
|
850
|
+
);
|
|
851
|
+
} finally {
|
|
852
|
+
api.unregister();
|
|
853
|
+
}
|
|
854
|
+
})();
|
|
855
|
+
if (isObject(loaded)) {
|
|
856
|
+
return loaded;
|
|
857
|
+
}
|
|
858
|
+
return { default: loaded };
|
|
859
|
+
} catch (error) {
|
|
860
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
861
|
+
throw new Error(
|
|
862
|
+
`Failed to load TypeScript schema module "${schemaPath}" using tsx runtime: ${message}`
|
|
863
|
+
);
|
|
864
|
+
}
|
|
865
|
+
}
|
|
802
866
|
async function loadSchemaModule(schemaPath) {
|
|
803
867
|
const absolutePath = path3.resolve(schemaPath);
|
|
804
868
|
const moduleUrl = pathToFileURL(absolutePath).href;
|
|
805
|
-
|
|
869
|
+
assertSchemaPathIsUsable(absolutePath, schemaPath);
|
|
870
|
+
const mod = isTypeScriptFile(absolutePath) ? await importTypeScriptModule(absolutePath, schemaPath) : await (async () => {
|
|
871
|
+
try {
|
|
872
|
+
return await import(moduleUrl);
|
|
873
|
+
} catch (error) {
|
|
874
|
+
const message = error instanceof Error ? error.message : "Unknown error";
|
|
875
|
+
throw new Error(
|
|
876
|
+
`Failed to import schema module "${schemaPath}": ${message}`
|
|
877
|
+
);
|
|
878
|
+
}
|
|
879
|
+
})();
|
|
806
880
|
const schemaCandidate = mod.default ?? mod.schema;
|
|
807
881
|
if (!isObject(schemaCandidate)) {
|
|
808
882
|
throw new Error(
|
|
@@ -830,8 +904,7 @@ async function runValidateCommand(options) {
|
|
|
830
904
|
console.error(formatIssues(error.issues));
|
|
831
905
|
return 1;
|
|
832
906
|
}
|
|
833
|
-
|
|
834
|
-
console.error(`CLI error: ${message}`);
|
|
907
|
+
console.error(formatCliError(error));
|
|
835
908
|
return 1;
|
|
836
909
|
}
|
|
837
910
|
}
|
|
@@ -927,8 +1000,7 @@ async function runValidateExampleCommand(options) {
|
|
|
927
1000
|
console.log("\u2713 .env.example validation passed.");
|
|
928
1001
|
return 0;
|
|
929
1002
|
} catch (error) {
|
|
930
|
-
|
|
931
|
-
console.error(`CLI error: ${message}`);
|
|
1003
|
+
console.error(formatCliError(error));
|
|
932
1004
|
return 1;
|
|
933
1005
|
}
|
|
934
1006
|
}
|
|
@@ -946,13 +1018,22 @@ Commands:
|
|
|
946
1018
|
validate-example Validate a .env.example file against a schema
|
|
947
1019
|
|
|
948
1020
|
Options:
|
|
949
|
-
--schema <path> Path to schema module
|
|
1021
|
+
--schema <path> Path to schema module (.js, .mjs, .cjs, .ts, .mts, .cts)
|
|
950
1022
|
--cwd <path> Working directory for env file loading
|
|
951
1023
|
--env-file <path> Custom env file path for validate
|
|
952
1024
|
--node-env <value> NODE_ENV override for validate
|
|
953
1025
|
--strict Enable strict mode for unknown keys
|
|
954
1026
|
--example-file <path> Custom example file path for validate-example
|
|
955
1027
|
--help Show this help
|
|
1028
|
+
|
|
1029
|
+
Schema module exports:
|
|
1030
|
+
- default export
|
|
1031
|
+
- named export: schema
|
|
1032
|
+
|
|
1033
|
+
Examples:
|
|
1034
|
+
node-safe-env validate --schema ./env.schema.ts
|
|
1035
|
+
node-safe-env validate-example --schema ./env.schema.ts
|
|
1036
|
+
node-safe-env validate --schema ./dist/env.schema.js --strict
|
|
956
1037
|
`);
|
|
957
1038
|
}
|
|
958
1039
|
function getStringFlag(flags, name) {
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/utils/parseArgs.ts","../src/errors/EnvValidationError.ts","../src/createEnv.ts","../src/flattenSchema.ts","../src/findUnknownEnvKeys.ts","../src/loadEnvFiles.ts","../src/mergeSources.ts","../src/applyTransform.ts","../src/validators/boolean.ts","../src/validators/enum.ts","../src/validators/json.ts","../src/validators/number.ts","../src/validators/port.ts","../src/validators/string.ts","../src/validators/url.ts","../src/validators/int.ts","../src/validators/float.ts","../src/validators/array.ts","../src/validators/custom.ts","../src/validators/email.ts","../src/validators/date.ts","../src/validators/index.ts","../src/parseValue.ts","../src/setNestedValue.ts","../src/cli/utils/formatIssues.ts","../src/cli/utils/loadSchemaModule.ts","../src/cli/commands/validate.ts","../src/readEnvFileSource.ts","../src/validateExampleEnv.ts","../src/validateExampleEnvFile.ts","../src/cli/commands/validateExample.ts","../src/cli/index.ts"],"sourcesContent":["export type ParsedCliArgs = {\r\n command?: string;\r\n flags: Record<string, string | boolean>;\r\n positionals: string[];\r\n};\r\n\r\nexport function parseArgs(argv: string[]): ParsedCliArgs {\r\n const [command, ...rest] = argv;\r\n\r\n const flags: Record<string, string | boolean> = {};\r\n const positionals: string[] = [];\r\n\r\n for (let index = 0; index < rest.length; index += 1) {\r\n const token = rest[index];\r\n\r\n if (!token.startsWith(\"--\")) {\r\n positionals.push(token);\r\n continue;\r\n }\r\n\r\n const flagName = token.slice(2);\r\n const next = rest[index + 1];\r\n\r\n if (!next || next.startsWith(\"--\")) {\r\n flags[flagName] = true;\r\n continue;\r\n }\r\n\r\n flags[flagName] = next;\r\n index += 1;\r\n }\r\n\r\n return {\r\n command,\r\n flags,\r\n positionals,\r\n };\r\n}\r\n","import type { EnvValidationIssue } from \"../types/schema\";\n\nexport class EnvValidationError extends Error {\n public readonly issues: EnvValidationIssue[];\n\n constructor(issues: EnvValidationIssue[]) {\n super(\n [\n \"Environment validation failed:\",\n ...issues.map((issue) => `- [${issue.code}] ${issue.message}`),\n ].join(\"\\n\"),\n );\n\n this.name = \"EnvValidationError\";\n this.issues = issues;\n }\n}\n","import { EnvValidationError } from \"./errors/EnvValidationError\";\nimport path from \"node:path\";\nimport { findUnknownEnvKeys } from \"./findUnknownEnvKeys\";\nimport { flattenSchema } from \"./flattenSchema\";\nimport { loadEnvFiles } from \"./loadEnvFiles\";\nimport { mergeSources } from \"./mergeSources\";\nimport { parseValue } from \"./parseValue\";\nimport { setNestedValue } from \"./setNestedValue\";\nimport type {\n CreateEnvOptions,\n EnvDebugDefaultKind,\n EnvDebugKeyEntry,\n EnvDebugLoadedFile,\n EnvDebugReport,\n EnvDebugSource,\n EnvRule,\n EnvSchema,\n EnvValidationIssue,\n EnvValueSource,\n LoadedEnvFiles,\n ParsedEnv,\n} from \"./types/schema\";\n\nfunction isEmptyString(value: string): boolean {\n return value.trim() === \"\";\n}\n\nfunction defaultToRawValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n return JSON.stringify(value);\n}\n\nfunction resolveDefaultValue(value: unknown): unknown {\n return typeof value === \"function\" ? (value as () => unknown)() : value;\n}\n\nfunction parseDefaultValue(\n envKey: string,\n rule: EnvRule,\n): ReturnType<typeof parseValue> & {\n defaultKind: EnvDebugDefaultKind;\n rawDefault?: string;\n} {\n const defaultKind: EnvDebugDefaultKind =\n typeof rule.default === \"function\" ? \"function\" : \"static\";\n let resolvedDefault: unknown;\n\n try {\n resolvedDefault = resolveDefaultValue(rule.default);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n issue: {\n key: envKey,\n code: \"invalid_default\",\n message: `Default function for \"${envKey}\" threw an error: ${message}`,\n },\n defaultKind,\n };\n }\n\n const rawDefault = defaultToRawValue(resolvedDefault);\n\n return {\n ...parseValue(envKey, rawDefault, rule),\n defaultKind,\n rawDefault,\n };\n}\n\ntype SourceTrace = Record<string, { source: EnvValueSource; raw: string }>;\n\nfunction countKeys(source: Record<string, string | undefined>): number {\n return Object.values(source).filter((value) => typeof value === \"string\")\n .length;\n}\n\nfunction buildLoadedFileReport(\n loadedFiles: LoadedEnvFiles,\n cwd: string,\n nodeEnv: string,\n envFile?: string,\n): EnvDebugLoadedFile[] {\n return [\n {\n source: \".env\",\n path: path.join(cwd, \".env\"),\n keyCount: countKeys(loadedFiles.base),\n },\n {\n source: \".env.local\",\n path: path.join(cwd, \".env.local\"),\n keyCount: countKeys(loadedFiles.local),\n },\n {\n source: \".env.environment\",\n path: path.join(cwd, `.env.${nodeEnv}`),\n keyCount: countKeys(loadedFiles.environment),\n },\n {\n source: \"custom\",\n path: envFile ? path.resolve(cwd, envFile) : undefined,\n keyCount: countKeys(loadedFiles.custom),\n },\n ];\n}\n\nfunction buildSourceTrace(\n loadedFiles: LoadedEnvFiles,\n runtimeValues: Record<string, string | undefined>,\n): SourceTrace {\n const trace: SourceTrace = Object.create(null) as SourceTrace;\n\n const applySource = (\n source: Record<string, string | undefined>,\n label: EnvValueSource,\n ): void => {\n for (const [key, raw] of Object.entries(source)) {\n if (typeof raw === \"string\") {\n trace[key] = { source: label, raw };\n }\n }\n };\n\n applySource(loadedFiles.base, \".env\");\n applySource(loadedFiles.local, \".env.local\");\n applySource(loadedFiles.environment, \".env.environment\");\n applySource(loadedFiles.custom, \"custom\");\n applySource(runtimeValues, \"process.env\");\n\n return trace;\n}\n\nfunction maskDebugValue(value: unknown, sensitive: boolean): unknown {\n if (value === undefined) {\n return undefined;\n }\n\n return sensitive ? \"***\" : value;\n}\n\nfunction resolveDebugLogger(\n debug: CreateEnvOptions[\"debug\"],\n): ((report: EnvDebugReport) => void) | undefined {\n if (debug === true) {\n return (report: EnvDebugReport): void => {\n console.info(report);\n };\n }\n\n if (debug && typeof debug === \"object\" && debug.logger) {\n return debug.logger;\n }\n\n return undefined;\n}\n\nexport function createEnv<S extends EnvSchema>(\n schema: S,\n options: CreateEnvOptions = {},\n): ParsedEnv<S> {\n const debugEnabled = options.debug !== undefined && options.debug !== false;\n const debugLogger = debugEnabled\n ? resolveDebugLogger(options.debug)\n : undefined;\n const debugKeys: EnvDebugKeyEntry[] = [];\n\n let source: Record<string, string | undefined>;\n let loadedFileReport: EnvDebugLoadedFile[] = [];\n let sourceTrace: SourceTrace = Object.create(null) as SourceTrace;\n\n if (options.source) {\n source = options.source;\n\n if (debugEnabled) {\n for (const [key, raw] of Object.entries(source)) {\n if (typeof raw === \"string\") {\n sourceTrace[key] = { source: \"process.env\", raw };\n }\n }\n }\n } else {\n const loadedFiles = loadEnvFiles({\n cwd: options.cwd,\n nodeEnv: options.nodeEnv,\n envFile: options.envFile,\n });\n source = mergeSources(loadedFiles, process.env);\n\n if (debugEnabled) {\n const cwd = options.cwd ?? process.cwd();\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV ?? \"development\";\n loadedFileReport = buildLoadedFileReport(\n loadedFiles,\n cwd,\n nodeEnv,\n options.envFile,\n );\n sourceTrace = buildSourceTrace(loadedFiles, process.env);\n }\n }\n\n const issues: EnvValidationIssue[] = [];\n const result: Record<string, unknown> = {};\n const flattenedSchema = flattenSchema(schema as Record<string, unknown>);\n\n if (options.strict) {\n issues.push(\n ...findUnknownEnvKeys(schema as Record<string, unknown>, source),\n );\n }\n\n for (const entry of flattenedSchema) {\n const { path, envKey, rule } = entry;\n const currentValue = source[envKey];\n const sourceInfo = sourceTrace[envKey];\n const sensitive = rule.sensitive === true;\n const defaultKind: EnvDebugDefaultKind | undefined =\n rule.default === undefined\n ? undefined\n : typeof rule.default === \"function\"\n ? \"function\"\n : \"static\";\n\n const pushDebugEntry = (\n status: EnvDebugKeyEntry[\"status\"],\n values: {\n source: EnvDebugSource;\n usedDefault: boolean;\n raw?: string;\n parsed?: unknown;\n issue?: EnvValidationIssue;\n defaultKind?: EnvDebugDefaultKind;\n },\n ): void => {\n if (!debugEnabled) {\n return;\n }\n\n debugKeys.push({\n key: envKey,\n ruleType: rule.type,\n source: values.source,\n usedDefault: values.usedDefault,\n defaultKind: values.defaultKind,\n raw: maskDebugValue(values.raw, sensitive) as string | undefined,\n parsed: maskDebugValue(values.parsed, sensitive),\n status,\n issue: values.issue,\n });\n };\n\n if (typeof currentValue !== \"string\") {\n if (rule.default !== undefined) {\n const parsedDefault = parseDefaultValue(envKey, rule);\n\n if (parsedDefault.issue) {\n issues.push(parsedDefault.issue);\n pushDebugEntry(\"issue\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n issue: parsedDefault.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"defaulted\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n parsed: parsedDefault.value,\n });\n setNestedValue(result, path, parsedDefault.value);\n continue;\n }\n\n if (rule.required) {\n const issue = {\n key: envKey,\n code: \"missing\",\n message: `Missing required environment variable \"${envKey}\".`,\n } as const;\n\n issues.push(issue);\n pushDebugEntry(\"missing\", {\n source: \"missing\",\n usedDefault: false,\n defaultKind,\n issue,\n });\n } else {\n pushDebugEntry(\"missing\", {\n source: \"missing\",\n usedDefault: false,\n defaultKind,\n });\n }\n\n continue;\n }\n\n const rawValue = currentValue;\n\n if (!rule.allowEmpty && isEmptyString(rawValue)) {\n if (rule.default !== undefined) {\n const parsedDefault = parseDefaultValue(envKey, rule);\n\n if (parsedDefault.issue) {\n issues.push(parsedDefault.issue);\n pushDebugEntry(\"issue\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n issue: parsedDefault.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"defaulted\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n parsed: parsedDefault.value,\n });\n setNestedValue(result, path, parsedDefault.value);\n continue;\n }\n\n const issue = {\n key: envKey,\n code: \"empty\",\n message: `Environment variable \"${envKey}\" cannot be empty.`,\n } as const;\n\n issues.push(issue);\n pushDebugEntry(\"empty\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n issue,\n });\n continue;\n }\n\n const parsed = parseValue(envKey, rawValue, rule);\n\n if (parsed.issue) {\n issues.push(parsed.issue);\n pushDebugEntry(\"issue\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n issue: parsed.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"parsed\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n parsed: parsed.value,\n });\n setNestedValue(result, path, parsed.value);\n }\n\n if (debugLogger) {\n debugLogger({\n loadedFiles: loadedFileReport,\n keys: debugKeys,\n });\n }\n\n if (issues.length > 0) {\n throw new EnvValidationError(issues);\n }\n\n return result as unknown as ParsedEnv<S>;\n}\n","import type { EnvRule } from \"./types/schema\";\r\n\r\nexport type FlattenedSchemaEntry = {\r\n path: string[];\r\n envKey: string;\r\n rule: EnvRule;\r\n};\r\n\r\nfunction isEnvRule(value: unknown): value is EnvRule {\r\n return (\r\n typeof value === \"object\" &&\r\n value !== null &&\r\n \"type\" in value &&\r\n typeof (value as { type?: unknown }).type === \"string\"\r\n );\r\n}\r\n\r\nfunction toEnvKey(path: string[]): string {\r\n return path.map((segment) => segment.toUpperCase()).join(\"_\");\r\n}\r\n\r\nexport function flattenSchema(\r\n schema: Record<string, unknown>,\r\n parentPath: string[] = [],\r\n): FlattenedSchemaEntry[] {\r\n const entries: FlattenedSchemaEntry[] = [];\r\n\r\n for (const [key, value] of Object.entries(schema)) {\r\n const currentPath = [...parentPath, key];\r\n\r\n if (isEnvRule(value)) {\r\n entries.push({\r\n path: currentPath,\r\n envKey: toEnvKey(currentPath),\r\n rule: value,\r\n });\r\n\r\n continue;\r\n }\r\n\r\n if (typeof value === \"object\" && value !== null) {\r\n entries.push(\r\n ...flattenSchema(value as Record<string, unknown>, currentPath),\r\n );\r\n }\r\n }\r\n\r\n return entries;\r\n}\r\n","import { flattenSchema } from \"./flattenSchema\";\r\nimport type { EnvSource, EnvValidationIssue } from \"./types/schema\";\r\n\r\nexport function findUnknownEnvKeys(\r\n schema: Record<string, unknown>,\r\n source: EnvSource,\r\n): EnvValidationIssue[] {\r\n const knownKeys = new Set(flattenSchema(schema).map((entry) => entry.envKey));\r\n const issues: EnvValidationIssue[] = [];\r\n\r\n for (const key of Object.keys(source)) {\r\n if (source[key] === undefined) {\r\n continue;\r\n }\r\n\r\n if (knownKeys.has(key)) {\r\n continue;\r\n }\r\n\r\n issues.push({\r\n key,\r\n code: \"unknown_key\",\r\n message: `Environment variable \"${key}\" is not defined in the schema.`,\r\n });\r\n }\r\n\r\n return issues;\r\n}\r\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type {\n LoadEnvFilesOptions,\n EnvSource,\n LoadedEnvFiles,\n} from \"./types/schema\";\n\nconst ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nfunction stripInlineComment(input: string): string {\n let inSingleQuote = false;\n let inDoubleQuote = false;\n let isEscaped = false;\n\n for (let index = 0; index < input.length; index += 1) {\n const char = input[index];\n\n if (isEscaped) {\n isEscaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n isEscaped = true;\n continue;\n }\n\n if (char === '\"' && !inSingleQuote) {\n inDoubleQuote = !inDoubleQuote;\n continue;\n }\n\n if (char === \"'\" && !inDoubleQuote) {\n inSingleQuote = !inSingleQuote;\n continue;\n }\n\n if (\n char === \"#\" &&\n !inSingleQuote &&\n !inDoubleQuote &&\n (index === 0 || /\\s/.test(input[index - 1] ?? \"\"))\n ) {\n return input.slice(0, index).trimEnd();\n }\n }\n\n return input.trimEnd();\n}\n\nfunction parseEnvFile(filePath: string): EnvSource {\n if (!fs.existsSync(filePath)) {\n return Object.create(null) as EnvSource;\n }\n\n const content = fs.readFileSync(filePath, \"utf8\");\n const result = Object.create(null) as EnvSource;\n\n for (const rawLine of content.split(/\\r?\\n/)) {\n let line = rawLine.trim();\n\n if (!line || line.startsWith(\"#\")) {\n continue;\n }\n\n if (line.startsWith(\"export \")) {\n line = line.slice(\"export \".length).trim();\n\n if (!line) {\n continue;\n }\n }\n\n const equalIndex = line.indexOf(\"=\");\n\n if (equalIndex <= 0) {\n continue;\n }\n\n const key = line.slice(0, equalIndex).trim();\n\n if (!ENV_KEY_PATTERN.test(key)) {\n continue;\n }\n\n let value = stripInlineComment(line.slice(equalIndex + 1)).trim();\n\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n result[key] = value;\n }\n\n return result;\n}\n\nexport function loadEnvFiles(\n options: LoadEnvFilesOptions = {},\n): LoadedEnvFiles {\n const cwd = options.cwd ?? process.cwd();\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV ?? \"development\";\n\n const base = parseEnvFile(path.join(cwd, \".env\"));\n const local = parseEnvFile(path.join(cwd, \".env.local\"));\n const environment = parseEnvFile(path.join(cwd, `.env.${nodeEnv}`));\n const custom = options.envFile\n ? parseEnvFile(path.resolve(cwd, options.envFile))\n : (Object.create(null) as EnvSource);\n\n return {\n base,\n local,\n environment,\n custom,\n };\n}\n","import type { EnvSource, LoadedEnvFiles } from \"./types/schema\";\n\nexport function mergeSources(\n files: LoadedEnvFiles,\n runtimeValues: EnvSource = process.env,\n): EnvSource {\n return Object.assign(\n Object.create(null),\n files.base,\n files.local,\n files.environment,\n files.custom,\n runtimeValues,\n ) as EnvSource;\n}\n","import type { EnvRule, EnvValidationIssue } from \"./types/schema\";\r\nimport type { ParseResult } from \"./validators\";\r\n\r\nexport function applyTransform(\r\n key: string,\r\n rule: EnvRule,\r\n result: ParseResult,\r\n): ParseResult {\r\n if (result.issue || result.value === undefined || !rule.transform) {\r\n return result;\r\n }\r\n\r\n try {\r\n return {\r\n value: rule.transform(result.value as never),\r\n };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message\r\n ? error.message\r\n : `Environment variable \"${key}\" failed transform.`;\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_custom\",\r\n message,\r\n } satisfies EnvValidationIssue,\r\n };\r\n }\r\n}\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nconst TRUE_VALUES = new Set([\"true\", \"1\", \"yes\", \"on\"]);\r\nconst FALSE_VALUES = new Set([\"false\", \"0\", \"no\", \"off\"]);\r\n\r\nexport const validateBoolean: EnvValidator = ({ key, rawValue }) => {\r\n const normalized = rawValue.trim().toLowerCase();\r\n\r\n if (TRUE_VALUES.has(normalized)) {\r\n return { value: true };\r\n }\r\n\r\n if (FALSE_VALUES.has(normalized)) {\r\n return { value: false };\r\n }\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_boolean\",\r\n message: `Environment variable \"${key}\" must be a valid boolean.`,\r\n },\r\n };\r\n};\r\n","import type { EnumRule } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateEnum: EnvValidator = ({ key, rawValue, rule }) => {\r\n const enumRule = rule as EnumRule;\r\n\r\n if (!enumRule.values.includes(rawValue)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_enum\",\r\n message: `Environment variable \"${key}\" must be one of: ${enumRule.values.join(\", \")}.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: rawValue };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateJson: EnvValidator = ({ key, rawValue }) => {\r\n try {\r\n const parsed = JSON.parse(rawValue);\r\n\r\n return { value: parsed };\r\n } catch {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_json\",\r\n message: `Environment variable \"${key}\" must contain valid JSON.`,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateNumber: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isFinite(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid number.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validatePort: EnvValidator = ({ key, rawValue }) => {\r\n const num = Number(rawValue);\r\n\r\n if (!Number.isInteger(num) || num < 1 || num > 65535) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_port\",\r\n message: `Environment variable \"${key}\" must be a valid port (1–65535).`,\r\n },\r\n };\r\n }\r\n\r\n return { value: num };\r\n};","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateString: EnvValidator = ({ rawValue }) => {\r\n return { value: rawValue };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateUrl: EnvValidator = ({ key, rawValue }) => {\r\n try {\r\n new URL(rawValue);\r\n\r\n return { value: rawValue };\r\n } catch {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_url\",\r\n message: `Environment variable \"${key}\" must be a valid URL.`,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateInt: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isInteger(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid integer.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateFloat: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isFinite(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid float.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { ArrayRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateArray: EnvValidator = ({ key, rawValue, rule }) => {\r\n const arrayRule = rule as ArrayRule;\r\n const separator = arrayRule.separator ?? \",\";\r\n const trimItems = arrayRule.trimItems ?? true;\r\n const allowEmptyItems = arrayRule.allowEmptyItems ?? false;\r\n const splitValues = rawValue.split(separator);\r\n\r\n const parsed = trimItems\r\n ? splitValues.map((item) => item.trim())\r\n : splitValues;\r\n\r\n if (!allowEmptyItems && parsed.some((item) => item === \"\")) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_array\",\r\n message: `Environment variable \"${key}\" cannot contain empty array items`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { CustomRule } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateCustom: EnvValidator = ({ key, rawValue, rule }) => {\r\n const customRule = rule as CustomRule;\r\n\r\n try {\r\n const parsed = customRule.parse(rawValue);\r\n\r\n return { value: parsed };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message\r\n ? error.message\r\n : `Environment variable \"${key}\" failed custom validation.`;\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_custom\",\r\n message,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EmailRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateEmail: EnvValidator = ({ key, rawValue, rule }) => {\r\n const emailRule = rule as EmailRule;\r\n void emailRule;\r\n\r\n const value = rawValue.trim();\r\n\r\n if (!value) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n if (/\\s/.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n\r\n if (!emailRegex.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n return {\r\n value,\r\n };\r\n};","import type { DateRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nfunction isValidDate(date: Date): boolean {\r\n return !Number.isNaN(date.getTime());\r\n}\r\n\r\nexport const validateDate: EnvValidator = ({ key, rawValue, rule }) => {\r\n const dateRule = rule as DateRule;\r\n void dateRule;\r\n\r\n const value = rawValue.trim();\r\n\r\n if (!value) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid ISO date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n const isoDateTimeRegex =\r\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,3})?)?(Z|[+-]\\d{2}:\\d{2})$/;\r\n\r\n if (!isoDateRegex.test(value) && !isoDateTimeRegex.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid ISO date string`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const parsed = new Date(value);\r\n\r\n if (!isValidDate(parsed)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n if (isoDateRegex.test(value)) {\r\n const [year, month, day] = value.split(\"-\").map(Number);\r\n\r\n if (\r\n parsed.getUTCFullYear() !== year ||\r\n parsed.getUTCMonth() + 1 !== month ||\r\n parsed.getUTCDate() !== day\r\n ) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a real calendar date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n }\r\n\r\n return {\r\n value: parsed,\r\n };\r\n};\r\n","import { validateBoolean } from \"./boolean\";\r\nimport { validateEnum } from \"./enum\";\r\nimport { validateJson } from \"./json\";\r\nimport { validateNumber } from \"./number\";\r\nimport { validatePort } from \"./port\";\r\nimport { validateString } from \"./string\";\r\nimport { validateUrl } from \"./url\";\r\nimport type { EnvValidator } from \"./types\";\r\nimport { validateInt } from \"./int\";\r\nimport { validateFloat } from \"./float\";\r\nimport { validateArray } from \"./array\";\r\nimport { validateCustom } from \"./custom\";\r\nimport { validateEmail } from \"./email\";\r\nimport { validateDate } from \"./date\";\r\n\r\nexport const validators = {\r\n string: validateString,\r\n number: validateNumber,\r\n boolean: validateBoolean,\r\n enum: validateEnum,\r\n url: validateUrl,\r\n port: validatePort,\r\n json: validateJson,\r\n int: validateInt,\r\n float: validateFloat,\r\n array: validateArray,\r\n custom: validateCustom,\r\n email: validateEmail,\r\n date: validateDate,\r\n} as const satisfies {\r\n string: EnvValidator;\r\n number: EnvValidator;\r\n boolean: EnvValidator;\r\n enum: EnvValidator;\r\n url: EnvValidator;\r\n port: EnvValidator;\r\n json: EnvValidator;\r\n int: EnvValidator;\r\n float: EnvValidator;\r\n array: EnvValidator;\r\n custom: EnvValidator;\r\n email: EnvValidator;\r\n date: EnvValidator;\r\n};\r\n\r\nexport type { ParseResult, EnvValidator } from \"./types\";\r\n","import { applyTransform } from \"./applyTransform\";\nimport type { EnvRule } from \"./types/schema\";\nimport { validators } from \"./validators\";\nimport type { ParseResult } from \"./validators\";\n\nexport function parseValue(\n key: string,\n rawValue: string,\n rule: EnvRule,\n): ParseResult {\n const validator = validators[rule.type];\n\n const result = validator({\n key,\n rawValue,\n rule,\n });\n\n return applyTransform(key, rule, result);\n}\n","export function setNestedValue(\r\n target: Record<string, unknown>,\r\n path: string[],\r\n value: unknown,\r\n): void {\r\n let current: Record<string, unknown> = target;\r\n\r\n for (let index = 0; index < path.length - 1; index += 1) {\r\n const segment = path[index];\r\n const existing = current[segment];\r\n\r\n if (\r\n typeof existing !== \"object\" ||\r\n existing === null ||\r\n Array.isArray(existing)\r\n ) {\r\n current[segment] = {};\r\n }\r\n\r\n current = current[segment] as Record<string, unknown>;\r\n }\r\n\r\n current[path[path.length - 1]] = value;\r\n}\r\n","import type { EnvValidationIssue } from \"../../types/schema\";\r\n\r\nexport function formatIssues(issues: EnvValidationIssue[]): string {\r\n return issues.map((issue) => `- ${issue.key}: ${issue.message}`).join(\"\\n\");\r\n}\r\n","import path from \"node:path\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport type { EnvSchema } from \"../../types/schema\";\r\n\r\ntype SchemaModule = {\r\n default?: unknown;\r\n schema?: unknown;\r\n};\r\n\r\nfunction isObject(value: unknown): value is Record<string, unknown> {\r\n return typeof value === \"object\" && value !== null;\r\n}\r\n\r\nexport async function loadSchemaModule(schemaPath: string): Promise<EnvSchema> {\r\n const absolutePath = path.resolve(schemaPath);\r\n const moduleUrl = pathToFileURL(absolutePath).href;\r\n\r\n const mod = (await import(moduleUrl)) as SchemaModule;\r\n\r\n const schemaCandidate = mod.default ?? mod.schema;\r\n\r\n if (!isObject(schemaCandidate)) {\r\n throw new Error(\r\n `Schema module \"${schemaPath}\" must export a schema as default export or named export \"schema\".`,\r\n );\r\n }\r\n\r\n return schemaCandidate as EnvSchema;\r\n}\r\n","import { createEnv } from \"../../createEnv\";\r\nimport { EnvValidationError } from \"../../errors/EnvValidationError\";\r\nimport { formatIssues } from \"../utils/formatIssues\";\r\nimport { loadSchemaModule } from \"../utils/loadSchemaModule\";\r\n\r\nexport type ValidateCommandOptions = {\r\n schemaPath: string;\r\n cwd?: string;\r\n envFile?: string;\r\n nodeEnv?: string;\r\n strict?: boolean;\r\n};\r\n\r\nexport async function runValidateCommand(\r\n options: ValidateCommandOptions,\r\n): Promise<number> {\r\n try {\r\n const schema = await loadSchemaModule(options.schemaPath);\r\n\r\n createEnv(schema, {\r\n cwd: options.cwd,\r\n envFile: options.envFile,\r\n nodeEnv: options.nodeEnv,\r\n strict: options.strict,\r\n });\r\n\r\n console.log(\"✓ Environment validation passed.\");\r\n return 0;\r\n } catch (error) {\r\n if (error instanceof EnvValidationError) {\r\n console.error(\"Environment validation failed:\\n\");\r\n console.error(formatIssues(error.issues));\r\n return 1;\r\n }\r\n\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown CLI error\";\r\n console.error(`CLI error: ${message}`);\r\n return 1;\r\n }\r\n}","import { existsSync, readFileSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\nimport type { EnvSource } from \"./types/schema\";\r\n\r\nfunction stripQuotes(value: string): string {\r\n if (\r\n (value.startsWith('\"') && value.endsWith('\"')) ||\r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\r\n ) {\r\n return value.slice(1, -1);\r\n }\r\n\r\n return value;\r\n}\r\n\r\nexport function readEnvFileSource(filePath: string): EnvSource {\r\n if (!existsSync(filePath)) {\r\n return {};\r\n }\r\n\r\n const content = readFileSync(filePath, \"utf8\");\r\n const source: EnvSource = {};\r\n\r\n for (const line of content.split(/\\r?\\n/)) {\r\n const trimmed = line.trim();\r\n\r\n if (!trimmed || trimmed.startsWith(\"#\")) {\r\n continue;\r\n }\r\n\r\n const equalsIndex = trimmed.indexOf(\"=\");\r\n\r\n if (equalsIndex === -1) {\r\n continue;\r\n }\r\n\r\n const key = trimmed.slice(0, equalsIndex).trim();\r\n const rawValue = trimmed.slice(equalsIndex + 1).trim();\r\n\r\n if (!key) {\r\n continue;\r\n }\r\n\r\n source[key] = stripQuotes(rawValue);\r\n }\r\n\r\n return source;\r\n}\r\n\r\nexport function resolveExampleEnvPath(\r\n cwd: string = process.cwd(),\r\n exampleFile: string = \".env.example\",\r\n): string {\r\n return resolve(cwd, exampleFile);\r\n}\r\n","import { flattenSchema } from \"./flattenSchema\";\r\nimport type { EnvSchema, EnvSource, EnvValidationIssue } from \"./types/schema\";\r\n\r\nexport function validateExampleEnv(\r\n schema: EnvSchema,\r\n exampleSource: EnvSource,\r\n): EnvValidationIssue[] {\r\n const issues: EnvValidationIssue[] = [];\r\n const flattenedSchema = flattenSchema(schema);\r\n const expectedKeys = new Set(flattenedSchema.map((entry) => entry.envKey));\r\n\r\n for (const entry of flattenedSchema) {\r\n const { envKey } = entry;\r\n\r\n if (!(envKey in exampleSource)) {\r\n issues.push({\r\n key: envKey,\r\n code: \"missing_example_key\",\r\n message: `Environment variable \"${envKey}\" is missing from .env.example.`,\r\n });\r\n }\r\n }\r\n\r\n for (const key of Object.keys(exampleSource)) {\r\n if (exampleSource[key] === undefined) {\r\n continue;\r\n }\r\n\r\n if (expectedKeys.has(key)) {\r\n continue;\r\n }\r\n\r\n issues.push({\r\n key,\r\n code: \"unknown_example_key\",\r\n message: `Environment variable \"${key}\" in .env.example is not defined in the schema.`,\r\n });\r\n }\r\n\r\n return issues;\r\n}\r\n","import { readEnvFileSource, resolveExampleEnvPath } from \"./readEnvFileSource\";\r\nimport { validateExampleEnv } from \"./validateExampleEnv\";\r\nimport type {\r\n EnvSchema,\r\n EnvValidationIssue,\r\n ValidateExampleEnvFileOptions,\r\n} from \"./types/schema\";\r\n\r\nexport function validateExampleEnvFile(\r\n schema: EnvSchema,\r\n options: ValidateExampleEnvFileOptions = {},\r\n): EnvValidationIssue[] {\r\n const filePath = resolveExampleEnvPath(options.cwd, options.exampleFile);\r\n const exampleSource = readEnvFileSource(filePath);\r\n\r\n return validateExampleEnv(schema, exampleSource);\r\n}\r\n","import { formatIssues } from \"../utils/formatIssues\";\r\nimport { loadSchemaModule } from \"../utils/loadSchemaModule\";\r\nimport { validateExampleEnvFile } from \"../../validateExampleEnvFile\";\r\n\r\nexport type ValidateExampleCommandOptions = {\r\n schemaPath: string;\r\n cwd?: string;\r\n exampleFile?: string;\r\n};\r\n\r\nexport async function runValidateExampleCommand(\r\n options: ValidateExampleCommandOptions,\r\n): Promise<number> {\r\n try {\r\n const schema = await loadSchemaModule(options.schemaPath);\r\n\r\n const issues = validateExampleEnvFile(schema, {\r\n cwd: options.cwd,\r\n exampleFile: options.exampleFile,\r\n });\r\n\r\n if (issues.length > 0) {\r\n console.error(\".env.example validation failed:\\n\");\r\n console.error(formatIssues(issues));\r\n return 1;\r\n }\r\n\r\n console.log(\"✓ .env.example validation passed.\");\r\n return 0;\r\n } catch (error) {\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown CLI error\";\r\n console.error(`CLI error: ${message}`);\r\n return 1;\r\n }\r\n}\r\n","#!/usr/bin/env node\r\n\r\nimport { parseArgs } from \"./utils/parseArgs\";\r\nimport { runValidateCommand } from \"./commands/validate\";\r\nimport { runValidateExampleCommand } from \"./commands/validateExample\";\r\n\r\ntype CliIO = {\r\n log: (message: string) => void;\r\n error: (message: string) => void;\r\n};\r\n\r\nfunction printHelp(io: CliIO): void {\r\n io.log(`node-safe-env CLI\r\n\r\nUsage:\r\n node-safe-env validate --schema <path> [--cwd <path>] [--env-file <path>] [--node-env <value>] [--strict]\r\n node-safe-env validate-example --schema <path> [--cwd <path>] [--example-file <path>]\r\n\r\nCommands:\r\n validate Validate environment variables using a schema\r\n validate-example Validate a .env.example file against a schema\r\n\r\nOptions:\r\n --schema <path> Path to schema module\r\n --cwd <path> Working directory for env file loading\r\n --env-file <path> Custom env file path for validate\r\n --node-env <value> NODE_ENV override for validate\r\n --strict Enable strict mode for unknown keys\r\n --example-file <path> Custom example file path for validate-example\r\n --help Show this help\r\n`);\r\n}\r\n\r\nfunction getStringFlag(\r\n flags: Record<string, string | boolean>,\r\n name: string,\r\n): string | undefined {\r\n const value = flags[name];\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nexport async function runCli(\r\n argv: string[],\r\n io: CliIO = {\r\n log: console.log,\r\n error: console.error,\r\n },\r\n): Promise<number> {\r\n const parsed = parseArgs(argv);\r\n\r\n if (\r\n !parsed.command ||\r\n parsed.flags.help ||\r\n parsed.command === \"help\" ||\r\n parsed.command === \"--help\"\r\n ) {\r\n printHelp(io);\r\n return 0;\r\n }\r\n\r\n const schemaPath = getStringFlag(parsed.flags, \"schema\");\r\n\r\n if (!schemaPath) {\r\n io.error('Missing required flag \"--schema\".\\n');\r\n printHelp(io);\r\n return 1;\r\n }\r\n\r\n if (parsed.command === \"validate\") {\r\n return runValidateCommand({\r\n schemaPath,\r\n cwd: getStringFlag(parsed.flags, \"cwd\"),\r\n envFile: getStringFlag(parsed.flags, \"env-file\"),\r\n nodeEnv: getStringFlag(parsed.flags, \"node-env\"),\r\n strict: parsed.flags.strict === true,\r\n });\r\n }\r\n\r\n if (parsed.command === \"validate-example\") {\r\n return runValidateExampleCommand({\r\n schemaPath,\r\n cwd: getStringFlag(parsed.flags, \"cwd\"),\r\n exampleFile: getStringFlag(parsed.flags, \"example-file\"),\r\n });\r\n }\r\n\r\n io.error(`Unknown command \"${parsed.command}\".\\n`);\r\n printHelp(io);\r\n return 1;\r\n}\r\n\r\nasync function main(): Promise<void> {\r\n const exitCode = await runCli(process.argv.slice(2));\r\n process.exitCode = exitCode;\r\n}\r\n\r\nvoid main();\r\n"],"mappings":"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","names":["path","path","path","path","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/cli/utils/parseArgs.ts","../src/errors/EnvValidationError.ts","../src/createEnv.ts","../src/flattenSchema.ts","../src/findUnknownEnvKeys.ts","../src/loadEnvFiles.ts","../src/mergeSources.ts","../src/applyTransform.ts","../src/validators/boolean.ts","../src/validators/enum.ts","../src/validators/json.ts","../src/validators/number.ts","../src/validators/port.ts","../src/validators/string.ts","../src/validators/url.ts","../src/validators/int.ts","../src/validators/float.ts","../src/validators/array.ts","../src/validators/custom.ts","../src/validators/email.ts","../src/validators/date.ts","../src/validators/index.ts","../src/parseValue.ts","../src/setNestedValue.ts","../src/cli/utils/formatIssues.ts","../src/cli/utils/formatCliError.ts","../src/cli/utils/loadSchemaModule.ts","../src/cli/commands/validate.ts","../src/readEnvFileSource.ts","../src/validateExampleEnv.ts","../src/validateExampleEnvFile.ts","../src/cli/commands/validateExample.ts","../src/cli/index.ts"],"sourcesContent":["export type ParsedCliArgs = {\r\n command?: string;\r\n flags: Record<string, string | boolean>;\r\n positionals: string[];\r\n};\r\n\r\nexport function parseArgs(argv: string[]): ParsedCliArgs {\r\n const [command, ...rest] = argv;\r\n\r\n const flags: Record<string, string | boolean> = {};\r\n const positionals: string[] = [];\r\n\r\n for (let index = 0; index < rest.length; index += 1) {\r\n const token = rest[index];\r\n\r\n if (!token.startsWith(\"--\")) {\r\n positionals.push(token);\r\n continue;\r\n }\r\n\r\n const flagName = token.slice(2);\r\n const next = rest[index + 1];\r\n\r\n if (!next || next.startsWith(\"--\")) {\r\n flags[flagName] = true;\r\n continue;\r\n }\r\n\r\n flags[flagName] = next;\r\n index += 1;\r\n }\r\n\r\n return {\r\n command,\r\n flags,\r\n positionals,\r\n };\r\n}\r\n","import type { EnvValidationIssue } from \"../types/schema\";\n\nexport class EnvValidationError extends Error {\n public readonly issues: EnvValidationIssue[];\n\n constructor(issues: EnvValidationIssue[]) {\n super(\n [\n \"Environment validation failed:\",\n ...issues.map((issue) => `- [${issue.code}] ${issue.message}`),\n ].join(\"\\n\"),\n );\n\n this.name = \"EnvValidationError\";\n this.issues = issues;\n }\n}\n","import { EnvValidationError } from \"./errors/EnvValidationError\";\nimport path from \"node:path\";\nimport { findUnknownEnvKeys } from \"./findUnknownEnvKeys\";\nimport { flattenSchema } from \"./flattenSchema\";\nimport { loadEnvFiles } from \"./loadEnvFiles\";\nimport { mergeSources } from \"./mergeSources\";\nimport { parseValue } from \"./parseValue\";\nimport { setNestedValue } from \"./setNestedValue\";\nimport type {\n CreateEnvOptions,\n EnvDebugDefaultKind,\n EnvDebugKeyEntry,\n EnvDebugLoadedFile,\n EnvDebugReport,\n EnvDebugSource,\n EnvRule,\n EnvSchema,\n EnvValidationIssue,\n EnvValueSource,\n LoadedEnvFiles,\n ParsedEnv,\n} from \"./types/schema\";\n\nfunction isEmptyString(value: string): boolean {\n return value.trim() === \"\";\n}\n\nfunction defaultToRawValue(value: unknown): string {\n if (typeof value === \"string\") {\n return value;\n }\n\n if (typeof value === \"number\" || typeof value === \"boolean\") {\n return String(value);\n }\n\n if (value instanceof Date) {\n return value.toISOString();\n }\n\n return JSON.stringify(value);\n}\n\nfunction resolveDefaultValue(value: unknown): unknown {\n return typeof value === \"function\" ? (value as () => unknown)() : value;\n}\n\nfunction parseDefaultValue(\n envKey: string,\n rule: EnvRule,\n): ReturnType<typeof parseValue> & {\n defaultKind: EnvDebugDefaultKind;\n rawDefault?: string;\n} {\n const defaultKind: EnvDebugDefaultKind =\n typeof rule.default === \"function\" ? \"function\" : \"static\";\n let resolvedDefault: unknown;\n\n try {\n resolvedDefault = resolveDefaultValue(rule.default);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n issue: {\n key: envKey,\n code: \"invalid_default\",\n message: `Default function for \"${envKey}\" threw an error: ${message}`,\n },\n defaultKind,\n };\n }\n\n const rawDefault = defaultToRawValue(resolvedDefault);\n\n return {\n ...parseValue(envKey, rawDefault, rule),\n defaultKind,\n rawDefault,\n };\n}\n\ntype SourceTrace = Record<string, { source: EnvValueSource; raw: string }>;\n\nfunction countKeys(source: Record<string, string | undefined>): number {\n return Object.values(source).filter((value) => typeof value === \"string\")\n .length;\n}\n\nfunction buildLoadedFileReport(\n loadedFiles: LoadedEnvFiles,\n cwd: string,\n nodeEnv: string,\n envFile?: string,\n): EnvDebugLoadedFile[] {\n return [\n {\n source: \".env\",\n path: path.join(cwd, \".env\"),\n keyCount: countKeys(loadedFiles.base),\n },\n {\n source: \".env.local\",\n path: path.join(cwd, \".env.local\"),\n keyCount: countKeys(loadedFiles.local),\n },\n {\n source: \".env.environment\",\n path: path.join(cwd, `.env.${nodeEnv}`),\n keyCount: countKeys(loadedFiles.environment),\n },\n {\n source: \"custom\",\n path: envFile ? path.resolve(cwd, envFile) : undefined,\n keyCount: countKeys(loadedFiles.custom),\n },\n ];\n}\n\nfunction buildSourceTrace(\n loadedFiles: LoadedEnvFiles,\n runtimeValues: Record<string, string | undefined>,\n): SourceTrace {\n const trace: SourceTrace = Object.create(null) as SourceTrace;\n\n const applySource = (\n source: Record<string, string | undefined>,\n label: EnvValueSource,\n ): void => {\n for (const [key, raw] of Object.entries(source)) {\n if (typeof raw === \"string\") {\n trace[key] = { source: label, raw };\n }\n }\n };\n\n applySource(loadedFiles.base, \".env\");\n applySource(loadedFiles.local, \".env.local\");\n applySource(loadedFiles.environment, \".env.environment\");\n applySource(loadedFiles.custom, \"custom\");\n applySource(runtimeValues, \"process.env\");\n\n return trace;\n}\n\nfunction maskDebugValue(value: unknown, sensitive: boolean): unknown {\n if (value === undefined) {\n return undefined;\n }\n\n return sensitive ? \"***\" : value;\n}\n\nfunction resolveDebugLogger(\n debug: CreateEnvOptions[\"debug\"],\n): ((report: EnvDebugReport) => void) | undefined {\n if (debug === true) {\n return (report: EnvDebugReport): void => {\n console.info(report);\n };\n }\n\n if (debug && typeof debug === \"object\" && debug.logger) {\n return debug.logger;\n }\n\n return undefined;\n}\n\nexport function createEnv<S extends EnvSchema>(\n schema: S,\n options: CreateEnvOptions = {},\n): ParsedEnv<S> {\n const debugEnabled = options.debug !== undefined && options.debug !== false;\n const debugLogger = debugEnabled\n ? resolveDebugLogger(options.debug)\n : undefined;\n const debugKeys: EnvDebugKeyEntry[] = [];\n\n let source: Record<string, string | undefined>;\n let loadedFileReport: EnvDebugLoadedFile[] = [];\n let sourceTrace: SourceTrace = Object.create(null) as SourceTrace;\n\n if (options.source) {\n source = options.source;\n\n if (debugEnabled) {\n for (const [key, raw] of Object.entries(source)) {\n if (typeof raw === \"string\") {\n sourceTrace[key] = { source: \"process.env\", raw };\n }\n }\n }\n } else {\n const loadedFiles = loadEnvFiles({\n cwd: options.cwd,\n nodeEnv: options.nodeEnv,\n envFile: options.envFile,\n });\n source = mergeSources(loadedFiles, process.env);\n\n if (debugEnabled) {\n const cwd = options.cwd ?? process.cwd();\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV ?? \"development\";\n loadedFileReport = buildLoadedFileReport(\n loadedFiles,\n cwd,\n nodeEnv,\n options.envFile,\n );\n sourceTrace = buildSourceTrace(loadedFiles, process.env);\n }\n }\n\n const issues: EnvValidationIssue[] = [];\n const result: Record<string, unknown> = {};\n const flattenedSchema = flattenSchema(schema as Record<string, unknown>);\n\n if (options.strict) {\n issues.push(\n ...findUnknownEnvKeys(schema as Record<string, unknown>, source),\n );\n }\n\n for (const entry of flattenedSchema) {\n const { path, envKey, rule } = entry;\n const currentValue = source[envKey];\n const sourceInfo = sourceTrace[envKey];\n const sensitive = rule.sensitive === true;\n const defaultKind: EnvDebugDefaultKind | undefined =\n rule.default === undefined\n ? undefined\n : typeof rule.default === \"function\"\n ? \"function\"\n : \"static\";\n\n const pushDebugEntry = (\n status: EnvDebugKeyEntry[\"status\"],\n values: {\n source: EnvDebugSource;\n usedDefault: boolean;\n raw?: string;\n parsed?: unknown;\n issue?: EnvValidationIssue;\n defaultKind?: EnvDebugDefaultKind;\n },\n ): void => {\n if (!debugEnabled) {\n return;\n }\n\n debugKeys.push({\n key: envKey,\n ruleType: rule.type,\n source: values.source,\n usedDefault: values.usedDefault,\n defaultKind: values.defaultKind,\n raw: maskDebugValue(values.raw, sensitive) as string | undefined,\n parsed: maskDebugValue(values.parsed, sensitive),\n status,\n issue: values.issue,\n });\n };\n\n if (typeof currentValue !== \"string\") {\n if (rule.default !== undefined) {\n const parsedDefault = parseDefaultValue(envKey, rule);\n\n if (parsedDefault.issue) {\n issues.push(parsedDefault.issue);\n pushDebugEntry(\"issue\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n issue: parsedDefault.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"defaulted\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n parsed: parsedDefault.value,\n });\n setNestedValue(result, path, parsedDefault.value);\n continue;\n }\n\n if (rule.required) {\n const issue = {\n key: envKey,\n code: \"missing\",\n message: `Missing required environment variable \"${envKey}\".`,\n } as const;\n\n issues.push(issue);\n pushDebugEntry(\"missing\", {\n source: \"missing\",\n usedDefault: false,\n defaultKind,\n issue,\n });\n } else {\n pushDebugEntry(\"missing\", {\n source: \"missing\",\n usedDefault: false,\n defaultKind,\n });\n }\n\n continue;\n }\n\n const rawValue = currentValue;\n\n if (!rule.allowEmpty && isEmptyString(rawValue)) {\n if (rule.default !== undefined) {\n const parsedDefault = parseDefaultValue(envKey, rule);\n\n if (parsedDefault.issue) {\n issues.push(parsedDefault.issue);\n pushDebugEntry(\"issue\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n issue: parsedDefault.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"defaulted\", {\n source: \"default\",\n usedDefault: true,\n defaultKind: parsedDefault.defaultKind,\n raw: parsedDefault.rawDefault,\n parsed: parsedDefault.value,\n });\n setNestedValue(result, path, parsedDefault.value);\n continue;\n }\n\n const issue = {\n key: envKey,\n code: \"empty\",\n message: `Environment variable \"${envKey}\" cannot be empty.`,\n } as const;\n\n issues.push(issue);\n pushDebugEntry(\"empty\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n issue,\n });\n continue;\n }\n\n const parsed = parseValue(envKey, rawValue, rule);\n\n if (parsed.issue) {\n issues.push(parsed.issue);\n pushDebugEntry(\"issue\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n issue: parsed.issue,\n });\n continue;\n }\n\n pushDebugEntry(\"parsed\", {\n source: sourceInfo?.source ?? \"process.env\",\n usedDefault: false,\n defaultKind,\n raw: rawValue,\n parsed: parsed.value,\n });\n setNestedValue(result, path, parsed.value);\n }\n\n if (debugLogger) {\n debugLogger({\n loadedFiles: loadedFileReport,\n keys: debugKeys,\n });\n }\n\n if (issues.length > 0) {\n throw new EnvValidationError(issues);\n }\n\n return result as unknown as ParsedEnv<S>;\n}\n","import type { EnvRule } from \"./types/schema\";\r\n\r\nexport type FlattenedSchemaEntry = {\r\n path: string[];\r\n envKey: string;\r\n rule: EnvRule;\r\n};\r\n\r\nfunction isEnvRule(value: unknown): value is EnvRule {\r\n return (\r\n typeof value === \"object\" &&\r\n value !== null &&\r\n \"type\" in value &&\r\n typeof (value as { type?: unknown }).type === \"string\"\r\n );\r\n}\r\n\r\nfunction toEnvKey(path: string[]): string {\r\n return path.map((segment) => segment.toUpperCase()).join(\"_\");\r\n}\r\n\r\nexport function flattenSchema(\r\n schema: Record<string, unknown>,\r\n parentPath: string[] = [],\r\n): FlattenedSchemaEntry[] {\r\n const entries: FlattenedSchemaEntry[] = [];\r\n\r\n for (const [key, value] of Object.entries(schema)) {\r\n const currentPath = [...parentPath, key];\r\n\r\n if (isEnvRule(value)) {\r\n entries.push({\r\n path: currentPath,\r\n envKey: toEnvKey(currentPath),\r\n rule: value,\r\n });\r\n\r\n continue;\r\n }\r\n\r\n if (typeof value === \"object\" && value !== null) {\r\n entries.push(\r\n ...flattenSchema(value as Record<string, unknown>, currentPath),\r\n );\r\n }\r\n }\r\n\r\n return entries;\r\n}\r\n","import { flattenSchema } from \"./flattenSchema\";\r\nimport type { EnvSource, EnvValidationIssue } from \"./types/schema\";\r\n\r\nexport function findUnknownEnvKeys(\r\n schema: Record<string, unknown>,\r\n source: EnvSource,\r\n): EnvValidationIssue[] {\r\n const knownKeys = new Set(flattenSchema(schema).map((entry) => entry.envKey));\r\n const issues: EnvValidationIssue[] = [];\r\n\r\n for (const key of Object.keys(source)) {\r\n if (source[key] === undefined) {\r\n continue;\r\n }\r\n\r\n if (knownKeys.has(key)) {\r\n continue;\r\n }\r\n\r\n issues.push({\r\n key,\r\n code: \"unknown_key\",\r\n message: `Environment variable \"${key}\" is not defined in the schema.`,\r\n });\r\n }\r\n\r\n return issues;\r\n}\r\n","import fs from \"node:fs\";\nimport path from \"node:path\";\nimport type {\n LoadEnvFilesOptions,\n EnvSource,\n LoadedEnvFiles,\n} from \"./types/schema\";\n\nconst ENV_KEY_PATTERN = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\nfunction stripInlineComment(input: string): string {\n let inSingleQuote = false;\n let inDoubleQuote = false;\n let isEscaped = false;\n\n for (let index = 0; index < input.length; index += 1) {\n const char = input[index];\n\n if (isEscaped) {\n isEscaped = false;\n continue;\n }\n\n if (char === \"\\\\\") {\n isEscaped = true;\n continue;\n }\n\n if (char === '\"' && !inSingleQuote) {\n inDoubleQuote = !inDoubleQuote;\n continue;\n }\n\n if (char === \"'\" && !inDoubleQuote) {\n inSingleQuote = !inSingleQuote;\n continue;\n }\n\n if (\n char === \"#\" &&\n !inSingleQuote &&\n !inDoubleQuote &&\n (index === 0 || /\\s/.test(input[index - 1] ?? \"\"))\n ) {\n return input.slice(0, index).trimEnd();\n }\n }\n\n return input.trimEnd();\n}\n\nfunction parseEnvFile(filePath: string): EnvSource {\n if (!fs.existsSync(filePath)) {\n return Object.create(null) as EnvSource;\n }\n\n const content = fs.readFileSync(filePath, \"utf8\");\n const result = Object.create(null) as EnvSource;\n\n for (const rawLine of content.split(/\\r?\\n/)) {\n let line = rawLine.trim();\n\n if (!line || line.startsWith(\"#\")) {\n continue;\n }\n\n if (line.startsWith(\"export \")) {\n line = line.slice(\"export \".length).trim();\n\n if (!line) {\n continue;\n }\n }\n\n const equalIndex = line.indexOf(\"=\");\n\n if (equalIndex <= 0) {\n continue;\n }\n\n const key = line.slice(0, equalIndex).trim();\n\n if (!ENV_KEY_PATTERN.test(key)) {\n continue;\n }\n\n let value = stripInlineComment(line.slice(equalIndex + 1)).trim();\n\n if (\n (value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\n ) {\n value = value.slice(1, -1);\n }\n\n result[key] = value;\n }\n\n return result;\n}\n\nexport function loadEnvFiles(\n options: LoadEnvFilesOptions = {},\n): LoadedEnvFiles {\n const cwd = options.cwd ?? process.cwd();\n const nodeEnv = options.nodeEnv ?? process.env.NODE_ENV ?? \"development\";\n\n const base = parseEnvFile(path.join(cwd, \".env\"));\n const local = parseEnvFile(path.join(cwd, \".env.local\"));\n const environment = parseEnvFile(path.join(cwd, `.env.${nodeEnv}`));\n const custom = options.envFile\n ? parseEnvFile(path.resolve(cwd, options.envFile))\n : (Object.create(null) as EnvSource);\n\n return {\n base,\n local,\n environment,\n custom,\n };\n}\n","import type { EnvSource, LoadedEnvFiles } from \"./types/schema\";\n\nexport function mergeSources(\n files: LoadedEnvFiles,\n runtimeValues: EnvSource = process.env,\n): EnvSource {\n return Object.assign(\n Object.create(null),\n files.base,\n files.local,\n files.environment,\n files.custom,\n runtimeValues,\n ) as EnvSource;\n}\n","import type { EnvRule, EnvValidationIssue } from \"./types/schema\";\r\nimport type { ParseResult } from \"./validators\";\r\n\r\nexport function applyTransform(\r\n key: string,\r\n rule: EnvRule,\r\n result: ParseResult,\r\n): ParseResult {\r\n if (result.issue || result.value === undefined || !rule.transform) {\r\n return result;\r\n }\r\n\r\n try {\r\n return {\r\n value: rule.transform(result.value as never),\r\n };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message\r\n ? error.message\r\n : `Environment variable \"${key}\" failed transform.`;\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_custom\",\r\n message,\r\n } satisfies EnvValidationIssue,\r\n };\r\n }\r\n}\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nconst TRUE_VALUES = new Set([\"true\", \"1\", \"yes\", \"on\"]);\r\nconst FALSE_VALUES = new Set([\"false\", \"0\", \"no\", \"off\"]);\r\n\r\nexport const validateBoolean: EnvValidator = ({ key, rawValue }) => {\r\n const normalized = rawValue.trim().toLowerCase();\r\n\r\n if (TRUE_VALUES.has(normalized)) {\r\n return { value: true };\r\n }\r\n\r\n if (FALSE_VALUES.has(normalized)) {\r\n return { value: false };\r\n }\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_boolean\",\r\n message: `Environment variable \"${key}\" must be a valid boolean.`,\r\n },\r\n };\r\n};\r\n","import type { EnumRule } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateEnum: EnvValidator = ({ key, rawValue, rule }) => {\r\n const enumRule = rule as EnumRule;\r\n\r\n if (!enumRule.values.includes(rawValue)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_enum\",\r\n message: `Environment variable \"${key}\" must be one of: ${enumRule.values.join(\", \")}.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: rawValue };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateJson: EnvValidator = ({ key, rawValue }) => {\r\n try {\r\n const parsed = JSON.parse(rawValue);\r\n\r\n return { value: parsed };\r\n } catch {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_json\",\r\n message: `Environment variable \"${key}\" must contain valid JSON.`,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateNumber: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isFinite(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid number.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validatePort: EnvValidator = ({ key, rawValue }) => {\r\n const num = Number(rawValue);\r\n\r\n if (!Number.isInteger(num) || num < 1 || num > 65535) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_port\",\r\n message: `Environment variable \"${key}\" must be a valid port (1–65535).`,\r\n },\r\n };\r\n }\r\n\r\n return { value: num };\r\n};","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateString: EnvValidator = ({ rawValue }) => {\r\n return { value: rawValue };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateUrl: EnvValidator = ({ key, rawValue }) => {\r\n try {\r\n new URL(rawValue);\r\n\r\n return { value: rawValue };\r\n } catch {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_url\",\r\n message: `Environment variable \"${key}\" must be a valid URL.`,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateInt: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isInteger(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid integer.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { EnvValidator } from \"./types\";\r\n\r\nexport const validateFloat: EnvValidator = ({ key, rawValue }) => {\r\n const parsed = Number(rawValue);\r\n\r\n if (!Number.isFinite(parsed)) {\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_number\",\r\n message: `Environment variable \"${key}\" must be a valid float.`,\r\n },\r\n };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { ArrayRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateArray: EnvValidator = ({ key, rawValue, rule }) => {\r\n const arrayRule = rule as ArrayRule;\r\n const separator = arrayRule.separator ?? \",\";\r\n const trimItems = arrayRule.trimItems ?? true;\r\n const allowEmptyItems = arrayRule.allowEmptyItems ?? false;\r\n const splitValues = rawValue.split(separator);\r\n\r\n const parsed = trimItems\r\n ? splitValues.map((item) => item.trim())\r\n : splitValues;\r\n\r\n if (!allowEmptyItems && parsed.some((item) => item === \"\")) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_array\",\r\n message: `Environment variable \"${key}\" cannot contain empty array items`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n return { value: parsed };\r\n};\r\n","import type { CustomRule } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateCustom: EnvValidator = ({ key, rawValue, rule }) => {\r\n const customRule = rule as CustomRule;\r\n\r\n try {\r\n const parsed = customRule.parse(rawValue);\r\n\r\n return { value: parsed };\r\n } catch (error) {\r\n const message =\r\n error instanceof Error && error.message\r\n ? error.message\r\n : `Environment variable \"${key}\" failed custom validation.`;\r\n\r\n return {\r\n issue: {\r\n key,\r\n code: \"invalid_custom\",\r\n message,\r\n },\r\n };\r\n }\r\n};\r\n","import type { EmailRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nexport const validateEmail: EnvValidator = ({ key, rawValue, rule }) => {\r\n const emailRule = rule as EmailRule;\r\n void emailRule;\r\n\r\n const value = rawValue.trim();\r\n\r\n if (!value) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n if (/\\s/.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n\r\n if (!emailRegex.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_email\",\r\n message: `Environment variable \"${key}\" must be a valid email address`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n return {\r\n value,\r\n };\r\n};","import type { DateRule, EnvValidationIssue } from \"../types/schema\";\r\nimport type { EnvValidator } from \"./types\";\r\n\r\nfunction isValidDate(date: Date): boolean {\r\n return !Number.isNaN(date.getTime());\r\n}\r\n\r\nexport const validateDate: EnvValidator = ({ key, rawValue, rule }) => {\r\n const dateRule = rule as DateRule;\r\n void dateRule;\r\n\r\n const value = rawValue.trim();\r\n\r\n if (!value) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid ISO date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const isoDateRegex = /^\\d{4}-\\d{2}-\\d{2}$/;\r\n const isoDateTimeRegex =\r\n /^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}(:\\d{2}(\\.\\d{1,3})?)?(Z|[+-]\\d{2}:\\d{2})$/;\r\n\r\n if (!isoDateRegex.test(value) && !isoDateTimeRegex.test(value)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid ISO date string`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n const parsed = new Date(value);\r\n\r\n if (!isValidDate(parsed)) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a valid date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n\r\n if (isoDateRegex.test(value)) {\r\n const [year, month, day] = value.split(\"-\").map(Number);\r\n\r\n if (\r\n parsed.getUTCFullYear() !== year ||\r\n parsed.getUTCMonth() + 1 !== month ||\r\n parsed.getUTCDate() !== day\r\n ) {\r\n const issue: EnvValidationIssue = {\r\n key,\r\n code: \"invalid_date\",\r\n message: `Environment variable \"${key}\" must be a real calendar date`,\r\n };\r\n\r\n return { issue };\r\n }\r\n }\r\n\r\n return {\r\n value: parsed,\r\n };\r\n};\r\n","import { validateBoolean } from \"./boolean\";\r\nimport { validateEnum } from \"./enum\";\r\nimport { validateJson } from \"./json\";\r\nimport { validateNumber } from \"./number\";\r\nimport { validatePort } from \"./port\";\r\nimport { validateString } from \"./string\";\r\nimport { validateUrl } from \"./url\";\r\nimport type { EnvValidator } from \"./types\";\r\nimport { validateInt } from \"./int\";\r\nimport { validateFloat } from \"./float\";\r\nimport { validateArray } from \"./array\";\r\nimport { validateCustom } from \"./custom\";\r\nimport { validateEmail } from \"./email\";\r\nimport { validateDate } from \"./date\";\r\n\r\nexport const validators = {\r\n string: validateString,\r\n number: validateNumber,\r\n boolean: validateBoolean,\r\n enum: validateEnum,\r\n url: validateUrl,\r\n port: validatePort,\r\n json: validateJson,\r\n int: validateInt,\r\n float: validateFloat,\r\n array: validateArray,\r\n custom: validateCustom,\r\n email: validateEmail,\r\n date: validateDate,\r\n} as const satisfies {\r\n string: EnvValidator;\r\n number: EnvValidator;\r\n boolean: EnvValidator;\r\n enum: EnvValidator;\r\n url: EnvValidator;\r\n port: EnvValidator;\r\n json: EnvValidator;\r\n int: EnvValidator;\r\n float: EnvValidator;\r\n array: EnvValidator;\r\n custom: EnvValidator;\r\n email: EnvValidator;\r\n date: EnvValidator;\r\n};\r\n\r\nexport type { ParseResult, EnvValidator } from \"./types\";\r\n","import { applyTransform } from \"./applyTransform\";\nimport type { EnvRule } from \"./types/schema\";\nimport { validators } from \"./validators\";\nimport type { ParseResult } from \"./validators\";\n\nexport function parseValue(\n key: string,\n rawValue: string,\n rule: EnvRule,\n): ParseResult {\n const validator = validators[rule.type];\n\n const result = validator({\n key,\n rawValue,\n rule,\n });\n\n return applyTransform(key, rule, result);\n}\n","export function setNestedValue(\r\n target: Record<string, unknown>,\r\n path: string[],\r\n value: unknown,\r\n): void {\r\n let current: Record<string, unknown> = target;\r\n\r\n for (let index = 0; index < path.length - 1; index += 1) {\r\n const segment = path[index];\r\n const existing = current[segment];\r\n\r\n if (\r\n typeof existing !== \"object\" ||\r\n existing === null ||\r\n Array.isArray(existing)\r\n ) {\r\n current[segment] = {};\r\n }\r\n\r\n current = current[segment] as Record<string, unknown>;\r\n }\r\n\r\n current[path[path.length - 1]] = value;\r\n}\r\n","import type { EnvValidationIssue } from \"../../types/schema\";\r\n\r\nexport function formatIssues(issues: EnvValidationIssue[]): string {\r\n return issues.map((issue) => `- ${issue.key}: ${issue.message}`).join(\"\\n\");\r\n}\r\n","export function formatCliError(error: unknown): string {\r\n const message = error instanceof Error ? error.message : \"Unknown CLI error\";\r\n return `CLI error: ${message}`;\r\n}\r\n","import path from \"node:path\";\r\nimport fs from \"node:fs\";\r\nimport { pathToFileURL } from \"node:url\";\r\nimport type { EnvSchema } from \"../../types/schema\";\r\n\r\ntype SchemaModule = {\r\n default?: unknown;\r\n schema?: unknown;\r\n};\r\n\r\nconst SUPPORTED_SCHEMA_EXTENSIONS = [\r\n \".js\",\r\n \".mjs\",\r\n \".cjs\",\r\n \".ts\",\r\n \".mts\",\r\n \".cts\",\r\n] as const;\r\n\r\nfunction isObject(value: unknown): value is Record<string, unknown> {\r\n return typeof value === \"object\" && value !== null;\r\n}\r\n\r\nfunction isTypeScriptFile(filePath: string): boolean {\r\n const ext = path.extname(filePath).toLowerCase();\r\n return ext === \".ts\" || ext === \".mts\" || ext === \".cts\";\r\n}\r\n\r\nfunction isSupportedSchemaFile(filePath: string): boolean {\r\n const ext = path.extname(filePath).toLowerCase();\r\n return SUPPORTED_SCHEMA_EXTENSIONS.includes(\r\n ext as (typeof SUPPORTED_SCHEMA_EXTENSIONS)[number],\r\n );\r\n}\r\n\r\nfunction assertSchemaPathIsUsable(\r\n absolutePath: string,\r\n schemaPath: string,\r\n): void {\r\n if (!isSupportedSchemaFile(absolutePath)) {\r\n throw new Error(\r\n `Unsupported schema file type for \"${schemaPath}\". Supported extensions: ${SUPPORTED_SCHEMA_EXTENSIONS.join(\", \")}.`,\r\n );\r\n }\r\n\r\n if (!fs.existsSync(absolutePath)) {\r\n throw new Error(\r\n `Schema file not found: \"${schemaPath}\" (resolved to \"${absolutePath}\").`,\r\n );\r\n }\r\n}\r\n\r\nasync function importTypeScriptModule(\r\n absolutePath: string,\r\n schemaPath: string,\r\n): Promise<SchemaModule> {\r\n try {\r\n const { register } = await import(\"tsx/esm/api\");\r\n const api = register({\r\n namespace: `node-safe-env:${Date.now()}:${Math.random().toString(36).slice(2)}`,\r\n });\r\n\r\n const loaded = await (async () => {\r\n try {\r\n return await api.import(\r\n pathToFileURL(absolutePath).href,\r\n import.meta.url,\r\n );\r\n } finally {\r\n api.unregister();\r\n }\r\n })();\r\n\r\n if (isObject(loaded)) {\r\n return loaded as SchemaModule;\r\n }\r\n\r\n return { default: loaded };\r\n } catch (error) {\r\n const message = error instanceof Error ? error.message : \"Unknown error\";\r\n throw new Error(\r\n `Failed to load TypeScript schema module \"${schemaPath}\" using tsx runtime: ${message}`,\r\n );\r\n }\r\n}\r\n\r\nexport async function loadSchemaModule(schemaPath: string): Promise<EnvSchema> {\r\n const absolutePath = path.resolve(schemaPath);\r\n const moduleUrl = pathToFileURL(absolutePath).href;\r\n\r\n assertSchemaPathIsUsable(absolutePath, schemaPath);\r\n\r\n const mod = isTypeScriptFile(absolutePath)\r\n ? await importTypeScriptModule(absolutePath, schemaPath)\r\n : await (async (): Promise<SchemaModule> => {\r\n try {\r\n return (await import(moduleUrl)) as SchemaModule;\r\n } catch (error) {\r\n const message =\r\n error instanceof Error ? error.message : \"Unknown error\";\r\n throw new Error(\r\n `Failed to import schema module \"${schemaPath}\": ${message}`,\r\n );\r\n }\r\n })();\r\n\r\n const schemaCandidate = mod.default ?? mod.schema;\r\n\r\n if (!isObject(schemaCandidate)) {\r\n throw new Error(\r\n `Schema module \"${schemaPath}\" must export a schema as default export or named export \"schema\".`,\r\n );\r\n }\r\n\r\n return schemaCandidate as EnvSchema;\r\n}\r\n","import { createEnv } from \"../../createEnv\";\r\nimport { EnvValidationError } from \"../../errors/EnvValidationError\";\r\nimport { formatIssues } from \"../utils/formatIssues\";\r\nimport { formatCliError } from \"../utils/formatCliError\";\r\nimport { loadSchemaModule } from \"../utils/loadSchemaModule\";\r\n\r\nexport type ValidateCommandOptions = {\r\n schemaPath: string;\r\n cwd?: string;\r\n envFile?: string;\r\n nodeEnv?: string;\r\n strict?: boolean;\r\n};\r\n\r\nexport async function runValidateCommand(\r\n options: ValidateCommandOptions,\r\n): Promise<number> {\r\n try {\r\n const schema = await loadSchemaModule(options.schemaPath);\r\n\r\n createEnv(schema, {\r\n cwd: options.cwd,\r\n envFile: options.envFile,\r\n nodeEnv: options.nodeEnv,\r\n strict: options.strict,\r\n });\r\n\r\n console.log(\"✓ Environment validation passed.\");\r\n return 0;\r\n } catch (error) {\r\n if (error instanceof EnvValidationError) {\r\n console.error(\"Environment validation failed:\\n\");\r\n console.error(formatIssues(error.issues));\r\n return 1;\r\n }\r\n\r\n console.error(formatCliError(error));\r\n return 1;\r\n }\r\n}\r\n","import { existsSync, readFileSync } from \"node:fs\";\r\nimport { resolve } from \"node:path\";\r\nimport type { EnvSource } from \"./types/schema\";\r\n\r\nfunction stripQuotes(value: string): string {\r\n if (\r\n (value.startsWith('\"') && value.endsWith('\"')) ||\r\n (value.startsWith(\"'\") && value.endsWith(\"'\"))\r\n ) {\r\n return value.slice(1, -1);\r\n }\r\n\r\n return value;\r\n}\r\n\r\nexport function readEnvFileSource(filePath: string): EnvSource {\r\n if (!existsSync(filePath)) {\r\n return {};\r\n }\r\n\r\n const content = readFileSync(filePath, \"utf8\");\r\n const source: EnvSource = {};\r\n\r\n for (const line of content.split(/\\r?\\n/)) {\r\n const trimmed = line.trim();\r\n\r\n if (!trimmed || trimmed.startsWith(\"#\")) {\r\n continue;\r\n }\r\n\r\n const equalsIndex = trimmed.indexOf(\"=\");\r\n\r\n if (equalsIndex === -1) {\r\n continue;\r\n }\r\n\r\n const key = trimmed.slice(0, equalsIndex).trim();\r\n const rawValue = trimmed.slice(equalsIndex + 1).trim();\r\n\r\n if (!key) {\r\n continue;\r\n }\r\n\r\n source[key] = stripQuotes(rawValue);\r\n }\r\n\r\n return source;\r\n}\r\n\r\nexport function resolveExampleEnvPath(\r\n cwd: string = process.cwd(),\r\n exampleFile: string = \".env.example\",\r\n): string {\r\n return resolve(cwd, exampleFile);\r\n}\r\n","import { flattenSchema } from \"./flattenSchema\";\r\nimport type { EnvSchema, EnvSource, EnvValidationIssue } from \"./types/schema\";\r\n\r\nexport function validateExampleEnv(\r\n schema: EnvSchema,\r\n exampleSource: EnvSource,\r\n): EnvValidationIssue[] {\r\n const issues: EnvValidationIssue[] = [];\r\n const flattenedSchema = flattenSchema(schema);\r\n const expectedKeys = new Set(flattenedSchema.map((entry) => entry.envKey));\r\n\r\n for (const entry of flattenedSchema) {\r\n const { envKey } = entry;\r\n\r\n if (!(envKey in exampleSource)) {\r\n issues.push({\r\n key: envKey,\r\n code: \"missing_example_key\",\r\n message: `Environment variable \"${envKey}\" is missing from .env.example.`,\r\n });\r\n }\r\n }\r\n\r\n for (const key of Object.keys(exampleSource)) {\r\n if (exampleSource[key] === undefined) {\r\n continue;\r\n }\r\n\r\n if (expectedKeys.has(key)) {\r\n continue;\r\n }\r\n\r\n issues.push({\r\n key,\r\n code: \"unknown_example_key\",\r\n message: `Environment variable \"${key}\" in .env.example is not defined in the schema.`,\r\n });\r\n }\r\n\r\n return issues;\r\n}\r\n","import { readEnvFileSource, resolveExampleEnvPath } from \"./readEnvFileSource\";\r\nimport { validateExampleEnv } from \"./validateExampleEnv\";\r\nimport type {\r\n EnvSchema,\r\n EnvValidationIssue,\r\n ValidateExampleEnvFileOptions,\r\n} from \"./types/schema\";\r\n\r\nexport function validateExampleEnvFile(\r\n schema: EnvSchema,\r\n options: ValidateExampleEnvFileOptions = {},\r\n): EnvValidationIssue[] {\r\n const filePath = resolveExampleEnvPath(options.cwd, options.exampleFile);\r\n const exampleSource = readEnvFileSource(filePath);\r\n\r\n return validateExampleEnv(schema, exampleSource);\r\n}\r\n","import { formatIssues } from \"../utils/formatIssues\";\r\nimport { formatCliError } from \"../utils/formatCliError\";\r\nimport { loadSchemaModule } from \"../utils/loadSchemaModule\";\r\nimport { validateExampleEnvFile } from \"../../validateExampleEnvFile\";\r\n\r\nexport type ValidateExampleCommandOptions = {\r\n schemaPath: string;\r\n cwd?: string;\r\n exampleFile?: string;\r\n};\r\n\r\nexport async function runValidateExampleCommand(\r\n options: ValidateExampleCommandOptions,\r\n): Promise<number> {\r\n try {\r\n const schema = await loadSchemaModule(options.schemaPath);\r\n\r\n const issues = validateExampleEnvFile(schema, {\r\n cwd: options.cwd,\r\n exampleFile: options.exampleFile,\r\n });\r\n\r\n if (issues.length > 0) {\r\n console.error(\".env.example validation failed:\\n\");\r\n console.error(formatIssues(issues));\r\n return 1;\r\n }\r\n\r\n console.log(\"✓ .env.example validation passed.\");\r\n return 0;\r\n } catch (error) {\r\n console.error(formatCliError(error));\r\n return 1;\r\n }\r\n}\r\n","#!/usr/bin/env node\r\n\r\nimport { parseArgs } from \"./utils/parseArgs\";\r\nimport { runValidateCommand } from \"./commands/validate\";\r\nimport { runValidateExampleCommand } from \"./commands/validateExample\";\r\n\r\ntype CliIO = {\r\n log: (message: string) => void;\r\n error: (message: string) => void;\r\n};\r\n\r\nfunction printHelp(io: CliIO): void {\r\n io.log(`node-safe-env CLI\r\n\r\nUsage:\r\n node-safe-env validate --schema <path> [--cwd <path>] [--env-file <path>] [--node-env <value>] [--strict]\r\n node-safe-env validate-example --schema <path> [--cwd <path>] [--example-file <path>]\r\n\r\nCommands:\r\n validate Validate environment variables using a schema\r\n validate-example Validate a .env.example file against a schema\r\n\r\nOptions:\r\n --schema <path> Path to schema module (.js, .mjs, .cjs, .ts, .mts, .cts)\r\n --cwd <path> Working directory for env file loading\r\n --env-file <path> Custom env file path for validate\r\n --node-env <value> NODE_ENV override for validate\r\n --strict Enable strict mode for unknown keys\r\n --example-file <path> Custom example file path for validate-example\r\n --help Show this help\r\n\r\nSchema module exports:\r\n - default export\r\n - named export: schema\r\n\r\nExamples:\r\n node-safe-env validate --schema ./env.schema.ts\r\n node-safe-env validate-example --schema ./env.schema.ts\r\n node-safe-env validate --schema ./dist/env.schema.js --strict\r\n`);\r\n}\r\n\r\nfunction getStringFlag(\r\n flags: Record<string, string | boolean>,\r\n name: string,\r\n): string | undefined {\r\n const value = flags[name];\r\n return typeof value === \"string\" ? value : undefined;\r\n}\r\n\r\nexport async function runCli(\r\n argv: string[],\r\n io: CliIO = {\r\n log: console.log,\r\n error: console.error,\r\n },\r\n): Promise<number> {\r\n const parsed = parseArgs(argv);\r\n\r\n if (\r\n !parsed.command ||\r\n parsed.flags.help ||\r\n parsed.command === \"help\" ||\r\n parsed.command === \"--help\"\r\n ) {\r\n printHelp(io);\r\n return 0;\r\n }\r\n\r\n const schemaPath = getStringFlag(parsed.flags, \"schema\");\r\n\r\n if (!schemaPath) {\r\n io.error('Missing required flag \"--schema\".\\n');\r\n printHelp(io);\r\n return 1;\r\n }\r\n\r\n if (parsed.command === \"validate\") {\r\n return runValidateCommand({\r\n schemaPath,\r\n cwd: getStringFlag(parsed.flags, \"cwd\"),\r\n envFile: getStringFlag(parsed.flags, \"env-file\"),\r\n nodeEnv: getStringFlag(parsed.flags, \"node-env\"),\r\n strict: parsed.flags.strict === true,\r\n });\r\n }\r\n\r\n if (parsed.command === \"validate-example\") {\r\n return runValidateExampleCommand({\r\n schemaPath,\r\n cwd: getStringFlag(parsed.flags, \"cwd\"),\r\n exampleFile: getStringFlag(parsed.flags, \"example-file\"),\r\n });\r\n }\r\n\r\n io.error(`Unknown command \"${parsed.command}\".\\n`);\r\n printHelp(io);\r\n return 1;\r\n}\r\n\r\nasync function main(): Promise<void> {\r\n const exitCode = await runCli(process.argv.slice(2));\r\n process.exitCode = exitCode;\r\n}\r\n\r\nvoid main();\r\n"],"mappings":"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","names":["path","path","path","path","path","fs"]}
|
package/package.json
CHANGED
|
@@ -1,11 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-safe-env",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "A tiny schema-based env loader and validator for Node.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"env",
|
|
7
|
+
"environment",
|
|
8
|
+
"environment variables",
|
|
7
9
|
"dotenv",
|
|
10
|
+
"env validation",
|
|
8
11
|
"config",
|
|
12
|
+
"configuration",
|
|
13
|
+
"node env",
|
|
14
|
+
"env schema",
|
|
15
|
+
"typescript env",
|
|
16
|
+
"env validator",
|
|
17
|
+
"env loader",
|
|
18
|
+
"env parser",
|
|
19
|
+
"node configuration",
|
|
9
20
|
"validator",
|
|
10
21
|
"node"
|
|
11
22
|
],
|
|
@@ -50,6 +61,9 @@
|
|
|
50
61
|
"format": "prettier --write .",
|
|
51
62
|
"check": "npm run lint && npm run build && npm run typecheck && npm run test"
|
|
52
63
|
},
|
|
64
|
+
"dependencies": {
|
|
65
|
+
"tsx": "^4.21.0"
|
|
66
|
+
},
|
|
53
67
|
"devDependencies": {
|
|
54
68
|
"@eslint/js": "9.39.1",
|
|
55
69
|
"@types/node": "^24.0.0",
|