Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
177 changes: 177 additions & 0 deletions lib/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"use strict";

const path = require("path");
const tty = require("tty");
const webpackSchema = require("../schemas/WebpackOptions.json");

/** @typedef {import("json-schema").JSONSchema4} JSONSchema4 */
Expand Down Expand Up @@ -712,5 +713,181 @@ const processArguments = (args, config, values) => {
return problems;
};

/**
* @returns {boolean} true when colors supported, otherwise false
*/
const isColorSupported = () => {
const { env = {}, argv = [], platform = "" } = process;

const isDisabled = "NO_COLOR" in env || argv.includes("--no-color");
const isForced = "FORCE_COLOR" in env || argv.includes("--color");
const isWindows = platform === "win32";
const isDumbTerminal = env.TERM === "dumb";

const isCompatibleTerminal = tty.isatty(1) && env.TERM && !isDumbTerminal;

const isCI =
"CI" in env &&
("GITHUB_ACTIONS" in env || "GITLAB_CI" in env || "CIRCLECI" in env);

return (
!isDisabled &&
(isForced || (isWindows && !isDumbTerminal) || isCompatibleTerminal || isCI)
);
};

/**
* @param {number} index index
* @param {string} string string
* @param {string} close close
* @param {string=} replace replace
* @param {string=} head head
* @param {string=} tail tail
* @param {number=} next next
* @returns {string} result
*/
const replaceClose = (
index,
string,
close,
replace,
head = string.slice(0, Math.max(0, index)) + replace,
tail = string.slice(Math.max(0, index + close.length)),
next = tail.indexOf(close)
) => head + (next < 0 ? tail : replaceClose(next, tail, close, replace));

/**
* @param {number} index index to replace
* @param {string} string string
* @param {string} open open string
* @param {string} close close string
* @param {string=} replace extra replace
* @returns {string} result
*/
const clearBleed = (index, string, open, close, replace) =>
index < 0
? open + string + close
: open + replaceClose(index, string, close, replace) + close;

/** @typedef {(value: EXPECTED_ANY) => string} PrintFunction */

/**
* @param {string} open open string
* @param {string} close close string
* @param {string=} replace extra replace
* @param {number=} at at
* @returns {PrintFunction} function to create color
*/
const filterEmpty =
(open, close, replace = open, at = open.length + 1) =>
(string) =>
string || !(string === "" || string === undefined)
? clearBleed(`${string}`.indexOf(close, at), string, open, close, replace)
: "";

/**
* @param {number} open open code
* @param {number} close close code
* @param {string=} replace extra replace
* @returns {PrintFunction} result
*/
const init = (open, close, replace) =>
filterEmpty(`\u001B[${open}m`, `\u001B[${close}m`, replace);

/**
* @typedef {{
* reset: PrintFunction
* bold: PrintFunction
* dim: PrintFunction
* italic: PrintFunction
* underline: PrintFunction
* inverse: PrintFunction
* hidden: PrintFunction
* strikethrough: PrintFunction
* black: PrintFunction
* red: PrintFunction
* green: PrintFunction
* yellow: PrintFunction
* blue: PrintFunction
* magenta: PrintFunction
* cyan: PrintFunction
* white: PrintFunction
* gray: PrintFunction
* bgBlack: PrintFunction
* bgRed: PrintFunction
* bgGreen: PrintFunction
* bgYellow: PrintFunction
* bgBlue: PrintFunction
* bgMagenta: PrintFunction
* bgCyan: PrintFunction
* bgWhite: PrintFunction
* blackBright: PrintFunction
* redBright: PrintFunction
* greenBright: PrintFunction
* yellowBright: PrintFunction
* blueBright: PrintFunction
* magentaBright: PrintFunction
* cyanBright: PrintFunction
* whiteBright: PrintFunction
* bgBlackBright: PrintFunction
* bgRedBright: PrintFunction
* bgGreenBright: PrintFunction
* bgYellowBright: PrintFunction
* bgBlueBright: PrintFunction
* bgMagentaBright: PrintFunction
* bgCyanBright: PrintFunction
* bgWhiteBright: PrintFunction
}} Colors */

/**
* @param {{ useColor?: boolean }=} options options
* @returns {Colors} colors
*/
const createColors = ({ useColor = isColorSupported() } = {}) => ({
reset: useColor ? init(0, 0) : String,
bold: useColor ? init(1, 22, "\u001B[22m\u001B[1m") : String,
dim: useColor ? init(2, 22, "\u001B[22m\u001B[2m") : String,
italic: useColor ? init(3, 23) : String,
underline: useColor ? init(4, 24) : String,
inverse: useColor ? init(7, 27) : String,
hidden: useColor ? init(8, 28) : String,
strikethrough: useColor ? init(9, 29) : String,
black: useColor ? init(30, 39) : String,
red: useColor ? init(31, 39) : String,
green: useColor ? init(32, 39) : String,
yellow: useColor ? init(33, 39) : String,
blue: useColor ? init(34, 39) : String,
magenta: useColor ? init(35, 39) : String,
cyan: useColor ? init(36, 39) : String,
white: useColor ? init(37, 39) : String,
gray: useColor ? init(90, 39) : String,
bgBlack: useColor ? init(40, 49) : String,
bgRed: useColor ? init(41, 49) : String,
bgGreen: useColor ? init(42, 49) : String,
bgYellow: useColor ? init(43, 49) : String,
bgBlue: useColor ? init(44, 49) : String,
bgMagenta: useColor ? init(45, 49) : String,
bgCyan: useColor ? init(46, 49) : String,
bgWhite: useColor ? init(47, 49) : String,
blackBright: useColor ? init(90, 39) : String,
redBright: useColor ? init(91, 39) : String,
greenBright: useColor ? init(92, 39) : String,
yellowBright: useColor ? init(93, 39) : String,
blueBright: useColor ? init(94, 39) : String,
magentaBright: useColor ? init(95, 39) : String,
cyanBright: useColor ? init(96, 39) : String,
whiteBright: useColor ? init(97, 39) : String,
bgBlackBright: useColor ? init(100, 49) : String,
bgRedBright: useColor ? init(101, 49) : String,
bgGreenBright: useColor ? init(102, 49) : String,
bgYellowBright: useColor ? init(103, 49) : String,
bgBlueBright: useColor ? init(104, 49) : String,
bgMagentaBright: useColor ? init(105, 49) : String,
bgCyanBright: useColor ? init(106, 49) : String,
bgWhiteBright: useColor ? init(107, 49) : String
});

module.exports.createColors = createColors;
module.exports.getArguments = getArguments;
module.exports.isColorSupported = isColorSupported;
module.exports.processArguments = processArguments;
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@
"es6-promise-polyfill": "^1.2.0",
"eslint": "^9.29.0",
"eslint-config-prettier": "^10.1.1",
"eslint-config-webpack": "^4.3.0",
"eslint-config-webpack": "^4.4.1",
"eslint-plugin-import": "^2.32.0",
"eslint-plugin-jest": "^29.0.1",
"eslint-plugin-jsdoc": "^51.2.3",
Expand Down
Loading
Loading