@romaintaillandier1978/dotenv-never-lies 1.1.1 → 1.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +103 -42
- package/dist/cli/commands/assert.d.ts +3 -4
- package/dist/cli/commands/assert.d.ts.map +1 -1
- package/dist/cli/commands/explain.d.ts +2 -3
- package/dist/cli/commands/explain.d.ts.map +1 -1
- package/dist/cli/commands/export.d.ts +4 -3
- package/dist/cli/commands/export.d.ts.map +1 -1
- package/dist/cli/commands/export.js +46 -0
- package/dist/cli/commands/generate.d.ts +2 -2
- package/dist/cli/commands/generate.d.ts.map +1 -1
- package/dist/cli/commands/infer.d.ts +15 -0
- package/dist/cli/commands/infer.d.ts.map +1 -0
- package/dist/cli/commands/infer.js +86 -0
- package/dist/cli/commands/init.d.ts +15 -0
- package/dist/cli/commands/init.d.ts.map +1 -0
- package/dist/cli/commands/init.js +30 -0
- package/dist/cli/commands/program.d.ts +4 -0
- package/dist/cli/commands/program.d.ts.map +1 -0
- package/dist/cli/commands/program.js +1 -0
- package/dist/cli/index.js +74 -30
- package/dist/cli/utils/infer-schema.d.ts +2 -2
- package/dist/cli/utils/infer-schema.d.ts.map +1 -1
- package/dist/cli/utils/infer-schema.js +20 -22
- package/dist/cli/utils/printer.d.ts +2 -0
- package/dist/cli/utils/printer.d.ts.map +1 -1
- package/dist/cli/utils/printer.js +104 -1
- package/dist/core.d.ts.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/infer/__tests__/port-vs-version.test.d.ts +2 -0
- package/dist/infer/__tests__/port-vs-version.test.d.ts.map +1 -0
- package/dist/infer/__tests__/port-vs-version.test.js +32 -0
- package/dist/infer/__tests__/rules/basic.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/basic.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/basic.test.js +85 -0
- package/dist/infer/__tests__/rules/boolean.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/boolean.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/boolean.test.js +34 -0
- package/dist/infer/__tests__/rules/duration.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/duration.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/duration.test.js +24 -0
- package/dist/infer/__tests__/rules/ip.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/ip.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/ip.test.js +24 -0
- package/dist/infer/__tests__/rules/json.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/json.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/json.test.js +38 -0
- package/dist/infer/__tests__/rules/list.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/list.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/list.test.js +130 -0
- package/dist/infer/__tests__/rules/port.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/port.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/port.test.js +24 -0
- package/dist/infer/__tests__/rules/url.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/url.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/url.test.js +39 -0
- package/dist/infer/__tests__/rules/version.test.d.ts +2 -0
- package/dist/infer/__tests__/rules/version.test.d.ts.map +1 -0
- package/dist/infer/__tests__/rules/version.test.js +37 -0
- package/dist/infer/generated/basic.d.ts +8 -0
- package/dist/infer/generated/basic.d.ts.map +1 -0
- package/dist/infer/generated/basic.js +24 -0
- package/dist/infer/generated/boolean.d.ts +3 -0
- package/dist/infer/generated/boolean.d.ts.map +1 -0
- package/dist/infer/generated/boolean.js +9 -0
- package/dist/infer/generated/duration.d.ts +3 -0
- package/dist/infer/generated/duration.d.ts.map +1 -0
- package/dist/infer/generated/duration.js +9 -0
- package/dist/infer/generated/ip.d.ts +3 -0
- package/dist/infer/generated/ip.d.ts.map +1 -0
- package/dist/infer/generated/ip.js +9 -0
- package/dist/infer/generated/json.d.ts +4 -0
- package/dist/infer/generated/json.d.ts.map +1 -0
- package/dist/infer/generated/json.js +10 -0
- package/dist/infer/generated/list.d.ts +8 -0
- package/dist/infer/generated/list.d.ts.map +1 -0
- package/dist/infer/generated/list.js +49 -0
- package/dist/infer/generated/port.d.ts +4 -0
- package/dist/infer/generated/port.d.ts.map +1 -0
- package/dist/infer/generated/port.js +10 -0
- package/dist/infer/generated/url.d.ts +14 -0
- package/dist/infer/generated/url.d.ts.map +1 -0
- package/dist/infer/generated/url.js +30 -0
- package/dist/infer/generated/version.d.ts +4 -0
- package/dist/infer/generated/version.d.ts.map +1 -0
- package/dist/infer/generated/version.js +10 -0
- package/dist/infer/helpers.d.ts +11 -0
- package/dist/infer/helpers.d.ts.map +1 -0
- package/dist/infer/helpers.js +41 -0
- package/dist/infer/index.d.ts +4 -0
- package/dist/infer/index.d.ts.map +1 -0
- package/dist/infer/index.js +35 -0
- package/dist/infer/rules/basic.d.ts +11 -0
- package/dist/infer/rules/basic.d.ts.map +1 -0
- package/dist/infer/rules/basic.js +90 -0
- package/dist/infer/rules/boolean.d.ts +3 -0
- package/dist/infer/rules/boolean.d.ts.map +1 -0
- package/dist/infer/rules/boolean.js +25 -0
- package/dist/infer/rules/duration.d.ts +3 -0
- package/dist/infer/rules/duration.d.ts.map +1 -0
- package/dist/infer/rules/duration.js +25 -0
- package/dist/infer/rules/ip.d.ts +3 -0
- package/dist/infer/rules/ip.d.ts.map +1 -0
- package/dist/infer/rules/ip.js +25 -0
- package/dist/infer/rules/json.d.ts +3 -0
- package/dist/infer/rules/json.d.ts.map +1 -0
- package/dist/infer/rules/json.js +59 -0
- package/dist/infer/rules/list.d.ts +12 -0
- package/dist/infer/rules/list.d.ts.map +1 -0
- package/dist/infer/rules/list.js +221 -0
- package/dist/infer/rules/port.d.ts +3 -0
- package/dist/infer/rules/port.d.ts.map +1 -0
- package/dist/infer/rules/port.js +30 -0
- package/dist/infer/rules/url.d.ts +4 -0
- package/dist/infer/rules/url.d.ts.map +1 -0
- package/dist/infer/rules/url.js +143 -0
- package/dist/infer/rules/version.d.ts +3 -0
- package/dist/infer/rules/version.d.ts.map +1 -0
- package/dist/infer/rules/version.js +26 -0
- package/dist/infer/types.d.ts +87 -0
- package/dist/infer/types.d.ts.map +1 -0
- package/dist/infer/types.js +1 -0
- package/dist/infer-rules/basic.d.ts +5 -0
- package/dist/infer-rules/basic.d.ts.map +1 -0
- package/dist/infer-rules/basic.js +48 -0
- package/dist/infer-rules/boolean.d.ts +3 -0
- package/dist/infer-rules/boolean.d.ts.map +1 -0
- package/dist/infer-rules/boolean.js +25 -0
- package/dist/infer-rules/dotted.d.ts +4 -0
- package/dist/infer-rules/dotted.d.ts.map +1 -0
- package/dist/infer-rules/dotted.js +48 -0
- package/dist/infer-rules/duration.d.ts +3 -0
- package/dist/infer-rules/duration.d.ts.map +1 -0
- package/dist/infer-rules/duration.js +25 -0
- package/dist/infer-rules/index.d.ts +50 -0
- package/dist/infer-rules/index.d.ts.map +1 -0
- package/dist/infer-rules/index.js +42 -0
- package/dist/infer-rules/json.d.ts +3 -0
- package/dist/infer-rules/json.d.ts.map +1 -0
- package/dist/infer-rules/json.js +50 -0
- package/dist/infer-rules/list.d.ts +5 -0
- package/dist/infer-rules/list.d.ts.map +1 -0
- package/dist/infer-rules/list.js +200 -0
- package/dist/infer-rules/path.d.ts +5 -0
- package/dist/infer-rules/path.d.ts.map +1 -0
- package/dist/infer-rules/path.js +78 -0
- package/dist/infer-rules/port.d.ts +3 -0
- package/dist/infer-rules/port.d.ts.map +1 -0
- package/dist/infer-rules/port.js +26 -0
- package/dist/infer-rules/simple.d.ts +3 -0
- package/dist/infer-rules/simple.d.ts.map +1 -0
- package/dist/infer-rules/simple.js +37 -0
- package/dist/infer-rules/url.d.ts +4 -0
- package/dist/infer-rules/url.d.ts.map +1 -0
- package/dist/infer-rules/url.js +149 -0
- package/dist/llm-kit/context.json.d.ts +2 -0
- package/dist/llm-kit/context.json.d.ts.map +1 -0
- package/dist/llm-kit/context.json.js +22 -0
- package/dist/sample/DNLTest.d.ts +2 -0
- package/dist/sample/DNLTest.d.ts.map +1 -0
- package/dist/sample/DNLTest.js +4 -0
- package/dist/sample/debug.d.ts +2 -0
- package/dist/sample/debug.d.ts.map +1 -0
- package/dist/sample/debug.js +5 -0
- package/dist/sample/env.dnl.d.ts +426 -0
- package/dist/sample/env.dnl.d.ts.map +1 -0
- package/dist/sample/env.dnl.js +429 -0
- package/dist/schemas/bool.d.ts +9 -0
- package/dist/schemas/bool.d.ts.map +1 -0
- package/dist/schemas/bool.js +22 -0
- package/dist/schemas/boolean.d.ts +9 -0
- package/dist/schemas/boolean.d.ts.map +1 -0
- package/dist/schemas/boolean.js +23 -0
- package/dist/schemas/dotted.d.ts +21 -0
- package/dist/schemas/dotted.d.ts.map +1 -0
- package/dist/schemas/dotted.js +45 -0
- package/dist/schemas/duration.d.ts +11 -0
- package/dist/schemas/duration.d.ts.map +1 -0
- package/dist/schemas/duration.js +44 -0
- package/dist/schemas/index.d.ts +9 -0
- package/dist/schemas/index.d.ts.map +1 -0
- package/dist/schemas/index.js +8 -0
- package/dist/schemas/ip-and-version.d.ts +12 -0
- package/dist/schemas/ip-and-version.d.ts.map +1 -0
- package/dist/schemas/ip-and-version.js +35 -0
- package/dist/schemas/ip.d.ts +11 -0
- package/dist/schemas/ip.d.ts.map +1 -0
- package/dist/schemas/ip.js +33 -0
- package/dist/schemas/json.d.ts +15 -0
- package/dist/schemas/json.d.ts.map +1 -0
- package/dist/schemas/json.js +34 -0
- package/dist/schemas/list.d.ts +89 -0
- package/dist/schemas/list.d.ts.map +1 -0
- package/dist/schemas/list.js +139 -0
- package/dist/schemas/path.d.ts +23 -0
- package/dist/schemas/path.d.ts.map +1 -0
- package/dist/schemas/path.js +33 -0
- package/dist/schemas/port.d.ts +8 -0
- package/dist/schemas/port.d.ts.map +1 -0
- package/dist/schemas/port.js +9 -0
- package/dist/schemas/urls.d.ts +15 -0
- package/dist/schemas/urls.d.ts.map +1 -0
- package/dist/schemas/urls.js +54 -0
- package/package.json +11 -6
- package/dist/DnlTest.d.ts +0 -2
- package/dist/DnlTest.d.ts.map +0 -1
- package/dist/DnlTest.js +0 -12
- package/dist/cli/utils/exitCodes.d.ts +0 -8
- package/dist/cli/utils/exitCodes.d.ts.map +0 -1
- package/dist/cli/utils/exitCodes.js +0 -8
- package/dist/romaintaillandier1978-dotenv-never-lies-0.3.0.tgz +0 -0
package/README.md
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
# dotenv-never-lies
|
|
2
2
|
|
|
3
|
+
> [!CAUTION]
|
|
4
|
+
> Experimental — not yet ready to use.
|
|
5
|
+
|
|
3
6
|
> Because environment variables lie all the time.
|
|
4
7
|
|
|
5
8
|
**dotenv-never-lies** validates, types, and documents your environment variables from a TypeScript / Zod schema.
|
|
@@ -28,10 +31,11 @@ And because `.env` files are:
|
|
|
28
31
|
## What the library does
|
|
29
32
|
|
|
30
33
|
- ✅ validates environment variables at startup
|
|
34
|
+
powered by zod, enables complex transformations (arrays, parsing, coercion…)
|
|
35
|
+
- ✅ provides infer .Env to get a first real life dnl schema
|
|
31
36
|
- ✅ provides reliable TypeScript typings
|
|
32
37
|
- ✅ documents each variable
|
|
33
|
-
- ✅ exposes a CLI for CI and humans
|
|
34
|
-
- ✅ enables complex transformations (arrays, parsing, coercion…)
|
|
38
|
+
- ✅ exposes a CLI for CI and humans (dnl export)
|
|
35
39
|
|
|
36
40
|
---
|
|
37
41
|
|
|
@@ -98,7 +102,7 @@ NODE_CORS_ORIGIN="${FRONT_A};${FRONT_B};${FRONT_C}"
|
|
|
98
102
|
|
|
99
103
|
The DNL schema is your new source of truth.
|
|
100
104
|
|
|
101
|
-
(`dnl
|
|
105
|
+
(`dnl infer` will help you scaffold the first skeleton)
|
|
102
106
|
|
|
103
107
|
### schema location
|
|
104
108
|
|
|
@@ -135,7 +139,7 @@ export default define({
|
|
|
135
139
|
|
|
136
140
|
NODE_PORT: {
|
|
137
141
|
description: "API port",
|
|
138
|
-
schema:
|
|
142
|
+
schema: portSchema("NODE_PORT").default(3000),
|
|
139
143
|
},
|
|
140
144
|
|
|
141
145
|
FRONT_URL: {
|
|
@@ -169,32 +173,8 @@ JWT_SECRET: {
|
|
|
169
173
|
}
|
|
170
174
|
```
|
|
171
175
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
assert: validates secrets like any other variable
|
|
175
|
-
|
|
176
|
-
reverse-env: when generating the schema, with `--guess-secret` option, the command tries to automatically identify sensitive variables (e.g. SECRET, KEY, TOKEN, PASSWORD).
|
|
177
|
-
**This detection is heuristic and must always be reviewed and corrected manually.**
|
|
178
|
-
|
|
179
|
-
export: adapts behavior depending on the target format (env, docker, CI, Kubernetes…). See the table below for details by format.
|
|
180
|
-
|
|
181
|
-
### During export
|
|
182
|
-
|
|
183
|
-
Variables marked `secret: true` in the schema are treated differently depending on the export format.
|
|
184
|
-
|
|
185
|
-
| Format | Secrets included by default | Maskable (`--hide-secret`) | Excludable (`--exclude-secret`) | Notes |
|
|
186
|
-
| ------------- | --------------------------- | -------------------------- | ------------------------------- | -------------------------- |
|
|
187
|
-
| env | yes | yes | yes | classic .env |
|
|
188
|
-
| docker-env | yes | yes | yes | For --env-file |
|
|
189
|
-
| docker-args | yes | yes | yes | For docker run -e |
|
|
190
|
-
| json | yes | yes | yes | Debug / tooling |
|
|
191
|
-
| ts | yes | yes | yes | Typed export |
|
|
192
|
-
| js | yes | yes | yes | Runtime export |
|
|
193
|
-
| github-env | yes | yes | yes | visible in logs |
|
|
194
|
-
| github-secret | secrets only | no | yes | Via gh secret set |
|
|
195
|
-
| gitlab-env | yes | yes | yes | GitLab CI variables |
|
|
196
|
-
| k8s-configmap | yes | yes | yes | warning if secret unmasked |
|
|
197
|
-
| k8s-secret | secrets only | yes | yes | Kubernetes Secret |
|
|
176
|
+
More about secrets, and usage in cli commands :
|
|
177
|
+
→ [Read secret documentation](docs/concepts/secrets.md)
|
|
198
178
|
|
|
199
179
|
## Variable lifecycle
|
|
200
180
|
|
|
@@ -302,12 +282,13 @@ This is the recommended mode when variables are injected by the runtime or CI.
|
|
|
302
282
|
- a value is invalid
|
|
303
283
|
- the schema is not respected
|
|
304
284
|
|
|
305
|
-
###
|
|
285
|
+
### init: Generate a .env file from the schema
|
|
306
286
|
|
|
307
|
-
|
|
287
|
+
Initialize a documented `.env` from the schema.
|
|
288
|
+
Do not read any environment variables
|
|
308
289
|
|
|
309
290
|
```bash
|
|
310
|
-
dnl
|
|
291
|
+
dnl init --schema env.dnl.ts --out .env
|
|
311
292
|
```
|
|
312
293
|
|
|
313
294
|
Useful for:
|
|
@@ -316,18 +297,17 @@ Useful for:
|
|
|
316
297
|
- sharing a template
|
|
317
298
|
- avoiding obsolete `.env.example` files
|
|
318
299
|
|
|
319
|
-
###
|
|
300
|
+
### infer: discover a .envfile, and generate a schema from an existing .env
|
|
320
301
|
|
|
321
|
-
|
|
302
|
+
Generate a DNL schema from an existing `.env` file.
|
|
322
303
|
|
|
323
304
|
```bash
|
|
324
|
-
dnl
|
|
305
|
+
dnl infer --source .env
|
|
325
306
|
```
|
|
326
307
|
|
|
327
|
-
Useful for
|
|
308
|
+
Useful for migrating an existing project
|
|
328
309
|
|
|
329
|
-
|
|
330
|
-
- documenting a legacy configuration afterwards
|
|
310
|
+
→ [Read infer documentation](docs/commands/infer.md)
|
|
331
311
|
|
|
332
312
|
### explain: Display variables documentation
|
|
333
313
|
|
|
@@ -402,6 +382,24 @@ printf '%s\n' "NODE_PORT=3000" >> $GITHUB_ENV
|
|
|
402
382
|
|
|
403
383
|
There are a few more formats and options (see CLI docs `dnl export --help`).
|
|
404
384
|
|
|
385
|
+
## export types : Exporting TypeScript types
|
|
386
|
+
|
|
387
|
+
`dnl export types` generates a `.d.ts` file describing the **static contract** of your environment variables.
|
|
388
|
+
|
|
389
|
+
This file is intentionally **conservative**.
|
|
390
|
+
|
|
391
|
+
### Transformed variables
|
|
392
|
+
|
|
393
|
+
If a variable uses a Zod `transform`, the exported type always reflects the **input type**, not the runtime output.
|
|
394
|
+
|
|
395
|
+
In that case:
|
|
396
|
+
|
|
397
|
+
- a warning is emitted in the CLI
|
|
398
|
+
- the generated type is annotated with `@dnl-transform`
|
|
399
|
+
- the runtime value returned by `assert()` may differ
|
|
400
|
+
|
|
401
|
+
This is a deliberate design choice to avoid lying to TypeScript.
|
|
402
|
+
|
|
405
403
|
## Real-life usage
|
|
406
404
|
|
|
407
405
|
### GitIgnore
|
|
@@ -484,7 +482,7 @@ jobs:
|
|
|
484
482
|
- run: corepack enable
|
|
485
483
|
- run: yarn install --frozen-lockfile
|
|
486
484
|
|
|
487
|
-
# Example with a .env file
|
|
485
|
+
# Example with a .env file
|
|
488
486
|
- run: yarn dnl assert --source .env
|
|
489
487
|
```
|
|
490
488
|
|
|
@@ -500,8 +498,8 @@ The `.env` file can be generated from a GitHub secret or mounted dynamically.
|
|
|
500
498
|
|
|
501
499
|
| Situation | Command to use |
|
|
502
500
|
| --------------------------------------: | ------------------------------ |
|
|
503
|
-
| New project |
|
|
504
|
-
| Existing project with a .env |
|
|
501
|
+
| New project | init |
|
|
502
|
+
| Existing project with a .env | infer |
|
|
505
503
|
| Validate configuration in CI | assert |
|
|
506
504
|
| Validate config injected by the runtime | assert |
|
|
507
505
|
| Document variables | explain |
|
|
@@ -515,6 +513,69 @@ Simple rule:
|
|
|
515
513
|
> The schema is always the source of truth.
|
|
516
514
|
> Commands only validate, document, or transform.
|
|
517
515
|
|
|
516
|
+
### Tips
|
|
517
|
+
|
|
518
|
+
**Alternative: minimal-intrusion integration**
|
|
519
|
+
|
|
520
|
+
For a minimally invasive integration, you can add an optional Yarn script
|
|
521
|
+
to validate your `.env` file before starting the application:
|
|
522
|
+
|
|
523
|
+
```json
|
|
524
|
+
{
|
|
525
|
+
"scripts": {
|
|
526
|
+
"env:check": "dnl assert --source .env",
|
|
527
|
+
"start:withdnl": "yarn env:check && yarn start"
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
```
|
|
531
|
+
|
|
532
|
+
This validates the environment before startup, without changing runtime behavior or application code.
|
|
533
|
+
|
|
534
|
+
> This is optional. It does not replace runtime validation.
|
|
535
|
+
|
|
536
|
+
**Intellisens and JSdoc for env vars**
|
|
537
|
+
|
|
538
|
+
After using `dnl export types` and importing the generated file, you get strong typing, auto-completion, IntelliSense and JSDoc for each environment variable.
|
|
539
|
+
|
|
540
|
+

|
|
541
|
+
|
|
542
|
+
> IntelliSense and JSDoc generated from the DNL schema after `dnl export types`.
|
|
543
|
+
|
|
544
|
+
## Common issues / Troubleshooting
|
|
545
|
+
|
|
546
|
+
### TypeScript projects with `rootDir: "src"`
|
|
547
|
+
|
|
548
|
+
If your project uses a strict TypeScript setup with `rootDir: "src"`,
|
|
549
|
+
and your `env.dnl.ts` file is located at the project root,
|
|
550
|
+
TypeScript may report an error like:
|
|
551
|
+
|
|
552
|
+
> File 'env.dnl.ts' is not under 'rootDir' (TS6059)
|
|
553
|
+
|
|
554
|
+
**Option A** (preferred) :
|
|
555
|
+
|
|
556
|
+
Keeps the schema outside application code, allowing reuse by the CLI, CI, and tooling.
|
|
557
|
+
|
|
558
|
+
To fix this, include `env.dnl.ts` explicitly in your `tsconfig.json` and widen `rootDir`:
|
|
559
|
+
|
|
560
|
+
```json
|
|
561
|
+
{
|
|
562
|
+
"compilerOptions": {
|
|
563
|
+
"rootDir": "."
|
|
564
|
+
},
|
|
565
|
+
"include": ["src/**/*.ts", "env.dnl.ts"]
|
|
566
|
+
}
|
|
567
|
+
```
|
|
568
|
+
|
|
569
|
+
This ensures `env.dnl.ts` is included in the TypeScript compilation graph.
|
|
570
|
+
|
|
571
|
+
**Option B** :
|
|
572
|
+
|
|
573
|
+
Move the schema into `./src` (for example `./src/env/env.dnl.ts`).
|
|
574
|
+
|
|
575
|
+
This avoids TypeScript configuration changes, but makes the schema part of the application codebase
|
|
576
|
+
|
|
577
|
+
You will need to specify schema location, see related section
|
|
578
|
+
|
|
518
579
|
## FAQ / Design choices
|
|
519
580
|
|
|
520
581
|
### Why so strict?
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
source
|
|
1
|
+
import { ProgramCliOptions } from "./program.js";
|
|
2
|
+
export type AssertCliOptions = ProgramCliOptions & {
|
|
3
|
+
source?: string;
|
|
4
4
|
};
|
|
5
5
|
export declare const assertCommand: (opts?: AssertCliOptions | undefined) => Promise<void>;
|
|
6
|
-
export {};
|
|
7
6
|
//# sourceMappingURL=assert.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/assert.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"assert.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/assert.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,gBAAgB,GAAG,iBAAiB,GAAG;IAC/C,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,eAAO,MAAM,aAAa,GAAU,OAAO,gBAAgB,GAAG,SAAS,KAAG,OAAO,CAAC,IAAI,CAsBrF,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Explanation } from "../utils/printer.js";
|
|
2
|
-
|
|
3
|
-
|
|
2
|
+
import { ProgramCliOptions } from "./program.js";
|
|
3
|
+
export type ExplainCliOptions = ProgramCliOptions & {
|
|
4
4
|
keys?: string[] | undefined;
|
|
5
5
|
format?: "human" | "json" | undefined;
|
|
6
6
|
};
|
|
@@ -9,5 +9,4 @@ export declare const explainCommand: (options?: ExplainCliOptions) => Promise<{
|
|
|
9
9
|
result: Explanation[];
|
|
10
10
|
}>;
|
|
11
11
|
export declare const printHuman: (result: Explanation[]) => void;
|
|
12
|
-
export {};
|
|
13
12
|
//# sourceMappingURL=explain.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/explain.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAiB,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"explain.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/explain.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAiB,MAAM,qBAAqB,CAAC;AAEjE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,iBAAiB,GAAG,iBAAiB,GAAG;IAChD,IAAI,CAAC,EAAE,MAAM,EAAE,GAAG,SAAS,CAAC;IAC5B,MAAM,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;CACzC,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,UAAU,iBAAiB,KAAG,OAAO,CAAC;IAAE,MAAM,EAAE,OAAO,GAAG,MAAM,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CA2B7H,CAAC;AAEF,eAAO,MAAM,UAAU,GAAI,QAAQ,WAAW,EAAE,SAqB/C,CAAC"}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import dnl from "../../index.js";
|
|
2
|
-
|
|
2
|
+
import { ProgramCliOptions } from "./program.js";
|
|
3
|
+
export declare const exportFormatsNames: readonly ["docker-env", "docker-args", "env", "k8s-configmap", "k8s-secret", "github-env", "github-secret", "gitlab-env", "json", "ts", "js", "types"];
|
|
3
4
|
export type ExportFormat = (typeof exportFormatsNames)[number];
|
|
4
5
|
export type ExportResult = {
|
|
5
6
|
content: string;
|
|
6
7
|
warnings: string[];
|
|
7
8
|
out?: string;
|
|
8
9
|
};
|
|
9
|
-
export type ExportCliOptions = {
|
|
10
|
+
export type ExportCliOptions = ProgramCliOptions & {
|
|
10
11
|
format: ExportFormat;
|
|
11
|
-
schema?: string | undefined;
|
|
12
12
|
source?: string | undefined;
|
|
13
13
|
hideSecret?: boolean;
|
|
14
14
|
excludeSecret?: boolean;
|
|
@@ -32,4 +32,5 @@ export declare const exportGitlabEnv: (envDef: dnl.EnvDefinitionHelper<any>, opt
|
|
|
32
32
|
export declare const exportJson: (envDef: dnl.EnvDefinitionHelper<any>, options: ExportCliOptions, warnings: string[]) => string;
|
|
33
33
|
export declare const exportTs: (envDef: dnl.EnvDefinitionHelper<any>, options: ExportCliOptions, warnings: string[]) => string;
|
|
34
34
|
export declare const exportJs: (envDef: dnl.EnvDefinitionHelper<any>, options: ExportCliOptions, warnings: string[]) => string;
|
|
35
|
+
export declare const exportDts: (envDef: dnl.EnvDefinitionHelper<any>, options: ExportCliOptions, warnings: string[]) => string;
|
|
35
36
|
//# sourceMappingURL=export.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":"AAAA,OAAO,GAA4B,MAAM,gBAAgB,CAAC;AAM1D,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"export.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/export.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ import { loadDef } from "../utils/load-schema.js";
|
|
|
3
3
|
import { resolveSchemaPath } from "../utils/resolve-schema.js";
|
|
4
4
|
import path from "path";
|
|
5
5
|
import { UsageError } from "../../errors.js";
|
|
6
|
+
import { isRequired, isTransform, printZodTypeDts } from "../utils/printer.js";
|
|
6
7
|
export const exportFormatsNames = [
|
|
7
8
|
"docker-env",
|
|
8
9
|
"docker-args",
|
|
@@ -15,6 +16,7 @@ export const exportFormatsNames = [
|
|
|
15
16
|
"json",
|
|
16
17
|
"ts",
|
|
17
18
|
"js",
|
|
19
|
+
"types",
|
|
18
20
|
];
|
|
19
21
|
const shellEscape = (value) => {
|
|
20
22
|
if (value.length === 0) {
|
|
@@ -32,6 +34,9 @@ export const exportCommand = async (options) => {
|
|
|
32
34
|
if (options.serializeTyped && !["js", "ts", "json"].includes(options.format)) {
|
|
33
35
|
throw new UsageError("--serialize-typed is only valid for js, ts and json exports");
|
|
34
36
|
}
|
|
37
|
+
if (options.format === "types" && options.source) {
|
|
38
|
+
throw new UsageError("--source is not applicable to the 'types' export format");
|
|
39
|
+
}
|
|
35
40
|
const schemaPath = resolveSchemaPath(options?.schema);
|
|
36
41
|
const envDef = (await loadDef(schemaPath));
|
|
37
42
|
const warnings = [];
|
|
@@ -66,6 +71,8 @@ export const contentByFormat = (format, envDef, options, warnings) => {
|
|
|
66
71
|
return exportDockerArgs(envDef, options, warnings);
|
|
67
72
|
case "docker-env":
|
|
68
73
|
return exportDockerEnv(envDef, options, warnings);
|
|
74
|
+
case "types":
|
|
75
|
+
return exportDts(envDef, options, warnings);
|
|
69
76
|
default:
|
|
70
77
|
throw new UsageError(`Unsupported format: ${format}`);
|
|
71
78
|
}
|
|
@@ -265,4 +272,43 @@ export const exportJs = (envDef, options, warnings) => {
|
|
|
265
272
|
}
|
|
266
273
|
return `export const env = {\n${middle.join("\n")}\n};`;
|
|
267
274
|
};
|
|
275
|
+
export const exportDts = (envDef, options, warnings) => {
|
|
276
|
+
const middle = [];
|
|
277
|
+
let transformedCount = 0;
|
|
278
|
+
for (const key of Object.keys(envDef.def)) {
|
|
279
|
+
const type = printZodTypeDts(envDef.def[key].schema.def);
|
|
280
|
+
const optional = isRequired(envDef.def[key].schema.def) ? "" : "?";
|
|
281
|
+
const transform = isTransform(envDef.def[key].schema.def);
|
|
282
|
+
const secret = envDef.def[key].secret;
|
|
283
|
+
const required = isRequired(envDef.def[key].schema.def);
|
|
284
|
+
const description = envDef.def[key].description;
|
|
285
|
+
let comment = ` /**\n * @env ${key}\n`;
|
|
286
|
+
if (secret)
|
|
287
|
+
comment += ` * @secret\n`;
|
|
288
|
+
if (required)
|
|
289
|
+
comment += ` * @required\n`;
|
|
290
|
+
if (description)
|
|
291
|
+
comment += ` * ${description}\n`;
|
|
292
|
+
if (transform) {
|
|
293
|
+
comment += ` *
|
|
294
|
+
* ⚠️ TRANSFORMED ENV VARIABLE
|
|
295
|
+
*
|
|
296
|
+
* Runtime type differs from declared type.
|
|
297
|
+
* Do NOT trust this type without checking the schema.
|
|
298
|
+
*
|
|
299
|
+
* @dnl-transform\n`;
|
|
300
|
+
}
|
|
301
|
+
comment += ` */`;
|
|
302
|
+
middle.push(comment);
|
|
303
|
+
middle.push(` ${key}${optional}: ${type};`);
|
|
304
|
+
if (transform) {
|
|
305
|
+
transformedCount++;
|
|
306
|
+
warnings.push(` - ${key} (@dnl-transform): runtime type differs from exported type.`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
if (transformedCount > 0) {
|
|
310
|
+
warnings.push(`⚠️ ${transformedCount} transformed variable detected. See @dnl-transform annotations.`);
|
|
311
|
+
}
|
|
312
|
+
return `export interface Env {\n${middle.join("\n")}\n}`;
|
|
313
|
+
};
|
|
268
314
|
// #endregion serialisation json/ts/js
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"generate.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/generate.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,kBAAkB,GAAG,iBAAiB,GAAG;IACjD,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AACF,MAAM,MAAM,cAAc,GAAG;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,eAAe,GAAU,OAAO,kBAAkB,GAAG,SAAS,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CA6BrH,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type InferCliOptions = {
|
|
2
|
+
source?: string;
|
|
3
|
+
out?: string;
|
|
4
|
+
force?: boolean;
|
|
5
|
+
dontGuessSecret?: boolean;
|
|
6
|
+
verbose?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export type InferResult = {
|
|
9
|
+
content: string;
|
|
10
|
+
out: string;
|
|
11
|
+
warnings: string[];
|
|
12
|
+
verbose?: Array<string>;
|
|
13
|
+
};
|
|
14
|
+
export declare const inferCommand: (opts?: InferCliOptions | undefined) => Promise<InferResult>;
|
|
15
|
+
//# sourceMappingURL=infer.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"infer.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/infer.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,eAAe,GAAG;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG;IACtB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,OAAO,CAAC,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC;CAC3B,CAAC;AAEF,eAAO,MAAM,YAAY,GAAU,OAAO,eAAe,GAAG,SAAS,KAAG,OAAO,CAAC,WAAW,CA+D1F,CAAC"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
import dnl from "../../index.js";
|
|
3
|
+
import { guessSecret } from "../../infer/helpers.js";
|
|
4
|
+
import { infer } from "../utils/infer-schema.js";
|
|
5
|
+
import fs from "node:fs";
|
|
6
|
+
import { ExportError } from "../../errors.js";
|
|
7
|
+
export const inferCommand = async (opts) => {
|
|
8
|
+
const source = path.resolve(process.cwd(), opts?.source ?? ".env");
|
|
9
|
+
if (!fs.existsSync(source)) {
|
|
10
|
+
throw new ExportError(`Source env file not found: ${source}`);
|
|
11
|
+
}
|
|
12
|
+
const out = opts?.out ?? "env.dnl.ts";
|
|
13
|
+
const target = path.resolve(process.cwd(), out);
|
|
14
|
+
if (fs.existsSync(target) && !opts?.force) {
|
|
15
|
+
throw new ExportError(`${out} already exists. Use --force to overwrite.`);
|
|
16
|
+
}
|
|
17
|
+
const env = dnl.readEnvFile(source);
|
|
18
|
+
const lines = [];
|
|
19
|
+
const warnings = [];
|
|
20
|
+
const importedSchemas = [];
|
|
21
|
+
const verbose = [];
|
|
22
|
+
lines.push(`// ⚠️ This file was generated by dotenv-never-lies`);
|
|
23
|
+
lines.push(`// Review and adjust schemas, descriptions and secrets before using`);
|
|
24
|
+
lines.push("");
|
|
25
|
+
lines.push(`import { z } from "zod";`);
|
|
26
|
+
lines.push(`import { define } from "@romaintaillandier1978/dotenv-never-lies";`);
|
|
27
|
+
lines.push("");
|
|
28
|
+
lines.push(`export default define({`);
|
|
29
|
+
for (const [key, value] of Object.entries(env)) {
|
|
30
|
+
const isValidIdentifier = /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key);
|
|
31
|
+
const safeKey = isValidIdentifier ? key : JSON.stringify(key);
|
|
32
|
+
if (!isValidIdentifier) {
|
|
33
|
+
warnings.push(`Key ${key} is not a valid identifier. It has been escaped to ${safeKey}.`);
|
|
34
|
+
}
|
|
35
|
+
lines.push(` ${safeKey}: {`);
|
|
36
|
+
lines.push(` description: "TODO",`);
|
|
37
|
+
if (value === undefined) {
|
|
38
|
+
lines.push(` schema: z.string().optional(),`);
|
|
39
|
+
}
|
|
40
|
+
else {
|
|
41
|
+
const localWarnings = [];
|
|
42
|
+
const schema = infer(key, value, importedSchemas, verbose, localWarnings);
|
|
43
|
+
for (const warning of localWarnings) {
|
|
44
|
+
lines.push(" // " + warning);
|
|
45
|
+
}
|
|
46
|
+
lines.push(` schema: ${schema},`);
|
|
47
|
+
}
|
|
48
|
+
if (!opts?.dontGuessSecret && guessSecret(key)) {
|
|
49
|
+
lines.push(` secret: true, // ⚠️ inferred as secret`);
|
|
50
|
+
verbose.push(` -> inferred as secret`);
|
|
51
|
+
warnings.push(`${key} inferred as secret`);
|
|
52
|
+
}
|
|
53
|
+
lines.push(` },`);
|
|
54
|
+
}
|
|
55
|
+
lines.push(`});`);
|
|
56
|
+
// insert the imported schemas at the top of the file
|
|
57
|
+
insertImports(lines, importedSchemas);
|
|
58
|
+
return {
|
|
59
|
+
content: lines.join("\n"),
|
|
60
|
+
out: target,
|
|
61
|
+
warnings: [...warnings, "Generated schema is a prototype. Review schemas, descriptions and secrets before using."],
|
|
62
|
+
verbose,
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
const insertImports = (lines, imports) => {
|
|
66
|
+
if (!imports || imports.length === 0)
|
|
67
|
+
return;
|
|
68
|
+
const byFrom = new Map();
|
|
69
|
+
for (const imp of imports) {
|
|
70
|
+
const current = byFrom.get(imp.from) ?? new Set();
|
|
71
|
+
current.add(imp.name);
|
|
72
|
+
byFrom.set(imp.from, current);
|
|
73
|
+
}
|
|
74
|
+
const importLines = [];
|
|
75
|
+
// tri par 'from' pour stabilité
|
|
76
|
+
const froms = Array.from(byFrom.keys()).sort();
|
|
77
|
+
for (const from of froms) {
|
|
78
|
+
const names = Array.from(byFrom.get(from) ?? new Set()).sort();
|
|
79
|
+
if (names.length === 0)
|
|
80
|
+
continue;
|
|
81
|
+
importLines.push(`import { ${names.join(", ")} } from ${JSON.stringify(from)};`);
|
|
82
|
+
}
|
|
83
|
+
if (importLines.length === 0)
|
|
84
|
+
return;
|
|
85
|
+
lines.splice(5, 0, ...importLines);
|
|
86
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { ProgramCliOptions } from "./program.js";
|
|
2
|
+
export type initCliOptions = ProgramCliOptions & {
|
|
3
|
+
out?: string;
|
|
4
|
+
includeSecret?: boolean;
|
|
5
|
+
force?: boolean;
|
|
6
|
+
};
|
|
7
|
+
export type InitResult = {
|
|
8
|
+
content: string;
|
|
9
|
+
out: string;
|
|
10
|
+
};
|
|
11
|
+
export declare const initCommand: (opts?: initCliOptions | undefined) => Promise<{
|
|
12
|
+
content: string;
|
|
13
|
+
out: string;
|
|
14
|
+
}>;
|
|
15
|
+
//# sourceMappingURL=init.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/init.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,cAAc,GAAG,iBAAiB,GAAG;IAC7C,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,KAAK,CAAC,EAAE,OAAO,CAAC;CACnB,CAAC;AACF,MAAM,MAAM,UAAU,GAAG;IACrB,OAAO,EAAE,MAAM,CAAC;IAChB,GAAG,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,eAAO,MAAM,WAAW,GAAU,OAAO,cAAc,GAAG,SAAS,KAAG,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,CA6B7G,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { loadDef } from "../utils/load-schema.js";
|
|
4
|
+
import { resolveSchemaPath } from "../utils/resolve-schema.js";
|
|
5
|
+
import { getDefaultEnvValue } from "../utils/printer.js";
|
|
6
|
+
import { ExportError } from "../../errors.js";
|
|
7
|
+
export const initCommand = async (opts) => {
|
|
8
|
+
const outFile = opts?.out ?? ".env";
|
|
9
|
+
const target = path.resolve(process.cwd(), outFile);
|
|
10
|
+
if (fs.existsSync(target) && !opts?.force) {
|
|
11
|
+
throw new ExportError(`${outFile} already exists. Use --force to overwrite.`);
|
|
12
|
+
}
|
|
13
|
+
const schemaPath = resolveSchemaPath(opts?.schema);
|
|
14
|
+
const envDef = (await loadDef(schemaPath));
|
|
15
|
+
const lines = [];
|
|
16
|
+
for (const [key, def] of Object.entries(envDef.def)) {
|
|
17
|
+
const typedDef = def;
|
|
18
|
+
if (typedDef.description) {
|
|
19
|
+
lines.push(`# ${typedDef.description}`);
|
|
20
|
+
}
|
|
21
|
+
const defaultValue = getDefaultEnvValue(typedDef.schema.def);
|
|
22
|
+
lines.push(`${key}=${defaultValue ?? ""}`);
|
|
23
|
+
lines.push(""); // blank line
|
|
24
|
+
}
|
|
25
|
+
const output = lines.join("\n");
|
|
26
|
+
return {
|
|
27
|
+
content: output,
|
|
28
|
+
out: target,
|
|
29
|
+
};
|
|
30
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/program.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,iBAAiB,GAAG;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|