From a9f0c771422b0bae65d3ff1ae4835de416350715 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 7 Aug 2017 17:41:16 +0200 Subject: [PATCH 001/170] Use a `Map` and some minor regex tweaks --- package.json | 2 +- templates.js | 30 +++++++++++++++--------------- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index a257127..a3152ee 100644 --- a/package.json +++ b/package.json @@ -47,7 +47,7 @@ "devDependencies": { "ava": "*", "coveralls": "^2.11.2", - "execa": "^0.7.0", + "execa": "^0.8.0", "import-fresh": "^2.0.0", "matcha": "^0.7.0", "nyc": "^11.0.2", diff --git a/templates.js b/templates.js index 1015515..dbdf9b2 100644 --- a/templates.js +++ b/templates.js @@ -1,28 +1,28 @@ 'use strict'; -const TEMPLATE_REGEX = /(?:\\(u[a-f0-9]{4}|x[a-f0-9]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[0-9a-f]{4}|x[0-9a-f]{2}|.)|([^\\])/gi; +const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; -const ESCAPES = { - n: '\n', - r: '\r', - t: '\t', - b: '\b', - f: '\f', - v: '\v', - 0: '\0', - '\\': '\\', - e: '\u001b', - a: '\u0007' -}; +const ESCAPES = new Map([ + ['n', '\n'], + ['r', '\r'], + ['t', '\t'], + ['b', '\b'], + ['f', '\f'], + ['v', '\v'], + ['0', '\0'], + ['\\', '\\'], + ['e', '\u001B'], + ['a', '\u0007'] +]); function unescape(c) { if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { return String.fromCharCode(parseInt(c.slice(1), 16)); } - return ESCAPES[c] || c; + return ESCAPES.get(c) || c; } function parseArguments(name, args) { From 37db75e1fd6efaabda7e7ba7751d359a34ab75cd Mon Sep 17 00:00:00 2001 From: LitoMore Date: Thu, 24 Aug 2017 02:58:45 +0800 Subject: [PATCH 002/170] Add related package in the readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index dfcfdf2..8c9609c 100644 --- a/readme.md +++ b/readme.md @@ -293,6 +293,7 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i - [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models - [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal - [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings +- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk scheme with a style pipe ## Maintainers From 7898eda561759850852fe63ba0895a49fe5b4b72 Mon Sep 17 00:00:00 2001 From: LitoMore Date: Thu, 24 Aug 2017 09:04:07 +0800 Subject: [PATCH 003/170] Update chalk-pipe description --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 8c9609c..ea7540a 100644 --- a/readme.md +++ b/readme.md @@ -293,7 +293,7 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i - [color-convert](https://github.com/qix-/color-convert) - Converts colors between different models - [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal - [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings -- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk scheme with a style pipe +- [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings ## Maintainers From 5e6d5fda44aa08e24a6b279bc16caf148c28e2db Mon Sep 17 00:00:00 2001 From: Kevin Martensson Date: Wed, 20 Sep 2017 18:03:52 +0200 Subject: [PATCH 004/170] Add `strip-ansi-stream` to related modules --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index ea7540a..7158d5a 100644 --- a/readme.md +++ b/readme.md @@ -286,6 +286,7 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i - [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal - [supports-color](https://github.com/chalk/supports-color) - Detect whether a terminal supports color - [strip-ansi](https://github.com/chalk/strip-ansi) - Strip ANSI escape codes +- [strip-ansi-stream](https://github.com/chalk/strip-ansi-stream) - Strip ANSI escape codes from a stream - [has-ansi](https://github.com/chalk/has-ansi) - Check if a string has ANSI escape codes - [ansi-regex](https://github.com/chalk/ansi-regex) - Regular expression for matching ANSI escape codes - [wrap-ansi](https://github.com/chalk/wrap-ansi) - Wordwrap a string with ANSI escape codes From f653b061d6fbdb1c7224f7d80476391202c47877 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Tue, 17 Oct 2017 22:10:43 -0500 Subject: [PATCH 005/170] Add TypeScript definitions (#207) --- index.js | 1 + package.json | 7 +++- types/index.d.ts | 90 +++++++++++++++++++++++++++++++++++++++++++++ types/test.ts | 47 +++++++++++++++++++++++ types/tsconfig.json | 9 +++++ 5 files changed, 152 insertions(+), 2 deletions(-) create mode 100644 types/index.d.ts create mode 100644 types/test.ts create mode 100644 types/tsconfig.json diff --git a/index.js b/index.js index 4c81d6d..de65bd4 100644 --- a/index.js +++ b/index.js @@ -218,3 +218,4 @@ Object.defineProperties(Chalk.prototype, styles); module.exports = Chalk(); // eslint-disable-line new-cap module.exports.supportsColor = supportsColor; +module.exports.default = module.exports; // For TypeScript diff --git a/package.json b/package.json index a3152ee..084aea6 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,14 @@ "node": ">=4" }, "scripts": { - "test": "xo && nyc ava", + "test": "xo && tsc --project types && nyc ava", "bench": "matcha benchmark.js", "coveralls": "nyc report --reporter=text-lcov | coveralls" }, "files": [ "index.js", - "templates.js" + "templates.js", + "types/index.d.ts" ], "keywords": [ "color", @@ -52,8 +53,10 @@ "matcha": "^0.7.0", "nyc": "^11.0.2", "resolve-from": "^3.0.0", + "typescript": "^2.5.3", "xo": "*" }, + "types": "types/index.d.ts", "xo": { "envs": [ "node", diff --git a/types/index.d.ts b/types/index.d.ts new file mode 100644 index 0000000..7505746 --- /dev/null +++ b/types/index.d.ts @@ -0,0 +1,90 @@ +// 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 Chalk { + new (options?: ChalkOptions): Chalk; + (options?: ChalkOptions): Chalk; + (...text: string[]): string; + (text: TemplateStringsArray, ...placeholders: string[]): string; + constructor: Chalk; + enabled: boolean; + level: Level; + supportsColor: { + level: Level; + hasBasic: boolean; + has256: boolean; + has16m: boolean; + }; + 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(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; + + reset: Chalk; + bold: Chalk; + dim: Chalk; + italic: Chalk; + underline: Chalk; + inverse: Chalk; + hidden: Chalk; + strikethrough: Chalk; + + black: Chalk; + red: Chalk; + green: Chalk; + yellow: Chalk; + blue: Chalk; + magenta: Chalk; + cyan: Chalk; + white: Chalk; + gray: Chalk; + grey: Chalk; + blackBright: Chalk; + redBright: Chalk; + greenBright: Chalk; + yellowBright: Chalk; + blueBright: Chalk; + magentaBright: Chalk; + cyanBright: Chalk; + whiteBright: Chalk; + + bgBlack: Chalk; + bgRed: Chalk; + bgGreen: Chalk; + bgYellow: Chalk; + bgBlue: Chalk; + bgMagenta: Chalk; + bgCyan: Chalk; + bgWhite: Chalk; + bgBlackBright: Chalk; + bgRedBright: Chalk; + bgGreenBright: Chalk; + bgYellowBright: Chalk; + bgBlueBright: Chalk; + bgMagentaBright: Chalk; + bgCyanBright: Chalk; + bgWhiteBright: Chalk; +} + +declare function chalk (): any; +export default chalk as Chalk; diff --git a/types/test.ts b/types/test.ts new file mode 100644 index 0000000..01509fd --- /dev/null +++ b/types/test.ts @@ -0,0 +1,47 @@ +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`; + +chalk.enabled = true; +chalk.level = 1; +chalk.level = Level.Ansi256; + +chalk.level === Level.Ansi256; + +let chalkInstance = new chalk(); +chalkInstance = new chalk.constructor(); +chalkInstance = chalk.constructor(); + +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'); diff --git a/types/tsconfig.json b/types/tsconfig.json new file mode 100644 index 0000000..b73840f --- /dev/null +++ b/types/tsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "noImplicitAny": true, + "noEmit": true, + "allowJs": true + } +} From f0533f655d237f04ec1b8744e45de60c42a7bee2 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 18 Oct 2017 10:14:40 +0700 Subject: [PATCH 006/170] Bump dev dependencies --- package.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 084aea6..2cd5a4e 100644 --- a/package.json +++ b/package.json @@ -47,12 +47,12 @@ }, "devDependencies": { "ava": "*", - "coveralls": "^2.11.2", + "coveralls": "^3.0.0", "execa": "^0.8.0", "import-fresh": "^2.0.0", "matcha": "^0.7.0", "nyc": "^11.0.2", - "resolve-from": "^3.0.0", + "resolve-from": "^4.0.0", "typescript": "^2.5.3", "xo": "*" }, From d86db88e778fa856f4d6f5f68c588750ca06b822 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 18 Oct 2017 10:15:39 +0700 Subject: [PATCH 007/170] 2.2.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 2cd5a4e..426092f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.1.0", + "version": "2.2.0", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From 4372d27f7eb887c4d33cdca1f9484f321ceab3dd Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 22 Oct 2017 15:20:23 +0700 Subject: [PATCH 008/170] Add Awesome mentioned badge --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 7158d5a..9423ebc 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ > Terminal string styling done right -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs) ### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0) From dc092b4a5f5ca77dd1e22607cdf2fdd388803064 Mon Sep 17 00:00:00 2001 From: Danny Kirchmeier Date: Mon, 23 Oct 2017 20:39:21 -0500 Subject: [PATCH 009/170] Add .visible for emitting text only when enabled (fixes #192) --- index.js | 10 +++++++++- readme.md | 1 + test/visible.js | 24 ++++++++++++++++++++++++ types/index.d.ts | 2 ++ types/test.ts | 4 ++++ 5 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 test/visible.js diff --git a/index.js b/index.js index de65bd4..861908c 100644 --- a/index.js +++ b/index.js @@ -63,6 +63,13 @@ for (const key of Object.keys(ansiStyles)) { }; } +styles.visible = { + get() { + this._emptyIfNotVisible = true; + return build.call(this, this._styles ? this._styles : [], 'visible'); + } +}; + ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); for (const model of Object.keys(ansiStyles.color.ansi)) { if (skipModels.has(model)) { @@ -116,6 +123,7 @@ function build(_styles, key) { }; builder._styles = _styles; + builder._emptyIfNotVisible = this._emptyIfNotVisible; const self = this; @@ -167,7 +175,7 @@ function applyStyle() { } if (!this.enabled || this.level <= 0 || !str) { - return str; + return this._emptyIfNotVisible ? '' : str; } // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, diff --git a/readme.md b/readme.md index 9423ebc..9bb2e65 100644 --- a/readme.md +++ b/readme.md @@ -170,6 +170,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= - `inverse` - `hidden` - `strikethrough` *(Not widely supported)* +- `visible` (Text is emitted only if enabled) ### Colors diff --git a/test/visible.js b/test/visible.js new file mode 100644 index 0000000..20f7ecb --- /dev/null +++ b/test/visible.js @@ -0,0 +1,24 @@ +import test from 'ava'; + +// Spoof supports-color +require('./_supports-color')(__dirname); + +const m = require('..'); + +test('visible: normal output when enabled', t => { + const ctx = new m.constructor({level: 3, enabled: true}); + t.is(ctx.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(ctx.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); +}); + +test('visible: no output when disabled', t => { + const ctx = new m.constructor({level: 3, enabled: false}); + t.is(ctx.red.visible('foo'), ''); + t.is(ctx.visible.red('foo'), ''); +}); + +test('visible: no output when level is too low', t => { + const ctx = new m.constructor({level: 0, enabled: true}); + t.is(ctx.visible.red('foo'), ''); + t.is(ctx.red.visible('foo'), ''); +}); diff --git a/types/index.d.ts b/types/index.d.ts index 7505746..9312e2d 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -49,6 +49,8 @@ export interface Chalk { hidden: Chalk; strikethrough: Chalk; + visible: Chalk; + black: Chalk; red: Chalk; green: Chalk; diff --git a/types/test.ts b/types/test.ts index 01509fd..63ca1e9 100644 --- a/types/test.ts +++ b/types/test.ts @@ -45,3 +45,7 @@ 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'); From 6adf5794a38552923ea474c4b60c372ef0582035 Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Mon, 23 Oct 2017 19:46:10 -0700 Subject: [PATCH 010/170] 2.2.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 426092f..d4cfc50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.2.0", + "version": "2.2.1", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From ede310303b9893146bd7cc24261a50e3b47c633a Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Mon, 23 Oct 2017 19:53:26 -0700 Subject: [PATCH 011/170] add failing test for .visible bug --- test/visible.js | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/visible.js b/test/visible.js index 20f7ecb..5d53bce 100644 --- a/test/visible.js +++ b/test/visible.js @@ -22,3 +22,26 @@ test('visible: no output when level is too low', t => { t.is(ctx.visible.red('foo'), ''); t.is(ctx.red.visible('foo'), ''); }); + +test('test switching back and forth between enabled and disabled', t => { + const ctx = new m.constructor({level: 3, enabled: true}); + t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(ctx.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(ctx.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(ctx.visible('foo'), 'foo'); + t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); + + ctx.enabled = false; + t.is(ctx.red('foo'), 'foo'); + t.is(ctx.visible('foo'), ''); + t.is(ctx.visible.red('foo'), ''); + t.is(ctx.red.visible('foo'), ''); + t.is(ctx.red('foo'), 'foo'); + + ctx.enabled = true; + t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(ctx.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(ctx.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(ctx.visible('foo'), 'foo'); + t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); +}); From e2a4aa427568ff1c5d649739c4d1f8319cf0d072 Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Mon, 23 Oct 2017 20:12:34 -0700 Subject: [PATCH 012/170] fix .visible when called after .enable is set to false --- index.js | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 861908c..05e62b3 100644 --- a/index.js +++ b/index.js @@ -58,15 +58,14 @@ for (const key of Object.keys(ansiStyles)) { styles[key] = { get() { const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], key); + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); } }; } styles.visible = { get() { - this._emptyIfNotVisible = true; - return build.call(this, this._styles ? this._styles : [], 'visible'); + return build.call(this, this._styles || [], true, 'visible'); } }; @@ -86,7 +85,7 @@ for (const model of Object.keys(ansiStyles.color.ansi)) { close: ansiStyles.color.close, closeRe: ansiStyles.color.closeRe }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], model); + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); }; } }; @@ -109,7 +108,7 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { close: ansiStyles.bgColor.close, closeRe: ansiStyles.bgColor.closeRe }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], model); + return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); }; } }; @@ -117,13 +116,13 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { const proto = Object.defineProperties(() => {}, styles); -function build(_styles, key) { +function build(_styles, _empty, key) { const builder = function () { return applyStyle.apply(builder, arguments); }; builder._styles = _styles; - builder._emptyIfNotVisible = this._emptyIfNotVisible; + builder._empty = _empty; const self = this; @@ -175,7 +174,7 @@ function applyStyle() { } if (!this.enabled || this.level <= 0 || !str) { - return this._emptyIfNotVisible ? '' : str; + return this._empty ? '' : str; } // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, From e1177ec3628f6d0d37489c1e1accd2c389a376a8 Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Mon, 23 Oct 2017 20:15:51 -0700 Subject: [PATCH 013/170] 2.2.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d4cfc50..7a9edde 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.2.1", + "version": "2.2.2", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From 7be154c074026f77b99e7d854b3a4cdd5e4ae502 Mon Sep 17 00:00:00 2001 From: calebboyd Date: Mon, 23 Oct 2017 23:02:36 -0500 Subject: [PATCH 014/170] TypeScript fixes (#217) --- types/index.d.ts | 151 ++++++++++++++++++++++++----------------------- types/test.ts | 9 ++- 2 files changed, 85 insertions(+), 75 deletions(-) diff --git a/types/index.d.ts b/types/index.d.ts index 9312e2d..b4e4dc5 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -13,80 +13,85 @@ export interface ChalkOptions { level?: Level; } -export interface Chalk { +export interface ChalkConstructor { new (options?: ChalkOptions): Chalk; (options?: ChalkOptions): Chalk; - (...text: string[]): string; - (text: TemplateStringsArray, ...placeholders: string[]): string; - constructor: Chalk; - enabled: boolean; - level: Level; - supportsColor: { - level: Level; - hasBasic: boolean; - has256: boolean; - has16m: boolean; - }; - 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(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; - - reset: Chalk; - bold: Chalk; - dim: Chalk; - italic: Chalk; - underline: Chalk; - inverse: Chalk; - hidden: Chalk; - strikethrough: Chalk; - - visible: Chalk; - - black: Chalk; - red: Chalk; - green: Chalk; - yellow: Chalk; - blue: Chalk; - magenta: Chalk; - cyan: Chalk; - white: Chalk; - gray: Chalk; - grey: Chalk; - blackBright: Chalk; - redBright: Chalk; - greenBright: Chalk; - yellowBright: Chalk; - blueBright: Chalk; - magentaBright: Chalk; - cyanBright: Chalk; - whiteBright: Chalk; - - bgBlack: Chalk; - bgRed: Chalk; - bgGreen: Chalk; - bgYellow: Chalk; - bgBlue: Chalk; - bgMagenta: Chalk; - bgCyan: Chalk; - bgWhite: Chalk; - bgBlackBright: Chalk; - bgRedBright: Chalk; - bgGreenBright: Chalk; - bgYellowBright: Chalk; - bgBlueBright: Chalk; - bgMagentaBright: Chalk; - bgCyanBright: Chalk; - bgWhiteBright: Chalk; } -declare function chalk (): any; -export default chalk as Chalk; +export interface ColorSupport { + level: Level; + hasBasic: boolean; + has256: boolean; + has16m: boolean; +} + +export interface Chalk { + (...text: string[]): string; + (text: TemplateStringsArray, ...placeholders: string[]): 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 index 63ca1e9..cedb39a 100644 --- a/types/test.ts +++ b/types/test.ts @@ -28,10 +28,15 @@ chalk.level = Level.Ansi256; chalk.level === Level.Ansi256; -let chalkInstance = new chalk(); -chalkInstance = new chalk.constructor(); +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; From 14e0aa97727019b22f0a003fdc631aeec5e2e24c Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 24 Oct 2017 11:12:53 +0700 Subject: [PATCH 015/170] 2.3.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 7a9edde..69889f0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.2.2", + "version": "2.3.0", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From 539231341426d4b3951b062e806123137b452bf7 Mon Sep 17 00:00:00 2001 From: Andrew Date: Wed, 25 Oct 2017 21:53:18 -0700 Subject: [PATCH 016/170] Correct HSV and HWB examples --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 9bb2e65..4536ac0 100644 --- a/readme.md +++ b/readme.md @@ -265,8 +265,8 @@ The following color models can be used: - [`hex`](https://en.wikipedia.org/wiki/Web_colors#Hex_triplet) - Example: `chalk.hex('#FF8800').bold('Orange!')` - [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')` - [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')` -- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 1, 1).bold('Orange!')` -- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hsl(32, 0, 50).bold('Orange!')` +- [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsv(32, 100, 100).bold('Orange!')` +- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hwb(32, 0, 50).bold('Orange!')` - `ansi16` - `ansi256` From a8c60e37fa5fd9024c727e296bd24c37f7d725d1 Mon Sep 17 00:00:00 2001 From: Brandon Smith Date: Sat, 9 Dec 2017 05:20:28 -0500 Subject: [PATCH 017/170] Fix spelling error in readme (#232) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 4536ac0..6148004 100644 --- a/readme.md +++ b/readme.md @@ -124,7 +124,7 @@ Multiple arguments will be separated by space. 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 expicitly disabled via the constructor or `chalk.level` is `0`. +Chalk is enabled by default unless explicitly disabled via the constructor or `chalk.level` is `0`. If you need to change this in a reusable module, create a new instance: From bc3dd75329b43eeda3200ac9a161b6e5a9b9dfe3 Mon Sep 17 00:00:00 2001 From: Samarth Verma Date: Sun, 31 Dec 2017 20:50:49 +0530 Subject: [PATCH 018/170] Update usage stats in the readme (#242) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 6148004..6955631 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ - Doesn't extend `String.prototype` - Clean and focused - Actively maintained -- [Used by ~17,000 packages](https://www.npmjs.com/browse/depended/chalk) as of June 20th, 2017 +- [Used by ~23,000 packages](https://www.npmjs.com/browse/depended/chalk) as of December 31, 2017 ## Install From 655403055099299cc8c5053af970366d0c4c32b7 Mon Sep 17 00:00:00 2001 From: Mario Nebl Date: Tue, 2 Jan 2018 08:53:34 +0100 Subject: [PATCH 019/170] Use svg screenshot --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 6955631..eb74603 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,7 @@ ### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0) -![](https://github.com/chalk/ansi-styles/raw/master/screenshot.png) + ## Highlights From 011dd0421e14b21a07392b8d9d28ba9e851397b4 Mon Sep 17 00:00:00 2001 From: Aman Pratap Singh Date: Sun, 11 Feb 2018 14:33:50 +0530 Subject: [PATCH 020/170] Fix usage example in the readme (#251) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index eb74603..6a903c7 100644 --- a/readme.md +++ b/readme.md @@ -51,7 +51,7 @@ const chalk = require('chalk'); const log = console.log; // Combine styled and normal strings -log(chalk.blue('Hello') + 'World' + chalk.red('!')); +log(chalk.blue('Hello') + ' World' + chalk.red('!')); // Compose multiple styles using the chainable API log(chalk.blue.bgRed.bold('Hello world!')); From 678152cf1952f3afe1e523a306c0413ad57c34b3 Mon Sep 17 00:00:00 2001 From: Kayla Washburn Date: Sun, 11 Feb 2018 02:59:24 -0700 Subject: [PATCH 021/170] Update chalk to use the latest updates to supports-color (#247) --- index.js | 6 +++--- package.json | 2 +- test/_supports-color.js | 10 ++++++---- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/index.js b/index.js index 05e62b3..1cc5fa8 100644 --- a/index.js +++ b/index.js @@ -1,7 +1,7 @@ 'use strict'; const escapeStringRegexp = require('escape-string-regexp'); const ansiStyles = require('ansi-styles'); -const supportsColor = require('supports-color'); +const stdoutColor = require('supports-color').stdout; const template = require('./templates.js'); @@ -19,7 +19,7 @@ function applyOptions(obj, options) { options = options || {}; // Detect level if not set manually - const scLevel = supportsColor ? supportsColor.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; } @@ -224,5 +224,5 @@ function chalkTag(chalk, strings) { Object.defineProperties(Chalk.prototype, styles); module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = supportsColor; +module.exports.supportsColor = stdoutColor; module.exports.default = module.exports; // For TypeScript diff --git a/package.json b/package.json index 69889f0..d5db4f7 100644 --- a/package.json +++ b/package.json @@ -43,7 +43,7 @@ "dependencies": { "ansi-styles": "^3.1.0", "escape-string-regexp": "^1.0.5", - "supports-color": "^4.0.0" + "supports-color": "^5.0.0" }, "devDependencies": { "ava": "*", diff --git a/test/_supports-color.js b/test/_supports-color.js index d6e82bb..cfca6cc 100644 --- a/test/_supports-color.js +++ b/test/_supports-color.js @@ -4,10 +4,12 @@ const resolveFrom = require('resolve-from'); module.exports = dir => { require.cache[resolveFrom(dir, 'supports-color')] = { exports: { - level: 3, - hasBasic: true, - has256: true, - has16m: true + stdout: { + level: 3, + hasBasic: true, + has256: true, + has16m: true + } } }; }; From b55dd79f8bbd37725de562ce7422cd3ba8c87c3e Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 11 Feb 2018 20:04:55 +0700 Subject: [PATCH 022/170] Force bump dependencies npm is buggy, so doing this just to be sure. --- package.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index d5db4f7..f59fbb5 100644 --- a/package.json +++ b/package.json @@ -41,14 +41,14 @@ "text" ], "dependencies": { - "ansi-styles": "^3.1.0", + "ansi-styles": "^3.2.0", "escape-string-regexp": "^1.0.5", - "supports-color": "^5.0.0" + "supports-color": "^5.2.0" }, "devDependencies": { "ava": "*", "coveralls": "^3.0.0", - "execa": "^0.8.0", + "execa": "^0.9.0", "import-fresh": "^2.0.0", "matcha": "^0.7.0", "nyc": "^11.0.2", From ae8a03f2c5c49896adeb3dd4ec5350e4ab9449a2 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 11 Feb 2018 20:18:25 +0700 Subject: [PATCH 023/170] 2.3.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index f59fbb5..a02207c 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.3.0", + "version": "2.3.1", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From 576d8d217179d2e913e29639586204c2c2a76dc3 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 15 Feb 2018 00:15:28 +0700 Subject: [PATCH 024/170] Update URL to XO --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 6a903c7..f96a964 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ > Terminal string styling done right -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/sindresorhus/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs) +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs) ### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0) From 12d1276b36cc026ecea1bdfe1771198b242f7b1d Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 15 Feb 2018 00:41:45 +0700 Subject: [PATCH 025/170] Fix linting --- templates.js | 1 + test/template-literal.js | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/templates.js b/templates.js index dbdf9b2..b2a33a4 100644 --- a/templates.js +++ b/templates.js @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/no-unsafe-regex */ 'use strict'; const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; diff --git a/test/template-literal.js b/test/template-literal.js index bfa346c..117b596 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -126,14 +126,14 @@ test('correctly parse escape in parameters (bug #177 comment 318622809)', t => { test('correctly parses unicode/hex escapes', t => { const ctx = m.constructor({level: 0}); - t.is(ctx`\u0078ylophones are fo\x78y! {magenta.inverse \u0078ylophones are fo\x78y!}`, + t.is(ctx`\u0078ylophones are fo\u0078y! {magenta.inverse \u0078ylophones are fo\u0078y!}`, 'xylophones are foxy! xylophones are foxy!'); }); test('correctly parses string arguments', t => { const ctx = m.constructor({level: 3}); t.is(ctx`{keyword('black').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); - t.is(ctx`{keyword('blac\x6B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); + t.is(ctx`{keyword('blac\u006B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); t.is(ctx`{keyword('blac\u006B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); }); @@ -159,7 +159,7 @@ test('throws if an extra unescaped } is found', t => { test('should not parse upper-case escapes', t => { const ctx = m.constructor({level: 0}); - t.is(ctx`\N\n\T\t\X07\x07\U000A\u000A\U000a\u000a`, 'N\nT\tX07\x07U000A\u000AU000a\u000A'); + t.is(ctx`\N\n\T\t\X07\u0007\U000A\u000A\U000a\u000a`, 'N\nT\tX07\u0007U000A\u000AU000a\u000A'); }); test('should properly handle undefined template interpolated values', t => { From 52823001a59ea2270c186cb41c36b0e3e0a6da37 Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Wed, 14 Feb 2018 18:28:22 -0800 Subject: [PATCH 026/170] Revert "Fix linting" This reverts commit 12d1276b36cc026ecea1bdfe1771198b242f7b1d. --- templates.js | 1 - test/template-literal.js | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/templates.js b/templates.js index b2a33a4..dbdf9b2 100644 --- a/templates.js +++ b/templates.js @@ -1,4 +1,3 @@ -/* eslint-disable unicorn/no-unsafe-regex */ 'use strict'; const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; diff --git a/test/template-literal.js b/test/template-literal.js index 117b596..bfa346c 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -126,14 +126,14 @@ test('correctly parse escape in parameters (bug #177 comment 318622809)', t => { test('correctly parses unicode/hex escapes', t => { const ctx = m.constructor({level: 0}); - t.is(ctx`\u0078ylophones are fo\u0078y! {magenta.inverse \u0078ylophones are fo\u0078y!}`, + t.is(ctx`\u0078ylophones are fo\x78y! {magenta.inverse \u0078ylophones are fo\x78y!}`, 'xylophones are foxy! xylophones are foxy!'); }); test('correctly parses string arguments', t => { const ctx = m.constructor({level: 3}); t.is(ctx`{keyword('black').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); - t.is(ctx`{keyword('blac\u006B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); + t.is(ctx`{keyword('blac\x6B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); t.is(ctx`{keyword('blac\u006B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); }); @@ -159,7 +159,7 @@ test('throws if an extra unescaped } is found', t => { test('should not parse upper-case escapes', t => { const ctx = m.constructor({level: 0}); - t.is(ctx`\N\n\T\t\X07\u0007\U000A\u000A\U000a\u000a`, 'N\nT\tX07\u0007U000A\u000AU000a\u000A'); + t.is(ctx`\N\n\T\t\X07\x07\U000A\u000A\U000a\u000a`, 'N\nT\tX07\x07U000A\u000AU000a\u000A'); }); test('should properly handle undefined template interpolated values', t => { From 925397a0f5d7f17605eaabd6ee3bb26d77280d2d Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Wed, 14 Feb 2018 18:29:19 -0800 Subject: [PATCH 027/170] Disable unicorn/no-unsafe-regex for template parser --- templates.js | 1 + 1 file changed, 1 insertion(+) diff --git a/templates.js b/templates.js index dbdf9b2..b2a33a4 100644 --- a/templates.js +++ b/templates.js @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/no-unsafe-regex */ 'use strict'; const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; From e80f02e2ddae53b897fa2d9751d5d86fae493b45 Mon Sep 17 00:00:00 2001 From: Josh Junon Date: Wed, 14 Feb 2018 18:30:01 -0800 Subject: [PATCH 028/170] Disable unicorn/no-hex-escape for template tests --- test/template-literal.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/template-literal.js b/test/template-literal.js index bfa346c..71cc106 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -1,3 +1,4 @@ +/* eslint-disable unicorn/no-hex-escape */ import test from 'ava'; // Spoof supports-color From 245dfa5c6fc4200894fc812eaa4b4159d153e0bb Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 3 Mar 2018 00:38:17 +0700 Subject: [PATCH 029/170] Bump dependencies Closes #255 Fixes #254 Fixes #224 --- package.json | 4 ++-- templates.js | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package.json b/package.json index a02207c..b1cabb5 100644 --- a/package.json +++ b/package.json @@ -41,9 +41,9 @@ "text" ], "dependencies": { - "ansi-styles": "^3.2.0", + "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^5.2.0" + "supports-color": "^5.3.0" }, "devDependencies": { "ava": "*", diff --git a/templates.js b/templates.js index b2a33a4..dbdf9b2 100644 --- a/templates.js +++ b/templates.js @@ -1,4 +1,3 @@ -/* eslint-disable unicorn/no-unsafe-regex */ 'use strict'; const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; From 84f27d4bd86f7f482a32652ae536cd996ad204bd Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 3 Mar 2018 00:43:48 +0700 Subject: [PATCH 030/170] 2.3.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b1cabb5..3edc94a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.3.1", + "version": "2.3.2", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From 0dae4c28e136513b96c3cc1b49de4d85a53b50a2 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 2 Apr 2018 14:35:53 +0700 Subject: [PATCH 031/170] Add Patreon badge --- readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/readme.md b/readme.md index f96a964..2e9b1a3 100644 --- a/readme.md +++ b/readme.md @@ -35,6 +35,10 @@ $ npm install chalk ``` + + + + ## Usage From 58483b5ab110775eb0cfc4999f1cf7e971a00fda Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 5 Apr 2018 00:43:20 +0700 Subject: [PATCH 032/170] Add a related package to the readme --- readme.md | 1 + 1 file changed, 1 insertion(+) diff --git a/readme.md b/readme.md index 2e9b1a3..aac3a71 100644 --- a/readme.md +++ b/readme.md @@ -300,6 +300,7 @@ If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) i - [chalk-animation](https://github.com/bokub/chalk-animation) - Animate strings in the terminal - [gradient-string](https://github.com/bokub/gradient-string) - Apply color gradients to strings - [chalk-pipe](https://github.com/LitoMore/chalk-pipe) - Create chalk style schemes with simpler style strings +- [terminal-link](https://github.com/sindresorhus/terminal-link) - Create clickable links in the terminal ## Maintainers From 7c6f83f719b241b7a1a1cd54b256d123e53eab4a Mon Sep 17 00:00:00 2001 From: Saad Quadri Date: Tue, 17 Apr 2018 00:26:17 -0400 Subject: [PATCH 033/170] Add Flow type definitions (#260) --- .flowconfig | 5 +++ index.js.flow | 95 +++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 9 +++-- test/_flow.js | 94 ++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 201 insertions(+), 2 deletions(-) create mode 100644 .flowconfig create mode 100644 index.js.flow create mode 100644 test/_flow.js diff --git a/.flowconfig b/.flowconfig new file mode 100644 index 0000000..2318f0d --- /dev/null +++ b/.flowconfig @@ -0,0 +1,5 @@ +[ignore] +.*/node_modules/.* + +[options] +suppress_comment= \\(.\\|\n\\)*\\$ExpectError diff --git a/index.js.flow b/index.js.flow new file mode 100644 index 0000000..a55cf1d --- /dev/null +++ b/index.js.flow @@ -0,0 +1,95 @@ +// @flow + +type TemplateStringsArray = $ReadOnlyArray; + +export type Level = $Values<{ + None: 0, + Basic: 1, + Ansi256: 2, + TrueColor: 3 +}>; + +export type ChalkOptions = {| + enabled?: boolean, + level?: Level +|}; + +export type ColorSupport = {| + level: Level, + hasBasic: boolean, + has256: boolean, + has16m: boolean +|}; + +export interface Chalk { + (...text: string[]): string, + (text: TemplateStringsArray, ...placeholders: string[]): string, + constructor(options?: ChalkOptions): Chalk, + enabled: boolean, + level: Level, + 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(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, + + +reset: Chalk, + +bold: Chalk, + +dim: Chalk, + +italic: Chalk, + +underline: Chalk, + +inverse: Chalk, + +hidden: Chalk, + +strikethrough: Chalk, + + +visible: Chalk, + + +black: Chalk, + +red: Chalk, + +green: Chalk, + +yellow: Chalk, + +blue: Chalk, + +magenta: Chalk, + +cyan: Chalk, + +white: Chalk, + +gray: Chalk, + +grey: Chalk, + +blackBright: Chalk, + +redBright: Chalk, + +greenBright: Chalk, + +yellowBright: Chalk, + +blueBright: Chalk, + +magentaBright: Chalk, + +cyanBright: Chalk, + +whiteBright: Chalk, + + +bgBlack: Chalk, + +bgRed: Chalk, + +bgGreen: Chalk, + +bgYellow: Chalk, + +bgBlue: Chalk, + +bgMagenta: Chalk, + +bgCyan: Chalk, + +bgWhite: Chalk, + +bgBlackBright: Chalk, + +bgRedBright: Chalk, + +bgGreenBright: Chalk, + +bgYellowBright: Chalk, + +bgBlueBright: Chalk, + +bgMagentaBright: Chalk, + +bgCyanBright: Chalk, + +bgWhiteBrigh: Chalk, + + supportsColor: ColorSupport +}; + +declare var chalk: Chalk; + +export default chalk; diff --git a/package.json b/package.json index 3edc94a..05ab3df 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,15 @@ "node": ">=4" }, "scripts": { - "test": "xo && tsc --project types && nyc ava", + "test": "xo && tsc --project types && flow --max-warnings=0 && nyc ava", "bench": "matcha benchmark.js", "coveralls": "nyc report --reporter=text-lcov | coveralls" }, "files": [ "index.js", "templates.js", - "types/index.d.ts" + "types/index.d.ts", + "index.js.flow" ], "keywords": [ "color", @@ -49,6 +50,7 @@ "ava": "*", "coveralls": "^3.0.0", "execa": "^0.9.0", + "flow-bin": "^0.68.0", "import-fresh": "^2.0.0", "matcha": "^0.7.0", "nyc": "^11.0.2", @@ -61,6 +63,9 @@ "envs": [ "node", "mocha" + ], + "ignores": [ + "test/_flow.js" ] } } diff --git a/test/_flow.js b/test/_flow.js new file mode 100644 index 0000000..2cf3cf2 --- /dev/null +++ b/test/_flow.js @@ -0,0 +1,94 @@ +// @flow +import chalk from '..'; + +// $ExpectError (Can't have typo in option name) +chalk.constructor({levl: 1}); +chalk.constructor({level: 1}); + +// $ExpectError (Option must have proper type) +new chalk.constructor({enabled: 'true'}); +new chalk.constructor({enabled: true}); + +// $ExpectError (Can't pass in null) +chalk.underline(null); +chalk.underline('foo'); + +// $ExpectError (Can't have typo in chalk method) +chalk.rd('foo'); +chalk.red('foo'); + +// $ExpectError (Can't have typo in chalk method) +chalk.gren`foo`; +chalk.green`foo`; + +// $ExpectError (Can't have typo in chalk method) +chalk.red.bgBlu.underline('foo'); +chalk.red.bgBlue.underline('foo'); + +// $ExpectError (Level must be 0, 1, 2, or 3) +const badCtx = chalk.constructor({level: 4}); +const ctx = chalk.constructor({level: 3}); + +// $ExpectError (Can't pass in null) +ctx(null); +ctx('foo'); + +// $ExpectError (Can't have typo in method name) +ctx.gry('foo'); +ctx.grey('foo'); + +// $ExpectError (Can't have typo in method name) +ctx`foo`.value(); +ctx`foo`.valueOf(); + +// $ExpectError (Can't have typo in property name) +chalk.abled = true; +chalk.enabled = true; + +// $ExpectError (Can't use invalid Level for property setter) +chalk.level = 10; +chalk.level = 1; + +const chalkInstance = new chalk.constructor(); + +// $ExpectError (Can't have typo in method name) +chalkInstance.blu('foo'); +chalkInstance.blue('foo'); +chalkInstance`foo`; + +// $ExpectError (Can't have typo in method name) +chalk.keywrd('orange').bgBlue('foo'); +chalk.keyword('orange').bgBlue('foo'); + +// $ExpectError (rgb should take in 3 numbers) +chalk.rgb(1, 14).bgBlue('foo'); +chalk.rgb(1, 14, 9).bgBlue('foo'); + +// $ExpectError (hsl should take in 3 numbers) +chalk.hsl(1, 14, '9').bgBlue('foo'); +chalk.hsl(1, 14, 9).bgBlue('foo'); + +// $ExpectError (hsv should take in 3 numbers) +chalk.hsv(1, 14).bgBlue('foo'); +chalk.hsv(1, 14, 9).bgBlue('foo'); + +// $ExpectError (hwb should take in 3 numbers) +chalk.hwb(1, 14).bgBlue('foo'); +chalk.hwb(1, 14, 9).bgBlue('foo'); + +// $ExpectError (Can't have typo in method name) +chalk.visibl('foo'); +chalk.visible('foo'); + +// $ExpectError (Can't have typo in method name) +chalk.red.visibl('foo'); +chalk.red.visible('foo'); +chalk.visible.red('foo'); + +// $ExpectError (Can't write to readonly property) +chalk.black = 'foo'; +chalk.black; + +// $ExpectError (Can't write to readonly property) +chalk.reset = 'foo'; +console.log(chalk.reset); From af8b3657e96a0a6ca5190fb0d0a1345797148320 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 17 Apr 2018 11:28:35 +0700 Subject: [PATCH 034/170] 2.4.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 05ab3df..1ba18c7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.3.2", + "version": "2.4.0", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From fc9a7e369b83eb91d27e0880b06b4d0a7e204a69 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 20 Apr 2018 13:42:21 +0700 Subject: [PATCH 035/170] GitHub now natively supports SVG --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index aac3a71..d298e2c 100644 --- a/readme.md +++ b/readme.md @@ -1,7 +1,7 @@



- chalk + Chalk


From 01cfb5c888481d044b90fcfebddb73defee602d7 Mon Sep 17 00:00:00 2001 From: Jamie Date: Wed, 25 Apr 2018 22:14:22 -0700 Subject: [PATCH 036/170] Improve Flow type definition for CommonJS interop (#268) --- index.js.flow | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/index.js.flow b/index.js.flow index a55cf1d..872a156 100644 --- a/index.js.flow +++ b/index.js.flow @@ -90,6 +90,4 @@ export interface Chalk { supportsColor: ColorSupport }; -declare var chalk: Chalk; - -export default chalk; +declare module.exports: Chalk; From 48ba5b0b9beadcabd9fc406ac4d9337d8fa6b36d Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 26 Apr 2018 12:15:49 +0700 Subject: [PATCH 037/170] 2.4.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1ba18c7..0893783 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.4.0", + "version": "2.4.1", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From a6ad9454525c0af602931049155cc51eccc72bb4 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 28 May 2018 09:16:44 +0700 Subject: [PATCH 038/170] Fix XO linting and update some dev dependencies Fixes #275 --- package.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 0893783..4a213f9 100644 --- a/package.json +++ b/package.json @@ -47,16 +47,16 @@ "supports-color": "^5.3.0" }, "devDependencies": { - "ava": "*", + "ava": "0.25.0", "coveralls": "^3.0.0", - "execa": "^0.9.0", - "flow-bin": "^0.68.0", + "execa": "^0.10.0", + "flow-bin": "^0.73.0", "import-fresh": "^2.0.0", "matcha": "^0.7.0", "nyc": "^11.0.2", "resolve-from": "^4.0.0", "typescript": "^2.5.3", - "xo": "*" + "xo": "0.20.3" }, "types": "types/index.d.ts", "xo": { From a2b5fa22dca4cf0949d978826d3c05478ea2ecf2 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Mon, 6 Aug 2018 15:53:00 +0700 Subject: [PATCH 039/170] Add some badges to the readme --- readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.md b/readme.md index d298e2c..e16f679 100644 --- a/readme.md +++ b/readme.md @@ -9,11 +9,11 @@ > Terminal string styling done right -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs) +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs) ### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0) - + ## Highlights @@ -26,7 +26,7 @@ - Doesn't extend `String.prototype` - Clean and focused - Actively maintained -- [Used by ~23,000 packages](https://www.npmjs.com/browse/depended/chalk) as of December 31, 2017 +- [Used by ~30,000 packages](https://www.npmjs.com/browse/depended/chalk) as of August 6, 2018 ## Install From 70f22d87ba4348637f236686bd17318922107a44 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 1 Sep 2018 02:50:53 +0700 Subject: [PATCH 040/170] Tiny travis.yml tweak --- .travis.yml | 3 ++- package.json | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index ea5900d..2126ad4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,4 +3,5 @@ node_js: - '8' - '6' - '4' -after_success: npm run coveralls +after_success: + - './node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/coveralls' diff --git a/package.json b/package.json index 4a213f9..514c53d 100644 --- a/package.json +++ b/package.json @@ -8,9 +8,8 @@ "node": ">=4" }, "scripts": { - "test": "xo && tsc --project types && flow --max-warnings=0 && nyc ava", - "bench": "matcha benchmark.js", - "coveralls": "nyc report --reporter=text-lcov | coveralls" + "test": "xo && nyc ava && tsc --project types && flow --max-warnings=0", + "bench": "matcha benchmark.js" }, "files": [ "index.js", From 0307f263cb29dace28e7cf0648b13a3f527697af Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 18 Sep 2018 14:05:08 +0700 Subject: [PATCH 041/170] Require Node.js 6 --- .gitattributes | 3 +- .travis.yml | 1 - benchmark.js | 2 +- index.js | 43 +++++++------- package.json | 22 +++---- templates.js | 2 +- test/chalk.js | 57 +++++++++---------- test/constructor.js | 22 +++---- test/enabled.js | 30 +++++----- test/level.js | 38 ++++++------- test/template-literal.js | 120 +++++++++++++++++++-------------------- test/visible.js | 56 +++++++++--------- test/windows.js | 24 ++++---- 13 files changed, 204 insertions(+), 216 deletions(-) diff --git a/.gitattributes b/.gitattributes index 391f0a4..6313b56 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,2 +1 @@ -* text=auto -*.js text eol=lf +* text=auto eol=lf diff --git a/.travis.yml b/.travis.yml index 2126ad4..60e38d8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,5 @@ language: node_js node_js: - '8' - '6' - - '4' after_success: - './node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/coveralls' diff --git a/benchmark.js b/benchmark.js index af90c06..f4e9cf3 100644 --- a/benchmark.js +++ b/benchmark.js @@ -1,4 +1,4 @@ -/* globals set bench */ +/* globals suite, set, bench */ 'use strict'; const chalk = require('.'); diff --git a/index.js b/index.js index 1cc5fa8..333c836 100644 --- a/index.js +++ b/index.js @@ -31,10 +31,7 @@ function Chalk(options) { const chalk = {}; applyOptions(chalk, options); - chalk.template = function () { - const args = [].slice.call(arguments); - return chalkTag.apply(null, [chalk.template].concat(args)); - }; + chalk.template = (...args) => chalkTag(...[chalk.template].concat(args)); Object.setPrototypeOf(chalk, Chalk.prototype); Object.setPrototypeOf(chalk.template, chalk); @@ -77,9 +74,9 @@ for (const model of Object.keys(ansiStyles.color.ansi)) { styles[model] = { get() { - const level = this.level; - return function () { - const open = ansiStyles.color[levelMapping[level]][model].apply(null, arguments); + const {level} = this; + return function (...args) { + const open = ansiStyles.color[levelMapping[level]][model](...args); const codes = { open, close: ansiStyles.color.close, @@ -100,9 +97,9 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); styles[bgModel] = { get() { - const level = this.level; - return function () { - const open = ansiStyles.bgColor[levelMapping[level]][model].apply(null, arguments); + const {level} = this; + return function (...args) { + const open = ansiStyles.bgColor[levelMapping[level]][model](...args); const codes = { open, close: ansiStyles.bgColor.close, @@ -117,10 +114,7 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { const proto = Object.defineProperties(() => {}, styles); function build(_styles, _empty, key) { - const builder = function () { - return applyStyle.apply(builder, arguments); - }; - + const builder = (...args) => applyStyle.call(builder, ...args); builder._styles = _styles; builder._empty = _empty; @@ -156,11 +150,10 @@ function build(_styles, _empty, key) { return builder; } -function applyStyle() { +function applyStyle(...args) { // Support varags, but simply cast to string in case there's only one arg - const args = arguments; const argsLen = args.length; - let str = String(arguments[0]); + let str = String(args[0]); if (argsLen === 0) { return ''; @@ -203,19 +196,21 @@ function applyStyle() { return str; } -function chalkTag(chalk, strings) { - if (!Array.isArray(strings)) { +function chalkTag(chalk, ...strings) { + const firstString = strings[0]; + + if (!Array.isArray(firstString)) { // If chalk() was called by itself or with a string, // return the string itself as a string. - return [].slice.call(arguments, 1).join(' '); + return strings.join(' '); } - const args = [].slice.call(arguments, 2); - const parts = [strings.raw[0]]; + const args = strings.slice(1); + const parts = [firstString.raw[0]]; - for (let i = 1; i < strings.length; i++) { + for (let i = 1; i < firstString.length; i++) { parts.push(String(args[i - 1]).replace(/[{}\\]/g, '\\$&')); - parts.push(String(strings.raw[i])); + parts.push(String(firstString.raw[i])); } return template(chalk, parts.join('')); diff --git a/package.json b/package.json index 514c53d..32c6f73 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "MIT", "repository": "chalk/chalk", "engines": { - "node": ">=4" + "node": ">=6" }, "scripts": { "test": "xo && nyc ava && tsc --project types && flow --max-warnings=0", @@ -43,26 +43,22 @@ "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" + "supports-color": "^5.5.0" }, "devDependencies": { - "ava": "0.25.0", - "coveralls": "^3.0.0", - "execa": "^0.10.0", - "flow-bin": "^0.73.0", + "ava": "^0.25.0", + "coveralls": "^3.0.2", + "execa": "^1.0.0", + "flow-bin": "^0.81.0", "import-fresh": "^2.0.0", "matcha": "^0.7.0", - "nyc": "^11.0.2", + "nyc": "^13.0.1", "resolve-from": "^4.0.0", - "typescript": "^2.5.3", - "xo": "0.20.3" + "typescript": "^3.0.3", + "xo": "^0.23.0" }, "types": "types/index.d.ts", "xo": { - "envs": [ - "node", - "mocha" - ], "ignores": [ "test/_flow.js" ] diff --git a/templates.js b/templates.js index dbdf9b2..8ce33fe 100644 --- a/templates.js +++ b/templates.js @@ -80,7 +80,7 @@ function buildStyle(chalk, styles) { } if (enabled[styleName].length > 0) { - current = current[styleName].apply(current, enabled[styleName]); + current = current[styleName](...enabled[styleName]); } else { current = current[styleName]; } diff --git a/test/chalk.js b/test/chalk.js index 8480dad..a53b6f5 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -3,51 +3,50 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const m = require('..'); +const chalk = require('..'); console.log('TERM:', process.env.TERM || '[none]'); console.log('platform:', process.platform || '[unknown]'); test('don\'t add any styling when called as the base function', t => { - t.is(m('foo'), 'foo'); + t.is(chalk('foo'), 'foo'); }); test('support multiple arguments in base function', t => { - t.is(m('hello', 'there'), 'hello there'); + t.is(chalk('hello', 'there'), 'hello there'); }); test('style string', t => { - t.is(m.underline('foo'), '\u001B[4mfoo\u001B[24m'); - t.is(m.red('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(m.bgRed('foo'), '\u001B[41mfoo\u001B[49m'); + t.is(chalk.underline('foo'), '\u001B[4mfoo\u001B[24m'); + t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(chalk.bgRed('foo'), '\u001B[41mfoo\u001B[49m'); }); test('support applying multiple styles at once', t => { - t.is(m.red.bgGreen.underline('foo'), '\u001B[31m\u001B[42m\u001B[4mfoo\u001B[24m\u001B[49m\u001B[39m'); - t.is(m.underline.red.bgGreen('foo'), '\u001B[4m\u001B[31m\u001B[42mfoo\u001B[49m\u001B[39m\u001B[24m'); + t.is(chalk.red.bgGreen.underline('foo'), '\u001B[31m\u001B[42m\u001B[4mfoo\u001B[24m\u001B[49m\u001B[39m'); + t.is(chalk.underline.red.bgGreen('foo'), '\u001B[4m\u001B[31m\u001B[42mfoo\u001B[49m\u001B[39m\u001B[24m'); }); test('support nesting styles', t => { t.is( - m.red('foo' + m.underline.bgBlue('bar') + '!'), + chalk.red('foo' + chalk.underline.bgBlue('bar') + '!'), '\u001B[31mfoo\u001B[4m\u001B[44mbar\u001B[49m\u001B[24m!\u001B[39m' ); }); test('support nesting styles of the same type (color, underline, bg)', t => { t.is( - m.red('a' + m.yellow('b' + m.green('c') + 'b') + 'c'), + chalk.red('a' + chalk.yellow('b' + chalk.green('c') + 'b') + 'c'), '\u001B[31ma\u001B[33mb\u001B[32mc\u001B[33mb\u001B[31mc\u001B[39m' ); }); test('reset all styles with `.reset()`', t => { - t.is(m.reset(m.red.bgGreen.underline('foo') + 'foo'), '\u001B[0m\u001B[31m\u001B[42m\u001B[4mfoo\u001B[24m\u001B[49m\u001B[39mfoo\u001B[0m'); + t.is(chalk.reset(chalk.red.bgGreen.underline('foo') + 'foo'), '\u001B[0m\u001B[31m\u001B[42m\u001B[4mfoo\u001B[24m\u001B[49m\u001B[39mfoo\u001B[0m'); }); test('support caching multiple styles', t => { - const red = m.red; - const green = m.green; + const {red, green} = chalk.red; const redBold = red.bold; const greenBold = green.bold; @@ -57,44 +56,44 @@ test('support caching multiple styles', t => { }); test('alias gray to grey', t => { - t.is(m.grey('foo'), '\u001B[90mfoo\u001B[39m'); + t.is(chalk.grey('foo'), '\u001B[90mfoo\u001B[39m'); }); test('support variable number of arguments', t => { - t.is(m.red('foo', 'bar'), '\u001B[31mfoo bar\u001B[39m'); + t.is(chalk.red('foo', 'bar'), '\u001B[31mfoo bar\u001B[39m'); }); test('support falsy values', t => { - t.is(m.red(0), '\u001B[31m0\u001B[39m'); + t.is(chalk.red(0), '\u001B[31m0\u001B[39m'); }); test('don\'t output escape codes if the input is empty', t => { - t.is(m.red(), ''); - t.is(m.red.blue.black(), ''); + t.is(chalk.red(), ''); + t.is(chalk.red.blue.black(), ''); }); test('keep Function.prototype methods', t => { - t.is(m.grey.apply(null, ['foo']), '\u001B[90mfoo\u001B[39m'); - t.is(m.reset(m.red.bgGreen.underline.bind(null)('foo') + 'foo'), '\u001B[0m\u001B[31m\u001B[42m\u001B[4mfoo\u001B[24m\u001B[49m\u001B[39mfoo\u001B[0m'); - t.is(m.red.blue.black.call(null), ''); + t.is(chalk.grey.apply(null, ['foo']), '\u001B[90mfoo\u001B[39m'); + t.is(chalk.reset(chalk.red.bgGreen.underline.bind(null)('foo') + 'foo'), '\u001B[0m\u001B[31m\u001B[42m\u001B[4mfoo\u001B[24m\u001B[49m\u001B[39mfoo\u001B[0m'); + t.is(chalk.red.blue.black.call(null), ''); }); test('line breaks should open and close colors', t => { - t.is(m.grey('hello\nworld'), '\u001B[90mhello\u001B[39m\n\u001B[90mworld\u001B[39m'); + t.is(chalk.grey('hello\nworld'), '\u001B[90mhello\u001B[39m\n\u001B[90mworld\u001B[39m'); }); test('properly convert RGB to 16 colors on basic color terminals', t => { - t.is(new m.constructor({level: 1}).hex('#FF0000')('hello'), '\u001B[91mhello\u001B[39m'); - t.is(new m.constructor({level: 1}).bgHex('#FF0000')('hello'), '\u001B[101mhello\u001B[49m'); + t.is(new chalk.constructor({level: 1}).hex('#FF0000')('hello'), '\u001B[91mhello\u001B[39m'); + t.is(new chalk.constructor({level: 1}).bgHex('#FF0000')('hello'), '\u001B[101mhello\u001B[49m'); }); test('properly convert RGB to 256 colors on basic color terminals', t => { - t.is(new m.constructor({level: 2}).hex('#FF0000')('hello'), '\u001B[38;5;196mhello\u001B[39m'); - t.is(new m.constructor({level: 2}).bgHex('#FF0000')('hello'), '\u001B[48;5;196mhello\u001B[49m'); - t.is(new m.constructor({level: 3}).bgHex('#FF0000')('hello'), '\u001B[48;2;255;0;0mhello\u001B[49m'); + t.is(new chalk.constructor({level: 2}).hex('#FF0000')('hello'), '\u001B[38;5;196mhello\u001B[39m'); + t.is(new chalk.constructor({level: 2}).bgHex('#FF0000')('hello'), '\u001B[48;5;196mhello\u001B[49m'); + t.is(new chalk.constructor({level: 3}).bgHex('#FF0000')('hello'), '\u001B[48;2;255;0;0mhello\u001B[49m'); }); test('don\'t emit RGB codes if level is 0', t => { - t.is(new m.constructor({level: 0}).hex('#FF0000')('hello'), 'hello'); - t.is(new m.constructor({level: 0}).bgHex('#FF0000')('hello'), 'hello'); + t.is(new chalk.constructor({level: 0}).hex('#FF0000')('hello'), 'hello'); + t.is(new chalk.constructor({level: 0}).bgHex('#FF0000')('hello'), 'hello'); }); diff --git a/test/constructor.js b/test/constructor.js index d592e82..510f1a0 100644 --- a/test/constructor.js +++ b/test/constructor.js @@ -3,20 +3,20 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const m = require('..'); +const chalk = require('..'); test('create an isolated context where colors can be disabled (by level)', t => { - const ctx = new m.constructor({level: 0, enabled: true}); - t.is(ctx.red('foo'), 'foo'); - t.is(m.red('foo'), '\u001B[31mfoo\u001B[39m'); - ctx.level = 2; - t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); + const instance = new chalk.constructor({level: 0, enabled: true}); + t.is(instance.red('foo'), 'foo'); + t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); + instance.level = 2; + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); }); test('create an isolated context where colors can be disabled (by enabled flag)', t => { - const ctx = new m.constructor({enabled: false}); - t.is(ctx.red('foo'), 'foo'); - t.is(m.red('foo'), '\u001B[31mfoo\u001B[39m'); - ctx.enabled = true; - t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); + const instance = new chalk.constructor({enabled: false}); + t.is(instance.red('foo'), 'foo'); + t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); + instance.enabled = true; + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); }); diff --git a/test/enabled.js b/test/enabled.js index 3270e54..e596621 100644 --- a/test/enabled.js +++ b/test/enabled.js @@ -3,33 +3,33 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const m = require('..'); +const chalk = require('..'); test('don\'t output colors when manually disabled', t => { - m.enabled = false; - t.is(m.red('foo'), 'foo'); - m.enabled = true; + chalk.enabled = false; + t.is(chalk.red('foo'), 'foo'); + chalk.enabled = true; }); test('enable/disable colors based on overall chalk enabled property, not individual instances', t => { - m.enabled = false; - const red = m.red; + chalk.enabled = false; + const {red} = chalk; t.false(red.enabled); - m.enabled = true; + chalk.enabled = true; t.true(red.enabled); - m.enabled = true; + chalk.enabled = true; }); test('propagate enable/disable changes from child colors', t => { - m.enabled = false; - const red = m.red; + chalk.enabled = false; + const {red} = chalk; t.false(red.enabled); - t.false(m.enabled); + t.false(chalk.enabled); red.enabled = true; t.true(red.enabled); - t.true(m.enabled); - m.enabled = false; + t.true(chalk.enabled); + chalk.enabled = false; t.false(red.enabled); - t.false(m.enabled); - m.enabled = true; + t.false(chalk.enabled); + chalk.enabled = true; }); diff --git a/test/level.js b/test/level.js index 85624ea..06fdb59 100644 --- a/test/level.js +++ b/test/level.js @@ -5,38 +5,38 @@ import execa from 'execa'; // Spoof supports-color require('./_supports-color')(__dirname); -const m = require('..'); +const chalk = require('..'); test('don\'t output colors when manually disabled', t => { - const oldLevel = m.level; - m.level = 0; - t.is(m.red('foo'), 'foo'); - m.level = oldLevel; + const oldLevel = chalk.level; + chalk.level = 0; + t.is(chalk.red('foo'), 'foo'); + chalk.level = oldLevel; }); test('enable/disable colors based on overall chalk enabled property, not individual instances', t => { - const oldLevel = m.level; - m.level = 1; - const red = m.red; + const oldLevel = chalk.level; + chalk.level = 1; + const {red} = chalk; t.is(red.level, 1); - m.level = 0; - t.is(red.level, m.level); - m.level = oldLevel; + chalk.level = 0; + t.is(red.level, chalk.level); + chalk.level = oldLevel; }); test('propagate enable/disable changes from child colors', t => { - const oldLevel = m.level; - m.level = 1; - const red = m.red; + const oldLevel = chalk.level; + chalk.level = 1; + const {red} = chalk; t.is(red.level, 1); - t.is(m.level, 1); + t.is(chalk.level, 1); red.level = 0; t.is(red.level, 0); - t.is(m.level, 0); - m.level = 1; + t.is(chalk.level, 0); + chalk.level = 1; t.is(red.level, 1); - t.is(m.level, 1); - m.level = oldLevel; + t.is(chalk.level, 1); + chalk.level = oldLevel; }); test('disable colors if they are not supported', async t => { diff --git a/test/template-literal.js b/test/template-literal.js index 71cc106..34588d2 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -4,82 +4,82 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const m = require('..'); +const chalk = require('..'); test('return an empty string for an empty literal', t => { - const ctx = m.constructor(); - t.is(ctx``, ''); + const instance = chalk.constructor(); + t.is(instance``, ''); }); test('return a regular string for a literal with no templates', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`hello`, 'hello'); + const instance = chalk.constructor({level: 0}); + t.is(instance`hello`, 'hello'); }); test('correctly perform template parsing', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`{bold Hello, {cyan World!} This is a} test. {green Woo!}`, - ctx.bold('Hello,', ctx.cyan('World!'), 'This is a') + ' test. ' + ctx.green('Woo!')); + const instance = chalk.constructor({level: 0}); + t.is(instance`{bold Hello, {cyan World!} This is a} test. {green Woo!}`, + instance.bold('Hello,', instance.cyan('World!'), 'This is a') + ' test. ' + instance.green('Woo!')); }); test('correctly perform template substitutions', t => { - const ctx = m.constructor({level: 0}); + const instance = chalk.constructor({level: 0}); const name = 'Sindre'; const exclamation = 'Neat'; - t.is(ctx`{bold Hello, {cyan.inverse ${name}!} This is a} test. {green ${exclamation}!}`, - ctx.bold('Hello,', ctx.cyan.inverse(name + '!'), 'This is a') + ' test. ' + ctx.green(exclamation + '!')); + t.is(instance`{bold Hello, {cyan.inverse ${name}!} This is a} test. {green ${exclamation}!}`, + instance.bold('Hello,', instance.cyan.inverse(name + '!'), 'This is a') + ' test. ' + instance.green(exclamation + '!')); }); test('correctly parse and evaluate color-convert functions', t => { - const ctx = m.constructor({level: 3}); - t.is(ctx`{bold.rgb(144,10,178).inverse Hello, {~inverse there!}}`, + const instance = chalk.constructor({level: 3}); + t.is(instance`{bold.rgb(144,10,178).inverse Hello, {~inverse there!}}`, '\u001B[1m\u001B[38;2;144;10;178m\u001B[7mHello, ' + '\u001B[27m\u001B[39m\u001B[22m\u001B[1m' + '\u001B[38;2;144;10;178mthere!\u001B[39m\u001B[22m'); - t.is(ctx`{bold.bgRgb(144,10,178).inverse Hello, {~inverse there!}}`, + t.is(instance`{bold.bgRgb(144,10,178).inverse Hello, {~inverse there!}}`, '\u001B[1m\u001B[48;2;144;10;178m\u001B[7mHello, ' + '\u001B[27m\u001B[49m\u001B[22m\u001B[1m' + '\u001B[48;2;144;10;178mthere!\u001B[49m\u001B[22m'); }); test('properly handle escapes', t => { - const ctx = m.constructor({level: 3}); - t.is(ctx`{bold hello \{in brackets\}}`, + const instance = chalk.constructor({level: 3}); + t.is(instance`{bold hello \{in brackets\}}`, '\u001B[1mhello {in brackets}\u001B[22m'); }); test('throw if there is an unclosed block', t => { - const ctx = m.constructor({level: 3}); + const instance = chalk.constructor({level: 3}); try { - console.log(ctx`{bold this shouldn't appear ever\}`); + console.log(instance`{bold this shouldn't appear ever\}`); t.fail(); - } catch (err) { - t.is(err.message, 'Chalk template literal is missing 1 closing bracket (`}`)'); + } catch (error) { + t.is(error.message, 'Chalk template literal is missing 1 closing bracket (`}`)'); } try { - console.log(ctx`{bold this shouldn't {inverse appear {underline ever\} :) \}`); + console.log(instance`{bold this shouldn't {inverse appear {underline ever\} :) \}`); t.fail(); - } catch (err) { - t.is(err.message, 'Chalk template literal is missing 3 closing brackets (`}`)'); + } catch (error) { + t.is(error.message, 'Chalk template literal is missing 3 closing brackets (`}`)'); } }); test('throw if there is an invalid style', t => { - const ctx = m.constructor({level: 3}); + const instance = chalk.constructor({level: 3}); try { - console.log(ctx`{abadstylethatdoesntexist this shouldn't appear ever}`); + console.log(instance`{abadstylethatdoesntexist this shouldn't appear ever}`); t.fail(); - } catch (err) { - t.is(err.message, 'Unknown Chalk style: abadstylethatdoesntexist'); + } catch (error) { + t.is(error.message, 'Unknown Chalk style: abadstylethatdoesntexist'); } }); test('properly style multiline color blocks', t => { - const ctx = m.constructor({level: 3}); + const instance = chalk.constructor({level: 3}); t.is( - ctx`{bold + instance`{bold Hello! This is a ${'multiline'} block! :) @@ -97,74 +97,74 @@ test('properly style multiline color blocks', t => { }); test('escape interpolated values', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`Hello {bold hi}`, 'Hello hi'); - t.is(ctx`Hello ${'{bold hi}'}`, 'Hello {bold hi}'); + const instance = chalk.constructor({level: 0}); + t.is(instance`Hello {bold hi}`, 'Hello hi'); + t.is(instance`Hello ${'{bold hi}'}`, 'Hello {bold hi}'); }); test('allow custom colors (themes) on custom contexts', t => { - const ctx = m.constructor({level: 3}); - ctx.rose = ctx.hex('#F6D9D9'); - t.is(ctx`Hello, {rose Rose}.`, 'Hello, \u001B[38;2;246;217;217mRose\u001B[39m.'); + const instance = chalk.constructor({level: 3}); + instance.rose = instance.hex('#F6D9D9'); + t.is(instance`Hello, {rose Rose}.`, 'Hello, \u001B[38;2;246;217;217mRose\u001B[39m.'); }); test('correctly parse newline literals (bug #184)', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`Hello + const instance = chalk.constructor({level: 0}); + t.is(instance`Hello {red there}`, 'Hello\nthere'); }); test('correctly parse newline escapes (bug #177)', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`Hello\nthere!`, `Hello\nthere!`); + const instance = chalk.constructor({level: 0}); + t.is(instance`Hello\nthere!`, 'Hello\nthere!'); }); test('correctly parse escape in parameters (bug #177 comment 318622809)', t => { - const ctx = m.constructor({level: 0}); + const instance = chalk.constructor({level: 0}); const str = '\\'; - t.is(ctx`{blue ${str}}`, '\\'); + t.is(instance`{blue ${str}}`, '\\'); }); test('correctly parses unicode/hex escapes', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`\u0078ylophones are fo\x78y! {magenta.inverse \u0078ylophones are fo\x78y!}`, + const instance = chalk.constructor({level: 0}); + t.is(instance`\u0078ylophones are fo\x78y! {magenta.inverse \u0078ylophones are fo\x78y!}`, 'xylophones are foxy! xylophones are foxy!'); }); test('correctly parses string arguments', t => { - const ctx = m.constructor({level: 3}); - t.is(ctx`{keyword('black').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); - t.is(ctx`{keyword('blac\x6B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); - t.is(ctx`{keyword('blac\u006B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); + const instance = chalk.constructor({level: 3}); + t.is(instance`{keyword('black').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); + t.is(instance`{keyword('blac\x6B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); + t.is(instance`{keyword('blac\u006B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); }); test('throws if a bad argument is encountered', t => { - const ctx = m.constructor({level: 3}); // Keep level at least 1 in case we optimize for disabled chalk instances + const instance = chalk.constructor({level: 3}); // Keep level at least 1 in case we optimize for disabled chalk instances try { - console.log(ctx`{keyword(????) hi}`); + console.log(instance`{keyword(????) hi}`); t.fail(); - } catch (err) { - t.is(err.message, 'Invalid Chalk template style argument: ???? (in style \'keyword\')'); + } catch (error) { + t.is(error.message, 'Invalid Chalk template style argument: ???? (in style \'keyword\')'); } }); test('throws if an extra unescaped } is found', t => { - const ctx = m.constructor({level: 0}); + const instance = chalk.constructor({level: 0}); try { - console.log(ctx`{red hi!}}`); + console.log(instance`{red hi!}}`); t.fail(); - } catch (err) { - t.is(err.message, 'Found extraneous } in Chalk template literal'); + } catch (error) { + t.is(error.message, 'Found extraneous } in Chalk template literal'); } }); test('should not parse upper-case escapes', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`\N\n\T\t\X07\x07\U000A\u000A\U000a\u000a`, 'N\nT\tX07\x07U000A\u000AU000a\u000A'); + const instance = chalk.constructor({level: 0}); + t.is(instance`\N\n\T\t\X07\x07\U000A\u000A\U000a\u000a`, 'N\nT\tX07\x07U000A\u000AU000a\u000A'); }); test('should properly handle undefined template interpolated values', t => { - const ctx = m.constructor({level: 0}); - t.is(ctx`hello ${undefined}`, 'hello undefined'); - t.is(ctx`hello ${null}`, 'hello null'); + const instance = chalk.constructor({level: 0}); + t.is(instance`hello ${undefined}`, 'hello undefined'); + t.is(instance`hello ${null}`, 'hello null'); }); diff --git a/test/visible.js b/test/visible.js index 5d53bce..3266295 100644 --- a/test/visible.js +++ b/test/visible.js @@ -3,45 +3,45 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const m = require('..'); +const chalk = require('..'); test('visible: normal output when enabled', t => { - const ctx = new m.constructor({level: 3, enabled: true}); - t.is(ctx.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(ctx.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); + const instance = new chalk.constructor({level: 3, enabled: true}); + t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); }); test('visible: no output when disabled', t => { - const ctx = new m.constructor({level: 3, enabled: false}); - t.is(ctx.red.visible('foo'), ''); - t.is(ctx.visible.red('foo'), ''); + const instance = new chalk.constructor({level: 3, enabled: false}); + t.is(instance.red.visible('foo'), ''); + t.is(instance.visible.red('foo'), ''); }); test('visible: no output when level is too low', t => { - const ctx = new m.constructor({level: 0, enabled: true}); - t.is(ctx.visible.red('foo'), ''); - t.is(ctx.red.visible('foo'), ''); + const instance = new chalk.constructor({level: 0, enabled: true}); + t.is(instance.visible.red('foo'), ''); + t.is(instance.red.visible('foo'), ''); }); test('test switching back and forth between enabled and disabled', t => { - const ctx = new m.constructor({level: 3, enabled: true}); - t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(ctx.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(ctx.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(ctx.visible('foo'), 'foo'); - t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); + const instance = new chalk.constructor({level: 3, enabled: true}); + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(instance.visible('foo'), 'foo'); + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); - ctx.enabled = false; - t.is(ctx.red('foo'), 'foo'); - t.is(ctx.visible('foo'), ''); - t.is(ctx.visible.red('foo'), ''); - t.is(ctx.red.visible('foo'), ''); - t.is(ctx.red('foo'), 'foo'); + instance.enabled = false; + t.is(instance.red('foo'), 'foo'); + t.is(instance.visible('foo'), ''); + t.is(instance.visible.red('foo'), ''); + t.is(instance.red.visible('foo'), ''); + t.is(instance.red('foo'), 'foo'); - ctx.enabled = true; - t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(ctx.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(ctx.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); - t.is(ctx.visible('foo'), 'foo'); - t.is(ctx.red('foo'), '\u001B[31mfoo\u001B[39m'); + instance.enabled = true; + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); + t.is(instance.visible('foo'), 'foo'); + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); }); diff --git a/test/windows.js b/test/windows.js index 2f2815e..3ede386 100644 --- a/test/windows.js +++ b/test/windows.js @@ -28,36 +28,36 @@ test.beforeEach(() => { test('detect a simple term if TERM isn\'t set', t => { delete process.env.TERM; - const m = importFresh('..'); - t.is(m.blue('foo'), '\u001B[94mfoo\u001B[39m'); + const chalk = importFresh('..'); + t.is(chalk.blue('foo'), '\u001B[94mfoo\u001B[39m'); }); test('replace blue foreground color in cmd.exe', t => { process.env.TERM = 'dumb'; - const m = importFresh('..'); - t.is(m.blue('foo'), '\u001B[94mfoo\u001B[39m'); + const chalk = importFresh('..'); + t.is(chalk.blue('foo'), '\u001B[94mfoo\u001B[39m'); }); test('don\'t replace blue foreground color in xterm based terminals', t => { process.env.TERM = 'xterm-256color'; - const m = importFresh('..'); - t.is(m.blue('foo'), '\u001B[34mfoo\u001B[39m'); + const chalk = importFresh('..'); + t.is(chalk.blue('foo'), '\u001B[34mfoo\u001B[39m'); }); test('don\'t apply dimmed styling on gray strings, see https://github.com/chalk/chalk/issues/58', t => { process.env.TERM = 'dumb'; - const m = importFresh('..'); - t.is(m.gray.dim('foo'), '\u001B[90mfoo\u001B[22m\u001B[39m'); + const chalk = importFresh('..'); + t.is(chalk.gray.dim('foo'), '\u001B[90mfoo\u001B[22m\u001B[39m'); }); test('apply dimmed styling on xterm compatible terminals', t => { process.env.TERM = 'xterm'; - const m = importFresh('..'); - t.is(m.gray.dim('foo'), '\u001B[90m\u001B[2mfoo\u001B[22m\u001B[39m'); + const chalk = importFresh('..'); + t.is(chalk.gray.dim('foo'), '\u001B[90m\u001B[2mfoo\u001B[22m\u001B[39m'); }); test('apply dimmed styling on strings of other colors', t => { process.env.TERM = 'dumb'; - const m = importFresh('..'); - t.is(m.blue.dim('foo'), '\u001B[94m\u001B[2mfoo\u001B[22m\u001B[39m'); + const chalk = importFresh('..'); + t.is(chalk.blue.dim('foo'), '\u001B[94m\u001B[2mfoo\u001B[22m\u001B[39m'); }); From 2a678789b1ecdb6ad2ad0c918a7ee70df7abb464 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 18 Sep 2018 15:33:20 +0700 Subject: [PATCH 042/170] Validate the `level` option Fixes #248 --- index.js | 6 ++++-- test/constructor.js | 12 ++++++++++++ 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/index.js b/index.js index 333c836..917c45f 100644 --- a/index.js +++ b/index.js @@ -15,8 +15,10 @@ const skipModels = new Set(['gray']); const styles = Object.create(null); -function applyOptions(obj, options) { - options = 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 scLevel = stdoutColor ? stdoutColor.level : 0; diff --git a/test/constructor.js b/test/constructor.js index 510f1a0..bda0137 100644 --- a/test/constructor.js +++ b/test/constructor.js @@ -20,3 +20,15 @@ test('create an isolated context where colors can be disabled (by enabled flag)' instance.enabled = true; t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); }); + +test('the `level` option should be a number from 0 to 3', t => { + /* eslint-disable no-new */ + t.throws(() => { + new chalk.constructor({level: 10}); + }, /should be an integer from 0 to 3/); + + t.throws(() => { + new chalk.constructor({level: -1}); + }, /should be an integer from 0 to 3/); + /* eslint-enable no-new */ +}); From 6a14c58e54809f15889830eddee1ea8a6acb1b2e Mon Sep 17 00:00:00 2001 From: Chris Harwood Date: Tue, 18 Sep 2018 04:48:47 -0400 Subject: [PATCH 043/170] Add failing test for #234 (#235) --- test/_supports-color.js | 22 +++++++++++----------- test/no-color-support.js | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 test/no-color-support.js diff --git a/test/_supports-color.js b/test/_supports-color.js index cfca6cc..490c323 100644 --- a/test/_supports-color.js +++ b/test/_supports-color.js @@ -1,15 +1,15 @@ 'use strict'; const resolveFrom = require('resolve-from'); -module.exports = dir => { - require.cache[resolveFrom(dir, 'supports-color')] = { - exports: { - stdout: { - level: 3, - hasBasic: true, - has256: true, - has16m: true - } - } - }; +const DEFAULT = { + stdout: { + level: 3, + hasBasic: true, + has256: true, + has16m: true + } +}; + +module.exports = (dir, override) => { + require.cache[resolveFrom(dir, 'supports-color')] = {exports: override || DEFAULT}; }; diff --git a/test/no-color-support.js b/test/no-color-support.js new file mode 100644 index 0000000..90d934d --- /dev/null +++ b/test/no-color-support.js @@ -0,0 +1,16 @@ +import test from 'ava'; + +// Spoof supports-color +require('./_supports-color')(__dirname, { + level: 0, + hasBasic: false, + has256: false, + has16m: false +}); + +const chalk = require('..'); + +test.failing('colors can be forced by using chalk.enabled', t => { + chalk.enabled = true; + t.is(chalk.green('hello'), '\u001B[32mhello\u001B[39m'); +}); From b9c95dbfd27371a428e642dd3b8d0f2159d642ac Mon Sep 17 00:00:00 2001 From: Paul Melnikow Date: Tue, 18 Sep 2018 15:20:53 -0400 Subject: [PATCH 044/170] Add type definitions badge (#286) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index e16f679..99556d8 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ > Terminal string styling done right -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) [![Mentioned in Awesome Node.js](https://awesome.re/mentioned-badge.svg)](https://github.com/sindresorhus/awesome-nodejs) +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript- and Flow-ready](https://img.shields.io/npm/types/chalk.svg) ### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0) From 8a090d788513a96c4c5e5cc74017c8006d1ba236 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sun, 30 Sep 2018 01:41:55 +0700 Subject: [PATCH 045/170] Add Tidelift mention in the readme --- readme.md | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 99556d8..2454dd2 100644 --- a/readme.md +++ b/readme.md @@ -11,10 +11,22 @@ [![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript- and Flow-ready](https://img.shields.io/npm/types/chalk.svg) -### [See what's new in Chalk 2](https://github.com/chalk/chalk/releases/tag/v2.0.0) - +--- + +
+ + Get professional support for Chalk with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
+ +--- + ## Highlights From 1542c85f1b31867f387a322be7396ce069adfe26 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 13 Oct 2018 12:32:09 +0700 Subject: [PATCH 046/170] Replace RawGit URL Fixes #305 --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 2454dd2..53a7e7e 100644 --- a/readme.md +++ b/readme.md @@ -11,7 +11,7 @@ [![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript- and Flow-ready](https://img.shields.io/npm/types/chalk.svg) - + --- From b827cb081792c04212284c93bb07bd5c758bab05 Mon Sep 17 00:00:00 2001 From: Atif Aziz Date: Sat, 27 Oct 2018 16:09:54 +0200 Subject: [PATCH 047/170] Fix ignore chars regex flags in rainbow example (#306) Use global matches rather than stopping after the first match. --- examples/rainbow.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/rainbow.js b/examples/rainbow.js index a4a2e0a..fc086fa 100644 --- a/examples/rainbow.js +++ b/examples/rainbow.js @@ -1,7 +1,7 @@ 'use strict'; const chalk = require('..'); -const ignoreChars = /[^!-~]/; +const ignoreChars = /[^!-~]/g; function rainbow(str, offset) { if (!str || str.length === 0) { From 70bb378e8e99385acfff28141b08249c5985b351 Mon Sep 17 00:00:00 2001 From: Timothy Yung Date: Thu, 29 Nov 2018 20:34:09 -0800 Subject: [PATCH 048/170] Strict mode in Flow definition (#309) --- index.js.flow | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js.flow b/index.js.flow index 872a156..622caaa 100644 --- a/index.js.flow +++ b/index.js.flow @@ -1,4 +1,4 @@ -// @flow +// @flow strict type TemplateStringsArray = $ReadOnlyArray; From f590a65489d8fc36c21a2f5f8d82d91d438ab05d Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 25 Dec 2018 14:45:17 +0100 Subject: [PATCH 049/170] Add security section --- readme.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/readme.md b/readme.md index 53a7e7e..604fc4e 100644 --- a/readme.md +++ b/readme.md @@ -297,6 +297,11 @@ 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 From 90c7a92ff126233a6e0350fdc163b5045935b09c Mon Sep 17 00:00:00 2001 From: George Gkasdrogkas Date: Wed, 26 Dec 2018 03:06:00 +0200 Subject: [PATCH 050/170] Add docs comments and tests for TypeScript definitions (#299) Fixes #293 --- index.d.ts | 282 +++++++++++++++++++++++++++ index.js | 2 +- index.test-d.ts | 139 +++++++++++++ package.json | 11 +- readme.md | 18 +- templates.js | 2 +- types/tsconfig.json => tsconfig.json | 0 types/index.d.ts | 97 --------- types/test.ts | 56 ------ 9 files changed, 438 insertions(+), 169 deletions(-) create mode 100644 index.d.ts create mode 100644 index.test-d.ts rename types/tsconfig.json => tsconfig.json (100%) delete mode 100644 types/index.d.ts delete mode 100644 types/test.ts diff --git a/index.d.ts b/index.d.ts new file mode 100644 index 0000000..f08f46d --- /dev/null +++ b/index.d.ts @@ -0,0 +1,282 @@ +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; + + /** + * Return a new Chalk instance. + */ + (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: string[]): string; + + (text: TemplateStringsArray, ...placeholders: string[]): 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 917c45f..b77dfbb 100644 --- a/index.js +++ b/index.js @@ -199,7 +199,7 @@ function applyStyle(...args) { } function chalkTag(chalk, ...strings) { - const firstString = strings[0]; + const [firstString] = strings; if (!Array.isArray(firstString)) { // If chalk() was called by itself or with a string, diff --git a/index.test-d.ts b/index.test-d.ts new file mode 100644 index 0000000..a91003b --- /dev/null +++ b/index.test-d.ts @@ -0,0 +1,139 @@ +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(chalk.constructor()); +expectType(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}}`); + +// -- 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 32c6f73..44a2ba3 100644 --- a/package.json +++ b/package.json @@ -8,13 +8,13 @@ "node": ">=6" }, "scripts": { - "test": "xo && nyc ava && tsc --project types && flow --max-warnings=0", + "test": "xo && nyc ava && tsd-check && flow --max-warnings=0", "bench": "matcha benchmark.js" }, "files": [ "index.js", "templates.js", - "types/index.d.ts", + "index.d.ts", "index.js.flow" ], "keywords": [ @@ -54,10 +54,11 @@ "matcha": "^0.7.0", "nyc": "^13.0.1", "resolve-from": "^4.0.0", - "typescript": "^3.0.3", - "xo": "^0.23.0" + "tsd-check": "^0.2.1", + "typescript": "^2.5.3", + "xo": "0.20.3" }, - "types": "types/index.d.ts", + "types": "index.d.ts", "xo": { "ignores": [ "test/_flow.js" diff --git a/readme.md b/readme.md index 604fc4e..7134b2b 100644 --- a/readme.md +++ b/readme.md @@ -178,15 +178,15 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= ### Modifiers -- `reset` -- `bold` -- `dim` -- `italic` *(Not widely supported)* -- `underline` -- `inverse` -- `hidden` -- `strikethrough` *(Not widely supported)* -- `visible` (Text is emitted only if enabled) +- `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. ### Colors diff --git a/templates.js b/templates.js index 8ce33fe..1f6c035 100644 --- a/templates.js +++ b/templates.js @@ -50,7 +50,7 @@ function parseStyle(style) { let matches; while ((matches = STYLE_REGEX.exec(style)) !== null) { - const name = matches[1]; + const name = matches[1]; // eslint-disable-line prefer-destructuring if (matches[2]) { const args = parseArguments(name, matches[2]); diff --git a/types/tsconfig.json b/tsconfig.json similarity index 100% rename from types/tsconfig.json rename to tsconfig.json diff --git a/types/index.d.ts b/types/index.d.ts deleted file mode 100644 index b4e4dc5..0000000 --- a/types/index.d.ts +++ /dev/null @@ -1,97 +0,0 @@ -// 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: string[]): string; - (text: TemplateStringsArray, ...placeholders: string[]): 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 deleted file mode 100644 index cedb39a..0000000 --- a/types/test.ts +++ /dev/null @@ -1,56 +0,0 @@ -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`; - -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'); From 4726b1bfda3046ed02387ed587c8e9e8be1728b5 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 26 Dec 2018 02:18:40 +0100 Subject: [PATCH 051/170] Update dependencies and meta tweaks --- .flowconfig | 1 + .travis.yml | 1 + package.json | 18 +++++++++--------- tsconfig.json | 4 +--- 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/.flowconfig b/.flowconfig index 2318f0d..48ee960 100644 --- a/.flowconfig +++ b/.flowconfig @@ -3,3 +3,4 @@ [options] suppress_comment= \\(.\\|\n\\)*\\$ExpectError +include_warnings=true diff --git a/.travis.yml b/.travis.yml index 60e38d8..c89aee6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: + - '10' - '8' - '6' after_success: diff --git a/package.json b/package.json index 44a2ba3..35fb7d0 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "node": ">=6" }, "scripts": { - "test": "xo && nyc ava && tsd-check && flow --max-warnings=0", + "test": "xo && nyc ava && tsd-check && flow", "bench": "matcha benchmark.js" }, "files": [ @@ -43,20 +43,20 @@ "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^5.5.0" + "supports-color": "^6.0.0" }, "devDependencies": { - "ava": "^0.25.0", + "@sindresorhus/tsconfig": "^0.1.1", + "ava": "^1.0.1", "coveralls": "^3.0.2", "execa": "^1.0.0", - "flow-bin": "^0.81.0", - "import-fresh": "^2.0.0", + "flow-bin": "^0.89.0", + "import-fresh": "^3.0.0", "matcha": "^0.7.0", - "nyc": "^13.0.1", + "nyc": "^13.1.0", "resolve-from": "^4.0.0", - "tsd-check": "^0.2.1", - "typescript": "^2.5.3", - "xo": "0.20.3" + "tsd-check": "^0.3.0", + "xo": "^0.23.0" }, "types": "index.d.ts", "xo": { diff --git a/tsconfig.json b/tsconfig.json index b73840f..3d73ee9 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,8 +1,6 @@ { + "extends": "@sindresorhus/tsconfig", "compilerOptions": { - "module": "commonjs", - "target": "es6", - "noImplicitAny": true, "noEmit": true, "allowJs": true } From cf6615647a55d5f0b8ff1c36f06faee6b22e3221 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 26 Dec 2018 02:25:23 +0100 Subject: [PATCH 052/170] Type definition improvements --- index.d.ts | 13 ++++++------- index.js.flow | 22 +++++++++++----------- 2 files changed, 17 insertions(+), 18 deletions(-) diff --git a/index.d.ts b/index.d.ts index f08f46d..f2a1149 100644 --- a/index.d.ts +++ b/index.d.ts @@ -29,9 +29,8 @@ export interface Options { enabled?: boolean; /** - * Specify the color support for Chalk. By default, - * color support is automatically detected based on - * the environment. + * Specify the color support for Chalk. + * By default, color support is automatically detected based on the environment. */ level?: Level; } @@ -91,9 +90,8 @@ export interface Chalk { enabled: boolean; /** - * The color support for Chalk. By default, color - * support is automatically detected based on the - * environment. + * The color support for Chalk. + * By default, color support is automatically detected based on the environment. */ level: Level; @@ -230,7 +228,8 @@ export interface Chalk { readonly strikethrough: this; /** - * Modifier: Prints the text only when Chalk is enabled. Can be useful for things that are purely cosmetic. + * Modifier: Prints the text only when Chalk is enabled. + * Can be useful for things that are purely cosmetic. */ readonly visible: this; diff --git a/index.js.flow b/index.js.flow index 622caaa..aac750e 100644 --- a/index.js.flow +++ b/index.js.flow @@ -9,7 +9,7 @@ export type Level = $Values<{ TrueColor: 3 }>; -export type ChalkOptions = {| +export type Options = {| enabled?: boolean, level?: Level |}; @@ -24,19 +24,19 @@ export type ColorSupport = {| export interface Chalk { (...text: string[]): string, (text: TemplateStringsArray, ...placeholders: string[]): string, - constructor(options?: ChalkOptions): Chalk, + constructor(options?: Options): Chalk, enabled: boolean, level: Level, - 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, + 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, bgHex(color: string): Chalk, bgKeyword(color: string): 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, + 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, hex(color: string): Chalk, keyword(color: string): Chalk, @@ -85,7 +85,7 @@ export interface Chalk { +bgBlueBright: Chalk, +bgMagentaBright: Chalk, +bgCyanBright: Chalk, - +bgWhiteBrigh: Chalk, + +bgWhiteBright: Chalk, supportsColor: ColorSupport }; From 1284415013c24c5c51c1ee339bf85c7c8b7cbd7c Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 26 Dec 2018 02:27:57 +0100 Subject: [PATCH 053/170] Enforce `chalk.constructor` to be called with `new` in TypeScript --- index.d.ts | 5 ----- index.test-d.ts | 2 -- 2 files changed, 7 deletions(-) diff --git a/index.d.ts b/index.d.ts index f2a1149..b42e4c0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -40,11 +40,6 @@ export interface Constructor { * Return a new Chalk instance. */ new (options?: Options): Chalk; - - /** - * Return a new Chalk instance. - */ - (options?: Options): Chalk; } /** diff --git a/index.test-d.ts b/index.test-d.ts index a91003b..6cda4da 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -17,8 +17,6 @@ expectType(chalk.supportsColor.has16m); // - Chalk - // -- Constructor -- -expectType(chalk.constructor()); -expectType(chalk.constructor()); expectType(new chalk.constructor({level: 1})); // -- Properties -- From 076f0c9eb6d6575db745f2753832918eaefe627d Mon Sep 17 00:00:00 2001 From: Chris Harwood Date: Tue, 25 Dec 2018 20:29:32 -0500 Subject: [PATCH 054/170] Add extra level/enabled property info in the readme (#308) --- readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/readme.md b/readme.md index 7134b2b..d8ca070 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. +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. 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. +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. If you need to change this in a reusable module, create a new instance: From 587a5fbcbb61f83270fc102da47615b8ff64351c Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 26 Dec 2018 02:37:03 +0100 Subject: [PATCH 055/170] Code style tweaks --- index.js | 50 +++++++++++++++++++------------------------------- templates.js | 40 ++++++++++++++++++++++------------------ 2 files changed, 41 insertions(+), 49 deletions(-) diff --git a/index.js b/index.js index b77dfbb..73598be 100644 --- a/index.js +++ b/index.js @@ -1,8 +1,7 @@ 'use strict'; const escapeStringRegexp = require('escape-string-regexp'); const ansiStyles = require('ansi-styles'); -const stdoutColor = require('supports-color').stdout; - +const {stdout: stdoutColor} = require('supports-color'); const template = require('./templates.js'); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -15,15 +14,15 @@ const skipModels = new Set(['gray']); const styles = Object.create(null); -function applyOptions(obj, options = {}) { +function applyOptions(object, 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 scLevel = stdoutColor ? stdoutColor.level : 0; - obj.level = options.level === undefined ? scLevel : options.level; - obj.enabled = 'enabled' in options ? options.enabled : obj.level > 0; + const colorLevel = stdoutColor ? stdoutColor.level : 0; + object.level = options.level === undefined ? colorLevel : options.level; + object.enabled = 'enabled' in options ? options.enabled : object.level > 0; } function Chalk(options) { @@ -33,7 +32,7 @@ function Chalk(options) { const chalk = {}; applyOptions(chalk, options); - chalk.template = (...args) => chalkTag(...[chalk.template].concat(args)); + chalk.template = (...args) => chalkTag(chalk.template, ...args); Object.setPrototypeOf(chalk, Chalk.prototype); Object.setPrototypeOf(chalk.template, chalk); @@ -57,7 +56,7 @@ for (const key of Object.keys(ansiStyles)) { styles[key] = { get() { const codes = ansiStyles[key]; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, key); + return build.call(this, [...(this._styles || []), codes], this._empty, key); } }; } @@ -84,7 +83,7 @@ for (const model of Object.keys(ansiStyles.color.ansi)) { close: ansiStyles.color.close, closeRe: ansiStyles.color.closeRe }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + return build.call(this, [...(this._styles || []), codes], this._empty, model); }; } }; @@ -107,7 +106,7 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { close: ansiStyles.bgColor.close, closeRe: ansiStyles.bgColor.closeRe }; - return build.call(this, this._styles ? this._styles.concat(codes) : [codes], this._empty, model); + return build.call(this, [...(this._styles || []), codes], this._empty, model); }; } }; @@ -153,23 +152,10 @@ function build(_styles, _empty, key) { } function applyStyle(...args) { - // Support varags, but simply cast to string in case there's only one arg - const argsLen = args.length; - let str = String(args[0]); + let string = args.join(' '); - 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 || !str) { - return this._empty ? '' : str; + if (!this.enabled || this.level <= 0 || !string) { + return this._empty ? '' : string; } // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, @@ -184,18 +170,18 @@ 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'. - str = code.open + str.replace(code.closeRe, code.open) + code.close; + string = code.open + string.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 - str = str.replace(/\r?\n/g, `${code.close}$&${code.open}`); + string = string.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 str; + return string; } function chalkTag(chalk, ...strings) { @@ -211,8 +197,10 @@ 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, '\\$&')); - parts.push(String(firstString.raw[i])); + parts.push( + String(args[i - 1]).replace(/[{}\\]/g, '\\$&'), + String(firstString.raw[i]) + ); } return template(chalk, parts.join('')); diff --git a/templates.js b/templates.js index 1f6c035..bbc614d 100644 --- a/templates.js +++ b/templates.js @@ -31,10 +31,11 @@ function parseArguments(name, args) { let matches; for (const chunk of chunks) { - if (!isNaN(chunk)) { - results.push(Number(chunk)); + const number = Number(chunk); + if (!Number.isNaN(number)) { + results.push(number); } else if ((matches = chunk.match(STRING_REGEX))) { - results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, chr) => escape ? unescape(escape) : chr)); + results.push(matches[2].replace(ESCAPE_REGEX, (m, escape, character) => escape ? unescape(escape) : character)); } else { throw new Error(`Invalid Chalk template style argument: ${chunk} (in style '${name}')`); } @@ -73,17 +74,20 @@ 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])) { - if (!(styleName in current)) { - throw new Error(`Unknown Chalk style: ${styleName}`); - } + if (!Array.isArray(enabled[styleName])) { + continue; + } - if (enabled[styleName].length > 0) { - current = current[styleName](...enabled[styleName]); - } else { - current = current[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]; } } @@ -96,13 +100,13 @@ module.exports = (chalk, tmp) => { let chunk = []; // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeChar, inverse, style, close, chr) => { - if (escapeChar) { - chunk.push(unescape(escapeChar)); + tmp.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { + if (escapeCharacter) { + chunk.push(unescape(escapeCharacter)); } else if (style) { - const str = chunk.join(''); + const string = chunk.join(''); chunk = []; - chunks.push(styles.length === 0 ? str : buildStyle(chalk, styles)(str)); + chunks.push(styles.length === 0 ? string : buildStyle(chalk, styles)(string)); styles.push({inverse, styles: parseStyle(style)}); } else if (close) { if (styles.length === 0) { @@ -113,7 +117,7 @@ module.exports = (chalk, tmp) => { chunk = []; styles.pop(); } else { - chunk.push(chr); + chunk.push(character); } }); From 7f6e5630b0097774d6961e9c0921697a300fbd0f Mon Sep 17 00:00:00 2001 From: Jonathan Van Buren Date: Fri, 28 Dec 2018 19:13:56 +0800 Subject: [PATCH 056/170] Change tagged template literal argument type to accept `unknown` instead of just `string` (#316) --- index.d.ts | 4 ++-- index.js.flow | 2 +- index.test-d.ts | 1 + test/_flow.js | 8 -------- 4 files changed, 4 insertions(+), 11 deletions(-) diff --git a/index.d.ts b/index.d.ts index b42e4c0..b2c7213 100644 --- a/index.d.ts +++ b/index.d.ts @@ -68,9 +68,9 @@ export interface ColorSupport { } export interface Chalk { - (...text: string[]): string; + (...text: unknown[]): string; - (text: TemplateStringsArray, ...placeholders: string[]): string; + (text: TemplateStringsArray, ...placeholders: unknown[]): string; /** * Return a new Chalk instance. diff --git a/index.js.flow b/index.js.flow index aac750e..1a3099d 100644 --- a/index.js.flow +++ b/index.js.flow @@ -23,7 +23,7 @@ export type ColorSupport = {| export interface Chalk { (...text: string[]): string, - (text: TemplateStringsArray, ...placeholders: string[]): string, + (text: TemplateStringsArray, ...placeholders: mixed[]): string, constructor(options?: Options): Chalk, enabled: boolean, level: Level, diff --git a/index.test-d.ts b/index.test-d.ts index 6cda4da..5920526 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -27,6 +27,7 @@ expectType(chalk.level); expectType(chalk``); const name = 'John'; expectType(chalk`Hello {bold.red ${name}}`); +expectType(chalk`Works with numbers {bold.red ${1}}`); // -- Color methods -- expectType(chalk.hex('#DEADED')); diff --git a/test/_flow.js b/test/_flow.js index 2cf3cf2..ac76e85 100644 --- a/test/_flow.js +++ b/test/_flow.js @@ -9,10 +9,6 @@ chalk.constructor({level: 1}); new chalk.constructor({enabled: 'true'}); new chalk.constructor({enabled: true}); -// $ExpectError (Can't pass in null) -chalk.underline(null); -chalk.underline('foo'); - // $ExpectError (Can't have typo in chalk method) chalk.rd('foo'); chalk.red('foo'); @@ -29,10 +25,6 @@ chalk.red.bgBlue.underline('foo'); const badCtx = chalk.constructor({level: 4}); const ctx = chalk.constructor({level: 3}); -// $ExpectError (Can't pass in null) -ctx(null); -ctx('foo'); - // $ExpectError (Can't have typo in method name) ctx.gry('foo'); ctx.grey('foo'); From 60959e05cfe7086a38927eae5b5e04c459ce4182 Mon Sep 17 00:00:00 2001 From: Richie Bendall Date: Fri, 1 Mar 2019 19:14:20 +1300 Subject: [PATCH 057/170] Update depended packages count --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index d8ca070..1a511d4 100644 --- a/readme.md +++ b/readme.md @@ -38,7 +38,7 @@ - Doesn't extend `String.prototype` - Clean and focused - Actively maintained -- [Used by ~30,000 packages](https://www.npmjs.com/browse/depended/chalk) as of August 6, 2018 +- [Used by ~40,000 packages](https://www.npmjs.com/browse/depended/chalk) as of March 1, 2019 ## Install From de2f4cd6063b40834096c7dc874562006bb1283c Mon Sep 17 00:00:00 2001 From: Tom Sherman Date: Tue, 12 Mar 2019 12:53:03 +0000 Subject: [PATCH 058/170] Deprecate `chalk.constructor()` in favor of `new chalk.Instance()` (#322) --- index.d.ts | 4 ++-- index.js | 39 +++++++++++++++++++++++---------------- index.js.flow | 2 +- index.test-d.ts | 4 ++-- readme.md | 6 +++--- test/_flow.js | 14 +++++++------- test/chalk.js | 14 +++++++------- test/constructor.js | 33 +++++++-------------------------- test/instance.js | 34 ++++++++++++++++++++++++++++++++++ test/template-literal.js | 40 ++++++++++++++++++++-------------------- test/visible.js | 8 ++++---- 11 files changed, 110 insertions(+), 88 deletions(-) create mode 100644 test/instance.js diff --git a/index.d.ts b/index.d.ts index b2c7213..189e1a3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -35,7 +35,7 @@ export interface Options { level?: Level; } -export interface Constructor { +export interface Instance { /** * Return a new Chalk instance. */ @@ -75,7 +75,7 @@ export interface Chalk { /** * Return a new Chalk instance. */ - constructor: Constructor; + Instance: Instance; /** * Enable or disable Chalk. diff --git a/index.js b/index.js index 73598be..d04ce95 100644 --- a/index.js +++ b/index.js @@ -25,24 +25,31 @@ function applyOptions(object, options = {}) { object.enabled = 'enabled' in options ? options.enabled : object.level > 0; } -function Chalk(options) { - // We check for this.template here since calling `chalk.constructor()` - // by itself will have a `this` of a previously constructed chalk object - if (!this || !(this instanceof Chalk) || this.template) { - const chalk = {}; - applyOptions(chalk, options); - - chalk.template = (...args) => chalkTag(chalk.template, ...args); - - Object.setPrototypeOf(chalk, Chalk.prototype); - Object.setPrototypeOf(chalk.template, chalk); - - chalk.template.constructor = Chalk; - - return chalk.template; +class ChalkClass { + constructor(options) { + return chalkFactory(options); } +} - applyOptions(this, options); +function chalkFactory(options) { + const chalk = {}; + applyOptions(chalk, options); + + chalk.template = (...args) => chalkTag(chalk.template, ...args); + + Object.setPrototypeOf(chalk, Chalk.prototype); + Object.setPrototypeOf(chalk.template, chalk); + + chalk.template.constructor = () => { + throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); + }; + chalk.template.Instance = ChalkClass; + + return chalk.template; +} + +function Chalk(options) { + return chalkFactory(options); } // Use bright blue on Windows as the normal blue color is illegible diff --git a/index.js.flow b/index.js.flow index 1a3099d..f7e4abc 100644 --- a/index.js.flow +++ b/index.js.flow @@ -24,7 +24,7 @@ export type ColorSupport = {| export interface Chalk { (...text: string[]): string, (text: TemplateStringsArray, ...placeholders: mixed[]): string, - constructor(options?: Options): Chalk, + Instance(options?: Options): Chalk, enabled: boolean, level: Level, rgb(red: number, green: number, blue: number): Chalk, diff --git a/index.test-d.ts b/index.test-d.ts index 5920526..0b26e9c 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -16,8 +16,8 @@ expectType(chalk.supportsColor.has256); expectType(chalk.supportsColor.has16m); // - Chalk - -// -- Constructor -- -expectType(new chalk.constructor({level: 1})); +// -- Instance -- +expectType(new chalk.Instance({level: 1})); // -- Properties -- expectType(chalk.enabled); diff --git a/readme.md b/readme.md index 1a511d4..1e3b9bb 100644 --- a/readme.md +++ b/readme.md @@ -140,12 +140,12 @@ Multiple arguments will be separated by space. 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. -Chalk is enabled by default unless explicitly disabled via the constructor or `chalk.level` is `0`. +Chalk is enabled by default unless explicitly disabled via `new chalk.Instance()` or `chalk.level` is `0`. If you need to change this in a reusable module, create a new instance: ```js -const ctx = new chalk.constructor({enabled: false}); +const ctx = new chalk.Instance({enabled: false}); ``` ### chalk.level @@ -155,7 +155,7 @@ Color support is automatically detected, but you can override it by setting the If you need to change this in a reusable module, create a new instance: ```js -const ctx = new chalk.constructor({level: 0}); +const ctx = new chalk.Instance({level: 0}); ``` Levels are as follows: diff --git a/test/_flow.js b/test/_flow.js index ac76e85..dbb6dd0 100644 --- a/test/_flow.js +++ b/test/_flow.js @@ -2,12 +2,12 @@ import chalk from '..'; // $ExpectError (Can't have typo in option name) -chalk.constructor({levl: 1}); -chalk.constructor({level: 1}); +new chalk.Instance({levl: 1}); +new chalk.Instance({level: 1}); // $ExpectError (Option must have proper type) -new chalk.constructor({enabled: 'true'}); -new chalk.constructor({enabled: true}); +new chalk.Instance({enabled: 'true'}); +new chalk.Instance({enabled: true}); // $ExpectError (Can't have typo in chalk method) chalk.rd('foo'); @@ -22,8 +22,8 @@ chalk.red.bgBlu.underline('foo'); chalk.red.bgBlue.underline('foo'); // $ExpectError (Level must be 0, 1, 2, or 3) -const badCtx = chalk.constructor({level: 4}); -const ctx = chalk.constructor({level: 3}); +const badCtx = chalk.Instance({level: 4}); +const ctx = chalk.Instance({level: 3}); // $ExpectError (Can't have typo in method name) ctx.gry('foo'); @@ -41,7 +41,7 @@ chalk.enabled = true; chalk.level = 10; chalk.level = 1; -const chalkInstance = new chalk.constructor(); +const chalkInstance = new chalk.Instance(); // $ExpectError (Can't have typo in method name) chalkInstance.blu('foo'); diff --git a/test/chalk.js b/test/chalk.js index a53b6f5..240f0f9 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -83,17 +83,17 @@ test('line breaks should open and close colors', t => { }); test('properly convert RGB to 16 colors on basic color terminals', t => { - t.is(new chalk.constructor({level: 1}).hex('#FF0000')('hello'), '\u001B[91mhello\u001B[39m'); - t.is(new chalk.constructor({level: 1}).bgHex('#FF0000')('hello'), '\u001B[101mhello\u001B[49m'); + t.is(new chalk.Instance({level: 1}).hex('#FF0000')('hello'), '\u001B[91mhello\u001B[39m'); + t.is(new chalk.Instance({level: 1}).bgHex('#FF0000')('hello'), '\u001B[101mhello\u001B[49m'); }); test('properly convert RGB to 256 colors on basic color terminals', t => { - t.is(new chalk.constructor({level: 2}).hex('#FF0000')('hello'), '\u001B[38;5;196mhello\u001B[39m'); - t.is(new chalk.constructor({level: 2}).bgHex('#FF0000')('hello'), '\u001B[48;5;196mhello\u001B[49m'); - t.is(new chalk.constructor({level: 3}).bgHex('#FF0000')('hello'), '\u001B[48;2;255;0;0mhello\u001B[49m'); + t.is(new chalk.Instance({level: 2}).hex('#FF0000')('hello'), '\u001B[38;5;196mhello\u001B[39m'); + t.is(new chalk.Instance({level: 2}).bgHex('#FF0000')('hello'), '\u001B[48;5;196mhello\u001B[49m'); + t.is(new chalk.Instance({level: 3}).bgHex('#FF0000')('hello'), '\u001B[48;2;255;0;0mhello\u001B[49m'); }); test('don\'t emit RGB codes if level is 0', t => { - t.is(new chalk.constructor({level: 0}).hex('#FF0000')('hello'), 'hello'); - t.is(new chalk.constructor({level: 0}).bgHex('#FF0000')('hello'), 'hello'); + t.is(new chalk.Instance({level: 0}).hex('#FF0000')('hello'), 'hello'); + t.is(new chalk.Instance({level: 0}).bgHex('#FF0000')('hello'), 'hello'); }); diff --git a/test/constructor.js b/test/constructor.js index bda0137..188001a 100644 --- a/test/constructor.js +++ b/test/constructor.js @@ -1,34 +1,15 @@ import test from 'ava'; -// Spoof supports-color -require('./_supports-color')(__dirname); - const chalk = require('..'); -test('create an isolated context where colors can be disabled (by level)', t => { - const instance = new chalk.constructor({level: 0, enabled: true}); - t.is(instance.red('foo'), 'foo'); - t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); - instance.level = 2; - t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); -}); +test('Chalk.constructor should throw an expected error', t => { + const expectedError = t.throws(() => { + chalk.constructor(); + }); -test('create an isolated context where colors can be disabled (by enabled flag)', t => { - const instance = new chalk.constructor({enabled: false}); - t.is(instance.red('foo'), 'foo'); - t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); - instance.enabled = true; - t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); -}); - -test('the `level` option should be a number from 0 to 3', t => { - /* eslint-disable no-new */ - t.throws(() => { - new chalk.constructor({level: 10}); - }, /should be an integer from 0 to 3/); + t.is(expectedError.message, '`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); t.throws(() => { - new chalk.constructor({level: -1}); - }, /should be an integer from 0 to 3/); - /* eslint-enable no-new */ + new chalk.constructor(); // eslint-disable-line no-new + }); }); diff --git a/test/instance.js b/test/instance.js new file mode 100644 index 0000000..e34bea7 --- /dev/null +++ b/test/instance.js @@ -0,0 +1,34 @@ +import test from 'ava'; + +// Spoof supports-color +require('./_supports-color')(__dirname); + +const chalk = require('..'); + +test('create an isolated context where colors can be disabled (by level)', t => { + const instance = new chalk.Instance({level: 0, enabled: true}); + t.is(instance.red('foo'), 'foo'); + t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); + instance.level = 2; + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); +}); + +test('create an isolated context where colors can be disabled (by enabled flag)', t => { + const instance = new chalk.Instance({enabled: false}); + t.is(instance.red('foo'), 'foo'); + t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); + instance.enabled = true; + t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); +}); + +test('the `level` option should be a number from 0 to 3', t => { + /* eslint-disable no-new */ + t.throws(() => { + new chalk.Instance({level: 10}); + }, /should be an integer from 0 to 3/); + + t.throws(() => { + new chalk.Instance({level: -1}); + }, /should be an integer from 0 to 3/); + /* eslint-enable no-new */ +}); diff --git a/test/template-literal.js b/test/template-literal.js index 34588d2..1f388c8 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -7,23 +7,23 @@ require('./_supports-color')(__dirname); const chalk = require('..'); test('return an empty string for an empty literal', t => { - const instance = chalk.constructor(); + const instance = new chalk.Instance(); t.is(instance``, ''); }); test('return a regular string for a literal with no templates', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`hello`, 'hello'); }); test('correctly perform template parsing', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`{bold Hello, {cyan World!} This is a} test. {green Woo!}`, instance.bold('Hello,', instance.cyan('World!'), 'This is a') + ' test. ' + instance.green('Woo!')); }); test('correctly perform template substitutions', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); const name = 'Sindre'; const exclamation = 'Neat'; t.is(instance`{bold Hello, {cyan.inverse ${name}!} This is a} test. {green ${exclamation}!}`, @@ -31,7 +31,7 @@ test('correctly perform template substitutions', t => { }); test('correctly parse and evaluate color-convert functions', t => { - const instance = chalk.constructor({level: 3}); + const instance = new chalk.Instance({level: 3}); t.is(instance`{bold.rgb(144,10,178).inverse Hello, {~inverse there!}}`, '\u001B[1m\u001B[38;2;144;10;178m\u001B[7mHello, ' + '\u001B[27m\u001B[39m\u001B[22m\u001B[1m' + @@ -44,13 +44,13 @@ test('correctly parse and evaluate color-convert functions', t => { }); test('properly handle escapes', t => { - const instance = chalk.constructor({level: 3}); + const instance = new chalk.Instance({level: 3}); t.is(instance`{bold hello \{in brackets\}}`, '\u001B[1mhello {in brackets}\u001B[22m'); }); test('throw if there is an unclosed block', t => { - const instance = chalk.constructor({level: 3}); + const instance = new chalk.Instance({level: 3}); try { console.log(instance`{bold this shouldn't appear ever\}`); t.fail(); @@ -67,7 +67,7 @@ test('throw if there is an unclosed block', t => { }); test('throw if there is an invalid style', t => { - const instance = chalk.constructor({level: 3}); + const instance = new chalk.Instance({level: 3}); try { console.log(instance`{abadstylethatdoesntexist this shouldn't appear ever}`); t.fail(); @@ -77,7 +77,7 @@ test('throw if there is an invalid style', t => { }); test('properly style multiline color blocks', t => { - const instance = chalk.constructor({level: 3}); + const instance = new chalk.Instance({level: 3}); t.is( instance`{bold Hello! This is a @@ -97,49 +97,49 @@ test('properly style multiline color blocks', t => { }); test('escape interpolated values', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`Hello {bold hi}`, 'Hello hi'); t.is(instance`Hello ${'{bold hi}'}`, 'Hello {bold hi}'); }); test('allow custom colors (themes) on custom contexts', t => { - const instance = chalk.constructor({level: 3}); + const instance = new chalk.Instance({level: 3}); instance.rose = instance.hex('#F6D9D9'); t.is(instance`Hello, {rose Rose}.`, 'Hello, \u001B[38;2;246;217;217mRose\u001B[39m.'); }); test('correctly parse newline literals (bug #184)', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`Hello {red there}`, 'Hello\nthere'); }); test('correctly parse newline escapes (bug #177)', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`Hello\nthere!`, 'Hello\nthere!'); }); test('correctly parse escape in parameters (bug #177 comment 318622809)', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); const str = '\\'; t.is(instance`{blue ${str}}`, '\\'); }); test('correctly parses unicode/hex escapes', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`\u0078ylophones are fo\x78y! {magenta.inverse \u0078ylophones are fo\x78y!}`, 'xylophones are foxy! xylophones are foxy!'); }); test('correctly parses string arguments', t => { - const instance = chalk.constructor({level: 3}); + const instance = new chalk.Instance({level: 3}); t.is(instance`{keyword('black').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); t.is(instance`{keyword('blac\x6B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); t.is(instance`{keyword('blac\u006B').bold can haz cheezburger}`, '\u001B[38;2;0;0;0m\u001B[1mcan haz cheezburger\u001B[22m\u001B[39m'); }); test('throws if a bad argument is encountered', t => { - const instance = chalk.constructor({level: 3}); // Keep level at least 1 in case we optimize for disabled chalk instances + const instance = new chalk.Instance({level: 3}); // Keep level at least 1 in case we optimize for disabled chalk instances try { console.log(instance`{keyword(????) hi}`); t.fail(); @@ -149,7 +149,7 @@ test('throws if a bad argument is encountered', t => { }); test('throws if an extra unescaped } is found', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); try { console.log(instance`{red hi!}}`); t.fail(); @@ -159,12 +159,12 @@ test('throws if an extra unescaped } is found', t => { }); test('should not parse upper-case escapes', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`\N\n\T\t\X07\x07\U000A\u000A\U000a\u000a`, 'N\nT\tX07\x07U000A\u000AU000a\u000A'); }); test('should properly handle undefined template interpolated values', t => { - const instance = chalk.constructor({level: 0}); + const instance = new chalk.Instance({level: 0}); t.is(instance`hello ${undefined}`, 'hello undefined'); t.is(instance`hello ${null}`, 'hello null'); }); diff --git a/test/visible.js b/test/visible.js index 3266295..01eb087 100644 --- a/test/visible.js +++ b/test/visible.js @@ -6,25 +6,25 @@ require('./_supports-color')(__dirname); const chalk = require('..'); test('visible: normal output when enabled', t => { - const instance = new chalk.constructor({level: 3, enabled: true}); + const instance = new chalk.Instance({level: 3, enabled: true}); t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); }); test('visible: no output when disabled', t => { - const instance = new chalk.constructor({level: 3, enabled: false}); + const instance = new chalk.Instance({level: 3, enabled: false}); t.is(instance.red.visible('foo'), ''); t.is(instance.visible.red('foo'), ''); }); test('visible: no output when level is too low', t => { - const instance = new chalk.constructor({level: 0, enabled: true}); + const instance = new chalk.Instance({level: 0, enabled: true}); t.is(instance.visible.red('foo'), ''); t.is(instance.red.visible('foo'), ''); }); test('test switching back and forth between enabled and disabled', t => { - const instance = new chalk.constructor({level: 3, enabled: true}); + const instance = new chalk.Instance({level: 3, enabled: true}); t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); From 3ef170b457dd9a318f74080dbaeb935c86ed026b Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 12 Mar 2019 20:11:31 +0700 Subject: [PATCH 059/170] Require Node.js 8 --- .travis.yml | 1 - examples/rainbow.js | 37 ++++++++++++++++++++----------------- index.d.ts | 2 +- index.js | 33 +++++++++++++++++++-------------- package.json | 16 ++++++++-------- templates.js | 21 ++++++++------------- 6 files changed, 56 insertions(+), 54 deletions(-) diff --git a/.travis.yml b/.travis.yml index c89aee6..5e3bcf3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,6 +2,5 @@ language: node_js node_js: - '10' - '8' - - '6' after_success: - './node_modules/.bin/nyc report --reporter=text-lcov | ./node_modules/.bin/coveralls' diff --git a/examples/rainbow.js b/examples/rainbow.js index fc086fa..813e026 100644 --- a/examples/rainbow.js +++ b/examples/rainbow.js @@ -3,36 +3,39 @@ const chalk = require('..'); const ignoreChars = /[^!-~]/g; -function rainbow(str, offset) { - if (!str || str.length === 0) { - return str; +const delay = milliseconds => new Promise(resolve => setTimeout(resolve, milliseconds)); + +function rainbow(string, offset) { + if (!string || string.length === 0) { + return string; } - const hueStep = 360 / str.replace(ignoreChars, '').length; + const hueStep = 360 / string.replace(ignoreChars, '').length; let hue = offset % 360; - const chars = []; - for (const c of str) { - if (c.match(ignoreChars)) { - chars.push(c); + const characters = []; + for (const character of string) { + if (character.match(ignoreChars)) { + characters.push(character); } else { - chars.push(chalk.hsl(hue, 100, 50)(c)); + characters.push(chalk.hsl(hue, 100, 50)(character)); hue = (hue + hueStep) % 360; } } - return chars.join(''); + return characters.join(''); } -const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); - -async function animateString(str) { +async function animateString(string) { console.log(); for (let i = 0; i < 360 * 5; i++) { - console.log('\u001B[1F\u001B[G ', rainbow(str, i)); - await sleep(2); // eslint-disable-line no-await-in-loop + console.log('\u001B[1F\u001B[G', rainbow(string, i)); + await delay(2); // eslint-disable-line no-await-in-loop } } -console.log(); -animateString('We hope you enjoy the new version of Chalk 2! <3').then(() => console.log()); +(async () => { + console.log(); + await animateString('We hope you enjoy Chalk! <3'); + console.log(); +})(); diff --git a/index.d.ts b/index.d.ts index 189e1a3..6256ce3 100644 --- a/index.d.ts +++ b/index.d.ts @@ -271,6 +271,6 @@ export interface Chalk { * 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 }; +declare const chalk: Chalk & {supportsColor: ColorSupport}; export default chalk; diff --git a/index.js b/index.js index d04ce95..50e7591 100644 --- a/index.js +++ b/index.js @@ -7,7 +7,12 @@ const template = require('./templates.js'); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); // `supportsColor.level` → `ansiStyles.color[name]` mapping -const levelMapping = ['ansi', 'ansi', 'ansi256', 'ansi16m']; +const levelMapping = [ + 'ansi', + 'ansi', + 'ansi256', + 'ansi16m' +]; // `color-convert` models to exclude from the Chalk API due to conflicts and such const skipModels = new Set(['gray']); @@ -35,7 +40,7 @@ function chalkFactory(options) { const chalk = {}; applyOptions(chalk, options); - chalk.template = (...args) => chalkTag(chalk.template, ...args); + chalk.template = (...arguments_) => chalkTag(chalk.template, ...arguments_); Object.setPrototypeOf(chalk, Chalk.prototype); Object.setPrototypeOf(chalk.template, chalk); @@ -43,6 +48,7 @@ function chalkFactory(options) { chalk.template.constructor = () => { throw new Error('`chalk.constructor()` is deprecated. Use `new chalk.Instance()` instead.'); }; + chalk.template.Instance = ChalkClass; return chalk.template; @@ -57,13 +63,12 @@ if (isSimpleWindowsTerm) { ansiStyles.blue.open = '\u001B[94m'; } -for (const key of Object.keys(ansiStyles)) { - ansiStyles[key].closeRe = new RegExp(escapeStringRegexp(ansiStyles[key].close), 'g'); +for (const [styleName, style] of Object.entries(ansiStyles)) { + style.closeRe = new RegExp(escapeStringRegexp(style.close), 'g'); - styles[key] = { + styles[styleName] = { get() { - const codes = ansiStyles[key]; - return build.call(this, [...(this._styles || []), codes], this._empty, key); + return build.call(this, [...(this._styles || []), style], this._empty, styleName); } }; } @@ -106,8 +111,8 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { styles[bgModel] = { get() { const {level} = this; - return function (...args) { - const open = ansiStyles.bgColor[levelMapping[level]][model](...args); + return function (...arguments_) { + const open = ansiStyles.bgColor[levelMapping[level]][model](...arguments_); const codes = { open, close: ansiStyles.bgColor.close, @@ -122,7 +127,7 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { const proto = Object.defineProperties(() => {}, styles); function build(_styles, _empty, key) { - const builder = (...args) => applyStyle.call(builder, ...args); + const builder = (...arguments_) => applyStyle.call(builder, ...arguments_); builder._styles = _styles; builder._empty = _empty; @@ -158,8 +163,8 @@ function build(_styles, _empty, key) { return builder; } -function applyStyle(...args) { - let string = args.join(' '); +function applyStyle(...arguments_) { + let string = arguments_.join(' '); if (!this.enabled || this.level <= 0 || !string) { return this._empty ? '' : string; @@ -200,12 +205,12 @@ function chalkTag(chalk, ...strings) { return strings.join(' '); } - const args = strings.slice(1); + const arguments_ = strings.slice(1); const parts = [firstString.raw[0]]; for (let i = 1; i < firstString.length; i++) { parts.push( - String(args[i - 1]).replace(/[{}\\]/g, '\\$&'), + String(arguments_[i - 1]).replace(/[{}\\]/g, '\\$&'), String(firstString.raw[i]) ); } diff --git a/package.json b/package.json index 35fb7d0..bbc1634 100644 --- a/package.json +++ b/package.json @@ -5,7 +5,7 @@ "license": "MIT", "repository": "chalk/chalk", "engines": { - "node": ">=6" + "node": ">=8" }, "scripts": { "test": "xo && nyc ava && tsd-check && flow", @@ -43,20 +43,20 @@ "dependencies": { "ansi-styles": "^3.2.1", "escape-string-regexp": "^1.0.5", - "supports-color": "^6.0.0" + "supports-color": "^6.1.0" }, "devDependencies": { - "@sindresorhus/tsconfig": "^0.1.1", - "ava": "^1.0.1", - "coveralls": "^3.0.2", + "@sindresorhus/tsconfig": "^0.2.1", + "ava": "^1.3.1", + "coveralls": "^3.0.3", "execa": "^1.0.0", - "flow-bin": "^0.89.0", + "flow-bin": "^0.94.0", "import-fresh": "^3.0.0", "matcha": "^0.7.0", - "nyc": "^13.1.0", + "nyc": "^13.3.0", "resolve-from": "^4.0.0", "tsd-check": "^0.3.0", - "xo": "^0.23.0" + "xo": "^0.24.0" }, "types": "index.d.ts", "xo": { diff --git a/templates.js b/templates.js index bbc614d..6cdddea 100644 --- a/templates.js +++ b/templates.js @@ -25,9 +25,9 @@ function unescape(c) { return ESCAPES.get(c) || c; } -function parseArguments(name, args) { +function parseArguments(name, arguments_) { const results = []; - const chunks = args.trim().split(/\s*,\s*/g); + const chunks = arguments_.trim().split(/\s*,\s*/g); let matches; for (const chunk of chunks) { @@ -51,7 +51,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,9 +74,8 @@ 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])) { + for (const [styleName, styles] of Object.entries(enabled)) { + if (!Array.isArray(styles)) { continue; } @@ -84,23 +83,19 @@ function buildStyle(chalk, styles) { throw new Error(`Unknown Chalk style: ${styleName}`); } - if (enabled[styleName].length > 0) { - current = current[styleName](...enabled[styleName]); - } else { - current = current[styleName]; - } + current = styles.length > 0 ? current[styleName](...styles) : current[styleName]; } return current; } -module.exports = (chalk, tmp) => { +module.exports = (chalk, temporary) => { const styles = []; const chunks = []; let chunk = []; // eslint-disable-next-line max-params - tmp.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { + temporary.replace(TEMPLATE_REGEX, (m, escapeCharacter, inverse, style, close, character) => { if (escapeCharacter) { chunk.push(unescape(escapeCharacter)); } else if (style) { From 2ca015c4c537896dd378b94ecbbdec935a7b1b52 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 12 Mar 2019 20:31:33 +0700 Subject: [PATCH 060/170] Remove the blue color workaround for Windows (#330) The illegible blue color has been fixed in Windows 10 build 16257: https://blogs.msdn.microsoft.com/commandline/2017/08/02/updating-the-windows-console-colors/ The workaround causes all kinds of problems, so better to remove it than adding conditionals for older Windows versions. Fixes #329 --- index.js | 5 ----- test/windows.js | 14 +------------- 2 files changed, 1 insertion(+), 18 deletions(-) diff --git a/index.js b/index.js index 50e7591..80d9e3d 100644 --- a/index.js +++ b/index.js @@ -58,11 +58,6 @@ function Chalk(options) { return chalkFactory(options); } -// Use bright blue on Windows as the normal blue color is illegible -if (isSimpleWindowsTerm) { - ansiStyles.blue.open = '\u001B[94m'; -} - for (const [styleName, style] of Object.entries(ansiStyles)) { style.closeRe = new RegExp(escapeStringRegexp(style.close), 'g'); diff --git a/test/windows.js b/test/windows.js index 3ede386..ca51a0a 100644 --- a/test/windows.js +++ b/test/windows.js @@ -29,18 +29,6 @@ test.beforeEach(() => { test('detect a simple term if TERM isn\'t set', t => { delete process.env.TERM; const chalk = importFresh('..'); - t.is(chalk.blue('foo'), '\u001B[94mfoo\u001B[39m'); -}); - -test('replace blue foreground color in cmd.exe', t => { - process.env.TERM = 'dumb'; - const chalk = importFresh('..'); - t.is(chalk.blue('foo'), '\u001B[94mfoo\u001B[39m'); -}); - -test('don\'t replace blue foreground color in xterm based terminals', t => { - process.env.TERM = 'xterm-256color'; - const chalk = importFresh('..'); t.is(chalk.blue('foo'), '\u001B[34mfoo\u001B[39m'); }); @@ -59,5 +47,5 @@ test('apply dimmed styling on xterm compatible terminals', t => { test('apply dimmed styling on strings of other colors', t => { process.env.TERM = 'dumb'; const chalk = importFresh('..'); - t.is(chalk.blue.dim('foo'), '\u001B[94m\u001B[2mfoo\u001B[22m\u001B[39m'); + t.is(chalk.blue.dim('foo'), '\u001B[34m\u001B[2mfoo\u001B[22m\u001B[39m'); }); From cd5de7a2f6a7a04fbad4c75c0364a3efc6048ade Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 13 Mar 2019 00:24:34 +0700 Subject: [PATCH 061/170] Remove dim style workaround for Windows (#331) See: https://github.com/chalk/chalk/pull/330/#issuecomment-471977551 The issue seems to have been fixed in newer Windows 10 builds. We're not interested in adding a conditional for older Windows versions as the fix severely complicates the codebase, and it also creates problems for consumers as it makes the output unpredictable. --- index.js | 26 +++++-------------------- test/windows.js | 51 ------------------------------------------------- 2 files changed, 5 insertions(+), 72 deletions(-) delete mode 100644 test/windows.js diff --git a/index.js b/index.js index 80d9e3d..a33dae0 100644 --- a/index.js +++ b/index.js @@ -4,8 +4,6 @@ const ansiStyles = require('ansi-styles'); const {stdout: stdoutColor} = require('supports-color'); const template = require('./templates.js'); -const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); - // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ 'ansi', @@ -63,14 +61,14 @@ for (const [styleName, style] of Object.entries(ansiStyles)) { styles[styleName] = { get() { - return build.call(this, [...(this._styles || []), style], this._empty, styleName); + return build.call(this, [...(this._styles || []), style], this._empty); } }; } styles.visible = { get() { - return build.call(this, this._styles || [], true, 'visible'); + return build.call(this, this._styles || [], true); } }; @@ -90,7 +88,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 || []), codes], this._empty); }; } }; @@ -113,7 +111,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 || []), codes], this._empty); }; } }; @@ -121,7 +119,7 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { const proto = Object.defineProperties(() => {}, styles); -function build(_styles, _empty, key) { +function build(_styles, _empty) { const builder = (...arguments_) => applyStyle.call(builder, ...arguments_); builder._styles = _styles; builder._empty = _empty; @@ -148,9 +146,6 @@ function build(_styles, _empty, key) { } }); - // See below for fix regarding invisible grey/dim combination on Windows - builder.hasGrey = this.hasGrey || key === 'gray' || key === 'grey'; - // `__proto__` is used because we must return a function, but there is // no way to create a function with a different prototype builder.__proto__ = proto; // eslint-disable-line no-proto @@ -165,14 +160,6 @@ function applyStyle(...arguments_) { return this._empty ? '' : string; } - // Turns out that on Windows dimmed gray text becomes invisible in cmd.exe, - // see https://github.com/chalk/chalk/issues/58 - // If we're on Windows and we're dealing with a gray color, temporarily make 'dim' a noop. - const originalDim = ansiStyles.dim.open; - if (isSimpleWindowsTerm && this.hasGrey) { - ansiStyles.dim.open = ''; - } - for (const code of this._styles.slice().reverse()) { // Replace any instances already present with a re-opening code // otherwise only the part of the string until said closing code @@ -185,9 +172,6 @@ function applyStyle(...arguments_) { string = string.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; } diff --git a/test/windows.js b/test/windows.js deleted file mode 100644 index ca51a0a..0000000 --- a/test/windows.js +++ /dev/null @@ -1,51 +0,0 @@ -import test from 'ava'; -import importFresh from 'import-fresh'; -import resolveFrom from 'resolve-from'; - -// Spoof supports-color -require('./_supports-color')(__dirname); - -let originalEnv; -let originalPlatform; - -test.before(() => { - originalEnv = process.env; - originalPlatform = process.platform; -}); - -test.after(() => { - process.env = originalEnv; - Object.defineProperty(process, 'platform', {value: originalPlatform}); -}); - -test.beforeEach(() => { - process.env = {}; - Object.defineProperty(process, 'platform', {value: 'win32'}); - // Since chalk internally modifies `ansiStyles.blue.open`, `ansi-styles` needs - // to be removed from the require cache for `require-uncached` to work - delete require.cache[resolveFrom(__dirname, 'ansi-styles')]; -}); - -test('detect a simple term if TERM isn\'t set', t => { - delete process.env.TERM; - const chalk = importFresh('..'); - t.is(chalk.blue('foo'), '\u001B[34mfoo\u001B[39m'); -}); - -test('don\'t apply dimmed styling on gray strings, see https://github.com/chalk/chalk/issues/58', t => { - process.env.TERM = 'dumb'; - const chalk = importFresh('..'); - t.is(chalk.gray.dim('foo'), '\u001B[90mfoo\u001B[22m\u001B[39m'); -}); - -test('apply dimmed styling on xterm compatible terminals', t => { - process.env.TERM = 'xterm'; - const chalk = importFresh('..'); - t.is(chalk.gray.dim('foo'), '\u001B[90m\u001B[2mfoo\u001B[22m\u001B[39m'); -}); - -test('apply dimmed styling on strings of other colors', t => { - process.env.TERM = 'dumb'; - const chalk = importFresh('..'); - t.is(chalk.blue.dim('foo'), '\u001B[34m\u001B[2mfoo\u001B[22m\u001B[39m'); -}); From 7b9211be501f0608ed89c1a6da88a144199b7a54 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 14 Mar 2019 23:53:22 +0700 Subject: [PATCH 062/170] Minor refactoring --- index.js | 44 +++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 23 deletions(-) diff --git a/index.js b/index.js index a33dae0..7d00571 100644 --- a/index.js +++ b/index.js @@ -17,7 +17,7 @@ const skipModels = new Set(['gray']); const styles = Object.create(null); -function applyOptions(object, options = {}) { +const applyOptions = (object, options = {}) => { if (options.level > 3 || options.level < 0) { throw new Error('The `level` option should be an integer from 0 to 3'); } @@ -26,7 +26,7 @@ function applyOptions(object, options = {}) { const colorLevel = stdoutColor ? stdoutColor.level : 0; object.level = options.level === undefined ? colorLevel : options.level; object.enabled = 'enabled' in options ? options.enabled : object.level > 0; -} +}; class ChalkClass { constructor(options) { @@ -34,7 +34,7 @@ class ChalkClass { } } -function chalkFactory(options) { +const chalkFactory = options => { const chalk = {}; applyOptions(chalk, options); @@ -50,7 +50,7 @@ function chalkFactory(options) { chalk.template.Instance = ChalkClass; return chalk.template; -} +}; function Chalk(options) { return chalkFactory(options); @@ -61,14 +61,14 @@ for (const [styleName, style] of Object.entries(ansiStyles)) { styles[styleName] = { get() { - return build.call(this, [...(this._styles || []), style], this._empty); + return createBuilder(this, [...(this._styles || []), style], this._isEmpty); } }; } styles.visible = { get() { - return build.call(this, this._styles || [], true); + return createBuilder(this, this._styles || [], true); } }; @@ -81,14 +81,14 @@ for (const model of Object.keys(ansiStyles.color.ansi)) { styles[model] = { get() { const {level} = this; - return function (...args) { - const open = ansiStyles.color[levelMapping[level]][model](...args); + return function (...arguments_) { + const open = ansiStyles.color[levelMapping[level]][model](...arguments_); const codes = { open, close: ansiStyles.color.close, closeRe: ansiStyles.color.closeRe }; - return build.call(this, [...(this._styles || []), codes], this._empty); + return createBuilder(this, [...(this._styles || []), codes], this._isEmpty); }; } }; @@ -111,7 +111,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); + return createBuilder(this, [...(this._styles || []), codes], this._isEmpty); }; } }; @@ -119,12 +119,10 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { const proto = Object.defineProperties(() => {}, styles); -function build(_styles, _empty) { - const builder = (...arguments_) => applyStyle.call(builder, ...arguments_); +const createBuilder = (self, _styles, _isEmpty) => { + const builder = (...arguments_) => applyStyle(builder, ...arguments_); builder._styles = _styles; - builder._empty = _empty; - - const self = this; + builder._isEmpty = _isEmpty; Object.defineProperty(builder, 'level', { enumerable: true, @@ -151,16 +149,16 @@ function build(_styles, _empty) { builder.__proto__ = proto; // eslint-disable-line no-proto return builder; -} +}; -function applyStyle(...arguments_) { +const applyStyle = (self, ...arguments_) => { let string = arguments_.join(' '); - if (!this.enabled || this.level <= 0 || !string) { - return this._empty ? '' : string; + if (!self.enabled || self.level <= 0 || !string) { + return self._isEmpty ? '' : string; } - for (const code of this._styles.slice().reverse()) { + for (const code of self._styles.slice().reverse()) { // 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'. @@ -173,9 +171,9 @@ function applyStyle(...arguments_) { } return string; -} +}; -function chalkTag(chalk, ...strings) { +const chalkTag = (chalk, ...strings) => { const [firstString] = strings; if (!Array.isArray(firstString)) { @@ -195,7 +193,7 @@ function chalkTag(chalk, ...strings) { } return template(chalk, parts.join('')); -} +}; Object.defineProperties(Chalk.prototype, styles); From 98628d9f087a5c1771651fa7b867dcd2356c2123 Mon Sep 17 00:00:00 2001 From: Dimitri Benin Date: Sun, 28 Apr 2019 04:10:44 +0000 Subject: [PATCH 063/170] Use CommonJS-compatible export in TypeScript definition (#344) --- .travis.yml | 1 + index.d.ts | 523 ++++++++++++++++++++++++------------------------ index.js | 1 - index.test-d.ts | 18 +- package.json | 15 +- 5 files changed, 284 insertions(+), 274 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5e3bcf3..1492647 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,6 @@ language: node_js node_js: + - '12' - '10' - '8' after_success: diff --git a/index.d.ts b/index.d.ts index 6256ce3..c7d4a54 100644 --- a/index.d.ts +++ b/index.d.ts @@ -1,276 +1,287 @@ -export const enum Level { +declare const enum LevelEnum { /** - * All colors disabled. - */ + All colors disabled. + */ None = 0, /** - * Basic 16 colors support. - */ + Basic 16 colors support. + */ Basic = 1, /** - * ANSI 256 colors support. - */ + ANSI 256 colors support. + */ Ansi256 = 2, /** - * Truecolor 16 million colors support. - */ + Truecolor 16 million colors support. + */ TrueColor = 3 } -export interface Options { - /** - * Enable or disable Chalk. - * - * @default true - */ - enabled?: boolean; +declare namespace chalk { + type Level = LevelEnum; + + 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; + } + + interface Instance { + /** + Return a new Chalk instance. + */ + new (options?: Options): Chalk; + } /** - * Specify the color support for Chalk. - * By default, color support is automatically detected based on the environment. - */ - level?: Level; -} + Detect whether the terminal supports color. + */ + interface ColorSupport { + /** + The color level used by Chalk. + */ + level: Level; -export interface Instance { - /** - * Return a new Chalk instance. - */ - new (options?: Options): Chalk; + /** + 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; + } + + interface Chalk { + (...text: unknown[]): string; + + (text: TemplateStringsArray, ...placeholders: unknown[]): string; + + /** + Return a new Chalk instance. + */ + Instance: Instance; + + /** + 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 = require('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 = require('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 = require('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 = require('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; + } } /** - * Detect whether the terminal supports color. - */ -export interface ColorSupport { - /** - * The color level used by Chalk. - */ - level: Level; +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.Chalk & { + supportsColor: chalk.ColorSupport; + Level: typeof LevelEnum; +}; - /** - * 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. - */ - Instance: Instance; - - /** - * 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; +export = chalk; diff --git a/index.js b/index.js index 7d00571..9f5575a 100644 --- a/index.js +++ b/index.js @@ -199,4 +199,3 @@ Object.defineProperties(Chalk.prototype, styles); module.exports = Chalk(); // eslint-disable-line new-cap module.exports.supportsColor = stdoutColor; -module.exports.default = module.exports; // For TypeScript diff --git a/index.test-d.ts b/index.test-d.ts index 0b26e9c..7a791a8 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,14 +1,14 @@ -import {expectType} from 'tsd-check'; -import chalk, {Level, Chalk, ColorSupport} from '.'; +import {expectType} from 'tsd'; +import chalk = require('.'); // - Helpers - -type colorReturn = Chalk & {supportsColor: ColorSupport}; +type colorReturn = chalk.Chalk & {supportsColor: chalk.ColorSupport}; // - Level - -expectType(Level.None); -expectType(Level.Basic); -expectType(Level.Ansi256); -expectType(Level.TrueColor); +expectType(chalk.Level.None); +expectType(chalk.Level.Basic); +expectType(chalk.Level.Ansi256); +expectType(chalk.Level.TrueColor); // - supportsColor - expectType(chalk.supportsColor.hasBasic); @@ -17,11 +17,11 @@ expectType(chalk.supportsColor.has16m); // - Chalk - // -- Instance -- -expectType(new chalk.Instance({level: 1})); +expectType(new chalk.Instance({level: 1})); // -- Properties -- expectType(chalk.enabled); -expectType(chalk.level); +expectType(chalk.level); // -- Template literal -- expectType(chalk``); diff --git a/package.json b/package.json index bbc1634..39ec03d 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,7 @@ "node": ">=8" }, "scripts": { - "test": "xo && nyc ava && tsd-check && flow", + "test": "xo && nyc ava && tsd && flow", "bench": "matcha benchmark.js" }, "files": [ @@ -46,19 +46,18 @@ "supports-color": "^6.1.0" }, "devDependencies": { - "@sindresorhus/tsconfig": "^0.2.1", - "ava": "^1.3.1", + "@sindresorhus/tsconfig": "^0.3.0", + "ava": "^1.4.1", "coveralls": "^3.0.3", "execa": "^1.0.0", - "flow-bin": "^0.94.0", + "flow-bin": "^0.98.0", "import-fresh": "^3.0.0", "matcha": "^0.7.0", - "nyc": "^13.3.0", - "resolve-from": "^4.0.0", - "tsd-check": "^0.3.0", + "nyc": "^14.0.0", + "resolve-from": "^5.0.0", + "tsd": "^0.7.2", "xo": "^0.24.0" }, - "types": "index.d.ts", "xo": { "ignores": [ "test/_flow.js" From d3be9c65b11f505e0e8bd9d4796c4988bb634cf7 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 3 May 2019 15:03:53 +0700 Subject: [PATCH 064/170] Drop built-in Flow type definition I don't want to be responsible for maintaining it. Submit it to https://github.com/flow-typed/flow-typed if you need it. --- .flowconfig | 6 ---- index.js.flow | 93 --------------------------------------------------- package.json | 11 ++---- readme.md | 2 +- test/_flow.js | 86 ----------------------------------------------- 5 files changed, 3 insertions(+), 195 deletions(-) delete mode 100644 .flowconfig delete mode 100644 index.js.flow delete mode 100644 test/_flow.js diff --git a/.flowconfig b/.flowconfig deleted file mode 100644 index 48ee960..0000000 --- a/.flowconfig +++ /dev/null @@ -1,6 +0,0 @@ -[ignore] -.*/node_modules/.* - -[options] -suppress_comment= \\(.\\|\n\\)*\\$ExpectError -include_warnings=true diff --git a/index.js.flow b/index.js.flow deleted file mode 100644 index f7e4abc..0000000 --- a/index.js.flow +++ /dev/null @@ -1,93 +0,0 @@ -// @flow strict - -type TemplateStringsArray = $ReadOnlyArray; - -export type Level = $Values<{ - None: 0, - Basic: 1, - Ansi256: 2, - TrueColor: 3 -}>; - -export type Options = {| - enabled?: boolean, - level?: Level -|}; - -export type ColorSupport = {| - level: Level, - hasBasic: boolean, - has256: boolean, - has16m: boolean -|}; - -export interface Chalk { - (...text: string[]): string, - (text: TemplateStringsArray, ...placeholders: mixed[]): string, - Instance(options?: Options): 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, - 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, - hex(color: string): Chalk, - keyword(color: string): Chalk, - - +reset: Chalk, - +bold: Chalk, - +dim: Chalk, - +italic: Chalk, - +underline: Chalk, - +inverse: Chalk, - +hidden: Chalk, - +strikethrough: Chalk, - - +visible: Chalk, - - +black: Chalk, - +red: Chalk, - +green: Chalk, - +yellow: Chalk, - +blue: Chalk, - +magenta: Chalk, - +cyan: Chalk, - +white: Chalk, - +gray: Chalk, - +grey: Chalk, - +blackBright: Chalk, - +redBright: Chalk, - +greenBright: Chalk, - +yellowBright: Chalk, - +blueBright: Chalk, - +magentaBright: Chalk, - +cyanBright: Chalk, - +whiteBright: Chalk, - - +bgBlack: Chalk, - +bgRed: Chalk, - +bgGreen: Chalk, - +bgYellow: Chalk, - +bgBlue: Chalk, - +bgMagenta: Chalk, - +bgCyan: Chalk, - +bgWhite: Chalk, - +bgBlackBright: Chalk, - +bgRedBright: Chalk, - +bgGreenBright: Chalk, - +bgYellowBright: Chalk, - +bgBlueBright: Chalk, - +bgMagentaBright: Chalk, - +bgCyanBright: Chalk, - +bgWhiteBright: Chalk, - - supportsColor: ColorSupport -}; - -declare module.exports: Chalk; diff --git a/package.json b/package.json index 39ec03d..b18d8a3 100644 --- a/package.json +++ b/package.json @@ -8,14 +8,13 @@ "node": ">=8" }, "scripts": { - "test": "xo && nyc ava && tsd && flow", + "test": "xo && nyc ava && tsd", "bench": "matcha benchmark.js" }, "files": [ "index.js", "templates.js", - "index.d.ts", - "index.js.flow" + "index.d.ts" ], "keywords": [ "color", @@ -50,17 +49,11 @@ "ava": "^1.4.1", "coveralls": "^3.0.3", "execa": "^1.0.0", - "flow-bin": "^0.98.0", "import-fresh": "^3.0.0", "matcha": "^0.7.0", "nyc": "^14.0.0", "resolve-from": "^5.0.0", "tsd": "^0.7.2", "xo": "^0.24.0" - }, - "xo": { - "ignores": [ - "test/_flow.js" - ] } } diff --git a/readme.md b/readme.md index 1e3b9bb..ed3cd1b 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ > Terminal string styling done right -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript- and Flow-ready](https://img.shields.io/npm/types/chalk.svg) +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript-ready](https://img.shields.io/npm/types/chalk.svg) diff --git a/test/_flow.js b/test/_flow.js deleted file mode 100644 index dbb6dd0..0000000 --- a/test/_flow.js +++ /dev/null @@ -1,86 +0,0 @@ -// @flow -import chalk from '..'; - -// $ExpectError (Can't have typo in option name) -new chalk.Instance({levl: 1}); -new chalk.Instance({level: 1}); - -// $ExpectError (Option must have proper type) -new chalk.Instance({enabled: 'true'}); -new chalk.Instance({enabled: true}); - -// $ExpectError (Can't have typo in chalk method) -chalk.rd('foo'); -chalk.red('foo'); - -// $ExpectError (Can't have typo in chalk method) -chalk.gren`foo`; -chalk.green`foo`; - -// $ExpectError (Can't have typo in chalk method) -chalk.red.bgBlu.underline('foo'); -chalk.red.bgBlue.underline('foo'); - -// $ExpectError (Level must be 0, 1, 2, or 3) -const badCtx = chalk.Instance({level: 4}); -const ctx = chalk.Instance({level: 3}); - -// $ExpectError (Can't have typo in method name) -ctx.gry('foo'); -ctx.grey('foo'); - -// $ExpectError (Can't have typo in method name) -ctx`foo`.value(); -ctx`foo`.valueOf(); - -// $ExpectError (Can't have typo in property name) -chalk.abled = true; -chalk.enabled = true; - -// $ExpectError (Can't use invalid Level for property setter) -chalk.level = 10; -chalk.level = 1; - -const chalkInstance = new chalk.Instance(); - -// $ExpectError (Can't have typo in method name) -chalkInstance.blu('foo'); -chalkInstance.blue('foo'); -chalkInstance`foo`; - -// $ExpectError (Can't have typo in method name) -chalk.keywrd('orange').bgBlue('foo'); -chalk.keyword('orange').bgBlue('foo'); - -// $ExpectError (rgb should take in 3 numbers) -chalk.rgb(1, 14).bgBlue('foo'); -chalk.rgb(1, 14, 9).bgBlue('foo'); - -// $ExpectError (hsl should take in 3 numbers) -chalk.hsl(1, 14, '9').bgBlue('foo'); -chalk.hsl(1, 14, 9).bgBlue('foo'); - -// $ExpectError (hsv should take in 3 numbers) -chalk.hsv(1, 14).bgBlue('foo'); -chalk.hsv(1, 14, 9).bgBlue('foo'); - -// $ExpectError (hwb should take in 3 numbers) -chalk.hwb(1, 14).bgBlue('foo'); -chalk.hwb(1, 14, 9).bgBlue('foo'); - -// $ExpectError (Can't have typo in method name) -chalk.visibl('foo'); -chalk.visible('foo'); - -// $ExpectError (Can't have typo in method name) -chalk.red.visibl('foo'); -chalk.red.visible('foo'); -chalk.visible.red('foo'); - -// $ExpectError (Can't write to readonly property) -chalk.black = 'foo'; -chalk.black; - -// $ExpectError (Can't write to readonly property) -chalk.reset = 'foo'; -console.log(chalk.reset); From b3e9b91405c8fa93fa8b2b9343449a797baba0a0 Mon Sep 17 00:00:00 2001 From: ExE Boss <3889017+ExE-Boss@users.noreply.github.com> Date: Sat, 11 May 2019 10:04:20 +0200 Subject: [PATCH 065/170] =?UTF-8?q?Fix=20TypeScript=20types=20for=20`suppo?= =?UTF-8?q?rtsColor`=20which=20is=C2=A0top=E2=80=91level=20only=20(#342)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Dimitri Benin --- index.d.ts | 132 +++++++++++++++++++++++++++--------------------- index.test-d.ts | 7 ++- 2 files changed, 79 insertions(+), 60 deletions(-) diff --git a/index.d.ts b/index.d.ts index c7d4a54..eed72e0 100644 --- a/index.d.ts +++ b/index.d.ts @@ -70,11 +70,27 @@ declare namespace chalk { has16m: boolean; } - interface Chalk { - (...text: unknown[]): string; + interface ChalkFunction { + /** + Use a template string. + @remarks Template literals are unsupported for nested calls (see [issue #341](https://github.com/chalk/chalk/issues/341)) + + @example + ``` + log(chalk` + CPU: {red ${cpu.totalPercent}%} + RAM: {green ${ram.used / ram.total * 100}%} + DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%} + `); + ``` + */ (text: TemplateStringsArray, ...placeholders: unknown[]): string; + (...text: unknown[]): string; + } + + interface Chalk extends ChalkFunction { /** Return a new Chalk instance. */ @@ -105,7 +121,7 @@ declare namespace chalk { chalk.hex('#DEADED'); ``` */ - hex(color: string): this; + hex(color: string): Chalk; /** Use keyword color value to set text color. @@ -119,27 +135,27 @@ declare namespace chalk { chalk.keyword('orange'); ``` */ - keyword(color: string): this; + keyword(color: string): Chalk; /** Use RGB values to set text color. */ - rgb(red: number, green: number, blue: number): this; + rgb(red: number, green: number, blue: number): Chalk; /** Use HSL values to set text color. */ - hsl(hue: number, saturation: number, lightness: number): this; + hsl(hue: number, saturation: number, lightness: number): Chalk; /** Use HSV values to set text color. */ - hsv(hue: number, saturation: number, value: number): this; + hsv(hue: number, saturation: number, value: number): Chalk; /** Use HWB values to set text color. */ - hwb(hue: number, whiteness: number, blackness: number): this; + hwb(hue: number, whiteness: number, blackness: number): Chalk; /** Use HEX value to set background color. @@ -153,7 +169,7 @@ declare namespace chalk { chalk.bgHex('#DEADED'); ``` */ - bgHex(color: string): this; + bgHex(color: string): Chalk; /** Use keyword color value to set background color. @@ -167,109 +183,109 @@ declare namespace chalk { chalk.bgKeyword('orange'); ``` */ - bgKeyword(color: string): this; + bgKeyword(color: string): Chalk; /** Use RGB values to set background color. */ - bgRgb(red: number, green: number, blue: number): this; + bgRgb(red: number, green: number, blue: number): Chalk; /** Use HSL values to set background color. */ - bgHsl(hue: number, saturation: number, lightness: number): this; + bgHsl(hue: number, saturation: number, lightness: number): Chalk; /** Use HSV values to set background color. */ - bgHsv(hue: number, saturation: number, value: number): this; + bgHsv(hue: number, saturation: number, value: number): Chalk; /** Use HWB values to set background color. */ - bgHwb(hue: number, whiteness: number, blackness: number): this; + bgHwb(hue: number, whiteness: number, blackness: number): Chalk; /** Modifier: Resets the current color chain. */ - readonly reset: this; + readonly reset: Chalk; /** Modifier: Make text bold. */ - readonly bold: this; + readonly bold: Chalk; /** Modifier: Emitting only a small amount of light. */ - readonly dim: this; + readonly dim: Chalk; /** Modifier: Make text italic. (Not widely supported) */ - readonly italic: this; + readonly italic: Chalk; /** Modifier: Make text underline. (Not widely supported) */ - readonly underline: this; + readonly underline: Chalk; /** Modifier: Inverse background and foreground colors. */ - readonly inverse: this; + readonly inverse: Chalk; /** Modifier: Prints the text, but makes it invisible. */ - readonly hidden: this; + readonly hidden: Chalk; /** Modifier: Puts a horizontal line through the center of the text. (Not widely supported) */ - readonly strikethrough: this; + readonly strikethrough: Chalk; /** Modifier: Prints the text only when Chalk is enabled. Can be useful for things that are purely cosmetic. */ - readonly visible: this; + readonly visible: Chalk; - 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 black: Chalk; + readonly red: Chalk; + readonly green: Chalk; + readonly yellow: Chalk; + readonly blue: Chalk; + readonly magenta: Chalk; + readonly cyan: Chalk; + readonly white: Chalk; + readonly gray: Chalk; + readonly grey: Chalk; + readonly blackBright: Chalk; + readonly redBright: Chalk; + readonly greenBright: Chalk; + readonly yellowBright: Chalk; + readonly blueBright: Chalk; + readonly magentaBright: Chalk; + readonly cyanBright: Chalk; + readonly whiteBright: Chalk; - 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; + readonly bgBlack: Chalk; + readonly bgRed: Chalk; + readonly bgGreen: Chalk; + readonly bgYellow: Chalk; + readonly bgBlue: Chalk; + readonly bgMagenta: Chalk; + readonly bgCyan: Chalk; + readonly bgWhite: Chalk; + readonly bgBlackBright: Chalk; + readonly bgRedBright: Chalk; + readonly bgGreenBright: Chalk; + readonly bgYellowBright: Chalk; + readonly bgBlueBright: Chalk; + readonly bgMagentaBright: Chalk; + readonly bgCyanBright: Chalk; + readonly bgWhiteBright: Chalk; } } @@ -279,7 +295,7 @@ 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.Chalk & { +declare const chalk: chalk.Chalk & chalk.ChalkFunction & { supportsColor: chalk.ColorSupport; Level: typeof LevelEnum; }; diff --git a/index.test-d.ts b/index.test-d.ts index 7a791a8..0a25ff7 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,8 +1,8 @@ -import {expectType} from 'tsd'; +import {expectType, expectError} from 'tsd'; import chalk = require('.'); // - Helpers - -type colorReturn = chalk.Chalk & {supportsColor: chalk.ColorSupport}; +type colorReturn = chalk.Chalk & {supportsColor?: never}; // - Level - expectType(chalk.Level.None); @@ -15,6 +15,9 @@ expectType(chalk.supportsColor.hasBasic); expectType(chalk.supportsColor.has256); expectType(chalk.supportsColor.has16m); +// -- `supportsColor` is not a member of the Chalk interface -- +expectError(chalk.reset.supportsColor); + // - Chalk - // -- Instance -- expectType(new chalk.Instance({level: 1})); From 4990a3578affe1c14ad5d66923ff9849a4117ec3 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Thu, 23 May 2019 16:45:56 +0700 Subject: [PATCH 066/170] Add GitHub Sponsors button to the repo --- .github/funding.yml | 5 +++++ readme.md | 4 ---- 2 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 .github/funding.yml diff --git a/.github/funding.yml b/.github/funding.yml new file mode 100644 index 0000000..baa12cf --- /dev/null +++ b/.github/funding.yml @@ -0,0 +1,5 @@ +github: sindresorhus +open_collective: sindresorhus +patreon: sindresorhus +tidelift: npm/chalk +custom: https://sindresorhus.com/donate diff --git a/readme.md b/readme.md index ed3cd1b..99693e4 100644 --- a/readme.md +++ b/readme.md @@ -47,10 +47,6 @@ $ npm install chalk ``` - - - - ## Usage From 4ab4665994689b1157be7d37148eb2547b0b446b Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 31 May 2019 14:53:04 +0700 Subject: [PATCH 067/170] Tidelift tasks --- .github/security.md | 3 +++ readme.md | 31 ++++++++++--------------------- 2 files changed, 13 insertions(+), 21 deletions(-) create mode 100644 .github/security.md diff --git a/.github/security.md b/.github/security.md new file mode 100644 index 0000000..5358dc5 --- /dev/null +++ b/.github/security.md @@ -0,0 +1,3 @@ +# Security Policy + +To report a security vulnerability, please use the [Tidelift security contact](https://tidelift.com/security). Tidelift will coordinate the fix and disclosure. diff --git a/readme.md b/readme.md index 99693e4..5e96212 100644 --- a/readme.md +++ b/readme.md @@ -13,20 +13,6 @@ ---- - -
- - Get professional support for Chalk with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
- ---- - ## Highlights @@ -293,11 +279,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 @@ -322,6 +303,14 @@ To report a security vulnerability, please use the [Tidelift security contact](h - [Josh Junon](https://github.com/qix-) -## License +--- -MIT +
+ + Get professional support for Chalk with a Tidelift subscription + +
+ + Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. +
+
From d82b2a66389d26dab1a44c85ac273f894af4aaae Mon Sep 17 00:00:00 2001 From: Florian Reuschel Date: Mon, 10 Jun 2019 19:47:16 +0200 Subject: [PATCH 068/170] Add missing `false` type to chalk.supportsColor (#347) --- index.d.ts | 2 +- index.test-d.ts | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/index.d.ts b/index.d.ts index eed72e0..0f5d885 100644 --- a/index.d.ts +++ b/index.d.ts @@ -296,7 +296,7 @@ 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.Chalk & chalk.ChalkFunction & { - supportsColor: chalk.ColorSupport; + supportsColor: chalk.ColorSupport | false; Level: typeof LevelEnum; }; diff --git a/index.test-d.ts b/index.test-d.ts index 0a25ff7..fd19d04 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -11,9 +11,10 @@ expectType(chalk.Level.Ansi256); expectType(chalk.Level.TrueColor); // - supportsColor - -expectType(chalk.supportsColor.hasBasic); -expectType(chalk.supportsColor.has256); -expectType(chalk.supportsColor.has16m); +expectType(chalk.supportsColor); +expectType((chalk.supportsColor as chalk.ColorSupport).hasBasic); +expectType((chalk.supportsColor as chalk.ColorSupport).has256); +expectType((chalk.supportsColor as chalk.ColorSupport).has16m); // -- `supportsColor` is not a member of the Chalk interface -- expectError(chalk.reset.supportsColor); From e2dd171597200df04aad3bf6e39329189a315153 Mon Sep 17 00:00:00 2001 From: Marcos Marado Date: Sun, 30 Jun 2019 17:11:52 +0100 Subject: [PATCH 069/170] Remove outdated info in the readme (#351) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 5e96212..78af5ae 100644 --- a/readme.md +++ b/readme.md @@ -176,7 +176,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= - `red` - `green` - `yellow` -- `blue` *(On Windows the bright version is used since normal blue is illegible)* +- `blue` - `magenta` - `cyan` - `white` From 983094883cfe42e79c60c6a6a05b21a0bcd00c35 Mon Sep 17 00:00:00 2001 From: Qix Date: Fri, 12 Jul 2019 08:35:11 +0200 Subject: [PATCH 070/170] Fix support for bracketed Unicode escapes in template literals (#350) --- templates.js | 13 ++++++++++--- test/template-literal.js | 7 +++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/templates.js b/templates.js index 6cdddea..fe94642 100644 --- a/templates.js +++ b/templates.js @@ -1,8 +1,8 @@ 'use strict'; -const TEMPLATE_REGEX = /(?:\\(u[a-f\d]{4}|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; +const TEMPLATE_REGEX = /(?:\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.))|(?:\{(~)?(\w+(?:\([^)]*\))?(?:\.\w+(?:\([^)]*\))?)*)(?:[ \t]|(?=\r?\n)))|(\})|((?:.|[\r\n\f])+?)/gi; const STYLE_REGEX = /(?:^|\.)(\w+)(?:\(([^)]*)\))?/g; const STRING_REGEX = /^(['"])((?:\\.|(?!\1)[^\\])*)\1$/; -const ESCAPE_REGEX = /\\(u[a-f\d]{4}|x[a-f\d]{2}|.)|([^\\])/gi; +const ESCAPE_REGEX = /\\(u(?:[a-f\d]{4}|\{[a-f\d]{1,6}\})|x[a-f\d]{2}|.)|([^\\])/gi; const ESCAPES = new Map([ ['n', '\n'], @@ -18,10 +18,17 @@ const ESCAPES = new Map([ ]); function unescape(c) { - if ((c[0] === 'u' && c.length === 5) || (c[0] === 'x' && c.length === 3)) { + const u = c[0] === 'u'; + const bracket = c[1] === '{'; + + if ((u && !bracket && c.length === 5) || (c[0] === 'x' && c.length === 3)) { return String.fromCharCode(parseInt(c.slice(1), 16)); } + if (u && bracket) { + return String.fromCodePoint(parseInt(c.slice(2, -1), 16)); + } + return ESCAPES.get(c) || c; } diff --git a/test/template-literal.js b/test/template-literal.js index 1f388c8..ae4a0bc 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -168,3 +168,10 @@ test('should properly handle undefined template interpolated values', t => { t.is(instance`hello ${undefined}`, 'hello undefined'); t.is(instance`hello ${null}`, 'hello null'); }); + +test('should allow bracketed Unicode escapes', t => { + const instance = new chalk.Instance({level: 3}); + t.is(instance`\u{AB}`, '\u{AB}'); + t.is(instance`This is a {bold \u{AB681}} test`, 'This is a \u001B[1m\u{AB681}\u001B[22m test'); + t.is(instance`This is a {bold \u{10FFFF}} test`, 'This is a \u001B[1m\u{10FFFF}\u001B[22m test'); +}); From c08417e88ca41f7133eb1a00e0b3fc8aefbb6cc9 Mon Sep 17 00:00:00 2001 From: Yanis Benson Date: Fri, 12 Jul 2019 09:40:23 +0300 Subject: [PATCH 071/170] Improve performance greatly (#337) --- benchmark.js | 42 ++++++++++--- examples/screenshot.js | 2 +- index.js | 133 +++++++++++++++++++++++++---------------- lib/util.js | 37 ++++++++++++ package.json | 1 - test/chalk.js | 4 ++ 6 files changed, 159 insertions(+), 60 deletions(-) create mode 100644 lib/util.js diff --git a/benchmark.js b/benchmark.js index f4e9cf3..dc24696 100644 --- a/benchmark.js +++ b/benchmark.js @@ -3,22 +3,48 @@ const chalk = require('.'); suite('chalk', () => { - set('iterations', 100000); + set('iterations', 1000000); - bench('single style', () => { + const chalkRed = chalk.red; + const chalkBgRed = chalk.bgRed; + const chalkBlueBgRed = chalk.blue.bgRed; + const chalkBlueBgRedBold = chalk.blue.bgRed.bold; + + const blueStyledString = 'the fox jumps' + chalk.blue('over the lazy dog') + '!'; + + bench('1 style', () => { chalk.red('the fox jumps over the lazy dog'); }); - bench('several styles', () => { + bench('2 styles', () => { + chalk.blue.bgRed('the fox jumps over the lazy dog'); + }); + + bench('3 styles', () => { chalk.blue.bgRed.bold('the fox jumps over the lazy dog'); }); - const cached = chalk.blue.bgRed.bold; - bench('cached styles', () => { - cached('the fox jumps over the lazy dog'); + bench('cached: 1 style', () => { + chalkRed('the fox jumps over the lazy dog'); }); - bench('nested styles', () => { - chalk.red('the fox jumps', chalk.underline.bgBlue('over the lazy dog') + '!'); + bench('cached: 2 styles', () => { + chalkBlueBgRed('the fox jumps over the lazy dog'); + }); + + bench('cached: 3 styles', () => { + chalkBlueBgRedBold('the fox jumps over the lazy dog'); + }); + + bench('cached: 1 style with newline', () => { + chalkRed('the fox jumps\nover the lazy dog'); + }); + + bench('cached: 1 style nested intersecting', () => { + chalkRed(blueStyledString); + }); + + bench('cached: 1 style nested non-intersecting', () => { + chalkBgRed(blueStyledString); }); }); diff --git a/examples/screenshot.js b/examples/screenshot.js index 7d195a6..37f5850 100644 --- a/examples/screenshot.js +++ b/examples/screenshot.js @@ -1,6 +1,6 @@ 'use strict'; -const chalk = require('..'); const styles = require('ansi-styles'); +const chalk = require('..'); // Generates screenshot for (const key of Object.keys(styles)) { diff --git a/index.js b/index.js index 9f5575a..21d3a83 100644 --- a/index.js +++ b/index.js @@ -1,9 +1,13 @@ 'use strict'; -const escapeStringRegexp = require('escape-string-regexp'); const ansiStyles = require('ansi-styles'); const {stdout: stdoutColor} = require('supports-color'); const template = require('./templates.js'); +const { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +} = require('./lib/util'); + // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ 'ansi', @@ -57,22 +61,23 @@ function Chalk(options) { } for (const [styleName, style] of Object.entries(ansiStyles)) { - style.closeRe = new RegExp(escapeStringRegexp(style.close), 'g'); - styles[styleName] = { get() { - return createBuilder(this, [...(this._styles || []), style], this._isEmpty); + const builder = createBuilder(this, createStyler(style.open, style.close, this._styler), this._isEmpty); + Object.defineProperty(this, styleName, {value: builder}); + return builder; } }; } styles.visible = { get() { - return createBuilder(this, this._styles || [], true); + const builder = createBuilder(this, this._styler, true); + Object.defineProperty(this, 'visible', {value: builder}); + return builder; } }; -ansiStyles.color.closeRe = new RegExp(escapeStringRegexp(ansiStyles.color.close), 'g'); for (const model of Object.keys(ansiStyles.color.ansi)) { if (skipModels.has(model)) { continue; @@ -82,19 +87,13 @@ for (const model of Object.keys(ansiStyles.color.ansi)) { get() { const {level} = this; return function (...arguments_) { - const open = ansiStyles.color[levelMapping[level]][model](...arguments_); - const codes = { - open, - close: ansiStyles.color.close, - closeRe: ansiStyles.color.closeRe - }; - return createBuilder(this, [...(this._styles || []), codes], this._isEmpty); + const styler = createStyler(ansiStyles.color[levelMapping[level]][model](...arguments_), ansiStyles.color.close, this._styler); + return createBuilder(this, styler, this._isEmpty); }; } }; } -ansiStyles.bgColor.closeRe = new RegExp(escapeStringRegexp(ansiStyles.bgColor.close), 'g'); for (const model of Object.keys(ansiStyles.bgColor.ansi)) { if (skipModels.has(model)) { continue; @@ -105,72 +104,106 @@ for (const model of Object.keys(ansiStyles.bgColor.ansi)) { get() { const {level} = this; return function (...arguments_) { - const open = ansiStyles.bgColor[levelMapping[level]][model](...arguments_); - const codes = { - open, - close: ansiStyles.bgColor.close, - closeRe: ansiStyles.bgColor.closeRe - }; - return createBuilder(this, [...(this._styles || []), codes], this._isEmpty); + const styler = createStyler(ansiStyles.bgColor[levelMapping[level]][model](...arguments_), ansiStyles.bgColor.close, this._styler); + return createBuilder(this, styler, this._isEmpty); }; } }; } -const proto = Object.defineProperties(() => {}, styles); - -const createBuilder = (self, _styles, _isEmpty) => { - const builder = (...arguments_) => applyStyle(builder, ...arguments_); - builder._styles = _styles; - builder._isEmpty = _isEmpty; - - Object.defineProperty(builder, 'level', { +const proto = Object.defineProperties(() => {}, { + ...styles, + level: { enumerable: true, get() { - return self.level; + return this._generator.level; }, set(level) { - self.level = level; + this._generator.level = level; } - }); - - Object.defineProperty(builder, 'enabled', { + }, + enabled: { enumerable: true, get() { - return self.enabled; + return this._generator.enabled; }, set(enabled) { - self.enabled = enabled; + this._generator.enabled = enabled; } - }); + } +}); + +const createStyler = (open, close, parent) => { + let openAll; + let closeAll; + if (parent === undefined) { + openAll = open; + closeAll = close; + } else { + openAll = parent.openAll + open; + closeAll = close + parent.closeAll; + } + + return { + open, + close, + openAll, + closeAll, + parent + }; +}; + +const createBuilder = (self, _styler, _isEmpty) => { + const builder = (...arguments_) => { + // Single argument is hot path, implicit coercion is faster than anything + // eslint-disable-next-line no-implicit-coercion + return applyStyle(builder, (arguments_.length === 1) ? ('' + arguments_[0]) : arguments_.join(' ')); + }; // `__proto__` is used because we must return a function, but there is // no way to create a function with a different prototype builder.__proto__ = proto; // eslint-disable-line no-proto + builder._generator = self; + builder._styler = _styler; + builder._isEmpty = _isEmpty; + return builder; }; -const applyStyle = (self, ...arguments_) => { - let string = arguments_.join(' '); - +const applyStyle = (self, string) => { if (!self.enabled || self.level <= 0 || !string) { return self._isEmpty ? '' : string; } - for (const code of self._styles.slice().reverse()) { - // 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; + let styler = self._styler; - // 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}`); + if (styler === undefined) { + return string; } - return string; + const {openAll, closeAll} = styler; + if (string.indexOf('\u001B') !== -1) { + while (styler !== undefined) { + // 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 = stringReplaceAll(string, styler.close, styler.open); + + styler = styler.parent; + } + } + + // We can move both next actions out of loop, because remaining actions in loop won't have any/visible effect on parts we add here + // 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 + const lfIndex = string.indexOf('\n'); + if (lfIndex !== -1) { + string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); + } + + return openAll + string + closeAll; }; const chalkTag = (chalk, ...strings) => { diff --git a/lib/util.js b/lib/util.js new file mode 100644 index 0000000..8ce1166 --- /dev/null +++ b/lib/util.js @@ -0,0 +1,37 @@ +const stringReplaceAll = (string, substring, replacer) => { + let index = string.indexOf(substring); + if (index === -1) { + return string; + } + + const subLen = substring.length; + let end = 0; + let res = ''; + do { + res += string.substr(end, index - end) + replacer; + end = index + subLen; + index = string.indexOf(substring, end); + } while (index !== -1); + + res += string.substr(end); + return res; +}; + +const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { + let end = 0; + let res = ''; + do { + const gotCR = string[index - 1] === '\r'; + res += string.substr(end, (gotCR ? index - 1 : index) - end) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + end = index + 1; + index = string.indexOf('\n', end); + } while (index !== -1); + + res += string.substr(end); + return res; +}; + +module.exports = { + stringReplaceAll, + stringEncaseCRLFWithFirstIndex +}; diff --git a/package.json b/package.json index b18d8a3..48712eb 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,6 @@ ], "dependencies": { "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", "supports-color": "^6.1.0" }, "devDependencies": { diff --git a/test/chalk.js b/test/chalk.js index 240f0f9..3f90ba6 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -82,6 +82,10 @@ test('line breaks should open and close colors', t => { t.is(chalk.grey('hello\nworld'), '\u001B[90mhello\u001B[39m\n\u001B[90mworld\u001B[39m'); }); +test('line breaks should open and close colors with CRLF', t => { + t.is(chalk.grey('hello\r\nworld'), '\u001B[90mhello\u001B[39m\r\n\u001B[90mworld\u001B[39m'); +}); + test('properly convert RGB to 16 colors on basic color terminals', t => { t.is(new chalk.Instance({level: 1}).hex('#FF0000')('hello'), '\u001B[91mhello\u001B[39m'); t.is(new chalk.Instance({level: 1}).bgHex('#FF0000')('hello'), '\u001B[101mhello\u001B[49m'); From af4a0782458e212aa858a858c55f3878fcbbd75b Mon Sep 17 00:00:00 2001 From: Boris K Date: Fri, 12 Jul 2019 09:11:25 +0200 Subject: [PATCH 072/170] Update docs for `FORCE_COLOR` environment variable (#315) --- readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/readme.md b/readme.md index 78af5ae..d403085 100644 --- a/readme.md +++ b/readme.md @@ -151,7 +151,7 @@ Levels are as follows: Detect whether the terminal [supports color](https://github.com/chalk/supports-color). Used internally and handled for you, but exposed for convenience. -Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, add the environment variable `FORCE_COLOR=1` to forcefully enable color or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. +Can be overridden by the user with the flags `--color` and `--no-color`. For situations where using `--color` is not possible, use the environment variable `FORCE_COLOR=1` (level 1), `FORCE_COLOR=2` (level 2), or `FORCE_COLOR=3` (level 3) to forcefully enable color, or `FORCE_COLOR=0` to forcefully disable. The use of `FORCE_COLOR` overrides all other color support checks. Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. From 655653bb0c88fb05f839d5027f79751449771ec4 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 12 Jul 2019 13:51:07 +0700 Subject: [PATCH 073/170] Meta tweaks --- index.d.ts | 2 ++ package.json | 5 ++--- readme.md | 4 ++-- index.js => source/index.js | 5 ++--- templates.js => source/templates.js | 0 {lib => source}/util.js | 2 ++ test/_fixture.js | 2 +- test/chalk.js | 2 +- test/constructor.js | 2 +- test/enabled.js | 2 +- test/instance.js | 2 +- test/level.js | 2 +- test/no-color-support.js | 2 +- test/template-literal.js | 2 +- test/visible.js | 2 +- tsconfig.json | 7 ------- 16 files changed, 19 insertions(+), 24 deletions(-) rename index.js => source/index.js (98%) rename templates.js => source/templates.js (100%) rename {lib => source}/util.js (98%) delete mode 100644 tsconfig.json diff --git a/index.d.ts b/index.d.ts index 0f5d885..9ccc725 100644 --- a/index.d.ts +++ b/index.d.ts @@ -78,6 +78,8 @@ declare namespace chalk { @example ``` + import chalk = require('chalk'); + log(chalk` CPU: {red ${cpu.totalPercent}%} RAM: {green ${ram.used / ram.total * 100}%} diff --git a/package.json b/package.json index 48712eb..764bcbf 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", + "main": "source", "engines": { "node": ">=8" }, @@ -12,8 +13,7 @@ "bench": "matcha benchmark.js" }, "files": [ - "index.js", - "templates.js", + "source", "index.d.ts" ], "keywords": [ @@ -44,7 +44,6 @@ "supports-color": "^6.1.0" }, "devDependencies": { - "@sindresorhus/tsconfig": "^0.3.0", "ava": "^1.4.1", "coveralls": "^3.0.3", "execa": "^1.0.0", diff --git a/readme.md b/readme.md index d403085..d99b712 100644 --- a/readme.md +++ b/readme.md @@ -220,8 +220,8 @@ const miles = 18; const calculateFeet = miles => miles * 5280; console.log(chalk` - There are {bold 5280 feet} in a mile. - In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}. + There are {bold 5280 feet} in a mile. + In {bold ${miles} miles}, there are {green.bold ${calculateFeet(miles)} feet}. `); ``` diff --git a/index.js b/source/index.js similarity index 98% rename from index.js rename to source/index.js index 21d3a83..0519720 100644 --- a/index.js +++ b/source/index.js @@ -1,12 +1,11 @@ 'use strict'; const ansiStyles = require('ansi-styles'); const {stdout: stdoutColor} = require('supports-color'); -const template = require('./templates.js'); - +const template = require('./templates'); const { stringReplaceAll, stringEncaseCRLFWithFirstIndex -} = require('./lib/util'); +} = require('./util'); // `supportsColor.level` → `ansiStyles.color[name]` mapping const levelMapping = [ diff --git a/templates.js b/source/templates.js similarity index 100% rename from templates.js rename to source/templates.js diff --git a/lib/util.js b/source/util.js similarity index 98% rename from lib/util.js rename to source/util.js index 8ce1166..aaf3d79 100644 --- a/lib/util.js +++ b/source/util.js @@ -1,3 +1,5 @@ +'use strict'; + const stringReplaceAll = (string, substring, replacer) => { let index = string.indexOf(substring); if (index === -1) { diff --git a/test/_fixture.js b/test/_fixture.js index 5f1771d..214a86c 100644 --- a/test/_fixture.js +++ b/test/_fixture.js @@ -1,4 +1,4 @@ 'use strict'; -const chalk = require('..'); +const chalk = require('../source'); console.log(chalk.hex('#ff6159')('test')); diff --git a/test/chalk.js b/test/chalk.js index 3f90ba6..92091cb 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -3,7 +3,7 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const chalk = require('..'); +const chalk = require('../source'); console.log('TERM:', process.env.TERM || '[none]'); console.log('platform:', process.platform || '[unknown]'); diff --git a/test/constructor.js b/test/constructor.js index 188001a..f4e9ca1 100644 --- a/test/constructor.js +++ b/test/constructor.js @@ -1,6 +1,6 @@ import test from 'ava'; -const chalk = require('..'); +const chalk = require('../source'); test('Chalk.constructor should throw an expected error', t => { const expectedError = t.throws(() => { diff --git a/test/enabled.js b/test/enabled.js index e596621..3d9c55f 100644 --- a/test/enabled.js +++ b/test/enabled.js @@ -3,7 +3,7 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const chalk = require('..'); +const chalk = require('../source'); test('don\'t output colors when manually disabled', t => { chalk.enabled = false; diff --git a/test/instance.js b/test/instance.js index e34bea7..8d2c4e1 100644 --- a/test/instance.js +++ b/test/instance.js @@ -3,7 +3,7 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const chalk = require('..'); +const chalk = require('../source'); test('create an isolated context where colors can be disabled (by level)', t => { const instance = new chalk.Instance({level: 0, enabled: true}); diff --git a/test/level.js b/test/level.js index 06fdb59..36df016 100644 --- a/test/level.js +++ b/test/level.js @@ -5,7 +5,7 @@ import execa from 'execa'; // Spoof supports-color require('./_supports-color')(__dirname); -const chalk = require('..'); +const chalk = require('../source'); test('don\'t output colors when manually disabled', t => { const oldLevel = chalk.level; diff --git a/test/no-color-support.js b/test/no-color-support.js index 90d934d..dae9bda 100644 --- a/test/no-color-support.js +++ b/test/no-color-support.js @@ -8,7 +8,7 @@ require('./_supports-color')(__dirname, { has16m: false }); -const chalk = require('..'); +const chalk = require('../source'); test.failing('colors can be forced by using chalk.enabled', t => { chalk.enabled = true; diff --git a/test/template-literal.js b/test/template-literal.js index ae4a0bc..ece1428 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -4,7 +4,7 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const chalk = require('..'); +const chalk = require('../source'); test('return an empty string for an empty literal', t => { const instance = new chalk.Instance(); diff --git a/test/visible.js b/test/visible.js index 01eb087..14ecc3c 100644 --- a/test/visible.js +++ b/test/visible.js @@ -3,7 +3,7 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname); -const chalk = require('..'); +const chalk = require('../source'); test('visible: normal output when enabled', t => { const instance = new chalk.Instance({level: 3, enabled: true}); diff --git a/tsconfig.json b/tsconfig.json deleted file mode 100644 index 3d73ee9..0000000 --- a/tsconfig.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "extends": "@sindresorhus/tsconfig", - "compilerOptions": { - "noEmit": true, - "allowJs": true - } -} From c25c32a25f4315c1f7ee21cc7b36b497c4f0212a Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 12 Jul 2019 13:59:50 +0700 Subject: [PATCH 074/170] Update dependencies --- index.d.ts | 20 ++++++++++++++++++++ package.json | 16 ++++++++-------- readme.md | 6 ++++-- source/index.js | 7 +++---- source/util.js | 30 +++++++++++++++--------------- test/chalk.js | 4 ++++ test/level.js | 3 ++- 7 files changed, 56 insertions(+), 30 deletions(-) diff --git a/index.d.ts b/index.d.ts index 9ccc725..455ba9a 100644 --- a/index.d.ts +++ b/index.d.ts @@ -261,8 +261,17 @@ declare namespace chalk { readonly magenta: Chalk; readonly cyan: Chalk; readonly white: Chalk; + + /* + Alias for `blackBright`. + */ readonly gray: Chalk; + + /* + Alias for `blackBright`. + */ readonly grey: Chalk; + readonly blackBright: Chalk; readonly redBright: Chalk; readonly greenBright: Chalk; @@ -280,6 +289,17 @@ declare namespace chalk { readonly bgMagenta: Chalk; readonly bgCyan: Chalk; readonly bgWhite: Chalk; + + /* + Alias for `bgBlackBright`. + */ + readonly bgGray: Chalk; + + /* + Alias for `bgBlackBright`. + */ + readonly bgGrey: Chalk; + readonly bgBlackBright: Chalk; readonly bgRedBright: Chalk; readonly bgGreenBright: Chalk; diff --git a/package.json b/package.json index 764bcbf..b6cbdd4 100644 --- a/package.json +++ b/package.json @@ -40,18 +40,18 @@ "text" ], "dependencies": { - "ansi-styles": "^3.2.1", - "supports-color": "^6.1.0" + "ansi-styles": "^4.0.0", + "supports-color": "^7.0.0" }, "devDependencies": { - "ava": "^1.4.1", - "coveralls": "^3.0.3", - "execa": "^1.0.0", - "import-fresh": "^3.0.0", + "ava": "^2.2.0", + "coveralls": "^3.0.5", + "execa": "^2.0.3", + "import-fresh": "^3.1.0", "matcha": "^0.7.0", - "nyc": "^14.0.0", + "nyc": "^14.1.1", "resolve-from": "^5.0.0", - "tsd": "^0.7.2", + "tsd": "^0.7.4", "xo": "^0.24.0" } } diff --git a/readme.md b/readme.md index d99b712..ede4ee1 100644 --- a/readme.md +++ b/readme.md @@ -13,6 +13,8 @@ +**This readme reflects the next major version that is currently in development. You probably want [the v2 readme](https://www.npmjs.com/package/chalk).** + ## Highlights @@ -180,7 +182,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= - `magenta` - `cyan` - `white` -- `gray` ("bright black") +- `blackBright` (alias: `gray`, `grey`) - `redBright` - `greenBright` - `yellowBright` @@ -199,7 +201,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= - `bgMagenta` - `bgCyan` - `bgWhite` -- `bgBlackBright` +- `bgBlackBright` (alias: `bgGray`, `bgGrey`) - `bgRedBright` - `bgGreenBright` - `bgYellowBright` diff --git a/source/index.js b/source/index.js index 0519720..e8d47c2 100644 --- a/source/index.js +++ b/source/index.js @@ -193,10 +193,9 @@ const applyStyle = (self, string) => { } } - // We can move both next actions out of loop, because remaining actions in loop won't have any/visible effect on parts we add here - // 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 + // We can move both next actions out of loop, because remaining actions in loop won't have + // any/visible effect on parts we add here. 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 const lfIndex = string.indexOf('\n'); if (lfIndex !== -1) { string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex); diff --git a/source/util.js b/source/util.js index aaf3d79..d617156 100644 --- a/source/util.js +++ b/source/util.js @@ -6,31 +6,31 @@ const stringReplaceAll = (string, substring, replacer) => { return string; } - const subLen = substring.length; - let end = 0; - let res = ''; + const substringLength = substring.length; + let endIndex = 0; + let returnValue = ''; do { - res += string.substr(end, index - end) + replacer; - end = index + subLen; - index = string.indexOf(substring, end); + returnValue += string.substr(endIndex, index - endIndex) + replacer; + endIndex = index + substringLength; + index = string.indexOf(substring, endIndex); } while (index !== -1); - res += string.substr(end); - return res; + returnValue += string.substr(endIndex); + return returnValue; }; const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { - let end = 0; - let res = ''; + let endIndex = 0; + let returnValue = ''; do { const gotCR = string[index - 1] === '\r'; - res += string.substr(end, (gotCR ? index - 1 : index) - end) + prefix + (gotCR ? '\r\n' : '\n') + postfix; - end = index + 1; - index = string.indexOf('\n', end); + returnValue += string.substr(endIndex, (gotCR ? index - 1 : index) - endIndex) + prefix + (gotCR ? '\r\n' : '\n') + postfix; + endIndex = index + 1; + index = string.indexOf('\n', endIndex); } while (index !== -1); - res += string.substr(end); - return res; + returnValue += string.substr(endIndex); + return returnValue; }; module.exports = { diff --git a/test/chalk.js b/test/chalk.js index 92091cb..008a128 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -101,3 +101,7 @@ test('don\'t emit RGB codes if level is 0', t => { t.is(new chalk.Instance({level: 0}).hex('#FF0000')('hello'), 'hello'); t.is(new chalk.Instance({level: 0}).bgHex('#FF0000')('hello'), 'hello'); }); + +test('supports blackBright color', t => { + t.is(chalk.blackBright('foo'), '\u001B[90mfoo\u001B[39m'); +}); diff --git a/test/level.js b/test/level.js index 36df016..bb6df47 100644 --- a/test/level.js +++ b/test/level.js @@ -40,5 +40,6 @@ test('propagate enable/disable changes from child colors', t => { }); test('disable colors if they are not supported', async t => { - t.is(await execa.stdout('node', [path.join(__dirname, '_fixture')]), 'test'); + const {stdout} = await execa.node(path.join(__dirname, '_fixture')); + t.is(stdout, 'test'); }); From 87156ce8e2696a6002a51fbd1168e43eb9c70ce4 Mon Sep 17 00:00:00 2001 From: Ahad Birang Date: Fri, 12 Jul 2019 23:19:56 +0430 Subject: [PATCH 075/170] Fix support for nested styles (#335) --- source/util.js | 2 +- test/chalk.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/util.js b/source/util.js index d617156..ca466fd 100644 --- a/source/util.js +++ b/source/util.js @@ -10,7 +10,7 @@ const stringReplaceAll = (string, substring, replacer) => { let endIndex = 0; let returnValue = ''; do { - returnValue += string.substr(endIndex, index - endIndex) + replacer; + returnValue += string.substr(endIndex, index - endIndex) + substring + replacer; endIndex = index + substringLength; index = string.indexOf(substring, endIndex); } while (index !== -1); diff --git a/test/chalk.js b/test/chalk.js index 008a128..2992a09 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -37,7 +37,7 @@ test('support nesting styles', t => { test('support nesting styles of the same type (color, underline, bg)', t => { t.is( chalk.red('a' + chalk.yellow('b' + chalk.green('c') + 'b') + 'c'), - '\u001B[31ma\u001B[33mb\u001B[32mc\u001B[33mb\u001B[31mc\u001B[39m' + '\u001B[31ma\u001B[33mb\u001B[32mc\u001B[39m\u001B[31m\u001B[33mb\u001B[39m\u001B[31mc\u001B[39m' ); }); From 1f77953f1a358fa8f626f0fd872792d63da6d58a Mon Sep 17 00:00:00 2001 From: Qix Date: Sat, 13 Jul 2019 07:45:31 +0200 Subject: [PATCH 076/170] Remove the `.enabled` property in favor of `.level` (#356) --- index.d.ts | 16 +--------------- index.test-d.ts | 1 - readme.md | 18 ++++-------------- source/index.js | 12 +----------- test/enabled.js | 35 ----------------------------------- test/instance.js | 10 +--------- test/level.js | 2 +- test/no-color-support.js | 4 ++-- test/visible.js | 20 +++++++------------- 9 files changed, 17 insertions(+), 101 deletions(-) delete mode 100644 test/enabled.js diff --git a/index.d.ts b/index.d.ts index 455ba9a..58da80e 100644 --- a/index.d.ts +++ b/index.d.ts @@ -24,13 +24,6 @@ declare namespace chalk { type Level = LevelEnum; 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. @@ -98,13 +91,6 @@ declare namespace chalk { */ Instance: Instance; - /** - Enable or disable Chalk. - - @default true - */ - enabled: boolean; - /** The color support for Chalk. By default, color support is automatically detected based on the environment. @@ -248,7 +234,7 @@ declare namespace chalk { readonly strikethrough: Chalk; /** - Modifier: Prints the text only when Chalk is enabled. + Modifier: Prints the text only when Chalk has a color support level > 0. Can be useful for things that are purely cosmetic. */ readonly visible: Chalk; diff --git a/index.test-d.ts b/index.test-d.ts index fd19d04..5ab486d 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -24,7 +24,6 @@ expectError(chalk.reset.supportsColor); expectType(new chalk.Instance({level: 1})); // -- Properties -- -expectType(chalk.enabled); expectType(chalk.level); // -- Template literal -- diff --git a/readme.md b/readme.md index ede4ee1..0de3051 100644 --- a/readme.md +++ b/readme.md @@ -120,21 +120,11 @@ Chain [styles](#styles) and call the last one as a method with a string argument 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. - -Chalk is enabled by default unless explicitly disabled via `new chalk.Instance()` or `chalk.level` is `0`. - -If you need to change this in a reusable module, create a new instance: - -```js -const ctx = new chalk.Instance({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. +Specifies the level of color support. + +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: @@ -170,7 +160,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= - `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. +- `visible`- Prints the text only when Chalk has a color level > 0. Can be useful for things that are purely cosmetic. ### Colors diff --git a/source/index.js b/source/index.js index e8d47c2..9b4b46b 100644 --- a/source/index.js +++ b/source/index.js @@ -28,7 +28,6 @@ const applyOptions = (object, options = {}) => { // 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; }; class ChalkClass { @@ -120,15 +119,6 @@ const proto = Object.defineProperties(() => {}, { set(level) { this._generator.level = level; } - }, - enabled: { - enumerable: true, - get() { - return this._generator.enabled; - }, - set(enabled) { - this._generator.enabled = enabled; - } } }); @@ -171,7 +161,7 @@ const createBuilder = (self, _styler, _isEmpty) => { }; const applyStyle = (self, string) => { - if (!self.enabled || self.level <= 0 || !string) { + if (self.level <= 0 || !string) { return self._isEmpty ? '' : string; } diff --git a/test/enabled.js b/test/enabled.js deleted file mode 100644 index 3d9c55f..0000000 --- a/test/enabled.js +++ /dev/null @@ -1,35 +0,0 @@ -import test from 'ava'; - -// Spoof supports-color -require('./_supports-color')(__dirname); - -const chalk = require('../source'); - -test('don\'t output colors when manually disabled', t => { - chalk.enabled = false; - t.is(chalk.red('foo'), 'foo'); - chalk.enabled = true; -}); - -test('enable/disable colors based on overall chalk enabled property, not individual instances', t => { - chalk.enabled = false; - const {red} = chalk; - t.false(red.enabled); - chalk.enabled = true; - t.true(red.enabled); - chalk.enabled = true; -}); - -test('propagate enable/disable changes from child colors', t => { - chalk.enabled = false; - const {red} = chalk; - t.false(red.enabled); - t.false(chalk.enabled); - red.enabled = true; - t.true(red.enabled); - t.true(chalk.enabled); - chalk.enabled = false; - t.false(red.enabled); - t.false(chalk.enabled); - chalk.enabled = true; -}); diff --git a/test/instance.js b/test/instance.js index 8d2c4e1..e936333 100644 --- a/test/instance.js +++ b/test/instance.js @@ -6,21 +6,13 @@ require('./_supports-color')(__dirname); const chalk = require('../source'); test('create an isolated context where colors can be disabled (by level)', t => { - const instance = new chalk.Instance({level: 0, enabled: true}); + const instance = new chalk.Instance({level: 0}); t.is(instance.red('foo'), 'foo'); t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); instance.level = 2; t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); }); -test('create an isolated context where colors can be disabled (by enabled flag)', t => { - const instance = new chalk.Instance({enabled: false}); - t.is(instance.red('foo'), 'foo'); - t.is(chalk.red('foo'), '\u001B[31mfoo\u001B[39m'); - instance.enabled = true; - t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); -}); - test('the `level` option should be a number from 0 to 3', t => { /* eslint-disable no-new */ t.throws(() => { diff --git a/test/level.js b/test/level.js index bb6df47..828de24 100644 --- a/test/level.js +++ b/test/level.js @@ -14,7 +14,7 @@ test('don\'t output colors when manually disabled', t => { chalk.level = oldLevel; }); -test('enable/disable colors based on overall chalk enabled property, not individual instances', t => { +test('enable/disable colors based on overall chalk .level property, not individual instances', t => { const oldLevel = chalk.level; chalk.level = 1; const {red} = chalk; diff --git a/test/no-color-support.js b/test/no-color-support.js index dae9bda..7318452 100644 --- a/test/no-color-support.js +++ b/test/no-color-support.js @@ -10,7 +10,7 @@ require('./_supports-color')(__dirname, { const chalk = require('../source'); -test.failing('colors can be forced by using chalk.enabled', t => { - chalk.enabled = true; +test('colors can be forced by using chalk.level', t => { + chalk.level = 1; t.is(chalk.green('hello'), '\u001B[32mhello\u001B[39m'); }); diff --git a/test/visible.js b/test/visible.js index 14ecc3c..7987712 100644 --- a/test/visible.js +++ b/test/visible.js @@ -5,40 +5,34 @@ require('./_supports-color')(__dirname); const chalk = require('../source'); -test('visible: normal output when enabled', t => { - const instance = new chalk.Instance({level: 3, enabled: true}); +test('visible: normal output when level > 0', t => { + const instance = new chalk.Instance({level: 3}); t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); }); -test('visible: no output when disabled', t => { - const instance = new chalk.Instance({level: 3, enabled: false}); - t.is(instance.red.visible('foo'), ''); - t.is(instance.visible.red('foo'), ''); -}); - test('visible: no output when level is too low', t => { - const instance = new chalk.Instance({level: 0, enabled: true}); + const instance = new chalk.Instance({level: 0}); t.is(instance.visible.red('foo'), ''); t.is(instance.red.visible('foo'), ''); }); -test('test switching back and forth between enabled and disabled', t => { - const instance = new chalk.Instance({level: 3, enabled: true}); +test('test switching back and forth between level == 0 and level > 0', t => { + const instance = new chalk.Instance({level: 3}); t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.visible('foo'), 'foo'); t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); - instance.enabled = false; + instance.level = 0; t.is(instance.red('foo'), 'foo'); t.is(instance.visible('foo'), ''); t.is(instance.visible.red('foo'), ''); t.is(instance.red.visible('foo'), ''); t.is(instance.red('foo'), 'foo'); - instance.enabled = true; + instance.level = 3; t.is(instance.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.visible.red('foo'), '\u001B[31mfoo\u001B[39m'); t.is(instance.red.visible('foo'), '\u001B[31mfoo\u001B[39m'); From 6b4d20683f7490195e51f80829f3d465b9835de1 Mon Sep 17 00:00:00 2001 From: Simen Bekkhus Date: Thu, 22 Aug 2019 15:28:25 +0200 Subject: [PATCH 077/170] Export TypeScript types for colors and modifiers (#357) Co-authored-by: Sindre Sorhus --- index.d.ts | 72 +++++++++++++++++++++++++++++++++++++++++++++++++ index.test-d.ts | 4 +++ 2 files changed, 76 insertions(+) diff --git a/index.d.ts b/index.d.ts index 58da80e..c650eb9 100644 --- a/index.d.ts +++ b/index.d.ts @@ -20,6 +20,74 @@ declare const enum LevelEnum { TrueColor = 3 } +/** +Basic foreground colors. + +[More colors here.](https://github.com/chalk/chalk/blob/master/readme.md#256-and-truecolor-color-support) +*/ +declare type ForegroundColor = + | 'black' + | 'red' + | 'green' + | 'yellow' + | 'blue' + | 'magenta' + | 'cyan' + | 'white' + | 'gray' + | 'grey' + | 'blackBright' + | 'redBright' + | 'greenBright' + | 'yellowBright' + | 'blueBright' + | 'magentaBright' + | 'cyanBright' + | 'whiteBright'; + +/** +Basic background colors. + +[More colors here.](https://github.com/chalk/chalk/blob/master/readme.md#256-and-truecolor-color-support) +*/ +declare type BackgroundColor = + | 'bgBlack' + | 'bgRed' + | 'bgGreen' + | 'bgYellow' + | 'bgBlue' + | 'bgMagenta' + | 'bgCyan' + | 'bgWhite' + | 'bgGray' + | 'bgGrey' + | 'bgBlackBright' + | 'bgRedBright' + | 'bgGreenBright' + | 'bgYellowBright' + | 'bgBlueBright' + | 'bgMagentaBright' + | 'bgCyanBright' + | 'bgWhiteBright'; + +/** +Basic colors. + +[More colors here.](https://github.com/chalk/chalk/blob/master/readme.md#256-and-truecolor-color-support) +*/ +declare type Color = ForegroundColor | BackgroundColor; + +declare type Modifiers = + | 'reset' + | 'bold' + | 'dim' + | 'italic' + | 'underline' + | 'inverse' + | 'hidden' + | 'strikethrough' + | 'visible'; + declare namespace chalk { type Level = LevelEnum; @@ -306,6 +374,10 @@ This simply means that `chalk.red.yellow.green` is equivalent to `chalk.green`. declare const chalk: chalk.Chalk & chalk.ChalkFunction & { supportsColor: chalk.ColorSupport | false; Level: typeof LevelEnum; + Color: Color; + ForegroundColor: ForegroundColor; + BackgroundColor: BackgroundColor; + Modifiers: Modifiers; }; export = chalk; diff --git a/index.test-d.ts b/index.test-d.ts index 5ab486d..1d2df98 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -139,3 +139,7 @@ expectType(chalk.bgWhiteBright`foo`); // -- Complex -- expectType(chalk.red.bgGreen.underline('foo')); expectType(chalk.underline.red.bgGreen('foo')); + +// -- Color types == +expectType('red'); +expectError('hotpink'); From 2a53389d72cf46dbb9d73ab730d99e15cb230c7f Mon Sep 17 00:00:00 2001 From: Yanis Benson Date: Sun, 22 Sep 2019 12:07:33 +0300 Subject: [PATCH 078/170] Add `chalk.stderr` (#359) --- index.d.ts | 1 + index.test-d.ts | 10 ++++++++++ readme.md | 4 ++++ source/index.js | 10 +++++++--- test/_fixture.js | 2 +- test/_supports-color.js | 6 ++++++ test/chalk.js | 5 +++++ test/level.js | 2 +- test/no-color-support.js | 16 ++++++++++++---- 9 files changed, 47 insertions(+), 9 deletions(-) diff --git a/index.d.ts b/index.d.ts index c650eb9..52dd5ae 100644 --- a/index.d.ts +++ b/index.d.ts @@ -378,6 +378,7 @@ declare const chalk: chalk.Chalk & chalk.ChalkFunction & { ForegroundColor: ForegroundColor; BackgroundColor: BackgroundColor; Modifiers: Modifiers; + stderr: chalk.Chalk & {supportsColor: chalk.ColorSupport | false}; }; export = chalk; diff --git a/index.test-d.ts b/index.test-d.ts index 1d2df98..bc3d17a 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -16,6 +16,16 @@ expectType((chalk.supportsColor as chalk.ColorSupport).hasBasic); expectType((chalk.supportsColor as chalk.ColorSupport).has256); expectType((chalk.supportsColor as chalk.ColorSupport).has16m); +// - stderr - +expectType(chalk.stderr); +expectType(chalk.stderr.supportsColor); +expectType((chalk.stderr.supportsColor as chalk.ColorSupport).hasBasic); +expectType((chalk.stderr.supportsColor as chalk.ColorSupport).has256); +expectType((chalk.stderr.supportsColor as chalk.ColorSupport).has16m); + +// -- `stderr` is not a member of the Chalk interface -- +expectError(chalk.reset.stderr); + // -- `supportsColor` is not a member of the Chalk interface -- expectError(chalk.reset.supportsColor); diff --git a/readme.md b/readme.md index 0de3051..aaa8b47 100644 --- a/readme.md +++ b/readme.md @@ -147,6 +147,10 @@ Can be overridden by the user with the flags `--color` and `--no-color`. For sit Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color=16m` flags, respectively. +### chalk.stderr and chalk.stderr.supportsColor + +`chalk.stderr` contains a separate instance configured with color support detected for `stderr` stream instead of `stdout`. Override rules from `chalk.supportsColor` apply to this too. `chalk.stderr.supportsColor` is exposed for convenience. + ## Styles diff --git a/source/index.js b/source/index.js index 9b4b46b..686758b 100644 --- a/source/index.js +++ b/source/index.js @@ -1,6 +1,6 @@ 'use strict'; const ansiStyles = require('ansi-styles'); -const {stdout: stdoutColor} = require('supports-color'); +const {stdout: stdoutColor, stderr: stderrColor} = require('supports-color'); const template = require('./templates'); const { stringReplaceAll, @@ -218,5 +218,9 @@ const chalkTag = (chalk, ...strings) => { Object.defineProperties(Chalk.prototype, styles); -module.exports = Chalk(); // eslint-disable-line new-cap -module.exports.supportsColor = stdoutColor; +const chalk = Chalk(); // eslint-disable-line new-cap +chalk.supportsColor = stdoutColor; +chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap +chalk.stderr.supportsColor = stderrColor; + +module.exports = chalk; diff --git a/test/_fixture.js b/test/_fixture.js index 214a86c..29f34b0 100644 --- a/test/_fixture.js +++ b/test/_fixture.js @@ -1,4 +1,4 @@ 'use strict'; const chalk = require('../source'); -console.log(chalk.hex('#ff6159')('test')); +console.log(`${chalk.hex('#ff6159')('testout')} ${chalk.stderr.hex('#ff6159')('testerr')}`); diff --git a/test/_supports-color.js b/test/_supports-color.js index 490c323..b5c0f78 100644 --- a/test/_supports-color.js +++ b/test/_supports-color.js @@ -7,6 +7,12 @@ const DEFAULT = { hasBasic: true, has256: true, has16m: true + }, + stderr: { + level: 3, + hasBasic: true, + has256: true, + has16m: true } }; diff --git a/test/chalk.js b/test/chalk.js index 2992a09..5e33f5e 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -105,3 +105,8 @@ test('don\'t emit RGB codes if level is 0', t => { test('supports blackBright color', t => { t.is(chalk.blackBright('foo'), '\u001B[90mfoo\u001B[39m'); }); + +test('sets correct level for chalk.stderr and respects it', t => { + t.is(chalk.stderr.level, 3); + t.is(chalk.stderr.red.bold('foo'), '\u001B[31m\u001B[1mfoo\u001B[22m\u001B[39m'); +}); diff --git a/test/level.js b/test/level.js index 828de24..65d4720 100644 --- a/test/level.js +++ b/test/level.js @@ -41,5 +41,5 @@ test('propagate enable/disable changes from child colors', t => { test('disable colors if they are not supported', async t => { const {stdout} = await execa.node(path.join(__dirname, '_fixture')); - t.is(stdout, 'test'); + t.is(stdout, 'testout testerr'); }); diff --git a/test/no-color-support.js b/test/no-color-support.js index 7318452..ae88ac9 100644 --- a/test/no-color-support.js +++ b/test/no-color-support.js @@ -2,10 +2,18 @@ import test from 'ava'; // Spoof supports-color require('./_supports-color')(__dirname, { - level: 0, - hasBasic: false, - has256: false, - has16m: false + stdout: { + level: 0, + hasBasic: false, + has256: false, + has16m: false + }, + stderr: { + level: 0, + hasBasic: false, + has256: false, + has16m: false + } }); const chalk = require('../source'); From 4e65299e7bc54949d00ec0c963daf08635d83bc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kh=E1=BA=A3i?= Date: Fri, 27 Sep 2019 10:53:54 +0700 Subject: [PATCH 079/170] Fix const enum for TypeScript (#364) --- source/index.js | 12 ++++++++++++ test/level.js | 12 ++++++++++++ 2 files changed, 24 insertions(+) diff --git a/source/index.js b/source/index.js index 686758b..6fee0f8 100644 --- a/source/index.js +++ b/source/index.js @@ -223,4 +223,16 @@ chalk.supportsColor = stdoutColor; chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap chalk.stderr.supportsColor = stderrColor; +// For TypeScript +chalk.Level = { + None: 0, + Basic: 1, + Ansi256: 2, + TrueColor: 3, + 0: 'None', + 1: 'Basic', + 2: 'Ansi256', + 3: 'TrueColor' +}; + module.exports = chalk; diff --git a/test/level.js b/test/level.js index 65d4720..4fe8fae 100644 --- a/test/level.js +++ b/test/level.js @@ -43,3 +43,15 @@ test('disable colors if they are not supported', async t => { const {stdout} = await execa.node(path.join(__dirname, '_fixture')); t.is(stdout, 'testout testerr'); }); + +test('chalk.Level enum object', t => { + const {Level} = chalk; + t.is(Level.None, 0); + t.is(Level.Basic, 1); + t.is(Level.Ansi256, 2); + t.is(Level.TrueColor, 3); + t.is(Level[Level.None], 'None'); + t.is(Level[Level.Basic], 'Basic'); + t.is(Level[Level.Ansi256], 'Ansi256'); + t.is(Level[Level.TrueColor], 'TrueColor'); +}); From 61aca7cb768cc4e3bc5d11abbad32377c72e1ff3 Mon Sep 17 00:00:00 2001 From: Yanis Benson Date: Fri, 27 Sep 2019 06:55:19 +0300 Subject: [PATCH 080/170] Improve require speed (#358) --- source/index.js | 21 ++++++++------------- 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/source/index.js b/source/index.js index 6fee0f8..53fcc16 100644 --- a/source/index.js +++ b/source/index.js @@ -1,7 +1,6 @@ 'use strict'; const ansiStyles = require('ansi-styles'); const {stdout: stdoutColor, stderr: stderrColor} = require('supports-color'); -const template = require('./templates'); const { stringReplaceAll, stringEncaseCRLFWithFirstIndex @@ -15,9 +14,6 @@ const levelMapping = [ 'ansi16m' ]; -// `color-convert` models to exclude from the Chalk API due to conflicts and such -const skipModels = new Set(['gray']); - const styles = Object.create(null); const applyOptions = (object, options = {}) => { @@ -76,11 +72,9 @@ styles.visible = { } }; -for (const model of Object.keys(ansiStyles.color.ansi)) { - if (skipModels.has(model)) { - continue; - } +const usedModels = ['rgb', 'hex', 'keyword', 'hsl', 'hsv', 'hwb', 'ansi', 'ansi256']; +for (const model of usedModels) { styles[model] = { get() { const {level} = this; @@ -92,11 +86,7 @@ for (const model of Object.keys(ansiStyles.color.ansi)) { }; } -for (const model of Object.keys(ansiStyles.bgColor.ansi)) { - if (skipModels.has(model)) { - continue; - } - +for (const model of usedModels) { const bgModel = 'bg' + model[0].toUpperCase() + model.slice(1); styles[bgModel] = { get() { @@ -194,6 +184,7 @@ const applyStyle = (self, string) => { return openAll + string + closeAll; }; +let template; const chalkTag = (chalk, ...strings) => { const [firstString] = strings; @@ -213,6 +204,10 @@ const chalkTag = (chalk, ...strings) => { ); } + if (template === undefined) { + template = require('./templates'); + } + return template(chalk, parts.join('')); }; From 1953816afd7d36e0a6751331a0441822477313b8 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 27 Sep 2019 11:16:49 +0700 Subject: [PATCH 081/170] Update dependencies --- package.json | 14 ++++++++++---- readme.md | 4 ++-- test/chalk.js | 2 +- 3 files changed, 13 insertions(+), 7 deletions(-) diff --git a/package.json b/package.json index b6cbdd4..b6ebb06 100644 --- a/package.json +++ b/package.json @@ -40,11 +40,11 @@ "text" ], "dependencies": { - "ansi-styles": "^4.0.0", - "supports-color": "^7.0.0" + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" }, "devDependencies": { - "ava": "^2.2.0", + "ava": "^2.4.0", "coveralls": "^3.0.5", "execa": "^2.0.3", "import-fresh": "^3.1.0", @@ -52,6 +52,12 @@ "nyc": "^14.1.1", "resolve-from": "^5.0.0", "tsd": "^0.7.4", - "xo": "^0.24.0" + "xo": "^0.25.3" + }, + "xo": { + "rules": { + "unicorn/prefer-string-slice": "off", + "unicorn/prefer-includes": "off" + } } } diff --git a/readme.md b/readme.md index aaa8b47..4a3b646 100644 --- a/readme.md +++ b/readme.md @@ -26,7 +26,7 @@ - Doesn't extend `String.prototype` - Clean and focused - Actively maintained -- [Used by ~40,000 packages](https://www.npmjs.com/browse/depended/chalk) as of March 1, 2019 +- [Used by ~46,000 packages](https://www.npmjs.com/browse/depended/chalk) as of October 1, 2019 ## Install @@ -267,7 +267,7 @@ The following color models can be used: ## Windows -If you're on Windows, do yourself a favor and use [`cmder`](http://cmder.net/) instead of `cmd.exe`. +If you're on Windows, do yourself a favor and use [Windows Terminal](https://github.com/microsoft/terminal) instead of `cmd.exe`. ## Origin story diff --git a/test/chalk.js b/test/chalk.js index 5e33f5e..21f0346 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -73,7 +73,7 @@ test('don\'t output escape codes if the input is empty', t => { }); test('keep Function.prototype methods', t => { - t.is(chalk.grey.apply(null, ['foo']), '\u001B[90mfoo\u001B[39m'); + t.is(Reflect.apply(chalk.grey, null, ['foo']), '\u001B[90mfoo\u001B[39m'); t.is(chalk.reset(chalk.red.bgGreen.underline.bind(null)('foo') + 'foo'), '\u001B[0m\u001B[31m\u001B[42m\u001B[4mfoo\u001B[24m\u001B[49m\u001B[39mfoo\u001B[0m'); t.is(chalk.red.blue.black.call(null), ''); }); From 48905d08052aad4c8ba53bbd9fbcd8a9faf4f6e5 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 27 Sep 2019 12:07:07 +0700 Subject: [PATCH 082/170] 3.0.0-beta.1 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index b6ebb06..32ea3bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "2.4.1", + "version": "3.0.0-beta.1", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From eef8c8c191d25deecde8c472e10a37c6f736e2e9 Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Mon, 30 Sep 2019 21:13:15 -0400 Subject: [PATCH 083/170] Replace level list with table in readme.md (#367) * Replace level list with table in readme.md * Capitalize table headings and center level numbers --- readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 4a3b646..6e52c05 100644 --- a/readme.md +++ b/readme.md @@ -132,12 +132,12 @@ If you need to change this in a reusable module, create a new instance: const ctx = new chalk.Instance({level: 0}); ``` -Levels are as follows: - -0. All colors disabled -1. Basic color support (16 colors) -2. 256 color support -3. Truecolor support (16 million colors) +| Level | Description | +| :---: | :--- | +| `0` | All colors disabled | +| `1` | Basic color support (16 colors) | +| `2` | 256 color support | +| `3` | Truecolor support (16 million colors) | ### chalk.supportsColor From fb8e85ab875eb95b55448fd615daacf8c325cf44 Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Tue, 8 Oct 2019 05:02:34 -0400 Subject: [PATCH 084/170] Add `ansi256` and `bgAnsi256` to TypeScript declarations (#368) --- index.d.ts | 10 ++++++++++ index.test-d.ts | 2 ++ readme.md | 4 ++-- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/index.d.ts b/index.d.ts index 52dd5ae..c50c17e 100644 --- a/index.d.ts +++ b/index.d.ts @@ -213,6 +213,11 @@ declare namespace chalk { */ hwb(hue: number, whiteness: number, blackness: number): Chalk; + /** + Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color. + */ + ansi256(index: number): Chalk; + /** Use HEX value to set background color. @@ -261,6 +266,11 @@ declare namespace chalk { */ bgHwb(hue: number, whiteness: number, blackness: number): Chalk; + /** + Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color. + */ + bgAnsi256(index: number): Chalk; + /** Modifier: Resets the current color chain. */ diff --git a/index.test-d.ts b/index.test-d.ts index bc3d17a..dd3ba99 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -49,12 +49,14 @@ 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.ansi256(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)); +expectType(chalk.bgAnsi256(0)); // -- Modifiers -- expectType(chalk.reset('foo')); diff --git a/readme.md b/readme.md index 6e52c05..7322f2b 100644 --- a/readme.md +++ b/readme.md @@ -260,9 +260,9 @@ The following color models can be used: - [`keyword`](https://www.w3.org/wiki/CSS/Properties/color/keywords) (CSS keywords) - Example: `chalk.keyword('orange').bold('Orange!')` - [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')` - [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsv(32, 100, 100).bold('Orange!')` -- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hwb(32, 0, 50).bold('Orange!')` +- [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hwb(32, 0, 50).bold('Orange!')` - `ansi16` -- `ansi256` +- [`ansi256`](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) - Example: `chalk.bgAnsi256(194)('Honeydew, more or less')` ## Windows From 4de1841129cf3d0a1db7a5d6638402b7828e1731 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Tue, 8 Oct 2019 16:21:40 +0700 Subject: [PATCH 085/170] 3.0.0-beta.2 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 32ea3bd..d22089b 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "3.0.0-beta.1", + "version": "3.0.0-beta.2", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From 628b5954cf1ea07a00dfed13d51bbd95f5d42de1 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 30 Oct 2019 19:38:56 +0700 Subject: [PATCH 086/170] Tidelift tasks --- readme.md | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/readme.md b/readme.md index 7322f2b..aa0070a 100644 --- a/readme.md +++ b/readme.md @@ -275,6 +275,13 @@ If you're on Windows, do yourself a favor and use [Windows Terminal](https://git [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. +## chalk for enterprise + +Available as part of the Tidelift Subscription. + +The maintainers of chalk and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-chalk?utm_source=npm-chalk&utm_medium=referral&utm_campaign=enterprise&utm_term=repo) + + ## Related - [chalk-cli](https://github.com/chalk/chalk-cli) - CLI for this module @@ -297,16 +304,3 @@ If you're on Windows, do yourself a favor and use [Windows Terminal](https://git - [Sindre Sorhus](https://github.com/sindresorhus) - [Josh Junon](https://github.com/qix-) - - ---- - -
- - Get professional support for Chalk with a Tidelift subscription - -
- - Tidelift helps make open source sustainable for maintainers while giving companies
assurances about security, maintenance, and licensing for their dependencies. -
-
From 18c280da2ea2d8a29556891f771c0f7bcf5678ab Mon Sep 17 00:00:00 2001 From: Mark Pedrotti Date: Sat, 9 Nov 2019 01:22:55 -0500 Subject: [PATCH 087/170] Add `ansi` and `bgAnsi` to TypeScript declaration (#369) --- index.d.ts | 17 +++++++++++++++++ index.test-d.ts | 2 ++ readme.md | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/index.d.ts b/index.d.ts index c50c17e..7e22c45 100644 --- a/index.d.ts +++ b/index.d.ts @@ -213,6 +213,14 @@ declare namespace chalk { */ hwb(hue: number, whiteness: number, blackness: number): Chalk; + /** + Use a [Select/Set Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters) (SGR) [color code number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) to set text color. + + 30 <= code && code < 38 || 90 <= code && code < 98 + For example, 31 for red, 91 for redBright. + */ + ansi(code: number): Chalk; + /** Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color. */ @@ -266,6 +274,15 @@ declare namespace chalk { */ bgHwb(hue: number, whiteness: number, blackness: number): Chalk; + /** + Use a [Select/Set Graphic Rendition](https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters) (SGR) [color code number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) to set background color. + + 30 <= code && code < 38 || 90 <= code && code < 98 + For example, 31 for red, 91 for redBright. + Use the foreground code, not the background code (for example, not 41, nor 101). + */ + bgAnsi(code: number): Chalk; + /** Use a [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set background color. */ diff --git a/index.test-d.ts b/index.test-d.ts index dd3ba99..177d6de 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -49,6 +49,7 @@ 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.ansi(30)); expectType(chalk.ansi256(0)); expectType(chalk.bgHex('#DEADED')); expectType(chalk.bgKeyword('orange')); @@ -56,6 +57,7 @@ expectType(chalk.bgRgb(0, 0, 0)); expectType(chalk.bgHsl(0, 0, 0)); expectType(chalk.bgHsv(0, 0, 0)); expectType(chalk.bgHwb(0, 0, 0)); +expectType(chalk.bgAnsi(30)); expectType(chalk.bgAnsi256(0)); // -- Modifiers -- diff --git a/readme.md b/readme.md index aa0070a..54c4aff 100644 --- a/readme.md +++ b/readme.md @@ -261,7 +261,7 @@ The following color models can be used: - [`hsl`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsl(32, 100, 50).bold('Orange!')` - [`hsv`](https://en.wikipedia.org/wiki/HSL_and_HSV) - Example: `chalk.hsv(32, 100, 100).bold('Orange!')` - [`hwb`](https://en.wikipedia.org/wiki/HWB_color_model) - Example: `chalk.hwb(32, 0, 50).bold('Orange!')` -- `ansi16` +- [`ansi`](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit) - Example: `chalk.ansi(31).bgAnsi(93)('red on yellowBright')` - [`ansi256`](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) - Example: `chalk.bgAnsi256(194)('Honeydew, more or less')` From b3930189a54aa84434a2f3ea7a18ec83d6a5ee92 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 9 Nov 2019 13:56:12 +0700 Subject: [PATCH 088/170] Meta tweaks --- package.json | 4 ++-- readme.md | 2 -- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index d22089b..724c0d5 100644 --- a/package.json +++ b/package.json @@ -45,8 +45,8 @@ }, "devDependencies": { "ava": "^2.4.0", - "coveralls": "^3.0.5", - "execa": "^2.0.3", + "coveralls": "^3.0.7", + "execa": "^3.2.0", "import-fresh": "^3.1.0", "matcha": "^0.7.0", "nyc": "^14.1.1", diff --git a/readme.md b/readme.md index 54c4aff..877cb93 100644 --- a/readme.md +++ b/readme.md @@ -13,8 +13,6 @@ -**This readme reflects the next major version that is currently in development. You probably want [the v2 readme](https://www.npmjs.com/package/chalk).** - ## Highlights From 20002d8bd1dfd6f68bfa8bdacba520ff6027a450 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Sat, 9 Nov 2019 13:58:44 +0700 Subject: [PATCH 089/170] 3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 724c0d5..047adf9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "chalk", - "version": "3.0.0-beta.2", + "version": "3.0.0", "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", From 0e6fecc7f7fd8158d3c96fb89608b8dfb744fdfa Mon Sep 17 00:00:00 2001 From: Edwin Kofler <24364012+eankeen@users.noreply.github.com> Date: Thu, 12 Dec 2019 12:12:22 -0800 Subject: [PATCH 090/170] Add link to replit run (#379) --- .replit | 2 ++ readme.md | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 .replit diff --git a/.replit b/.replit new file mode 100644 index 0000000..cf3930d --- /dev/null +++ b/.replit @@ -0,0 +1,2 @@ +language = "nodejs" +run = "cd examples && node rainbow" diff --git a/readme.md b/readme.md index 877cb93..c38fa60 100644 --- a/readme.md +++ b/readme.md @@ -9,7 +9,7 @@ > Terminal string styling done right -[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript-ready](https://img.shields.io/npm/types/chalk.svg) +[![Build Status](https://travis-ci.org/chalk/chalk.svg?branch=master)](https://travis-ci.org/chalk/chalk) [![Coverage Status](https://coveralls.io/repos/github/chalk/chalk/badge.svg?branch=master)](https://coveralls.io/github/chalk/chalk?branch=master) [![npm dependents](https://badgen.net/npm/dependents/chalk)](https://www.npmjs.com/package/chalk?activeTab=dependents) [![Downloads](https://badgen.net/npm/dt/chalk)](https://www.npmjs.com/package/chalk) [![](https://img.shields.io/badge/unicorn-approved-ff69b4.svg)](https://www.youtube.com/watch?v=9auOCbH5Ns4) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) ![TypeScript-ready](https://img.shields.io/npm/types/chalk.svg) [![run on repl.it](http://repl.it/badge/github/chalk/chalk)](https://repl.it/github/chalk/chalk) From 797461ee3232c0013afc9b51d18ea2ba87227f10 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Wed, 1 Jan 2020 19:05:40 +0100 Subject: [PATCH 091/170] Meta tweaks --- package.json | 3 ++- readme.md | 14 +------------- 2 files changed, 3 insertions(+), 14 deletions(-) diff --git a/package.json b/package.json index 047adf9..0a4aaa9 100644 --- a/package.json +++ b/package.json @@ -4,6 +4,7 @@ "description": "Terminal string styling done right", "license": "MIT", "repository": "chalk/chalk", + "funding": "https://github.com/chalk/chalk?sponsor=1", "main": "source", "engines": { "node": ">=8" @@ -49,7 +50,7 @@ "execa": "^3.2.0", "import-fresh": "^3.1.0", "matcha": "^0.7.0", - "nyc": "^14.1.1", + "nyc": "^15.0.0", "resolve-from": "^5.0.0", "tsd": "^0.7.4", "xo": "^0.25.3" diff --git a/readme.md b/readme.md index c38fa60..a0ca245 100644 --- a/readme.md +++ b/readme.md @@ -13,7 +13,6 @@ - ## Highlights - Expressive API @@ -24,8 +23,7 @@ - Doesn't extend `String.prototype` - Clean and focused - Actively maintained -- [Used by ~46,000 packages](https://www.npmjs.com/browse/depended/chalk) as of October 1, 2019 - +- [Used by ~50,000 packages](https://www.npmjs.com/browse/depended/chalk) as of January 1, 2020 ## Install @@ -33,7 +31,6 @@ $ npm install chalk ``` - ## Usage ```js @@ -107,7 +104,6 @@ console.log(chalk.green('Hello %s'), name); //=> 'Hello Sindre' ``` - ## API ### chalk.`