webdiscus / ansis Goto Github PK
View Code? Open in Web Editor NEWSmall and fast Node.js lib to colorize terminal output. Lightweight but powerful alternative to Chalk. Supports Bun, Deno, Next.JS.
License: ISC License
Small and fast Node.js lib to colorize terminal output. Lightweight but powerful alternative to Chalk. Supports Bun, Deno, Next.JS.
License: ISC License
When using Ansis inside Next.js's middleware.ts
file, colours aren't enabled.
Colours shown in terminal when using Ansis in a Next.js edge function.
I've narrowed this down to this line:
Line 29 in 7fca74c
process.stdout
not being available in Next.js's middleware. Is the stdout && 'isTTY' in stdout
necessary if you also require the /^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)
to pass?Hello @webdiscus ,
What is motivation or use case for adding/changing the behavior?
I found out that color detection does not work when running an application using PM2 process manager.
I managed to debug it to the line
Line 47 in 9f78e35
The reason is that process.stdout
does not have isTTY
property.
Line 124 in 9f78e35
PM2 uses log files to write the process output and the colors support depends on the terminal used.
So, despite following process.env
variables colors do not appear:
COLORTERM: 'truecolor',
LC_TERMINAL: 'iTerm2',
TERM: 'xterm-256color',
Describe the solution you'd like
I'd like to request an exception for PM2 case that can be identified by the following two process.env
variables:
const isPM2 = "PM2_HOME" in env && "pm_id" in env;
So that the line 47 could look this way:
if ((!isTTY && !isPM2) || /-mono|dumb/i.test(term)) return SPACE_MONO;
Then this statement would be skipped for PM2 case and the actual terminal would be detected.
Describe alternatives you've considered
I tried using FORCE_COLOR
env — it works, but since I'm actually developing a library for consumer applications, I'd like to avoid that. I also tried the PM2 detection approach inside by library that is using ansis
, but it can not work because getColorSpace()
is executed immediately after import, so I can not alter process.env
in advance from the library I work on.
However, I'm open to any suggestions and discussions in this regard.
What do you think, @webdiscus ?
Describe the bug
Support British English spelling of gray
.
To Reproduce
Support British english grey
Additional context
Thank you for work you've done here. This is a brilliant CLI colour variant. Top stuff.
Describe the bug
After updating my packages, Ansis 1.5 is pulled in and then fails with this message:
Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in XXXXXX/node_modules/ansis/package.json
> NODE_ENV=production webpack --config .config/webpack.config.prod.js
[webpack-cli] Failed to load 'XXXX/.config/webpack.config.prod.js' config
[webpack-cli] Error [ERR_PACKAGE_PATH_NOT_EXPORTED]: No "exports" main defined in XXXX/node_modules/ansis/package.json
at new NodeError (node:internal/errors:372:5)
at throwExportsNotFound (node:internal/modules/esm/resolve:472:9)
at packageExportsResolve (node:internal/modules/esm/resolve:693:7)
at resolveExports (node:internal/modules/cjs/loader:482:36)
at Function.Module._findPath (node:internal/modules/cjs/loader:522:31)
at Function.Module._resolveFilename (node:internal/modules/cjs/loader:919:27)
at Function.Module._load (node:internal/modules/cjs/loader:778:27)
at Module.require (node:internal/modules/cjs/loader:1005:19)
at require (node:internal/modules/cjs/helpers:102:18)
at Object.<anonymous> (XXXX/node_modules/webpack-remove-empty-scripts/src/index.js:6:15) {
code: 'ERR_PACKAGE_PATH_NOT_EXPORTED'
}
❯ npm explain ansis
[email protected] devn
node_modules/ansis
ansis@"^1.4.0" from [email protected]
node_modules/webpack-remove-empty-scripts
webpack-remove-empty-scripts@"^0.8.0" from @humanmade/[email protected]
node_modules/@humanmade/webpack-helpers
dev @humanmade/webpack-helpers@"1.0.0-beta.16" from the root project
To Reproduce
Not clear at the moment if this is a universal issue or limited to a specific use case, only just encountered the problem
Expected behavior
I only became aware of the package when updating and encountering this message.
Dev Environment (please complete the following information):
Additional context
Add any other context about the problem here.
I am leveraging ansis and appreciate the work you've done here but I have a couple of pain points and I'd like to suggest some minor refactors to improve how the module is used and generally just provide a better experience overall.
The current approach is to have ansis export on the default but this is not always ideal. In order to obtain a single colour one needs to do the following:
import ansis from 'ansis';
console.log(`Print ${ansis.yellow('I am yellow')}`)
While this suffices, it can get a little cumbersome and a better option would be to provide an additional import/file that exposes the defaults as named exports, for example:
import { yellow } from 'ansis/colors';
console.log(`Print ${yellow('I am yellow')}`)
OR alternatively, you could expose the named exports directly and still preserve the default, eg:
import ansis, { red } from 'ansis';
console.log(`Print ${ansis.yellow('I am yellow')} and ${red('I am red')}`)
Supporting this is trivial, you can simply add them to the exports, eg:
// ....
const ansis = new Ansis();
export const {
cyan,
cyanBright,
red,
redBright,
green,
greenBright,
yellow,
yellowBright,
magenta,
magentaBright,
blue,
blueBright,
white,
whiteBright,
gray,
underline,
bold,
reset,
italic,
strike
// etc etc etc
} = ansis;
export default ansis
It would be nice to have types available for additional usage. I have various functions which construct log output and accept colour parameters which I pass to ansis. In order for folks to take advantage of intellisense capabilities having a reference of the defaults would be a great help. Take the following sample:
import ansis from 'ansis'
export const write = (colour: string, message: string) => {
message += fn(message) // do something
console.log(ansis[colour](message);
}
Currently, there is no exposed type refs for colors that ansis provides. Where the parameter colour
expects a string
a far better approach is to have this available in the declaration, eg:
import ansis, { Colors } from 'ansis' // using US english for the sake of brevity
export const write = (colour: Colors, message: string) => {
message += fn(message) // do something
console.log(ansis[colour](message))
}
This is rather simple to provide, here is a starting point:
/**
* Default Colors
*/
export type Colors = (
| 'cyan'
| 'cyanBright'
| 'red'
| 'redBright'
| 'green'
| 'greenBright'
| 'yellow'
| 'yellowBright'
| 'magenta'
| 'magentaBright'
| 'blue'
| 'blueBright'
| 'white'
| 'whiteBright'
| 'gray'
| 'underline'
| 'bold'
| 'reset'
| 'italic'
| 'strike'
// etc etc etc
);
An even better approach would be:
type StringUnion<T, B extends string> = T | (B & Record<never, never>);
export type Colors = (
| 'cyan'
| 'cyanBright'
| 'red'
| 'redBright'
| 'green'
| 'greenBright'
| 'yellow'
| 'yellowBright'
| 'magenta'
| 'magentaBright'
| 'blue'
| 'blueBright'
| 'white'
| 'whiteBright'
| 'gray'
| 'underline'
| 'bold'
| 'reset'
| 'italic'
| 'strike'
// etc etc
)
export type ColorsExtend<T extends string> = StringUnion<Colors, T>;
The above ColorsExtend
would allow for consumers to extend the defaults with any custom colours generated in their projects, using the initial sample and the above types you could then do:
import ansis, { ColorsExtend } from 'ansis'
const pink = ansis.hex('#ff75d1');
const orange = ansis.hex('#FFAB40');
export const write = (colour: ColorsExtend<'pink' | 'orange'>, message: string) => {
message += fn(message) // do something
console.log(ansis[colour](message))
}
Thanks
Describe the bug
It looks like the recently released version (1.3.5) is broken. The published package.json points to src/index.js
while the published code lives in the dist directory.
This is probably breaking a bunch of packages that depends on this package.
To Reproduce
If issue is small you can add the code block to commentary.
Preferably, create a bug repository with reproducible problems.
Expected behavior
A clear and concise description of what you expected to happen.
Dev Environment (please complete the following information):
Additional context
Add any other context about the problem here.
Great work on this library!
What is motivation or use case for adding/changing the behavior?
chalk exposes supportsColor
which is useful to understand if colors are supported without needing to duplicate logic:
https://www.npmjs.com/package/chalk#supportscolor
Describe the solution you'd like
Either a supportsColor
export or hasColor
which is already used internally:
Line 5 in c1ef85e
Describe alternatives you've considered
Duplicating code :)
When using hex()
method in a terminal having only 256 colors, the following things happen:
import { ansi256, hex, white } from "ansis";
const pink = hex("#F5A9B8");
const blue = hex("#5BCEFA");
// running in 256 colors mode
console.log(ansi256(199)("Color 199")); // works
console.log(pink("This should be pink")); // no fallback to 256
console.log(blue("This should be blue")); // no fallback to 256, wrong color
console.log("This should be default"); // does not return to default color
console.log(white("Forced white")); // can not even force white
Using built-in Terminal on MacOS having 256 colors.
For comparison, this is how it looks when running in iTerm having true color support
Here is a similar code, but using chalk
v4.1.2
import chalk from "chalk";
const pink = chalk.hex("#F5A9B8");
const blue = chalk.hex("#5BCEFA");
console.log(chalk.ansi256(199)("Color 199"));
console.log(pink("This should be pink"));
console.log(blue("This should be blue"));
console.log("This should be default");
console.log(chalk.whiteBright("Forced white"));
Running it in built-in Terminal on MacOS having 256 colors gives the desirable output:
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.