From fa16f4ec37c1c25bda6ca1864bf53ecd3ea3d3c9 Mon Sep 17 00:00:00 2001 From: Sindre Sorhus Date: Fri, 16 Apr 2021 15:23:29 +0700 Subject: [PATCH] Require Node.js 12 and move to ESM --- .github/funding.yml | 2 +- .github/workflows/main.yml | 3 +- benchmark.js | 3 +- examples/rainbow.js | 9 +- examples/screenshot.js | 5 +- index.d.ts | 602 ++++++++++++++++++------------------- index.test-d.ts | 18 +- license | 2 +- package.json | 21 +- readme.md | 17 +- source/index.js | 20 +- source/templates.js | 11 +- source/util.js | 19 +- test/_fixture.js | 3 +- test/_supports-color.js | 21 -- test/chalk.js | 7 +- test/constructor.js | 3 +- test/instance.js | 6 +- test/level.js | 10 +- test/no-color-support.js | 32 +- test/template-literal.js | 6 +- test/visible.js | 6 +- 22 files changed, 388 insertions(+), 438 deletions(-) delete mode 100644 test/_supports-color.js diff --git a/.github/funding.yml b/.github/funding.yml index 5692ede..1cd069f 100644 --- a/.github/funding.yml +++ b/.github/funding.yml @@ -1,4 +1,4 @@ -github: [sindresorhus,Qix-] +github: [sindresorhus, Qix-] open_collective: sindresorhus tidelift: npm/chalk custom: https://sindresorhus.com/donate diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c1870cf..d36e1a8 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -12,10 +12,9 @@ jobs: node-version: - 14 - 12 - - 10 steps: - uses: actions/checkout@v2 - - uses: actions/setup-node@v1 + - uses: actions/setup-node@v2 with: node-version: ${{ matrix.node-version }} - run: npm install diff --git a/benchmark.js b/benchmark.js index 98ee5ee..c5c6e27 100644 --- a/benchmark.js +++ b/benchmark.js @@ -1,6 +1,5 @@ /* globals suite, bench */ -'use strict'; -const chalk = require('.'); +import chalk from './index.js'; suite('chalk', () => { const chalkRed = chalk.red; diff --git a/examples/rainbow.js b/examples/rainbow.js index 6e0664c..67dd236 100644 --- a/examples/rainbow.js +++ b/examples/rainbow.js @@ -1,5 +1,4 @@ -'use strict'; -const chalk = require('..'); +import chalk from '../index.js'; const ignoreChars = /[^!-~]/g; @@ -17,7 +16,7 @@ function rainbow(string, offset) { let hue = offset % 360; const characters = []; for (const character of string) { - if (character.match(ignoreChars)) { + if (ignoreChars.test(character)) { characters.push(character); } else { characters.push(chalk.hsl(hue, 100, 50)(character)); @@ -30,8 +29,8 @@ function rainbow(string, offset) { async function animateString(string) { console.log(); - for (let i = 0; i < 360 * 5; i++) { - console.log('\u001B[1F\u001B[G', rainbow(string, i)); + for (let index = 0; index < 360 * 5; index++) { + console.log('\u001B[1F\u001B[G', rainbow(string, index)); await delay(2); // eslint-disable-line no-await-in-loop } } diff --git a/examples/screenshot.js b/examples/screenshot.js index fc64030..ea61e0c 100644 --- a/examples/screenshot.js +++ b/examples/screenshot.js @@ -1,6 +1,5 @@ -'use strict'; -const styles = require('ansi-styles'); -const chalk = require('..'); +import styles from 'ansi-styles'; +import chalk from '../index.js'; // Generates screenshot for (const key of Object.keys(styles)) { diff --git a/index.d.ts b/index.d.ts index ddaf8d4..268ab75 100644 --- a/index.d.ts +++ b/index.d.ts @@ -3,7 +3,7 @@ Basic foreground colors. [More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support) */ -declare type ForegroundColor = +export type ForegroundColor = | 'black' | 'red' | 'green' @@ -28,7 +28,7 @@ Basic background colors. [More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support) */ -declare type BackgroundColor = +export type BackgroundColor = | 'bgBlack' | 'bgRed' | 'bgGreen' @@ -53,9 +53,9 @@ Basic colors. [More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support) */ -declare type Color = ForegroundColor | BackgroundColor; +export type Color = ForegroundColor | BackgroundColor; -declare type Modifiers = +export type Modifiers = | 'reset' | 'bold' | 'dim' @@ -66,350 +66,346 @@ declare type Modifiers = | 'strikethrough' | 'visible'; -declare namespace chalk { +/** +Levels: +- `0` - All colors disabled. +- `1` - Basic 16 colors support. +- `2` - ANSI 256 colors support. +- `3` - Truecolor 16 million colors support. +*/ +export type ColorSupportLevel = 0 | 1 | 2 | 3; + +export interface Options { /** + Specify the color support for Chalk. + + By default, color support is automatically detected based on the environment. + Levels: - `0` - All colors disabled. - `1` - Basic 16 colors support. - `2` - ANSI 256 colors support. - `3` - Truecolor 16 million colors support. */ - type Level = 0 | 1 | 2 | 3; + readonly level?: ColorSupportLevel; +} + +/** +Return a new Chalk instance. +*/ +export type ChalkInstance = new (options?: Options) => Chalk; + +/** +Detect whether the terminal supports color. +*/ +export interface ColorSupport { + /** + The color level used by Chalk. + */ + level: ColorSupportLevel; + + /** + 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 ChalkFunction { + /** + Use a template string. + + @remarks Template literals are unsupported for nested calls (see [issue #341](https://github.com/chalk/chalk/issues/341)) + + @example + ``` + import chalk from 'chalk'; + + log(chalk` + CPU: {red ${cpu.totalPercent}%} + RAM: {green ${ram.used / ram.total * 100}%} + DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%} + `); + ``` - interface Options { - /** - Specify the color support for Chalk. + @example + ``` + import chalk from 'chalk'; - By default, color support is automatically detected based on the environment. + log(chalk.red.bgBlack`2 + 3 = {bold ${2 + 3}}`) + ``` + */ + (text: TemplateStringsArray, ...placeholders: unknown[]): string; - Levels: - - `0` - All colors disabled. - - `1` - Basic 16 colors support. - - `2` - ANSI 256 colors support. - - `3` - Truecolor 16 million colors support. - */ - level?: Level; - } + (...text: unknown[]): string; +} +export interface Chalk extends ChalkFunction { /** Return a new Chalk instance. */ - type Instance = new (options?: Options) => Chalk; + Instance: ChalkInstance; /** - Detect whether the terminal supports color. + The color support for Chalk. + + By default, color support is automatically detected based on the environment. + + Levels: + - `0` - All colors disabled. + - `1` - Basic 16 colors support. + - `2` - ANSI 256 colors support. + - `3` - Truecolor 16 million colors support. */ - interface ColorSupport { - /** - The color level used by Chalk. - */ - level: Level; + level: ColorSupportLevel; - /** - Return whether Chalk supports basic 16 colors. - */ - hasBasic: boolean; + /** + Use HEX value to set text color. - /** - Return whether Chalk supports ANSI 256 colors. - */ - has256: boolean; + @param color - Hexadecimal value representing the desired color. - /** - Return whether Chalk supports Truecolor 16 million colors. - */ - has16m: boolean; - } + @example + ``` + import chalk from 'chalk'; - interface ChalkFunction { - /** - Use a template string. + chalk.hex('#DEADED'); + ``` + */ + hex: (color: string) => Chalk; - @remarks Template literals are unsupported for nested calls (see [issue #341](https://github.com/chalk/chalk/issues/341)) + /** + Use keyword color value to set text color. - @example - ``` - import chalk = require('chalk'); + @param color - Keyword value representing the desired color. - log(chalk` - CPU: {red ${cpu.totalPercent}%} - RAM: {green ${ram.used / ram.total * 100}%} - DISK: {rgb(255,131,0) ${disk.used / disk.total * 100}%} - `); - ``` + @example + ``` + import chalk from 'chalk'; - @example - ``` - import chalk = require('chalk'); + chalk.keyword('orange'); + ``` + */ + keyword: (color: string) => Chalk; - log(chalk.red.bgBlack`2 + 3 = {bold ${2 + 3}}`) - ``` - */ - (text: TemplateStringsArray, ...placeholders: unknown[]): string; + /** + Use RGB values to set text color. + */ + rgb: (red: number, green: number, blue: number) => Chalk; - (...text: unknown[]): string; - } + /** + Use HSL values to set text color. + */ + hsl: (hue: number, saturation: number, lightness: number) => Chalk; - interface Chalk extends ChalkFunction { - /** - Return a new Chalk instance. - */ - Instance: Instance; + /** + Use HSV values to set text color. + */ + hsv: (hue: number, saturation: number, value: number) => Chalk; + + /** + Use HWB values to set text color. + */ + hwb: (hue: number, whiteness: number, blackness: number) => Chalk; - /** - The color support for 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. - By default, color support is automatically detected based on the environment. + 30 <= code && code < 38 || 90 <= code && code < 98 + For example, 31 for red, 91 for redBright. + */ + ansi: (code: number) => Chalk; - Levels: - - `0` - All colors disabled. - - `1` - Basic 16 colors support. - - `2` - ANSI 256 colors support. - - `3` - Truecolor 16 million colors support. - */ - level: Level; + /** + 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 text color. + /** + Use HEX value to set background color. - @param color - Hexadecimal value representing the desired color. + @param color - Hexadecimal value representing the desired color. - @example - ``` - import chalk = require('chalk'); + @example + ``` + import chalk from 'chalk'; - chalk.hex('#DEADED'); - ``` - */ - hex: (color: string) => Chalk; + chalk.bgHex('#DEADED'); + ``` + */ + bgHex: (color: string) => Chalk; - /** - Use keyword color value to set text color. - - @param color - Keyword value representing the desired color. + /** + Use keyword color value to set background color. - @example - ``` - import chalk = require('chalk'); + @param color - Keyword value representing the desired color. - chalk.keyword('orange'); - ``` - */ - keyword: (color: string) => Chalk; - - /** - Use RGB values to set text color. - */ - rgb: (red: number, green: number, blue: number) => Chalk; - - /** - Use HSL values to set text color. - */ - hsl: (hue: number, saturation: number, lightness: number) => Chalk; - - /** - Use HSV values to set text color. - */ - hsv: (hue: number, saturation: number, value: number) => Chalk; - - /** - Use HWB values to set text color. - */ - 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. - */ - ansi256: (index: number) => Chalk; - - /** - 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) => Chalk; - - /** - 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) => Chalk; - - /** - Use RGB values to set background color. - */ - bgRgb: (red: number, green: number, blue: number) => Chalk; - - /** - Use HSL values to set background color. - */ - bgHsl: (hue: number, saturation: number, lightness: number) => Chalk; - - /** - Use HSV values to set background color. - */ - bgHsv: (hue: number, saturation: number, value: number) => Chalk; - - /** - Use HWB values to set background color. - */ - 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. - */ - bgAnsi256: (index: number) => Chalk; - - /** - Modifier: Resets the current color chain. - */ - readonly reset: Chalk; - - /** - Modifier: Make text bold. - */ - readonly bold: Chalk; - - /** - Modifier: Emitting only a small amount of light. - */ - readonly dim: Chalk; - - /** - Modifier: Make text italic. (Not widely supported) - */ - readonly italic: Chalk; - - /** - Modifier: Make text underline. (Not widely supported) - */ - readonly underline: Chalk; - - /** - Modifier: Inverse background and foreground colors. - */ - readonly inverse: Chalk; - - /** - Modifier: Prints the text, but makes it invisible. - */ - readonly hidden: Chalk; - - /** - Modifier: Puts a horizontal line through the center of the text. (Not widely supported) - */ - readonly strikethrough: Chalk; - - /** - 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; - - readonly black: Chalk; - readonly red: Chalk; - readonly green: Chalk; - readonly yellow: Chalk; - readonly blue: 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; - readonly yellowBright: Chalk; - readonly blueBright: Chalk; - readonly magentaBright: Chalk; - readonly cyanBright: Chalk; - readonly whiteBright: Chalk; - - readonly bgBlack: Chalk; - readonly bgRed: Chalk; - readonly bgGreen: Chalk; - readonly bgYellow: Chalk; - readonly bgBlue: 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; - readonly bgYellowBright: Chalk; - readonly bgBlueBright: Chalk; - readonly bgMagentaBright: Chalk; - readonly bgCyanBright: Chalk; - readonly bgWhiteBright: Chalk; - } + @example + ``` + import chalk from 'chalk'; + + chalk.bgKeyword('orange'); + ``` + */ + bgKeyword: (color: string) => Chalk; + + /** + Use RGB values to set background color. + */ + bgRgb: (red: number, green: number, blue: number) => Chalk; + + /** + Use HSL values to set background color. + */ + bgHsl: (hue: number, saturation: number, lightness: number) => Chalk; + + /** + Use HSV values to set background color. + */ + bgHsv: (hue: number, saturation: number, value: number) => Chalk; + + /** + Use HWB values to set background color. + */ + 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. + */ + bgAnsi256: (index: number) => Chalk; + + /** + Modifier: Resets the current color chain. + */ + readonly reset: Chalk; + + /** + Modifier: Make text bold. + */ + readonly bold: Chalk; + + /** + Modifier: Emitting only a small amount of light. + */ + readonly dim: Chalk; + + /** + Modifier: Make text italic. (Not widely supported) + */ + readonly italic: Chalk; + + /** + Modifier: Make text underline. (Not widely supported) + */ + readonly underline: Chalk; + + /** + Modifier: Inverse background and foreground colors. + */ + readonly inverse: Chalk; + + /** + Modifier: Prints the text, but makes it invisible. + */ + readonly hidden: Chalk; + + /** + Modifier: Puts a horizontal line through the center of the text. (Not widely supported) + */ + readonly strikethrough: Chalk; + + /** + 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; + + readonly black: Chalk; + readonly red: Chalk; + readonly green: Chalk; + readonly yellow: Chalk; + readonly blue: 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; + readonly yellowBright: Chalk; + readonly blueBright: Chalk; + readonly magentaBright: Chalk; + readonly cyanBright: Chalk; + readonly whiteBright: Chalk; + + readonly bgBlack: Chalk; + readonly bgRed: Chalk; + readonly bgGreen: Chalk; + readonly bgYellow: Chalk; + readonly bgBlue: 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; + readonly bgYellowBright: Chalk; + readonly bgBlueBright: Chalk; + readonly bgMagentaBright: Chalk; + readonly bgCyanBright: Chalk; + readonly bgWhiteBright: Chalk; } /** 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 & chalk.ChalkFunction & { - supportsColor: chalk.ColorSupport | false; - Level: chalk.Level; - Color: Color; - ForegroundColor: ForegroundColor; - BackgroundColor: BackgroundColor; - Modifiers: Modifiers; - stderr: chalk.Chalk & {supportsColor: chalk.ColorSupport | false}; +declare const chalk: Chalk & ChalkFunction & { + supportsColor: ColorSupport | false; + stderr: Chalk & {supportsColor: ColorSupport | false}; }; -export = chalk; +export default chalk; diff --git a/index.test-d.ts b/index.test-d.ts index ba91b63..292707e 100644 --- a/index.test-d.ts +++ b/index.test-d.ts @@ -1,11 +1,11 @@ import {expectType, expectAssignable, expectError} from 'tsd'; -import chalk = require('.'); +import chalk, {Chalk, Color, ColorSupport, ColorSupportLevel} from './index.js'; // - Helpers - -type colorReturn = chalk.Chalk & {supportsColor?: never}; +type colorReturn = Chalk & {supportsColor?: never}; // - supportsColor - -expectType(chalk.supportsColor); +expectType(chalk.supportsColor); if (chalk.supportsColor) { expectType(chalk.supportsColor.hasBasic); expectType(chalk.supportsColor.has256); @@ -13,8 +13,8 @@ if (chalk.supportsColor) { } // - stderr - -expectAssignable(chalk.stderr); -expectType(chalk.stderr.supportsColor); +expectAssignable(chalk.stderr); +expectType(chalk.stderr.supportsColor); if (chalk.stderr.supportsColor) { expectType(chalk.stderr.supportsColor.hasBasic); expectType(chalk.stderr.supportsColor.has256); @@ -29,10 +29,10 @@ expectError(chalk.reset.supportsColor); // - Chalk - // -- Instance -- -expectType(new chalk.Instance({level: 1})); +expectType(new chalk.Instance({level: 1})); // -- Properties -- -expectType(chalk.level); +expectType(chalk.level); // -- Template literal -- expectType(chalk``); @@ -158,5 +158,5 @@ expectType(chalk.red.bgGreen.bold`Hello {italic.blue ${name}}`); expectType(chalk.strikethrough.cyanBright.bgBlack`Works with {reset {bold numbers}} {bold.red ${1}}`); // -- Color types == -expectAssignable('red'); -expectError('hotpink'); +expectAssignable('red'); +expectError('hotpink'); diff --git a/license b/license index e7af2f7..fa7ceba 100644 --- a/license +++ b/license @@ -1,6 +1,6 @@ MIT License -Copyright (c) Sindre Sorhus (sindresorhus.com) +Copyright (c) Sindre Sorhus (https://sindresorhus.com) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/package.json b/package.json index 7a3bd25..9e6f031 100644 --- a/package.json +++ b/package.json @@ -5,9 +5,10 @@ "license": "MIT", "repository": "chalk/chalk", "funding": "https://github.com/chalk/chalk?sponsor=1", - "main": "source", + "type": "module", + "exports": "./source/index.js", "engines": { - "node": ">=10" + "node": ">=12" }, "scripts": { "test": "xo && nyc ava && tsd", @@ -42,26 +43,20 @@ ], "dependencies": { "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "supports-color": "^9.0.0" }, "devDependencies": { - "ava": "^2.4.0", + "ava": "^3.15.0", "coveralls": "^3.1.0", - "execa": "^4.0.3", - "import-fresh": "^3.2.1", + "execa": "^5.0.0", "matcha": "^0.7.0", "nyc": "^15.1.0", - "resolve-from": "^5.0.0", - "tsd": "^0.13.1", - "xo": "^0.33.1" + "tsd": "^0.14.0", + "xo": "^0.38.2" }, "xo": { "rules": { "unicorn/prefer-string-slice": "off", - "unicorn/prefer-includes": "off", - "@typescript-eslint/member-ordering": "off", - "no-redeclare": "off", - "unicorn/string-content": "off", "unicorn/better-regex": "off" } } diff --git a/readme.md b/readme.md index 4867321..c48056c 100644 --- a/readme.md +++ b/readme.md @@ -79,7 +79,7 @@ $ npm install chalk ## Usage ```js -const chalk = require('chalk'); +import chalk from 'chalk'; console.log(chalk.blue('Hello world!')); ``` @@ -87,7 +87,8 @@ console.log(chalk.blue('Hello world!')); Chalk comes with an easy to use composable API where you just chain and nest the styles you want. ```js -const chalk = require('chalk'); +import chalk from 'chalk'; + const log = console.log; // Combine styled and normal strings @@ -132,7 +133,7 @@ log(chalk.hex('#DEADED').bold('Bold gray!')); Easily define your own themes: ```js -const chalk = require('chalk'); +import chalk from 'chalk'; const error = chalk.bold.red; const warning = chalk.keyword('orange'); @@ -144,6 +145,8 @@ console.log(warning('Warning!')); Take advantage of console.log [string substitution](https://nodejs.org/docs/latest/api/console.html#console_console_log_data_args): ```js +import chalk from 'chalk'; + const name = 'Sindre'; console.log(chalk.green('Hello %s'), name); //=> 'Hello Sindre' @@ -168,7 +171,9 @@ 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.Instance({level: 0}); +import chalk from 'chalk'; + +const customChalk = new chalk.Instance({level: 0}); ``` | Level | Description | @@ -247,7 +252,7 @@ Explicit 256/Truecolor mode can be enabled using the `--color=256` and `--color= Chalk can be used as a [tagged template literal](https://exploringjs.com/es6/ch_template-literals.html#_tagged-template-literals). ```js -const chalk = require('chalk'); +import chalk from 'chalk'; const miles = 18; const calculateFeet = miles => miles * 5280; @@ -263,6 +268,8 @@ Blocks are delimited by an opening curly brace (`{`), a style, some content, and Template styles are chained exactly like normal Chalk styles. The following three statements are equivalent: ```js +import chalk from 'chalk'; + console.log(chalk.bold.rgb(10, 100, 200)('Hello!')); console.log(chalk.bold.rgb(10, 100, 200)`Hello!`); console.log(chalk`{bold.rgb(10,100,200) Hello!}`); diff --git a/source/index.js b/source/index.js index 6313bde..9a9986d 100644 --- a/source/index.js +++ b/source/index.js @@ -1,11 +1,12 @@ -'use strict'; -const ansiStyles = require('ansi-styles'); -const {stdout: stdoutColor, stderr: stderrColor} = require('supports-color'); -const { +import ansiStyles from 'ansi-styles'; +import supportsColor from 'supports-color'; +import { stringReplaceAll, stringEncaseCRLFWithFirstIndex -} = require('./util'); +} from './util.js'; +import template from './templates.js'; +const {stdout: stdoutColor, stderr: stderrColor} = supportsColor; const {isArray} = Array; // `supportsColor.level` → `ansiStyles.color[name]` mapping @@ -168,7 +169,7 @@ const applyStyle = (self, string) => { } const {openAll, closeAll} = styler; - if (string.indexOf('\u001B') !== -1) { + if (string.includes('\u001B')) { while (styler !== undefined) { // Replace any instances already present with a re-opening code // otherwise only the part of the string until said closing code @@ -190,7 +191,6 @@ const applyStyle = (self, string) => { return openAll + string + closeAll; }; -let template; const chalkTag = (chalk, ...strings) => { const [firstString] = strings; @@ -210,10 +210,6 @@ const chalkTag = (chalk, ...strings) => { ); } - if (template === undefined) { - template = require('./templates'); - } - return template(chalk, parts.join('')); }; @@ -224,4 +220,4 @@ chalk.supportsColor = stdoutColor; chalk.stderr = Chalk({level: stderrColor ? stderrColor.level : 0}); // eslint-disable-line new-cap chalk.stderr.supportsColor = stderrColor; -module.exports = chalk; +export default chalk; diff --git a/source/templates.js b/source/templates.js index bfdaba8..1a2f95c 100644 --- a/source/templates.js +++ b/source/templates.js @@ -1,4 +1,3 @@ -'use strict'; 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$/; @@ -62,7 +61,7 @@ function parseStyle(style) { if (matches[2]) { const args = parseArguments(name, matches[2]); - results.push([name].concat(args)); + results.push([name, ...args]); } else { results.push([name]); } @@ -96,7 +95,7 @@ function buildStyle(chalk, styles) { return current; } -module.exports = (chalk, temporary) => { +export default function template(chalk, temporary) { const styles = []; const chunks = []; let chunk = []; @@ -126,9 +125,9 @@ module.exports = (chalk, temporary) => { chunks.push(chunk.join('')); if (styles.length > 0) { - const errMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; - throw new Error(errMessage); + const errorMessage = `Chalk template literal is missing ${styles.length} closing bracket${styles.length === 1 ? '' : 's'} (\`}\`)`; + throw new Error(errorMessage); } return chunks.join(''); -}; +} diff --git a/source/util.js b/source/util.js index ca466fd..4d8bc4a 100644 --- a/source/util.js +++ b/source/util.js @@ -1,6 +1,4 @@ -'use strict'; - -const stringReplaceAll = (string, substring, replacer) => { +export function stringReplaceAll(string, substring, replacer) { let index = string.indexOf(substring); if (index === -1) { return string; @@ -15,11 +13,11 @@ const stringReplaceAll = (string, substring, replacer) => { index = string.indexOf(substring, endIndex); } while (index !== -1); - returnValue += string.substr(endIndex); + returnValue += string.slice(endIndex); return returnValue; -}; +} -const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { +export function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) { let endIndex = 0; let returnValue = ''; do { @@ -29,11 +27,6 @@ const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => { index = string.indexOf('\n', endIndex); } while (index !== -1); - returnValue += string.substr(endIndex); + returnValue += string.slice(endIndex); return returnValue; -}; - -module.exports = { - stringReplaceAll, - stringEncaseCRLFWithFirstIndex -}; +} diff --git a/test/_fixture.js b/test/_fixture.js index 29f34b0..1a8e8ba 100644 --- a/test/_fixture.js +++ b/test/_fixture.js @@ -1,4 +1,3 @@ -'use strict'; -const chalk = require('../source'); +import chalk from '../source/index.js'; console.log(`${chalk.hex('#ff6159')('testout')} ${chalk.stderr.hex('#ff6159')('testerr')}`); diff --git a/test/_supports-color.js b/test/_supports-color.js deleted file mode 100644 index b5c0f78..0000000 --- a/test/_supports-color.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; -const resolveFrom = require('resolve-from'); - -const DEFAULT = { - stdout: { - level: 3, - hasBasic: true, - has256: true, - has16m: true - }, - stderr: { - 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/chalk.js b/test/chalk.js index 4e78565..93e9c23 100644 --- a/test/chalk.js +++ b/test/chalk.js @@ -1,9 +1,8 @@ import test from 'ava'; +import chalk from '../source/index.js'; -// Spoof supports-color -require('./_supports-color')(__dirname); - -const chalk = require('../source'); +chalk.level = 3; +chalk.stderr.level = 3; console.log('TERM:', process.env.TERM || '[none]'); console.log('platform:', process.platform || '[unknown]'); diff --git a/test/constructor.js b/test/constructor.js index f4e9ca1..78ee070 100644 --- a/test/constructor.js +++ b/test/constructor.js @@ -1,6 +1,5 @@ import test from 'ava'; - -const chalk = require('../source'); +import chalk from '../source/index.js'; test('Chalk.constructor should throw an expected error', t => { const expectedError = t.throws(() => { diff --git a/test/instance.js b/test/instance.js index 37c72eb..c063109 100644 --- a/test/instance.js +++ b/test/instance.js @@ -1,9 +1,7 @@ import test from 'ava'; +import chalk from '../source/index.js'; -// Spoof supports-color -require('./_supports-color')(__dirname); - -const chalk = require('../source'); +chalk.level = 1; test('create an isolated context where colors can be disabled (by level)', t => { const instance = new chalk.Instance({level: 0}); diff --git a/test/level.js b/test/level.js index 65d4720..4aab162 100644 --- a/test/level.js +++ b/test/level.js @@ -1,11 +1,9 @@ -import path from 'path'; +import {fileURLToPath} from 'url'; import test from 'ava'; import execa from 'execa'; +import chalk from '../source/index.js'; -// Spoof supports-color -require('./_supports-color')(__dirname); - -const chalk = require('../source'); +chalk.level = 1; test('don\'t output colors when manually disabled', t => { const oldLevel = chalk.level; @@ -40,6 +38,6 @@ 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')); + const {stdout} = await execa.node(fileURLToPath(new URL('./_fixture.js', import.meta.url))); t.is(stdout, 'testout testerr'); }); diff --git a/test/no-color-support.js b/test/no-color-support.js index ae88ac9..0a5734d 100644 --- a/test/no-color-support.js +++ b/test/no-color-support.js @@ -1,22 +1,22 @@ import test from 'ava'; +import chalk from '../source/index.js'; +// TODO: Do this when ESM supports loader hooks // Spoof supports-color -require('./_supports-color')(__dirname, { - stdout: { - level: 0, - hasBasic: false, - has256: false, - has16m: false - }, - stderr: { - level: 0, - hasBasic: false, - has256: false, - has16m: false - } -}); - -const chalk = require('../source'); +// require('./_supports-color')(__dirname, { +// stdout: { +// level: 0, +// hasBasic: false, +// has256: false, +// has16m: false +// }, +// stderr: { +// level: 0, +// hasBasic: false, +// has256: false, +// has16m: false +// } +// }); test('colors can be forced by using chalk.level', t => { chalk.level = 1; diff --git a/test/template-literal.js b/test/template-literal.js index c918a5b..95383c4 100644 --- a/test/template-literal.js +++ b/test/template-literal.js @@ -1,10 +1,8 @@ /* eslint-disable unicorn/no-hex-escape */ import test from 'ava'; +import chalk from '../source/index.js'; -// Spoof supports-color -require('./_supports-color')(__dirname); - -const chalk = require('../source'); +chalk.level = 1; 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 7987712..cd9e46d 100644 --- a/test/visible.js +++ b/test/visible.js @@ -1,9 +1,7 @@ import test from 'ava'; +import chalk from '../source/index.js'; -// Spoof supports-color -require('./_supports-color')(__dirname); - -const chalk = require('../source'); +chalk.level = 1; test('visible: normal output when level > 0', t => { const instance = new chalk.Instance({level: 3});