node-safe-env 0.1.1 → 0.1.3

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