UNPKG

dotenv-extended

Version:

A module for loading .env files and optionally loading defaults and a schema for validating all values are present.

241 lines (233 loc) 8.08 kB
var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); // src/index.js var import_dotenv2 = __toESM(require("dotenv")); // src/utils/parse-primitive.js var parsePrimitive = (value) => { if (value === null || typeof value === "undefined") { return value; } if (typeof value === "number" || typeof value === "boolean") { return value; } if (typeof value !== "string") { return value; } let normalized = value.trim().replace(/(^"|"$)|(^'|'$)/g, "").toLowerCase(); if (normalized === "" || normalized === "undefined") { return void 0; } if (normalized === "null") { return null; } if (normalized === "nan") { return NaN; } if (normalized === "true" || normalized === "1") { return true; } if (normalized === "false" || normalized === "0") { return false; } const numeric = Number(normalized); if (!Number.isNaN(numeric)) { return numeric; } return value; }; var parse_primitive_default = parsePrimitive; // src/utils/normalize-option-key.js var normalizedWithSeparators = (key) => key.toLowerCase().replace(/[_-\s]+([a-z0-9])/g, (_, next) => next.toUpperCase()); var normalizeOptionKey = (key) => { const trimmed = key.trim(); if (!trimmed) { return ""; } if (/[_-\s]/.test(trimmed)) { return normalizedWithSeparators(trimmed); } if (trimmed === trimmed.toUpperCase()) { return trimmed.toLowerCase(); } return trimmed.charAt(0).toLowerCase() + trimmed.slice(1); }; var normalize_option_key_default = normalizeOptionKey; // src/utils/config-from-env.js var getConfigFromEnv = (env) => { let config2 = {}; Object.keys(env).forEach((key) => { const curr = key.split("DOTENV_CONFIG_"); if (curr.length === 2 && curr[0] === "" && curr[1].length) { config2[normalize_option_key_default(curr[1])] = parse_primitive_default(env[key]); } }); return config2; }; var config_from_env_default = getConfigFromEnv; // src/utils/load-environment-file.js var import_fs = __toESM(require("fs")); var import_dotenv = __toESM(require("dotenv")); var loadEnvironmentFile = (path, encoding, silent, errorOnMissingFiles = false) => { try { const data = import_fs.default.readFileSync(path, encoding); return import_dotenv.default.parse(data); } catch (err) { if (errorOnMissingFiles && err && err.code === "ENOENT") { throw new Error(`MISSING CONFIG FILE: ${path}`); } if (!silent) { console.error(err.message); } return {}; } }; var load_environment_file_default = loadEnvironmentFile; // src/index.js var normalizeLayeredFiles = (value) => { if (!value) { return []; } if (Array.isArray(value)) { return value.filter(Boolean); } if (typeof value === "string") { return value.split(",").map((item) => item.trim()).filter(Boolean); } return []; }; var loadLayeredFiles = (files, options2) => normalizeLayeredFiles(files).reduce((acc, filePath) => { const fileData = load_environment_file_default( filePath, options2.encoding, options2.silent, options2.errorOnMissingFiles ); return Object.assign(acc, fileData); }, {}); var parse = import_dotenv2.default.parse.bind(import_dotenv2.default); var config = (options2) => { let defaultsData, environmentData, defaultOptions = { encoding: "utf8", silent: true, path: ".env", defaults: ".env.defaults", schema: ".env.schema", schemaExtends: void 0, errorOnMissing: false, errorOnExtra: false, errorOnRegex: false, errorOnMissingFiles: false, returnSchemaOnly: false, includeProcessEnv: false, assignToProcessEnv: true, overrideProcessEnv: false }, processEnvOptions = config_from_env_default(process.env); options2 = Object.assign({}, defaultOptions, processEnvOptions, options2); defaultsData = loadLayeredFiles(options2.defaults, options2); environmentData = loadLayeredFiles(options2.path, options2); let configData = Object.assign({}, defaultsData, environmentData); const config2 = options2.includeProcessEnv ? Object.assign({}, configData, process.env) : configData; const configOnlyKeys = Object.keys(configData); const configKeys = Object.keys(config2); let schemaKeys = null; if (options2.errorOnMissing || options2.errorOnExtra || options2.errorOnRegex || options2.returnSchemaOnly) { const baseSchema = load_environment_file_default( options2.schema, options2.encoding, options2.silent, options2.errorOnMissingFiles ); const schema = normalizeLayeredFiles(options2.schemaExtends).reduce( (acc, schemaPath) => { const schemaLayer = load_environment_file_default( schemaPath, options2.encoding, options2.silent, options2.errorOnMissingFiles ); return Object.assign(acc, schemaLayer); }, Object.assign({}, baseSchema) ); schemaKeys = Object.keys(schema); let missingKeys = schemaKeys.filter(function(key) { return configKeys.indexOf(key) < 0; }); let extraKeys = configOnlyKeys.filter(function(key) { return schemaKeys.indexOf(key) < 0; }); if (options2.errorOnMissing && missingKeys.length) { throw new Error("MISSING CONFIG VALUES: " + missingKeys.join(", ")); } if (options2.errorOnExtra && extraKeys.length) { throw new Error("EXTRA CONFIG VALUES: " + extraKeys.join(", ")); } if (options2.errorOnRegex) { const regexMismatchKeys = schemaKeys.filter(function(key) { if (schema[key]) { return !new RegExp(schema[key]).test( typeof config2[key] === "string" ? config2[key] : "" ); } }); if (regexMismatchKeys.length) { throw new Error("REGEX MISMATCH: " + regexMismatchKeys.join(", ")); } } } if (options2.includeProcessEnv && !options2.overrideProcessEnv) { for (let i = 0; i < configKeys.length; i++) { if (typeof process.env[configKeys[i]] !== "undefined") configData[configKeys[i]] = process.env[configKeys[i]]; } } if (options2.returnSchemaOnly && schemaKeys) { configData = schemaKeys.reduce((acc, key) => { if (typeof config2[key] !== "undefined") { acc[key] = config2[key]; } return acc; }, {}); } if (options2.assignToProcessEnv) { if (options2.overrideProcessEnv) { Object.assign(process.env, configData); } else { const tmp = Object.assign({}, configData, process.env); Object.assign(process.env, tmp); } } return configData; }; // src/config.js var reduceArguments = (prev, curr) => { const matches = curr.match(/^dotenv_config_(.+)=(.+)/); return hasMatches(matches) ? expandKeyValFromMatches(matches, prev) : prev; }; var expandKeyValFromMatches = ([, key, value], prev) => ({ ...prev, [key]: value }); var hasMatches = (matches) => matches && matches.length >= 3; var options = process.argv.reduce(reduceArguments, {}); config(options);