dotenv-mono
Version:
This package permit to have a centralized dotenv on a monorepo. It also includes some extra features such as manipulation and saving of changes to the dotenv file, a default centralized file, and a file loader with ordering and priorities.
137 lines • 4.94 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.DotenvOptionsType = exports.OptionType = void 0;
exports.parseOption = parseOption;
exports.runNodeCli = runNodeCli;
/**
* Configuration option types.
*/
var OptionType;
(function (OptionType) {
OptionType[OptionType["boolean"] = 0] = "boolean";
OptionType[OptionType["number"] = 1] = "number";
OptionType[OptionType["string"] = 2] = "string";
OptionType[OptionType["array"] = 3] = "array";
OptionType[OptionType["object"] = 4] = "object";
OptionType[OptionType["mapOfNumbers"] = 5] = "mapOfNumbers";
})(OptionType || (exports.OptionType = OptionType = {}));
/**
* List of all Dotenv configuration options type.
*/
exports.DotenvOptionsType = {
cwd: OptionType.string,
debug: OptionType.boolean,
defaults: OptionType.string,
depth: OptionType.number,
encoding: OptionType.string,
expand: OptionType.boolean,
extension: OptionType.string,
path: OptionType.string,
override: OptionType.boolean,
priorities: OptionType.mapOfNumbers,
};
/**
* Parse error.
*/
class ParseError extends Error {
constructor(message, option = "") {
super(`${message} Parsed value: ${option}`);
this.name = "ParseError";
}
}
/**
* Parse CLI parameter type.
* @param option - value to parse
* @param type - value type
* @returns parsed option
*/
function parseOption(option, type) {
// Undefined
if (option === undefined || option === null)
return undefined;
// Number
if (type === OptionType.number)
return Number(option);
// Boolean
if (type === OptionType.boolean)
return option === "true";
// Objects
if (type === OptionType.array ||
type === OptionType.object ||
type === OptionType.mapOfNumbers) {
try {
// For mapOfNumbers, we need to handle undefined values specially
// since JSON doesn't support undefined, we'll preprocess the string
let processedOption = option;
if (type === OptionType.mapOfNumbers) {
// Remove undefined values completely from the JSON string
processedOption = option.replace(/,\s*"[^"]*":\s*undefined/g, "");
processedOption = processedOption.replace(/"[^"]*":\s*undefined\s*,/g, "");
processedOption = processedOption.replace(/{\s*"[^"]*":\s*undefined\s*}/g, "{}");
}
const result = JSON.parse(processedOption);
// For arrays, we need to allow Array objects
if (type === OptionType.array) {
// Array check
if (!Array.isArray(result)) {
throw new ParseError(`The value is not an array.`, option);
}
return result;
}
// For other object types, reject arrays
if (typeof result !== "object" || Array.isArray(result)) {
throw new ParseError(`The value is not an object.`, option);
}
// Check if is a map of numbers, null and undefined are allowed
if (type === OptionType.mapOfNumbers) {
for (const [_key, value] of Object.entries(result)) {
if (value !== null && typeof value !== "number") {
throw new ParseError(`The value is not an map of numbers.`, option);
}
}
return result;
}
// Object
return result;
}
catch (e) {
console.error(`Invalid option value!\r\n`, e);
return undefined;
}
}
// String
return option;
}
/**
* Run CLI Dotenv runners.
* @param runner
*/
function runNodeCli(runner) {
// Empty options
const options = {};
// Environment configuration
Object.keys(exports.DotenvOptionsType).forEach((option) => {
const envName = "DOTENV_CONFIG_" + option.toUpperCase();
if (process.env[envName] != null) {
options[option] = parseOption(process.env[envName], exports.DotenvOptionsType[option]);
}
});
// CLI Parameter configuration parser
const args = process.argv;
const keys = Object.keys(exports.DotenvOptionsType).join("|");
const re = new RegExp(`^dotenv_config_(${keys})=(.*)$`, "i");
const cliOptions = args.reduce(function (opts, cur) {
const matches = re.exec(cur);
if (matches) {
const option = String(matches[1]).trim();
const match = String(matches[2]).trim();
opts[option] = parseOption(match, exports.DotenvOptionsType[option]);
}
re.lastIndex = 0; // Reset regex for next iteration
return opts;
}, {});
// Run command
return runner(Object.assign(Object.assign({}, options), cliOptions));
}
//# sourceMappingURL=node-cli.js.map