Sorry, the diff of this file is not supported yet
| import { EnvCmdOptions } from './types'; | ||
| /** | ||
| * Executes env - cmd using command line arguments | ||
| * @export | ||
| * @param {string[]} args Command line argument to pass in ['-f', './.env'] | ||
| * @returns {Promise<{ [key: string]: any }>} | ||
| */ | ||
| export declare function CLI(args: string[]): Promise<{ | ||
| [key: string]: any; | ||
| }>; | ||
| /** | ||
| * The main env-cmd program. This will spawn a new process and run the given command using | ||
| * various environment file solutions. | ||
| * | ||
| * @export | ||
| * @param {EnvCmdOptions} { command, commandArgs, envFile, rc, options } | ||
| * @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value | ||
| */ | ||
| export declare function EnvCmd({ command, commandArgs, envFile, rc, options }: EnvCmdOptions): Promise<{ | ||
| [key: string]: any; | ||
| }>; |
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const spawn_1 = require("./spawn"); | ||
| const signal_termination_1 = require("./signal-termination"); | ||
| const parse_args_1 = require("./parse-args"); | ||
| const get_env_vars_1 = require("./get-env-vars"); | ||
| /** | ||
| * Executes env - cmd using command line arguments | ||
| * @export | ||
| * @param {string[]} args Command line argument to pass in ['-f', './.env'] | ||
| * @returns {Promise<{ [key: string]: any }>} | ||
| */ | ||
| function CLI(args) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| // Parse the args from the command line | ||
| const parsedArgs = parse_args_1.parseArgs(args); | ||
| // Run EnvCmd | ||
| return exports.EnvCmd(parsedArgs); | ||
| }); | ||
| } | ||
| exports.CLI = CLI; | ||
| /** | ||
| * The main env-cmd program. This will spawn a new process and run the given command using | ||
| * various environment file solutions. | ||
| * | ||
| * @export | ||
| * @param {EnvCmdOptions} { command, commandArgs, envFile, rc, options } | ||
| * @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value | ||
| */ | ||
| function EnvCmd({ command, commandArgs, envFile, rc, options }) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| options = options || {}; | ||
| let env = yield get_env_vars_1.getEnvVars({ envFile, rc }); | ||
| // Override the merge order if --no-override flag set | ||
| if (options.noOverride) { | ||
| env = Object.assign({}, env, process.env); | ||
| } | ||
| else { | ||
| // Add in the system environment variables to our environment list | ||
| env = Object.assign({}, process.env, env); | ||
| } | ||
| // Execute the command with the given environment variables | ||
| const proc = spawn_1.spawn(command, commandArgs, { | ||
| stdio: 'inherit', | ||
| shell: options.useShell, | ||
| env | ||
| }); | ||
| // Handle any termination signals for parent and child proceses | ||
| const signals = new signal_termination_1.TermSignals(); | ||
| signals.handleUncaughtExceptions(); | ||
| signals.handleTermSignals(proc); | ||
| return env; | ||
| }); | ||
| } | ||
| exports.EnvCmd = EnvCmd; |
| import { GetEnvVarOptions } from './types'; | ||
| export declare function getEnvVars(options?: GetEnvVarOptions): Promise<{ | ||
| [key: string]: any; | ||
| }>; | ||
| export declare function getEnvFile({ filePath, fallback }: { | ||
| filePath?: string; | ||
| fallback?: boolean; | ||
| }): Promise<{ | ||
| [key: string]: any; | ||
| }>; | ||
| export declare function getRCFile({ environments, filePath }: { | ||
| environments: string[]; | ||
| filePath?: string; | ||
| }): Promise<{ | ||
| [key: string]: any; | ||
| }>; |
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const parse_rc_file_1 = require("./parse-rc-file"); | ||
| const parse_env_file_1 = require("./parse-env-file"); | ||
| const RC_FILE_DEFAULT_LOCATIONS = ['./.env-cmdrc', './.env-cmdrc.js', './.env-cmdrc.json']; | ||
| const ENV_FILE_DEFAULT_LOCATION = './.env'; | ||
| function getEnvVars(options) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| options = options || {}; | ||
| options.envFile = options.envFile || {}; | ||
| // Check for rc file usage | ||
| if (options.rc) { | ||
| return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath }); | ||
| } | ||
| return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback }); | ||
| }); | ||
| } | ||
| exports.getEnvVars = getEnvVars; | ||
| function getEnvFile({ filePath, fallback }) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| // Use env file | ||
| if (filePath) { | ||
| try { | ||
| return yield parse_env_file_1.getEnvFileVars(filePath); | ||
| } | ||
| catch (e) { } | ||
| if (!fallback) { | ||
| throw new Error(`Unable to locate env file at location (${filePath})`); | ||
| } | ||
| } | ||
| // Use the default env file location | ||
| try { | ||
| return yield parse_env_file_1.getEnvFileVars(ENV_FILE_DEFAULT_LOCATION); | ||
| } | ||
| catch (e) { | ||
| throw new Error(`Unable to locate env file at default location (${ENV_FILE_DEFAULT_LOCATION})`); | ||
| } | ||
| }); | ||
| } | ||
| exports.getEnvFile = getEnvFile; | ||
| function getRCFile({ environments, filePath }) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| // User provided an .rc file path | ||
| if (filePath) { | ||
| try { | ||
| return parse_rc_file_1.getRCFileVars({ environments, filePath }); | ||
| } | ||
| catch (e) { | ||
| throw new Error(`Unable to locate .rc file at location (${filePath})`); | ||
| } | ||
| } | ||
| // Use the default .rc file locations | ||
| for (const path of RC_FILE_DEFAULT_LOCATIONS) { | ||
| try { | ||
| return parse_rc_file_1.getRCFileVars({ environments, filePath: path }); | ||
| } | ||
| catch (e) { } | ||
| } | ||
| throw new Error(`Unable to locate .rc file at default locations (${RC_FILE_DEFAULT_LOCATIONS})`); | ||
| }); | ||
| } | ||
| exports.getRCFile = getRCFile; |
+10
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| /** | ||
| * Prints out some minor help text | ||
| * @return {String} Help text | ||
| */ | ||
| function PrintHelp() { | ||
| return "\nUsage: env-cmd [options] [env_file | env_name] command [command options]\n\nA simple utility for running a cli application using an env config file.\n\nAlso supports using a .env-cmdrc json file in the execution directory to support multiple\nenvironment configs in one file.\n\nOptions:\n --no-override - do not override existing process env vars with file env vars\n --fallback - if provided env file does not exist, attempt to use fallback .env file in root dir\n "; | ||
| } | ||
| exports.PrintHelp = PrintHelp; |
| import { getEnvVars } from './get-env-vars'; | ||
| export * from './types'; | ||
| export * from './env-cmd'; | ||
| export declare const GetEnvVars: typeof getEnvVars; |
| "use strict"; | ||
| function __export(m) { | ||
| for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; | ||
| } | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const get_env_vars_1 = require("./get-env-vars"); | ||
| __export(require("./env-cmd")); | ||
| exports.GetEnvVars = get_env_vars_1.getEnvVars; |
| import { EnvCmdOptions } from './types'; | ||
| /** | ||
| * Parses the arguments passed into the cli | ||
| */ | ||
| export declare function parseArgs(args: string[]): EnvCmdOptions; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const commander_1 = require("commander"); | ||
| const utils_1 = require("./utils"); | ||
| /** | ||
| * Parses the arguments passed into the cli | ||
| */ | ||
| function parseArgs(args) { | ||
| const program = new commander_1.Command(); | ||
| program | ||
| .version('9.0.0', '-v, --version') | ||
| .usage('[options] <command> [...args]') | ||
| .option('-f, --file [path]', 'Custom env file file path (default path: ./.env)') | ||
| .option('-r, --rc-file [path]', 'Custom rc file path (default path: ./.env-cmdrc(|.js|.json)') | ||
| .option('-e, --environments [env1,env2,...]', 'The rc file environment(s) to use', utils_1.parseArgList) | ||
| .option('--fallback', 'Fallback to default env file path, if custom env file path not found') | ||
| .option('--no-override', 'Do not override existing environment variables') | ||
| .option('--use-shell', 'Execute the command in a new shell with the given environment') | ||
| .parse(['_', '_', ...args]); | ||
| // get the command and command args | ||
| const command = program.args[0]; | ||
| const commandArgs = program.args.slice(1); | ||
| const noOverride = !program.override; | ||
| const useShell = !!program.useShell; | ||
| let rc; | ||
| if (program.environments && program.environments.length) { | ||
| rc = rc || {}; | ||
| rc.environments = program.environments; | ||
| rc.filePath = program.rcFile; | ||
| } | ||
| let envFile; | ||
| if (program.file) { | ||
| envFile = envFile || {}; | ||
| envFile.filePath = program.file; | ||
| envFile.fallback = program.fallback; | ||
| } | ||
| return { | ||
| command, | ||
| commandArgs, | ||
| envFile, | ||
| rc, | ||
| options: { | ||
| noOverride, | ||
| useShell | ||
| } | ||
| }; | ||
| } | ||
| exports.parseArgs = parseArgs; |
| /** | ||
| * Gets the environment vars from an env file | ||
| */ | ||
| export declare function getEnvFileVars(envFilePath: string): Promise<{ | ||
| [key: string]: any; | ||
| }>; | ||
| /** | ||
| * Parse out all env vars from a given env file string and return an object | ||
| */ | ||
| export declare function parseEnvString(envFileString: string): { | ||
| [key: string]: string; | ||
| }; | ||
| /** | ||
| * Parse out all env vars from an env file string | ||
| */ | ||
| export declare function parseEnvVars(envString: string): { | ||
| [key: string]: string; | ||
| }; | ||
| /** | ||
| * Strips out comments from env file string | ||
| */ | ||
| export declare function stripComments(envString: string): string; | ||
| /** | ||
| * Strips out newlines from env file string | ||
| */ | ||
| export declare function stripEmptyLines(envString: string): string; |
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const fs = require("fs"); | ||
| const path = require("path"); | ||
| const utils_1 = require("./utils"); | ||
| const REQUIRE_HOOK_EXTENSIONS = ['.json', '.js']; | ||
| /** | ||
| * Gets the environment vars from an env file | ||
| */ | ||
| function getEnvFileVars(envFilePath) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const absolutePath = utils_1.resolveEnvFilePath(envFilePath); | ||
| if (!fs.existsSync(absolutePath)) { | ||
| throw new Error(`Invalid env file path (${envFilePath}).`); | ||
| } | ||
| // Get the file extension | ||
| const ext = path.extname(absolutePath).toLowerCase(); | ||
| let env = {}; | ||
| if (~REQUIRE_HOOK_EXTENSIONS.indexOf(ext)) { | ||
| const possiblePromise = require(absolutePath); /* eslint-disable-line */ | ||
| env = utils_1.isPromise(possiblePromise) ? yield possiblePromise : possiblePromise; | ||
| } | ||
| else { | ||
| const file = fs.readFileSync(absolutePath, { encoding: 'utf8' }); | ||
| env = parseEnvString(file); | ||
| } | ||
| return env; | ||
| }); | ||
| } | ||
| exports.getEnvFileVars = getEnvFileVars; | ||
| /** | ||
| * Parse out all env vars from a given env file string and return an object | ||
| */ | ||
| function parseEnvString(envFileString) { | ||
| // First thing we do is stripe out all comments | ||
| envFileString = stripComments(envFileString.toString()); | ||
| // Next we stripe out all the empty lines | ||
| envFileString = stripEmptyLines(envFileString); | ||
| // Merge the file env vars with the current process env vars (the file vars overwrite process vars) | ||
| return parseEnvVars(envFileString); | ||
| } | ||
| exports.parseEnvString = parseEnvString; | ||
| /** | ||
| * Parse out all env vars from an env file string | ||
| */ | ||
| function parseEnvVars(envString) { | ||
| const envParseRegex = /^((.+?)[=](.*))$/gim; | ||
| const matches = {}; | ||
| let match; | ||
| while ((match = envParseRegex.exec(envString)) !== null) { | ||
| // Note: match[1] is the full env=var line | ||
| const key = match[2].trim(); | ||
| const value = match[3].trim() || ''; | ||
| // remove any surrounding quotes | ||
| matches[key] = value | ||
| .replace(/(^['"]|['"]$)/g, '') | ||
| .replace(`\\n`, `\n`); | ||
| } | ||
| return matches; | ||
| } | ||
| exports.parseEnvVars = parseEnvVars; | ||
| /** | ||
| * Strips out comments from env file string | ||
| */ | ||
| function stripComments(envString) { | ||
| const commentsRegex = /(^#.*$)/gim; | ||
| let match = commentsRegex.exec(envString); | ||
| let newString = envString; | ||
| while (match != null) { | ||
| newString = newString.replace(match[1], ''); | ||
| match = commentsRegex.exec(envString); | ||
| } | ||
| return newString; | ||
| } | ||
| exports.stripComments = stripComments; | ||
| /** | ||
| * Strips out newlines from env file string | ||
| */ | ||
| function stripEmptyLines(envString) { | ||
| const emptyLinesRegex = /(^\n)/gim; | ||
| return envString.replace(emptyLinesRegex, ''); | ||
| } | ||
| exports.stripEmptyLines = stripEmptyLines; |
| /** | ||
| * Gets the env vars from the rc file and rc environments | ||
| */ | ||
| export declare function getRCFileVars({ environments, filePath }: { | ||
| environments: string[]; | ||
| filePath: string; | ||
| }): Promise<{ | ||
| [key: string]: any; | ||
| }>; | ||
| /** | ||
| * Reads and parses the .rc file | ||
| */ | ||
| export declare function parseRCFile(fileData: string): { | ||
| [key: string]: any; | ||
| }; |
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const fs_1 = require("fs"); | ||
| const util_1 = require("util"); | ||
| const path_1 = require("path"); | ||
| const utils_1 = require("./utils"); | ||
| const statAsync = util_1.promisify(fs_1.stat); | ||
| const readFileAsync = util_1.promisify(fs_1.readFile); | ||
| /** | ||
| * Gets the env vars from the rc file and rc environments | ||
| */ | ||
| function getRCFileVars({ environments, filePath }) { | ||
| return __awaiter(this, void 0, void 0, function* () { | ||
| const absolutePath = utils_1.resolveEnvFilePath(filePath); | ||
| try { | ||
| yield statAsync(absolutePath); | ||
| } | ||
| catch (e) { | ||
| throw new Error('Invalid .rc file path.'); | ||
| } | ||
| // Get the file extension | ||
| const ext = path_1.extname(absolutePath).toLowerCase(); | ||
| let parsedData; | ||
| if (ext === '.json' || ext === '.js') { | ||
| const possiblePromise = require(absolutePath); /* eslint-disable-line */ | ||
| parsedData = utils_1.isPromise(possiblePromise) ? yield possiblePromise : possiblePromise; | ||
| } | ||
| else { | ||
| const file = yield readFileAsync(absolutePath, { encoding: 'utf8' }); | ||
| parsedData = parseRCFile(file); | ||
| } | ||
| // Parse and merge multiple rc environments together | ||
| let result = {}; | ||
| let environmentFound = false; | ||
| environments.forEach((name) => { | ||
| const envVars = parsedData[name]; | ||
| if (envVars) { | ||
| environmentFound = true; | ||
| result = Object.assign({}, result, envVars); | ||
| } | ||
| }); | ||
| if (!environmentFound) { | ||
| console.error(`Error: | ||
| Could not find any environments: | ||
| ${environments} | ||
| in .rc file: | ||
| ${absolutePath}`); | ||
| throw new Error(`All environments (${environments}) are missing in in .rc file (${absolutePath}).`); | ||
| } | ||
| return result; | ||
| }); | ||
| } | ||
| exports.getRCFileVars = getRCFileVars; | ||
| /** | ||
| * Reads and parses the .rc file | ||
| */ | ||
| function parseRCFile(fileData) { | ||
| let data; | ||
| try { | ||
| data = JSON.parse(fileData); | ||
| } | ||
| catch (e) { | ||
| console.error(`Error: | ||
| Failed to parse the .rc file. | ||
| Please make sure its a valid JSON format.`); | ||
| throw new Error(`Unable to parse JSON in .rc file.`); | ||
| } | ||
| return data; | ||
| } | ||
| exports.parseRCFile = parseRCFile; |
| /// <reference types="node" /> | ||
| import { ChildProcess } from 'child_process'; | ||
| export declare class TermSignals { | ||
| private terminateSpawnedProcessFuncHandlers; | ||
| _exitCalled: boolean; | ||
| handleTermSignals(proc: ChildProcess): void; | ||
| /** | ||
| * Enables catching of unhandled exceptions | ||
| */ | ||
| handleUncaughtExceptions(): void; | ||
| /** | ||
| * Terminate parent process helper | ||
| */ | ||
| _terminateProcess(code?: number, signal?: string): void; | ||
| /** | ||
| * Exit event listener clean up helper | ||
| */ | ||
| _removeProcessListeners(): void; | ||
| /** | ||
| * General exception handler | ||
| */ | ||
| _uncaughtExceptionHandler(e: Error): void; | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const SIGNALS_TO_HANDLE = [ | ||
| 'SIGINT', 'SIGTERM', 'SIGHUP' | ||
| ]; | ||
| class TermSignals { | ||
| constructor() { | ||
| this.terminateSpawnedProcessFuncHandlers = {}; | ||
| this._exitCalled = false; | ||
| } | ||
| handleTermSignals(proc) { | ||
| // Terminate child process if parent process receives termination events | ||
| SIGNALS_TO_HANDLE.forEach((signal) => { | ||
| this.terminateSpawnedProcessFuncHandlers[signal] = | ||
| (signal, code) => { | ||
| this._removeProcessListeners(); | ||
| if (!this._exitCalled) { | ||
| this._exitCalled = true; | ||
| proc.kill(signal); | ||
| this._terminateProcess(code, signal); | ||
| } | ||
| }; | ||
| process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal]); | ||
| }); | ||
| process.once('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']); | ||
| // Terminate parent process if child process receives termination events | ||
| proc.on('exit', (code, signal) => { | ||
| this._removeProcessListeners(); | ||
| if (!this._exitCalled) { | ||
| this._exitCalled = true; | ||
| this._terminateProcess(code, signal); | ||
| } | ||
| }); | ||
| } | ||
| /** | ||
| * Enables catching of unhandled exceptions | ||
| */ | ||
| handleUncaughtExceptions() { | ||
| process.on('uncaughtException', (e) => this._uncaughtExceptionHandler(e)); | ||
| } | ||
| /** | ||
| * Terminate parent process helper | ||
| */ | ||
| _terminateProcess(code, signal) { | ||
| if (signal != null) { | ||
| return process.kill(process.pid, signal); | ||
| } | ||
| if (code != null) { | ||
| return process.exit(code); | ||
| } | ||
| throw new Error('Unable to terminate parent process successfully'); | ||
| } | ||
| /** | ||
| * Exit event listener clean up helper | ||
| */ | ||
| _removeProcessListeners() { | ||
| SIGNALS_TO_HANDLE.forEach((signal) => { | ||
| process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal]); | ||
| }); | ||
| process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']); | ||
| } | ||
| /** | ||
| * General exception handler | ||
| */ | ||
| _uncaughtExceptionHandler(e) { | ||
| console.error(e.message); | ||
| process.exit(1); | ||
| } | ||
| } | ||
| exports.TermSignals = TermSignals; |
| import * as spawn from 'cross-spawn'; | ||
| export { spawn }; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const spawn = require("cross-spawn"); | ||
| exports.spawn = spawn; |
| export interface GetEnvVarOptions { | ||
| envFile?: { | ||
| filePath?: string; | ||
| fallback?: boolean; | ||
| }; | ||
| rc?: { | ||
| environments: string[]; | ||
| filePath?: string; | ||
| }; | ||
| } | ||
| export interface EnvCmdOptions extends GetEnvVarOptions { | ||
| command: string; | ||
| commandArgs: string[]; | ||
| options?: { | ||
| noOverride?: boolean; | ||
| useShell?: boolean; | ||
| }; | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); |
| /** | ||
| * A simple function for resolving the path the user entered | ||
| */ | ||
| export declare function resolveEnvFilePath(userPath: string): string; | ||
| /** | ||
| * A simple function that parses a comma separated string into an array of strings | ||
| */ | ||
| export declare function parseArgList(list: string): string[]; | ||
| /** | ||
| * A simple function to test if the value is a promise | ||
| */ | ||
| export declare function isPromise(value: any | PromiseLike<Object>): boolean; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| const path = require("path"); | ||
| const os = require("os"); | ||
| /** | ||
| * A simple function for resolving the path the user entered | ||
| */ | ||
| function resolveEnvFilePath(userPath) { | ||
| // Make sure a home directory exist | ||
| const home = os.homedir(); | ||
| if (home) { | ||
| userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`); | ||
| } | ||
| return path.resolve(process.cwd(), userPath); | ||
| } | ||
| exports.resolveEnvFilePath = resolveEnvFilePath; | ||
| /** | ||
| * A simple function that parses a comma separated string into an array of strings | ||
| */ | ||
| function parseArgList(list) { | ||
| return list.split(','); | ||
| } | ||
| exports.parseArgList = parseArgList; | ||
| /** | ||
| * A simple function to test if the value is a promise | ||
| */ | ||
| function isPromise(value) { | ||
| return value && typeof value.then === 'function'; | ||
| } | ||
| exports.isPromise = isPromise; |
+1
-1
| #! /usr/bin/env node | ||
| require('../lib').EnvCmd(process.argv.slice(2)) | ||
| require('../dist').CLI(process.argv.slice(2)) |
+13
-0
| # Changelog | ||
| ## 9.0.0 | ||
| - ***BREAKING***: Converted project to Typescript | ||
| - ***BREAKING***: Changes to all option flags, see docs for new options | ||
| - ***BREAKING***: Dropping support for node v4 and v6 | ||
| - **Change**: Updated all dependencies | ||
| - **Change**: Update package-lock.json file | ||
| - **Feature**: Added support for asynchronous .env and .rc files | ||
| - **Feature**: Added support for a programmatic API | ||
| - **Feature**: Added --use-shell option (thanks to nidkil) | ||
| - **Fix**: Keep newline (`\n`) characters intact when parsing env files | ||
| - **Change**: Added node v10 and v12 to build automation | ||
| - **Change**: Updated Readme file to reflect new options and CLI changes | ||
| ## 8.0.2 | ||
@@ -3,0 +16,0 @@ - **Change**: Updated dependencies and packages.json to fix `npm audit` concerns. |
+1
-1
| MIT License | ||
| Copyright (c) 2017 Todd Bluhm | ||
| Copyright (c) 2019 Todd Bluhm | ||
@@ -5,0 +5,0 @@ Permission is hereby granted, free of charge, to any person obtaining a copy |
+47
-14
| { | ||
| "name": "env-cmd", | ||
| "version": "8.0.2", | ||
| "version": "9.0.0", | ||
| "description": "Executes a command using the envs in the provided env file", | ||
| "main": "lib/index.js", | ||
| "main": "dist/index.js", | ||
| "types": "dist/index.d.ts", | ||
| "engines": { | ||
| "node": ">=4.0.0" | ||
| "node": ">=8.0.0" | ||
| }, | ||
@@ -13,7 +14,8 @@ "bin": { | ||
| "scripts": { | ||
| "test": "mocha", | ||
| "test": "mocha -r ts-node/register ./test/**/*.ts", | ||
| "test-cover": "nyc --reporter=lcov --reporter=text npm test", | ||
| "test-lint": "standard", | ||
| "test-lint": "eslint ./src/**/*.ts ./test/**/*.ts", | ||
| "coveralls": "coveralls < coverage/lcov.info", | ||
| "lint": "standard --fix" | ||
| "lint": "eslint --fix ./src/**/*.ts ./test/**/*.ts", | ||
| "build": "tsc" | ||
| }, | ||
@@ -45,13 +47,44 @@ "repository": { | ||
| "dependencies": { | ||
| "cross-spawn": "^6.0.5" | ||
| "commander": "^2.20.0", | ||
| "cross-spawn": "6.0.5" | ||
| }, | ||
| "devDependencies": { | ||
| "better-assert": "^1.0.2", | ||
| "coveralls": "^3.0.1", | ||
| "mocha": "^5.1.1", | ||
| "nyc": "^11.8.0", | ||
| "proxyquire": "^2.0.1", | ||
| "sinon": "^5.0.7", | ||
| "standard": "^11.0.1" | ||
| "@types/chai": "4.1.7", | ||
| "@types/cross-spawn": "6.0.0", | ||
| "@types/mocha": "5.2.6", | ||
| "@types/node": "^12.0.0", | ||
| "@types/sinon": "^7.0.11", | ||
| "@typescript-eslint/eslint-plugin": "^1.7.0", | ||
| "@typescript-eslint/parser": "^1.7.0", | ||
| "chai": "4.2.0", | ||
| "coveralls": "3.0.3", | ||
| "eslint": "^5.16.0", | ||
| "eslint-config-standard-with-typescript": "^7.0.0", | ||
| "eslint-plugin-import": "^2.17.2", | ||
| "eslint-plugin-node": "^9.0.1", | ||
| "eslint-plugin-promise": "^4.1.1", | ||
| "eslint-plugin-standard": "^4.0.0", | ||
| "mocha": "^6.1.4", | ||
| "nyc": "^14.1.0", | ||
| "sinon": "^7.3.2", | ||
| "ts-node": "^8.1.0", | ||
| "typescript": "^3.4.5" | ||
| }, | ||
| "nyc": { | ||
| "include": [ | ||
| "src/**/*.ts" | ||
| ], | ||
| "extension": [ | ||
| ".ts" | ||
| ], | ||
| "require": [ | ||
| "ts-node/register" | ||
| ], | ||
| "reporter": [ | ||
| "text-summary", | ||
| "html" | ||
| ], | ||
| "sourceMap": true, | ||
| "instrument": true | ||
| } | ||
| } |
+94
-52
@@ -16,3 +16,3 @@ [](https://travis-ci.org/toddbluhm/env-cmd) | ||
| **Environment file `./test/.env`** | ||
| **Environment file `./.env`** | ||
| ``` | ||
@@ -29,56 +29,37 @@ # This is a comment | ||
| "scripts": { | ||
| "test": "env-cmd ./test/.env mocha -R spec" | ||
| "test": "env-cmd mocha -R spec" | ||
| } | ||
| } | ||
| ``` | ||
| or | ||
| **Terminal** | ||
| ```sh | ||
| ./node_modules/.bin/env-cmd ./test/.env node index.js | ||
| ./node_modules/.bin/env-cmd node index.js | ||
| ``` | ||
| ## Advanced Usage | ||
| ### `--fallback` file usage option | ||
| You can specify an `.env.local` (or any name) env file, add that to your `.gitignore` and use that in your local development environment. Then you can use a regular `.env` file in root directory with production configs that can get committed to a private/protected repo. When `env-cmd` cannot find the `.env.local` file it will fallback to looking for a regular `.env` file. | ||
| **Environment file `./.env.local`** | ||
| ## 📜 Help | ||
| ``` | ||
| # This is a comment | ||
| ENV1=THANKS | ||
| ENV2=FOR ALL | ||
| ENV3=THE FISH | ||
| ``` | ||
| **Fallback Environment file `./.env`** | ||
| ``` | ||
| # This can be used as an example fallback | ||
| ENV1=foo | ||
| ENV2=bar | ||
| ENV3=baz | ||
| ENV4=quux | ||
| ENV5=gorge | ||
| ``` | ||
| Usage: _ [options] <command> [...args] | ||
| **Package.json** | ||
| uses `./.env` as a fallback | ||
| ```json | ||
| { | ||
| "scripts": { | ||
| "test": "env-cmd --fallback ./.env.local mocha -R spec" | ||
| } | ||
| } | ||
| Options: | ||
| -v, --version output the version number | ||
| -f, --file [path] Custom env file file path (default path: ./.env) | ||
| -r, --rc-file [path] Custom rc file path (default path: ./.env-cmdrc(|.js|.json) | ||
| -e, --environments [env1,env2,...] The rc file environment(s) to use | ||
| --fallback Fallback to default env file path, if custom env file path not found | ||
| --no-override Do not override existing environment variables | ||
| --use-shell Execute the command in a new shell with the given environment | ||
| -h, --help output usage information | ||
| ``` | ||
| or | ||
| **Terminal** | ||
| ```sh | ||
| # uses ./.env as a fallback, because it can't find `./.env.local` | ||
| ./node_modules/.bin/env-cmd ./.env.local node index.js | ||
| ``` | ||
| ## 🔬 Advanced Usage | ||
| ### `.rc` file usage | ||
| For more complex projects, a `.env-cmdrc` file can be defined in the root directory and supports as many environments as you want. Instead of passing the path to a `.env` file to `env-cmd`, simply pass the name of the environment you want to use thats in your `.env-cmdrc` file. You may also use multiple environment names to merge env vars together. | ||
| For more complex projects, a `.env-cmdrc` file can be defined in the root directory and supports | ||
| as many environments as you want. Simply use the `-e` flag and provide which environments you wish to | ||
| use from the `.env-cmdrc` file. Using multiple environment names will merge the environment variables | ||
| together. Later environments overwrite earlier ones in the list if conflicting environment variables | ||
| are found. | ||
@@ -105,6 +86,6 @@ **.rc file `.env-cmdrc`** | ||
| ```sh | ||
| ./node_modules/.bin/env-cmd production node index.js | ||
| ./node_modules/.bin/env-cmd -e production node index.js | ||
| # Or for multiple environments (where `production` vars override `test` vars, | ||
| # but both are included) | ||
| ./node_modules/.bin/env-cmd test,production node index.js | ||
| ./node_modules/.bin/env-cmd -e test,production node index.js | ||
| ``` | ||
@@ -114,8 +95,37 @@ | ||
| Sometimes you want to set env variables from a file without overriding existing process env vars or shell env vars. | ||
| Prevents overriding of existing environment variables on `process.env` and within the current | ||
| environment. | ||
| ### `--fallback` file usage option | ||
| If the `.env` file does not exist at the provieded custom path, then use the default | ||
| fallback location `./.env` env file instead. | ||
| ### `--use-shell` | ||
| Executes the command within a new shell environment. This is useful if you want to string multiple | ||
| commands together that share the same environment variables. | ||
| **Terminal** | ||
| ```sh | ||
| ENV1=welcome ./node_modules/.bin/env-cmd --no-override ./test/.env node index.js | ||
| ./node_modules/.bin/env-cmd -f ./test/.env --use-shell "node run lint && node test" | ||
| ``` | ||
| ### Asynchronous env file support | ||
| EnvCmd supports reading from asynchronous `.env` files. Instead of using a `.env` file, pass in a `.js` | ||
| file that returns a `Promise` resolving to an object (`{ ENV_VAR_NAME: value, ... }`). Asynchronous `.rc` | ||
| files are also supported using `.js` file extension and resolving to an object with top level environment | ||
| names (`{ production: { ENV_VAR_NAME: value, ... } }`). | ||
| **Terminal** | ||
| ```sh | ||
| ./node_modules/.bin/env-cmd -f ./async-file.js node index.js | ||
| ``` | ||
| ## Examples | ||
| You can find examples of how to use the various options above by visiting | ||
| the examples repo [env-cmd-examples](https://github.com/toddbluhm/env-cmd-examples). | ||
| ## Environment File Formats | ||
@@ -126,3 +136,3 @@ | ||
| - Key/value pairs as JSON | ||
| - JavaScript file exporting an object | ||
| - JavaScript file exporting an `object` or a `Promise` that resolves to an `object` | ||
| - `.env-cmdrc` file (as valid json) in execution directory | ||
@@ -145,7 +155,37 @@ | ||
| ## ⚒ API Usage | ||
| ### `EnvCmd` | ||
| A function that executes a given command in a new child process with the given environment and options | ||
| - **`options`** { `object` } | ||
| - **`command`** { `string` }: The command to execute (`node`, `mocha`, ...) | ||
| - **`commandArgs`** { `string[]` }: List of arguments to pass to the `command` (`['-R', 'Spec']`) | ||
| - **`envFile`** { `object` } | ||
| - **`filePath`** { `string` }: Custom path to .env file to read from (defaults to: `./.env`) | ||
| - **`fallback`** { `boolean` }: Should fall back to default `./.env` file if custom path does not exist | ||
| - **`rc`** { `object` } | ||
| - **`environments`** { `string[]` }: List of environment to read from the `.rc` file | ||
| - **`filePath`** { `string` }: Custom path to the `.rc` file (defaults to: `./.env-cmdrc(|.js|.json)`) | ||
| - **`options`** { `object` } | ||
| - **`noOverride`** { `boolean` }: Prevent `.env` file vars from overriding existing `process.env` vars (default: `false`) | ||
| - **`useShell`** { `boolean` }: Runs command inside a new shell instance (default: `false`) | ||
| - **Returns** { `Promise<object>` }: key is env var name and value is the env var value | ||
| ### `GetEnvVars` | ||
| A function that parses environment variables from a `.env` or a `.rc` file | ||
| - **`options`** { `object` } | ||
| - **`envFile`** { `object` } | ||
| - **`filePath`** { `string` }: Custom path to .env file to read from (defaults to: `./.env`) | ||
| - **`fallback`** { `boolean` }: Should fall back to default `./.env` file if custom path does not exist | ||
| - **`rc`** { `object` } | ||
| - **`environments`** { `string[]` }: List of environment to read from the `.rc` file | ||
| - **`filePath`** { `string` }: Custom path to the `.rc` file (defaults to: `./.env-cmdrc(|.js|.json)`) | ||
| - **Returns** { `Promise<object>` }: key is env var name and value is the env var value | ||
| ## Why | ||
| Because sometimes its just too cumbersome passing lots of environment variables to scripts. Its usually just easier to have a file with all the vars in them, especially for development and testing. | ||
| Because sometimes it is just too cumbersome passing a lot of environment variables to scripts. It is | ||
| usually just easier to have a file with all the vars in them, especially for development and testing. | ||
| **Do not commit sensitive environment data to a public git repo!** | ||
| 🚨**Do not commit sensitive environment data to a public git repo!** 🚨 | ||
@@ -156,7 +196,8 @@ ## Related Projects | ||
| ## Special Thanks | ||
| ## 🎊 Special Thanks | ||
| Special thanks to [`cross-env`](https://github.com/kentcdodds/cross-env) for inspiration (use's the same `cross-spawn` lib underneath too). | ||
| Special thanks to [`cross-env`](https://github.com/kentcdodds/cross-env) for inspiration (use's the | ||
| same `cross-spawn` lib underneath too). | ||
| ## Contributors | ||
| ## 🎉 Contributors | ||
@@ -168,7 +209,8 @@ - Eric Lanehart | ||
| ## Contributing Guide | ||
| I welcome all pull requests. Please make sure you add appropriate test cases for any features added. Before opening a PR please make sure to run the following scripts: | ||
| ## 📋 Contributing Guide | ||
| I welcome all pull requests. Please make sure you add appropriate test cases for any features | ||
| added. Before opening a PR please make sure to run the following scripts: | ||
| - `npm run lint` checks for code errors and formats according to [js-standard](https://github.com/feross/standard) | ||
| - `npm run lint` checks for code errors and format according to [js-standard](https://github.com/feross/standard) | ||
| - `npm test` make sure all tests pass | ||
| - `npm run test-cover` make sure the coverage has not decreased from current master |
| {"/Users/toddbluhm/Development/Github/env-cmd/lib/index.js":{"path":"/Users/toddbluhm/Development/Github/env-cmd/lib/index.js","statementMap":{"0":{"start":{"line":3,"column":14},"end":{"line":3,"column":42}},"1":{"start":{"line":4,"column":13},"end":{"line":4,"column":28}},"2":{"start":{"line":5,"column":11},"end":{"line":5,"column":24}},"3":{"start":{"line":6,"column":11},"end":{"line":6,"column":24}},"4":{"start":{"line":7,"column":23},"end":{"line":7,"column":61}},"5":{"start":{"line":8,"column":27},"end":{"line":8,"column":59}},"6":{"start":{"line":9,"column":44},"end":{"line":9,"column":46}},"7":{"start":{"line":11,"column":26},"end":{"line":13,"column":1}},"8":{"start":{"line":14,"column":20},"end":{"line":16,"column":1}},"9":{"start":{"line":26,"column":21},"end":{"line":26,"column":36}},"10":{"start":{"line":30,"column":2},"end":{"line":35,"column":3}},"11":{"start":{"line":31,"column":4},"end":{"line":31,"column":58}},"12":{"start":{"line":34,"column":4},"end":{"line":34,"column":96}},"13":{"start":{"line":39,"column":2},"end":{"line":44,"column":3}},"14":{"start":{"line":40,"column":4},"end":{"line":40,"column":51}},"15":{"start":{"line":43,"column":4},"end":{"line":43,"column":51}},"16":{"start":{"line":47,"column":15},"end":{"line":50,"column":4}},"17":{"start":{"line":54,"column":2},"end":{"line":57,"column":4}},"18":{"start":{"line":55,"column":4},"end":{"line":55,"column":102}},"19":{"start":{"line":56,"column":4},"end":{"line":56,"column":69}},"20":{"start":{"line":58,"column":2},"end":{"line":58,"column":70}},"21":{"start":{"line":60,"column":2},"end":{"line":60,"column":72}},"22":{"start":{"line":61,"column":2},"end":{"line":61,"column":46}},"23":{"start":{"line":63,"column":2},"end":{"line":63,"column":13}},"24":{"start":{"line":73,"column":2},"end":{"line":75,"column":3}},"25":{"start":{"line":74,"column":4},"end":{"line":74,"column":66}},"26":{"start":{"line":81,"column":20},"end":{"line":81,"column":32}},"27":{"start":{"line":82,"column":2},"end":{"line":99,"column":3}},"28":{"start":{"line":83,"column":16},"end":{"line":83,"column":35}},"29":{"start":{"line":84,"column":4},"end":{"line":87,"column":5}},"30":{"start":{"line":85,"column":6},"end":{"line":85,"column":24}},"31":{"start":{"line":86,"column":6},"end":{"line":86,"column":14}},"32":{"start":{"line":88,"column":4},"end":{"line":91,"column":5}},"33":{"start":{"line":89,"column":6},"end":{"line":89,"column":23}},"34":{"start":{"line":90,"column":6},"end":{"line":90,"column":14}},"35":{"start":{"line":93,"column":4},"end":{"line":98,"column":5}},"36":{"start":{"line":94,"column":6},"end":{"line":94,"column":19}},"37":{"start":{"line":96,"column":6},"end":{"line":96,"column":19}},"38":{"start":{"line":97,"column":6},"end":{"line":97,"column":11}},"39":{"start":{"line":101,"column":2},"end":{"line":107,"column":3}},"40":{"start":{"line":117,"column":24},"end":{"line":117,"column":36}},"41":{"start":{"line":118,"column":14},"end":{"line":118,"column":43}},"42":{"start":{"line":119,"column":18},"end":{"line":119,"column":27}},"43":{"start":{"line":120,"column":2},"end":{"line":123,"column":3}},"44":{"start":{"line":121,"column":4},"end":{"line":121,"column":47}},"45":{"start":{"line":122,"column":4},"end":{"line":122,"column":41}},"46":{"start":{"line":124,"column":2},"end":{"line":124,"column":18}},"47":{"start":{"line":134,"column":26},"end":{"line":134,"column":36}},"48":{"start":{"line":135,"column":2},"end":{"line":135,"column":47}},"49":{"start":{"line":145,"column":24},"end":{"line":145,"column":45}},"50":{"start":{"line":146,"column":18},"end":{"line":146,"column":20}},"51":{"start":{"line":148,"column":2},"end":{"line":157,"column":3}},"52":{"start":{"line":150,"column":16},"end":{"line":150,"column":31}},"53":{"start":{"line":151,"column":16},"end":{"line":151,"column":37}},"54":{"start":{"line":154,"column":4},"end":{"line":154,"column":47}},"55":{"start":{"line":156,"column":4},"end":{"line":156,"column":24}},"56":{"start":{"line":158,"column":2},"end":{"line":158,"column":16}},"57":{"start":{"line":169,"column":2},"end":{"line":169,"column":57}},"58":{"start":{"line":172,"column":2},"end":{"line":172,"column":48}},"59":{"start":{"line":175,"column":2},"end":{"line":175,"column":36}},"60":{"start":{"line":186,"column":2},"end":{"line":193,"column":3}},"61":{"start":{"line":187,"column":4},"end":{"line":187,"column":31}},"62":{"start":{"line":189,"column":4},"end":{"line":191,"column":48}},"63":{"start":{"line":192,"column":4},"end":{"line":192,"column":63}},"64":{"start":{"line":194,"column":2},"end":{"line":194,"column":13}},"65":{"start":{"line":205,"column":19},"end":{"line":205,"column":72}},"66":{"start":{"line":206,"column":21},"end":{"line":206,"column":42}},"67":{"start":{"line":208,"column":15},"end":{"line":208,"column":17}},"68":{"start":{"line":209,"column":19},"end":{"line":209,"column":45}},"69":{"start":{"line":210,"column":2},"end":{"line":217,"column":3}},"70":{"start":{"line":211,"column":4},"end":{"line":215,"column":23}},"71":{"start":{"line":216,"column":4},"end":{"line":216,"column":81}},"72":{"start":{"line":219,"column":2},"end":{"line":224,"column":4}},"73":{"start":{"line":220,"column":20},"end":{"line":220,"column":36}},"74":{"start":{"line":221,"column":4},"end":{"line":223,"column":5}},"75":{"start":{"line":222,"column":6},"end":{"line":222,"column":45}},"76":{"start":{"line":225,"column":2},"end":{"line":225,"column":15}},"77":{"start":{"line":237,"column":22},"end":{"line":237,"column":57}},"78":{"start":{"line":241,"column":2},"end":{"line":247,"column":3}},"79":{"start":{"line":242,"column":4},"end":{"line":242,"column":61}},"80":{"start":{"line":244,"column":4},"end":{"line":246,"column":5}},"81":{"start":{"line":245,"column":6},"end":{"line":245,"column":15}},"82":{"start":{"line":250,"column":2},"end":{"line":256,"column":3}},"83":{"start":{"line":251,"column":4},"end":{"line":255,"column":5}},"84":{"start":{"line":252,"column":6},"end":{"line":252,"column":48}},"85":{"start":{"line":254,"column":6},"end":{"line":254,"column":102}},"86":{"start":{"line":259,"column":14},"end":{"line":259,"column":53}},"87":{"start":{"line":262,"column":14},"end":{"line":264,"column":26}},"88":{"start":{"line":266,"column":2},"end":{"line":266,"column":12}},"89":{"start":{"line":274,"column":2},"end":{"line":285,"column":3}},"90":{"start":{"line":293,"column":2},"end":{"line":295,"column":3}},"91":{"start":{"line":294,"column":4},"end":{"line":294,"column":28}},"92":{"start":{"line":296,"column":2},"end":{"line":296,"column":24}},"93":{"start":{"line":297,"column":2},"end":{"line":297,"column":17}},"94":{"start":{"line":307,"column":15},"end":{"line":307,"column":27}},"95":{"start":{"line":308,"column":2},"end":{"line":310,"column":3}},"96":{"start":{"line":309,"column":4},"end":{"line":309,"column":59}},"97":{"start":{"line":311,"column":2},"end":{"line":311,"column":46}},"98":{"start":{"line":319,"column":2},"end":{"line":319,"column":26}},"99":{"start":{"line":321,"column":2},"end":{"line":325,"column":3}},"100":{"start":{"line":322,"column":4},"end":{"line":322,"column":26}},"101":{"start":{"line":323,"column":4},"end":{"line":323,"column":58}},"102":{"start":{"line":324,"column":4},"end":{"line":324,"column":21}},"103":{"start":{"line":327,"column":2},"end":{"line":329,"column":3}},"104":{"start":{"line":328,"column":4},"end":{"line":328,"column":29}},"105":{"start":{"line":331,"column":2},"end":{"line":331,"column":35}},"106":{"start":{"line":338,"column":2},"end":{"line":338,"column":26}},"107":{"start":{"line":340,"column":2},"end":{"line":348,"column":3}},"108":{"start":{"line":341,"column":4},"end":{"line":341,"column":26}},"109":{"start":{"line":342,"column":4},"end":{"line":345,"column":5}},"110":{"start":{"line":343,"column":6},"end":{"line":343,"column":74}},"111":{"start":{"line":344,"column":6},"end":{"line":344,"column":46}},"112":{"start":{"line":346,"column":4},"end":{"line":346,"column":68}},"113":{"start":{"line":347,"column":4},"end":{"line":347,"column":22}},"114":{"start":{"line":355,"column":2},"end":{"line":357,"column":4}},"115":{"start":{"line":356,"column":4},"end":{"line":356,"column":79}},"116":{"start":{"line":358,"column":2},"end":{"line":358,"column":80}},"117":{"start":{"line":361,"column":0},"end":{"line":361,"column":57}},"118":{"start":{"line":363,"column":0},"end":{"line":378,"column":1}}},"fnMap":{"0":{"name":"EnvCmd","decl":{"start":{"line":24,"column":9},"end":{"line":24,"column":15}},"loc":{"start":{"line":24,"column":23},"end":{"line":64,"column":1}},"line":24},"1":{"name":"(anonymous_1)","decl":{"start":{"line":54,"column":28},"end":{"line":54,"column":29}},"loc":{"start":{"line":54,"column":38},"end":{"line":57,"column":3}},"line":54},"2":{"name":"ParseArgs","decl":{"start":{"line":72,"column":9},"end":{"line":72,"column":18}},"loc":{"start":{"line":72,"column":26},"end":{"line":108,"column":1}},"line":72},"3":{"name":"StripComments","decl":{"start":{"line":116,"column":9},"end":{"line":116,"column":22}},"loc":{"start":{"line":116,"column":35},"end":{"line":125,"column":1}},"line":116},"4":{"name":"StripEmptyLines","decl":{"start":{"line":133,"column":9},"end":{"line":133,"column":24}},"loc":{"start":{"line":133,"column":37},"end":{"line":136,"column":1}},"line":133},"5":{"name":"ParseEnvVars","decl":{"start":{"line":144,"column":9},"end":{"line":144,"column":21}},"loc":{"start":{"line":144,"column":34},"end":{"line":159,"column":1}},"line":144},"6":{"name":"ParseEnvString","decl":{"start":{"line":167,"column":9},"end":{"line":167,"column":23}},"loc":{"start":{"line":167,"column":40},"end":{"line":176,"column":1}},"line":167},"7":{"name":"ParseRCFile","decl":{"start":{"line":184,"column":9},"end":{"line":184,"column":20}},"loc":{"start":{"line":184,"column":32},"end":{"line":195,"column":1}},"line":184},"8":{"name":"UseRCFile","decl":{"start":{"line":204,"column":9},"end":{"line":204,"column":18}},"loc":{"start":{"line":204,"column":29},"end":{"line":226,"column":1}},"line":204},"9":{"name":"(anonymous_9)","decl":{"start":{"line":219,"column":19},"end":{"line":219,"column":20}},"loc":{"start":{"line":219,"column":35},"end":{"line":224,"column":3}},"line":219},"10":{"name":"UseCmdLine","decl":{"start":{"line":236,"column":9},"end":{"line":236,"column":19}},"loc":{"start":{"line":236,"column":30},"end":{"line":267,"column":1}},"line":236},"11":{"name":"PrintHelp","decl":{"start":{"line":273,"column":9},"end":{"line":273,"column":18}},"loc":{"start":{"line":273,"column":22},"end":{"line":286,"column":1}},"line":273},"12":{"name":"HandleUncaughtExceptions","decl":{"start":{"line":292,"column":9},"end":{"line":292,"column":33}},"loc":{"start":{"line":292,"column":38},"end":{"line":298,"column":1}},"line":292},"13":{"name":"ResolveEnvFilePath","decl":{"start":{"line":305,"column":9},"end":{"line":305,"column":27}},"loc":{"start":{"line":305,"column":39},"end":{"line":312,"column":1}},"line":305},"14":{"name":"TerminateSpawnedProc","decl":{"start":{"line":318,"column":9},"end":{"line":318,"column":29}},"loc":{"start":{"line":318,"column":51},"end":{"line":332,"column":1}},"line":318},"15":{"name":"TerminateParentProcess","decl":{"start":{"line":337,"column":9},"end":{"line":337,"column":31}},"loc":{"start":{"line":337,"column":47},"end":{"line":349,"column":1}},"line":337},"16":{"name":"RemoveProcessListeners","decl":{"start":{"line":354,"column":9},"end":{"line":354,"column":31}},"loc":{"start":{"line":354,"column":35},"end":{"line":359,"column":1}},"line":354},"17":{"name":"(anonymous_17)","decl":{"start":{"line":355,"column":28},"end":{"line":355,"column":29}},"loc":{"start":{"line":355,"column":38},"end":{"line":357,"column":3}},"line":355}},"branchMap":{"0":{"loc":{"start":{"line":30,"column":2},"end":{"line":35,"column":3}},"type":"if","locations":[{"start":{"line":30,"column":2},"end":{"line":35,"column":3}},{"start":{"line":30,"column":2},"end":{"line":35,"column":3}}],"line":30},"1":{"loc":{"start":{"line":39,"column":2},"end":{"line":44,"column":3}},"type":"if","locations":[{"start":{"line":39,"column":2},"end":{"line":44,"column":3}},{"start":{"line":39,"column":2},"end":{"line":44,"column":3}}],"line":39},"2":{"loc":{"start":{"line":73,"column":2},"end":{"line":75,"column":3}},"type":"if","locations":[{"start":{"line":73,"column":2},"end":{"line":75,"column":3}},{"start":{"line":73,"column":2},"end":{"line":75,"column":3}}],"line":73},"3":{"loc":{"start":{"line":84,"column":4},"end":{"line":87,"column":5}},"type":"if","locations":[{"start":{"line":84,"column":4},"end":{"line":87,"column":5}},{"start":{"line":84,"column":4},"end":{"line":87,"column":5}}],"line":84},"4":{"loc":{"start":{"line":88,"column":4},"end":{"line":91,"column":5}},"type":"if","locations":[{"start":{"line":88,"column":4},"end":{"line":91,"column":5}},{"start":{"line":88,"column":4},"end":{"line":91,"column":5}}],"line":88},"5":{"loc":{"start":{"line":93,"column":4},"end":{"line":98,"column":5}},"type":"if","locations":[{"start":{"line":93,"column":4},"end":{"line":98,"column":5}},{"start":{"line":93,"column":4},"end":{"line":98,"column":5}}],"line":93},"6":{"loc":{"start":{"line":151,"column":16},"end":{"line":151,"column":37}},"type":"binary-expr","locations":[{"start":{"line":151,"column":16},"end":{"line":151,"column":31}},{"start":{"line":151,"column":35},"end":{"line":151,"column":37}}],"line":151},"7":{"loc":{"start":{"line":210,"column":2},"end":{"line":217,"column":3}},"type":"if","locations":[{"start":{"line":210,"column":2},"end":{"line":217,"column":3}},{"start":{"line":210,"column":2},"end":{"line":217,"column":3}}],"line":210},"8":{"loc":{"start":{"line":210,"column":6},"end":{"line":210,"column":55}},"type":"binary-expr","locations":[{"start":{"line":210,"column":6},"end":{"line":210,"column":27}},{"start":{"line":210,"column":31},"end":{"line":210,"column":55}}],"line":210},"9":{"loc":{"start":{"line":221,"column":4},"end":{"line":223,"column":5}},"type":"if","locations":[{"start":{"line":221,"column":4},"end":{"line":223,"column":5}},{"start":{"line":221,"column":4},"end":{"line":223,"column":5}}],"line":221},"10":{"loc":{"start":{"line":244,"column":4},"end":{"line":246,"column":5}},"type":"if","locations":[{"start":{"line":244,"column":4},"end":{"line":246,"column":5}},{"start":{"line":244,"column":4},"end":{"line":246,"column":5}}],"line":244},"11":{"loc":{"start":{"line":250,"column":2},"end":{"line":256,"column":3}},"type":"if","locations":[{"start":{"line":250,"column":2},"end":{"line":256,"column":3}},{"start":{"line":250,"column":2},"end":{"line":256,"column":3}}],"line":250},"12":{"loc":{"start":{"line":250,"column":6},"end":{"line":250,"column":34}},"type":"binary-expr","locations":[{"start":{"line":250,"column":6},"end":{"line":250,"column":11}},{"start":{"line":250,"column":15},"end":{"line":250,"column":34}}],"line":250},"13":{"loc":{"start":{"line":262,"column":14},"end":{"line":264,"column":26}},"type":"cond-expr","locations":[{"start":{"line":263,"column":6},"end":{"line":263,"column":26}},{"start":{"line":264,"column":6},"end":{"line":264,"column":26}}],"line":262},"14":{"loc":{"start":{"line":262,"column":14},"end":{"line":262,"column":46}},"type":"binary-expr","locations":[{"start":{"line":262,"column":14},"end":{"line":262,"column":29}},{"start":{"line":262,"column":33},"end":{"line":262,"column":46}}],"line":262},"15":{"loc":{"start":{"line":293,"column":2},"end":{"line":295,"column":3}},"type":"if","locations":[{"start":{"line":293,"column":2},"end":{"line":295,"column":3}},{"start":{"line":293,"column":2},"end":{"line":295,"column":3}}],"line":293},"16":{"loc":{"start":{"line":308,"column":2},"end":{"line":310,"column":3}},"type":"if","locations":[{"start":{"line":308,"column":2},"end":{"line":310,"column":3}},{"start":{"line":308,"column":2},"end":{"line":310,"column":3}}],"line":308},"17":{"loc":{"start":{"line":321,"column":2},"end":{"line":325,"column":3}},"type":"if","locations":[{"start":{"line":321,"column":2},"end":{"line":325,"column":3}},{"start":{"line":321,"column":2},"end":{"line":325,"column":3}}],"line":321},"18":{"loc":{"start":{"line":327,"column":2},"end":{"line":329,"column":3}},"type":"if","locations":[{"start":{"line":327,"column":2},"end":{"line":329,"column":3}},{"start":{"line":327,"column":2},"end":{"line":329,"column":3}}],"line":327},"19":{"loc":{"start":{"line":340,"column":2},"end":{"line":348,"column":3}},"type":"if","locations":[{"start":{"line":340,"column":2},"end":{"line":348,"column":3}},{"start":{"line":340,"column":2},"end":{"line":348,"column":3}}],"line":340},"20":{"loc":{"start":{"line":342,"column":4},"end":{"line":345,"column":5}},"type":"if","locations":[{"start":{"line":342,"column":4},"end":{"line":345,"column":5}},{"start":{"line":342,"column":4},"end":{"line":345,"column":5}}],"line":342}},"s":{"0":1,"1":1,"2":1,"3":1,"4":1,"5":1,"6":1,"7":1,"8":1,"9":13,"10":13,"11":7,"12":6,"13":10,"14":1,"15":9,"16":10,"17":10,"18":30,"19":30,"20":10,"21":10,"22":10,"23":10,"24":18,"25":1,"26":17,"27":17,"28":37,"29":37,"30":1,"31":1,"32":36,"33":2,"34":2,"35":34,"36":17,"37":17,"38":17,"39":17,"40":4,"41":4,"42":4,"43":4,"44":2,"45":2,"46":4,"47":4,"48":4,"49":13,"50":13,"51":13,"52":32,"53":32,"54":32,"55":32,"56":13,"57":3,"58":3,"59":3,"60":7,"61":7,"62":1,"63":1,"64":6,"65":7,"66":7,"67":6,"68":6,"69":6,"70":1,"71":1,"72":5,"73":8,"74":8,"75":7,"76":5,"77":6,"78":6,"79":6,"80":2,"81":1,"82":5,"83":1,"84":1,"85":1,"86":4,"87":4,"88":4,"89":2,"90":2,"91":1,"92":2,"93":2,"94":13,"95":13,"96":12,"97":13,"98":7,"99":7,"100":5,"101":5,"102":5,"103":7,"104":1,"105":6,"106":6,"107":6,"108":4,"109":4,"110":1,"111":1,"112":3,"113":3,"114":13,"115":39,"116":13,"117":1,"118":1},"f":{"0":13,"1":30,"2":18,"3":4,"4":4,"5":13,"6":3,"7":7,"8":7,"9":8,"10":6,"11":2,"12":2,"13":13,"14":7,"15":6,"16":13,"17":39},"b":{"0":[7,6],"1":[1,9],"2":[1,17],"3":[1,36],"4":[2,34],"5":[17,17],"6":[32,1],"7":[1,5],"8":[6,3],"9":[7,1],"10":[1,1],"11":[1,4],"12":[5,3],"13":[2,2],"14":[4,3],"15":[1,1],"16":[12,1],"17":[5,2],"18":[1,6],"19":[4,2],"20":[1,3]},"_coverageSchema":"332fd63041d2c1bcb487cc26dd0d5f7d97098a6c","hash":"8b5847db0e8855769a714d8c5ec023e8593c2f17","contentHash":"f87b8cb5f1f2bafcc70fd6954fffebb2_11.6.0"}} |
-375
| 'use strict' | ||
| const spawn = require('cross-spawn').spawn | ||
| const path = require('path') | ||
| const fs = require('fs') | ||
| const os = require('os') | ||
| const rcFileLocation = path.join(process.cwd(), '.env-cmdrc') | ||
| const envFilePathDefault = path.join(process.cwd(), '.env') | ||
| const terminateSpawnedProcessFuncHandlers = {} | ||
| let terminateProcessFuncHandler | ||
| const SIGNALS_TO_HANDLE = [ | ||
| 'SIGINT', 'SIGTERM', 'SIGHUP' | ||
| ] | ||
| const sharedState = { | ||
| exitCalled: false | ||
| } | ||
| /** | ||
| * The main process for reading, parsing, applying and then running the process with env vars | ||
| * @param {Array<String>} args And array if strings representing cli args | ||
| * | ||
| * @return {Object} The child process | ||
| */ | ||
| function EnvCmd (args) { | ||
| // First Parse the args from the command line | ||
| const parsedArgs = ParseArgs(args) | ||
| // If a .rc file was found then use that | ||
| let parsedEnv | ||
| if (fs.existsSync(rcFileLocation)) { | ||
| parsedEnv = UseRCFile({ envFile: parsedArgs.envFile }) | ||
| } else { | ||
| // Try to use a .env file | ||
| parsedEnv = UseCmdLine({ envFile: parsedArgs.envFile, useFallback: parsedArgs.useFallback }) | ||
| } | ||
| let env | ||
| // Override the merge order if --no-override flag set | ||
| if (parsedArgs.noOverride) { | ||
| env = Object.assign({}, parsedEnv, process.env) | ||
| } else { | ||
| // Add in the system environment variables to our environment list | ||
| env = Object.assign({}, process.env, parsedEnv) | ||
| } | ||
| // Execute the command with the given environment variables | ||
| const proc = spawn(parsedArgs.command, parsedArgs.commandArgs, { | ||
| stdio: 'inherit', | ||
| env | ||
| }) | ||
| // Handle a few special signals and then the general node exit event | ||
| // on both parent and spawned process | ||
| SIGNALS_TO_HANDLE.forEach(signal => { | ||
| terminateSpawnedProcessFuncHandlers[signal] = TerminateSpawnedProc.bind(sharedState, proc, signal) | ||
| process.once(signal, terminateSpawnedProcessFuncHandlers[signal]) | ||
| }) | ||
| process.once('exit', terminateSpawnedProcessFuncHandlers['SIGTERM']) | ||
| terminateProcessFuncHandler = TerminateParentProcess.bind(sharedState) | ||
| proc.on('exit', terminateProcessFuncHandler) | ||
| return proc | ||
| } | ||
| /** | ||
| * Parses the arguments passed into the cli | ||
| * @param {Array<String>} args An array of strings to parse the options out of | ||
| * | ||
| * @return {Object} An object containing cli options and commands | ||
| */ | ||
| function ParseArgs (args) { | ||
| if (args.length < 2) { | ||
| throw new Error('Error! Too few arguments passed to env-cmd.') | ||
| } | ||
| let envFile | ||
| let command | ||
| let noOverride | ||
| let useFallback | ||
| let commandArgs = args.slice() | ||
| while (commandArgs.length) { | ||
| const arg = commandArgs.shift() | ||
| if (arg === '--fallback') { | ||
| useFallback = true | ||
| continue | ||
| } | ||
| if (arg === '--no-override') { | ||
| noOverride = true | ||
| continue | ||
| } | ||
| // assume the first arg is the env file (or if using .rc the environment name) | ||
| if (!envFile) { | ||
| envFile = arg | ||
| } else { | ||
| command = arg | ||
| break | ||
| } | ||
| } | ||
| return { | ||
| envFile, | ||
| command, | ||
| commandArgs, | ||
| noOverride, | ||
| useFallback | ||
| } | ||
| } | ||
| /** | ||
| * Strips out comments from env file string | ||
| * @param {String} envString The .env file string | ||
| * | ||
| * @return {String} The .env file string with comments stripped out | ||
| */ | ||
| function StripComments (envString) { | ||
| const commentsRegex = /(^#.*$)/gim | ||
| let match = commentsRegex.exec(envString) | ||
| let newString = envString | ||
| while (match != null) { | ||
| newString = newString.replace(match[1], '') | ||
| match = commentsRegex.exec(envString) | ||
| } | ||
| return newString | ||
| } | ||
| /** | ||
| * Strips out newlines from env file string | ||
| * @param {String} envString The .env file string | ||
| * | ||
| * @return {String} The .env file string with newlines stripped out | ||
| */ | ||
| function StripEmptyLines (envString) { | ||
| const emptyLinesRegex = /(^\n)/gim | ||
| return envString.replace(emptyLinesRegex, '') | ||
| } | ||
| /** | ||
| * Parse out all env vars from an env file string | ||
| * @param {String} envString The .env file string | ||
| * | ||
| * @return {Object} Key/Value pairs corresponding to the .env file data | ||
| */ | ||
| function ParseEnvVars (envString) { | ||
| const envParseRegex = /^((.+?)[=](.*))$/gim | ||
| const matches = {} | ||
| let match | ||
| while ((match = envParseRegex.exec(envString)) !== null) { | ||
| // Note: match[1] is the full env=var line | ||
| const key = match[2].trim() | ||
| let value = match[3].trim() || '' | ||
| // remove any surrounding quotes | ||
| value = value.replace(/(^['"]|['"]$)/g, '') | ||
| matches[key] = value | ||
| } | ||
| return matches | ||
| } | ||
| /** | ||
| * Parse out all env vars from a given env file string and return an object | ||
| * @param {String} envString The .env file string | ||
| * | ||
| * @return {Object} Key/Value pairs of all env vars parsed from files | ||
| */ | ||
| function ParseEnvString (envFileString) { | ||
| // First thing we do is stripe out all comments | ||
| envFileString = StripComments(envFileString.toString()) | ||
| // Next we stripe out all the empty lines | ||
| envFileString = StripEmptyLines(envFileString) | ||
| // Merge the file env vars with the current process env vars (the file vars overwrite process vars) | ||
| return ParseEnvVars(envFileString) | ||
| } | ||
| /** | ||
| * Reads and parses the .env-cmdrc file | ||
| * @param {String} fileData the .env-cmdrc file data (which should be a valid json string) | ||
| * | ||
| * @return {Object} The .env-cmdrc as a parsed JSON object | ||
| */ | ||
| function ParseRCFile (fileData) { | ||
| let data | ||
| try { | ||
| data = JSON.parse(fileData) | ||
| } catch (e) { | ||
| console.error(`Error: | ||
| Could not parse the .env-cmdrc file. | ||
| Please make sure its in a valid JSON format.`) | ||
| throw new Error(`Unable to parse JSON in .env-cmdrc file.`) | ||
| } | ||
| return data | ||
| } | ||
| /** | ||
| * Uses the rc file to get env vars | ||
| * @param {Object} options | ||
| * @param {String} options.envFile The .env-cmdrc file environment to use | ||
| * | ||
| * @return {Object} Key/Value pair of env vars from the .env-cmdrc file | ||
| */ | ||
| function UseRCFile (options) { | ||
| const fileData = fs.readFileSync(rcFileLocation, { encoding: 'utf8' }) | ||
| const parsedData = ParseRCFile(fileData) | ||
| let result = {} | ||
| const envNames = options.envFile.split(',') | ||
| if (envNames.length === 1 && !parsedData[envNames[0]]) { | ||
| console.error(`Error: | ||
| Could not find environment: | ||
| ${options.envFile} | ||
| in .rc file: | ||
| ${rcFileLocation}`) | ||
| throw new Error(`Missing environment ${options.envFile} in .env-cmdrc file.`) | ||
| } | ||
| envNames.forEach(function (name) { | ||
| const envVars = parsedData[name] | ||
| if (envVars) { | ||
| result = Object.assign(result, envVars) | ||
| } | ||
| }) | ||
| return result | ||
| } | ||
| /** | ||
| * Uses the cli passed env file to get env vars | ||
| * @param {Object} options | ||
| * @param {String} options.envFile The .env file name/relative path | ||
| * @param {Boolean} options.useFallback Should we attempt to find a fallback file | ||
| * | ||
| * @return {Object} Key/Value pairing of env vars found in .env file | ||
| */ | ||
| function UseCmdLine (options) { | ||
| const envFilePath = ResolveEnvFilePath(options.envFile) | ||
| // Attempt to open the provided file | ||
| let file | ||
| try { | ||
| file = fs.readFileSync(envFilePath, { encoding: 'utf8' }) | ||
| } catch (err) { | ||
| if (!options.useFallback) { | ||
| return {} | ||
| } | ||
| } | ||
| // If we don't have a main file try the fallback file | ||
| if (!file && options.useFallback) { | ||
| try { | ||
| file = fs.readFileSync(envFilePathDefault) | ||
| } catch (e) { | ||
| throw new Error(`Error! Could not find fallback file or read env file at ${envFilePathDefault}`) | ||
| } | ||
| } | ||
| // Get the file extension | ||
| const ext = path.extname(envFilePath).toLowerCase() | ||
| // Parse the env file string using the correct parser | ||
| const env = ext === '.json' || ext === '.js' | ||
| ? require(envFilePath) | ||
| : ParseEnvString(file) | ||
| return env | ||
| } | ||
| /** | ||
| * Prints out some minor help text | ||
| * @return {String} Help text | ||
| */ | ||
| function PrintHelp () { | ||
| return ` | ||
| Usage: env-cmd [options] [env_file | env_name] command [command options] | ||
| A simple utility for running a cli application using an env config file. | ||
| Also supports using a .env-cmdrc json file in the execution directory to support multiple | ||
| environment configs in one file. | ||
| Options: | ||
| --no-override - do not override existing process env vars with file env vars | ||
| --fallback - if provided env file does not exist, attempt to use fallback .env file in root dir | ||
| ` | ||
| } | ||
| /** | ||
| * General exception handler | ||
| * @param {Error} e The exception error to handle | ||
| */ | ||
| function HandleUncaughtExceptions (e) { | ||
| if (e.message.match(/passed/gi)) { | ||
| console.log(PrintHelp()) | ||
| } | ||
| console.log(e.message) | ||
| process.exit(1) | ||
| } | ||
| /** | ||
| * A simple function for resolving the path the user entered | ||
| * @param {String} userPath A path | ||
| * @return {String} The fully qualified absolute path | ||
| */ | ||
| function ResolveEnvFilePath (userPath) { | ||
| // Make sure a home directory exist | ||
| const home = os.homedir() | ||
| if (home) { | ||
| userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`) | ||
| } | ||
| return path.resolve(process.cwd(), userPath) | ||
| } | ||
| /** | ||
| * Helper for terminating the spawned process | ||
| * @param {ProccessHandler} proc The spawned process handler | ||
| */ | ||
| function TerminateSpawnedProc (proc, signal, code) { | ||
| RemoveProcessListeners() | ||
| if (!this.exitCalled) { | ||
| this.exitCalled = true | ||
| proc.kill(signal) | ||
| } | ||
| if (code) { | ||
| return process.exit(code) | ||
| } | ||
| process.kill(process.pid, signal) | ||
| } | ||
| /** | ||
| * Helper for terminating the parent process | ||
| */ | ||
| function TerminateParentProcess (code, signal) { | ||
| RemoveProcessListeners() | ||
| if (!this.exitCalled) { | ||
| this.exitCalled = true | ||
| if (signal) { | ||
| return process.kill(process.pid, signal) | ||
| } | ||
| process.exit(code) | ||
| } | ||
| } | ||
| /** | ||
| * Helper for removing all termination signal listeners from parent process | ||
| */ | ||
| function RemoveProcessListeners () { | ||
| SIGNALS_TO_HANDLE.forEach(signal => { | ||
| process.removeListener(signal, terminateSpawnedProcessFuncHandlers[signal]) | ||
| }) | ||
| process.removeListener('exit', terminateSpawnedProcessFuncHandlers['SIGTERM']) | ||
| } | ||
| process.on('uncaughtException', HandleUncaughtExceptions) | ||
| module.exports = { | ||
| EnvCmd, | ||
| ParseArgs, | ||
| ParseEnvString, | ||
| PrintHelp, | ||
| HandleUncaughtExceptions, | ||
| TerminateSpawnedProc, | ||
| TerminateParentProcess, | ||
| StripComments, | ||
| StripEmptyLines, | ||
| ParseEnvVars, | ||
| ParseRCFile, | ||
| UseRCFile, | ||
| UseCmdLine, | ||
| ResolveEnvFilePath | ||
| } |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Shell access
Supply chain riskThis module accesses the system shell. Accessing the system shell increases the risk of executing arbitrary code.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
AI-detected potential code anomaly
Supply chain riskAI has identified unusual behaviors that may pose a security risk.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Filesystem access
Supply chain riskAccesses the file system, and could potentially read sensitive data.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
45646
11.23%27
200%619
85.89%209
25.15%2
100%20
185.71%7
40%2
100%+ Added
+ Added
+ Added
- Removed
Updated