typed-env
Version:
Typed environment variable parser
87 lines (86 loc) • 2.03 kB
JavaScript
//#region src/index.ts
function createEnv(info, options) {
const env = options?.env ?? (typeof process !== "undefined" ? process.env : null);
if (!env) throw new TypeError("No env specified");
const errors = [];
const config = {};
for (const [key, argInfo] of Object.entries(info)) {
const value = env[key];
if (!value) {
if ("default" in argInfo) config[key] = argInfo.default;
else if (!argInfo.optional) errors.push({
key,
kind: "missing"
});
continue;
}
if ("parser" in argInfo) {
try {
config[key] = argInfo.parser(value);
} catch (error) {
errors.push({
key,
value,
kind: "custom",
error
});
}
continue;
}
if (argInfo.choices && !argInfo.choices.includes(value)) {
errors.push({
key,
value,
kind: "choice",
expected: argInfo.choices
});
continue;
}
switch (argInfo.type) {
case "string":
config[key] = value;
break;
case "number": {
const numberValue = Number(value);
if (Number.isNaN(numberValue)) {
errors.push({
key,
value,
kind: "number"
});
continue;
}
config[key] = numberValue;
break;
}
case "boolean":
config[key] = value.toLowerCase() === "true" || value === "1";
break;
case "array":
config[key] = value.split(/, ?/gu);
break;
}
}
if (errors.length !== 0) {
let message = "The following environment variables are invalid:\n";
for (const error of errors) switch (error.kind) {
case "missing":
message += ` ${error.key} (missing)\n`;
break;
case "number":
message += ` ${error.key}: ${error.value} (expected number)\n`;
break;
case "choice":
message += ` ${error.key}: ${error.value} (expected one of ${error.expected.join(", ")})\n`;
break;
case "custom":
message += ` ${error.key}: ${error.value} (${error.error})\n`;
break;
}
throw new TypeError(message);
}
return config;
}
//#endregion
export { createEnv };
//# sourceMappingURL=index.mjs.map