zod-envkit 1.3.0 → 1.3.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 +29 -1
- package/dist/cli/index.cjs +35 -7
- package/dist/cli/index.js +35 -7
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,4 +1,32 @@
|
|
|
1
|
-
|
|
1
|
+
## [1.3.2](https://github.com/nxtxe/zod-envkit/compare/v1.3.1...v1.3.2) (2026-03-23)
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
### Bug Fixes
|
|
5
|
+
|
|
6
|
+
* handle meta fallback edge case ([f54596e](https://github.com/nxtxe/zod-envkit/commit/f54596e9835f47076c079029f2c926228329d990))
|
|
7
|
+
|
|
8
|
+
## [1.3.2](https://github.com/nxtxe/zod-envkit/compare/v1.3.1...v1.3.2) (2026-03-xx)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
### Bug Fixes
|
|
12
|
+
|
|
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
|
|
21
|
+
|
|
22
|
+
## [1.3.1](https://github.com/nxtxe/zod-envkit/compare/v1.3.0...v1.3.1) (2026-03-19)
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
### Bug Fixes
|
|
26
|
+
|
|
27
|
+
* **cli:** improve env error grouping and hints ([d098a70](https://github.com/nxtxe/zod-envkit/commit/d098a70683f8028b7be275bd16a580f4fccb4938))
|
|
28
|
+
|
|
29
|
+
## [1.3.0](https://github.com/nxtxe/zod-envkit/compare/v1.2.3...v1.3.0) (2026-03-04)
|
|
2
30
|
|
|
3
31
|
|
|
4
32
|
### Features
|
package/dist/cli/index.cjs
CHANGED
|
@@ -29,16 +29,18 @@ var import_commander = require("commander");
|
|
|
29
29
|
// src/messages.ts
|
|
30
30
|
var messages = {
|
|
31
31
|
en: {
|
|
32
|
+
ENV_INVALID: "Environment is invalid.",
|
|
32
33
|
META_NOT_FOUND: "env meta file not found.",
|
|
33
34
|
META_TRIED: "Tried:",
|
|
34
35
|
META_TIP: "Tip:",
|
|
35
36
|
META_PARSE_FAILED: "Failed to read/parse env meta file:",
|
|
37
|
+
META_EXAMPLE_EMPTY: ".env.example exists but has no parseable variables.",
|
|
36
38
|
META_FALLBACK_EXAMPLE: "env.meta.json not found, falling back to .env.example (minimal meta).",
|
|
37
39
|
META_FALLBACK_TIP: "Tip: create env.meta.json for richer docs, grouping, and stable CLI behavior.",
|
|
38
40
|
GENERATED: "Generated: {example}, {docs}",
|
|
39
41
|
ENV_OK: "Environment looks good.",
|
|
40
42
|
MISSING_ENV: "Missing required environment variables:",
|
|
41
|
-
UNKNOWN_ENV: "Unknown environment variables:",
|
|
43
|
+
UNKNOWN_ENV: "Unknown environment variables (strict mode; only dotenv-loaded keys):",
|
|
42
44
|
INVALID_FORMAT: "Invalid docs format",
|
|
43
45
|
INVALID_MASK_MODE: "Invalid mask mode",
|
|
44
46
|
INVALID_SORT: "Invalid sort mode",
|
|
@@ -51,16 +53,18 @@ var messages = {
|
|
|
51
53
|
META_HINT_SYNC_SCHEMA: "Hint: add these to your Zod schema or remove from env.meta.json."
|
|
52
54
|
},
|
|
53
55
|
ru: {
|
|
56
|
+
ENV_INVALID: "\u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F \u0437\u0430\u0434\u0430\u043D\u044B \u043D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u043E.",
|
|
54
57
|
META_NOT_FOUND: "\u0424\u0430\u0439\u043B env.meta.json \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.",
|
|
55
58
|
META_TRIED: "\u041F\u0440\u043E\u0431\u043E\u0432\u0430\u043B\u0438:",
|
|
56
59
|
META_TIP: "\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430:",
|
|
57
60
|
META_PARSE_FAILED: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C \u0438\u043B\u0438 \u0440\u0430\u0441\u043F\u0430\u0440\u0441\u0438\u0442\u044C env meta \u0444\u0430\u0439\u043B:",
|
|
61
|
+
META_EXAMPLE_EMPTY: ".env.example \u043D\u0430\u0439\u0434\u0435\u043D, \u043D\u043E \u0432 \u043D\u0435\u043C \u043D\u0435\u0442 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u0435\u043C\u044B\u0445 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445.",
|
|
58
62
|
META_FALLBACK_EXAMPLE: "env.meta.json \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C .env.example \u043A\u0430\u043A \u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0443\u044E \u043C\u0435\u0442\u0443.",
|
|
59
63
|
META_FALLBACK_TIP: "\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430: \u043B\u0443\u0447\u0448\u0435 \u0441\u043E\u0437\u0434\u0430\u0442\u044C env.meta.json \u2014 \u0431\u0443\u0434\u0435\u0442 \u0431\u043E\u0433\u0430\u0447\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044F \u0438 \u0441\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u0435\u0435 CLI-\u043A\u043E\u043D\u0442\u0440\u0430\u043A\u0442.",
|
|
60
64
|
GENERATED: "\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043E: {example}, {docs}",
|
|
61
65
|
ENV_OK: "\u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F \u0432 \u043F\u043E\u0440\u044F\u0434\u043A\u0435.",
|
|
62
66
|
MISSING_ENV: "\u041E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F:",
|
|
63
|
-
UNKNOWN_ENV: "\u041E\u0431\u043D\u0430\u0440\u0443\u0436\u0435\u043D\u044B \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F:",
|
|
67
|
+
UNKNOWN_ENV: "\u041E\u0431\u043D\u0430\u0440\u0443\u0436\u0435\u043D\u044B \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F (strict; \u0442\u043E\u043B\u044C\u043A\u043E \u0438\u0437 dotenv-\u0444\u0430\u0439\u043B\u043E\u0432):",
|
|
64
68
|
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",
|
|
65
69
|
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",
|
|
66
70
|
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",
|
|
@@ -160,22 +164,38 @@ function loadMeta(lang, configFile) {
|
|
|
160
164
|
const raw = import_node_fs.default.readFileSync(found, "utf8");
|
|
161
165
|
return { meta: JSON.parse(raw), configPath: found };
|
|
162
166
|
} catch {
|
|
163
|
-
fail(lang, "META_PARSE_FAILED", [
|
|
167
|
+
fail(lang, "META_PARSE_FAILED", [
|
|
168
|
+
`- ${found}`,
|
|
169
|
+
"",
|
|
170
|
+
t(lang, "META_TIP"),
|
|
171
|
+
" Run: npx zod-envkit generate -c env.meta.json"
|
|
172
|
+
]);
|
|
164
173
|
}
|
|
165
174
|
}
|
|
166
175
|
const examplePath = import_node_path.default.resolve(process.cwd(), ".env.example");
|
|
167
176
|
if (import_node_fs.default.existsSync(examplePath)) {
|
|
177
|
+
const meta = buildMetaFromEnvExample(examplePath);
|
|
178
|
+
const keys = Object.keys(meta);
|
|
179
|
+
if (keys.length === 0) {
|
|
180
|
+
fail(lang, "META_EXAMPLE_EMPTY", [
|
|
181
|
+
`- ${examplePath}`,
|
|
182
|
+
"",
|
|
183
|
+
t(lang, "META_TIP"),
|
|
184
|
+
" Add at least one KEY=value line to .env.example,",
|
|
185
|
+
" or create env.meta.json and run: npx zod-envkit generate -c env.meta.json"
|
|
186
|
+
]);
|
|
187
|
+
}
|
|
168
188
|
console.warn(`\u26A0\uFE0F ${t(lang, "META_FALLBACK_EXAMPLE")}`);
|
|
169
189
|
console.warn(` ${t(lang, "META_FALLBACK_TIP")}`);
|
|
170
190
|
console.warn("");
|
|
171
|
-
return { meta
|
|
191
|
+
return { meta, configPath: examplePath };
|
|
172
192
|
}
|
|
173
193
|
fail(lang, "META_NOT_FOUND", [
|
|
174
194
|
t(lang, "META_TRIED"),
|
|
175
195
|
...candidates.map((p) => `- ${p}`),
|
|
176
196
|
"",
|
|
177
197
|
t(lang, "META_TIP"),
|
|
178
|
-
" npx zod-envkit
|
|
198
|
+
" Run: npx zod-envkit generate -c env.meta.json"
|
|
179
199
|
]);
|
|
180
200
|
}
|
|
181
201
|
|
|
@@ -618,16 +638,24 @@ function registerCheck(program2, getLang2) {
|
|
|
618
638
|
const lang = getLang2();
|
|
619
639
|
const loaded = loadDotEnv(opts.dotenv);
|
|
620
640
|
const { meta } = loadMeta(lang, opts.config);
|
|
641
|
+
const sections = [];
|
|
621
642
|
const missing = getMissingEnv(meta, process.env);
|
|
622
643
|
if (missing.length) {
|
|
623
|
-
|
|
644
|
+
sections.push(t(lang, "MISSING_ENV"));
|
|
645
|
+
missing.forEach((k) => sections.push(`- ${k}`));
|
|
646
|
+
sections.push("");
|
|
624
647
|
}
|
|
625
648
|
if (opts.strict) {
|
|
626
649
|
const unknown = getUnknownEnv(meta, loaded.env);
|
|
627
650
|
if (unknown.length) {
|
|
628
|
-
|
|
651
|
+
sections.push(t(lang, "UNKNOWN_ENV"));
|
|
652
|
+
unknown.forEach((k) => sections.push(`- ${k}`));
|
|
653
|
+
sections.push("");
|
|
629
654
|
}
|
|
630
655
|
}
|
|
656
|
+
if (sections.length) {
|
|
657
|
+
fail(lang, "ENV_INVALID", sections);
|
|
658
|
+
}
|
|
631
659
|
if (opts.schema) {
|
|
632
660
|
const schemaMode = String(opts.schemaMode ?? "strict").toLowerCase();
|
|
633
661
|
if (schemaMode !== "warn" && schemaMode !== "strict") {
|
package/dist/cli/index.js
CHANGED
|
@@ -13,16 +13,18 @@ import { Command } from "commander";
|
|
|
13
13
|
// src/messages.ts
|
|
14
14
|
var messages = {
|
|
15
15
|
en: {
|
|
16
|
+
ENV_INVALID: "Environment is invalid.",
|
|
16
17
|
META_NOT_FOUND: "env meta file not found.",
|
|
17
18
|
META_TRIED: "Tried:",
|
|
18
19
|
META_TIP: "Tip:",
|
|
19
20
|
META_PARSE_FAILED: "Failed to read/parse env meta file:",
|
|
21
|
+
META_EXAMPLE_EMPTY: ".env.example exists but has no parseable variables.",
|
|
20
22
|
META_FALLBACK_EXAMPLE: "env.meta.json not found, falling back to .env.example (minimal meta).",
|
|
21
23
|
META_FALLBACK_TIP: "Tip: create env.meta.json for richer docs, grouping, and stable CLI behavior.",
|
|
22
24
|
GENERATED: "Generated: {example}, {docs}",
|
|
23
25
|
ENV_OK: "Environment looks good.",
|
|
24
26
|
MISSING_ENV: "Missing required environment variables:",
|
|
25
|
-
UNKNOWN_ENV: "Unknown environment variables:",
|
|
27
|
+
UNKNOWN_ENV: "Unknown environment variables (strict mode; only dotenv-loaded keys):",
|
|
26
28
|
INVALID_FORMAT: "Invalid docs format",
|
|
27
29
|
INVALID_MASK_MODE: "Invalid mask mode",
|
|
28
30
|
INVALID_SORT: "Invalid sort mode",
|
|
@@ -35,16 +37,18 @@ var messages = {
|
|
|
35
37
|
META_HINT_SYNC_SCHEMA: "Hint: add these to your Zod schema or remove from env.meta.json."
|
|
36
38
|
},
|
|
37
39
|
ru: {
|
|
40
|
+
ENV_INVALID: "\u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F \u0437\u0430\u0434\u0430\u043D\u044B \u043D\u0435\u043A\u043E\u0440\u0440\u0435\u043A\u0442\u043D\u043E.",
|
|
38
41
|
META_NOT_FOUND: "\u0424\u0430\u0439\u043B env.meta.json \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D.",
|
|
39
42
|
META_TRIED: "\u041F\u0440\u043E\u0431\u043E\u0432\u0430\u043B\u0438:",
|
|
40
43
|
META_TIP: "\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430:",
|
|
41
44
|
META_PARSE_FAILED: "\u041D\u0435 \u0443\u0434\u0430\u043B\u043E\u0441\u044C \u043F\u0440\u043E\u0447\u0438\u0442\u0430\u0442\u044C \u0438\u043B\u0438 \u0440\u0430\u0441\u043F\u0430\u0440\u0441\u0438\u0442\u044C env meta \u0444\u0430\u0439\u043B:",
|
|
45
|
+
META_EXAMPLE_EMPTY: ".env.example \u043D\u0430\u0439\u0434\u0435\u043D, \u043D\u043E \u0432 \u043D\u0435\u043C \u043D\u0435\u0442 \u0440\u0430\u0441\u043F\u043E\u0437\u043D\u0430\u0432\u0430\u0435\u043C\u044B\u0445 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0445.",
|
|
42
46
|
META_FALLBACK_EXAMPLE: "env.meta.json \u043D\u0435 \u043D\u0430\u0439\u0434\u0435\u043D, \u0438\u0441\u043F\u043E\u043B\u044C\u0437\u0443\u0435\u043C .env.example \u043A\u0430\u043A \u043C\u0438\u043D\u0438\u043C\u0430\u043B\u044C\u043D\u0443\u044E \u043C\u0435\u0442\u0443.",
|
|
43
47
|
META_FALLBACK_TIP: "\u041F\u043E\u0434\u0441\u043A\u0430\u0437\u043A\u0430: \u043B\u0443\u0447\u0448\u0435 \u0441\u043E\u0437\u0434\u0430\u0442\u044C env.meta.json \u2014 \u0431\u0443\u0434\u0435\u0442 \u0431\u043E\u0433\u0430\u0447\u0435 \u0434\u043E\u043A\u0443\u043C\u0435\u043D\u0442\u0430\u0446\u0438\u044F \u0438 \u0441\u0442\u0430\u0431\u0438\u043B\u044C\u043D\u0435\u0435 CLI-\u043A\u043E\u043D\u0442\u0440\u0430\u043A\u0442.",
|
|
44
48
|
GENERATED: "\u0421\u0433\u0435\u043D\u0435\u0440\u0438\u0440\u043E\u0432\u0430\u043D\u043E: {example}, {docs}",
|
|
45
49
|
ENV_OK: "\u041F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F \u0432 \u043F\u043E\u0440\u044F\u0434\u043A\u0435.",
|
|
46
50
|
MISSING_ENV: "\u041E\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u044E\u0442 \u043E\u0431\u044F\u0437\u0430\u0442\u0435\u043B\u044C\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F:",
|
|
47
|
-
UNKNOWN_ENV: "\u041E\u0431\u043D\u0430\u0440\u0443\u0436\u0435\u043D\u044B \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F:",
|
|
51
|
+
UNKNOWN_ENV: "\u041E\u0431\u043D\u0430\u0440\u0443\u0436\u0435\u043D\u044B \u043D\u0435\u0438\u0437\u0432\u0435\u0441\u0442\u043D\u044B\u0435 \u043F\u0435\u0440\u0435\u043C\u0435\u043D\u043D\u044B\u0435 \u043E\u043A\u0440\u0443\u0436\u0435\u043D\u0438\u044F (strict; \u0442\u043E\u043B\u044C\u043A\u043E \u0438\u0437 dotenv-\u0444\u0430\u0439\u043B\u043E\u0432):",
|
|
48
52
|
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",
|
|
49
53
|
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",
|
|
50
54
|
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",
|
|
@@ -144,22 +148,38 @@ function loadMeta(lang, configFile) {
|
|
|
144
148
|
const raw = fs.readFileSync(found, "utf8");
|
|
145
149
|
return { meta: JSON.parse(raw), configPath: found };
|
|
146
150
|
} catch {
|
|
147
|
-
fail(lang, "META_PARSE_FAILED", [
|
|
151
|
+
fail(lang, "META_PARSE_FAILED", [
|
|
152
|
+
`- ${found}`,
|
|
153
|
+
"",
|
|
154
|
+
t(lang, "META_TIP"),
|
|
155
|
+
" Run: npx zod-envkit generate -c env.meta.json"
|
|
156
|
+
]);
|
|
148
157
|
}
|
|
149
158
|
}
|
|
150
159
|
const examplePath = path.resolve(process.cwd(), ".env.example");
|
|
151
160
|
if (fs.existsSync(examplePath)) {
|
|
161
|
+
const meta = buildMetaFromEnvExample(examplePath);
|
|
162
|
+
const keys = Object.keys(meta);
|
|
163
|
+
if (keys.length === 0) {
|
|
164
|
+
fail(lang, "META_EXAMPLE_EMPTY", [
|
|
165
|
+
`- ${examplePath}`,
|
|
166
|
+
"",
|
|
167
|
+
t(lang, "META_TIP"),
|
|
168
|
+
" Add at least one KEY=value line to .env.example,",
|
|
169
|
+
" or create env.meta.json and run: npx zod-envkit generate -c env.meta.json"
|
|
170
|
+
]);
|
|
171
|
+
}
|
|
152
172
|
console.warn(`\u26A0\uFE0F ${t(lang, "META_FALLBACK_EXAMPLE")}`);
|
|
153
173
|
console.warn(` ${t(lang, "META_FALLBACK_TIP")}`);
|
|
154
174
|
console.warn("");
|
|
155
|
-
return { meta
|
|
175
|
+
return { meta, configPath: examplePath };
|
|
156
176
|
}
|
|
157
177
|
fail(lang, "META_NOT_FOUND", [
|
|
158
178
|
t(lang, "META_TRIED"),
|
|
159
179
|
...candidates.map((p) => `- ${p}`),
|
|
160
180
|
"",
|
|
161
181
|
t(lang, "META_TIP"),
|
|
162
|
-
" npx zod-envkit
|
|
182
|
+
" Run: npx zod-envkit generate -c env.meta.json"
|
|
163
183
|
]);
|
|
164
184
|
}
|
|
165
185
|
|
|
@@ -397,16 +417,24 @@ function registerCheck(program2, getLang2) {
|
|
|
397
417
|
const lang = getLang2();
|
|
398
418
|
const loaded = loadDotEnv(opts.dotenv);
|
|
399
419
|
const { meta } = loadMeta(lang, opts.config);
|
|
420
|
+
const sections = [];
|
|
400
421
|
const missing = getMissingEnv(meta, process.env);
|
|
401
422
|
if (missing.length) {
|
|
402
|
-
|
|
423
|
+
sections.push(t(lang, "MISSING_ENV"));
|
|
424
|
+
missing.forEach((k) => sections.push(`- ${k}`));
|
|
425
|
+
sections.push("");
|
|
403
426
|
}
|
|
404
427
|
if (opts.strict) {
|
|
405
428
|
const unknown = getUnknownEnv(meta, loaded.env);
|
|
406
429
|
if (unknown.length) {
|
|
407
|
-
|
|
430
|
+
sections.push(t(lang, "UNKNOWN_ENV"));
|
|
431
|
+
unknown.forEach((k) => sections.push(`- ${k}`));
|
|
432
|
+
sections.push("");
|
|
408
433
|
}
|
|
409
434
|
}
|
|
435
|
+
if (sections.length) {
|
|
436
|
+
fail(lang, "ENV_INVALID", sections);
|
|
437
|
+
}
|
|
410
438
|
if (opts.schema) {
|
|
411
439
|
const schemaMode = String(opts.schemaMode ?? "strict").toLowerCase();
|
|
412
440
|
if (schemaMode !== "warn" && schemaMode !== "strict") {
|