envalid
Version:
Validation for your environment variables
87 lines • 3.87 kB
JavaScript
;
exports.__esModule = true;
exports.getSanitizedEnv = exports.testOnlySymbol = void 0;
var errors_1 = require("./errors");
var reporter_1 = require("./reporter");
exports.testOnlySymbol = Symbol('envalid - test only');
/**
* Validate a single env var, given a spec object
*
* @throws EnvError - If validation is unsuccessful
* @return - The cleaned value
*/
function validateVar(_a) {
var spec = _a.spec, name = _a.name, rawValue = _a.rawValue;
if (typeof spec._parse !== 'function') {
throw new errors_1.EnvError("Invalid spec for \"" + name + "\"");
}
var value = spec._parse(rawValue);
if (spec.choices) {
if (!Array.isArray(spec.choices)) {
throw new TypeError("\"choices\" must be an array (in spec for \"" + name + "\")");
}
else if (!spec.choices.includes(value)) {
throw new errors_1.EnvError("Value \"" + value + "\" not in choices [" + spec.choices + "]");
}
}
if (value == null)
throw new errors_1.EnvError("Invalid value for env var \"" + name + "\"");
return value;
}
// Format a string error message for when a required env var is missing
function formatSpecDescription(spec) {
var egText = spec.example ? " (eg. \"" + spec.example + "\")" : '';
var docsText = spec.docs ? ". See " + spec.docs : '';
return "" + spec.desc + egText + docsText;
}
var readRawEnvValue = function (env, k) {
return env[k];
};
var isTestOnlySymbol = function (value) { return value === exports.testOnlySymbol; };
/**
* Perform the central validation/sanitization logic on the full environment object
*/
function getSanitizedEnv(environment, specs, options) {
var _a;
if (options === void 0) { options = {}; }
var cleanedEnv = {};
var errors = {};
var varKeys = Object.keys(specs);
var rawNodeEnv = readRawEnvValue(environment, 'NODE_ENV');
for (var _i = 0, varKeys_1 = varKeys; _i < varKeys_1.length; _i++) {
var k = varKeys_1[_i];
var spec = specs[k];
// Use devDefault values only if NODE_ENV was explicitly set, and isn't 'production'
var usingDevDefault = rawNodeEnv && rawNodeEnv !== 'production' && spec.hasOwnProperty('devDefault');
var devDefaultValue = usingDevDefault ? spec.devDefault : undefined;
var rawValue = (_a = readRawEnvValue(environment, k)) !== null && _a !== void 0 ? _a : (devDefaultValue === undefined ? spec["default"] : devDefaultValue);
// Default values can be anything falsy (including an explicitly set undefined), without
// triggering validation errors:
var usingFalsyDefault = (spec.hasOwnProperty('default') && spec["default"] === rawValue) ||
(usingDevDefault && devDefaultValue === rawValue);
try {
if (isTestOnlySymbol(rawValue)) {
throw new errors_1.EnvMissingError(formatSpecDescription(spec));
}
if (rawValue === undefined) {
if (!usingFalsyDefault)
throw new errors_1.EnvMissingError(formatSpecDescription(spec));
// @ts-ignore (fixes #138) Need to figure out why explicitly undefined default/devDefault breaks inference
cleanedEnv[k] = undefined;
}
else {
cleanedEnv[k] = validateVar({ name: k, spec: spec, rawValue: rawValue });
}
}
catch (err) {
if ((options === null || options === void 0 ? void 0 : options.reporter) === null)
throw err;
errors[k] = err;
}
}
var reporter = (options === null || options === void 0 ? void 0 : options.reporter) || reporter_1.defaultReporter;
reporter({ errors: errors, env: cleanedEnv });
return cleanedEnv;
}
exports.getSanitizedEnv = getSanitizedEnv;
//# sourceMappingURL=core.js.map