zod-envkit 1.3.2 → 1.3.4

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 CHANGED
@@ -1,23 +1,45 @@
1
- ## [1.3.2](https://github.com/nxtxe/zod-envkit/compare/v1.3.1...v1.3.2) (2026-03-23)
1
+ ## [1.3.4](https://github.com/nxtxe/zod-envkit/compare/v1.3.3...v1.3.4) (2026-04-20)
2
2
 
3
3
 
4
4
  ### Bug Fixes
5
5
 
6
- * handle meta fallback edge case ([f54596e](https://github.com/nxtxe/zod-envkit/commit/f54596e9835f47076c079029f2c926228329d990))
6
+ * **cli:** harden 1.3.4 output stability and edge robustness ([e3f52d7](https://github.com/nxtxe/zod-envkit/commit/e3f52d78917f726f08f7213fd31c00a52ca39deb))
7
+
8
+ ## [1.3.4](https://github.com/nxtxe/zod-envkit/compare/v1.3.3...v1.3.4) (2026-03-xx)
9
+
10
+
11
+ ### Bug Fixes
12
+
13
+ * deterministic output polish:
14
+ * lock stable ordering and formatting of grouped `check --strict` errors across repeated runs
15
+ * masking edge hardening:
16
+ * add coverage for short secret values (`1-2` chars) in `partial/full` modes
17
+ * keep case-insensitive secret detection stable (`Api_Key`, `my_password`)
18
+ * dotenv parsing robustness:
19
+ * add coverage for BOM, trailing spaces, and duplicate keys with deterministic override behavior
20
+ * fallback clarity hardening:
21
+ * extend tests for empty/comment-only `.env.example` fallback path
22
+ * CLI smoke hardening:
23
+ * repeated `--help`, `--version`, `show`, and `check` invocations across locales
24
+ * docs consistency patch:
25
+ * keep EN/RU CLI contract sections aligned (no behavior changes)
7
26
 
8
- ## [1.3.2](https://github.com/nxtxe/zod-envkit/compare/v1.3.1...v1.3.2) (2026-03-xx)
27
+ ## [1.3.3](https://github.com/nxtxe/zod-envkit/compare/v1.3.2...v1.3.3) (2026-03-xx)
9
28
 
10
29
 
11
30
  ### Bug Fixes
12
31
 
13
- * edge hardening for meta fallback:
14
- * fail with actionable guidance when `.env.example` exists but has no parseable variables
15
- * keep fallback behavior for valid `.env.example` (minimal meta generation)
16
- * improve robustness coverage for edge paths:
17
- * invalid JSON meta
18
- * missing meta + fallback behavior
19
- * strict dotenv-only checks
20
- * repeated runs/idempotency scenarios
32
+ * output stability lock for CLI contract:
33
+ * harden tests that lock `--help` command list, `--version` behavior, and exit-code semantics
34
+ * lock stable `show` table headers (`Key`, `Required`, `Present`, `Value`, `Description`)
35
+ * document CLI stability policy in docs (EN + RU) without changing runtime behavior
36
+
37
+ ## [1.3.2](https://github.com/nxtxe/zod-envkit/compare/v1.3.1...v1.3.2) (2026-03-23)
38
+
39
+
40
+ ### Bug Fixes
41
+
42
+ * handle meta fallback edge case ([f54596e](https://github.com/nxtxe/zod-envkit/commit/f54596e9835f47076c079029f2c926228329d990))
21
43
 
22
44
  ## [1.3.1](https://github.com/nxtxe/zod-envkit/compare/v1.3.0...v1.3.1) (2026-03-19)
23
45
 
package/README.RU.md CHANGED
@@ -24,72 +24,79 @@
24
24
  </div>
25
25
 
26
26
 
27
- Типобезопасная валидация и документация переменных окружения с помощью Zod.
28
-
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* файлов с приоритетом
27
+ Типобезопасная валидация переменных окружения и документация с помощью **Zod**.
28
+
29
+ **zod-envkit**небольшая и явная библиотека + CLI, которая рассматривает переменные окружения как
30
+ **runtime-контракт**, а не как неявную игру в угадайку.
31
+
32
+ - валидация `process.env` при старте приложения
33
+ - полностью типизированные переменные окружения
34
+ - генерация `.env.example`
35
+ - генерация документации (`ENV.md`, `ENV.json`, `ENV.yaml`)
36
+ - просмотр состояния env через CLI (с маскированием секретов)
37
+ - строгая валидация env в CI/CD
38
+ - инициализация конфигурации через `zod-envkit init`
39
+ - загрузка нескольких `.env*` файлов с приоритетом
39
40
 
40
41
  Никакого облака. Никакой магии. Только код.
41
42
 
42
-
43
+ ---
43
44
 
44
- Зачем
45
+ ## Зачем
45
46
 
46
47
  Переменные окружения критичны, но обычно обрабатываются неправильно.
47
48
 
48
49
  Типичные проблемы:
49
- • process.env — это просто string | undefined
50
- • отсутствующие или некорректные переменные ломают приложение во время выполнения
51
- • .env.example и документация рассинхронизируются
52
- • CI/CD падает поздно и непредсказуемо
53
50
 
54
- zod-envkit решает это, делая env:
55
- • валидируемым на раннем этапе
56
- • типизированным
57
- • документированным
58
- • проверяемым в CI
51
+ - `process.env` это просто `string | undefined`
52
+ - отсутствующие или некорректные переменные ломают приложение во время выполнения
53
+ - `.env.example` и документация рассинхронизируются
54
+ - CI/CD падает поздно и непредсказуемо
55
+
56
+ **zod-envkit** решает это, делая env:
57
+
58
+ - валидируемым на раннем этапе
59
+ - типизированным
60
+ - документированным
61
+ - проверяемым в CI
62
+
63
+ ---
59
64
 
60
-
65
+ ## Когда использовать
61
66
 
62
- Когда использовать
67
+ Используйте **zod-envkit**, если:
63
68
 
64
- Используйте zod-envkit, если:
65
- вы хотите, чтобы ошибки env обнаруживались при старте, а не в продакшене
66
- вы используете TypeScript и вам важны корректные типы
67
- вы хотите получать .env.example и документацию из единого источника правды
68
- • вы хотите, чтобы CI ловил отсутствующие или лишние переменные
69
+ - вы хотите, чтобы ошибки env обнаруживались при старте, а не в продакшене
70
+ - вы используете TypeScript и вам важны корректные типы
71
+ - вы хотите получать `.env.example` и документацию из единого источника правды
72
+ - вы хотите, чтобы CI ловил отсутствующие и лишние переменные
69
73
 
70
- Когда НЕ использовать
74
+ ## Когда НЕ использовать
71
75
 
72
- Не стоит использовать zod-envkit, если:
73
- • ваш проект очень маленький и неформальный
74
- • вы вообще не контролируете переменные окружения
75
- • вы ожидаете автоматическую интроспекцию схем или “магическое” поведение
76
+ Не стоит использовать **zod-envkit**, если:
76
77
 
77
-
78
+ - ваш проект очень маленький и неформальный
79
+ - вы вообще не контролируете переменные окружения
80
+ - вы ожидаете автоматическую интроспекцию схем или «магическое» поведение
78
81
 
79
- Установка
82
+ ---
80
83
 
84
+ ## Установка
85
+
86
+ ```bash
81
87
  npm install zod-envkit
82
88
  yarn add zod-envkit
83
89
  pnpm add zod-envkit
84
90
  bun add zod-envkit
91
+ ```
85
92
 
93
+ ---
86
94
 
87
-
88
-
89
- Использование библиотеки (runtime-валидация)
95
+ ## Использование библиотеки (runtime-валидация)
90
96
 
91
97
  Создайте один файл, отвечающий за загрузку и валидацию env.
92
98
 
99
+ ```ts
93
100
  import "dotenv/config";
94
101
  import { z } from "zod";
95
102
  import { loadEnv, mustLoadEnv, formatZodError } from "zod-envkit";
@@ -99,9 +106,11 @@ const EnvSchema = z.object({
99
106
  PORT: z.coerce.number().int().min(1).max(65535),
100
107
  DATABASE_URL: z.string().url(),
101
108
  });
109
+ ```
102
110
 
103
- Безопасный режим (без исключений)
111
+ ### Безопасный режим (без исключений)
104
112
 
113
+ ```ts
105
114
  const result = loadEnv(EnvSchema);
106
115
 
107
116
  if (!result.ok) {
@@ -110,31 +119,37 @@ if (!result.ok) {
110
119
  }
111
120
 
112
121
  export const env = result.env;
122
+ ```
113
123
 
114
- Fail-fast режим (рекомендуется)
124
+ ### Fail-fast режим (рекомендуется)
115
125
 
126
+ ```ts
116
127
  export const env = mustLoadEnv(EnvSchema);
128
+ ```
117
129
 
118
130
  Теперь:
119
- • env.PORT — это number
120
- • env.DATABASE_URL — это string
121
- • TypeScript знает всё на этапе компиляции
122
- • приложение падает сразу, если env некорректен
123
131
 
124
-
132
+ - `env.PORT` — это **number**
133
+ - `env.DATABASE_URL` — это **string**
134
+ - TypeScript знает всё на этапе компиляции
135
+ - приложение падает сразу, если env некорректен
125
136
 
126
- Использование CLI
137
+ ---
127
138
 
128
- CLI работает на основе мета-файла: env.meta.json.
139
+ ## Использование CLI
140
+
141
+ CLI работает на основе мета-файла: `env.meta.json`.
129
142
 
130
143
  По умолчанию он ищется в:
131
- • ./env.meta.json
132
- • ./examples/env.meta.json
133
144
 
134
-
145
+ - `./env.meta.json`
146
+ - `./examples/env.meta.json`
147
+
148
+ ---
135
149
 
136
- Пример env.meta.json
150
+ ## Пример `env.meta.json`
137
151
 
152
+ ```json
138
153
  {
139
154
  "NODE_ENV": {
140
155
  "description": "Режим выполнения",
@@ -152,165 +167,188 @@ CLI работает на основе мета-файла: env.meta.json.
152
167
  "required": true
153
168
  }
154
169
  }
170
+ ```
155
171
 
172
+ ---
156
173
 
157
-
174
+ ## Команды CLI
158
175
 
159
- Команды CLI
160
-
161
- Генерация .env.example и документации
176
+ ### Генерация `.env.example` и документации
162
177
 
163
178
  (Поведение по умолчанию)
164
179
 
180
+ ```bash
165
181
  npx zod-envkit
182
+ ```
166
183
 
167
184
  или явно:
168
185
 
186
+ ```bash
169
187
  npx zod-envkit generate
188
+ ```
170
189
 
171
190
  Генерация документации в разных форматах:
172
191
 
192
+ ```bash
173
193
  npx zod-envkit generate --format json
174
194
  npx zod-envkit generate --format yaml
195
+ ```
175
196
 
176
197
  Управление сортировкой:
177
198
 
199
+ ```bash
178
200
  npx zod-envkit generate --sort alpha
179
201
  npx zod-envkit generate --sort required-first
202
+ ```
180
203
 
204
+ ---
181
205
 
182
-
183
-
184
- Просмотр текущего состояния окружения
206
+ ### Просмотр текущего состояния окружения
185
207
 
186
208
  Загружает dotenv-файлы, маскирует секреты и выводит читаемую таблицу.
187
209
 
210
+ ```bash
188
211
  npx zod-envkit show
212
+ ```
189
213
 
190
214
  Дополнительные опции:
191
215
 
216
+ ```bash
192
217
  npx zod-envkit show --mask-mode full
193
218
  npx zod-envkit show --no-mask
194
219
  npx zod-envkit show --dotenv ".env,.env.local,.env.production"
220
+ ```
195
221
 
222
+ ---
196
223
 
197
-
198
-
199
- Проверка окружения (удобно для CI)
224
+ ### Проверка окружения (удобно для CI)
200
225
 
226
+ ```bash
201
227
  npx zod-envkit check
228
+ ```
202
229
 
203
230
  Строгий режим (падает при неизвестных переменных):
204
231
 
232
+ ```bash
205
233
  npx zod-envkit check --strict
234
+ ```
206
235
 
207
- завершает процесс с кодом 1, если отсутствуют обязательные переменные
208
- в --strict режиме также падает при наличии неизвестных переменных
236
+ - завершает процесс с кодом `1`, если отсутствуют обязательные переменные
237
+ - в `--strict` режиме также падает при наличии неизвестных переменных
209
238
 
210
-
239
+ ---
211
240
 
212
- Инициализация конфигурации
241
+ ### Инициализация конфигурации
213
242
 
214
243
  Быстрый старт конфигурации из существующих файлов.
215
244
 
216
- Сгенерировать env.meta.json из .env.example:
245
+ Сгенерировать `env.meta.json` из `.env.example`:
217
246
 
247
+ ```bash
218
248
  npx zod-envkit init
249
+ ```
219
250
 
220
- Сгенерировать .env.example из существующего env.meta.json:
251
+ Сгенерировать `.env.example` из существующего `env.meta.json`:
221
252
 
253
+ ```bash
222
254
  npx zod-envkit init --from-meta
255
+ ```
223
256
 
257
+ ---
224
258
 
225
-
259
+ ## Стабильность и версионирование
226
260
 
227
- Стабильность и версионирование
261
+ `zod-envkit` следует **Semantic Versioning**.
228
262
 
229
- zod-envkit следует Semantic Versioning.
263
+ ### Стабильность Public API (1.x)
230
264
 
231
- Стабильность Public API (1.x)
265
+ Всё перечисленное ниже считается **стабильным public API** в рамках ветки 1.x.
232
266
 
233
- Всё перечисленное ниже считается стабильным public API в рамках всей ветки 1.x.
267
+ **Экспорты библиотеки (entrypoint `zod-envkit`):**
234
268
 
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
269
+ - `loadEnv`
270
+ - `mustLoadEnv`
271
+ - `formatZodError`
272
+ - `checkEnv`
273
+ - `getMissingEnv`
274
+ - `getUnknownEnv`
275
+ - `isSecretKey`
276
+ - `generateEnvExample`
277
+ - `generateEnvDocs`
278
+ - `sortMetaEntries`
279
+ - связанные публичные типы: `EnvMeta`, `EnvMetaEntry`, `EnvCheckResult`, `GenerateDocsOptions`, `DocsFormat`, `SortMode`
247
280
 
248
- CLI-контракт:
249
- • команды: generate, show, check, init
250
- • задокументированные флаги и значения по умолчанию
251
- • поведение exit-кодов (успех = 0, пользовательская ошибка = 1)
281
+ **CLI-контракт:**
252
282
 
253
- Политика breaking-изменений
283
+ - команды: `generate`, `show`, `check`, `init`
284
+ - задокументированные флаги и значения по умолчанию
285
+ - поведение exit-кодов (успех = `0`, пользовательская ошибка = `1`)
286
+
287
+ ### Политика breaking-изменений
254
288
 
255
289
  Breaking change (major) включает:
256
- • изменение сигнатур или структуры возвращаемых значений стабильных экспортов
257
- • удаление или переименование public-экспортов
258
- удаление или переименование CLI-команд или флагов
259
- • изменение поведения CLI по умолчанию
260
- изменение семантики exit-кодов
261
- изменение контрактов формата вывода, ломающих существующие инструменты
290
+
291
+ - изменение сигнатур или структуры возвращаемых значений стабильных экспортов
292
+ - удаление или переименование public-экспортов
293
+ - удаление или переименование CLI-команд или флагов
294
+ - изменение поведения CLI по умолчанию (например, что делает `zod-envkit` без аргументов)
295
+ - изменение семантики exit-кодов
296
+ - изменение контрактов формата вывода, ломающих существующие инструменты
262
297
 
263
298
  Не считается breaking (minor/patch):
264
- • добавление новых экспортов (обратно совместимых)
265
- • добавление новых CLI-флагов (обратно совместимых)
266
- • добавление новых опциональных полей в env.meta.json
267
- • улучшение сообщений об ошибках или форматирования документации без нарушения совместимости
268
299
 
269
-
300
+ - добавление новых экспортов (обратно совместимых)
301
+ - добавление новых CLI-флагов (обратно совместимых)
302
+ - добавление новых опциональных полей в `env.meta.json`
303
+ - улучшение сообщений об ошибках или форматирования документации без нарушения совместимости
270
304
 
271
- Что нового в 1.2.0
305
+ ### Что нового в 1.2.0
272
306
 
273
- Версия 1.2.0 сосредоточена на надёжности, контрактности и готовности к CI.
307
+ Версия **1.2.0** сосредоточена на надёжности, контрактности и готовности к CI.
274
308
 
275
309
  Основные изменения:
276
- • усилено поведение строгого режима (check --strict) для CI
277
- • детерминированная обработка приоритета dotenv-файлов
278
- • улучшены гарантии маскирования секретов в show
279
- • расширен preprod-набор тестов (smoke, contract, CLI E2E, robustness)
280
- • CI-pipeline принудительно выполняет: build → tests → docs build
281
310
 
282
- С этого момента zod-envkit это не просто “утилита”, а
283
- стабильный инструмент контрактов окружения для CI/CD-пайплайнов.
311
+ - усилено поведение строгого режима (`check --strict`) для CI
312
+ - детерминированная обработка приоритета dotenv-файлов
313
+ - улучшены гарантии маскирования секретов в `show`
314
+ - расширен preprod-набор тестов (smoke, contract, CLI E2E, robustness)
315
+ - CI-pipeline принудительно выполняет: build → tests → docs build
316
+
317
+ С этого момента `zod-envkit` — это не просто «утилита», а
318
+ **стабильный инструмент контрактов окружения для CI/CD-пайплайнов**.
319
+
320
+ ---
321
+
322
+ ## Почему не просто dotenv?
323
+
324
+ `dotenv`:
284
325
 
285
-
326
+ - ❌ нет валидации
327
+ - ❌ нет типов
328
+ - ❌ нет документации
329
+ - ❌ нет проверок для CI
286
330
 
287
- Почему не просто dotenv?
331
+ `zod-envkit`:
288
332
 
289
- dotenv:
290
- • ❌ нет валидации
291
- • ❌ нет типов
292
- • ❌ нет документации
293
- • ❌ нет проверок для CI
333
+ - ✅ валидация
334
+ - вывод типов для TypeScript
335
+ - документация
336
+ - CLI-инструменты
294
337
 
295
- zod-envkit:
296
- • ✅ валидация
297
- • ✅ вывод типов для TypeScript
298
- • ✅ документация
299
- • ✅ CLI-инструменты
338
+ Они предназначены для использования **вместе**.
300
339
 
301
- Они предназначены для использования вместе.
340
+ ---
302
341
 
303
-
342
+ ## Принципы дизайна
304
343
 
305
- Принципы дизайна
306
- • явная конфигурация вместо магии
307
- • отсутствие привязки к фреймворкам
308
- • маленький и предсказуемый API
309
- • библиотека и CLI независимы, но дополняют друг друга
310
- • переменные окружения — это runtime-контракт
344
+ - явная конфигурация вместо магии
345
+ - отсутствие привязки к фреймворкам
346
+ - маленький и предсказуемый API
347
+ - библиотека и CLI независимы, но дополняют друг друга
348
+ - переменные окружения это runtime-контракт
311
349
 
312
-
350
+ ---
313
351
 
314
- Лицензия
352
+ ## Лицензия
315
353
 
316
354
  MIT
@@ -25,6 +25,8 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
25
25
 
26
26
  // src/cli/index.ts
27
27
  var import_commander = require("commander");
28
+ var import_node_fs5 = __toESM(require("fs"), 1);
29
+ var import_node_path5 = __toESM(require("path"), 1);
28
30
 
29
31
  // src/messages.ts
30
32
  var messages = {
@@ -743,8 +745,10 @@ injectDefaultCommandIfMissing(process.argv, {
743
745
  "show",
744
746
  "check",
745
747
  "init",
748
+ "help",
746
749
  "-h",
747
750
  "--help",
751
+ "--all",
748
752
  "-V",
749
753
  "--version",
750
754
  "--lang"
@@ -752,10 +756,115 @@ injectDefaultCommandIfMissing(process.argv, {
752
756
  defaultCommand: "generate"
753
757
  });
754
758
  var program = new import_commander.Command();
755
- program.name("zod-envkit").description("Env docs + runtime checks for Node.js projects").showHelpAfterError().showSuggestionAfterError().option("--lang <lang>", "CLI language (en | ru)");
759
+ var scriptPath = process.argv[1] ? import_node_path5.default.resolve(process.argv[1]) : import_node_path5.default.resolve("dist/cli/index.js");
760
+ var packageJsonPath = import_node_path5.default.resolve(import_node_path5.default.dirname(scriptPath), "../../package.json");
761
+ var pkgVersion = (() => {
762
+ try {
763
+ const raw = import_node_fs5.default.readFileSync(packageJsonPath, "utf8");
764
+ const parsed = JSON.parse(raw);
765
+ return parsed.version ?? "0.0.0";
766
+ } catch {
767
+ return "0.0.0";
768
+ }
769
+ })();
770
+ program.name("zod-envkit").description("Env docs + runtime checks for Node.js projects").version(pkgVersion, "-V, --version", "output the current version").showHelpAfterError().showSuggestionAfterError().option("--lang <lang>", "CLI language (en | ru)");
756
771
  var getLang = () => resolveLang(program.opts().lang);
757
772
  registerGenerate(program, getLang);
758
773
  registerShow(program, getLang);
759
774
  registerCheck(program, getLang);
760
775
  registerInit(program, getLang);
776
+ function resolveCliLangArg(argv) {
777
+ for (let i = 0; i < argv.length; i++) {
778
+ const token = argv[i] ?? "";
779
+ if (token === "--lang") return argv[i + 1];
780
+ if (token.startsWith("--lang=")) return token.slice("--lang=".length);
781
+ }
782
+ return void 0;
783
+ }
784
+ function renderDeepHelp(lang) {
785
+ const commandNames = program.commands.map((cmd) => cmd.name()).join(", ");
786
+ const blocks = lang === "ru" ? [
787
+ "=== zod-envkit \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u0430\u044F \u0441\u043F\u0440\u0430\u0432\u043A\u0430 ===",
788
+ "",
789
+ "\u0411\u0430\u0437\u043E\u0432\u0430\u044F \u0438\u0434\u0435\u044F:",
790
+ " env.meta.json \u2014 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u043F\u0440\u0430\u0432\u0434\u044B \u0434\u043B\u044F \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0438, \u043F\u0440\u043E\u0432\u0435\u0440\u043E\u043A \u0438 \u043E\u043D\u0431\u043E\u0440\u0434\u0438\u043D\u0433\u0430.",
791
+ "",
792
+ "\u0411\u044B\u0441\u0442\u0440\u044B\u0439 \u0441\u0442\u0430\u0440\u0442:",
793
+ " 1) npx zod-envkit init",
794
+ " 2) npx zod-envkit generate",
795
+ " 3) npx zod-envkit show",
796
+ " 4) npx zod-envkit check --strict",
797
+ "",
798
+ "\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B:",
799
+ ` ${commandNames}`,
800
+ "",
801
+ "\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u043C\u044B\u0435 workflow:",
802
+ " - \u0441\u0442\u0430\u0440\u0442 \u0438\u0437 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E env example:",
803
+ " npx zod-envkit init --input .env.example --output env.meta.json",
804
+ " - \u0434\u0435\u0442\u0435\u0440\u043C\u0438\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u0430\u044F \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044F \u0432 CI:",
805
+ " npx zod-envkit generate --format md --sort required-first",
806
+ " npx zod-envkit check --strict --dotenv .env,.env.local",
807
+ " - \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u0430\u043A\u0442\u0430 schema \u2194 meta:",
808
+ " npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
809
+ "",
810
+ "\u0414\u0435\u0442\u0430\u043B\u044C\u043D\u0430\u044F \u0441\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0430\u043C:",
811
+ ""
812
+ ] : [
813
+ "=== zod-envkit deep help ===",
814
+ "",
815
+ "Core idea:",
816
+ " env.meta.json is the source of truth for docs, checks and onboarding.",
817
+ "",
818
+ "Quick start:",
819
+ " 1) npx zod-envkit init",
820
+ " 2) npx zod-envkit generate",
821
+ " 3) npx zod-envkit show",
822
+ " 4) npx zod-envkit check --strict",
823
+ "",
824
+ "Available commands:",
825
+ ` ${commandNames}`,
826
+ "",
827
+ "Recommended workflows:",
828
+ " - bootstrap from existing env example:",
829
+ " npx zod-envkit init --input .env.example --output env.meta.json",
830
+ " - keep docs deterministic in CI:",
831
+ " npx zod-envkit generate --format md --sort required-first",
832
+ " npx zod-envkit check --strict --dotenv .env,.env.local",
833
+ " - validate schema contract against meta:",
834
+ " npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
835
+ "",
836
+ "Detailed command reference:",
837
+ ""
838
+ ];
839
+ for (const cmd of program.commands) {
840
+ blocks.push(cmd.helpInformation().trim(), "");
841
+ }
842
+ if (lang === "ru") {
843
+ blocks.push(
844
+ "\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438:",
845
+ " - \u044F\u0437\u044B\u043A CLI: --lang en|ru",
846
+ " - \u0441\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0435: npx zod-envkit help <command>",
847
+ " - \u043F\u043E\u043B\u043D\u044B\u0439 \u0433\u0430\u0439\u0434: npx zod-envkit help --all"
848
+ );
849
+ } else {
850
+ blocks.push(
851
+ "Tips:",
852
+ " - global language: --lang en|ru",
853
+ " - command help: npx zod-envkit help <command>",
854
+ " - full handbook: npx zod-envkit help --all"
855
+ );
856
+ }
857
+ return `${blocks.join("\n").trimEnd()}
858
+ `;
859
+ }
860
+ program.addHelpText("after", () => {
861
+ const lang = resolveLang(resolveCliLangArg(process.argv.slice(2)));
862
+ return lang === "ru" ? "\n\u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E: `npx zod-envkit help --all` \u0432\u044B\u0432\u043E\u0434\u0438\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u0443\u044E \u0441\u043F\u0440\u0430\u0432\u043A\u0443 \u0441 workflow \u0438 \u043F\u043E\u043B\u043D\u043E\u0439 \u0441\u0432\u043E\u0434\u043A\u043E\u0439 \u043A\u043E\u043C\u0430\u043D\u0434.\n" : "\nTip: `npx zod-envkit help --all` prints an extended handbook with workflows and full command reference.\n";
863
+ });
864
+ var cliArgs = process.argv.slice(2);
865
+ if (cliArgs[0] === "help" && cliArgs.includes("--all")) {
866
+ const lang = resolveLang(resolveCliLangArg(cliArgs));
867
+ process.stdout.write(renderDeepHelp(lang));
868
+ process.exit(0);
869
+ }
761
870
  program.parse(process.argv);
package/dist/cli/index.js CHANGED
@@ -9,6 +9,8 @@ import {
9
9
 
10
10
  // src/cli/index.ts
11
11
  import { Command } from "commander";
12
+ import fs5 from "fs";
13
+ import path5 from "path";
12
14
 
13
15
  // src/messages.ts
14
16
  var messages = {
@@ -522,8 +524,10 @@ injectDefaultCommandIfMissing(process.argv, {
522
524
  "show",
523
525
  "check",
524
526
  "init",
527
+ "help",
525
528
  "-h",
526
529
  "--help",
530
+ "--all",
527
531
  "-V",
528
532
  "--version",
529
533
  "--lang"
@@ -531,10 +535,115 @@ injectDefaultCommandIfMissing(process.argv, {
531
535
  defaultCommand: "generate"
532
536
  });
533
537
  var program = new Command();
534
- program.name("zod-envkit").description("Env docs + runtime checks for Node.js projects").showHelpAfterError().showSuggestionAfterError().option("--lang <lang>", "CLI language (en | ru)");
538
+ var scriptPath = process.argv[1] ? path5.resolve(process.argv[1]) : path5.resolve("dist/cli/index.js");
539
+ var packageJsonPath = path5.resolve(path5.dirname(scriptPath), "../../package.json");
540
+ var pkgVersion = (() => {
541
+ try {
542
+ const raw = fs5.readFileSync(packageJsonPath, "utf8");
543
+ const parsed = JSON.parse(raw);
544
+ return parsed.version ?? "0.0.0";
545
+ } catch {
546
+ return "0.0.0";
547
+ }
548
+ })();
549
+ program.name("zod-envkit").description("Env docs + runtime checks for Node.js projects").version(pkgVersion, "-V, --version", "output the current version").showHelpAfterError().showSuggestionAfterError().option("--lang <lang>", "CLI language (en | ru)");
535
550
  var getLang = () => resolveLang(program.opts().lang);
536
551
  registerGenerate(program, getLang);
537
552
  registerShow(program, getLang);
538
553
  registerCheck(program, getLang);
539
554
  registerInit(program, getLang);
555
+ function resolveCliLangArg(argv) {
556
+ for (let i = 0; i < argv.length; i++) {
557
+ const token = argv[i] ?? "";
558
+ if (token === "--lang") return argv[i + 1];
559
+ if (token.startsWith("--lang=")) return token.slice("--lang=".length);
560
+ }
561
+ return void 0;
562
+ }
563
+ function renderDeepHelp(lang) {
564
+ const commandNames = program.commands.map((cmd) => cmd.name()).join(", ");
565
+ const blocks = lang === "ru" ? [
566
+ "=== zod-envkit \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u0430\u044F \u0441\u043F\u0440\u0430\u0432\u043A\u0430 ===",
567
+ "",
568
+ "\u0411\u0430\u0437\u043E\u0432\u0430\u044F \u0438\u0434\u0435\u044F:",
569
+ " env.meta.json \u2014 \u0438\u0441\u0442\u043E\u0447\u043D\u0438\u043A \u043F\u0440\u0430\u0432\u0434\u044B \u0434\u043B\u044F \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0438, \u043F\u0440\u043E\u0432\u0435\u0440\u043E\u043A \u0438 \u043E\u043D\u0431\u043E\u0440\u0434\u0438\u043D\u0433\u0430.",
570
+ "",
571
+ "\u0411\u044B\u0441\u0442\u0440\u044B\u0439 \u0441\u0442\u0430\u0440\u0442:",
572
+ " 1) npx zod-envkit init",
573
+ " 2) npx zod-envkit generate",
574
+ " 3) npx zod-envkit show",
575
+ " 4) npx zod-envkit check --strict",
576
+ "",
577
+ "\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B:",
578
+ ` ${commandNames}`,
579
+ "",
580
+ "\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u043C\u044B\u0435 workflow:",
581
+ " - \u0441\u0442\u0430\u0440\u0442 \u0438\u0437 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E env example:",
582
+ " npx zod-envkit init --input .env.example --output env.meta.json",
583
+ " - \u0434\u0435\u0442\u0435\u0440\u043C\u0438\u043D\u0438\u0440\u043E\u0432\u0430\u043D\u043D\u0430\u044F \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044F \u0432 CI:",
584
+ " npx zod-envkit generate --format md --sort required-first",
585
+ " npx zod-envkit check --strict --dotenv .env,.env.local",
586
+ " - \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u0430\u043A\u0442\u0430 schema \u2194 meta:",
587
+ " npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
588
+ "",
589
+ "\u0414\u0435\u0442\u0430\u043B\u044C\u043D\u0430\u044F \u0441\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0430\u043C:",
590
+ ""
591
+ ] : [
592
+ "=== zod-envkit deep help ===",
593
+ "",
594
+ "Core idea:",
595
+ " env.meta.json is the source of truth for docs, checks and onboarding.",
596
+ "",
597
+ "Quick start:",
598
+ " 1) npx zod-envkit init",
599
+ " 2) npx zod-envkit generate",
600
+ " 3) npx zod-envkit show",
601
+ " 4) npx zod-envkit check --strict",
602
+ "",
603
+ "Available commands:",
604
+ ` ${commandNames}`,
605
+ "",
606
+ "Recommended workflows:",
607
+ " - bootstrap from existing env example:",
608
+ " npx zod-envkit init --input .env.example --output env.meta.json",
609
+ " - keep docs deterministic in CI:",
610
+ " npx zod-envkit generate --format md --sort required-first",
611
+ " npx zod-envkit check --strict --dotenv .env,.env.local",
612
+ " - validate schema contract against meta:",
613
+ " npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
614
+ "",
615
+ "Detailed command reference:",
616
+ ""
617
+ ];
618
+ for (const cmd of program.commands) {
619
+ blocks.push(cmd.helpInformation().trim(), "");
620
+ }
621
+ if (lang === "ru") {
622
+ blocks.push(
623
+ "\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438:",
624
+ " - \u044F\u0437\u044B\u043A CLI: --lang en|ru",
625
+ " - \u0441\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0435: npx zod-envkit help <command>",
626
+ " - \u043F\u043E\u043B\u043D\u044B\u0439 \u0433\u0430\u0439\u0434: npx zod-envkit help --all"
627
+ );
628
+ } else {
629
+ blocks.push(
630
+ "Tips:",
631
+ " - global language: --lang en|ru",
632
+ " - command help: npx zod-envkit help <command>",
633
+ " - full handbook: npx zod-envkit help --all"
634
+ );
635
+ }
636
+ return `${blocks.join("\n").trimEnd()}
637
+ `;
638
+ }
639
+ program.addHelpText("after", () => {
640
+ const lang = resolveLang(resolveCliLangArg(process.argv.slice(2)));
641
+ return lang === "ru" ? "\n\u0414\u043E\u043F\u043E\u043B\u043D\u0438\u0442\u0435\u043B\u044C\u043D\u043E: `npx zod-envkit help --all` \u0432\u044B\u0432\u043E\u0434\u0438\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043D\u043D\u0443\u044E \u0441\u043F\u0440\u0430\u0432\u043A\u0443 \u0441 workflow \u0438 \u043F\u043E\u043B\u043D\u043E\u0439 \u0441\u0432\u043E\u0434\u043A\u043E\u0439 \u043A\u043E\u043C\u0430\u043D\u0434.\n" : "\nTip: `npx zod-envkit help --all` prints an extended handbook with workflows and full command reference.\n";
642
+ });
643
+ var cliArgs = process.argv.slice(2);
644
+ if (cliArgs[0] === "help" && cliArgs.includes("--all")) {
645
+ const lang = resolveLang(resolveCliLangArg(cliArgs));
646
+ process.stdout.write(renderDeepHelp(lang));
647
+ process.exit(0);
648
+ }
540
649
  program.parse(process.argv);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "zod-envkit",
3
- "version": "1.3.2",
3
+ "version": "1.3.4",
4
4
  "description": "Validate environment variables with Zod and generate .env.example",
5
5
  "license": "MIT",
6
6
  "author": "",