diff --git a/index.js b/index.js index 41e3ab7..7b86790 100644 --- a/index.js +++ b/index.js @@ -4,7 +4,7 @@ */ "use strict"; -const chalk = require("chalk"); +const pc = require("picocolors"); const { codeFrameColumns } = require("@babel/code-frame"); const path = require("path"); @@ -36,7 +36,7 @@ function formatFilePath(filePath, line, column) { relPath += `:${line}:${column}`; } - return chalk.green(relPath); + return pc.green(relPath); } /** @@ -46,9 +46,9 @@ function formatFilePath(filePath, line, column) { * @returns {string} The formatted output. */ function formatMessage(message, parentResult) { - const type = (message.fatal || message.severity === 2) ? chalk.red("error") : chalk.yellow("warning"); - const msg = `${chalk.bold(message.message.replace(/([^ ])\.$/u, "$1"))}`; - const ruleId = message.fatal ? "" : chalk.dim(`(${message.ruleId})`); + const type = (message.fatal || message.severity === 2) ? pc.red("error") : pc.yellow("warning"); + const msg = `${pc.bold(message.message.replace(/([^ ])\.$/u, "$1"))}`; + const ruleId = message.fatal ? "" : pc.dim(`(${message.ruleId})`); const filePath = formatFilePath(parentResult.filePath, message.line, message.column); const sourceCode = parentResult.output ? parentResult.output : parentResult.source; @@ -99,10 +99,10 @@ function formatSummary(errors, warnings, fixableErrors, fixableWarnings) { fixablesSummary.push(`${fixableWarnings} ${pluralize("warning", fixableWarnings)}`); } - let output = chalk[summaryColor].bold(`${summary.join(" and ")} found.`); + let output = pc[summaryColor](pc.bold(`${summary.join(" and ")} found.`)); if (fixableErrors || fixableWarnings) { - output += chalk[summaryColor].bold(`\n${fixablesSummary.join(" and ")} potentially fixable with the \`--fix\` option.`); + output += pc[summaryColor](pc.bold(`\n${fixablesSummary.join(" and ")} potentially fixable with the \`--fix\` option.`)); } return output; diff --git a/package.json b/package.json index a3ed8c0..0bde746 100755 --- a/package.json +++ b/package.json @@ -11,8 +11,8 @@ "license": "MIT", "author": "Nicholas C. Zakas ", "dependencies": { - "@babel/code-frame": "7.12.11", - "chalk": "^4.0.0" + "@babel/code-frame": "7.26.2", + "picocolors": "^1.1.1" }, "engines": { "node": "^10.12.0 || >=12.0.0" diff --git a/test.js b/test.js index f7b0740..a0ee083 100644 --- a/test.js +++ b/test.js @@ -12,30 +12,11 @@ const assert = require("chai").assert; const sinon = require("sinon"); const proxyquire = require("proxyquire"); -const chalk = require("chalk"); +const pc = require("picocolors"); const path = require("path"); const stripAnsi = require("strip-ansi"); -// Chalk protects its methods so we need to inherit from it for Sinon to work. -const chalkStub = Object.create(chalk, { - yellow: { - value(str) { - return chalk.yellow(str); - }, - writable: true - }, - red: { - value(str) { - return chalk.red(str); - }, - writable: true - } -}); - -chalkStub.yellow.bold = chalk.yellow.bold; -chalkStub.red.bold = chalk.red.bold; - -const formatter = proxyquire(".", { chalk: chalkStub }); +const formatter = proxyquire(".", { pc }); //------------------------------------------------------------------------------ // Tests @@ -86,20 +67,22 @@ describe("formatter:codeframe", () => { "> 1 | var foo = 1;", " | ^", " 2 | var bar = 2;", - " 3 | ", + " 3 |", "\n", "1 warning found." ].join("\n")); }); it("should return bold yellow summary when there are only warnings", () => { - sinon.spy(chalkStub.yellow, "bold"); - sinon.spy(chalkStub.red, "bold"); + sinon.spy(pc, "yellow"); + sinon.spy(pc, "red"); + sinon.spy(pc, "bold"); formatter(code); - assert.strictEqual(chalkStub.yellow.bold.callCount, 1); - assert.strictEqual(chalkStub.red.bold.callCount, 0); + assert.strictEqual(pc.yellow.callCount, 2); + assert.strictEqual(pc.red.callCount, 0); + assert.strictEqual(pc.bold.callCount, 2); }); describe("when the warning is fixable", () => { @@ -115,7 +98,7 @@ describe("formatter:codeframe", () => { "> 1 | var foo = 1;", " | ^", " 2 | var bar = 2;", - " 3 | ", + " 3 |", "\n", "1 warning found.", "1 warning potentially fixable with the `--fix` option." @@ -147,20 +130,22 @@ describe("formatter:codeframe", () => { "> 1 | var foo = 1;", " | ^", " 2 | var bar = 2;", - " 3 | ", + " 3 |", "\n", "1 error found." ].join("\n")); }); it("should return bold red summary when there are errors", () => { - sinon.spy(chalkStub.yellow, "bold"); - sinon.spy(chalkStub.red, "bold"); + sinon.spy(pc, "yellow"); + sinon.spy(pc, "red"); + sinon.spy(pc, "bold"); formatter(code); - assert.strictEqual(chalkStub.yellow.bold.callCount, 0); - assert.strictEqual(chalkStub.red.bold.callCount, 1); + assert.strictEqual(pc.yellow.callCount, 0); + assert.strictEqual(pc.red.callCount, 2); + assert.strictEqual(pc.bold.callCount, 2); }); }); @@ -212,28 +197,30 @@ describe("formatter:codeframe", () => { "error: Missing semicolon (semi) at foo.js:1:14:", "> 1 | const foo = 1", " | ^", - " 2 | ", + " 2 |", "\n", "error: 'foo' is assigned a value but never used (no-unused-vars) at foo.js:1:7:", "> 1 | const foo = 1", " | ^", - " 2 | ", + " 2 |", "\n", "2 errors found." ].join("\n")); }); it("should return bold red summary when at least 1 of the messages is an error", () => { - sinon.spy(chalkStub.yellow, "bold"); - sinon.spy(chalkStub.red, "bold"); + sinon.spy(pc, "yellow"); + sinon.spy(pc, "red"); + sinon.spy(pc, "bold"); code[0].messages[0].severity = 1; code[0].warningCount = 1; code[0].errorCount = 1; formatter(code); - assert.strictEqual(chalkStub.yellow.bold.callCount, 0); - assert.strictEqual(chalkStub.red.bold.callCount, 1); + assert.strictEqual(pc.yellow.callCount, 1); + assert.strictEqual(pc.red.callCount, 2); + assert.strictEqual(pc.bold.callCount, 3); }); }); @@ -258,13 +245,13 @@ describe("formatter:codeframe", () => { assert.strictEqual(stripAnsi(result), [ "error: 'foo' is assigned a value but never used (no-unused-vars) at foo.js:4:11:", - " 2 | ", + " 2 |", " 3 | // a comment", "> 4 | const foo = 1;", " | ^", " 5 | }", - " 6 | ", - " 7 | ", + " 6 |", + " 7 |", "\n", "1 error found." ].join("\n")); @@ -305,12 +292,12 @@ describe("formatter:codeframe", () => { "error: Missing semicolon (semi) at foo.js:1:14:", "> 1 | const foo = 1", " | ^", - " 2 | ", + " 2 |", "\n", "error: Missing semicolon (semi) at bar.js:1:14:", "> 1 | const bar = 2", " | ^", - " 2 | ", + " 2 |", "\n", "2 errors found." ].join("\n")); @@ -341,7 +328,7 @@ describe("formatter:codeframe", () => { "error: Parsing error: Unexpected token { at foo.js:1:2:", "> 1 | e{}", " | ^", - " 2 | ", + " 2 |", "\n", "1 error found." ].join("\n"));