colorino 0.15.4 → 0.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/node.mjs CHANGED
@@ -100,21 +100,9 @@ class AbstractColorino {
100
100
  };
101
101
  }
102
102
  const ansiPrefix = this._toAnsiPrefix(hex);
103
- if (!ansiPrefix) {
104
- return text;
105
- }
103
+ if (!ansiPrefix) return text;
106
104
  return `${ansiPrefix}${text}\x1B[0m`;
107
105
  }
108
- _out(level, args) {
109
- const consoleMethod = TypeValidator.isConsoleMethod(level) ? level : "log";
110
- const processedArgs = this._processArgs(args);
111
- if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
112
- this._output(consoleMethod, processedArgs);
113
- return;
114
- }
115
- const coloredArgs = this._applyColors(consoleMethod, processedArgs);
116
- this._output(consoleMethod, coloredArgs);
117
- }
118
106
  _toAnsiPrefix(_hex) {
119
107
  return "";
120
108
  }
@@ -166,6 +154,16 @@ ${cleanStack}`);
166
154
  console.log(...args);
167
155
  }
168
156
  }
157
+ _out(level, args) {
158
+ const consoleMethod = TypeValidator.isConsoleMethod(level) ? level : "log";
159
+ const processedArgs = this._processArgs(args);
160
+ if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
161
+ this._output(consoleMethod, processedArgs);
162
+ return;
163
+ }
164
+ const coloredArgs = this._applyColors(consoleMethod, processedArgs);
165
+ this._output(consoleMethod, coloredArgs);
166
+ }
169
167
  }
170
168
 
171
169
  function hexToRgb(hex) {
@@ -212,17 +210,60 @@ function rgbToAnsi16(rgb) {
212
210
  }
213
211
  return ansi;
214
212
  }
213
+ function interpolateRgb(startRgb, endRgb, steps) {
214
+ if (steps === 1) return [startRgb];
215
+ if (steps === 2) return [startRgb, endRgb];
216
+ const colors = [];
217
+ for (let i = 0; i < steps; i++) {
218
+ const ratio = i / (steps - 1);
219
+ const r = Math.round(startRgb[0] + (endRgb[0] - startRgb[0]) * ratio);
220
+ const g = Math.round(startRgb[1] + (endRgb[1] - startRgb[1]) * ratio);
221
+ const b = Math.round(startRgb[2] + (endRgb[2] - startRgb[2]) * ratio);
222
+ colors.push([r, g, b]);
223
+ }
224
+ return colors;
225
+ }
226
+ function hexGradient(startHex, endHex, steps) {
227
+ const startRgb = hexToRgb(startHex);
228
+ const endRgb = hexToRgb(endHex);
229
+ return interpolateRgb(startRgb, endRgb, steps);
230
+ }
215
231
  const colorConverter = {
216
232
  hex: {
217
233
  toRgb: hexToRgb,
218
234
  toAnsi16: (hex) => rgbToAnsi16(hexToRgb(hex)),
219
- toAnsi256: (hex) => rgbToAnsi256(hexToRgb(hex))
235
+ toAnsi256: (hex) => rgbToAnsi256(hexToRgb(hex)),
236
+ gradient: hexGradient
237
+ },
238
+ rgb: {
239
+ toAnsi16: rgbToAnsi16,
240
+ toAnsi256: rgbToAnsi256,
241
+ interpolate: interpolateRgb
220
242
  }};
221
243
 
222
244
  class ColorinoNode extends AbstractColorino {
223
245
  constructor(initialPalette, userPalette, validator, colorLevel, options = {}) {
224
246
  super(initialPalette, userPalette, validator, colorLevel, options);
225
247
  }
248
+ gradient(text, startHex, endHex) {
249
+ if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv" || this._colorLevel === ColorLevel.ANSI) {
250
+ return text;
251
+ }
252
+ const characters = [...text];
253
+ const rgbColors = colorConverter.hex.gradient(
254
+ startHex,
255
+ endHex,
256
+ characters.length
257
+ );
258
+ return characters.map((char, index) => {
259
+ const [r, g, b] = rgbColors[index] ?? [0, 0, 0];
260
+ if (this._colorLevel === ColorLevel.TRUECOLOR) {
261
+ return `\x1B[38;2;${r};${g};${b}m${char}`;
262
+ }
263
+ const code = colorConverter.rgb.toAnsi256([r, g, b]);
264
+ return `\x1B[38;5;${code}m${char}`;
265
+ }).join("") + "\x1B[0m";
266
+ }
226
267
  _applyColors(consoleMethod, args) {
227
268
  const paletteHex = this._palette[consoleMethod];
228
269
  const prefix = this._toAnsiPrefix(paletteHex);
@@ -399,15 +440,7 @@ class InputValidator {
399
440
  }
400
441
 
401
442
  const __dirname$1 = dirname(fileURLToPath(import.meta.url));
402
- let alreadyWarned = false;
403
- function getTerminalThemeSync(areWarningsDisabled) {
404
- const maybeWarnUser = () => {
405
- if (alreadyWarned || areWarningsDisabled) return;
406
- alreadyWarned = true;
407
- console.warn(
408
- "Consider switching the console (Win: Terminal is best) or disabling oscProbe by adding disableOscProbe = true to the options passed into createColorino()."
409
- );
410
- };
443
+ function getTerminalThemeSync() {
411
444
  const scriptPath = join(__dirname$1, "osc-child-probe.js");
412
445
  const result = spawnSync(process.execPath, [scriptPath], {
413
446
  stdio: ["inherit", "pipe", "inherit"],
@@ -415,20 +448,17 @@ function getTerminalThemeSync(areWarningsDisabled) {
415
448
  timeout: 1500
416
449
  });
417
450
  if (result.error || result.status !== 0) {
418
- maybeWarnUser();
419
451
  return "unknown";
420
452
  }
421
453
  const output = result.stdout.trim();
422
454
  if (output === "dark" || output === "light") {
423
455
  return output;
424
456
  }
425
- maybeWarnUser();
426
457
  return "unknown";
427
458
  }
428
459
 
429
460
  class NodeColorSupportDetector {
430
- constructor(_areWarningsDisabled, _process, _overrideTheme, _disableOscProbe = false) {
431
- this._areWarningsDisabled = _areWarningsDisabled;
461
+ constructor(_process, _overrideTheme, _disableOscProbe = false) {
432
462
  this._process = _process;
433
463
  this._overrideTheme = _overrideTheme;
434
464
  this._disableOscProbe = _disableOscProbe;
@@ -438,11 +468,6 @@ class NodeColorSupportDetector {
438
468
  }
439
469
  if (!this.isNodeEnv()) {
440
470
  this._theme = "unknown";
441
- if (_areWarningsDisabled && !this._alreadyWarned)
442
- this._alreadyWarned = true;
443
- console.warn(
444
- "NodeColorSupportDetector() called in an env without process API. Don't do this."
445
- );
446
471
  return;
447
472
  }
448
473
  this._isTTY = !!_process.stdout.isTTY;
@@ -456,14 +481,9 @@ class NodeColorSupportDetector {
456
481
  this._envWtSession = processEnv["WT_SESSION"];
457
482
  if (!this._isTTY || this._disableOscProbe) {
458
483
  this._theme = "unknown";
459
- if (_areWarningsDisabled && !this._alreadyWarned)
460
- this._alreadyWarned = true;
461
- console.warn(
462
- "No theme detected, because of TTY env or disabled OSC probe."
463
- );
464
484
  return;
465
485
  }
466
- this._theme = getTerminalThemeSync(_areWarningsDisabled);
486
+ this._theme = getTerminalThemeSync();
467
487
  }
468
488
  _envForceColor;
469
489
  _envTerm;
@@ -474,7 +494,6 @@ class NodeColorSupportDetector {
474
494
  _envWtSession;
475
495
  _isTTY;
476
496
  _theme;
477
- _alreadyWarned;
478
497
  isNodeEnv() {
479
498
  return typeof this._process !== "undefined";
480
499
  }
@@ -547,7 +566,6 @@ function createColorino(userPalette = {}, options = {}) {
547
566
  detectorThemeOverride = "unknown";
548
567
  }
549
568
  const nodeDetector = new NodeColorSupportDetector(
550
- !!options.disableWarnings,
551
569
  process,
552
570
  detectorThemeOverride,
553
571
  options.disableOscProbe ?? false
@@ -0,0 +1,66 @@
1
+ const stdin = process.stdin
2
+ const stdout = process.stdout
3
+ const stderr = process.stderr
4
+
5
+ if (!stdin.isTTY || !stdin.setRawMode) {
6
+ stdout.write('unknown\n')
7
+ process.exit(0)
8
+ }
9
+
10
+ let buffer = ''
11
+ let done = false
12
+
13
+ const finish = theme => {
14
+ if (done) return
15
+ done = true
16
+
17
+ stdin.removeListener('data', onData)
18
+ try {
19
+ stdin.setRawMode(false)
20
+ } catch {}
21
+ stdin.pause()
22
+
23
+ stdout.write(theme + '\n')
24
+ process.exit(0)
25
+ }
26
+
27
+ const onData = chunk => {
28
+ buffer += chunk.toString('utf8')
29
+
30
+ if (
31
+ !buffer.includes(']11;rgb:') ||
32
+ (!buffer.includes('\x07') && !buffer.includes('\x1b\\'))
33
+ )
34
+ return
35
+
36
+ const match = buffer.match(
37
+ /rgb:([0-9a-f]{2,4})\/([0-9a-f]{2,4})\/([0-9a-f]{2,4})/i
38
+ )
39
+ if (!match) {
40
+ finish('unknown')
41
+ return
42
+ }
43
+
44
+ const normalize = hex => {
45
+ const value = parseInt(hex, 16)
46
+ const max = (1 << (4 * hex.length)) - 1
47
+ return Math.round((value / max) * 255)
48
+ }
49
+
50
+ const red = normalize(match[1])
51
+ const green = normalize(match[2])
52
+ const blue = normalize(match[3])
53
+ const luminance = (0.299 * red + 0.587 * green + 0.114 * blue) / 255
54
+
55
+ finish(luminance < 0.5 ? 'dark' : 'light')
56
+ }
57
+
58
+ stdin.on('data', onData)
59
+ stdin.setRawMode(true)
60
+ stdin.resume()
61
+
62
+ stderr.write('\x1b]11;?\x07')
63
+
64
+ setTimeout(() => {
65
+ finish('unknown')
66
+ }, 300)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "colorino",
3
- "version": "0.15.4",
3
+ "version": "0.16.0",
4
4
  "description": "A super simple colorized logger that gets the most out of your terminal",
5
5
  "keywords": [
6
6
  "ansi",