zod-envkit 1.3.3 → 1.3.5
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 +28 -2
- package/dist/{chunk-J4V5ODI6.js → chunk-WWWQDMV5.js} +1 -1
- package/dist/cli/index.cjs +107 -5
- package/dist/cli/index.js +107 -5
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/package.json +3 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,35 @@
|
|
|
1
|
-
## [1.3.
|
|
1
|
+
## [1.3.5](https://github.com/nxtxe/zod-envkit/compare/v1.3.4...v1.3.5) (2026-05-04)
|
|
2
2
|
|
|
3
3
|
|
|
4
4
|
### Bug Fixes
|
|
5
5
|
|
|
6
|
-
* **cli:**
|
|
6
|
+
* **cli:** harden 1.3.5 stability checks and release hygiene ([74381b9](https://github.com/nxtxe/zod-envkit/commit/74381b97785a469bf5465d8839702f206acb4c2e))
|
|
7
|
+
|
|
8
|
+
## [1.3.4](https://github.com/nxtxe/zod-envkit/compare/v1.3.3...v1.3.4) (2026-04-20)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
13
|
+
* **cli:** harden 1.3.4 output stability and edge robustness ([e3f52d7](https://github.com/nxtxe/zod-envkit/commit/e3f52d78917f726f08f7213fd31c00a52ca39deb))
|
|
14
|
+
|
|
15
|
+
## [1.3.4](https://github.com/nxtxe/zod-envkit/compare/v1.3.3...v1.3.4) (2026-03-xx)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
### Bug Fixes
|
|
19
|
+
|
|
20
|
+
* deterministic output polish:
|
|
21
|
+
* lock stable ordering and formatting of grouped `check --strict` errors across repeated runs
|
|
22
|
+
* masking edge hardening:
|
|
23
|
+
* add coverage for short secret values (`1-2` chars) in `partial/full` modes
|
|
24
|
+
* keep case-insensitive secret detection stable (`Api_Key`, `my_password`)
|
|
25
|
+
* dotenv parsing robustness:
|
|
26
|
+
* add coverage for BOM, trailing spaces, and duplicate keys with deterministic override behavior
|
|
27
|
+
* fallback clarity hardening:
|
|
28
|
+
* extend tests for empty/comment-only `.env.example` fallback path
|
|
29
|
+
* CLI smoke hardening:
|
|
30
|
+
* repeated `--help`, `--version`, `show`, and `check` invocations across locales
|
|
31
|
+
* docs consistency patch:
|
|
32
|
+
* keep EN/RU CLI contract sections aligned (no behavior changes)
|
|
7
33
|
|
|
8
34
|
## [1.3.3](https://github.com/nxtxe/zod-envkit/compare/v1.3.2...v1.3.3) (2026-03-xx)
|
|
9
35
|
|
|
@@ -196,7 +196,7 @@ var SECRET_PATTERNS = [
|
|
|
196
196
|
(k) => k.includes("SESSION"),
|
|
197
197
|
(k) => k.includes("CREDENTIAL"),
|
|
198
198
|
(k) => k.includes("CREDS"),
|
|
199
|
-
(k) => k.includes("DATABASE_URL") || k === "DB_URL",
|
|
199
|
+
(k) => k.includes("DATABASE_URL") || k === "DB_URL" || k === "POSTGRES_URL" || k === "MYSQL_URL" || k === "DATABASE",
|
|
200
200
|
(k) => k.includes("CONNECTION_STRING")
|
|
201
201
|
];
|
|
202
202
|
function isSecretKey(key) {
|
package/dist/cli/index.cjs
CHANGED
|
@@ -46,7 +46,10 @@ var messages = {
|
|
|
46
46
|
INVALID_FORMAT: "Invalid docs format",
|
|
47
47
|
INVALID_MASK_MODE: "Invalid mask mode",
|
|
48
48
|
INVALID_SORT: "Invalid sort mode",
|
|
49
|
+
INVALID_SCHEMA_MODE: "Invalid schema mode",
|
|
49
50
|
INIT_INPUT_EMPTY: "Input env file is empty or not found:",
|
|
51
|
+
META_EMPTY_TIP_LINE_1: "Add at least one KEY=value line to .env.example,",
|
|
52
|
+
META_EMPTY_TIP_LINE_2: "or create env.meta.json and run: npx zod-envkit generate -c env.meta.json",
|
|
50
53
|
SCHEMA_LOAD_FAILED: "Failed to load schema file:",
|
|
51
54
|
SCHEMA_NOT_OBJECT: "Schema file must export a Zod object (z.object(...)).",
|
|
52
55
|
SCHEMA_VARS_NOT_IN_META: "Schema variables not listed in env.meta.json:",
|
|
@@ -70,7 +73,10 @@ var messages = {
|
|
|
70
73
|
INVALID_FORMAT: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0438",
|
|
71
74
|
INVALID_MASK_MODE: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C \u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0438",
|
|
72
75
|
INVALID_SORT: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438",
|
|
76
|
+
INVALID_SCHEMA_MODE: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C schema",
|
|
73
77
|
INIT_INPUT_EMPTY: "\u0424\u0430\u0439\u043B \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F \u043F\u0443\u0441\u0442 \u0438\u043B\u0438 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D:",
|
|
78
|
+
META_EMPTY_TIP_LINE_1: "\u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u0432 .env.example \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u0443 \u0441\u0442\u0440\u043E\u043A\u0443 KEY=value,",
|
|
79
|
+
META_EMPTY_TIP_LINE_2: "\u0438\u043B\u0438 \u0441\u043E\u0437\u0434\u0430\u0439\u0442\u0435 env.meta.json \u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435: npx zod-envkit generate -c env.meta.json",
|
|
74
80
|
SCHEMA_LOAD_FAILED: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u0430\u0439\u043B \u0441\u0445\u0435\u043C\u044B:",
|
|
75
81
|
SCHEMA_NOT_OBJECT: "\u0424\u0430\u0439\u043B \u0441\u0445\u0435\u043C\u044B \u0434\u043E\u043B\u0436\u0435\u043D \u044D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C Zod object (z.object(...)).",
|
|
76
82
|
SCHEMA_VARS_NOT_IN_META: "\u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u0441\u0445\u0435\u043C\u044B \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442 \u0432 env.meta.json:",
|
|
@@ -183,8 +189,8 @@ function loadMeta(lang, configFile) {
|
|
|
183
189
|
`- ${examplePath}`,
|
|
184
190
|
"",
|
|
185
191
|
t(lang, "META_TIP"),
|
|
186
|
-
|
|
187
|
-
|
|
192
|
+
` ${t(lang, "META_EMPTY_TIP_LINE_1")}`,
|
|
193
|
+
` ${t(lang, "META_EMPTY_TIP_LINE_2")}`
|
|
188
194
|
]);
|
|
189
195
|
}
|
|
190
196
|
console.warn(`\u26A0\uFE0F ${t(lang, "META_FALLBACK_EXAMPLE")}`);
|
|
@@ -470,7 +476,7 @@ var SECRET_PATTERNS = [
|
|
|
470
476
|
(k) => k.includes("SESSION"),
|
|
471
477
|
(k) => k.includes("CREDENTIAL"),
|
|
472
478
|
(k) => k.includes("CREDS"),
|
|
473
|
-
(k) => k.includes("DATABASE_URL") || k === "DB_URL",
|
|
479
|
+
(k) => k.includes("DATABASE_URL") || k === "DB_URL" || k === "POSTGRES_URL" || k === "MYSQL_URL" || k === "DATABASE",
|
|
474
480
|
(k) => k.includes("CONNECTION_STRING")
|
|
475
481
|
];
|
|
476
482
|
function isSecretKey(key) {
|
|
@@ -661,7 +667,7 @@ function registerCheck(program2, getLang2) {
|
|
|
661
667
|
if (opts.schema) {
|
|
662
668
|
const schemaMode = String(opts.schemaMode ?? "strict").toLowerCase();
|
|
663
669
|
if (schemaMode !== "warn" && schemaMode !== "strict") {
|
|
664
|
-
fail(lang, "
|
|
670
|
+
fail(lang, "INVALID_SCHEMA_MODE", ["- warn | strict"]);
|
|
665
671
|
}
|
|
666
672
|
const { keys: schemaKeys } = await loadSchemaFile(opts.schema, lang);
|
|
667
673
|
const metaKeys = new Set(Object.keys(meta));
|
|
@@ -672,7 +678,7 @@ function registerCheck(program2, getLang2) {
|
|
|
672
678
|
const lines = [];
|
|
673
679
|
if (inSchemaNotMeta.length) {
|
|
674
680
|
lines.push(`\u274C ${t(lang, "SCHEMA_VARS_NOT_IN_META")}`);
|
|
675
|
-
inSchemaNotMeta.forEach((k) => lines.push(`- ${k}`));
|
|
681
|
+
inSchemaNotMeta.sort((a, b) => a.localeCompare(b)).forEach((k) => lines.push(`- ${k}`));
|
|
676
682
|
lines.push(` ${t(lang, "SCHEMA_HINT_ADD_TO_META")}`);
|
|
677
683
|
lines.push("");
|
|
678
684
|
}
|
|
@@ -745,8 +751,10 @@ injectDefaultCommandIfMissing(process.argv, {
|
|
|
745
751
|
"show",
|
|
746
752
|
"check",
|
|
747
753
|
"init",
|
|
754
|
+
"help",
|
|
748
755
|
"-h",
|
|
749
756
|
"--help",
|
|
757
|
+
"--all",
|
|
750
758
|
"-V",
|
|
751
759
|
"--version",
|
|
752
760
|
"--lang"
|
|
@@ -771,4 +779,98 @@ registerGenerate(program, getLang);
|
|
|
771
779
|
registerShow(program, getLang);
|
|
772
780
|
registerCheck(program, getLang);
|
|
773
781
|
registerInit(program, getLang);
|
|
782
|
+
function resolveCliLangArg(argv) {
|
|
783
|
+
for (let i = 0; i < argv.length; i++) {
|
|
784
|
+
const token = argv[i] ?? "";
|
|
785
|
+
if (token === "--lang") return argv[i + 1];
|
|
786
|
+
if (token.startsWith("--lang=")) return token.slice("--lang=".length);
|
|
787
|
+
}
|
|
788
|
+
return void 0;
|
|
789
|
+
}
|
|
790
|
+
function renderDeepHelp(lang) {
|
|
791
|
+
const commandNames = program.commands.map((cmd) => cmd.name()).join(", ");
|
|
792
|
+
const blocks = lang === "ru" ? [
|
|
793
|
+
"=== zod-envkit \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u0430\u044F \u0441\u043F\u0440\u0430\u0432\u043A\u0430 ===",
|
|
794
|
+
"",
|
|
795
|
+
"\u0411\u0430\u0437\u043E\u0432\u0430\u044F \u0438\u0434\u0435\u044F:",
|
|
796
|
+
" 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.",
|
|
797
|
+
"",
|
|
798
|
+
"\u0411\u044B\u0441\u0442\u0440\u044B\u0439 \u0441\u0442\u0430\u0440\u0442:",
|
|
799
|
+
" 1) npx zod-envkit init",
|
|
800
|
+
" 2) npx zod-envkit generate",
|
|
801
|
+
" 3) npx zod-envkit show",
|
|
802
|
+
" 4) npx zod-envkit check --strict",
|
|
803
|
+
"",
|
|
804
|
+
"\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B:",
|
|
805
|
+
` ${commandNames}`,
|
|
806
|
+
"",
|
|
807
|
+
"\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u043C\u044B\u0435 workflow:",
|
|
808
|
+
" - \u0441\u0442\u0430\u0440\u0442 \u0438\u0437 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E env example:",
|
|
809
|
+
" npx zod-envkit init --input .env.example --output env.meta.json",
|
|
810
|
+
" - \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:",
|
|
811
|
+
" npx zod-envkit generate --format md --sort required-first",
|
|
812
|
+
" npx zod-envkit check --strict --dotenv .env,.env.local",
|
|
813
|
+
" - \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u0430\u043A\u0442\u0430 schema \u2194 meta:",
|
|
814
|
+
" npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
|
|
815
|
+
"",
|
|
816
|
+
"\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:",
|
|
817
|
+
""
|
|
818
|
+
] : [
|
|
819
|
+
"=== zod-envkit deep help ===",
|
|
820
|
+
"",
|
|
821
|
+
"Core idea:",
|
|
822
|
+
" env.meta.json is the source of truth for docs, checks and onboarding.",
|
|
823
|
+
"",
|
|
824
|
+
"Quick start:",
|
|
825
|
+
" 1) npx zod-envkit init",
|
|
826
|
+
" 2) npx zod-envkit generate",
|
|
827
|
+
" 3) npx zod-envkit show",
|
|
828
|
+
" 4) npx zod-envkit check --strict",
|
|
829
|
+
"",
|
|
830
|
+
"Available commands:",
|
|
831
|
+
` ${commandNames}`,
|
|
832
|
+
"",
|
|
833
|
+
"Recommended workflows:",
|
|
834
|
+
" - bootstrap from existing env example:",
|
|
835
|
+
" npx zod-envkit init --input .env.example --output env.meta.json",
|
|
836
|
+
" - keep docs deterministic in CI:",
|
|
837
|
+
" npx zod-envkit generate --format md --sort required-first",
|
|
838
|
+
" npx zod-envkit check --strict --dotenv .env,.env.local",
|
|
839
|
+
" - validate schema contract against meta:",
|
|
840
|
+
" npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
|
|
841
|
+
"",
|
|
842
|
+
"Detailed command reference:",
|
|
843
|
+
""
|
|
844
|
+
];
|
|
845
|
+
for (const cmd of program.commands) {
|
|
846
|
+
blocks.push(cmd.helpInformation().trim(), "");
|
|
847
|
+
}
|
|
848
|
+
if (lang === "ru") {
|
|
849
|
+
blocks.push(
|
|
850
|
+
"\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438:",
|
|
851
|
+
" - \u044F\u0437\u044B\u043A CLI: --lang en|ru",
|
|
852
|
+
" - \u0441\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0435: npx zod-envkit help <command>",
|
|
853
|
+
" - \u043F\u043E\u043B\u043D\u044B\u0439 \u0433\u0430\u0439\u0434: npx zod-envkit help --all"
|
|
854
|
+
);
|
|
855
|
+
} else {
|
|
856
|
+
blocks.push(
|
|
857
|
+
"Tips:",
|
|
858
|
+
" - global language: --lang en|ru",
|
|
859
|
+
" - command help: npx zod-envkit help <command>",
|
|
860
|
+
" - full handbook: npx zod-envkit help --all"
|
|
861
|
+
);
|
|
862
|
+
}
|
|
863
|
+
return `${blocks.join("\n").trimEnd()}
|
|
864
|
+
`;
|
|
865
|
+
}
|
|
866
|
+
program.addHelpText("after", () => {
|
|
867
|
+
const lang = resolveLang(resolveCliLangArg(process.argv.slice(2)));
|
|
868
|
+
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";
|
|
869
|
+
});
|
|
870
|
+
var cliArgs = process.argv.slice(2);
|
|
871
|
+
if (cliArgs[0] === "help" && cliArgs.includes("--all")) {
|
|
872
|
+
const lang = resolveLang(resolveCliLangArg(cliArgs));
|
|
873
|
+
process.stdout.write(renderDeepHelp(lang));
|
|
874
|
+
process.exit(0);
|
|
875
|
+
}
|
|
774
876
|
program.parse(process.argv);
|
package/dist/cli/index.js
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
getMissingEnv,
|
|
6
6
|
getUnknownEnv,
|
|
7
7
|
isSecretKey
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-WWWQDMV5.js";
|
|
9
9
|
|
|
10
10
|
// src/cli/index.ts
|
|
11
11
|
import { Command } from "commander";
|
|
@@ -30,7 +30,10 @@ var messages = {
|
|
|
30
30
|
INVALID_FORMAT: "Invalid docs format",
|
|
31
31
|
INVALID_MASK_MODE: "Invalid mask mode",
|
|
32
32
|
INVALID_SORT: "Invalid sort mode",
|
|
33
|
+
INVALID_SCHEMA_MODE: "Invalid schema mode",
|
|
33
34
|
INIT_INPUT_EMPTY: "Input env file is empty or not found:",
|
|
35
|
+
META_EMPTY_TIP_LINE_1: "Add at least one KEY=value line to .env.example,",
|
|
36
|
+
META_EMPTY_TIP_LINE_2: "or create env.meta.json and run: npx zod-envkit generate -c env.meta.json",
|
|
34
37
|
SCHEMA_LOAD_FAILED: "Failed to load schema file:",
|
|
35
38
|
SCHEMA_NOT_OBJECT: "Schema file must export a Zod object (z.object(...)).",
|
|
36
39
|
SCHEMA_VARS_NOT_IN_META: "Schema variables not listed in env.meta.json:",
|
|
@@ -54,7 +57,10 @@ var messages = {
|
|
|
54
57
|
INVALID_FORMAT: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0444\u043E\u0440\u043C\u0430\u0442 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u0438",
|
|
55
58
|
INVALID_MASK_MODE: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C \u043C\u0430\u0441\u043A\u0438\u0440\u043E\u0432\u043A\u0438",
|
|
56
59
|
INVALID_SORT: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C \u0441\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u043A\u0438",
|
|
60
|
+
INVALID_SCHEMA_MODE: "\u041D\u0435\u0432\u0435\u0440\u043D\u044B\u0439 \u0440\u0435\u0436\u0438\u043C schema",
|
|
57
61
|
INIT_INPUT_EMPTY: "\u0424\u0430\u0439\u043B \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F \u043F\u0443\u0441\u0442 \u0438\u043B\u0438 \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D:",
|
|
62
|
+
META_EMPTY_TIP_LINE_1: "\u0414\u043E\u0431\u0430\u0432\u044C\u0442\u0435 \u0432 .env.example \u0445\u043E\u0442\u044F \u0431\u044B \u043E\u0434\u043D\u0443 \u0441\u0442\u0440\u043E\u043A\u0443 KEY=value,",
|
|
63
|
+
META_EMPTY_TIP_LINE_2: "\u0438\u043B\u0438 \u0441\u043E\u0437\u0434\u0430\u0439\u0442\u0435 env.meta.json \u0438 \u0432\u044B\u043F\u043E\u043B\u043D\u0438\u0442\u0435: npx zod-envkit generate -c env.meta.json",
|
|
58
64
|
SCHEMA_LOAD_FAILED: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044C \u0444\u0430\u0439\u043B \u0441\u0445\u0435\u043C\u044B:",
|
|
59
65
|
SCHEMA_NOT_OBJECT: "\u0424\u0430\u0439\u043B \u0441\u0445\u0435\u043C\u044B \u0434\u043E\u043B\u0436\u0435\u043D \u044D\u043A\u0441\u043F\u043E\u0440\u0442\u0438\u0440\u043E\u0432\u0430\u0442\u044C Zod object (z.object(...)).",
|
|
60
66
|
SCHEMA_VARS_NOT_IN_META: "\u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u0441\u0445\u0435\u043C\u044B \u043E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442 \u0432 env.meta.json:",
|
|
@@ -167,8 +173,8 @@ function loadMeta(lang, configFile) {
|
|
|
167
173
|
`- ${examplePath}`,
|
|
168
174
|
"",
|
|
169
175
|
t(lang, "META_TIP"),
|
|
170
|
-
|
|
171
|
-
|
|
176
|
+
` ${t(lang, "META_EMPTY_TIP_LINE_1")}`,
|
|
177
|
+
` ${t(lang, "META_EMPTY_TIP_LINE_2")}`
|
|
172
178
|
]);
|
|
173
179
|
}
|
|
174
180
|
console.warn(`\u26A0\uFE0F ${t(lang, "META_FALLBACK_EXAMPLE")}`);
|
|
@@ -440,7 +446,7 @@ function registerCheck(program2, getLang2) {
|
|
|
440
446
|
if (opts.schema) {
|
|
441
447
|
const schemaMode = String(opts.schemaMode ?? "strict").toLowerCase();
|
|
442
448
|
if (schemaMode !== "warn" && schemaMode !== "strict") {
|
|
443
|
-
fail(lang, "
|
|
449
|
+
fail(lang, "INVALID_SCHEMA_MODE", ["- warn | strict"]);
|
|
444
450
|
}
|
|
445
451
|
const { keys: schemaKeys } = await loadSchemaFile(opts.schema, lang);
|
|
446
452
|
const metaKeys = new Set(Object.keys(meta));
|
|
@@ -451,7 +457,7 @@ function registerCheck(program2, getLang2) {
|
|
|
451
457
|
const lines = [];
|
|
452
458
|
if (inSchemaNotMeta.length) {
|
|
453
459
|
lines.push(`\u274C ${t(lang, "SCHEMA_VARS_NOT_IN_META")}`);
|
|
454
|
-
inSchemaNotMeta.forEach((k) => lines.push(`- ${k}`));
|
|
460
|
+
inSchemaNotMeta.sort((a, b) => a.localeCompare(b)).forEach((k) => lines.push(`- ${k}`));
|
|
455
461
|
lines.push(` ${t(lang, "SCHEMA_HINT_ADD_TO_META")}`);
|
|
456
462
|
lines.push("");
|
|
457
463
|
}
|
|
@@ -524,8 +530,10 @@ injectDefaultCommandIfMissing(process.argv, {
|
|
|
524
530
|
"show",
|
|
525
531
|
"check",
|
|
526
532
|
"init",
|
|
533
|
+
"help",
|
|
527
534
|
"-h",
|
|
528
535
|
"--help",
|
|
536
|
+
"--all",
|
|
529
537
|
"-V",
|
|
530
538
|
"--version",
|
|
531
539
|
"--lang"
|
|
@@ -550,4 +558,98 @@ registerGenerate(program, getLang);
|
|
|
550
558
|
registerShow(program, getLang);
|
|
551
559
|
registerCheck(program, getLang);
|
|
552
560
|
registerInit(program, getLang);
|
|
561
|
+
function resolveCliLangArg(argv) {
|
|
562
|
+
for (let i = 0; i < argv.length; i++) {
|
|
563
|
+
const token = argv[i] ?? "";
|
|
564
|
+
if (token === "--lang") return argv[i + 1];
|
|
565
|
+
if (token.startsWith("--lang=")) return token.slice("--lang=".length);
|
|
566
|
+
}
|
|
567
|
+
return void 0;
|
|
568
|
+
}
|
|
569
|
+
function renderDeepHelp(lang) {
|
|
570
|
+
const commandNames = program.commands.map((cmd) => cmd.name()).join(", ");
|
|
571
|
+
const blocks = lang === "ru" ? [
|
|
572
|
+
"=== zod-envkit \u043F\u043E\u0434\u0440\u043E\u0431\u043D\u0430\u044F \u0441\u043F\u0440\u0430\u0432\u043A\u0430 ===",
|
|
573
|
+
"",
|
|
574
|
+
"\u0411\u0430\u0437\u043E\u0432\u0430\u044F \u0438\u0434\u0435\u044F:",
|
|
575
|
+
" 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.",
|
|
576
|
+
"",
|
|
577
|
+
"\u0411\u044B\u0441\u0442\u0440\u044B\u0439 \u0441\u0442\u0430\u0440\u0442:",
|
|
578
|
+
" 1) npx zod-envkit init",
|
|
579
|
+
" 2) npx zod-envkit generate",
|
|
580
|
+
" 3) npx zod-envkit show",
|
|
581
|
+
" 4) npx zod-envkit check --strict",
|
|
582
|
+
"",
|
|
583
|
+
"\u0414\u043E\u0441\u0442\u0443\u043F\u043D\u044B\u0435 \u043A\u043E\u043C\u0430\u043D\u0434\u044B:",
|
|
584
|
+
` ${commandNames}`,
|
|
585
|
+
"",
|
|
586
|
+
"\u0420\u0435\u043A\u043E\u043C\u0435\u043D\u0434\u0443\u0435\u043C\u044B\u0435 workflow:",
|
|
587
|
+
" - \u0441\u0442\u0430\u0440\u0442 \u0438\u0437 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044E\u0449\u0435\u0433\u043E env example:",
|
|
588
|
+
" npx zod-envkit init --input .env.example --output env.meta.json",
|
|
589
|
+
" - \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:",
|
|
590
|
+
" npx zod-envkit generate --format md --sort required-first",
|
|
591
|
+
" npx zod-envkit check --strict --dotenv .env,.env.local",
|
|
592
|
+
" - \u043F\u0440\u043E\u0432\u0435\u0440\u043A\u0430 \u043A\u043E\u043D\u0442\u0440\u0430\u043A\u0442\u0430 schema \u2194 meta:",
|
|
593
|
+
" npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
|
|
594
|
+
"",
|
|
595
|
+
"\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:",
|
|
596
|
+
""
|
|
597
|
+
] : [
|
|
598
|
+
"=== zod-envkit deep help ===",
|
|
599
|
+
"",
|
|
600
|
+
"Core idea:",
|
|
601
|
+
" env.meta.json is the source of truth for docs, checks and onboarding.",
|
|
602
|
+
"",
|
|
603
|
+
"Quick start:",
|
|
604
|
+
" 1) npx zod-envkit init",
|
|
605
|
+
" 2) npx zod-envkit generate",
|
|
606
|
+
" 3) npx zod-envkit show",
|
|
607
|
+
" 4) npx zod-envkit check --strict",
|
|
608
|
+
"",
|
|
609
|
+
"Available commands:",
|
|
610
|
+
` ${commandNames}`,
|
|
611
|
+
"",
|
|
612
|
+
"Recommended workflows:",
|
|
613
|
+
" - bootstrap from existing env example:",
|
|
614
|
+
" npx zod-envkit init --input .env.example --output env.meta.json",
|
|
615
|
+
" - keep docs deterministic in CI:",
|
|
616
|
+
" npx zod-envkit generate --format md --sort required-first",
|
|
617
|
+
" npx zod-envkit check --strict --dotenv .env,.env.local",
|
|
618
|
+
" - validate schema contract against meta:",
|
|
619
|
+
" npx zod-envkit check --schema ./schema/env.mjs --schema-mode strict",
|
|
620
|
+
"",
|
|
621
|
+
"Detailed command reference:",
|
|
622
|
+
""
|
|
623
|
+
];
|
|
624
|
+
for (const cmd of program.commands) {
|
|
625
|
+
blocks.push(cmd.helpInformation().trim(), "");
|
|
626
|
+
}
|
|
627
|
+
if (lang === "ru") {
|
|
628
|
+
blocks.push(
|
|
629
|
+
"\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0438:",
|
|
630
|
+
" - \u044F\u0437\u044B\u043A CLI: --lang en|ru",
|
|
631
|
+
" - \u0441\u043F\u0440\u0430\u0432\u043A\u0430 \u043F\u043E \u043A\u043E\u043C\u0430\u043D\u0434\u0435: npx zod-envkit help <command>",
|
|
632
|
+
" - \u043F\u043E\u043B\u043D\u044B\u0439 \u0433\u0430\u0439\u0434: npx zod-envkit help --all"
|
|
633
|
+
);
|
|
634
|
+
} else {
|
|
635
|
+
blocks.push(
|
|
636
|
+
"Tips:",
|
|
637
|
+
" - global language: --lang en|ru",
|
|
638
|
+
" - command help: npx zod-envkit help <command>",
|
|
639
|
+
" - full handbook: npx zod-envkit help --all"
|
|
640
|
+
);
|
|
641
|
+
}
|
|
642
|
+
return `${blocks.join("\n").trimEnd()}
|
|
643
|
+
`;
|
|
644
|
+
}
|
|
645
|
+
program.addHelpText("after", () => {
|
|
646
|
+
const lang = resolveLang(resolveCliLangArg(process.argv.slice(2)));
|
|
647
|
+
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";
|
|
648
|
+
});
|
|
649
|
+
var cliArgs = process.argv.slice(2);
|
|
650
|
+
if (cliArgs[0] === "help" && cliArgs.includes("--all")) {
|
|
651
|
+
const lang = resolveLang(resolveCliLangArg(cliArgs));
|
|
652
|
+
process.stdout.write(renderDeepHelp(lang));
|
|
653
|
+
process.exit(0);
|
|
654
|
+
}
|
|
553
655
|
program.parse(process.argv);
|
package/dist/index.cjs
CHANGED
|
@@ -231,7 +231,7 @@ var SECRET_PATTERNS = [
|
|
|
231
231
|
(k) => k.includes("SESSION"),
|
|
232
232
|
(k) => k.includes("CREDENTIAL"),
|
|
233
233
|
(k) => k.includes("CREDS"),
|
|
234
|
-
(k) => k.includes("DATABASE_URL") || k === "DB_URL",
|
|
234
|
+
(k) => k.includes("DATABASE_URL") || k === "DB_URL" || k === "POSTGRES_URL" || k === "MYSQL_URL" || k === "DATABASE",
|
|
235
235
|
(k) => k.includes("CONNECTION_STRING")
|
|
236
236
|
];
|
|
237
237
|
function isSecretKey(key) {
|
package/dist/index.js
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "zod-envkit",
|
|
3
|
-
"version": "1.3.
|
|
3
|
+
"version": "1.3.5",
|
|
4
4
|
"description": "Validate environment variables with Zod and generate .env.example",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "",
|
|
@@ -49,8 +49,9 @@
|
|
|
49
49
|
"test:preprod:robust": "pnpm build && PREPROD_ITER=30 vitest run tests/test/preprod/30-robustness",
|
|
50
50
|
"test:before-release": "pnpm build && pnpm test:preprod && pnpm test:preprod:robust",
|
|
51
51
|
"ci:smoke": "pnpm build && node dist/cli/index.js --help",
|
|
52
|
+
"ci:release-hygiene": "node scripts/validate-release-state.cjs",
|
|
52
53
|
"ci:docs": "pnpm docs:build",
|
|
53
|
-
"ci:all": "pnpm ci:smoke && pnpm test && pnpm ci:docs",
|
|
54
|
+
"ci:all": "pnpm ci:smoke && pnpm test && pnpm ci:release-hygiene && pnpm ci:docs",
|
|
54
55
|
"prepublishOnly": "pnpm build && pnpm test",
|
|
55
56
|
"docs:api": "typedoc --tsconfig tsconfig.docs.json --entryPoints src/index.ts",
|
|
56
57
|
"docs:build": "pnpm docs:api && node scripts/copy-changelog-to-docs.cjs && vitepress build docs",
|