@xlameiro/env-typegen 0.1.8 → 0.1.9
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 +6 -0
- package/dist/cli.js +121 -45
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +78 -32
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +78 -32
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -407,8 +407,8 @@ function generateEnvValidation(parsed) {
|
|
|
407
407
|
function toZodType(envVarType) {
|
|
408
408
|
if (envVarType === "number") return "z.coerce.number()";
|
|
409
409
|
if (envVarType === "boolean") return "z.coerce.boolean()";
|
|
410
|
-
if (envVarType === "url") return "z.
|
|
411
|
-
if (envVarType === "email") return "z.
|
|
410
|
+
if (envVarType === "url") return "z.url()";
|
|
411
|
+
if (envVarType === "email") return "z.email()";
|
|
412
412
|
return "z.string()";
|
|
413
413
|
}
|
|
414
414
|
function generateZodSchema(parsed) {
|
|
@@ -435,7 +435,10 @@ function generateZodSchema(parsed) {
|
|
|
435
435
|
lines.push(
|
|
436
436
|
"});",
|
|
437
437
|
"",
|
|
438
|
-
"export const envSchema =
|
|
438
|
+
"export const envSchema = z.object({",
|
|
439
|
+
" ...serverEnvSchema.shape,",
|
|
440
|
+
" ...clientEnvSchema.shape,",
|
|
441
|
+
"});",
|
|
439
442
|
"export type Env = z.infer<typeof envSchema>;"
|
|
440
443
|
);
|
|
441
444
|
return lines.join("\n") + "\n";
|
|
@@ -474,8 +477,8 @@ function escapeJsStringLiteral(value) {
|
|
|
474
477
|
function toT3ZodType(envVarType) {
|
|
475
478
|
if (envVarType === "number") return "z.coerce.number()";
|
|
476
479
|
if (envVarType === "boolean") return "z.coerce.boolean()";
|
|
477
|
-
if (envVarType === "url") return "z.
|
|
478
|
-
if (envVarType === "email") return "z.
|
|
480
|
+
if (envVarType === "url") return "z.url()";
|
|
481
|
+
if (envVarType === "email") return "z.email()";
|
|
479
482
|
return "z.string()";
|
|
480
483
|
}
|
|
481
484
|
function buildZodExpr(variable) {
|
|
@@ -546,11 +549,7 @@ Rename it to ${filePath.replace(/\.ts$/, ".mjs")} and use ESM syntax (export def
|
|
|
546
549
|
}
|
|
547
550
|
return void 0;
|
|
548
551
|
}
|
|
549
|
-
var CONFIG_FILE_NAMES = [
|
|
550
|
-
"env-typegen.config.mjs",
|
|
551
|
-
"env-typegen.config.js",
|
|
552
|
-
"env-typegen.config.ts"
|
|
553
|
-
];
|
|
552
|
+
var CONFIG_FILE_NAMES = ["env-typegen.config.mjs", "env-typegen.config.js"];
|
|
554
553
|
function defineConfig(config) {
|
|
555
554
|
return config;
|
|
556
555
|
}
|
|
@@ -558,19 +557,6 @@ async function loadConfig(cwd = process.cwd()) {
|
|
|
558
557
|
for (const name of CONFIG_FILE_NAMES) {
|
|
559
558
|
const filePath = path6__default.default.resolve(cwd, name);
|
|
560
559
|
if (fs.existsSync(filePath)) {
|
|
561
|
-
if (filePath.endsWith(".ts")) {
|
|
562
|
-
throw new Error(
|
|
563
|
-
`Config file "${name}" was found but TypeScript files cannot be loaded directly at runtime.
|
|
564
|
-
Rename it to "env-typegen.config.mjs" and use ESM export syntax:
|
|
565
|
-
|
|
566
|
-
// env-typegen.config.mjs
|
|
567
|
-
import { defineConfig } from "@xlameiro/env-typegen";
|
|
568
|
-
export default defineConfig({ input: ".env.example" });
|
|
569
|
-
|
|
570
|
-
Tip: keep env-typegen.config.ts for IDE autocompletion and create a sibling
|
|
571
|
-
env-typegen.config.mjs for runtime loading.`
|
|
572
|
-
);
|
|
573
|
-
}
|
|
574
560
|
const fileUrl = url.pathToFileURL(filePath).href;
|
|
575
561
|
const mod = await import(fileUrl);
|
|
576
562
|
return mod.default;
|
|
@@ -1847,7 +1833,7 @@ var HELP_TEXT = {
|
|
|
1847
1833
|
"Usage: env-typegen diff [options]",
|
|
1848
1834
|
"",
|
|
1849
1835
|
"Options:",
|
|
1850
|
-
" --targets <list> Comma-separated targets (default: .env,.env.
|
|
1836
|
+
" --targets <list> Comma-separated targets (default: .env,.env.production)",
|
|
1851
1837
|
" --contract <path> Contract file path (default: env.contract.ts)",
|
|
1852
1838
|
" --example <path> Fallback .env.example used to bootstrap contract",
|
|
1853
1839
|
" --strict Validate extras as errors (default: true)",
|
|
@@ -1871,7 +1857,7 @@ var HELP_TEXT = {
|
|
|
1871
1857
|
"",
|
|
1872
1858
|
"Options:",
|
|
1873
1859
|
" --env <path> Environment file to validate (default: .env)",
|
|
1874
|
-
" --targets <list> Comma-separated targets for drift analysis",
|
|
1860
|
+
" --targets <list> Comma-separated targets for drift analysis (default: .env,.env.production)",
|
|
1875
1861
|
" --contract <path> Contract file path (default: env.contract.ts)",
|
|
1876
1862
|
" --example <path> Fallback .env.example used to bootstrap contract",
|
|
1877
1863
|
" --strict Validate extras as errors (default: true)",
|
|
@@ -2004,7 +1990,58 @@ function parseTargets(values, fileConfig) {
|
|
|
2004
1990
|
if (fileConfig?.diffTargets !== void 0 && fileConfig.diffTargets.length > 0) {
|
|
2005
1991
|
return fileConfig.diffTargets;
|
|
2006
1992
|
}
|
|
2007
|
-
return [".env", ".env.
|
|
1993
|
+
return [".env", ".env.production"];
|
|
1994
|
+
}
|
|
1995
|
+
function splitExistingAndMissingTargets(targets) {
|
|
1996
|
+
const existingTargets = [];
|
|
1997
|
+
const missingTargets = [];
|
|
1998
|
+
for (const target of targets) {
|
|
1999
|
+
const resolvedTarget = path6__default.default.resolve(target);
|
|
2000
|
+
if (fs.existsSync(resolvedTarget)) {
|
|
2001
|
+
existingTargets.push(target);
|
|
2002
|
+
continue;
|
|
2003
|
+
}
|
|
2004
|
+
missingTargets.push(target);
|
|
2005
|
+
}
|
|
2006
|
+
return { existingTargets, missingTargets };
|
|
2007
|
+
}
|
|
2008
|
+
function buildMissingTargetIssue(target, missingCount) {
|
|
2009
|
+
const suffix = missingCount === 1 ? "" : "s";
|
|
2010
|
+
return {
|
|
2011
|
+
code: "ENV_MISSING",
|
|
2012
|
+
type: "missing",
|
|
2013
|
+
severity: "error",
|
|
2014
|
+
key: "*",
|
|
2015
|
+
environment: target,
|
|
2016
|
+
message: `Target file ${target} was not found; treating as empty (${missingCount} missing variable${suffix}).`,
|
|
2017
|
+
value: null
|
|
2018
|
+
};
|
|
2019
|
+
}
|
|
2020
|
+
function summarizeDoctorMissingTargetIssues(report, missingTargets) {
|
|
2021
|
+
if (missingTargets.length === 0) return report;
|
|
2022
|
+
const missingTargetSet = new Set(missingTargets);
|
|
2023
|
+
const retainedIssues = report.issues.filter(
|
|
2024
|
+
(issue) => !(issue.code === "ENV_MISSING" && missingTargetSet.has(issue.environment))
|
|
2025
|
+
);
|
|
2026
|
+
const groupedIssues = missingTargets.map((target) => {
|
|
2027
|
+
const missingCount = report.issues.filter(
|
|
2028
|
+
(issue) => issue.code === "ENV_MISSING" && issue.environment === target
|
|
2029
|
+
).length;
|
|
2030
|
+
return buildMissingTargetIssue(target, missingCount);
|
|
2031
|
+
});
|
|
2032
|
+
const issues = [...retainedIssues, ...groupedIssues];
|
|
2033
|
+
const errors = issues.filter((issue) => issue.severity === "error").length;
|
|
2034
|
+
const warnings = issues.filter((issue) => issue.severity === "warning").length;
|
|
2035
|
+
return {
|
|
2036
|
+
...report,
|
|
2037
|
+
status: errors > 0 ? "fail" : "ok",
|
|
2038
|
+
issues,
|
|
2039
|
+
summary: {
|
|
2040
|
+
errors,
|
|
2041
|
+
warnings,
|
|
2042
|
+
total: issues.length
|
|
2043
|
+
}
|
|
2044
|
+
};
|
|
2008
2045
|
}
|
|
2009
2046
|
async function prepareCommonContext(values) {
|
|
2010
2047
|
const fileConfig = await loadCommandConfig(values.config);
|
|
@@ -2089,8 +2126,13 @@ async function runDiffCommand(args) {
|
|
|
2089
2126
|
await loadValidationContract(loadContractOptions),
|
|
2090
2127
|
context.plugins
|
|
2091
2128
|
);
|
|
2129
|
+
const targets = parseTargets(args.values, context.fileConfig);
|
|
2130
|
+
const { existingTargets, missingTargets } = splitExistingAndMissingTargets(targets);
|
|
2131
|
+
for (const missingTarget of missingTargets) {
|
|
2132
|
+
warn(`Target file not found: ${missingTarget} \u2014 treating as empty`);
|
|
2133
|
+
}
|
|
2092
2134
|
const sources = {};
|
|
2093
|
-
for (const target of
|
|
2135
|
+
for (const target of existingTargets) {
|
|
2094
2136
|
const values = await loadEnvSource({ filePath: target, allowMissing: true });
|
|
2095
2137
|
sources[target] = applySourcePlugins({ environment: target, values }, context.plugins);
|
|
2096
2138
|
}
|
|
@@ -2144,8 +2186,13 @@ async function runDoctorCommand(args) {
|
|
|
2144
2186
|
strict: context.strict,
|
|
2145
2187
|
debugValues: context.debugValues
|
|
2146
2188
|
});
|
|
2189
|
+
const targets = parseTargets(args.values, context.fileConfig);
|
|
2190
|
+
const { existingTargets, missingTargets } = splitExistingAndMissingTargets(targets);
|
|
2191
|
+
for (const missingTarget of missingTargets) {
|
|
2192
|
+
warn(`Target file not found: ${missingTarget} \u2014 treating as empty`);
|
|
2193
|
+
}
|
|
2147
2194
|
const sources = {};
|
|
2148
|
-
for (const target of
|
|
2195
|
+
for (const target of existingTargets) {
|
|
2149
2196
|
const values = await loadEnvSource({ filePath: target, allowMissing: true });
|
|
2150
2197
|
sources[target] = applySourcePlugins({ environment: target, values }, context.plugins);
|
|
2151
2198
|
}
|
|
@@ -2167,10 +2214,9 @@ async function runDoctorCommand(args) {
|
|
|
2167
2214
|
strict: context.strict,
|
|
2168
2215
|
debugValues: context.debugValues
|
|
2169
2216
|
});
|
|
2170
|
-
const
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
);
|
|
2217
|
+
const rawReport = buildDoctorReport({ checkReport, diffReport });
|
|
2218
|
+
const summarizedReport = summarizeDoctorMissingTargetIssues(rawReport, missingTargets);
|
|
2219
|
+
const report = applyReportPlugins(summarizedReport, context.plugins);
|
|
2174
2220
|
return emitAndReturnExitCode(report, {
|
|
2175
2221
|
jsonMode: args.jsonMode,
|
|
2176
2222
|
...context.outputFile !== void 0 && { outputFile: context.outputFile }
|