node-safe-env 0.1.0 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +116 -205
- package/dist/cli.js +89 -21
- package/dist/cli.js.map +1 -1
- package/package.json +4 -1
package/README.md
CHANGED
|
@@ -1,10 +1,25 @@
|
|
|
1
1
|
# node-safe-env
|
|
2
2
|
|
|
3
|
-
Schema-based environment
|
|
3
|
+
Schema-based environment validation for Node.js and TypeScript.
|
|
4
4
|
|
|
5
|
-
`node-safe-env` helps you fail fast at startup
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
`node-safe-env` helps you fail fast at startup: validate env variables, parse them into typed runtime values, and get all validation issues in one clear error report.
|
|
6
|
+
|
|
7
|
+
## Why node-safe-env?
|
|
8
|
+
|
|
9
|
+
- Fail-fast startup validation: catch config mistakes before your app starts serving traffic.
|
|
10
|
+
- Typed parsing: parse strings from `.env` and `process.env` into `number`, `boolean`, `Date`, arrays, and more.
|
|
11
|
+
- Aggregated errors: see all invalid/missing values at once.
|
|
12
|
+
- CLI validation: validate your env setup from scripts and CI.
|
|
13
|
+
- `.env.example` validation: keep examples aligned with your schema.
|
|
14
|
+
- Debug tracing: inspect where each value came from and how it was parsed.
|
|
15
|
+
|
|
16
|
+
## Try It Now
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx node-safe-env --help
|
|
20
|
+
npx node-safe-env validate --schema ./env.schema.ts
|
|
21
|
+
npx node-safe-env validate-example --schema ./env.schema.ts
|
|
22
|
+
```
|
|
8
23
|
|
|
9
24
|
## Install
|
|
10
25
|
|
|
@@ -14,6 +29,8 @@ npm install node-safe-env
|
|
|
14
29
|
|
|
15
30
|
## Quick Start
|
|
16
31
|
|
|
32
|
+
Define a schema:
|
|
33
|
+
|
|
17
34
|
```ts
|
|
18
35
|
import { createEnv, defineEnv } from "node-safe-env";
|
|
19
36
|
|
|
@@ -27,7 +44,11 @@ const schema = defineEnv({
|
|
|
27
44
|
default: "development",
|
|
28
45
|
},
|
|
29
46
|
} as const);
|
|
47
|
+
```
|
|
30
48
|
|
|
49
|
+
Use it at runtime:
|
|
50
|
+
|
|
51
|
+
```ts
|
|
31
52
|
const env = createEnv(schema);
|
|
32
53
|
|
|
33
54
|
env.APP_NAME; // string
|
|
@@ -36,9 +57,25 @@ env.DEBUG; // boolean
|
|
|
36
57
|
env.NODE_ENV; // "development" | "test" | "production"
|
|
37
58
|
```
|
|
38
59
|
|
|
39
|
-
|
|
60
|
+
What this gives you:
|
|
40
61
|
|
|
41
|
-
|
|
62
|
+
- `required: true` means the value must exist.
|
|
63
|
+
- `default` is used when a value is missing.
|
|
64
|
+
- `type` controls parsing and validation.
|
|
65
|
+
- returned `env` is strongly typed from your schema.
|
|
66
|
+
|
|
67
|
+
## What Is a Schema in node-safe-env?
|
|
68
|
+
|
|
69
|
+
A schema is an object where each key maps to a rule object.
|
|
70
|
+
|
|
71
|
+
Each rule describes:
|
|
72
|
+
|
|
73
|
+
- what type the value should be (`type`)
|
|
74
|
+
- whether it must be present (`required`)
|
|
75
|
+
- what to use if missing (`default`)
|
|
76
|
+
- optional rule-specific settings (for example enum values, array options, custom parser)
|
|
77
|
+
|
|
78
|
+
Use `defineEnv()` when you want better literal type inference and reusable exported schema modules.
|
|
42
79
|
|
|
43
80
|
```ts
|
|
44
81
|
// env.schema.ts
|
|
@@ -50,50 +87,72 @@ export const schema = defineEnv({
|
|
|
50
87
|
} as const);
|
|
51
88
|
```
|
|
52
89
|
|
|
53
|
-
|
|
54
|
-
// main.ts
|
|
55
|
-
import { createEnv } from "node-safe-env";
|
|
56
|
-
import { schema } from "./env.schema.js";
|
|
90
|
+
## CLI
|
|
57
91
|
|
|
58
|
-
|
|
92
|
+
`node-safe-env` includes:
|
|
93
|
+
|
|
94
|
+
- `validate`: validate current environment values against your schema
|
|
95
|
+
- `validate-example`: validate `.env.example` coverage against your schema
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
node-safe-env validate --schema ./env.schema.ts
|
|
99
|
+
node-safe-env validate-example --schema ./env.schema.ts
|
|
100
|
+
node-safe-env validate --schema ./dist/env.schema.js --strict
|
|
59
101
|
```
|
|
60
102
|
|
|
61
|
-
|
|
103
|
+
### CLI schema files
|
|
104
|
+
|
|
105
|
+
The `--schema` module supports both JavaScript and TypeScript files:
|
|
106
|
+
|
|
107
|
+
- JavaScript: `.js`, `.mjs`, `.cjs`
|
|
108
|
+
- TypeScript: `.ts`, `.mts`, `.cts`
|
|
109
|
+
|
|
110
|
+
Accepted export shapes:
|
|
62
111
|
|
|
63
|
-
|
|
112
|
+
- default export
|
|
113
|
+
- named export `schema`
|
|
114
|
+
|
|
115
|
+
## `.env.example` Validation
|
|
116
|
+
|
|
117
|
+
Validate a real file:
|
|
64
118
|
|
|
65
119
|
```ts
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
url: { type: "string", required: true },
|
|
72
|
-
},
|
|
120
|
+
import { validateExampleEnvFile } from "node-safe-env";
|
|
121
|
+
|
|
122
|
+
const issues = validateExampleEnvFile(schema, {
|
|
123
|
+
cwd: process.cwd(),
|
|
124
|
+
exampleFile: ".env.example",
|
|
73
125
|
});
|
|
74
126
|
```
|
|
75
127
|
|
|
76
|
-
|
|
77
|
-
SERVER_PORT=4000
|
|
78
|
-
DATABASE_URL=postgres://localhost:5432/app
|
|
79
|
-
```
|
|
128
|
+
Validate an in-memory object:
|
|
80
129
|
|
|
81
130
|
```ts
|
|
82
|
-
env
|
|
83
|
-
|
|
131
|
+
import { validateExampleEnv } from "node-safe-env";
|
|
132
|
+
|
|
133
|
+
const issues = validateExampleEnv(schema, {
|
|
134
|
+
PORT: "",
|
|
135
|
+
});
|
|
84
136
|
```
|
|
85
137
|
|
|
86
|
-
##
|
|
138
|
+
## Common Use Cases
|
|
87
139
|
|
|
88
|
-
|
|
140
|
+
- App startup validation: load and validate env once during bootstrap.
|
|
141
|
+
- CI checks for `.env.example`: fail PRs when required keys are missing or stale.
|
|
142
|
+
- Debugging source issues: use debug/tracing output to understand where values were loaded from.
|
|
89
143
|
|
|
90
|
-
|
|
91
|
-
2. `.env.local`
|
|
92
|
-
3. `.env.<NODE_ENV>`
|
|
93
|
-
4. custom file from `options.envFile`
|
|
94
|
-
5. `process.env`
|
|
144
|
+
## Value at a Glance
|
|
95
145
|
|
|
96
|
-
|
|
146
|
+
`node-safe-env` is a schema-based env validator with:
|
|
147
|
+
|
|
148
|
+
- TypeScript-friendly schema inference
|
|
149
|
+
- CLI commands for runtime and `.env.example` validation
|
|
150
|
+
- structured, aggregated validation errors
|
|
151
|
+
- source tracing and debug visibility
|
|
152
|
+
|
|
153
|
+
## Rule Types
|
|
154
|
+
|
|
155
|
+
Supported `type` values:
|
|
97
156
|
|
|
98
157
|
- `string`
|
|
99
158
|
- `number`
|
|
@@ -109,87 +168,38 @@ When `options.source` is not provided, values are loaded and merged in this orde
|
|
|
109
168
|
- `date`
|
|
110
169
|
- `custom`
|
|
111
170
|
|
|
112
|
-
##
|
|
113
|
-
|
|
114
|
-
```ts
|
|
115
|
-
const env = createEnv({
|
|
116
|
-
ADMIN_EMAIL: { type: "email", required: true },
|
|
117
|
-
});
|
|
118
|
-
```
|
|
119
|
-
|
|
120
|
-
## Date Rule
|
|
121
|
-
|
|
122
|
-
`date` parses ISO-compatible values into `Date`.
|
|
123
|
-
|
|
124
|
-
```ts
|
|
125
|
-
const env = createEnv({
|
|
126
|
-
START_DATE: { type: "date", required: true },
|
|
127
|
-
});
|
|
128
|
-
|
|
129
|
-
env.START_DATE; // Date
|
|
130
|
-
```
|
|
131
|
-
|
|
132
|
-
## Custom Rule
|
|
171
|
+
## Nested Schemas
|
|
133
172
|
|
|
134
|
-
|
|
173
|
+
Schemas can be nested. Env keys are flattened with `_` between segments.
|
|
135
174
|
|
|
136
175
|
```ts
|
|
137
176
|
const env = createEnv({
|
|
138
|
-
|
|
139
|
-
type: "
|
|
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
|
-
},
|
|
177
|
+
server: {
|
|
178
|
+
port: { type: "port", default: 3000 },
|
|
146
179
|
},
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
env.RETRY_DELAY_MS; // number
|
|
150
|
-
```
|
|
151
|
-
|
|
152
|
-
If `parse` throws, `createEnv` records an `invalid_custom` validation issue with the thrown message.
|
|
153
|
-
|
|
154
|
-
## Array Rule Options
|
|
155
|
-
|
|
156
|
-
Array parsing supports separator and item controls.
|
|
157
|
-
|
|
158
|
-
```ts
|
|
159
|
-
const env = createEnv({
|
|
160
|
-
ALLOWED_HOSTS: {
|
|
161
|
-
type: "array",
|
|
162
|
-
separator: "|", // default: ","
|
|
163
|
-
trimItems: false, // default: true
|
|
164
|
-
allowEmptyItems: true, // default: false
|
|
180
|
+
database: {
|
|
181
|
+
url: { type: "string", required: true },
|
|
165
182
|
},
|
|
166
183
|
});
|
|
167
184
|
```
|
|
168
185
|
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
- `allowEmptyItems`: `false`
|
|
174
|
-
|
|
175
|
-
## Defaults (Static and Functional)
|
|
186
|
+
```env
|
|
187
|
+
SERVER_PORT=4000
|
|
188
|
+
DATABASE_URL=postgres://localhost:5432/app
|
|
189
|
+
```
|
|
176
190
|
|
|
177
|
-
|
|
191
|
+
## Loading Order
|
|
178
192
|
|
|
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
|
-
```
|
|
193
|
+
When `options.source` is not provided, values are merged in this order (last wins):
|
|
186
194
|
|
|
187
|
-
|
|
195
|
+
1. `.env`
|
|
196
|
+
2. `.env.local`
|
|
197
|
+
3. `.env.<NODE_ENV>`
|
|
198
|
+
4. custom file from `options.envFile`
|
|
199
|
+
5. `process.env`
|
|
188
200
|
|
|
189
201
|
## Debug Mode
|
|
190
202
|
|
|
191
|
-
Enable debug reporting during `createEnv` execution.
|
|
192
|
-
|
|
193
203
|
```ts
|
|
194
204
|
import { createEnv, type EnvDebugReport } from "node-safe-env";
|
|
195
205
|
|
|
@@ -202,118 +212,19 @@ createEnv(schema, {
|
|
|
202
212
|
});
|
|
203
213
|
```
|
|
204
214
|
|
|
205
|
-
|
|
215
|
+
Or:
|
|
206
216
|
|
|
207
217
|
```ts
|
|
208
|
-
createEnv(schema, { debug: true });
|
|
218
|
+
createEnv(schema, { debug: true });
|
|
209
219
|
```
|
|
210
220
|
|
|
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
221
|
## Strict Mode
|
|
219
222
|
|
|
220
223
|
```ts
|
|
221
224
|
createEnv(schema, { strict: true });
|
|
222
225
|
```
|
|
223
226
|
|
|
224
|
-
Strict mode reports unknown environment keys as
|
|
225
|
-
|
|
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
|
|
227
|
+
Strict mode reports unknown environment keys as issues.
|
|
317
228
|
|
|
318
229
|
## Error Handling
|
|
319
230
|
|
|
@@ -346,7 +257,7 @@ Exports:
|
|
|
346
257
|
- `readEnvFileSource`
|
|
347
258
|
- `resolveExampleEnvPath`
|
|
348
259
|
|
|
349
|
-
`createEnv(schema, options?)
|
|
260
|
+
`createEnv(schema, options?)`:
|
|
350
261
|
|
|
351
262
|
```ts
|
|
352
263
|
{
|
|
@@ -365,7 +276,7 @@ Exports:
|
|
|
365
276
|
- ESM and CommonJS builds
|
|
366
277
|
- TypeScript declarations included
|
|
367
278
|
|
|
368
|
-
## Development
|
|
279
|
+
## Development
|
|
369
280
|
|
|
370
281
|
```bash
|
|
371
282
|
npm run lint
|
|
@@ -378,4 +289,4 @@ npm run check
|
|
|
378
289
|
|
|
379
290
|
## License
|
|
380
291
|
|
|
381
|
-
MIT
|
|
292
|
+
MIT
|
package/dist/cli.js
CHANGED
|
@@ -1,8 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
#!/usr/bin/env node
|
|
3
|
-
|
|
4
|
-
// src/cli/index.ts
|
|
5
|
-
import { pathToFileURL as pathToFileURL2 } from "url";
|
|
6
2
|
|
|
7
3
|
// src/cli/utils/parseArgs.ts
|
|
8
4
|
function parseArgs(argv) {
|
|
@@ -797,16 +793,90 @@ function formatIssues(issues) {
|
|
|
797
793
|
return issues.map((issue) => `- ${issue.key}: ${issue.message}`).join("\n");
|
|
798
794
|
}
|
|
799
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
|
+
|
|
800
802
|
// src/cli/utils/loadSchemaModule.ts
|
|
801
803
|
import path3 from "path";
|
|
804
|
+
import fs2 from "fs";
|
|
802
805
|
import { pathToFileURL } from "url";
|
|
806
|
+
var SUPPORTED_SCHEMA_EXTENSIONS = [
|
|
807
|
+
".js",
|
|
808
|
+
".mjs",
|
|
809
|
+
".cjs",
|
|
810
|
+
".ts",
|
|
811
|
+
".mts",
|
|
812
|
+
".cts"
|
|
813
|
+
];
|
|
803
814
|
function isObject(value) {
|
|
804
815
|
return typeof value === "object" && value !== null;
|
|
805
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
|
+
}
|
|
806
866
|
async function loadSchemaModule(schemaPath) {
|
|
807
867
|
const absolutePath = path3.resolve(schemaPath);
|
|
808
868
|
const moduleUrl = pathToFileURL(absolutePath).href;
|
|
809
|
-
|
|
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
|
+
})();
|
|
810
880
|
const schemaCandidate = mod.default ?? mod.schema;
|
|
811
881
|
if (!isObject(schemaCandidate)) {
|
|
812
882
|
throw new Error(
|
|
@@ -834,8 +904,7 @@ async function runValidateCommand(options) {
|
|
|
834
904
|
console.error(formatIssues(error.issues));
|
|
835
905
|
return 1;
|
|
836
906
|
}
|
|
837
|
-
|
|
838
|
-
console.error(`CLI error: ${message}`);
|
|
907
|
+
console.error(formatCliError(error));
|
|
839
908
|
return 1;
|
|
840
909
|
}
|
|
841
910
|
}
|
|
@@ -931,8 +1000,7 @@ async function runValidateExampleCommand(options) {
|
|
|
931
1000
|
console.log("\u2713 .env.example validation passed.");
|
|
932
1001
|
return 0;
|
|
933
1002
|
} catch (error) {
|
|
934
|
-
|
|
935
|
-
console.error(`CLI error: ${message}`);
|
|
1003
|
+
console.error(formatCliError(error));
|
|
936
1004
|
return 1;
|
|
937
1005
|
}
|
|
938
1006
|
}
|
|
@@ -950,13 +1018,22 @@ Commands:
|
|
|
950
1018
|
validate-example Validate a .env.example file against a schema
|
|
951
1019
|
|
|
952
1020
|
Options:
|
|
953
|
-
--schema <path> Path to schema module
|
|
1021
|
+
--schema <path> Path to schema module (.js, .mjs, .cjs, .ts, .mts, .cts)
|
|
954
1022
|
--cwd <path> Working directory for env file loading
|
|
955
1023
|
--env-file <path> Custom env file path for validate
|
|
956
1024
|
--node-env <value> NODE_ENV override for validate
|
|
957
1025
|
--strict Enable strict mode for unknown keys
|
|
958
1026
|
--example-file <path> Custom example file path for validate-example
|
|
959
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
|
|
960
1037
|
`);
|
|
961
1038
|
}
|
|
962
1039
|
function getStringFlag(flags, name) {
|
|
@@ -968,7 +1045,7 @@ async function runCli(argv, io = {
|
|
|
968
1045
|
error: console.error
|
|
969
1046
|
}) {
|
|
970
1047
|
const parsed = parseArgs(argv);
|
|
971
|
-
if (!parsed.command || parsed.flags.help || parsed.command === "help") {
|
|
1048
|
+
if (!parsed.command || parsed.flags.help || parsed.command === "help" || parsed.command === "--help") {
|
|
972
1049
|
printHelp(io);
|
|
973
1050
|
return 0;
|
|
974
1051
|
}
|
|
@@ -1003,16 +1080,7 @@ async function main() {
|
|
|
1003
1080
|
const exitCode = await runCli(process.argv.slice(2));
|
|
1004
1081
|
process.exitCode = exitCode;
|
|
1005
1082
|
}
|
|
1006
|
-
|
|
1007
|
-
const entry = process.argv[1];
|
|
1008
|
-
if (!entry) {
|
|
1009
|
-
return false;
|
|
1010
|
-
}
|
|
1011
|
-
return import.meta.url === pathToFileURL2(entry).href;
|
|
1012
|
-
}
|
|
1013
|
-
if (isDirectRun()) {
|
|
1014
|
-
void main();
|
|
1015
|
-
}
|
|
1083
|
+
void main();
|
|
1016
1084
|
export {
|
|
1017
1085
|
runCli
|
|
1018
1086
|
};
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli/index.ts","../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"],"sourcesContent":["#!/usr/bin/env node\r\n\r\nimport { pathToFileURL } from \"node:url\";\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 (!parsed.command || parsed.flags.help || parsed.command === \"help\") {\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\nfunction isDirectRun(): boolean {\r\n const entry = process.argv[1];\r\n\r\n if (!entry) {\r\n return false;\r\n }\r\n\r\n return import.meta.url === pathToFileURL(entry).href;\r\n}\r\n\r\nif (isDirectRun()) {\r\n void main();\r\n}\r\n","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"],"mappings":"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","names":["pathToFileURL","path","path","path","path","path","pathToFileURL"]}
|
|
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,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "node-safe-env",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A tiny schema-based env loader and validator for Node.js.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"env",
|
|
@@ -50,6 +50,9 @@
|
|
|
50
50
|
"format": "prettier --write .",
|
|
51
51
|
"check": "npm run lint && npm run build && npm run typecheck && npm run test"
|
|
52
52
|
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"tsx": "^4.21.0"
|
|
55
|
+
},
|
|
53
56
|
"devDependencies": {
|
|
54
57
|
"@eslint/js": "9.39.1",
|
|
55
58
|
"@types/node": "^24.0.0",
|