Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

linkinator

Package Overview
Dependencies
Maintainers
1
Versions
114
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

linkinator - npm Package Compare versions

Comparing version 2.8.2 to 2.9.0

build/src/logger.d.ts

132

build/src/cli.js

@@ -10,2 +10,3 @@ #!/usr/bin/env node

const config_1 = require("./config");
const logger_1 = require("./logger");
// eslint-disable-next-line @typescript-eslint/no-var-requires

@@ -16,2 +17,3 @@ const toCSV = util_1.promisify(require('jsonexport'));

updateNotifier({ pkg }).notify();
/* eslint-disable no-process-exit */
const cli = meow(`

@@ -47,10 +49,7 @@ Usage

--server-root
When scanning a locally directory, customize the location on disk
When scanning a locally directory, customize the location on disk
where the server is started. Defaults to the path passed in [LOCATION].
--silent
Only output broken links
--skip, -s
List of urls in regexy form to not include in the check.
List of urls in regexy form to not include in the check.

@@ -60,2 +59,6 @@ --timeout

--verbosity
Override the default verbosity for this command. Available options are
'debug', 'info', 'warning', 'error', and 'none'. Defaults to 'warning'.
Examples

@@ -78,2 +81,3 @@ $ linkinator docs/

serverRoot: { type: 'string' },
verbosity: { type: 'string' },
},

@@ -90,15 +94,8 @@ booleanDefault: undefined,

const start = Date.now();
if (!flags.silent) {
log(`🏊‍♂️ crawling ${cli.input}`);
}
const verbosity = parseVerbosity(cli.flags);
const format = parseFormat(cli.flags);
const logger = new logger_1.Logger(verbosity, format);
logger.error(`🏊‍♂️ crawling ${cli.input}`);
const checker = new index_1.LinkChecker();
// checker.on('pagestart', url => {
// if (!flags.silent) {
// log(`\n Scanning ${chalk.grey(url)}`);
// }
// });
checker.on('link', (link) => {
if (flags.silent && link.state !== index_1.LinkState.BROKEN) {
return;
}
let state = '';

@@ -108,11 +105,13 @@ switch (link.state) {

state = `[${chalk.red(link.status.toString())}]`;
logger.error(`${state} ${chalk.gray(link.url)}`);
break;
case index_1.LinkState.OK:
state = `[${chalk.green(link.status.toString())}]`;
logger.warn(`${state} ${chalk.gray(link.url)}`);
break;
case index_1.LinkState.SKIPPED:
state = `[${chalk.grey('SKP')}]`;
logger.info(`${state} ${chalk.gray(link.url)}`);
break;
}
log(`${state} ${chalk.gray(link.url)}`);
});

@@ -128,17 +127,10 @@ const opts = {

if (flags.skip) {
if (typeof flags.skip === 'string') {
opts.linksToSkip = flags.skip.split(' ').filter(x => !!x);
}
else if (Array.isArray(flags.skip)) {
opts.linksToSkip = flags.skip;
}
opts.linksToSkip = flags.skip.split(' ').filter(x => !!x);
}
const result = await checker.check(opts);
log();
const format = flags.format ? flags.format.toLowerCase() : null;
if (format === 'json') {
if (format === logger_1.Format.JSON) {
console.log(JSON.stringify(result, null, 2));
return;
}
else if (format === 'csv') {
else if (format === logger_1.Format.CSV) {
const csv = await toCSV(result.links);

@@ -149,19 +141,47 @@ console.log(csv);

else {
// Build a collection scanned links, collated by the parent link used in
// the scan. For example:
// {
// "./README.md": [
// {
// url: "https://img.shields.io/npm/v/linkinator.svg",
// status: 200
// ....
// }
// ],
// }
const parents = result.links.reduce((acc, curr) => {
if (!flags.silent || curr.state === index_1.LinkState.BROKEN) {
const parent = curr.parent || '';
if (!acc[parent]) {
acc[parent] = [];
}
acc[parent].push(curr);
const parent = curr.parent || '';
if (!acc[parent]) {
acc[parent] = [];
}
acc[parent].push(curr);
return acc;
}, {});
Object.keys(parents).forEach(parent => {
const links = parents[parent];
log(chalk.blue(parent));
// prune links based on verbosity
const links = parents[parent].filter(link => {
if (verbosity === logger_1.LogLevel.NONE) {
return false;
}
if (link.state === index_1.LinkState.BROKEN) {
return true;
}
if (link.state === index_1.LinkState.OK) {
if (verbosity <= logger_1.LogLevel.WARNING) {
return true;
}
}
if (link.state === index_1.LinkState.SKIPPED) {
if (verbosity <= logger_1.LogLevel.INFO) {
return true;
}
}
return false;
});
if (links.length === 0) {
return;
}
logger.error(chalk.blue(parent));
links.forEach(link => {
if (flags.silent && link.state !== index_1.LinkState.BROKEN) {
return;
}
let state = '';

@@ -171,11 +191,13 @@ switch (link.state) {

state = `[${chalk.red(link.status.toString())}]`;
logger.error(` ${state} ${chalk.gray(link.url)}`);
break;
case index_1.LinkState.OK:
state = `[${chalk.green(link.status.toString())}]`;
logger.warn(` ${state} ${chalk.gray(link.url)}`);
break;
case index_1.LinkState.SKIPPED:
state = `[${chalk.grey('SKP')}]`;
logger.info(` ${state} ${chalk.gray(link.url)}`);
break;
}
log(` ${state} ${chalk.gray(link.url)}`);
});

@@ -187,14 +209,36 @@ });

const borked = result.links.filter(x => x.state === index_1.LinkState.BROKEN);
console.error(chalk.bold(`${chalk.red('ERROR')}: Detected ${borked.length} broken links. Scanned ${chalk.yellow(result.links.length.toString())} links in ${chalk.cyan(total.toString())} seconds.`));
// eslint-disable-next-line no-process-exit
logger.error(chalk.bold(`${chalk.red('ERROR')}: Detected ${borked.length} broken links. Scanned ${chalk.yellow(result.links.length.toString())} links in ${chalk.cyan(total.toString())} seconds.`));
process.exit(1);
}
log(chalk.bold(`🤖 Successfully scanned ${chalk.green(result.links.length.toString())} links in ${chalk.cyan(total.toString())} seconds.`));
logger.error(chalk.bold(`🤖 Successfully scanned ${chalk.green(result.links.length.toString())} links in ${chalk.cyan(total.toString())} seconds.`));
}
function log(message = '\n') {
function parseVerbosity(flags) {
if (flags.silent && flags.verbosity) {
throw new Error('The SILENT and VERBOSITY flags cannot both be defined. Please consider using VERBOSITY only.');
}
if (flags.silent) {
return logger_1.LogLevel.ERROR;
}
if (!flags.verbosity) {
return logger_1.LogLevel.WARNING;
}
const verbosity = flags.verbosity.toUpperCase();
const options = Object.values(logger_1.LogLevel);
if (!options.includes(verbosity)) {
throw new Error(`Invalid flag: VERBOSITY must be one of [${options.join(',')}]`);
}
return logger_1.LogLevel[verbosity];
}
function parseFormat(flags) {
if (!flags.format) {
console.log(message);
return logger_1.Format.TEXT;
}
flags.format = flags.format.toUpperCase();
const options = Object.values(logger_1.Format);
if (!options.includes(flags.format)) {
throw new Error("Invalid flag: FORMAT must be 'TEXT', 'JSON', or 'CSV'.");
}
return logger_1.Format[flags.format];
}
main();
//# sourceMappingURL=cli.js.map
{
"name": "linkinator",
"description": "Find broken links, missing images, etc in your HTML. Scurry around your site and find all those broken links.",
"version": "2.8.2",
"version": "2.9.0",
"license": "MIT",

@@ -6,0 +6,0 @@ "repository": "JustinBeckwith/linkinator",

@@ -67,5 +67,2 @@ # 🐿 linkinator

--silent
Only output broken links.
--skip, -s

@@ -76,2 +73,6 @@ List of urls in regexy form to not include in the check.

Request timeout in ms. Defaults to 0 (no timeout).
--verbosity
Override the default verbosity for this command. Available options are
'debug', 'info', 'warning', 'error', and 'none'. Defaults to 'warning'.
```

@@ -78,0 +79,0 @@

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc