zod-envkit 1.2.0 → 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +46 -30
- package/README.RU.md +141 -158
- package/README.md +62 -44
- package/dist/cli/index.cjs +39 -18
- package/dist/cli/index.js +39 -18
- package/dist/index.d.cts +8 -6
- package/dist/index.d.ts +8 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,40 +1,70 @@
|
|
|
1
|
-
|
|
1
|
+
## [1.2.2](https://github.com/nxtxe/zod-envkit/compare/v1.2.1...v1.2.2) (2026-02-16)
|
|
2
2
|
|
|
3
3
|
|
|
4
|
-
###
|
|
4
|
+
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
*
|
|
6
|
+
* regenerate lockfile (remove stale link: specifier) ([19d243b](https://github.com/nxtxe/zod-envkit/commit/19d243b411f03c2044fae7f59e0c66676d1d1e90))
|
|
7
|
+
* remove self link dependency from optionalDependencies ([3fd0568](https://github.com/nxtxe/zod-envkit/commit/3fd0568f327d112f496e357962810efdb06deaee))
|
|
7
8
|
|
|
8
|
-
## [1.1
|
|
9
|
+
## [1.2.1](https://github.com/nxtxe/zod-envkit/compare/v1.2.0...v1.2.1) (2026-02-16)
|
|
9
10
|
|
|
10
11
|
|
|
11
12
|
### Bug Fixes
|
|
12
13
|
|
|
13
|
-
*
|
|
14
|
-
* tests ([a691dab](https://github.com/nxtxe/zod-envkit/commit/a691dab0f207685bd96688e36aaabcdb5784f956))
|
|
14
|
+
* strengthen CLI + env contract guarantees ([d516fbb](https://github.com/nxtxe/zod-envkit/commit/d516fbb4c8248745f7d74c1f07defaf4529c33ec))
|
|
15
15
|
|
|
16
16
|
# Changelog
|
|
17
17
|
|
|
18
18
|
All notable changes to this project will be documented in this file.
|
|
19
19
|
This project follows [Semantic Versioning](https://semver.org/).
|
|
20
20
|
|
|
21
|
-
## [1.
|
|
21
|
+
## [1.2.0] – 2026-02-16
|
|
22
22
|
|
|
23
|
-
###
|
|
23
|
+
### Added
|
|
24
24
|
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
25
|
+
* Preprod test suite (smoke, contract, CLI E2E, robustness)
|
|
26
|
+
* Strict CLI isolation for CI (no host env leakage)
|
|
27
|
+
* Robust helpers for CLI E2E testing
|
|
28
|
+
* Internal contract tests for public exports and exit codes
|
|
29
29
|
|
|
30
|
+
### Changed
|
|
30
31
|
|
|
31
|
-
|
|
32
|
+
* `init --from-meta` now generates `.env.example` from `env.meta.json`
|
|
33
|
+
* Test architecture restructured under `tests/test/preprod`
|
|
34
|
+
* CI workflow aligned with pnpm-only setup
|
|
35
|
+
* Improved stability of strict mode behavior
|
|
32
36
|
|
|
37
|
+
### Stability
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
* Public API (`loadEnv`, `mustLoadEnv`, CLI flags) treated as stable contract
|
|
40
|
+
* CLI exit codes verified by contract tests
|
|
41
|
+
* Documentation build enforced in CI
|
|
35
42
|
|
|
36
|
-
|
|
37
|
-
|
|
43
|
+
[1.2.0]: https://www.npmjs.com/package/zod-envkit/v/1.2.0
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## [1.1.2] – 2026-01-29
|
|
48
|
+
|
|
49
|
+
### Fixed
|
|
50
|
+
|
|
51
|
+
* Strict mode now validates only dotenv-loaded variables (prevents host env leakage)
|
|
52
|
+
* Options validation and docs links stabilized
|
|
53
|
+
* CI updated to include CLI smoke tests and docs build
|
|
54
|
+
* Internal cleanup to align behavior with documented API contract
|
|
55
|
+
|
|
56
|
+
[1.1.2]: https://www.npmjs.com/package/zod-envkit/v/1.1.2
|
|
57
|
+
|
|
58
|
+
---
|
|
59
|
+
|
|
60
|
+
## [1.1.1] – 2026-01-29
|
|
61
|
+
|
|
62
|
+
### Fixed
|
|
63
|
+
|
|
64
|
+
* Options validation and docs links stabilized
|
|
65
|
+
* Public API, CLI behavior, and documentation hardened
|
|
66
|
+
|
|
67
|
+
[1.1.1]: https://www.npmjs.com/package/zod-envkit/v/1.1.1
|
|
38
68
|
|
|
39
69
|
---
|
|
40
70
|
|
|
@@ -43,39 +73,31 @@ This project follows [Semantic Versioning](https://semver.org/).
|
|
|
43
73
|
### Added
|
|
44
74
|
|
|
45
75
|
* New `zod-envkit init` command to bootstrap configuration:
|
|
46
|
-
|
|
47
76
|
* generate `env.meta.json` from `.env.example`
|
|
48
77
|
* generate `.env.example` from existing `env.meta.json`
|
|
49
78
|
* Support for loading multiple dotenv files via `--dotenv`
|
|
50
|
-
|
|
51
79
|
* example: `.env,.env.local,.env.production`
|
|
52
80
|
* files are loaded in order with override semantics
|
|
53
81
|
* Documentation generation in multiple formats:
|
|
54
|
-
|
|
55
82
|
* `md` (default)
|
|
56
83
|
* `json`
|
|
57
84
|
* `yaml`
|
|
58
85
|
* Sorting options for docs and CLI output via `--sort`:
|
|
59
|
-
|
|
60
86
|
* `alpha`
|
|
61
87
|
* `required-first`
|
|
62
88
|
* `none`
|
|
63
89
|
* Strict CI validation via `zod-envkit check --strict`
|
|
64
|
-
|
|
65
90
|
* fails on missing **and** unknown environment variables
|
|
66
91
|
* Configurable secret masking in `zod-envkit show`:
|
|
67
|
-
|
|
68
92
|
* `--mask-mode partial | full | none`
|
|
69
93
|
* `--no-mask` alias
|
|
70
94
|
* Grouping support for environment variables via `meta.group`
|
|
71
95
|
* Extended env metadata fields:
|
|
72
|
-
|
|
73
96
|
* `default`
|
|
74
97
|
* `deprecated`
|
|
75
98
|
* `since`
|
|
76
99
|
* `link`
|
|
77
100
|
* New public core utilities:
|
|
78
|
-
|
|
79
101
|
* `getMissingEnv`
|
|
80
102
|
* `getUnknownEnv`
|
|
81
103
|
* `checkEnv`
|
|
@@ -84,16 +106,13 @@ This project follows [Semantic Versioning](https://semver.org/).
|
|
|
84
106
|
### Changed
|
|
85
107
|
|
|
86
108
|
* CLI architecture refactored into a modular structure (`src/cli/*`)
|
|
87
|
-
|
|
88
109
|
* no breaking behavior changes
|
|
89
110
|
* Documentation generator improved:
|
|
90
|
-
|
|
91
111
|
* grouped sections
|
|
92
112
|
* width-aware, centered markdown tables
|
|
93
113
|
* extended metadata columns
|
|
94
114
|
* Public API explicitly documented and treated as a stable contract
|
|
95
115
|
* CLI default behavior preserved:
|
|
96
|
-
|
|
97
116
|
* running `zod-envkit` without subcommand defaults to `generate`
|
|
98
117
|
|
|
99
118
|
### Fixed
|
|
@@ -119,13 +138,11 @@ This project follows [Semantic Versioning](https://semver.org/).
|
|
|
119
138
|
|
|
120
139
|
* Public API stabilized and separated from CLI internals
|
|
121
140
|
* CLI error handling improved:
|
|
122
|
-
|
|
123
141
|
* no stack traces for user errors
|
|
124
142
|
* consistent human-readable messages
|
|
125
143
|
* strict exit codes
|
|
126
144
|
* `ENV.md` generation now produces centered, width-aware tables
|
|
127
145
|
* CLI now reliably resolves `env.meta.json` from:
|
|
128
|
-
|
|
129
146
|
* project root
|
|
130
147
|
* `./examples/`
|
|
131
148
|
* explicit `-c/--config`
|
|
@@ -184,7 +201,6 @@ This project follows [Semantic Versioning](https://semver.org/).
|
|
|
184
201
|
* Type-safe env validation with Zod
|
|
185
202
|
* `loadEnv` and `formatZodError`
|
|
186
203
|
* CLI to generate:
|
|
187
|
-
|
|
188
204
|
* `.env.example`
|
|
189
205
|
* `ENV.md`
|
|
190
206
|
* ESM and CommonJS builds
|
package/README.RU.md
CHANGED
|
@@ -16,90 +16,80 @@
|
|
|
16
16
|
</a>
|
|
17
17
|
</p>
|
|
18
18
|
|
|
19
|
+
|
|
19
20
|
<p>
|
|
20
21
|
<a href="./README.md">English</a> |
|
|
21
22
|
<a href="./README.RU.md">Русский</a>
|
|
22
23
|
</p>
|
|
23
24
|
</div>
|
|
24
25
|
|
|
25
|
-
Типобезопасная валидация и документация переменных окружения с помощью **Zod**.
|
|
26
26
|
|
|
27
|
-
|
|
28
|
-
**явный runtime-контракт**, а не как неявную игру в угадайку.
|
|
27
|
+
Типобезопасная валидация и документация переменных окружения с помощью Zod.
|
|
29
28
|
|
|
30
|
-
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
zod-envkit — это небольшая, явная библиотека + CLI, которая рассматривает переменные окружения как
|
|
30
|
+
явный runtime-контракт, а не как неявную игру в угадайку.
|
|
31
|
+
• валидирует process.env при старте приложения
|
|
32
|
+
• предоставляет полностью типизированные переменные окружения
|
|
33
|
+
• генерирует .env.example
|
|
34
|
+
• генерирует документацию (ENV.md, ENV.json, ENV.yaml)
|
|
35
|
+
• позволяет просматривать состояние env через CLI (с маскированием секретов)
|
|
36
|
+
• строго валидирует env в CI/CD
|
|
37
|
+
• инициализирует конфигурацию через zod-envkit init
|
|
38
|
+
• загружает несколько .env* файлов с приоритетом
|
|
38
39
|
|
|
39
40
|
Никакого облака. Никакой магии. Только код.
|
|
40
41
|
|
|
41
|
-
|
|
42
|
+
⸻
|
|
42
43
|
|
|
43
|
-
|
|
44
|
+
Зачем
|
|
44
45
|
|
|
45
|
-
Переменные окружения критичны, но
|
|
46
|
+
Переменные окружения критичны, но обычно обрабатываются неправильно.
|
|
46
47
|
|
|
47
48
|
Типичные проблемы:
|
|
49
|
+
• process.env — это просто string | undefined
|
|
50
|
+
• отсутствующие или некорректные переменные ломают приложение во время выполнения
|
|
51
|
+
• .env.example и документация рассинхронизируются
|
|
52
|
+
• CI/CD падает поздно и непредсказуемо
|
|
48
53
|
|
|
49
|
-
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
**zod-envkit** решает это, делая env:
|
|
55
|
-
|
|
56
|
-
- валидируемым на раннем этапе
|
|
57
|
-
- типизированным
|
|
58
|
-
- документированным
|
|
59
|
-
- проверяемым в CI
|
|
60
|
-
|
|
61
|
-
---
|
|
54
|
+
zod-envkit решает это, делая env:
|
|
55
|
+
• валидируемым на раннем этапе
|
|
56
|
+
• типизированным
|
|
57
|
+
• документированным
|
|
58
|
+
• проверяемым в CI
|
|
62
59
|
|
|
63
|
-
|
|
60
|
+
⸻
|
|
64
61
|
|
|
65
|
-
|
|
62
|
+
Когда использовать
|
|
66
63
|
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
64
|
+
Используйте zod-envkit, если:
|
|
65
|
+
• вы хотите, чтобы ошибки env обнаруживались при старте, а не в продакшене
|
|
66
|
+
• вы используете TypeScript и вам важны корректные типы
|
|
67
|
+
• вы хотите получать .env.example и документацию из единого источника правды
|
|
68
|
+
• вы хотите, чтобы CI ловил отсутствующие или лишние переменные
|
|
71
69
|
|
|
72
|
-
|
|
70
|
+
Когда НЕ использовать
|
|
73
71
|
|
|
74
|
-
Не стоит использовать
|
|
72
|
+
Не стоит использовать zod-envkit, если:
|
|
73
|
+
• ваш проект очень маленький и неформальный
|
|
74
|
+
• вы вообще не контролируете переменные окружения
|
|
75
|
+
• вы ожидаете автоматическую интроспекцию схем или “магическое” поведение
|
|
75
76
|
|
|
76
|
-
|
|
77
|
-
- вы не контролируете переменные окружения
|
|
78
|
-
- вы ожидаете “магическую” автогенерацию схем
|
|
77
|
+
⸻
|
|
79
78
|
|
|
80
|
-
|
|
79
|
+
Установка
|
|
81
80
|
|
|
82
|
-
## Установка
|
|
83
|
-
|
|
84
|
-
```bash
|
|
85
81
|
npm install zod-envkit
|
|
86
|
-
````
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
82
|
yarn add zod-envkit
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
83
|
pnpm add zod-envkit
|
|
94
|
-
|
|
84
|
+
bun add zod-envkit
|
|
95
85
|
|
|
96
|
-
---
|
|
97
86
|
|
|
98
|
-
|
|
87
|
+
⸻
|
|
88
|
+
|
|
89
|
+
Использование библиотеки (runtime-валидация)
|
|
99
90
|
|
|
100
91
|
Создайте один файл, отвечающий за загрузку и валидацию env.
|
|
101
92
|
|
|
102
|
-
```ts
|
|
103
93
|
import "dotenv/config";
|
|
104
94
|
import { z } from "zod";
|
|
105
95
|
import { loadEnv, mustLoadEnv, formatZodError } from "zod-envkit";
|
|
@@ -109,11 +99,9 @@ const EnvSchema = z.object({
|
|
|
109
99
|
PORT: z.coerce.number().int().min(1).max(65535),
|
|
110
100
|
DATABASE_URL: z.string().url(),
|
|
111
101
|
});
|
|
112
|
-
```
|
|
113
102
|
|
|
114
|
-
|
|
103
|
+
Безопасный режим (без исключений)
|
|
115
104
|
|
|
116
|
-
```ts
|
|
117
105
|
const result = loadEnv(EnvSchema);
|
|
118
106
|
|
|
119
107
|
if (!result.ok) {
|
|
@@ -122,37 +110,31 @@ if (!result.ok) {
|
|
|
122
110
|
}
|
|
123
111
|
|
|
124
112
|
export const env = result.env;
|
|
125
|
-
```
|
|
126
113
|
|
|
127
|
-
|
|
114
|
+
Fail-fast режим (рекомендуется)
|
|
128
115
|
|
|
129
|
-
```ts
|
|
130
116
|
export const env = mustLoadEnv(EnvSchema);
|
|
131
|
-
```
|
|
132
117
|
|
|
133
118
|
Теперь:
|
|
119
|
+
• env.PORT — это number
|
|
120
|
+
• env.DATABASE_URL — это string
|
|
121
|
+
• TypeScript знает всё на этапе компиляции
|
|
122
|
+
• приложение падает сразу, если env некорректен
|
|
134
123
|
|
|
135
|
-
|
|
136
|
-
* `env.DATABASE_URL` — это **string**
|
|
137
|
-
* TypeScript всё знает на этапе компиляции
|
|
138
|
-
* приложение падает сразу, если env некорректен
|
|
139
|
-
|
|
140
|
-
---
|
|
124
|
+
⸻
|
|
141
125
|
|
|
142
|
-
|
|
126
|
+
Использование CLI
|
|
143
127
|
|
|
144
|
-
CLI работает на основе мета-файла:
|
|
128
|
+
CLI работает на основе мета-файла: env.meta.json.
|
|
145
129
|
|
|
146
130
|
По умолчанию он ищется в:
|
|
131
|
+
• ./env.meta.json
|
|
132
|
+
• ./examples/env.meta.json
|
|
147
133
|
|
|
148
|
-
|
|
149
|
-
* `./examples/env.meta.json`
|
|
134
|
+
⸻
|
|
150
135
|
|
|
151
|
-
|
|
136
|
+
Пример env.meta.json
|
|
152
137
|
|
|
153
|
-
## Пример `env.meta.json`
|
|
154
|
-
|
|
155
|
-
```json
|
|
156
138
|
{
|
|
157
139
|
"NODE_ENV": {
|
|
158
140
|
"description": "Режим выполнения",
|
|
@@ -170,164 +152,165 @@ CLI работает на основе мета-файла: `env.meta.json`.
|
|
|
170
152
|
"required": true
|
|
171
153
|
}
|
|
172
154
|
}
|
|
173
|
-
```
|
|
174
155
|
|
|
175
|
-
---
|
|
176
156
|
|
|
177
|
-
|
|
157
|
+
⸻
|
|
158
|
+
|
|
159
|
+
Команды CLI
|
|
178
160
|
|
|
179
|
-
|
|
161
|
+
Генерация .env.example и документации
|
|
180
162
|
|
|
181
163
|
(Поведение по умолчанию)
|
|
182
164
|
|
|
183
|
-
```bash
|
|
184
165
|
npx zod-envkit
|
|
185
|
-
```
|
|
186
166
|
|
|
187
167
|
или явно:
|
|
188
168
|
|
|
189
|
-
```bash
|
|
190
169
|
npx zod-envkit generate
|
|
191
|
-
```
|
|
192
170
|
|
|
193
171
|
Генерация документации в разных форматах:
|
|
194
172
|
|
|
195
|
-
```bash
|
|
196
173
|
npx zod-envkit generate --format json
|
|
197
174
|
npx zod-envkit generate --format yaml
|
|
198
|
-
```
|
|
199
175
|
|
|
200
|
-
|
|
176
|
+
Управление сортировкой:
|
|
201
177
|
|
|
202
|
-
```bash
|
|
203
178
|
npx zod-envkit generate --sort alpha
|
|
204
179
|
npx zod-envkit generate --sort required-first
|
|
205
|
-
```
|
|
206
180
|
|
|
207
|
-
---
|
|
208
181
|
|
|
209
|
-
|
|
182
|
+
⸻
|
|
183
|
+
|
|
184
|
+
Просмотр текущего состояния окружения
|
|
210
185
|
|
|
211
186
|
Загружает dotenv-файлы, маскирует секреты и выводит читаемую таблицу.
|
|
212
187
|
|
|
213
|
-
```bash
|
|
214
188
|
npx zod-envkit show
|
|
215
|
-
```
|
|
216
189
|
|
|
217
190
|
Дополнительные опции:
|
|
218
191
|
|
|
219
|
-
```bash
|
|
220
192
|
npx zod-envkit show --mask-mode full
|
|
221
193
|
npx zod-envkit show --no-mask
|
|
222
194
|
npx zod-envkit show --dotenv ".env,.env.local,.env.production"
|
|
223
|
-
```
|
|
224
195
|
|
|
225
|
-
---
|
|
226
196
|
|
|
227
|
-
|
|
197
|
+
⸻
|
|
198
|
+
|
|
199
|
+
Проверка окружения (удобно для CI)
|
|
228
200
|
|
|
229
|
-
```bash
|
|
230
201
|
npx zod-envkit check
|
|
231
|
-
```
|
|
232
202
|
|
|
233
|
-
Строгий
|
|
203
|
+
Строгий режим (падает при неизвестных переменных):
|
|
234
204
|
|
|
235
|
-
```bash
|
|
236
205
|
npx zod-envkit check --strict
|
|
237
|
-
```
|
|
238
206
|
|
|
239
|
-
|
|
240
|
-
|
|
207
|
+
• завершает процесс с кодом 1, если отсутствуют обязательные переменные
|
|
208
|
+
• в --strict режиме также падает при наличии неизвестных переменных
|
|
241
209
|
|
|
242
|
-
|
|
210
|
+
⸻
|
|
243
211
|
|
|
244
|
-
|
|
212
|
+
Инициализация конфигурации
|
|
245
213
|
|
|
246
214
|
Быстрый старт конфигурации из существующих файлов.
|
|
247
215
|
|
|
248
|
-
Сгенерировать
|
|
216
|
+
Сгенерировать env.meta.json из .env.example:
|
|
249
217
|
|
|
250
|
-
```bash
|
|
251
218
|
npx zod-envkit init
|
|
252
|
-
```
|
|
253
219
|
|
|
254
|
-
Сгенерировать
|
|
220
|
+
Сгенерировать .env.example из существующего env.meta.json:
|
|
255
221
|
|
|
256
|
-
```bash
|
|
257
222
|
npx zod-envkit init --from-meta
|
|
258
|
-
```
|
|
259
223
|
|
|
260
|
-
---
|
|
261
224
|
|
|
262
|
-
|
|
225
|
+
⸻
|
|
226
|
+
|
|
227
|
+
Стабильность и версионирование
|
|
263
228
|
|
|
264
|
-
|
|
229
|
+
zod-envkit следует Semantic Versioning.
|
|
265
230
|
|
|
266
|
-
|
|
231
|
+
Стабильность Public API (1.x)
|
|
267
232
|
|
|
268
|
-
|
|
233
|
+
Всё перечисленное ниже считается стабильным public API в рамках всей ветки 1.x.
|
|
269
234
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
235
|
+
Экспорты библиотеки (entrypoint zod-envkit):
|
|
236
|
+
• loadEnv
|
|
237
|
+
• mustLoadEnv
|
|
238
|
+
• formatZodError
|
|
239
|
+
• checkEnv
|
|
240
|
+
• getMissingEnv
|
|
241
|
+
• getUnknownEnv
|
|
242
|
+
• isSecretKey
|
|
243
|
+
• generateEnvExample
|
|
244
|
+
• generateEnvDocs
|
|
245
|
+
• sortMetaEntries
|
|
246
|
+
• связанные публичные типы: EnvMeta, EnvMetaEntry, EnvCheckResult, GenerateDocsOptions, DocsFormat, SortMode
|
|
279
247
|
|
|
280
|
-
|
|
248
|
+
CLI-контракт:
|
|
249
|
+
• команды: generate, show, check, init
|
|
250
|
+
• задокументированные флаги и значения по умолчанию
|
|
251
|
+
• поведение exit-кодов (успех = 0, пользовательская ошибка = 1)
|
|
281
252
|
|
|
282
|
-
|
|
283
|
-
* задокументированные флаги и коды выхода
|
|
253
|
+
Политика breaking-изменений
|
|
284
254
|
|
|
285
|
-
|
|
255
|
+
Breaking change (major) включает:
|
|
256
|
+
• изменение сигнатур или структуры возвращаемых значений стабильных экспортов
|
|
257
|
+
• удаление или переименование public-экспортов
|
|
258
|
+
• удаление или переименование CLI-команд или флагов
|
|
259
|
+
• изменение поведения CLI по умолчанию
|
|
260
|
+
• изменение семантики exit-кодов
|
|
261
|
+
• изменение контрактов формата вывода, ломающих существующие инструменты
|
|
286
262
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
263
|
+
Не считается breaking (minor/patch):
|
|
264
|
+
• добавление новых экспортов (обратно совместимых)
|
|
265
|
+
• добавление новых CLI-флагов (обратно совместимых)
|
|
266
|
+
• добавление новых опциональных полей в env.meta.json
|
|
267
|
+
• улучшение сообщений об ошибках или форматирования документации без нарушения совместимости
|
|
292
268
|
|
|
293
|
-
|
|
269
|
+
⸻
|
|
294
270
|
|
|
295
|
-
|
|
296
|
-
* добавление новых флагов
|
|
297
|
-
* улучшение форматирования и сообщений об ошибках
|
|
271
|
+
Что нового в 1.2.0
|
|
298
272
|
|
|
299
|
-
|
|
273
|
+
Версия 1.2.0 сосредоточена на надёжности, контрактности и готовности к CI.
|
|
300
274
|
|
|
301
|
-
|
|
275
|
+
Основные изменения:
|
|
276
|
+
• усилено поведение строгого режима (check --strict) для CI
|
|
277
|
+
• детерминированная обработка приоритета dotenv-файлов
|
|
278
|
+
• улучшены гарантии маскирования секретов в show
|
|
279
|
+
• расширен preprod-набор тестов (smoke, contract, CLI E2E, robustness)
|
|
280
|
+
• CI-pipeline принудительно выполняет: build → tests → docs build
|
|
302
281
|
|
|
303
|
-
|
|
282
|
+
С этого момента zod-envkit — это не просто “утилита”, а
|
|
283
|
+
стабильный инструмент контрактов окружения для CI/CD-пайплайнов.
|
|
304
284
|
|
|
305
|
-
|
|
306
|
-
* ❌ нет типов
|
|
307
|
-
* ❌ нет документации
|
|
308
|
-
* ❌ нет проверок для CI
|
|
285
|
+
⸻
|
|
309
286
|
|
|
310
|
-
|
|
287
|
+
Почему не просто dotenv?
|
|
311
288
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
289
|
+
dotenv:
|
|
290
|
+
• ❌ нет валидации
|
|
291
|
+
• ❌ нет типов
|
|
292
|
+
• ❌ нет документации
|
|
293
|
+
• ❌ нет проверок для CI
|
|
316
294
|
|
|
317
|
-
|
|
295
|
+
zod-envkit:
|
|
296
|
+
• ✅ валидация
|
|
297
|
+
• ✅ вывод типов для TypeScript
|
|
298
|
+
• ✅ документация
|
|
299
|
+
• ✅ CLI-инструменты
|
|
318
300
|
|
|
319
|
-
|
|
301
|
+
Они предназначены для использования вместе.
|
|
320
302
|
|
|
321
|
-
|
|
303
|
+
⸻
|
|
322
304
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
305
|
+
Принципы дизайна
|
|
306
|
+
• явная конфигурация вместо магии
|
|
307
|
+
• отсутствие привязки к фреймворкам
|
|
308
|
+
• маленький и предсказуемый API
|
|
309
|
+
• библиотека и CLI независимы, но дополняют друг друга
|
|
310
|
+
• переменные окружения — это runtime-контракт
|
|
328
311
|
|
|
329
|
-
|
|
312
|
+
⸻
|
|
330
313
|
|
|
331
|
-
|
|
314
|
+
Лицензия
|
|
332
315
|
|
|
333
316
|
MIT
|
package/README.md
CHANGED
|
@@ -83,16 +83,10 @@ Skip **zod-envkit** if:
|
|
|
83
83
|
|
|
84
84
|
```bash
|
|
85
85
|
npm install zod-envkit
|
|
86
|
-
````
|
|
87
|
-
|
|
88
|
-
```bash
|
|
89
86
|
yarn add zod-envkit
|
|
90
|
-
```
|
|
91
|
-
|
|
92
|
-
```bash
|
|
93
87
|
pnpm add zod-envkit
|
|
88
|
+
bun add zod-envkit
|
|
94
89
|
```
|
|
95
|
-
|
|
96
90
|
---
|
|
97
91
|
|
|
98
92
|
## Library usage (runtime validation)
|
|
@@ -263,38 +257,62 @@ npx zod-envkit init --from-meta
|
|
|
263
257
|
|
|
264
258
|
`zod-envkit` follows **Semantic Versioning**.
|
|
265
259
|
|
|
266
|
-
###
|
|
260
|
+
### Public API stability (1.x)
|
|
261
|
+
|
|
262
|
+
Everything listed below is treated as **stable public API** for the whole 1.x line.
|
|
263
|
+
|
|
264
|
+
**Library exports (entrypoint `zod-envkit`):**
|
|
265
|
+
|
|
266
|
+
- `loadEnv`
|
|
267
|
+
- `mustLoadEnv`
|
|
268
|
+
- `formatZodError`
|
|
269
|
+
- `checkEnv`
|
|
270
|
+
- `getMissingEnv`
|
|
271
|
+
- `getUnknownEnv`
|
|
272
|
+
- `isSecretKey`
|
|
273
|
+
- `generateEnvExample`
|
|
274
|
+
- `generateEnvDocs`
|
|
275
|
+
- `sortMetaEntries`
|
|
276
|
+
- related public types: `EnvMeta`, `EnvMetaEntry`, `EnvCheckResult`, `GenerateDocsOptions`, `DocsFormat`, `SortMode`
|
|
277
|
+
|
|
278
|
+
**CLI contract:**
|
|
279
|
+
|
|
280
|
+
- commands: `generate`, `show`, `check`, `init`
|
|
281
|
+
- documented flags and defaults
|
|
282
|
+
- exit code behavior (success = `0`, user error = `1`)
|
|
283
|
+
|
|
284
|
+
### Breaking change policy
|
|
285
|
+
|
|
286
|
+
A **breaking** change (major) includes:
|
|
267
287
|
|
|
268
|
-
|
|
288
|
+
- changing signatures or return shapes of the stable exports
|
|
289
|
+
- removing/renaming public exports
|
|
290
|
+
- removing/renaming CLI commands or flags
|
|
291
|
+
- changing CLI default behavior (e.g. what `zod-envkit` does with no args)
|
|
292
|
+
- changing exit code semantics
|
|
293
|
+
- changing output format contracts in a way that breaks existing tooling
|
|
269
294
|
|
|
270
|
-
|
|
271
|
-
* `mustLoadEnv`
|
|
272
|
-
* `formatZodError`
|
|
273
|
-
* `checkEnv`
|
|
274
|
-
* `getMissingEnv`
|
|
275
|
-
* `getUnknownEnv`
|
|
276
|
-
* `isSecretKey`
|
|
277
|
-
* `generateEnvExample`
|
|
278
|
-
* `generateEnvDocs`
|
|
295
|
+
A **non-breaking** change (minor/patch) includes:
|
|
279
296
|
|
|
280
|
-
|
|
297
|
+
- adding new exports (backwards compatible)
|
|
298
|
+
- adding new CLI flags (backwards compatible)
|
|
299
|
+
- adding new optional fields to `env.meta.json`
|
|
300
|
+
- improving error messages or docs output while keeping it valid
|
|
281
301
|
|
|
282
|
-
|
|
283
|
-
* documented flags and exit codes
|
|
302
|
+
### What’s new in 1.2.0
|
|
284
303
|
|
|
285
|
-
|
|
304
|
+
Version **1.2.0** focuses on reliability, contract enforcement, and CI readiness.
|
|
286
305
|
|
|
287
|
-
|
|
288
|
-
* removing or renaming public exports
|
|
289
|
-
* removing or renaming CLI commands or flags
|
|
290
|
-
* changing exit code semantics
|
|
291
|
-
* changing default CLI behavior
|
|
306
|
+
Highlights:
|
|
292
307
|
|
|
293
|
-
|
|
308
|
+
- hardened strict mode behavior (`check --strict`) for CI usage
|
|
309
|
+
- deterministic dotenv priority handling
|
|
310
|
+
- improved secret masking guarantees in `show`
|
|
311
|
+
- expanded preprod test suite (smoke, contract, CLI E2E, robustness)
|
|
312
|
+
- CI pipeline enforces: build → tests → docs build
|
|
294
313
|
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
* improving error messages or formatting
|
|
314
|
+
This is the point where `zod-envkit` stops being “just a helper” and becomes a
|
|
315
|
+
**stable environment contract tool for CI/CD pipelines**.
|
|
298
316
|
|
|
299
317
|
---
|
|
300
318
|
|
|
@@ -302,17 +320,17 @@ Non-breaking:
|
|
|
302
320
|
|
|
303
321
|
`dotenv`:
|
|
304
322
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
323
|
+
- ❌ no validation
|
|
324
|
+
- ❌ no types
|
|
325
|
+
- ❌ no documentation
|
|
326
|
+
- ❌ no CI checks
|
|
309
327
|
|
|
310
328
|
`zod-envkit`:
|
|
311
329
|
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
330
|
+
- ✅ validation
|
|
331
|
+
- ✅ TypeScript inference
|
|
332
|
+
- ✅ documentation
|
|
333
|
+
- ✅ CLI tooling
|
|
316
334
|
|
|
317
335
|
They are designed to be used **together**.
|
|
318
336
|
|
|
@@ -320,11 +338,11 @@ They are designed to be used **together**.
|
|
|
320
338
|
|
|
321
339
|
## Design principles
|
|
322
340
|
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
341
|
+
- explicit configuration over magic
|
|
342
|
+
- no framework coupling
|
|
343
|
+
- small and predictable API
|
|
344
|
+
- library and CLI are independent but complementary
|
|
345
|
+
- environment variables are a runtime contract
|
|
328
346
|
|
|
329
347
|
---
|
|
330
348
|
|
package/dist/cli/index.cjs
CHANGED
|
@@ -77,9 +77,16 @@ function t(lang, key, vars) {
|
|
|
77
77
|
|
|
78
78
|
// src/cli/lib/argv.ts
|
|
79
79
|
function injectDefaultCommandIfMissing(argv, opts) {
|
|
80
|
+
if (argv.length <= 2) {
|
|
81
|
+
argv.splice(2, 0, opts.defaultCommand);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
80
84
|
const args = argv.slice(2);
|
|
81
85
|
const hasKnownToken = args.some((a) => opts.known.has(a));
|
|
82
|
-
|
|
86
|
+
const alreadyInjected = args[0] === opts.defaultCommand;
|
|
87
|
+
if (!hasKnownToken && !alreadyInjected) {
|
|
88
|
+
argv.splice(2, 0, opts.defaultCommand);
|
|
89
|
+
}
|
|
83
90
|
}
|
|
84
91
|
|
|
85
92
|
// src/cli/commands/generate.ts
|
|
@@ -409,36 +416,54 @@ function maskValue(key, value, mode) {
|
|
|
409
416
|
}
|
|
410
417
|
|
|
411
418
|
// src/cli/lib/table.ts
|
|
419
|
+
function strLen2(s) {
|
|
420
|
+
return (s ?? "").length;
|
|
421
|
+
}
|
|
412
422
|
function padCenter2(text, width) {
|
|
413
423
|
const v = text ?? "";
|
|
414
|
-
const diff = width - v
|
|
424
|
+
const diff = width - strLen2(v);
|
|
415
425
|
if (diff <= 0) return v;
|
|
416
426
|
const left = Math.floor(diff / 2);
|
|
417
427
|
const right = diff - left;
|
|
418
428
|
return " ".repeat(left) + v + " ".repeat(right);
|
|
419
429
|
}
|
|
430
|
+
function makeDivider2(width, align) {
|
|
431
|
+
const w = Math.max(3, width);
|
|
432
|
+
if (align === "center") return ":" + "-".repeat(w - 2) + ":";
|
|
433
|
+
if (align === "right") return "-".repeat(w - 1) + ":";
|
|
434
|
+
return "-".repeat(w);
|
|
435
|
+
}
|
|
420
436
|
function printMarkdownTable(rows, headers) {
|
|
437
|
+
if (headers.length === 0) return;
|
|
421
438
|
const widths = {};
|
|
422
|
-
for (const h of headers) widths[h] = h
|
|
439
|
+
for (const h of headers) widths[h] = strLen2(h);
|
|
423
440
|
for (const row of rows) {
|
|
424
|
-
for (const h of headers)
|
|
441
|
+
for (const h of headers) {
|
|
442
|
+
widths[h] = Math.max(widths[h], strLen2(row[h] ?? ""));
|
|
443
|
+
}
|
|
425
444
|
}
|
|
426
445
|
for (const h of headers) widths[h] += 2;
|
|
427
|
-
const headerLine = "|" + headers.map((h) =>
|
|
428
|
-
const sepLine = "|" + headers.map((h) =>
|
|
446
|
+
const headerLine = "|" + headers.map((h) => ` ${padCenter2(h, widths[h])} `).join("|") + "|";
|
|
447
|
+
const sepLine = "|" + headers.map((h) => ` ${makeDivider2(widths[h], "center")} `).join("|") + "|";
|
|
429
448
|
console.log(headerLine);
|
|
430
449
|
console.log(sepLine);
|
|
431
450
|
for (const row of rows) {
|
|
432
|
-
console.log(
|
|
451
|
+
console.log(
|
|
452
|
+
"|" + headers.map((h) => ` ${padCenter2(row[h] ?? "", widths[h])} `).join("|") + "|"
|
|
453
|
+
);
|
|
433
454
|
}
|
|
434
455
|
}
|
|
435
456
|
|
|
436
457
|
// src/cli/lib/sort.ts
|
|
437
458
|
function sortKeys(meta, sort) {
|
|
438
459
|
const keys = Object.keys(meta);
|
|
439
|
-
if (sort === "none")
|
|
440
|
-
|
|
441
|
-
|
|
460
|
+
if (sort === "none") {
|
|
461
|
+
return [...keys];
|
|
462
|
+
}
|
|
463
|
+
if (sort === "alpha") {
|
|
464
|
+
return [...keys].sort((a, b) => a.localeCompare(b));
|
|
465
|
+
}
|
|
466
|
+
return [...keys].sort((a, b) => {
|
|
442
467
|
const ar = meta[a]?.required === false ? 1 : 0;
|
|
443
468
|
const br = meta[b]?.required === false ? 1 : 0;
|
|
444
469
|
if (ar !== br) return ar - br;
|
|
@@ -457,7 +482,7 @@ function registerShow(program2, getLang2) {
|
|
|
457
482
|
program2.command("show").description("Show current env status (loads dotenv, masks secrets)").option("-c, --config <file>", "Path to env meta json", "env.meta.json").option("--dotenv <list>", "Comma-separated dotenv files (default: .env)", ".env").option("--mask-mode <mode>", "Mask mode (partial | full | none)", "partial").option("--no-mask", "Alias for --mask-mode none").option("--sort <mode>", "Sort mode (alpha | required-first | none)", "none").action((opts) => {
|
|
458
483
|
const lang = getLang2();
|
|
459
484
|
loadDotEnv(String(opts.dotenv ?? ".env"));
|
|
460
|
-
const { meta } = loadMeta(lang, opts.config);
|
|
485
|
+
const { meta } = loadMeta(lang, String(opts.config ?? "env.meta.json"));
|
|
461
486
|
const fallbackMode = opts.mask === false ? "none" : "partial";
|
|
462
487
|
const modeRaw = String(opts.maskMode ?? fallbackMode);
|
|
463
488
|
if (!isMaskMode(modeRaw)) {
|
|
@@ -499,16 +524,12 @@ function registerCheck(program2, getLang2) {
|
|
|
499
524
|
const { meta } = loadMeta(lang, opts.config);
|
|
500
525
|
const missing = getMissingEnv(meta, process.env);
|
|
501
526
|
if (missing.length) {
|
|
502
|
-
|
|
503
|
-
for (const k of missing) console.error(`- ${k}`);
|
|
504
|
-
process.exit(1);
|
|
527
|
+
fail(lang, "MISSING_ENV", missing.map((k) => `- ${k}`));
|
|
505
528
|
}
|
|
506
529
|
if (opts.strict) {
|
|
507
530
|
const unknown = getUnknownEnv(meta, loaded.env);
|
|
508
531
|
if (unknown.length) {
|
|
509
|
-
|
|
510
|
-
for (const k of unknown) console.error(`- ${k}`);
|
|
511
|
-
process.exit(1);
|
|
532
|
+
fail(lang, "UNKNOWN_ENV", unknown.map((k) => `- ${k}`));
|
|
512
533
|
}
|
|
513
534
|
}
|
|
514
535
|
console.log(`\u2705 ${t(lang, "ENV_OK")}`);
|
|
@@ -552,7 +573,7 @@ function registerInit(program2, getLang2) {
|
|
|
552
573
|
}
|
|
553
574
|
const env = readEnvFile(input);
|
|
554
575
|
if (Object.keys(env).length === 0) {
|
|
555
|
-
fail(lang, "
|
|
576
|
+
fail(lang, "INIT_INPUT_EMPTY", [`- ${input}`]);
|
|
556
577
|
}
|
|
557
578
|
const meta = metaFromEnv(env, opts.group ? String(opts.group) : void 0);
|
|
558
579
|
import_node_fs4.default.writeFileSync(output, JSON.stringify(meta, null, 2) + "\n", "utf8");
|
package/dist/cli/index.js
CHANGED
|
@@ -61,9 +61,16 @@ function t(lang, key, vars) {
|
|
|
61
61
|
|
|
62
62
|
// src/cli/lib/argv.ts
|
|
63
63
|
function injectDefaultCommandIfMissing(argv, opts) {
|
|
64
|
+
if (argv.length <= 2) {
|
|
65
|
+
argv.splice(2, 0, opts.defaultCommand);
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
64
68
|
const args = argv.slice(2);
|
|
65
69
|
const hasKnownToken = args.some((a) => opts.known.has(a));
|
|
66
|
-
|
|
70
|
+
const alreadyInjected = args[0] === opts.defaultCommand;
|
|
71
|
+
if (!hasKnownToken && !alreadyInjected) {
|
|
72
|
+
argv.splice(2, 0, opts.defaultCommand);
|
|
73
|
+
}
|
|
67
74
|
}
|
|
68
75
|
|
|
69
76
|
// src/cli/commands/generate.ts
|
|
@@ -197,36 +204,54 @@ function maskValue(key, value, mode) {
|
|
|
197
204
|
}
|
|
198
205
|
|
|
199
206
|
// src/cli/lib/table.ts
|
|
207
|
+
function strLen(s) {
|
|
208
|
+
return (s ?? "").length;
|
|
209
|
+
}
|
|
200
210
|
function padCenter(text, width) {
|
|
201
211
|
const v = text ?? "";
|
|
202
|
-
const diff = width - v
|
|
212
|
+
const diff = width - strLen(v);
|
|
203
213
|
if (diff <= 0) return v;
|
|
204
214
|
const left = Math.floor(diff / 2);
|
|
205
215
|
const right = diff - left;
|
|
206
216
|
return " ".repeat(left) + v + " ".repeat(right);
|
|
207
217
|
}
|
|
218
|
+
function makeDivider(width, align) {
|
|
219
|
+
const w = Math.max(3, width);
|
|
220
|
+
if (align === "center") return ":" + "-".repeat(w - 2) + ":";
|
|
221
|
+
if (align === "right") return "-".repeat(w - 1) + ":";
|
|
222
|
+
return "-".repeat(w);
|
|
223
|
+
}
|
|
208
224
|
function printMarkdownTable(rows, headers) {
|
|
225
|
+
if (headers.length === 0) return;
|
|
209
226
|
const widths = {};
|
|
210
|
-
for (const h of headers) widths[h] = h
|
|
227
|
+
for (const h of headers) widths[h] = strLen(h);
|
|
211
228
|
for (const row of rows) {
|
|
212
|
-
for (const h of headers)
|
|
229
|
+
for (const h of headers) {
|
|
230
|
+
widths[h] = Math.max(widths[h], strLen(row[h] ?? ""));
|
|
231
|
+
}
|
|
213
232
|
}
|
|
214
233
|
for (const h of headers) widths[h] += 2;
|
|
215
|
-
const headerLine = "|" + headers.map((h) =>
|
|
216
|
-
const sepLine = "|" + headers.map((h) =>
|
|
234
|
+
const headerLine = "|" + headers.map((h) => ` ${padCenter(h, widths[h])} `).join("|") + "|";
|
|
235
|
+
const sepLine = "|" + headers.map((h) => ` ${makeDivider(widths[h], "center")} `).join("|") + "|";
|
|
217
236
|
console.log(headerLine);
|
|
218
237
|
console.log(sepLine);
|
|
219
238
|
for (const row of rows) {
|
|
220
|
-
console.log(
|
|
239
|
+
console.log(
|
|
240
|
+
"|" + headers.map((h) => ` ${padCenter(row[h] ?? "", widths[h])} `).join("|") + "|"
|
|
241
|
+
);
|
|
221
242
|
}
|
|
222
243
|
}
|
|
223
244
|
|
|
224
245
|
// src/cli/lib/sort.ts
|
|
225
246
|
function sortKeys(meta, sort) {
|
|
226
247
|
const keys = Object.keys(meta);
|
|
227
|
-
if (sort === "none")
|
|
228
|
-
|
|
229
|
-
|
|
248
|
+
if (sort === "none") {
|
|
249
|
+
return [...keys];
|
|
250
|
+
}
|
|
251
|
+
if (sort === "alpha") {
|
|
252
|
+
return [...keys].sort((a, b) => a.localeCompare(b));
|
|
253
|
+
}
|
|
254
|
+
return [...keys].sort((a, b) => {
|
|
230
255
|
const ar = meta[a]?.required === false ? 1 : 0;
|
|
231
256
|
const br = meta[b]?.required === false ? 1 : 0;
|
|
232
257
|
if (ar !== br) return ar - br;
|
|
@@ -245,7 +270,7 @@ function registerShow(program2, getLang2) {
|
|
|
245
270
|
program2.command("show").description("Show current env status (loads dotenv, masks secrets)").option("-c, --config <file>", "Path to env meta json", "env.meta.json").option("--dotenv <list>", "Comma-separated dotenv files (default: .env)", ".env").option("--mask-mode <mode>", "Mask mode (partial | full | none)", "partial").option("--no-mask", "Alias for --mask-mode none").option("--sort <mode>", "Sort mode (alpha | required-first | none)", "none").action((opts) => {
|
|
246
271
|
const lang = getLang2();
|
|
247
272
|
loadDotEnv(String(opts.dotenv ?? ".env"));
|
|
248
|
-
const { meta } = loadMeta(lang, opts.config);
|
|
273
|
+
const { meta } = loadMeta(lang, String(opts.config ?? "env.meta.json"));
|
|
249
274
|
const fallbackMode = opts.mask === false ? "none" : "partial";
|
|
250
275
|
const modeRaw = String(opts.maskMode ?? fallbackMode);
|
|
251
276
|
if (!isMaskMode(modeRaw)) {
|
|
@@ -287,16 +312,12 @@ function registerCheck(program2, getLang2) {
|
|
|
287
312
|
const { meta } = loadMeta(lang, opts.config);
|
|
288
313
|
const missing = getMissingEnv(meta, process.env);
|
|
289
314
|
if (missing.length) {
|
|
290
|
-
|
|
291
|
-
for (const k of missing) console.error(`- ${k}`);
|
|
292
|
-
process.exit(1);
|
|
315
|
+
fail(lang, "MISSING_ENV", missing.map((k) => `- ${k}`));
|
|
293
316
|
}
|
|
294
317
|
if (opts.strict) {
|
|
295
318
|
const unknown = getUnknownEnv(meta, loaded.env);
|
|
296
319
|
if (unknown.length) {
|
|
297
|
-
|
|
298
|
-
for (const k of unknown) console.error(`- ${k}`);
|
|
299
|
-
process.exit(1);
|
|
320
|
+
fail(lang, "UNKNOWN_ENV", unknown.map((k) => `- ${k}`));
|
|
300
321
|
}
|
|
301
322
|
}
|
|
302
323
|
console.log(`\u2705 ${t(lang, "ENV_OK")}`);
|
|
@@ -340,7 +361,7 @@ function registerInit(program2, getLang2) {
|
|
|
340
361
|
}
|
|
341
362
|
const env = readEnvFile(input);
|
|
342
363
|
if (Object.keys(env).length === 0) {
|
|
343
|
-
fail(lang, "
|
|
364
|
+
fail(lang, "INIT_INPUT_EMPTY", [`- ${input}`]);
|
|
344
365
|
}
|
|
345
366
|
const meta = metaFromEnv(env, opts.group ? String(opts.group) : void 0);
|
|
346
367
|
fs4.writeFileSync(output, JSON.stringify(meta, null, 2) + "\n", "utf8");
|
package/dist/index.d.cts
CHANGED
|
@@ -149,7 +149,7 @@ declare function generateEnvDocs(meta: EnvMeta, opts?: GenerateDocsOptions): str
|
|
|
149
149
|
* - `unknown`: keys present in env but not described in meta
|
|
150
150
|
*
|
|
151
151
|
* @public
|
|
152
|
-
* @since 1.
|
|
152
|
+
* @since 1.2.0
|
|
153
153
|
*/
|
|
154
154
|
type EnvCheckResult = {
|
|
155
155
|
ok: boolean;
|
|
@@ -160,7 +160,7 @@ type EnvCheckResult = {
|
|
|
160
160
|
* Return required keys from `meta` that are missing (or empty) in `env`.
|
|
161
161
|
*
|
|
162
162
|
* @public
|
|
163
|
-
* @since 1.
|
|
163
|
+
* @since 1.2.0
|
|
164
164
|
*/
|
|
165
165
|
declare function getMissingEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[];
|
|
166
166
|
/**
|
|
@@ -169,7 +169,7 @@ declare function getMissingEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[]
|
|
|
169
169
|
* Note: the result is returned in stable alphabetical order.
|
|
170
170
|
*
|
|
171
171
|
* @public
|
|
172
|
-
* @since 1.
|
|
172
|
+
* @since 1.2.0
|
|
173
173
|
*/
|
|
174
174
|
declare function getUnknownEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[];
|
|
175
175
|
/**
|
|
@@ -178,7 +178,7 @@ declare function getUnknownEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[]
|
|
|
178
178
|
* Used by the CLI to mask values (TOKEN/SECRET/PASSWORD/*_KEY/PRIVATE).
|
|
179
179
|
*
|
|
180
180
|
* @public
|
|
181
|
-
* @since 1.
|
|
181
|
+
* @since 1.2.0
|
|
182
182
|
*/
|
|
183
183
|
declare function isSecretKey(key: string): boolean;
|
|
184
184
|
/**
|
|
@@ -188,12 +188,14 @@ declare function isSecretKey(key: string): boolean;
|
|
|
188
188
|
*
|
|
189
189
|
* Note: `ok` here means:
|
|
190
190
|
* - no missing required vars
|
|
191
|
-
* - no unknown vars
|
|
191
|
+
* - no unknown vars
|
|
192
|
+
*
|
|
193
|
+
* The CLI may choose to ignore `unknown` unless `--strict` is enabled.
|
|
192
194
|
*
|
|
193
195
|
* If you want "missing only" checks, use {@link getMissingEnv}.
|
|
194
196
|
*
|
|
195
197
|
* @public
|
|
196
|
-
* @since 1.
|
|
198
|
+
* @since 1.2.0
|
|
197
199
|
*/
|
|
198
200
|
declare function checkEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): EnvCheckResult;
|
|
199
201
|
|
package/dist/index.d.ts
CHANGED
|
@@ -149,7 +149,7 @@ declare function generateEnvDocs(meta: EnvMeta, opts?: GenerateDocsOptions): str
|
|
|
149
149
|
* - `unknown`: keys present in env but not described in meta
|
|
150
150
|
*
|
|
151
151
|
* @public
|
|
152
|
-
* @since 1.
|
|
152
|
+
* @since 1.2.0
|
|
153
153
|
*/
|
|
154
154
|
type EnvCheckResult = {
|
|
155
155
|
ok: boolean;
|
|
@@ -160,7 +160,7 @@ type EnvCheckResult = {
|
|
|
160
160
|
* Return required keys from `meta` that are missing (or empty) in `env`.
|
|
161
161
|
*
|
|
162
162
|
* @public
|
|
163
|
-
* @since 1.
|
|
163
|
+
* @since 1.2.0
|
|
164
164
|
*/
|
|
165
165
|
declare function getMissingEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[];
|
|
166
166
|
/**
|
|
@@ -169,7 +169,7 @@ declare function getMissingEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[]
|
|
|
169
169
|
* Note: the result is returned in stable alphabetical order.
|
|
170
170
|
*
|
|
171
171
|
* @public
|
|
172
|
-
* @since 1.
|
|
172
|
+
* @since 1.2.0
|
|
173
173
|
*/
|
|
174
174
|
declare function getUnknownEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[];
|
|
175
175
|
/**
|
|
@@ -178,7 +178,7 @@ declare function getUnknownEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): string[]
|
|
|
178
178
|
* Used by the CLI to mask values (TOKEN/SECRET/PASSWORD/*_KEY/PRIVATE).
|
|
179
179
|
*
|
|
180
180
|
* @public
|
|
181
|
-
* @since 1.
|
|
181
|
+
* @since 1.2.0
|
|
182
182
|
*/
|
|
183
183
|
declare function isSecretKey(key: string): boolean;
|
|
184
184
|
/**
|
|
@@ -188,12 +188,14 @@ declare function isSecretKey(key: string): boolean;
|
|
|
188
188
|
*
|
|
189
189
|
* Note: `ok` here means:
|
|
190
190
|
* - no missing required vars
|
|
191
|
-
* - no unknown vars
|
|
191
|
+
* - no unknown vars
|
|
192
|
+
*
|
|
193
|
+
* The CLI may choose to ignore `unknown` unless `--strict` is enabled.
|
|
192
194
|
*
|
|
193
195
|
* If you want "missing only" checks, use {@link getMissingEnv}.
|
|
194
196
|
*
|
|
195
197
|
* @public
|
|
196
|
-
* @since 1.
|
|
198
|
+
* @since 1.2.0
|
|
197
199
|
*/
|
|
198
200
|
declare function checkEnv(meta: EnvMeta, env?: NodeJS.ProcessEnv): EnvCheckResult;
|
|
199
201
|
|