@beuluis/hook-cli
Advanced tools
Comparing version 1.1.2 to 1.1.3
@@ -6,3 +6,3 @@ #!/usr/bin/env node | ||
const yargs_1 = tslib_1.__importDefault(require("yargs")); | ||
(0, yargs_1.default)(process.argv.slice(2)) | ||
void (0, yargs_1.default)(process.argv.slice(2)) | ||
.scriptName('hook-cli') | ||
@@ -9,0 +9,0 @@ .alias('v', 'version') |
@@ -9,2 +9,13 @@ "use strict"; | ||
const yarn_helper_1 = require("../util/yarn.helper"); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isAuditResult = (object) => Object.prototype.hasOwnProperty.call(object, 'info') && | ||
typeof object.info === 'number' && | ||
Object.prototype.hasOwnProperty.call(object, 'low') && | ||
typeof object.low === 'number' && | ||
Object.prototype.hasOwnProperty.call(object, 'moderate') && | ||
typeof object.moderate === 'number' && | ||
Object.prototype.hasOwnProperty.call(object, 'high') && | ||
typeof object.high === 'number' && | ||
Object.prototype.hasOwnProperty.call(object, 'critical') && | ||
typeof object.critical === 'number'; | ||
const filterAuditResult = (auditResult) => { | ||
@@ -22,15 +33,5 @@ if (isAuditResult(auditResult)) { | ||
}; | ||
const isAuditResult = (obj) => Object.prototype.hasOwnProperty.call(obj, 'info') && | ||
typeof obj.info === 'number' && | ||
Object.prototype.hasOwnProperty.call(obj, 'low') && | ||
typeof obj.low === 'number' && | ||
Object.prototype.hasOwnProperty.call(obj, 'moderate') && | ||
typeof obj.moderate === 'number' && | ||
Object.prototype.hasOwnProperty.call(obj, 'high') && | ||
typeof obj.high === 'number' && | ||
Object.prototype.hasOwnProperty.call(obj, 'critical') && | ||
typeof obj.critical === 'number'; | ||
const auditCommandBuilder = (packageManager, prod) => { | ||
const auditCommandBuilder = (packageManager, production) => { | ||
let command = `${packageManager} audit`; | ||
if (prod) { | ||
if (production) { | ||
if (packageManager === 'yarn') { | ||
@@ -45,3 +46,3 @@ command += ' --groups dependencies'; | ||
}; | ||
const totalVulnerabilities = (obj) => Object.values(obj).reduce((a, b) => a + b); | ||
const totalVulnerabilities = (object) => Object.values(object).reduce((a, b) => a + b); | ||
module.exports = (0, commandModule_helper_1.registerCommandModule)()({ | ||
@@ -81,14 +82,15 @@ command: 'checkForVulnerabilities', | ||
title: `Check for vulnerabilities with '${console_log_colors_1.color.cyan(`${packageManager} audit`)}'`, | ||
task: (_ctx, task) => (0, exec_helper_1.execute)(`${auditCommandBuilder(packageManager, prod)} --json`) | ||
task: async (_context, task) => await (0, exec_helper_1.execute)(`${auditCommandBuilder(packageManager, prod)} --json`) | ||
.then(() => (task.title = `No package vulnerabilities with level ${auditLevel} or higher found`)) | ||
.catch((e) => { | ||
if (e instanceof exec_helper_1.ExecuteError) { | ||
// eslint-disable-next-line complexity | ||
.catch(async (error) => { | ||
if (error instanceof exec_helper_1.ExecuteError) { | ||
let auditResult; | ||
if (packageManager === 'npm') { | ||
const result = (0, npm_helper_1.NPMOutputParser)(e.stdout).metadata.vulnerabilities; | ||
const result = (0, npm_helper_1.NPMOutputParser)(error.stdout).metadata.vulnerabilities; | ||
auditResult = filterAuditResult(result); | ||
} | ||
else if (packageManager === 'yarn') { | ||
const result = (0, yarn_helper_1.YarnOutputParser)(e.stdout, e.stderr); | ||
const auditSummary = result.find(el => el.type === 'auditSummary'); | ||
const result = (0, yarn_helper_1.YarnOutputParser)(error.stdout, error.stderr); | ||
const auditSummary = result.find(element => element.type === 'auditSummary'); | ||
if (auditSummary) { | ||
@@ -105,3 +107,3 @@ const vulnerabilities = auditSummary.data.vulnerabilities; | ||
} | ||
let levelMet = false; | ||
let levelMet; | ||
switch (auditLevel) { | ||
@@ -135,2 +137,4 @@ case 'info': | ||
break; | ||
default: | ||
levelMet = false; | ||
} | ||
@@ -143,3 +147,3 @@ const auditCount = totalVulnerabilities(auditResult); | ||
task.title = `Found ${console_log_colors_1.color.cyan(auditCount)} vulnerabilities of lower level then ${console_log_colors_1.color.cyan(auditLevel)}`; | ||
return Promise.resolve(); // We found some but we dont care because the level is not right | ||
return; // We found some but we dont care because the level is not right | ||
} | ||
@@ -150,13 +154,14 @@ throw new Error('Unknown error'); | ||
]); | ||
tasks | ||
.run() | ||
.then(() => process.exit(0)) | ||
.catch(e => { | ||
if (e instanceof commandModule_helper_1.HookFailedError && noFail) { | ||
try { | ||
await tasks.run(); | ||
process.exit(0); | ||
} | ||
catch (error) { | ||
if (error instanceof commandModule_helper_1.HookFailedError && noFail) { | ||
process.exit(0); | ||
} | ||
process.exit(1); | ||
}); | ||
} | ||
}, | ||
}); | ||
//# sourceMappingURL=checkForVulnerabilities.js.map |
"use strict"; | ||
const tslib_1 = require("tslib"); | ||
const console_log_colors_1 = require("console-log-colors"); | ||
const console_table_printer_1 = require("console-table-printer"); | ||
const listr_1 = tslib_1.__importDefault(require("listr")); | ||
const console_table_printer_1 = require("console-table-printer"); | ||
const commandModule_helper_1 = require("../util/commandModule.helper"); | ||
@@ -10,20 +10,22 @@ const exec_helper_1 = require("../util/exec.helper"); | ||
const yarn_helper_1 = require("../util/yarn.helper"); | ||
const isOutdatedNpm = (obj) => Object.prototype.hasOwnProperty.call(obj, 'current') && | ||
typeof obj.current === 'string' && | ||
Object.prototype.hasOwnProperty.call(obj, 'wanted') && | ||
typeof obj.wanted === 'string' && | ||
Object.prototype.hasOwnProperty.call(obj, 'latest') && | ||
typeof obj.latest === 'string'; | ||
const transformNpmOutput = (obj) => { | ||
let result = []; | ||
for (let key in obj) { | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isOutdatedNpm = (object) => Object.prototype.hasOwnProperty.call(object, 'current') && | ||
typeof object.current === 'string' && | ||
Object.prototype.hasOwnProperty.call(object, 'wanted') && | ||
typeof object.wanted === 'string' && | ||
Object.prototype.hasOwnProperty.call(object, 'latest') && | ||
typeof object.latest === 'string'; | ||
const transformNpmOutput = (object) => { | ||
const result = []; | ||
// eslint-disable-next-line guard-for-in | ||
for (const key in object) { | ||
// TODO: better typing | ||
// but i mean there has to be a key if we loop over it right...? Right JavaScript? | ||
const el = obj[key]; | ||
if (isOutdatedNpm(el)) { | ||
const element = object[key]; | ||
if (isOutdatedNpm(element)) { | ||
result.push({ | ||
package: key, | ||
current: el.current, | ||
wanted: el.wanted, | ||
latest: el.latest, | ||
current: element.current, | ||
wanted: element.wanted, | ||
latest: element.latest, | ||
}); | ||
@@ -35,17 +37,18 @@ } | ||
// I could to a more in depth type guard but i don´t want to. So we will just assume that yarn report right | ||
const isYarnOutdatedTable = (obj) => Object.prototype.hasOwnProperty.call(obj, 'head') && | ||
Array.isArray(obj.head) && | ||
obj.head[0] === 'Package' && | ||
obj.head[1] === 'Current' && | ||
obj.head[2] === 'Wanted' && | ||
obj.head[3] === 'Latest' && | ||
Object.prototype.hasOwnProperty.call(obj, 'body') && | ||
Array.isArray(obj.body); | ||
const transformYarnOutput = (arr) => { | ||
const outdatedTable = arr.find(el => el.type === 'table'); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isYarnOutdatedTable = (object) => Object.prototype.hasOwnProperty.call(object, 'head') && | ||
Array.isArray(object.head) && | ||
object.head[0] === 'Package' && | ||
object.head[1] === 'Current' && | ||
object.head[2] === 'Wanted' && | ||
object.head[3] === 'Latest' && | ||
Object.prototype.hasOwnProperty.call(object, 'body') && | ||
Array.isArray(object.body); | ||
const transformYarnOutput = (array) => { | ||
const outdatedTable = array.find(element => element.type === 'table'); | ||
if (!outdatedTable || !isYarnOutdatedTable(outdatedTable.data)) { | ||
throw new Error('Yarn returned unexpected json'); | ||
} | ||
let result = []; | ||
for (var outdated of outdatedTable.data.body) { | ||
const result = []; | ||
for (const outdated of outdatedTable.data.body) { | ||
result.push({ | ||
@@ -83,12 +86,12 @@ package: outdated[0], | ||
title: `Check for updates with '${console_log_colors_1.color.cyan(`${packageManager} outdated`)}'`, | ||
task: (ctx, task) => (0, exec_helper_1.execute)(`${packageManager} outdated --json`) | ||
task: async (context, task) => await (0, exec_helper_1.execute)(`${packageManager} outdated --json`) | ||
.then(() => (task.title = `No package updates found`)) | ||
.catch((e) => { | ||
if (e instanceof exec_helper_1.ExecuteError) { | ||
.catch((error) => { | ||
if (error instanceof exec_helper_1.ExecuteError) { | ||
let outdatedList; | ||
if (packageManager === 'npm') { | ||
outdatedList = transformNpmOutput((0, npm_helper_1.NPMOutputParser)(e.stdout)); | ||
outdatedList = transformNpmOutput((0, npm_helper_1.NPMOutputParser)(error.stdout)); | ||
} | ||
else if (packageManager === 'yarn') { | ||
outdatedList = transformYarnOutput((0, yarn_helper_1.YarnOutputParser)(e.stdout, e.stderr)); | ||
outdatedList = transformYarnOutput((0, yarn_helper_1.YarnOutputParser)(error.stdout, error.stderr)); | ||
} | ||
@@ -98,3 +101,3 @@ else { | ||
} | ||
ctx.outdatedList = outdatedList; | ||
context.outdatedList = outdatedList; | ||
task.title = `Found ${console_log_colors_1.color.red(outdatedList.length)} packages to update:`; | ||
@@ -107,7 +110,9 @@ throw new commandModule_helper_1.HookFailedError(); | ||
]); | ||
tasks | ||
.run() | ||
.then(() => process.exit(0)) | ||
.catch(e => { | ||
if (e.context.outdatedList) { | ||
try { | ||
await tasks.run(); | ||
process.exit(0); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
} | ||
catch (error) { | ||
if (error.context.outdatedList) { | ||
new console_table_printer_1.Table({ | ||
@@ -120,6 +125,6 @@ columns: [ | ||
], | ||
rows: e.context.outdatedList, | ||
rows: error.context.outdatedList, | ||
}).printTable(); | ||
} | ||
if (e instanceof commandModule_helper_1.HookFailedError) { | ||
if (error instanceof commandModule_helper_1.HookFailedError) { | ||
if (fail) { | ||
@@ -131,5 +136,5 @@ process.exit(1); | ||
process.exit(1); | ||
}); | ||
} | ||
}, | ||
}); | ||
//# sourceMappingURL=updateReminder.js.map |
@@ -6,14 +6,11 @@ "use strict"; | ||
* Type helper function to register a command module | ||
* | ||
* @example <caption>Minimal command registration</caption> | ||
* registerCommandModule()({command: 'helloWorld', describe: 'HelloWorld', handler: () => console.log('HelloWorld')}); | ||
* | ||
* @example <caption>Command registration with options</caption> | ||
* registerCommandModule()({ command: 'helloWorld', describe: 'HelloWorld', builder: { name: { alias: 'n', type: 'string' }}, handler: (args) => console.log(`Hello ${args.name}`)}); | ||
* | ||
* @example <caption>Command registration with argument</caption> | ||
* registerCommandModule<{ name: string }>()({ command: 'helloWorld [name]', describe: 'HelloWorld', handler: (args) => console.log(`Hello ${args.name}`)}); | ||
* | ||
* @example <caption>Command registration with alias</caption> | ||
* registerCommandModule()({command: 'helloWorld', aliases: 'hello', describe: 'HelloWorld', handler: () => console.log('HelloWorld')}); | ||
* | ||
* @example <caption>Command registration with deprecated warning</caption> | ||
@@ -20,0 +17,0 @@ * registerCommandModule()({command: 'helloWorld', deprecated: true, describe: 'HelloWorld', handler: () => console.log('HelloWorld')}); |
@@ -16,2 +16,3 @@ "use strict"; | ||
* Execute a command and collects the results | ||
* | ||
* @example <caption>Execute command</caption> | ||
@@ -21,3 +22,3 @@ * const result = await execute('echo HelloWorld'); | ||
*/ | ||
const execute = (command) => new Promise((resolve, rejects) => { | ||
const execute = async (command) => await new Promise((resolve, reject) => { | ||
var _a, _b; | ||
@@ -31,5 +32,5 @@ let stdout = ''; | ||
? resolve({ code, stdout, stderr }) | ||
: rejects(new ExecuteError(code, stdout, stderr))); | ||
: reject(new ExecuteError(code, stdout, stderr))); | ||
}); | ||
exports.execute = execute; | ||
//# sourceMappingURL=exec.helper.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.NPMOutputParser = void 0; | ||
const isNPMError = (obj) => typeof obj === 'object' && Object.prototype.hasOwnProperty.call(obj, 'message'); | ||
const isNPMError = (object) => typeof object === 'object' && Object.prototype.hasOwnProperty.call(object, 'message'); | ||
/** | ||
* Parse a npm --json command output. | ||
* Throws error if it encounters invalid json or a error message from npm | ||
* | ||
* @example <caption>Execute command</caption> | ||
@@ -12,15 +13,15 @@ * const result = NPMOutputParser(await execute('npm outdated --json').stdout); | ||
const NPMOutputParser = (stdout) => { | ||
let outputObj = {}; | ||
let outputObject = {}; | ||
try { | ||
outputObj = JSON.parse(stdout); | ||
outputObject = JSON.parse(stdout); | ||
} | ||
catch (e) { | ||
catch { | ||
throw new Error('Unable to parse npm json response'); | ||
} | ||
if (isNPMError(outputObj)) { | ||
throw new Error(outputObj.message); | ||
if (isNPMError(outputObject)) { | ||
throw new Error(outputObject.message); | ||
} | ||
return outputObj; | ||
return outputObject; | ||
}; | ||
exports.NPMOutputParser = NPMOutputParser; | ||
//# sourceMappingURL=npm.helper.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.YarnOutputParser = void 0; | ||
const isYarnObject = (obj) => Object.prototype.hasOwnProperty.call(obj, 'type') && | ||
typeof obj.type === 'string' && | ||
Object.prototype.hasOwnProperty.call(obj, 'data'); | ||
// eslint-disable-next-line @typescript-eslint/no-explicit-any | ||
const isYarnObject = (object) => Object.prototype.hasOwnProperty.call(object, 'type') && | ||
typeof object.type === 'string' && | ||
Object.prototype.hasOwnProperty.call(object, 'data'); | ||
/** | ||
* Parse a yarn --json command output (One object per line). | ||
* Throws error if it encounters invalid json or a error data type from yarn | ||
* | ||
* @example <caption>Execute command</caption> | ||
@@ -15,21 +17,21 @@ * const commandOut = await execute('yarn outdated --json'); | ||
const YarnOutputParser = (stdout, stderr) => { | ||
const rawOutputArr = stdout.split(/\r?\n/); | ||
const rawErrorArr = stderr.split(/\r?\n/); | ||
let outputObj = []; | ||
let errorObj = []; | ||
const rawOutputArray = stdout.split(/\r?\n/u); | ||
const rawErrorArray = stderr.split(/\r?\n/u); | ||
let outputObject = []; | ||
let errorObject = []; | ||
try { | ||
// filter empty elements for new line at the end | ||
outputObj = JSON.parse(`[${rawOutputArr.filter(el => el).join()}]`); | ||
errorObj = JSON.parse(`[${rawErrorArr.filter(el => el).join()}]`); | ||
outputObject = JSON.parse(`[${rawOutputArray.filter(Boolean).join(',')}]`); | ||
errorObject = JSON.parse(`[${rawErrorArray.filter(Boolean).join(',')}]`); | ||
} | ||
catch (e) { | ||
catch { | ||
throw new Error('Unable to parse yarn json response'); | ||
} | ||
const error = errorObj.find(el => isYarnObject(el) && el.type === 'error'); | ||
const error = errorObject.find(element => isYarnObject(element) && element.type === 'error'); | ||
if (error) { | ||
throw new Error(typeof error.data === 'string' ? error.data : 'Unknown error'); | ||
} | ||
return outputObj.filter(el => isYarnObject(el)); | ||
return outputObject.filter(element => isYarnObject(element)); | ||
}; | ||
exports.YarnOutputParser = YarnOutputParser; | ||
//# sourceMappingURL=yarn.helper.js.map |
{ | ||
"name": "@beuluis/hook-cli", | ||
"version": "1.1.2", | ||
"version": "1.1.3", | ||
"description": "A small hook cli that can be used with for example husky", | ||
@@ -20,3 +20,5 @@ "bin": { | ||
"hook-cli": "ts-node src/index.ts", | ||
"test": "echo \"Error: no test specified\"" | ||
"test": "npm run hook-cli -- --help", | ||
"lint": "eslint .", | ||
"prepare": "husky install" | ||
}, | ||
@@ -40,6 +42,12 @@ "repository": { | ||
"devDependencies": { | ||
"@beuluis/prettier-config": "^1.0.2", | ||
"@beuluis/eslint-config": "^1.0.2", | ||
"@beuluis/hook-cli": "^1.1.2", | ||
"@beuluis/prettier-config": "^2.0.1", | ||
"@types/listr": "^0.14.4", | ||
"@types/node": "^17.0.35", | ||
"@types/node": "^18.7.18", | ||
"@types/yargs": "^17.0.10", | ||
"eslint": "^8.23.1", | ||
"husky": "^8.0.1", | ||
"lint-staged": "^13.0.3", | ||
"np": "^7.6.2", | ||
"ts-node": "^10.8.0", | ||
@@ -55,3 +63,12 @@ "tslib": "^2.4.0", | ||
], | ||
"prettier": "@beuluis/prettier-config" | ||
"prettier": "@beuluis/prettier-config", | ||
"lint-staged": { | ||
"*.md": [ | ||
"prettier --write" | ||
], | ||
"*.{js,ts,json,yml,yaml}": [ | ||
"prettier --write", | ||
"eslint" | ||
] | ||
} | ||
} |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
72951
422
0
13