From a50b1d47726b016d097b7e2c767dcc8ddf05f75f Mon Sep 17 00:00:00 2001 From: Jonathan Van Buren Date: Fri, 28 Dec 2018 17:26:59 +0800 Subject: [PATCH] Revert "Merge branch 'master' of https://github.com/vanbujm/chalk" This reverts commit cbd922b43b23ae081a0e961c4519c6abe106008b, reversing changes made to a5192264ea49574ee2cd79735c1dfd9c40a97cf7. --- .flowconfig | 1 - .travis.yml | 1 - index.d.ts | 276 -------------------------------------------- index.js | 52 +++++---- index.js.flow | 22 ++-- index.test-d.ts | 138 ---------------------- package.json | 19 ++- readme.md | 27 ++--- templates.js | 42 +++---- tsconfig.json | 7 -- types/index.d.ts | 97 ++++++++++++++++ types/test.ts | 57 +++++++++ types/tsconfig.json | 9 ++ 13 files changed, 245 insertions(+), 503 deletions(-) delete mode 100644 index.d.ts delete mode 100644 index.test-d.ts delete mode 100644 tsconfig.json create mode 100644 types/index.d.ts create mode 100644 types/test.ts create mode 100644 types/tsconfig.json diff --git a/.flowconfig b/.flowconfig index 48ee9606..2318f0d7 100644 --- a/.flowconfig +++ b/.flowconfig @@ -3,4 +3,3 @@ [options] suppress_comment= \\(.\\|\n\\)*\\$ExpectError -include_warnings=true diff --git a/.travis.yml b/.travis.yml index c89aee6f..60e38d8a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,5 @@ language: node_js node_js: - - '10' - '8' - '6' after_success: diff --git a/index.d.ts b/index.d.ts deleted file mode 100644 index b2c72139..00000000 --- a/index.d.ts +++ /dev/null @@ -1,276 +0,0 @@ -export const enum Level { - /** - * All colors disabled. - */ - None = 0, - - /** - * Basic 16 colors support. - */ - Basic = 1, - - /** - * ANSI 256 colors support. - */ - Ansi256 = 2, - - /** - * Truecolor 16 million colors support. - */ - TrueColor = 3 -} - -export interface Options { - /** - * Enable or disable Chalk. - * - * @default true - */ - enabled?: boolean; - - /** - * Specify the color support for Chalk. - * By default, color support is automatically detected based on the environment. - */ - level?: Level; -} - -export interface Constructor { - /** - * Return a new Chalk instance. - */ - new (options?: Options): Chalk; -} - -/** - * Detect whether the terminal supports color. - */ -export interface ColorSupport { - /** - * The color level used by Chalk. - */ - level: Level; - - /** - * Return whether Chalk supports basic 16 colors. - */ - hasBasic: boolean; - - /** - * Return whether Chalk supports ANSI 256 colors. - */ - has256: boolean; - - /** - * Return whether Chalk supports Truecolor 16 million colors. - */ - has16m: boolean; -} - -export interface Chalk { - (...text: unknown[]): string; - - (text: TemplateStringsArray, ...placeholders: unknown[]): string; - - /** - * Return a new Chalk instance. - */ - constructor: Constructor; - - /** - * Enable or disable Chalk. - * - * @default true - */ - enabled: boolean; - - /** - * The color support for Chalk. - * By default, color support is automatically detected based on the environment. - */ - level: Level; - - /** - * Use HEX value to set text color. - * - * @param color - Hexadecimal value representing the desired color. - * - * @example - * - * import chalk from 'chalk'; - * - * chalk.hex('#DEADED'); - */ - hex(color: string): this; - - /** - * Use keyword color value to set text color. - * - * @param color - Keyword value representing the desired color. - * - * @example - * - * import chalk from 'chalk'; - * - * chalk.keyword('orange'); - */ - keyword(color: string): this; - - /** - * Use RGB values to set text color. - */ - rgb(red: number, green: number, blue: number): this; - - /** - * Use HSL values to set text color. - */ - hsl(hue: number, saturation: number, lightness: number): this; - - /** - * Use HSV values to set text color. - */ - hsv(hue: number, saturation: number, value: number): this; - - /** - * Use HWB values to set text color. - */ - hwb(hue: number, whiteness: number, blackness: number): this; - - /** - * Use HEX value to set background color. - * - * @param color - Hexadecimal value representing the desired color. - * - * @example - * - * import chalk from 'chalk'; - * - * chalk.bgHex('#DEADED'); - */ - bgHex(color: string): this; - - /** - * Use keyword color value to set background color. - * - * @param color - Keyword value representing the desired color. - * - * @example - * - * import chalk from 'chalk'; - * - * chalk.bgKeyword('orange'); - */ - bgKeyword(color: string): this; - - /** - * Use RGB values to set background color. - */ - bgRgb(red: number, green: number, blue: number): this; - - /** - * Use HSL values to set background color. - */ - bgHsl(hue: number, saturation: number, lightness: number): this; - - /** - * Use HSV values to set background color. - */ - bgHsv(hue: number, saturation: number, value: number): this; - - /** - * Use HWB values to set background color. - */ - bgHwb(hue: number, whiteness: number, blackness: number): this; - - /** - * Modifier: Resets the current color chain. - */ - readonly reset: this; - - /** - * Modifier: Make text bold. - */ - readonly bold: this; - - /** - * Modifier: Emitting only a small amount of light. - */ - readonly dim: this; - - /** - * Modifier: Make text italic. (Not widely supported) - */ - readonly italic: this; - - /** - * Modifier: Make text underline. (Not widely supported) - */ - readonly underline: this; - - /** - * Modifier: Inverse background and foreground colors. - */ - readonly inverse: this; - - /** - * Modifier: Prints the text, but makes it invisible. - */ - readonly hidden: this; - - /** - * Modifier: Puts a horizontal line through the center of the text. (Not widely supported) - */ - readonly strikethrough: this; - - /** - * Modifier: Prints the text only when Chalk is enabled. - * Can be useful for things that are purely cosmetic. - */ - readonly visible: this; - - readonly black: this; - readonly red: this; - readonly green: this; - readonly yellow: this; - readonly blue: this; - readonly magenta: this; - readonly cyan: this; - readonly white: this; - readonly gray: this; - readonly grey: this; - readonly blackBright: this; - readonly redBright: this; - readonly greenBright: this; - readonly yellowBright: this; - readonly blueBright: this; - readonly magentaBright: this; - readonly cyanBright: this; - readonly whiteBright: this; - - readonly bgBlack: this; - readonly bgRed: this; - readonly bgGreen: this; - readonly bgYellow: this; - readonly bgBlue: this; - readonly bgMagenta: this; - readonly bgCyan: this; - readonly bgWhite: this; - readonly bgBlackBright: this; - readonly bgRedBright: this; - readonly bgGreenBright: this; - readonly bgYellowBright: this; - readonly bgBlueBright: this; - readonly bgMagentaBright: this; - readonly bgCyanBright: this; - readonly bgWhiteBright: this; -} - -/** - * Main Chalk object that allows to chain styles together. - * Call the last one as a method with a string argument. - * Order doesn't matter, and later styles take precedent in case of a conflict. - * This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`. - */ -declare const chalk: Chalk & { supportsColor: ColorSupport }; - -export default chalk; diff --git a/index.js b/index.js index 73598bef..917c45f0 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,8 @@ 'use strict'; const escapeStringRegexp = require('escape-string-regexp'); const ansiStyles = require('ansi-styles'); -const {stdout: stdoutColor} = require('supports-color'); +const stdoutColor = require('supports-color').stdout; + const template = require('./templates.js'); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -14,15 +15,15 @@ const skipModels = new Set(['gray']); const styles = Object.create(null); -function applyOptions(object, options = {}) { +function applyOptions(obj, options = {}) { if (options.level > 3 || options.level < 0) { throw new Error('The `level` option should be an integer from 0 to 3'); } // Detect level if not set manually - const colorLevel = stdoutColor ? stdoutColor.level : 0; - object.level = options.level === undefined ? colorLevel : options.level; - object.enabled = 'enabled' in options ? options.enabled : object.level > 0; + const scLevel = stdoutColor ? stdoutColor.level : 0; + obj.level = options.level === undefined ? scLevel : options.level; + obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; } function Chalk(options) { @@ -32,7 +33,7 @@ function Chalk(options) { const chalk = {}; applyOptions(chalk, options); - chalk.template = (...args) => chalkTag(chalk.template, ...args); + chalk.template = (...args) => chalkTag(...[chalk.template].concat(args)); Object.setPrototypeOf(chalk, Chalk.prototype); Object.setPrototypeOf(chalk.template, chalk); @@ -56,7 +57,7 @@ for (const key of Object.keys(ansiStyles)) { styles[key] = { get() { const codes = ansiStyles[key]; - return build.call(this, [...(this._styles || []), codes], this._empty, key); + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); } }; } @@ -83,7 +84,7 @@ for (const model of Object.keys(ansiStyles.color.ansi)) { close: ansiStyles.color.close, closeRe: ansiStyles.color.closeRe }; - return build.call(this, [...(this._styles || []), codes], this._empty, model); + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); }; } }; @@ -106,7 +107,7 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { close: ansiStyles.bgColor.close, closeRe: ansiStyles.bgColor.closeRe }; - return build.call(this, [...(this._styles || []), codes], this._empty, model); + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); }; } }; @@ -152,10 +153,23 @@ function build(_styles, _empty, key) { } function applyStyle(...args) { - let string = args.join(' '); + // Support varags, but simply cast to string in case there's only one arg + const argsLen = args.length; + let str = String(args[0]); + + if (argsLen === 0) { + return ''; + } + + if (argsLen > 1) { + // Don't slice `arguments`, it prevents V8 optimizations + for (let a = 1; a < argsLen; a++) { + str += ' ' + args[a]; + } + } - if (!this.enabled || this.level <= 0 || !string) { - return this._empty ? '' : string; + if (!this.enabled || this.level <= 0 || !str) { + return this._empty ? '' : str; } // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, @@ -170,22 +184,22 @@ function applyStyle(...args) { // Replace any instances already present with a re-opening code // otherwise only the part of the string until said closing code // will be colored, and the rest will simply be 'plain'. - string = code.open + string.replace(code.closeRe, code.open) + code.close; + str = code.open + str.replace(code.closeRe, code.open) + code.close; // Close the styling before a linebreak and reopen // after next line to fix a bleed issue on macOS // https://github.com/chalk/chalk/pull/92 - string = string.replace(/\r?\n/g, `${code.close}$&${code.open}`); + str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); } // Reset the original `dim` if we changed it to work around the Windows dimmed gray issue ansiStyles.dim.open = originalDim; - return string; + return str; } function chalkTag(chalk, ...strings) { - const [firstString] = strings; + const firstString = strings[0]; if (!Array.isArray(firstString)) { // If chalk() was called by itself or with a string, @@ -197,10 +211,8 @@ function chalkTag(chalk, ...strings) { const parts = [firstString.raw[0]]; for (let i = 1; i < firstString.length; i++) { - parts.push( - String(args[i - 1]).replace(/[{}\\]/g, '\\$&'), - String(firstString.raw[i]) - ); + parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); + parts.push(String(firstString.raw[i])); } return template(chalk, parts.join('')); diff --git a/index.js.flow b/index.js.flow index 9e70c22f..83e20185 100644 --- a/index.js.flow +++ b/index.js.flow @@ -9,7 +9,7 @@ export type Level = $Values<{ TrueColor: 3 }>; -export type Options = {| +export type ChalkOptions = {| enabled?: boolean, level?: Level |}; @@ -24,19 +24,19 @@ export type ColorSupport = {| export interface Chalk { (...text: mixed[]): string, (text: TemplateStringsArray, ...placeholders: mixed[]): string, - constructor(options?: Options): Chalk, + constructor(options?: ChalkOptions): Chalk, enabled: boolean, level: Level, - rgb(red: number, green: number, blue: number): Chalk, - hsl(hue: number, saturation: number, lightness: number): Chalk, - hsv(hue: number, saturation: number, value: number): Chalk, - hwb(hue: number, whiteness: number, blackness: number): Chalk, + rgb(r: number, g: number, b: number): Chalk, + hsl(h: number, s: number, l: number): Chalk, + hsv(h: number, s: number, v: number): Chalk, + hwb(h: number, w: number, b: number): Chalk, bgHex(color: string): Chalk, bgKeyword(color: string): Chalk, - bgRgb(red: number, green: number, blue: number): Chalk, - bgHsl(hue: number, saturation: number, lightness: number): Chalk, - bgHsv(hue: number, saturation: number, value: number): Chalk, - bgHwb(hue: number, whiteness: number, blackness: number): Chalk, + bgRgb(r: number, g: number, b: number): Chalk, + bgHsl(h: number, s: number, l: number): Chalk, + bgHsv(h: number, s: number, v: number): Chalk, + bgHwb(h: number, w: number, b: number): Chalk, hex(color: string): Chalk, keyword(color: string): Chalk, @@ -85,7 +85,7 @@ export interface Chalk { +bgBlueBright: Chalk, +bgMagentaBright: Chalk, +bgCyanBright: Chalk, - +bgWhiteBright: Chalk, + +bgWhiteBrigh: Chalk, supportsColor: ColorSupport }; diff --git a/index.test-d.ts b/index.test-d.ts deleted file mode 100644 index 26f3bc2f..00000000 --- a/index.test-d.ts +++ /dev/null @@ -1,138 +0,0 @@ -import {expectType} from 'tsd-check'; -import chalk, {Level, Chalk, ColorSupport} from '.'; - -// - Helpers - -type colorReturn = Chalk & {supportsColor: ColorSupport}; - -// - Level - -expectType(Level.None); -expectType(Level.Basic); -expectType(Level.Ansi256); -expectType(Level.TrueColor); - -// - supportsColor - -expectType(chalk.supportsColor.hasBasic); -expectType(chalk.supportsColor.has256); -expectType(chalk.supportsColor.has16m); - -// - Chalk - -// -- Constructor -- -expectType(new chalk.constructor({level: 1})); - -// -- Properties -- -expectType(chalk.enabled); -expectType(chalk.level); - -// -- Template literal -- -expectType(chalk``); -const name = 'John'; -expectType(chalk`Hello {bold.red ${name}}`); -expectType(chalk`With Numbers {bold.red ${1}}`); - -// -- Color methods -- -expectType(chalk.hex('#DEADED')); -expectType(chalk.keyword('orange')); -expectType(chalk.rgb(0, 0, 0)); -expectType(chalk.hsl(0, 0, 0)); -expectType(chalk.hsv(0, 0, 0)); -expectType(chalk.hwb(0, 0, 0)); -expectType(chalk.bgHex('#DEADED')); -expectType(chalk.bgKeyword('orange')); -expectType(chalk.bgRgb(0, 0, 0)); -expectType(chalk.bgHsl(0, 0, 0)); -expectType(chalk.bgHsv(0, 0, 0)); -expectType(chalk.bgHwb(0, 0, 0)); - -// -- Modifiers -- -expectType(chalk.reset('foo')); -expectType(chalk.bold('foo')); -expectType(chalk.dim('foo')); -expectType(chalk.italic('foo')); -expectType(chalk.underline('foo')); -expectType(chalk.inverse('foo')); -expectType(chalk.hidden('foo')); -expectType(chalk.strikethrough('foo')); -expectType(chalk.visible('foo')); -expectType(chalk.reset`foo`); -expectType(chalk.bold`foo`); -expectType(chalk.dim`foo`); -expectType(chalk.italic`foo`); -expectType(chalk.underline`foo`); -expectType(chalk.inverse`foo`); -expectType(chalk.hidden`foo`); -expectType(chalk.strikethrough`foo`); -expectType(chalk.visible`foo`); - -// -- Colors -- -expectType(chalk.black('foo')); -expectType(chalk.red('foo')); -expectType(chalk.green('foo')); -expectType(chalk.yellow('foo')); -expectType(chalk.blue('foo')); -expectType(chalk.magenta('foo')); -expectType(chalk.cyan('foo')); -expectType(chalk.white('foo')); -expectType(chalk.gray('foo')); -expectType(chalk.grey('foo')); -expectType(chalk.blackBright('foo')); -expectType(chalk.redBright('foo')); -expectType(chalk.greenBright('foo')); -expectType(chalk.yellowBright('foo')); -expectType(chalk.blueBright('foo')); -expectType(chalk.magentaBright('foo')); -expectType(chalk.cyanBright('foo')); -expectType(chalk.whiteBright('foo')); -expectType(chalk.bgBlack('foo')); -expectType(chalk.bgRed('foo')); -expectType(chalk.bgGreen('foo')); -expectType(chalk.bgYellow('foo')); -expectType(chalk.bgBlue('foo')); -expectType(chalk.bgMagenta('foo')); -expectType(chalk.bgCyan('foo')); -expectType(chalk.bgWhite('foo')); -expectType(chalk.bgBlackBright('foo')); -expectType(chalk.bgRedBright('foo')); -expectType(chalk.bgGreenBright('foo')); -expectType(chalk.bgYellowBright('foo')); -expectType(chalk.bgBlueBright('foo')); -expectType(chalk.bgMagentaBright('foo')); -expectType(chalk.bgCyanBright('foo')); -expectType(chalk.bgWhiteBright('foo')); -expectType(chalk.black`foo`); -expectType(chalk.red`foo`); -expectType(chalk.green`foo`); -expectType(chalk.yellow`foo`); -expectType(chalk.blue`foo`); -expectType(chalk.magenta`foo`); -expectType(chalk.cyan`foo`); -expectType(chalk.white`foo`); -expectType(chalk.gray`foo`); -expectType(chalk.grey`foo`); -expectType(chalk.blackBright`foo`); -expectType(chalk.redBright`foo`); -expectType(chalk.greenBright`foo`); -expectType(chalk.yellowBright`foo`); -expectType(chalk.blueBright`foo`); -expectType(chalk.magentaBright`foo`); -expectType(chalk.cyanBright`foo`); -expectType(chalk.whiteBright`foo`); -expectType(chalk.bgBlack`foo`); -expectType(chalk.bgRed`foo`); -expectType(chalk.bgGreen`foo`); -expectType(chalk.bgYellow`foo`); -expectType(chalk.bgBlue`foo`); -expectType(chalk.bgMagenta`foo`); -expectType(chalk.bgCyan`foo`); -expectType(chalk.bgWhite`foo`); -expectType(chalk.bgBlackBright`foo`); -expectType(chalk.bgRedBright`foo`); -expectType(chalk.bgGreenBright`foo`); -expectType(chalk.bgYellowBright`foo`); -expectType(chalk.bgBlueBright`foo`); -expectType(chalk.bgMagentaBright`foo`); -expectType(chalk.bgCyanBright`foo`); -expectType(chalk.bgWhiteBright`foo`); - -// -- Complex -- -expectType(chalk.red.bgGreen.underline('foo')); -expectType(chalk.underline.red.bgGreen('foo')); diff --git a/package.json b/package.json index 35fb7d0d..32c6f73b 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ "node": ">=6" }, "scripts": { - "test": "xo && nyc ava && tsd-check && flow", + "test": "xo && nyc ava && tsc --project types && flow --max-warnings=0", "bench": "matcha benchmark.js" }, "files": [ "index.js", "templates.js", - "index.d.ts", + "types/index.d.ts", "index.js.flow" ], "keywords": [ @@ -43,22 +43,21 @@ "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^6.0.0" + "supports-color": "^5.5.0" }, "devDependencies": { - "@sindresorhus/tsconfig": "^0.1.1", - "ava": "^1.0.1", + "ava": "^0.25.0", "coveralls": "^3.0.2", "execa": "^1.0.0", - "flow-bin": "^0.89.0", - "import-fresh": "^3.0.0", + "flow-bin": "^0.81.0", + "import-fresh": "^2.0.0", "matcha": "^0.7.0", - "nyc": "^13.1.0", + "nyc": "^13.0.1", "resolve-from": "^4.0.0", - "tsd-check": "^0.3.0", + "typescript": "^3.0.3", "xo": "^0.23.0" }, - "types": "index.d.ts", + "types": "types/index.d.ts", "xo": { "ignores": [ "test/_flow.js" diff --git a/readme.md b/readme.md index d8ca0708..53a7e7e9 100644 --- a/readme.md +++ b/readme.md @@ -138,7 +138,7 @@ Multiple arguments will be separated by space. ### chalk.enabled -Color support is automatically detected, as is the level (see `chalk.level`). However, if you'd like to simply enable/disable Chalk, you can do so via the `.enabled` property. When `chalk.enabled` is `true`, `chalk.level` must *also* be greater than `0` for colored output to be produced. +Color support is automatically detected, as is the level (see `chalk.level`). However, if you'd like to simply enable/disable Chalk, you can do so via the `.enabled` property. Chalk is enabled by default unless explicitly disabled via the constructor or `chalk.level` is `0`. @@ -150,7 +150,7 @@ const ctx = new chalk.constructor({enabled: false}); ### chalk.level -Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers. When `chalk.level` is greater than `0`, `chalk.enabled` must *also* be `true` for colored output to be produced. +Color support is automatically detected, but you can override it by setting the `level` property. You should however only do this in your own code as it applies globally to all Chalk consumers. If you need to change this in a reusable module, create a new instance: @@ -178,15 +178,15 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= ### Modifiers -- `reset` - Resets the current color chain. -- `bold` - Make text bold. -- `dim` - Emitting only a small amount of light. -- `italic` - Make text italic. *(Not widely supported)* -- `underline` - Make text underline. *(Not widely supported)* -- `inverse`- Inverse background and foreground colors. -- `hidden` - Prints the text, but makes it invisible. -- `strikethrough` - Puts a horizontal line through the center of the text. *(Not widely supported)* -- `visible`- Prints the text only when Chalk is enabled. Can be useful for things that are purely cosmetic. +- `reset` +- `bold` +- `dim` +- `italic` *(Not widely supported)* +- `underline` +- `inverse` +- `hidden` +- `strikethrough` *(Not widely supported)* +- `visible` (Text is emitted only if enabled) ### Colors @@ -297,11 +297,6 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i [colors.js](https://github.com/Marak/colors.js) used to be the most popular string styling module, but it has serious deficiencies like extending `String.prototype` which causes all kinds of [problems](https://github.com/yeoman/yo/issues/68) and the package is unmaintained. Although there are other packages, they either do too much or not enough. Chalk is a clean and focused alternative. -## Security - -To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. - - ## Related - [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module diff --git a/templates.js b/templates.js index bbc614d8..8ce33fe6 100644 --- a/templates.js +++ b/templates.js @@ -31,11 +31,10 @@ function parseArguments(name, args) { let matches; for (const chunk of chunks) { - const number = Number(chunk); - if (!Number.isNaN(number)) { - results.push(number); + if (!isNaN(chunk)) { + results.push(Number(chunk)); } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); } else { throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); } @@ -51,7 +50,7 @@ function parseStyle(style) { let matches; while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; // eslint-disable-line prefer-destructuring + const name = matches[1]; if (matches[2]) { const args = parseArguments(name, matches[2]); @@ -74,20 +73,17 @@ function buildStyle(chalk, styles) { } let current = chalk; - // TODO: Use `Object.entries` when targeting Node.js 8 for (const styleName of Object.keys(enabled)) { - if (!Array.isArray(enabled[styleName])) { - continue; - } - - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } + if (Array.isArray(enabled[styleName])) { + if (!(styleName in current)) { + throw new Error(`Unknown Chalk style: ${styleName}`); + } - if (enabled[styleName].length > 0) { - current = current[styleName](...enabled[styleName]); - } else { - current = current[styleName]; + if (enabled[styleName].length > 0) { + current = current[styleName](...enabled[styleName]); + } else { + current = current[styleName]; + } } } @@ -100,13 +96,13 @@ module.exports = (chalk, tmp) => { let chunk = []; // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { - if (escapeCharacter) { - chunk.push(unescape(escapeCharacter)); + tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { + if (escapeChar) { + chunk.push(unescape(escapeChar)); } else if (style) { - const string = chunk.join(''); + const str = chunk.join(''); chunk = []; - chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); + chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); styles.push({inverse, styles: parseStyle(style)}); } else if (close) { if (styles.length === 0) { @@ -117,7 +113,7 @@ module.exports = (chalk, tmp) => { chunk = []; styles.pop(); } else { - chunk.push(character); + chunk.push(chr); } }); diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 3d73ee9e..00000000 --- a/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "@sindresorhus/tsconfig", - "compilerOptions": { - "noEmit": true, - "allowJs": true - } -} diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 00000000..08f9b13f --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,97 @@ +// Type definitions for Chalk +// Definitions by: Thomas Sauer + +export const enum Level { + None = 0, + Basic = 1, + Ansi256 = 2, + TrueColor = 3 +} + +export interface ChalkOptions { + enabled?: boolean; + level?: Level; +} + +export interface ChalkConstructor { + new (options?: ChalkOptions): Chalk; + (options?: ChalkOptions): Chalk; +} + +export interface ColorSupport { + level: Level; + hasBasic: boolean; + has256: boolean; + has16m: boolean; +} + +export interface Chalk { + (...text: unknown[]): string; + (text: TemplateStringsArray, ...placeholders: unknown[]): string; + constructor: ChalkConstructor; + enabled: boolean; + level: Level; + rgb(r: number, g: number, b: number): this; + hsl(h: number, s: number, l: number): this; + hsv(h: number, s: number, v: number): this; + hwb(h: number, w: number, b: number): this; + bgHex(color: string): this; + bgKeyword(color: string): this; + bgRgb(r: number, g: number, b: number): this; + bgHsl(h: number, s: number, l: number): this; + bgHsv(h: number, s: number, v: number): this; + bgHwb(h: number, w: number, b: number): this; + hex(color: string): this; + keyword(color: string): this; + + readonly reset: this; + readonly bold: this; + readonly dim: this; + readonly italic: this; + readonly underline: this; + readonly inverse: this; + readonly hidden: this; + readonly strikethrough: this; + + readonly visible: this; + + readonly black: this; + readonly red: this; + readonly green: this; + readonly yellow: this; + readonly blue: this; + readonly magenta: this; + readonly cyan: this; + readonly white: this; + readonly gray: this; + readonly grey: this; + readonly blackBright: this; + readonly redBright: this; + readonly greenBright: this; + readonly yellowBright: this; + readonly blueBright: this; + readonly magentaBright: this; + readonly cyanBright: this; + readonly whiteBright: this; + + readonly bgBlack: this; + readonly bgRed: this; + readonly bgGreen: this; + readonly bgYellow: this; + readonly bgBlue: this; + readonly bgMagenta: this; + readonly bgCyan: this; + readonly bgWhite: this; + readonly bgBlackBright: this; + readonly bgRedBright: this; + readonly bgGreenBright: this; + readonly bgYellowBright: this; + readonly bgBlueBright: this; + readonly bgMagentaBright: this; + readonly bgCyanBright: this; + readonly bgWhiteBright: this; +} + +declare const chalk: Chalk & { supportsColor: ColorSupport }; + +export default chalk diff --git a/types/test.ts b/types/test.ts new file mode 100644 index 00000000..45d44f4b --- /dev/null +++ b/types/test.ts @@ -0,0 +1,57 @@ +import chalk, {Level} from '..'; + +chalk.underline('foo'); +chalk.red('foo'); +chalk.bgRed('foo'); + +const name = 'Josh'; +chalk`Hello {bold.red ${name}}`; + +chalk.red`foo`; +chalk.underline`foo`; +chalk`foo`; + +chalk.red.bgGreen.underline('foo'); +chalk.underline.red.bgGreen('foo'); + +chalk.grey('foo'); + +chalk.constructor({level: 1}); +const ctx = chalk.constructor({level: Level.TrueColor }); +ctx('foo'); +ctx.red('foo'); +ctx`foo`; +ctx`works with numbers ${1}`; + +chalk.enabled = true; +chalk.level = 1; +chalk.level = Level.Ansi256; + +chalk.level === Level.Ansi256; + +let chalkInstance = new chalk.constructor(); +chalkInstance = chalk.constructor(); + +chalkInstance.blue('foo'); +chalkInstance`foo`; + +let x = 'imastring'; +x = chalk(); + +chalk.enabled; +chalk.level; +chalk.supportsColor.level; +chalk.supportsColor.has16m; +chalk.supportsColor.has256; +chalk.supportsColor.hasBasic; + +chalk.keyword('orange').bgBlue('foo'); +chalk.hex('#123456').bgBlue('foo'); +chalk.rgb(1, 14, 9).bgBlue('foo'); +chalk.hsl(1, 14, 9).bgBlue('foo'); +chalk.hsv(1, 14, 9).bgBlue('foo'); +chalk.hwb(1, 14, 9).bgBlue('foo'); + +chalk.visible('foo'); +chalk.red.visible('foo'); +chalk.visible.red('foo'); diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 00000000..b73840f2 --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "noEmit": true, + "allowJs": true + } +}