Updated typescript-eslint packages and fixed lint errors

- Updated commander
- Brought coverage back up to 100%
- Updated tsconfig to adhere to linter parser update
This commit is contained in:
Todd Bluhm 2019-08-28 03:13:50 -05:00
parent ae7981691e
commit f5e2e33939
No known key found for this signature in database
GPG Key ID: 9CF312607477B8AB
34 changed files with 186 additions and 160 deletions

3
.gitignore vendored
View File

@ -10,3 +10,6 @@ package-lock.json
# Code Editor directory # Code Editor directory
.vscode .vscode
# Ignore compiled dist/tests
dist/test

66
dist/get-env-vars.js vendored
View File

@ -1,66 +0,0 @@
"use strict";
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_LOCATIONS = ['./.env', './.env.js', './.env.json'];
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 locations
for (const path of ENV_FILE_DEFAULT_LOCATIONS) {
try {
return yield parse_env_file_1.getEnvFileVars(path);
}
catch (e) { }
}
throw new Error(`Unable to locate env file at default locations (${ENV_FILE_DEFAULT_LOCATIONS})`);
});
}
exports.getEnvFile = getEnvFile;
async function getRCFile({ environments, filePath }) {
// User provided an .rc file path
if (filePath) {
try {
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
}
catch (e) {
if (e.name !== 'PathError')
console.log(e);
throw new Error(`Unable to locate .rc file at location (${filePath})`);
}
}
// Use the default .rc file locations
for (const filePath of RC_FILE_DEFAULT_LOCATIONS) {
try {
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
}
catch (e) {
if (e.name !== 'PathError')
console.log(e);
}
}
throw new Error(`Unable to locate .rc file at default locations (${RC_FILE_DEFAULT_LOCATIONS})`);
}
exports.getRCFile = getRCFile;

View File

@ -31,11 +31,10 @@ exports.CLI = CLI;
* @param {EnvCmdOptions} { command, commandArgs, envFile, rc, options } * @param {EnvCmdOptions} { command, commandArgs, envFile, rc, options }
* @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value * @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value
*/ */
async function EnvCmd({ command, commandArgs, envFile, rc, options }) { async function EnvCmd({ command, commandArgs, envFile, rc, options = {} }) {
options = options || {};
let env = await get_env_vars_1.getEnvVars({ envFile, rc }); let env = await get_env_vars_1.getEnvVars({ envFile, rc });
// Override the merge order if --no-override flag set // Override the merge order if --no-override flag set
if (options.noOverride) { if (options.noOverride === true) {
env = Object.assign({}, env, process.env); env = Object.assign({}, env, process.env);
} }
else { else {

61
dist/src/get-env-vars.js vendored Normal file
View File

@ -0,0 +1,61 @@
"use strict";
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_LOCATIONS = ['./.env', './.env.js', './.env.json'];
async function getEnvVars(options = {}) {
options.envFile = options.envFile !== undefined ? options.envFile : {};
// Check for rc file usage
if (options.rc !== undefined) {
return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath });
}
return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback });
}
exports.getEnvVars = getEnvVars;
async function getEnvFile({ filePath, fallback }) {
// Use env file
if (filePath !== undefined) {
try {
return await parse_env_file_1.getEnvFileVars(filePath);
}
catch (e) { }
if (fallback !== true) {
throw new Error(`Unable to locate env file at location (${filePath})`);
}
}
// Use the default env file locations
for (const path of ENV_FILE_DEFAULT_LOCATIONS) {
try {
return await parse_env_file_1.getEnvFileVars(path);
}
catch (e) { }
}
throw new Error(`Unable to locate env file at default locations (${ENV_FILE_DEFAULT_LOCATIONS})`);
}
exports.getEnvFile = getEnvFile;
async function getRCFile({ environments, filePath }) {
// User provided an .rc file path
if (filePath !== undefined) {
try {
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
}
catch (e) {
if (e.name !== 'PathError')
console.error(e);
throw new Error(`Unable to locate .rc file at location (${filePath})`);
}
}
// Use the default .rc file locations
for (const filePath of RC_FILE_DEFAULT_LOCATIONS) {
try {
return await parse_rc_file_1.getRCFileVars({ environments, filePath });
}
catch (e) {
if (e.name !== 'PathError')
console.error(e);
}
}
throw new Error(`Unable to locate .rc file at default locations (${RC_FILE_DEFAULT_LOCATIONS})`);
}
exports.getRCFile = getRCFile;

