pax_global_header00006660000000000000000000000064147040021030014501gustar00rootroot0000000000000052 comment=7249f8c5d4825550f70bc1ea98652639933d3bbd alexeyraspopov-picocolors-93bde36/000077500000000000000000000000001470400210300173555ustar00rootroot00000000000000alexeyraspopov-picocolors-93bde36/.editorconfig000066400000000000000000000004211470400210300220270ustar00rootroot00000000000000# EditorConfig is awesome: https://EditorConfig.org root = true [*] end_of_line = lf insert_final_newline = true [*.{js,d.ts}] charset = utf-8 indent_style = tab indent_size = 2 trim_trailing_whitespace = true [package.json,*.yaml] indent_style = space indent_size = 2 alexeyraspopov-picocolors-93bde36/.github/000077500000000000000000000000001470400210300207155ustar00rootroot00000000000000alexeyraspopov-picocolors-93bde36/.github/workflows/000077500000000000000000000000001470400210300227525ustar00rootroot00000000000000alexeyraspopov-picocolors-93bde36/.github/workflows/benchmarks.yaml000066400000000000000000000016141470400210300257550ustar00rootroot00000000000000name: Benchmarks on: push: branches: [main] pull_request: branches: [main] env: FORCE_COLOR: 3 jobs: benchmarks: name: Benchmarks runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - uses: actions/setup-node@v2 with: node-version: 22 - run: npm install - name: Ensure color support detection run: node tests/environments.js - name: Install esbuild run: npm install esbuild - name: Install missing libs run: npm install chalk5@"npm:chalk@v5.x" - name: Simple API calls run: node benchmarks/simple.mjs --expose-gc - name: Complex formatting expression run: node benchmarks/complex.mjs --expose-gc - name: Library module's init time run: node benchmarks/loading.mjs --expose-gc - name: Total loaded code size run: node benchmarks/size.mjs alexeyraspopov-picocolors-93bde36/.github/workflows/testing.yaml000066400000000000000000000015651470400210300253220ustar00rootroot00000000000000name: Testing on: push: branches: [main] pull_request: branches: [main] jobs: modern: name: Node v${{ matrix.node-version }} runs-on: ubuntu-latest strategy: matrix: node-version: - 20 - 18 - 16 - 14 - 12 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install - run: node tests/test.js legacy: name: Node v${{ matrix.node-version }} (Legacy) runs-on: ubuntu-latest strategy: matrix: node-version: - 10 - 8 - 6 steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: ${{ matrix.node-version }} - run: npm install - run: node tests/test.js alexeyraspopov-picocolors-93bde36/.gitignore000066400000000000000000000000151470400210300213410ustar00rootroot00000000000000node_modules alexeyraspopov-picocolors-93bde36/CHANGELOG.md000066400000000000000000000047711470400210300211770ustar00rootroot00000000000000# Changelog ## [v1.1.1](https://github.com/alexeyraspopov/picocolors/releases/tag/v1.1.1) - Moved TypeScript declarations to a `d.ts` file ([#82](https://github.com/alexeyraspopov/picocolors/pull/82)) - Reworked color detection algorithm to properly work with empty strings in `NO_COLOR` and `FORCE_COLOR` env variables ([#87](https://github.com/alexeyraspopov/picocolors/pull/87)) - Eliminated `require()` call to make the package compatible with some tools ([#87](https://github.com/alexeyraspopov/picocolors/pull/87)) ## [v1.1.0](https://github.com/alexeyraspopov/picocolors/releases/tag/v1.1.0) - Added bright color variants ([#55](https://github.com/alexeyraspopov/picocolors/pull/55)) ## [v1.0.1](https://github.com/alexeyraspopov/picocolors/releases/tag/v1.0.1) - Updated color detection mechanism to work properly on Vercel Edge Runtime ([#64](https://github.com/alexeyraspopov/picocolors/pull/64)) - Remove use of recursion to avoid possible stack overflow for very long inputs ([#56](https://github.com/alexeyraspopov/picocolors/pull/56)) ## [v1.0.0](https://github.com/alexeyraspopov/picocolors/releases/tag/v1.0.0) - Removed several code elements to reduce the package size ([#31](https://github.com/alexeyraspopov/picocolors/pull/31)) - Fixed optional flag for `createColors()` in TypeScript typings ([#34](https://github.com/alexeyraspopov/picocolors/pull/34)) ## [v0.2.1](https://github.com/alexeyraspopov/picocolors/releases/tag/v0.2.1) - Removed semicolons to reduce the package size ([#28](https://github.com/alexeyraspopov/picocolors/pull/28)) - Fixed type definitions ([#29](https://github.com/alexeyraspopov/picocolors/pull/29)) - Made `createColors()` use `isColorSupported` if no flag was provided ([`aaf57e1`](https://github.com/alexeyraspopov/picocolors/commit/aaf57e14b250112c6ad4fbeff08ad78cafc6c887)) ## [v0.2.0](https://github.com/alexeyraspopov/picocolors/releases/tag/v0.2.0) - Removed ESM Module to fix the rest of compatibility issues and reduce package size ([#26](https://github.com/alexeyraspopov/picocolors/pull/26)) - Added support for non-string inputs ([`3276400`](https://github.com/alexeyraspopov/picocolors/commit/3276400d5046c93ae56648e3db137a20b1f420b4)) ## [v0.1.0](https://github.com/alexeyraspopov/picocolors/releases/tag/v0.1.0) - Added CommonJS support ([#7](https://github.com/alexeyraspopov/picocolors/pull/7)) - Ensured Node.js 6+ support ([#8](https://github.com/alexeyraspopov/picocolors/pull/8)) - Added Browsers support ([#10](https://github.com/alexeyraspopov/picocolors/pull/10)) alexeyraspopov-picocolors-93bde36/LICENSE000066400000000000000000000014231470400210300203620ustar00rootroot00000000000000ISC License Copyright (c) 2021-2024 Oleksii Raspopov, Kostiantyn Denysov, Anton Verinov Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies. THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. alexeyraspopov-picocolors-93bde36/README.md000066400000000000000000000116031470400210300206350ustar00rootroot00000000000000# picocolors The tiniest and the fastest library for terminal output formatting with ANSI colors. ```javascript import pc from "picocolors" console.log( pc.green(`How are ${pc.italic(`you`)} doing?`) ) ``` - **No dependencies.** - **14 times** smaller and **2 times** faster than chalk. - Used by popular tools like PostCSS, SVGO, Stylelint, and Browserslist. - Node.js v6+ & browsers support. Support for both CJS and ESM projects. - TypeScript type declarations included. - [`NO_COLOR`](https://no-color.org/) friendly. ## Motivation With `picocolors` we are trying to draw attention to the `node_modules` size problem and promote performance-first culture. ## Prior Art Credits go to the following projects: - [Nanocolors](https://github.com/ai/nanocolors) by [@ai](https://github.com/ai) - [Colorette](https://github.com/jorgebucaran/colorette) by [@jorgebucaran](https://github.com/jorgebucaran) - [Kleur](https://github.com/lukeed/kleur) by [@lukeed](https://github.com/lukeed) - [Colors.js](https://github.com/Marak/colors.js) by [@Marak](https://github.com/Marak) - [Chalk](https://github.com/chalk/chalk) by [@sindresorhus](https://github.com/sindresorhus) ## Benchmarks The space in node_modules including sub-dependencies: ```diff $ node ./benchmarks/size.js Data from packagephobia.com chalk 101 kB cli-color 1249 kB ansi-colors 25 kB kleur 21 kB colorette 17 kB nanocolors 16 kB + picocolors 7 kB ``` Library loading time: ```diff $ node ./benchmarks/loading.js chalk 6.167 ms cli-color 31.431 ms ansi-colors 1.585 ms kleur 2.008 ms kleur/colors 0.773 ms colorette 2.476 ms nanocolors 0.833 ms + picocolors 0.466 ms ``` Benchmark for simple use case: ```diff $ node ./benchmarks/simple.js chalk 24,066,342 ops/sec cli-color 938,700 ops/sec ansi-colors 4,532,542 ops/sec kleur 20,343,122 ops/sec kleur/colors 35,415,770 ops/sec colorette 34,244,834 ops/sec nanocolors 33,443,265 ops/sec + picocolors 33,271,645 ops/sec ``` Benchmark for complex use cases: ```diff $ node ./benchmarks/complex.js chalk 969,915 ops/sec cli-color 131,639 ops/sec ansi-colors 342,250 ops/sec kleur 611,880 ops/sec kleur/colors 1,129,526 ops/sec colorette 1,747,277 ops/sec nanocolors 1,251,312 ops/sec + picocolors 2,024,086 ops/sec ``` ## Usage Picocolors provides an object which includes a variety of text coloring and formatting functions ```javascript import pc from "picocolors" ``` The object includes following coloring functions: `black`, `red`, `green`, `yellow`, `blue`, `magenta`, `cyan`, `white`, `gray`. ```javascript console.log(`I see a ${pc.red("red door")} and I want it painted ${pc.black("black")}`) ``` The object also includes following background color modifier functions: `bgBlack`, `bgRed`, `bgGreen`, `bgYellow`, `bgBlue`, `bgMagenta`, `bgCyan`, `bgWhite` and bright variants `bgBlackBright`, `bgRedBright`, `bgGreenBright`, `bgYellowBright`, `bgBlueBright`, `bgMagentaBright`, `bgCyanBright`, `bgWhiteBright`. ```javascript console.log( pc.bgBlack( pc.white(`Tom appeared on the sidewalk with a bucket of whitewash and a long-handled brush.`) ) ) ``` Besides colors, the object includes following formatting functions: `dim`, `bold`, `hidden`, `italic`, `underline`, `strikethrough`, `reset`, `inverse` and bright variants `blackBright`, `redBright`, `greenBright`, `yellowBright`, `blueBright`, `magentaBright`, `cyanBright`, `whiteBright`. ```javascript for (let task of tasks) { console.log(`${pc.bold(task.name)} ${pc.dim(task.durationMs + "ms")}`) } ``` The library provides additional utilities to ensure the best results for the task: - `isColorSupported` — boolean, explicitly tells whether or not the colors or formatting appear on the screen ```javascript import pc from "picocolors" if (pc.isColorSupported) { console.log("Yay! This script can use colors and formatters") } ``` - `createColors(enabled)` — a function that returns a new API object with manually defined color support configuration ```javascript import pc from "picocolors" let { red, bgWhite } = pc.createColors(options.enableColors) ``` ## Replacing `chalk` 1. Replace package name in import: ```diff - import chalk from 'chalk' + import pico from 'picocolors' ``` 2. Replace variable: ```diff - chalk.red(text) + pico.red(text) ``` 3. Replace chains to nested calls: ```diff - chalk.red.bold(text) + pico.red(pico.bold(text)) ``` 4. You can use [`colorize-template`](https://github.com/usmanyunusov/colorize-template) to replace chalk’s tagged template literal. ```diff + import { createColorize } from 'colorize-template' + let colorize = createColorize(pico) - chalk.red.bold`full {yellow ${"text"}}` + colorize`{red.bold full {yellow ${"text"}}}` ``` alexeyraspopov-picocolors-93bde36/benchmarks/000077500000000000000000000000001470400210300214725ustar00rootroot00000000000000alexeyraspopov-picocolors-93bde36/benchmarks/complex.mjs000066400000000000000000000064211470400210300236570ustar00rootroot00000000000000/* @prettier */ import { run, bench, summary } from "mitata" import * as colorette from "colorette" import kleur from "kleur" import * as kleurColors from "kleur/colors" import chalk from "chalk" import chalk5 from "chalk5" import ansi from "ansi-colors" import cliColor from "cli-color" import picocolors from "../picocolors.js" import * as nanocolors from "nanocolors" import * as yoctocolors from "yoctocolors" summary(() => { let index = 1e8 bench( "chalk v4", () => chalk.red(".") + chalk.yellow(".") + chalk.green(".") + chalk.bgRed(chalk.black(" ERROR ")) + chalk.red( " Add plugin " + chalk.yellow("name") + " to use time limit with " + chalk.yellow(++index) ) ) bench( "chalk v5", () => chalk5.red(".") + chalk5.yellow(".") + chalk5.green(".") + chalk5.bgRed(chalk5.black(" ERROR ")) + chalk5.red( " Add plugin " + chalk5.yellow("name") + " to use time limit with " + chalk5.yellow(++index) ) ) bench( "yoctocolors", () => yoctocolors.red(".") + yoctocolors.yellow(".") + yoctocolors.green(".") + yoctocolors.bgRed(yoctocolors.black(" ERROR ")) + yoctocolors.red( " Add plugin " + yoctocolors.yellow("name") + " to use time limit with " + yoctocolors.yellow(++index) ) ) bench( "cli-color", () => cliColor.red(".") + cliColor.yellow(".") + cliColor.green(".") + cliColor.bgRed(cliColor.black(" ERROR ")) + cliColor.red( " Add plugin " + cliColor.yellow("name") + " to use time limit with " + cliColor.yellow(++index) ) ) bench( "ansi-colors", () => ansi.red(".") + ansi.yellow(".") + ansi.green(".") + ansi.bgRed(ansi.black(" ERROR ")) + ansi.red( " Add plugin " + ansi.yellow("name") + " to use time limit with " + ansi.yellow(++index) ) ) bench( "kleur", () => kleur.red(".") + kleur.yellow(".") + kleur.green(".") + kleur.bgRed(kleur.black(" ERROR ")) + kleur.red( " Add plugin " + kleur.yellow("name") + " to use time limit with " + kleur.yellow(++index) ) ) bench( "kleur/colors", () => kleurColors.red(".") + kleurColors.yellow(".") + kleurColors.green(".") + kleurColors.bgRed(kleurColors.black(" ERROR ")) + kleurColors.red( " Add plugin " + kleurColors.yellow("name") + " to use time limit with " + kleurColors.yellow(++index) ) ) bench( "colorette", () => colorette.red(".") + colorette.yellow(".") + colorette.green(".") + colorette.bgRed(colorette.black(" ERROR ")) + colorette.red( " Add plugin " + colorette.yellow("name") + " to use time limit with " + colorette.yellow(++index) ) ) bench( "nanocolors", () => nanocolors.red(".") + nanocolors.yellow(".") + nanocolors.green(".") + nanocolors.bgRed(nanocolors.black(" ERROR ")) + nanocolors.red( " Add plugin " + nanocolors.yellow("name") + " to use time limit with " + nanocolors.yellow(++index) ) ) bench( "picocolors", () => picocolors.red(".") + picocolors.yellow(".") + picocolors.green(".") + picocolors.bgRed(picocolors.black(" ERROR ")) + picocolors.red( " Add plugin " + picocolors.yellow("name") + " to use time limit with " + picocolors.yellow(`${++index}`) ) ) }) await run() alexeyraspopov-picocolors-93bde36/benchmarks/loading.mjs000077500000000000000000000062471470400210300236360ustar00rootroot00000000000000/* @prettier */ import { run, bench, group } from "mitata" import { buildSync } from "esbuild" import { createRequire } from "module" import { dirname } from "path" import { createContext, compileFunction } from "vm" let filename = new URL(import.meta.url).pathname function build(contents) { let root = dirname(filename) let result = buildSync({ bundle: true, write: false, platform: "node", format: "cjs", target: "es2020", stdin: { contents, loader: "js", resolveDir: root }, }) let code = result.outputFiles[0].text return code } function compile(code, context) { return compileFunction(code, [], { parsingContext: context }) } group(() => { let codeP = build( `let picocolors = require("../picocolors.js"); console.log(picocolors != null);` ) let contextP = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("picocolors", () => compile(codeP, contextP)) let codeAC = build(`let ansi = require("ansi-colors"); console.log(ansi != null);`) let contextAC = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("ansi-colors", () => compile(codeAC, contextAC)) let codeK = build(`let kleur = require("kleur"); console.log(kleur != null);`) let contextK = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("kleur", () => compile(codeK, contextK)) let codeKC = build(`let kleurColors = require("kleur/colors"); console.log(kleurColors != null);`) let contextKC = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("kleur/colors", () => compile(codeKC, contextKC)) let codeC = build(`let colorette = require("colorette"); console.log(colorette != null);`) let contextC = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("colorette", () => compile(codeC, contextC)) let codeN = build(`let nanocolors = require("nanocolors"); console.log(nanocolors != null);`) let contextN = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("nanocolors", () => compile(codeN, contextN)) let codeY = build(`import * as yoctocolors from "yoctocolors"; console.log(yoctocolors != null);`) let contextY = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("yoctocolors", () => compile(codeY, contextY)) let codeCh = build(`let chalk = require("chalk"); console.log(chalk != null);`) let contextCh = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("chalk v4", () => compile(codeCh, contextCh)) let codeCh5 = build(`import * as chalk5 from "chalk5"; console.log(chalk5 != null);`) let contextCh5 = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("chalk v5", () => compile(codeCh5, contextCh5)) let codeCC = build(`let cliColor = require("cli-color")`) let contextCC = createContext({ require: createRequire(filename), process: { env: { FORCE_COLOR: 1 } }, }) bench("cli-color", () => compile(codeCC, contextCC)) }) await run() alexeyraspopov-picocolors-93bde36/benchmarks/recursion.mjs000066400000000000000000000026111470400210300242160ustar00rootroot00000000000000/* @prettier */ import { run, bench, summary } from "mitata" import * as colorette from "colorette" import kleur from "kleur" import * as kleurColors from "kleur/colors" import chalk from "chalk" import chalk5 from "chalk5" import ansi from "ansi-colors" import cliColor from "cli-color" import picocolors from "../picocolors.js" import * as nanocolors from "nanocolors" import * as yoctocolors from "yoctocolors" let count = 1000 let input = "lorem ipsum dolor sit amet" summary(() => { bench("chalk v4", () => { return chalk.blue(chalk.red(input).repeat(count)) }) bench("chalk v5", () => { return chalk5.blue(chalk5.red(input).repeat(count)) }) bench("cli-color", () => { return cliColor.blue(cliColor.red(input).repeat(count)) }) bench("ansi-colors", () => { return ansi.blue(ansi.red(input).repeat(count)) }) bench("kleur", () => { return kleur.blue(kleur.red(input).repeat(count)) }) bench("kleur/colors", () => { return kleurColors.blue(kleurColors.red(input).repeat(count)) }) bench("colorette", () => { return colorette.blue(colorette.red(input).repeat(count)) }) bench("nanocolors", () => { return nanocolors.blue(nanocolors.red(input).repeat(count)) }) bench("yoctocolors", () => { return yoctocolors.blue(yoctocolors.red(input).repeat(count)) }) bench("picocolors", () => { return picocolors.blue(picocolors.red(input).repeat(count)) }) }) await run() alexeyraspopov-picocolors-93bde36/benchmarks/simple.mjs000066400000000000000000000031771470400210300235060ustar00rootroot00000000000000/* @prettier */ import { run, bench, boxplot } from "mitata" import * as colorette from "colorette" import kleur from "kleur" import * as kleurColors from "kleur/colors" import chalk from "chalk" import chalk5 from "chalk5" import ansi from "ansi-colors" import cliColor from "cli-color" import picocolors from "../picocolors.js" import * as nanocolors from "nanocolors" import * as yoctocolors from "yoctocolors" console.log(colorette.green("colorette")) console.log(kleur.green("kleur")) console.log(chalk.green("chalk")) console.log(chalk5.green("chalk5")) console.log(ansi.green("ansi")) console.log(cliColor.green("cliColor")) console.log(picocolors.green("picocolors")) console.log(nanocolors.green("nanocolors")) console.log(yoctocolors.green("yoctocolors")) boxplot(() => { bench("chalk v4", () => { return chalk.red("Add plugin to use time limit") }) bench("chalk v5", () => { return chalk5.red("Add plugin to use time limit") }) bench("cli-color", () => { return cliColor.red("Add plugin to use time limit") }) bench("ansi-colors", () => { return ansi.red("Add plugin to use time limit") }) bench("kleur", () => { return kleur.red("Add plugin to use time limit") }) bench("kleur/colors", () => { return kleurColors.red("Add plugin to use time limit") }) bench("colorette", () => { return colorette.red("Add plugin to use time limit") }) bench("nanocolors", () => { return nanocolors.red("Add plugin to use time limit") }) bench("yoctocolors", () => { return yoctocolors.red("Add plugin to use time limit") }) bench("picocolors", () => { return picocolors.red("Add plugin to use time limit") }) }) await run() alexeyraspopov-picocolors-93bde36/benchmarks/size.mjs000066400000000000000000000022451470400210300231620ustar00rootroot00000000000000/* @prettier */ import { buildSync } from "esbuild" import { dirname } from "node:path" console.table({ picocolors: build(`export { default as picocolors } from "../picocolors.js"`), colorette: build(`export * as colorette from "colorette"`), "chalk v4": build(`export { default as chalk } from "chalk"`), "chalk v5": build(`export * as chalk from "chalk5"`), kleur: build(`export { default as kleur } from "kleur"`), "kleur/colors": build(`export * as kleurColors from "kleur/colors"`), "ansi-colors": build(`export { default as ansi } from "ansi-colors"`), "cli-color": build(`export { default as cliColor } from "cli-color"`), nanocolors: build(`export * as nanocolors from "nanocolors"`), yoctocolors: build(`export * as yoctocolors from "yoctocolors"`), }) function build(contents) { let root = dirname(new URL(import.meta.url).pathname) let result = buildSync({ bundle: true, write: false, minify: false, platform: "node", stdin: { contents, loader: "js", resolveDir: root }, }) let code = result.outputFiles[0].text return { "size (KB)": toKB(code.length) } } function toKB(value) { return (((value / 1024) * 100) | 0) / 100 } alexeyraspopov-picocolors-93bde36/package.json000066400000000000000000000021231470400210300216410ustar00rootroot00000000000000{ "name": "picocolors", "version": "1.1.1", "main": "./picocolors.js", "types": "./picocolors.d.ts", "browser": { "./picocolors.js": "./picocolors.browser.js" }, "sideEffects": false, "description": "The tiniest and the fastest library for terminal output formatting with ANSI colors", "scripts": { "test": "node tests/test.js" }, "files": [ "picocolors.*", "types.d.ts" ], "keywords": [ "terminal", "colors", "formatting", "cli", "console" ], "author": "Alexey Raspopov", "repository": "alexeyraspopov/picocolors", "license": "ISC", "devDependencies": { "ansi-colors": "^4.1.1", "chalk": "^4.1.2", "clean-publish": "^3.0.3", "cli-color": "^2.0.0", "colorette": "^2.0.12", "kleur": "^4.1.4", "mitata": "^1.0.10", "nanocolors": "^0.2.12", "prettier": "^3.3.3", "yoctocolors": "^2.1.1" }, "prettier": { "printWidth": 100, "useTabs": true, "tabWidth": 2, "semi": false, "arrowParens": "avoid", "requirePragma": true }, "clean-publish": { "cleanDocs": true } } alexeyraspopov-picocolors-93bde36/picocolors.browser.js000066400000000000000000000011261470400210300235510ustar00rootroot00000000000000var x=String; var create=function() {return {isColorSupported:false,reset:x,bold:x,dim:x,italic:x,underline:x,inverse:x,hidden:x,strikethrough:x,black:x,red:x,green:x,yellow:x,blue:x,magenta:x,cyan:x,white:x,gray:x,bgBlack:x,bgRed:x,bgGreen:x,bgYellow:x,bgBlue:x,bgMagenta:x,bgCyan:x,bgWhite:x,blackBright:x,redBright:x,greenBright:x,yellowBright:x,blueBright:x,magentaBright:x,cyanBright:x,whiteBright:x,bgBlackBright:x,bgRedBright:x,bgGreenBright:x,bgYellowBright:x,bgBlueBright:x,bgMagentaBright:x,bgCyanBright:x,bgWhiteBright:x}}; module.exports=create(); module.exports.createColors = create; alexeyraspopov-picocolors-93bde36/picocolors.d.ts000066400000000000000000000002121470400210300223160ustar00rootroot00000000000000import { Colors } from "./types" declare const picocolors: Colors & { createColors: (enabled?: boolean) => Colors } export = picocolors alexeyraspopov-picocolors-93bde36/picocolors.js000066400000000000000000000051471470400210300220760ustar00rootroot00000000000000let p = process || {}, argv = p.argv || [], env = p.env || {} let isColorSupported = !(!!env.NO_COLOR || argv.includes("--no-color")) && (!!env.FORCE_COLOR || argv.includes("--color") || p.platform === "win32" || ((p.stdout || {}).isTTY && env.TERM !== "dumb") || !!env.CI) let formatter = (open, close, replace = open) => input => { let string = "" + input, index = string.indexOf(close, open.length) return ~index ? open + replaceClose(string, close, replace, index) + close : open + string + close } let replaceClose = (string, close, replace, index) => { let result = "", cursor = 0 do { result += string.substring(cursor, index) + replace cursor = index + close.length index = string.indexOf(close, cursor) } while (~index) return result + string.substring(cursor) } let createColors = (enabled = isColorSupported) => { let f = enabled ? formatter : () => String return { isColorSupported: enabled, reset: f("\x1b[0m", "\x1b[0m"), bold: f("\x1b[1m", "\x1b[22m", "\x1b[22m\x1b[1m"), dim: f("\x1b[2m", "\x1b[22m", "\x1b[22m\x1b[2m"), italic: f("\x1b[3m", "\x1b[23m"), underline: f("\x1b[4m", "\x1b[24m"), inverse: f("\x1b[7m", "\x1b[27m"), hidden: f("\x1b[8m", "\x1b[28m"), strikethrough: f("\x1b[9m", "\x1b[29m"), black: f("\x1b[30m", "\x1b[39m"), red: f("\x1b[31m", "\x1b[39m"), green: f("\x1b[32m", "\x1b[39m"), yellow: f("\x1b[33m", "\x1b[39m"), blue: f("\x1b[34m", "\x1b[39m"), magenta: f("\x1b[35m", "\x1b[39m"), cyan: f("\x1b[36m", "\x1b[39m"), white: f("\x1b[37m", "\x1b[39m"), gray: f("\x1b[90m", "\x1b[39m"), bgBlack: f("\x1b[40m", "\x1b[49m"), bgRed: f("\x1b[41m", "\x1b[49m"), bgGreen: f("\x1b[42m", "\x1b[49m"), bgYellow: f("\x1b[43m", "\x1b[49m"), bgBlue: f("\x1b[44m", "\x1b[49m"), bgMagenta: f("\x1b[45m", "\x1b[49m"), bgCyan: f("\x1b[46m", "\x1b[49m"), bgWhite: f("\x1b[47m", "\x1b[49m"), blackBright: f("\x1b[90m", "\x1b[39m"), redBright: f("\x1b[91m", "\x1b[39m"), greenBright: f("\x1b[92m", "\x1b[39m"), yellowBright: f("\x1b[93m", "\x1b[39m"), blueBright: f("\x1b[94m", "\x1b[39m"), magentaBright: f("\x1b[95m", "\x1b[39m"), cyanBright: f("\x1b[96m", "\x1b[39m"), whiteBright: f("\x1b[97m", "\x1b[39m"), bgBlackBright: f("\x1b[100m", "\x1b[49m"), bgRedBright: f("\x1b[101m", "\x1b[49m"), bgGreenBright: f("\x1b[102m", "\x1b[49m"), bgYellowBright: f("\x1b[103m", "\x1b[49m"), bgBlueBright: f("\x1b[104m", "\x1b[49m"), bgMagentaBright: f("\x1b[105m", "\x1b[49m"), bgCyanBright: f("\x1b[106m", "\x1b[49m"), bgWhiteBright: f("\x1b[107m", "\x1b[49m"), } } module.exports = createColors() module.exports.createColors = createColors alexeyraspopov-picocolors-93bde36/tests/000077500000000000000000000000001470400210300205175ustar00rootroot00000000000000alexeyraspopov-picocolors-93bde36/tests/environments.js000066400000000000000000000050451470400210300236100ustar00rootroot00000000000000/* @prettier */ let vm = require("vm") let fs = require("fs") let pc = require("../picocolors.js") let assert = require("assert") let source = fs.readFileSync(__dirname + "/../picocolors.js", "utf-8") let CI = process.env.CI test("ci server", () => { let pc = initModuleEnv({ env: { TERM: "dumb", CI: "1" } }) assert.equal(pc.isColorSupported, true) assert.equal(pc.red("text"), pc.createColors(true).red("text")) }) test("arg --color", () => { let pc = initModuleEnv({ env: { TERM: "dumb" }, argv: ["--color"] }) assert.equal(pc.isColorSupported, true) assert.equal(pc.red("text"), pc.createColors(true).red("text")) }) test("env NO_COLOR", () => { let pc = initModuleEnv({ env: { FORCE_COLOR: "1", NO_COLOR: "1" } }) assert.equal(pc.isColorSupported, false) assert.equal(pc.red("text"), pc.createColors(false).red("text")) }) test("env NO_COLOR empty", () => { let pc = initModuleEnv({ env: { NO_COLOR: "", CI } }) assert.equal(pc.isColorSupported, true) assert.equal(pc.red("text"), pc.createColors(true).red("text")) }) test("env FORCE_COLOR", () => { let pc = initModuleEnv({ env: { TERM: "dumb", FORCE_COLOR: "1" } }) assert.equal(pc.isColorSupported, true) assert.equal(pc.red("text"), pc.createColors(true).red("text")) }) test("arg --no-color", () => { let pc = initModuleEnv({ env: { FORCE_COLOR: "1" }, argv: ["--no-color"] }) assert.equal(pc.isColorSupported, false) assert.equal(pc.red("text"), pc.createColors(false).red("text")) }) test("no term", () => { let pc = initModuleEnv({ env: { TERM: "dumb" } }) assert.equal(pc.isColorSupported, false) assert.equal(pc.red("text"), pc.createColors(false).red("text")) }) test("windows", () => { let pc = initModuleEnv({ env: { TERM: "dumb" }, platform: "win32" }) assert.equal(pc.isColorSupported, true) assert.equal(pc.red("text"), pc.createColors(true).red("text")) }) test("edge runtime", () => { let pc = initModuleEnv({ env: { FORCE_COLOR: "1" }, argv: undefined, require: undefined }) assert.equal(pc.isColorSupported, true) assert.equal(pc.red("text"), pc.createColors(true).red("text")) }) function test(name, fn) { try { fn() console.log(pc.green("✓ " + name)) } catch (error) { console.log(pc.red("✗ " + name)) throw error } } function initModuleEnv({ env, argv = [], platform = "darwin", require = global.require, stdout = process.stdout, }) { let process = { env, argv, platform, stdout } let context = vm.createContext({ require, process, module: { exports: {} } }) let script = new vm.Script(source) script.runInContext(context) return context.module.exports } alexeyraspopov-picocolors-93bde36/tests/test.js000066400000000000000000000103561470400210300220410ustar00rootroot00000000000000/* @prettier */ let pc = require("../picocolors.js") let assert = require("assert") const FMT = { reset: ["\x1b[0m", "\x1b[0m"], bold: ["\x1b[1m", "\x1b[22m"], dim: ["\x1b[2m", "\x1b[22m"], italic: ["\x1b[3m", "\x1b[23m"], underline: ["\x1b[4m", "\x1b[24m"], inverse: ["\x1b[7m", "\x1b[27m"], hidden: ["\x1b[8m", "\x1b[28m"], strikethrough: ["\x1b[9m", "\x1b[29m"], black: ["\x1b[30m", "\x1b[39m"], red: ["\x1b[31m", "\x1b[39m"], green: ["\x1b[32m", "\x1b[39m"], yellow: ["\x1b[33m", "\x1b[39m"], blue: ["\x1b[34m", "\x1b[39m"], magenta: ["\x1b[35m", "\x1b[39m"], cyan: ["\x1b[36m", "\x1b[39m"], white: ["\x1b[37m", "\x1b[39m"], gray: ["\x1b[90m", "\x1b[39m"], bgBlack: ["\x1b[40m", "\x1b[49m"], bgRed: ["\x1b[41m", "\x1b[49m"], bgGreen: ["\x1b[42m", "\x1b[49m"], bgYellow: ["\x1b[43m", "\x1b[49m"], bgBlue: ["\x1b[44m", "\x1b[49m"], bgMagenta: ["\x1b[45m", "\x1b[49m"], bgCyan: ["\x1b[46m", "\x1b[49m"], bgWhite: ["\x1b[47m", "\x1b[49m"], blackBright: ["\x1b[90m", "\x1b[39m"], redBright: ["\x1b[91m", "\x1b[39m"], greenBright: ["\x1b[92m", "\x1b[39m"], yellowBright: ["\x1b[93m", "\x1b[39m"], blueBright: ["\x1b[94m", "\x1b[39m"], magentaBright: ["\x1b[95m", "\x1b[39m"], cyanBright: ["\x1b[96m", "\x1b[39m"], whiteBright: ["\x1b[97m", "\x1b[39m"], bgBlackBright: ["\x1b[100m", "\x1b[49m"], bgRedBright: ["\x1b[101m", "\x1b[49m"], bgGreenBright: ["\x1b[102m", "\x1b[49m"], bgYellowBright: ["\x1b[103m", "\x1b[49m"], bgBlueBright: ["\x1b[104m", "\x1b[49m"], bgMagentaBright: ["\x1b[105m", "\x1b[49m"], bgCyanBright: ["\x1b[106m", "\x1b[49m"], bgWhiteBright: ["\x1b[107m", "\x1b[49m"], } test("color matching", () => { for (let format in FMT) { assert.equal(pc[format]("string"), FMT[format][0] + "string" + FMT[format][1]) console.log(pc[format]("testing: " + format)) } }) test("format/color nesting", () => { assert.equal( pc.bold(`BOLD ${pc.red(`RED ${pc.dim("DIM")} RED`)} BOLD`), FMT.bold[0] + "BOLD " + FMT.red[0] + "RED " + FMT.dim[0] + "DIM" + FMT.dim[1] + FMT.bold[0] + " RED" + FMT.red[1] + " BOLD" + FMT.bold[1] ) }) test("proper wrapping", () => { assert.equal( pc.red(pc.bold("==TEST==")), FMT.red[0] + FMT.bold[0] + "==TEST==" + FMT.bold[1] + FMT.red[1] ) }) test("complex case of wrapping", () => { assert.equal( pc.bold(pc.yellow(pc.bgRed(pc.italic("==TEST==")))), FMT.bold[0] + FMT.yellow[0] + FMT.bgRed[0] + FMT.italic[0] + "==TEST==" + FMT.italic[1] + FMT.bgRed[1] + FMT.yellow[1] + FMT.bold[1] ) assert.equal( pc.cyan(pc.bold(pc.underline("==TEST=="))), FMT.cyan[0] + FMT.bold[0] + FMT.underline[0] + "==TEST==" + FMT.underline[1] + FMT.bold[1] + FMT.cyan[1] ) }) test("close sequence replacement", () => { assert.equal( pc.red(`foo ${pc.yellow("bar")} baz`), FMT.red[0] + "foo " + FMT.yellow[0] + "bar" + FMT.red[0] + " baz" + FMT.red[1] ) assert.equal( pc.bold(`foo ${pc.red(pc.dim("bar"))} baz`), FMT.bold[0] + "foo " + FMT.red[0] + FMT.dim[0] + "bar" + FMT.dim[1] + FMT.bold[0] + FMT.red[1] + " baz" + FMT.bold[1] ) assert.equal( pc.yellow(`foo ${pc.red(pc.bold("red"))} bar ${pc.cyan("cyan")} baz`), FMT.yellow[0] + "foo " + FMT.red[0] + FMT.bold[0] + "red" + FMT.bold[1] + FMT.yellow[0] + " bar " + FMT.cyan[0] + "cyan" + FMT.yellow[0] + " baz" + FMT.yellow[1] ) }) test("non-string input", () => { assert.equal(pc.red(), FMT.red[0] + "undefined" + FMT.red[1]) assert.equal(pc.red(undefined), FMT.red[0] + "undefined" + FMT.red[1]) assert.equal(pc.red(0), FMT.red[0] + "0" + FMT.red[1]) assert.equal(pc.red(NaN), FMT.red[0] + "NaN" + FMT.red[1]) assert.equal(pc.red(null), FMT.red[0] + "null" + FMT.red[1]) assert.equal(pc.red(true), FMT.red[0] + "true" + FMT.red[1]) assert.equal(pc.red(false), FMT.red[0] + "false" + FMT.red[1]) assert.equal(pc.red(Infinity), FMT.red[0] + "Infinity" + FMT.red[1]) }) test("shouldn't overflow when coloring already colored large text", () => { try { pc.blue(pc.red("x").repeat(10000)) assert(true) } catch (error) { console.error(error) assert(false) } }) function test(name, fn) { try { fn() console.log(pc.green("✓ " + name)) } catch (error) { console.log(pc.red("✗ " + name)) throw error } } alexeyraspopov-picocolors-93bde36/types.d.ts000066400000000000000000000017651470400210300213240ustar00rootroot00000000000000export type Formatter = (input: string | number | null | undefined) => string export interface Colors { isColorSupported: boolean reset: Formatter bold: Formatter dim: Formatter italic: Formatter underline: Formatter inverse: Formatter hidden: Formatter strikethrough: Formatter black: Formatter red: Formatter green: Formatter yellow: Formatter blue: Formatter magenta: Formatter cyan: Formatter white: Formatter gray: Formatter bgBlack: Formatter bgRed: Formatter bgGreen: Formatter bgYellow: Formatter bgBlue: Formatter bgMagenta: Formatter bgCyan: Formatter bgWhite: Formatter blackBright: Formatter redBright: Formatter greenBright: Formatter yellowBright: Formatter blueBright: Formatter magentaBright: Formatter cyanBright: Formatter whiteBright: Formatter bgBlackBright: Formatter bgRedBright: Formatter bgGreenBright: Formatter bgYellowBright: Formatter bgBlueBright: Formatter bgMagentaBright: Formatter bgCyanBright: Formatter bgWhiteBright: Formatter }