@st4rbugs/ensure-env
Version:
Type-Safe Env Validator and Parser
113 lines (110 loc) • 4.22 kB
JavaScript
// src/ensure-env.ts
var parseProps = (props) => {
if (typeof props === "string") {
return { name: props };
}
return props;
};
function ensureEnv(props) {
if (process?.env === void 0) throw new Error("process.env is not available in this environment");
const { name, required = true, parser, fallback } = parseProps(props);
const value = process.env[name];
const hasValue = value !== void 0 && value !== "";
if (!hasValue && fallback !== void 0) return fallback;
else if (!hasValue && required) throw new Error(`Missing environment variable: ${name}`);
else if (!hasValue) return void 0;
const parsedValue = parser ? parser(value) : value;
if (typeof parsedValue === "number" && isNaN(parsedValue)) {
if (required) throw new Error(`Invalid value for environment variable: ${name}`);
console.warn(`Warn: Expected a number, but received NaN for environment variable: ${name}`);
return void 0;
}
if (typeof parsedValue === "string") {
const trimmedValue = parsedValue.trim();
if (trimmedValue === "" && required) {
throw new Error(`Invalid value for environment variable: ${name}`);
} else if (trimmedValue === "") {
console.warn(`Warn: Expected a non-empty string, but received an empty string for environment variable: ${name}`);
return void 0;
} else {
return trimmedValue;
}
}
return parsedValue;
}
// src/env-parsers.ts
var AbstractDefaultParsers = class {
/**
* Parses a string into a boolean.
* Returns `true` if the input is '1', 'true', or 'yes' (case-insensitive).
*/
static booleanParser;
/**
* Parses a string into an integer.
* Uses radix 10 to avoid unexpected results.
*/
static intParser;
/** Parses a string into a floating-point number. */
static floatParser;
/** Returns the input string as-is. */
static stringParser;
/**
* Parses a JSON string into an object.
* Note: This can throw a SyntaxError if the input is not valid JSON.
*/
static jsonParser;
/**
* Parses a string into an array of type T using the provided parser and optional delimiter.
* If no delimiter is provided, a comma is used as the default delimiter.
* @param args - The delimiter and parser to convert each array element.
*/
static arrayParser;
};
var DefaultParsers = class _DefaultParsers extends AbstractDefaultParsers {
static booleanValues = ["1", "true", "yes"];
static delimiter = ",";
static stringParser = (value) => value;
static booleanParser = (value) => {
return _DefaultParsers.booleanValues.includes(value.trim().toLowerCase());
};
static intParser = (value) => parseInt(value, 10);
static floatParser = (value) => parseFloat(value);
static jsonParser = (value) => JSON.parse(value);
static arrayParser(...args) {
const [delimiter, parser] = _DefaultParsers.parseArgs(args);
return (value) => value.split(delimiter).map((v) => parser(v));
}
/**
* Parses the arguments provided to arrayParser and returns the delimiter and parser.
* @param args - The arguments passed to arrayParser.
* @returns A tuple containing the delimiter and parser.
* @throws Error if the arguments are invalid.
*/
static parseArgs(args) {
if (args.length === 0) return [_DefaultParsers.delimiter, _DefaultParsers.stringParser];
if (args.length === 1) {
const firstArg = args[0];
if (typeof firstArg === "string") {
return [firstArg, _DefaultParsers.stringParser];
} else if (typeof firstArg === "function") {
return [_DefaultParsers.delimiter, firstArg];
} else if (typeof firstArg === "object" && "delimiter" in firstArg && "parser" in firstArg) {
return [firstArg.delimiter, firstArg.parser];
}
} else if (args.length === 2) {
const [delim, pars] = args;
if (typeof delim === "string" && typeof pars === "function") {
return [delim, pars];
}
}
throw new Error(
"Invalid arguments for arrayParser. Expected either a delimiter and parser, a parser alone, or an object with delimiter and parser."
);
}
};
// src/index.ts
var index_default = ensureEnv;
export {
DefaultParsers as EnvParsers,
index_default as default
};