View File

View File

@ -15,16 +15,18 @@ function parseArgs(args) {
const noOverride = !program.override; const noOverride = !program.override;
const useShell = !!program.useShell; const useShell = !!program.useShell;
let rc; let rc;
if (program.environments && program.environments.length) { if (program.environments !== undefined && program.environments.length !== 0) {
rc = rc || {}; rc = {
rc.environments = program.environments; environments: program.environments,
rc.filePath = program.rcFile; filePath: program.rcFile
};
} }
let envFile; let envFile;
if (program.file) { if (program.file !== undefined) {
envFile = envFile || {}; envFile = {
envFile.filePath = program.file; filePath: program.file,
envFile.fallback = program.fallback; fallback: program.fallback
};
} }
return { return {
command, command,

View File

@ -15,7 +15,7 @@ async function getEnvFileVars(envFilePath) {
// Get the file extension // Get the file extension
const ext = path.extname(absolutePath).toLowerCase(); const ext = path.extname(absolutePath).toLowerCase();
let env = {}; let env = {};
if (~REQUIRE_HOOK_EXTENSIONS.indexOf(ext)) { if (REQUIRE_HOOK_EXTENSIONS.indexOf(ext) > -1) {
const possiblePromise = require(absolutePath); /* eslint-disable-line */ const possiblePromise = require(absolutePath); /* eslint-disable-line */
env = utils_1.isPromise(possiblePromise) ? await possiblePromise : possiblePromise; env = utils_1.isPromise(possiblePromise) ? await possiblePromise : possiblePromise;
} }
@ -48,11 +48,11 @@ function parseEnvVars(envString) {
while ((match = envParseRegex.exec(envString)) !== null) { while ((match = envParseRegex.exec(envString)) !== null) {
// Note: match[1] is the full env=var line // Note: match[1] is the full env=var line
const key = match[2].trim(); const key = match[2].trim();
const value = match[3].trim() || ''; const value = match[3].trim();
// remove any surrounding quotes // remove any surrounding quotes
matches[key] = value matches[key] = value
.replace(/(^['"]|['"]$)/g, '') .replace(/(^['"]|['"]$)/g, '')
.replace(/\\n/g, `\n`); .replace(/\\n/g, '\n');
} }
return matches; return matches;
} }

View File

@ -35,7 +35,7 @@ async function getRCFileVars({ environments, filePath }) {
let environmentFound = false; let environmentFound = false;
environments.forEach((name) => { environments.forEach((name) => {
const envVars = parsedData[name]; const envVars = parsedData[name];
if (envVars) { if (envVars !== undefined) {
environmentFound = true; environmentFound = true;
result = Object.assign({}, result, envVars); result = Object.assign({}, result, envVars);
} }
@ -63,7 +63,7 @@ function parseRCFile(fileData) {
console.error(`Error: console.error(`Error:
Failed to parse the .rc file. Failed to parse the .rc file.
Please make sure its a valid JSON format.`); Please make sure its a valid JSON format.`);
throw new Error(`Unable to parse JSON in .rc file.`); throw new Error('Unable to parse JSON in .rc file.');
} }
return data; return data;
} }

View File

@ -1,7 +1,7 @@
/// <reference types="node" /> /// <reference types="node" />
import { ChildProcess } from 'child_process'; import { ChildProcess } from 'child_process';
export declare class TermSignals { export declare class TermSignals {
private terminateSpawnedProcessFuncHandlers; private readonly terminateSpawnedProcessFuncHandlers;
_exitCalled: boolean; _exitCalled: boolean;
handleTermSignals(proc: ChildProcess): void; handleTermSignals(proc: ChildProcess): void;
/** /**

View File

@ -22,7 +22,7 @@ class TermSignals {
}; };
process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal]); process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal]);
}); });
process.once('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']); process.once('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM);
// Terminate parent process if child process receives termination events // Terminate parent process if child process receives termination events
proc.on('exit', (code, signal) => { proc.on('exit', (code, signal) => {
this._removeProcessListeners(); this._removeProcessListeners();
@ -42,10 +42,10 @@ class TermSignals {
* Terminate parent process helper * Terminate parent process helper
*/ */
_terminateProcess(code, signal) { _terminateProcess(code, signal) {
if (signal != null) { if (signal !== undefined) {
return process.kill(process.pid, signal); return process.kill(process.pid, signal);
} }
if (code != null) { if (code !== undefined) {
return process.exit(code); return process.exit(code);
} }
throw new Error('Unable to terminate parent process successfully'); throw new Error('Unable to terminate parent process successfully');
@ -57,7 +57,7 @@ class TermSignals {
SIGNALS_TO_HANDLE.forEach((signal) => { SIGNALS_TO_HANDLE.forEach((signal) => {
process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal]); process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal]);
}); });
process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']); process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM);
} }
/** /**
* General exception handler * General exception handler

View File

View File

View File

@ -9,4 +9,4 @@ export declare function parseArgList(list: string): string[];
/** /**
* A simple function to test if the value is a promise * A simple function to test if the value is a promise
*/ */
export declare function isPromise(value: any | PromiseLike<Object>): boolean; export declare function isPromise(value: any | PromiseLike<Object>): value is Promise<any>;

View File

@ -8,7 +8,7 @@ const os = require("os");
function resolveEnvFilePath(userPath) { function resolveEnvFilePath(userPath) {
// Make sure a home directory exist // Make sure a home directory exist
const home = os.homedir(); const home = os.homedir();
if (home) { if (home !== undefined) {
userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`); userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`);
} }
return path.resolve(process.cwd(), userPath); return path.resolve(process.cwd(), userPath);
@ -25,6 +25,6 @@ exports.parseArgList = parseArgList;
* A simple function to test if the value is a promise * A simple function to test if the value is a promise
*/ */
function isPromise(value) { function isPromise(value) {
return value && typeof value.then === 'function'; return value !== undefined && typeof value.then === 'function';
} }
exports.isPromise = isPromise; exports.isPromise = isPromise;

View File

@ -2,8 +2,8 @@
"name": "env-cmd", "name": "env-cmd",
"version": "10.0.0", "version": "10.0.0",
"description": "Executes a command using the environment variables in an env file", "description": "Executes a command using the environment variables in an env file",
"main": "dist/index.js", "main": "dist/src/index.js",
"types": "dist/index.d.ts", "types": "dist/src/index.d.ts",
"engines": { "engines": {
"node": ">=8.0.0" "node": ">=8.0.0"
}, },
@ -48,7 +48,7 @@
}, },
"homepage": "https://github.com/toddbluhm/env-cmd#readme", "homepage": "https://github.com/toddbluhm/env-cmd#readme",
"dependencies": { "dependencies": {
"commander": "^2.0.0", "commander": "^3.0.0",
"cross-spawn": "^6.0.0" "cross-spawn": "^6.0.0"
}, },
"devDependencies": { "devDependencies": {
@ -57,12 +57,13 @@
"@types/mocha": "^5.0.0", "@types/mocha": "^5.0.0",
"@types/node": "^12.0.0", "@types/node": "^12.0.0",
"@types/sinon": "^7.0.0", "@types/sinon": "^7.0.0",
"@typescript-eslint/eslint-plugin": "^1.0.0", "@typescript-eslint/eslint-plugin": "^2.0.0",
"@typescript-eslint/parser": "^1.0.0", "@typescript-eslint/parser": "^2.0.0",
"chai": "^4.0.0", "chai": "^4.0.0",
"coveralls": "^3.0.0", "coveralls": "^3.0.0",
"eslint": "^5.0.0", "eslint": "^6.0.0",
"eslint-config-standard-with-typescript": "^8.0.0", "eslint-config-standard": "^14.0.0",
"eslint-config-standard-with-typescript": "toddbluhm/eslint-config-standard-with-typescript#compiled",
"eslint-plugin-import": "^2.0.0", "eslint-plugin-import": "^2.0.0",
"eslint-plugin-node": "^9.0.0", "eslint-plugin-node": "^9.0.0",
"eslint-plugin-promise": "^4.0.0", "eslint-plugin-promise": "^4.0.0",

View File

@ -32,12 +32,11 @@ export async function CLI (args: string[]): Promise<{ [key: string]: any }> {
* @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value * @returns {Promise<{ [key: string]: any }>} Returns an object containing [environment variable name]: value
*/ */
export async function EnvCmd ( export async function EnvCmd (
{ command, commandArgs, envFile, rc, options }: EnvCmdOptions { command, commandArgs, envFile, rc, options = {} }: EnvCmdOptions
): Promise<{ [key: string]: any }> { ): Promise<{ [key: string]: any }> {
options = options || {}
let env = await getEnvVars({ envFile, rc }) let env = await getEnvVars({ envFile, rc })
// Override the merge order if --no-override flag set // Override the merge order if --no-override flag set
if (options.noOverride) { if (options.noOverride === true) {
env = Object.assign({}, env, process.env) env = Object.assign({}, env, process.env)
} else { } else {
// Add in the system environment variables to our environment list // Add in the system environment variables to our environment list

View File

@ -5,11 +5,10 @@ import { getEnvFileVars } from './parse-env-file'
const RC_FILE_DEFAULT_LOCATIONS = ['./.env-cmdrc', './.env-cmdrc.js', './.env-cmdrc.json'] const RC_FILE_DEFAULT_LOCATIONS = ['./.env-cmdrc', './.env-cmdrc.js', './.env-cmdrc.json']
const ENV_FILE_DEFAULT_LOCATIONS = ['./.env', './.env.js', './.env.json'] const ENV_FILE_DEFAULT_LOCATIONS = ['./.env', './.env.js', './.env.json']
export async function getEnvVars (options?: GetEnvVarOptions): Promise<{ [key: string]: any }> { export async function getEnvVars (options: GetEnvVarOptions = {}): Promise<{ [key: string]: any }> {
options = options || {} options.envFile = options.envFile !== undefined ? options.envFile : {}
options.envFile = options.envFile || {}
// Check for rc file usage // Check for rc file usage
if (options.rc) { if (options.rc !== undefined) {
return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath }) return getRCFile({ environments: options.rc.environments, filePath: options.rc.filePath })
} }
return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback }) return getEnvFile({ filePath: options.envFile.filePath, fallback: options.envFile.fallback })
@ -19,11 +18,11 @@ export async function getEnvFile (
{ filePath, fallback }: { filePath?: string, fallback?: boolean } { filePath, fallback }: { filePath?: string, fallback?: boolean }
): Promise<{ [key: string]: any }> { ): Promise<{ [key: string]: any }> {
// Use env file // Use env file
if (filePath) { if (filePath !== undefined) {
try { try {
return await getEnvFileVars(filePath) return await getEnvFileVars(filePath)
} catch (e) { } } catch (e) { }
if (!fallback) { if (fallback !== true) {
throw new Error(`Unable to locate env file at location (${filePath})`) throw new Error(`Unable to locate env file at location (${filePath})`)
} }
} }
@ -42,11 +41,11 @@ export async function getRCFile (
{ environments, filePath }: { environments: string[], filePath?: string } { environments, filePath }: { environments: string[], filePath?: string }
): Promise<{ [key: string]: any }> { ): Promise<{ [key: string]: any }> {
// User provided an .rc file path // User provided an .rc file path
if (filePath) { if (filePath !== undefined) {
try { try {
return await getRCFileVars({ environments, filePath }) return await getRCFileVars({ environments, filePath })
} catch (e) { } catch (e) {
if (e.name !== 'PathError') console.log(e) if (e.name !== 'PathError') console.error(e)
throw new Error(`Unable to locate .rc file at location (${filePath})`) throw new Error(`Unable to locate .rc file at location (${filePath})`)
} }
} }
@ -56,7 +55,7 @@ export async function getRCFile (
try { try {
return await getRCFileVars({ environments, filePath }) return await getRCFileVars({ environments, filePath })
} catch (e) { } catch (e) {
if (e.name !== 'PathError') console.log(e) if (e.name !== 'PathError') console.error(e)
} }
} }

View File

@ -13,21 +13,23 @@ export function parseArgs (args: string[]): EnvCmdOptions {
// Reprocess the args with the command and command args removed // Reprocess the args with the command and command args removed
program = parseArgsUsingCommander(args.slice(0, args.indexOf(command))) program = parseArgsUsingCommander(args.slice(0, args.indexOf(command)))
const noOverride = !program.override const noOverride = !(program.override as boolean)
const useShell = !!program.useShell const useShell = !!(program.useShell as boolean)
let rc: any let rc: any
if (program.environments && program.environments.length) { if (program.environments !== undefined && program.environments.length !== 0) {
rc = rc || {} rc = {
rc.environments = program.environments environments: program.environments,
rc.filePath = program.rcFile filePath: program.rcFile
}
} }
let envFile: any let envFile: any
if (program.file) { if (program.file !== undefined) {
envFile = envFile || {} envFile = {
envFile.filePath = program.file filePath: program.file,
envFile.fallback = program.fallback fallback: program.fallback
}
} }
return { return {

View File

@ -16,7 +16,7 @@ export async function getEnvFileVars (envFilePath: string): Promise<{ [key: stri
// Get the file extension // Get the file extension
const ext = path.extname(absolutePath).toLowerCase() const ext = path.extname(absolutePath).toLowerCase()
let env = {} let env = {}
if (~REQUIRE_HOOK_EXTENSIONS.indexOf(ext)) { if (REQUIRE_HOOK_EXTENSIONS.indexOf(ext) > -1) {
const possiblePromise = require(absolutePath) /* eslint-disable-line */ const possiblePromise = require(absolutePath) /* eslint-disable-line */
env = isPromise(possiblePromise) ? await possiblePromise : possiblePromise env = isPromise(possiblePromise) ? await possiblePromise : possiblePromise
} else { } else {
@ -50,12 +50,12 @@ export function parseEnvVars (envString: string): { [key: string]: string } {
while ((match = envParseRegex.exec(envString)) !== null) { while ((match = envParseRegex.exec(envString)) !== null) {
// Note: match[1] is the full env=var line // Note: match[1] is the full env=var line
const key = match[2].trim() const key = match[2].trim()
const value = match[3].trim() || '' const value = match[3].trim()
// remove any surrounding quotes // remove any surrounding quotes
matches[key] = value matches[key] = value
.replace(/(^['"]|['"]$)/g, '') .replace(/(^['"]|['"]$)/g, '')
.replace(/\\n/g, `\n`) .replace(/\\n/g, '\n')
} }
return matches return matches
} }

View File

@ -38,7 +38,7 @@ export async function getRCFileVars (
let environmentFound = false let environmentFound = false
environments.forEach((name): void => { environments.forEach((name): void => {
const envVars = parsedData[name] const envVars = parsedData[name]
if (envVars) { if (envVars !== undefined) {
environmentFound = true environmentFound = true
result = { result = {
...result, ...result,
@ -70,7 +70,7 @@ export function parseRCFile (fileData: string): { [key: string]: any } {
console.error(`Error: console.error(`Error:
Failed to parse the .rc file. Failed to parse the .rc file.
Please make sure its a valid JSON format.`) Please make sure its a valid JSON format.`)
throw new Error(`Unable to parse JSON in .rc file.`) throw new Error('Unable to parse JSON in .rc file.')
} }
return data return data
} }

View File

@ -5,7 +5,7 @@ const SIGNALS_TO_HANDLE: NodeJS.Signals[] = [
] ]
export class TermSignals { export class TermSignals {
private terminateSpawnedProcessFuncHandlers: { [key: string]: any } = {} private readonly terminateSpawnedProcessFuncHandlers: { [key: string]: any } = {}
public _exitCalled = false public _exitCalled = false
public handleTermSignals (proc: ChildProcess): void { public handleTermSignals (proc: ChildProcess): void {
@ -22,7 +22,7 @@ export class TermSignals {
} }
process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal]) process.once(signal, this.terminateSpawnedProcessFuncHandlers[signal])
}) })
process.once('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']) process.once('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM)
// Terminate parent process if child process receives termination events // Terminate parent process if child process receives termination events
proc.on('exit', (code: number | undefined, signal: string | undefined): void => { proc.on('exit', (code: number | undefined, signal: string | undefined): void => {
@ -45,10 +45,10 @@ export class TermSignals {
* Terminate parent process helper * Terminate parent process helper
*/ */
public _terminateProcess (code?: number, signal?: string): void { public _terminateProcess (code?: number, signal?: string): void {
if (signal != null) { if (signal !== undefined) {
return process.kill(process.pid, signal) return process.kill(process.pid, signal)
} }
if (code != null) { if (code !== undefined) {
return process.exit(code) return process.exit(code)
} }
throw new Error('Unable to terminate parent process successfully') throw new Error('Unable to terminate parent process successfully')
@ -61,7 +61,7 @@ export class TermSignals {
SIGNALS_TO_HANDLE.forEach((signal): void => { SIGNALS_TO_HANDLE.forEach((signal): void => {
process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal]) process.removeListener(signal, this.terminateSpawnedProcessFuncHandlers[signal])
}) })
process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers['SIGTERM']) process.removeListener('exit', this.terminateSpawnedProcessFuncHandlers.SIGTERM)
} }
/** /**

View File

@ -7,7 +7,7 @@ import * as os from 'os'
export function resolveEnvFilePath (userPath: string): string { export function resolveEnvFilePath (userPath: string): string {
// Make sure a home directory exist // Make sure a home directory exist
const home = os.homedir() const home = os.homedir()
if (home) { if (home !== undefined) {
userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`) userPath = userPath.replace(/^~($|\/|\\)/, `${home}$1`)
} }
return path.resolve(process.cwd(), userPath) return path.resolve(process.cwd(), userPath)
@ -22,6 +22,6 @@ export function parseArgList (list: string): string[] {
/** /**
* A simple function to test if the value is a promise * A simple function to test if the value is a promise
*/ */
export function isPromise (value: any | PromiseLike<Object>): boolean { export function isPromise (value: any | PromiseLike<Object>): value is Promise<any> {
return value && typeof value.then === 'function' return value !== undefined && typeof value.then === 'function'
} }

View File

@ -7,6 +7,7 @@ import * as envFile from '../src/parse-env-file'
describe('getEnvVars', (): void => { describe('getEnvVars', (): void => {
let getRCFileVarsStub: sinon.SinonStub<any, any> let getRCFileVarsStub: sinon.SinonStub<any, any>
let getEnvFileVarsStub: sinon.SinonStub<any, any> let getEnvFileVarsStub: sinon.SinonStub<any, any>
let logStub: sinon.SinonStub<any, any>
const pathError = new Error() const pathError = new Error()
pathError.name = 'PathError' pathError.name = 'PathError'
@ -14,6 +15,7 @@ describe('getEnvVars', (): void => {
before((): void => { before((): void => {
getRCFileVarsStub = sinon.stub(rcFile, 'getRCFileVars') getRCFileVarsStub = sinon.stub(rcFile, 'getRCFileVars')
getEnvFileVarsStub = sinon.stub(envFile, 'getEnvFileVars') getEnvFileVarsStub = sinon.stub(envFile, 'getEnvFileVars')
logStub = sinon.stub(console, 'error')
}) })
after((): void => { after((): void => {
@ -62,6 +64,17 @@ describe('getEnvVars', (): void => {
} }
}) })
it('should log to error console on non-path errors', async (): Promise<void> => {
getRCFileVarsStub.rejects(new Error('Non-path Error'))
try {
await getEnvVars({ rc: { environments: ['production'] } })
assert.fail('should not get here.')
} catch (e) {
assert.match(logStub.getCall(0).args[0].message, /non-path error/gi)
assert.match(e.message, /locate \.rc/gi)
}
})
it('should find .rc file at custom path location', async (): Promise<void> => { it('should find .rc file at custom path location', async (): Promise<void> => {
getRCFileVarsStub.returns({ THANKS: 'FORALLTHEFISH' }) getRCFileVarsStub.returns({ THANKS: 'FORALLTHEFISH' })
const envs = await getEnvVars({ const envs = await getEnvVars({
@ -84,7 +97,19 @@ describe('getEnvVars', (): void => {
}) })
assert.fail('should not get here.') assert.fail('should not get here.')
} catch (e) { } catch (e) {
console.log(e) assert.match(e.message, /locate \.rc/gi)
}
})
it('should log to error console on non-path errors', async (): Promise<void> => {
getRCFileVarsStub.rejects(new Error('Non-path Error'))
try {
await getEnvVars({
rc: { environments: ['production'], filePath: '../.custom-rc' }
})
assert.fail('should not get here.')
} catch (e) {
assert.match(logStub.getCall(0).args[0].message, /non-path error/gi)
assert.match(e.message, /locate \.rc/gi) assert.match(e.message, /locate \.rc/gi)
} }
}) })

View File

@ -63,7 +63,7 @@ describe('parseEnvVars', (): void => {
}) })
it('should preserve newlines when surrounded in quotes', (): void => { it('should preserve newlines when surrounded in quotes', (): void => {
const envVars = parseEnvVars(`ONE_NEWLINE="ONE\\n"\nTWO_NEWLINES="HELLO\\nWORLD\\n"\nTHREE_NEWLINES="HELLO\\n\\nWOR\\nLD"\n`) const envVars = parseEnvVars('ONE_NEWLINE="ONE\\n"\nTWO_NEWLINES="HELLO\\nWORLD\\n"\nTHREE_NEWLINES="HELLO\\n\\nWOR\\nLD"\n')
assert(envVars.ONE_NEWLINE === 'ONE\n') assert(envVars.ONE_NEWLINE === 'ONE\n')
assert(envVars.TWO_NEWLINES === 'HELLO\nWORLD\n') assert(envVars.TWO_NEWLINES === 'HELLO\nWORLD\n')
assert(envVars.THREE_NEWLINES === 'HELLO\n\nWOR\nLD') assert(envVars.THREE_NEWLINES === 'HELLO\n\nWOR\nLD')
@ -104,47 +104,47 @@ describe('getEnvFileVars', (): void => {
it('should parse a json file', async (): Promise<void> => { it('should parse a json file', async (): Promise<void> => {
const env = await getEnvFileVars('./test/test-files/test.json') const env = await getEnvFileVars('./test/test-files/test.json')
assert.deepEqual(env, { assert.deepEqual(env, {
'THANKS': 'FOR WHAT?!', THANKS: 'FOR WHAT?!',
'ANSWER': 42, ANSWER: 42,
'ONLY': 'IN PRODUCTION', ONLY: 'IN PRODUCTION',
'GALAXY': 'hitch\nhiking' GALAXY: 'hitch\nhiking'
}) })
}) })
it('should parse a json file keeping all newlines intact', async (): Promise<void> => { it('should parse a json file keeping all newlines intact', async (): Promise<void> => {
const env = await getEnvFileVars('./test/test-files/test-newlines.json') const env = await getEnvFileVars('./test/test-files/test-newlines.json')
assert.deepEqual(env, { assert.deepEqual(env, {
'THANKS': 'FOR WHAT?!', THANKS: 'FOR WHAT?!',
'ANSWER': 42, ANSWER: 42,
'ONLY': 'IN\n PRODUCTION', ONLY: 'IN\n PRODUCTION',
'GALAXY': 'hitch\nhiking\n\n' GALAXY: 'hitch\nhiking\n\n'
}) })
}) })
it('should parse a js file', async (): Promise<void> => { it('should parse a js file', async (): Promise<void> => {
const env = await getEnvFileVars('./test/test-files/test.js') const env = await getEnvFileVars('./test/test-files/test.js')
assert.deepEqual(env, { assert.deepEqual(env, {
'THANKS': 'FOR ALL THE FISH', THANKS: 'FOR ALL THE FISH',
'ANSWER': 0, ANSWER: 0,
'GALAXY': 'hitch\nhiking' GALAXY: 'hitch\nhiking'
}) })
}) })
it('should parse an async js file', async (): Promise<void> => { it('should parse an async js file', async (): Promise<void> => {
const env = await getEnvFileVars('./test/test-files/test-async.js') const env = await getEnvFileVars('./test/test-files/test-async.js')
assert.deepEqual(env, { assert.deepEqual(env, {
'THANKS': 'FOR ALL THE FISH', THANKS: 'FOR ALL THE FISH',
'ANSWER': 0 ANSWER: 0
}) })
}) })
it('should parse an env file', async (): Promise<void> => { it('should parse an env file', async (): Promise<void> => {
const env = await getEnvFileVars('./test/test-files/test') const env = await getEnvFileVars('./test/test-files/test')
assert.deepEqual(env, { assert.deepEqual(env, {
'THANKS': 'FOR WHAT?!', THANKS: 'FOR WHAT?!',
'ANSWER': '42', ANSWER: '42',
'ONLY': 'IN=PRODUCTION', ONLY: 'IN=PRODUCTION',
'GALAXY': 'hitch\nhiking' GALAXY: 'hitch\nhiking'
}) })
}) })

View File

@ -30,9 +30,9 @@ describe('getRCFileVars', (): void => {
const res = await getRCFileVars({ environments: ['production'], filePath: rcFilePath }) const res = await getRCFileVars({ environments: ['production'], filePath: rcFilePath })
assert.exists(res) assert.exists(res)
assert.deepEqual(res, { assert.deepEqual(res, {
'THANKS': 'FOR WHAT?!', THANKS: 'FOR WHAT?!',
'ANSWER': 42, ANSWER: 42,
'ONLY': 'IN PRODUCTION' ONLY: 'IN PRODUCTION'
}) })
}) })
@ -40,8 +40,8 @@ describe('getRCFileVars', (): void => {
const res = await getRCFileVars({ environments: ['test'], filePath: rcJSONFilePath }) const res = await getRCFileVars({ environments: ['test'], filePath: rcJSONFilePath })
assert.exists(res) assert.exists(res)
assert.deepEqual(res, { assert.deepEqual(res, {
'THANKS': 'FOR MORE FISHIES', THANKS: 'FOR MORE FISHIES',
'ANSWER': 21 ANSWER: 21
}) })
}) })
@ -69,9 +69,9 @@ describe('getRCFileVars', (): void => {
filePath: './test/test-files/.rc-test-async.js' filePath: './test/test-files/.rc-test-async.js'
}) })
assert.deepEqual(env, { assert.deepEqual(env, {
'THANKS': 'FOR WHAT?!', THANKS: 'FOR WHAT?!',
'ANSWER': 42, ANSWER: 42,
'ONLY': 'IN PRODUCTION' ONLY: 'IN PRODUCTION'
}) })
}) })
}) })

View File

@ -10,6 +10,7 @@
] ]
}, },
"include": [ "include": [
"./src/**/*" "./src/**/*",
"./test/**/*"
] ]
} }