@mks2508/better-logger 3.0.0 → 4.0.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/.claude/settings.local.json +3 -1
- package/CHANGELOG.json +98 -1
- package/dist/Logger.d.ts +24 -12
- package/dist/Logger.d.ts.map +1 -1
- package/dist/chunks/{Logger-C126NTrD.js → Logger-D-gmmgR2.js} +207 -18
- package/dist/chunks/Logger-D-gmmgR2.js.map +1 -0
- package/dist/chunks/Logger-D7cfaz15.js +2 -0
- package/dist/chunks/Logger-D7cfaz15.js.map +1 -0
- package/dist/chunks/{environment-TI2ByCPT.js → environment-COWvu6Wz.js} +466 -98
- package/dist/chunks/environment-COWvu6Wz.js.map +1 -0
- package/dist/chunks/environment-C_8J-zQ_.js +4 -0
- package/dist/chunks/environment-C_8J-zQ_.js.map +1 -0
- package/dist/chunks/{formatting-CuNUqGks.js → formatting-CYjT9yhO.js} +2 -2
- package/dist/chunks/{formatting-CuNUqGks.js.map → formatting-CYjT9yhO.js.map} +1 -1
- package/dist/chunks/{formatting-Blwy-f0W.js → formatting-Cg5YhB9Y.js} +2 -2
- package/dist/chunks/{formatting-Blwy-f0W.js.map → formatting-Cg5YhB9Y.js.map} +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.js +2 -2
- package/dist/exports.cjs +1 -1
- package/dist/exports.js +2 -2
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +10 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +151 -20
- package/dist/index.js.map +1 -1
- package/dist/styling.cjs +1 -1
- package/dist/styling.js +3 -3
- package/dist/terminal/color-converter.d.ts +73 -0
- package/dist/terminal/color-converter.d.ts.map +1 -0
- package/dist/terminal/formatter.d.ts +20 -0
- package/dist/terminal/formatter.d.ts.map +1 -0
- package/dist/terminal/terminal-renderer.d.ts +20 -6
- package/dist/terminal/terminal-renderer.d.ts.map +1 -1
- package/dist/types/core.d.ts +61 -0
- package/dist/types/core.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/utils/environment-detector.d.ts +10 -0
- package/dist/utils/environment-detector.d.ts.map +1 -1
- package/dist/writers/BufferWriter.d.ts +96 -0
- package/dist/writers/BufferWriter.d.ts.map +1 -0
- package/dist/writers/index.d.ts +6 -0
- package/dist/writers/index.d.ts.map +1 -0
- package/package.json +1 -1
- package/packages/core/package.json +1 -1
- package/packages/styling/package.json +2 -2
- package/src/Logger.ts +63 -21
- package/src/index.ts +61 -2
- package/src/terminal/color-converter.ts +315 -0
- package/src/terminal/formatter.ts +236 -0
- package/src/terminal/terminal-renderer.ts +74 -79
- package/src/types/core.ts +68 -0
- package/src/types/index.ts +5 -0
- package/src/utils/environment-detector.ts +23 -1
- package/src/writers/BufferWriter.ts +157 -0
- package/src/writers/index.ts +6 -0
- package/dist/chunks/Logger-BCfx_yCK.js +0 -2
- package/dist/chunks/Logger-BCfx_yCK.js.map +0 -1
- package/dist/chunks/Logger-C126NTrD.js.map +0 -1
- package/dist/chunks/environment-Ba5kShbx.js +0 -4
- package/dist/chunks/environment-Ba5kShbx.js.map +0 -1
- package/dist/chunks/environment-TI2ByCPT.js.map +0 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/writers/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,YAAY,EAAE,KAAK,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mks2508/better-logger",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "4.0.0",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Logger avanzado para consola con estilos CSS, temas adaptativos, badges automáticos, SVG, animaciones, CLI integrado y soporte dual browser/terminal con colores ANSI",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mks2508/better-logger-core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.1-alpha.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Universal core logging functionality for Better Logger - Works in both Node.js and browser environments",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mks2508/better-logger-styling",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.16.0-alpha.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Advanced CSS styling system for Better Logger - Console styling with gradients, animations and SVG support",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -36,6 +36,6 @@
|
|
|
36
36
|
"README.md"
|
|
37
37
|
],
|
|
38
38
|
"peerDependencies": {
|
|
39
|
-
"@mks2508/better-logger-core": "^0.
|
|
39
|
+
"@mks2508/better-logger-core": "^0.16.0-alpha.1"
|
|
40
40
|
}
|
|
41
41
|
}
|
package/src/Logger.ts
CHANGED
|
@@ -36,7 +36,8 @@ import { TransportManager } from './transports/index.js';
|
|
|
36
36
|
import { parseStackTrace } from './utils/stackTrace.js';
|
|
37
37
|
import { formatTimestamp } from './utils/timestamps.js';
|
|
38
38
|
import { createStyledOutput, setupThemeChangeListener } from './utils/output.js';
|
|
39
|
-
import { getEnvironment } from './utils/environment-detector.js';
|
|
39
|
+
import { getEnvironment, getColorCapability } from './utils/environment-detector.js';
|
|
40
|
+
import { formatBadge } from './terminal/formatter.js';
|
|
40
41
|
|
|
41
42
|
// Styling imports
|
|
42
43
|
import {
|
|
@@ -420,9 +421,9 @@ export class Logger {
|
|
|
420
421
|
*
|
|
421
422
|
* @since 0.3.0
|
|
422
423
|
*/
|
|
423
|
-
hideTimestamp():
|
|
424
|
+
hideTimestamp(): this {
|
|
424
425
|
this.displaySettings.showTimestamp = false;
|
|
425
|
-
this
|
|
426
|
+
return this;
|
|
426
427
|
}
|
|
427
428
|
|
|
428
429
|
/**
|
|
@@ -434,9 +435,9 @@ export class Logger {
|
|
|
434
435
|
*
|
|
435
436
|
* @since 0.3.0
|
|
436
437
|
*/
|
|
437
|
-
showTimestamp():
|
|
438
|
+
showTimestamp(): this {
|
|
438
439
|
this.displaySettings.showTimestamp = true;
|
|
439
|
-
this
|
|
440
|
+
return this;
|
|
440
441
|
}
|
|
441
442
|
|
|
442
443
|
/**
|
|
@@ -448,9 +449,9 @@ export class Logger {
|
|
|
448
449
|
*
|
|
449
450
|
* @since 0.3.0
|
|
450
451
|
*/
|
|
451
|
-
hideLocation():
|
|
452
|
+
hideLocation(): this {
|
|
452
453
|
this.displaySettings.showLocation = false;
|
|
453
|
-
this
|
|
454
|
+
return this;
|
|
454
455
|
}
|
|
455
456
|
|
|
456
457
|
/**
|
|
@@ -462,9 +463,9 @@ export class Logger {
|
|
|
462
463
|
*
|
|
463
464
|
* @since 0.3.0
|
|
464
465
|
*/
|
|
465
|
-
showLocation():
|
|
466
|
+
showLocation(): this {
|
|
466
467
|
this.displaySettings.showLocation = true;
|
|
467
|
-
this
|
|
468
|
+
return this;
|
|
468
469
|
}
|
|
469
470
|
|
|
470
471
|
/**
|
|
@@ -477,9 +478,9 @@ export class Logger {
|
|
|
477
478
|
*
|
|
478
479
|
* @since 0.3.0
|
|
479
480
|
*/
|
|
480
|
-
hideBadges():
|
|
481
|
+
hideBadges(): this {
|
|
481
482
|
this.displaySettings.showBadges = false;
|
|
482
|
-
this
|
|
483
|
+
return this;
|
|
483
484
|
}
|
|
484
485
|
|
|
485
486
|
/**
|
|
@@ -492,9 +493,9 @@ export class Logger {
|
|
|
492
493
|
*
|
|
493
494
|
* @since 0.3.0
|
|
494
495
|
*/
|
|
495
|
-
showBadges():
|
|
496
|
+
showBadges(): this {
|
|
496
497
|
this.displaySettings.showBadges = true;
|
|
497
|
-
this
|
|
498
|
+
return this;
|
|
498
499
|
}
|
|
499
500
|
|
|
500
501
|
/**
|
|
@@ -942,12 +943,8 @@ export class Logger {
|
|
|
942
943
|
const groupIndent = ' '.repeat(this.groupDepth);
|
|
943
944
|
const finalFormat = groupIndent + format;
|
|
944
945
|
|
|
945
|
-
// Output
|
|
946
|
-
|
|
947
|
-
console.log(finalFormat, ...styles, ...additionalArgs);
|
|
948
|
-
} else {
|
|
949
|
-
console.log(finalFormat, ...styles);
|
|
950
|
-
}
|
|
946
|
+
// Output via configured writer (console by default)
|
|
947
|
+
this.writeOutput(finalFormat, level, styles, additionalArgs);
|
|
951
948
|
|
|
952
949
|
// Update export handler group info
|
|
953
950
|
if (this.exportHandler) {
|
|
@@ -999,11 +996,13 @@ export class Logger {
|
|
|
999
996
|
if (!this.shouldLog(level)) return;
|
|
1000
997
|
|
|
1001
998
|
let prefix = '';
|
|
999
|
+
const colorCapability = getColorCapability();
|
|
1000
|
+
|
|
1002
1001
|
if (bindings.badges?.length) {
|
|
1003
|
-
prefix += bindings.badges.map(b =>
|
|
1002
|
+
prefix += bindings.badges.map(b => formatBadge(b, 'pill', colorCapability, '#00ff88')).join(' ') + ' ';
|
|
1004
1003
|
}
|
|
1005
1004
|
if (bindings.scope) {
|
|
1006
|
-
prefix +=
|
|
1005
|
+
prefix += formatBadge(bindings.scope, 'pill', colorCapability, '#00ffff') + ' ';
|
|
1007
1006
|
}
|
|
1008
1007
|
|
|
1009
1008
|
if (prefix && args.length > 0) {
|
|
@@ -1463,6 +1462,49 @@ export class Logger {
|
|
|
1463
1462
|
}
|
|
1464
1463
|
}
|
|
1465
1464
|
|
|
1465
|
+
// ===== OUTPUT WRITER SYSTEM =====
|
|
1466
|
+
|
|
1467
|
+
/**
|
|
1468
|
+
* Writes formatted output to the configured destination.
|
|
1469
|
+
* Respects outputMode configuration for console, silent, or custom output.
|
|
1470
|
+
*
|
|
1471
|
+
* @private
|
|
1472
|
+
* @param {string} message - Formatted log message
|
|
1473
|
+
* @param {LogLevel} level - Log level
|
|
1474
|
+
* @param {string[]} styles - CSS styles for browser console
|
|
1475
|
+
* @param {any[]} additionalArgs - Additional arguments to log
|
|
1476
|
+
* @since 4.0.0
|
|
1477
|
+
*/
|
|
1478
|
+
private writeOutput(
|
|
1479
|
+
message: string,
|
|
1480
|
+
level: LogLevel,
|
|
1481
|
+
styles: string[],
|
|
1482
|
+
additionalArgs: any[]
|
|
1483
|
+
): void {
|
|
1484
|
+
const mode = this.config.outputMode ?? 'console';
|
|
1485
|
+
|
|
1486
|
+
// Silent mode: no output
|
|
1487
|
+
if (mode === 'silent') {
|
|
1488
|
+
return;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
// Custom mode: use configured writer
|
|
1492
|
+
if (mode === 'custom' && this.config.outputWriter) {
|
|
1493
|
+
const fullMessage = additionalArgs.length > 0
|
|
1494
|
+
? `${message} ${additionalArgs.map(a => String(a)).join(' ')}`
|
|
1495
|
+
: message;
|
|
1496
|
+
this.config.outputWriter.write(fullMessage, level, styles);
|
|
1497
|
+
return;
|
|
1498
|
+
}
|
|
1499
|
+
|
|
1500
|
+
// Default: console output
|
|
1501
|
+
if (additionalArgs.length > 0) {
|
|
1502
|
+
console.log(message, ...styles, ...additionalArgs);
|
|
1503
|
+
} else {
|
|
1504
|
+
console.log(message, ...styles);
|
|
1505
|
+
}
|
|
1506
|
+
}
|
|
1507
|
+
|
|
1466
1508
|
// ===== CLI SYSTEM =====
|
|
1467
1509
|
|
|
1468
1510
|
/**
|
package/src/index.ts
CHANGED
|
@@ -146,7 +146,12 @@ export type {
|
|
|
146
146
|
TransportOptions,
|
|
147
147
|
TransportTarget,
|
|
148
148
|
ITransport,
|
|
149
|
-
StyleCacheConfig
|
|
149
|
+
StyleCacheConfig,
|
|
150
|
+
BadgeStyle,
|
|
151
|
+
TimestampFormat,
|
|
152
|
+
ColumnAlign,
|
|
153
|
+
ColumnConfig,
|
|
154
|
+
LogOptions,
|
|
150
155
|
} from './types/index.js';
|
|
151
156
|
|
|
152
157
|
// Styling utilities
|
|
@@ -316,4 +321,58 @@ export const stylePresets = {
|
|
|
316
321
|
warning: StylePresets.warning().build(),
|
|
317
322
|
info: StylePresets.info().build(),
|
|
318
323
|
accent: StylePresets.accent().build(),
|
|
319
|
-
};
|
|
324
|
+
};
|
|
325
|
+
|
|
326
|
+
// Terminal formatting utilities
|
|
327
|
+
export {
|
|
328
|
+
formatWithRightAlign,
|
|
329
|
+
formatColumns,
|
|
330
|
+
formatKeyValue,
|
|
331
|
+
formatBadge,
|
|
332
|
+
formatTimestamp as formatTimestampExt,
|
|
333
|
+
formatRelativeTime,
|
|
334
|
+
formatElapsedTime,
|
|
335
|
+
resetStartTime,
|
|
336
|
+
isKeyValueObject,
|
|
337
|
+
stripAnsi,
|
|
338
|
+
getVisibleLength,
|
|
339
|
+
padToWidth,
|
|
340
|
+
applyLogOptions,
|
|
341
|
+
} from './terminal/formatter.js';
|
|
342
|
+
|
|
343
|
+
// Color converter utilities
|
|
344
|
+
export {
|
|
345
|
+
hexToRgb,
|
|
346
|
+
rgbToHex,
|
|
347
|
+
hexTo256,
|
|
348
|
+
colorToHex,
|
|
349
|
+
getANSIForeground,
|
|
350
|
+
getANSIBackground,
|
|
351
|
+
getANSI256Foreground,
|
|
352
|
+
getANSI256Background,
|
|
353
|
+
cssColorToANSI,
|
|
354
|
+
ANSI,
|
|
355
|
+
} from './terminal/color-converter.js';
|
|
356
|
+
|
|
357
|
+
export type { RGB, ColorCapability } from './terminal/color-converter.js';
|
|
358
|
+
|
|
359
|
+
// Terminal renderer
|
|
360
|
+
export { TerminalRenderer } from './terminal/terminal-renderer.js';
|
|
361
|
+
export type { ANSIStyle, ChalkLikeInterface } from './terminal/terminal-renderer.js';
|
|
362
|
+
|
|
363
|
+
// Environment detection
|
|
364
|
+
export {
|
|
365
|
+
getEnvironment,
|
|
366
|
+
isRunningInTerminal,
|
|
367
|
+
supportsANSI,
|
|
368
|
+
getColorCapability,
|
|
369
|
+
getTerminalWidth,
|
|
370
|
+
getTerminalHeight,
|
|
371
|
+
getEnvironmentInfo,
|
|
372
|
+
} from './utils/environment-detector.js';
|
|
373
|
+
|
|
374
|
+
export type { Environment } from './utils/environment-detector.js';
|
|
375
|
+
|
|
376
|
+
// Output writers for custom log destinations
|
|
377
|
+
export { BufferWriter, type BufferEntry } from './writers/index.js';
|
|
378
|
+
export type { OutputWriter, OutputMode } from './types/core.js';
|
|
@@ -0,0 +1,315 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Color Converter - CSS colors to ANSI extended color codes
|
|
3
|
+
* Supports 256-color and truecolor (24-bit) terminals
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export type ColorCapability = 'full' | 'basic' | 'none';
|
|
7
|
+
|
|
8
|
+
export interface RGB {
|
|
9
|
+
r: number;
|
|
10
|
+
g: number;
|
|
11
|
+
b: number;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const ANSI_16_COLORS: Record<string, { fg: string; bg: string; bright: { fg: string; bg: string } }> = {
|
|
15
|
+
black: { fg: '30', bg: '40', bright: { fg: '90', bg: '100' } },
|
|
16
|
+
red: { fg: '31', bg: '41', bright: { fg: '91', bg: '101' } },
|
|
17
|
+
green: { fg: '32', bg: '42', bright: { fg: '92', bg: '102' } },
|
|
18
|
+
yellow: { fg: '33', bg: '43', bright: { fg: '93', bg: '103' } },
|
|
19
|
+
blue: { fg: '34', bg: '44', bright: { fg: '94', bg: '104' } },
|
|
20
|
+
magenta: { fg: '35', bg: '45', bright: { fg: '95', bg: '105' } },
|
|
21
|
+
cyan: { fg: '36', bg: '46', bright: { fg: '96', bg: '106' } },
|
|
22
|
+
white: { fg: '37', bg: '47', bright: { fg: '97', bg: '107' } },
|
|
23
|
+
gray: { fg: '90', bg: '100', bright: { fg: '37', bg: '47' } },
|
|
24
|
+
grey: { fg: '90', bg: '100', bright: { fg: '37', bg: '47' } },
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const CSS_NAMED_COLORS: Record<string, string> = {
|
|
28
|
+
aliceblue: '#f0f8ff', antiquewhite: '#faebd7', aqua: '#00ffff',
|
|
29
|
+
aquamarine: '#7fffd4', azure: '#f0ffff', beige: '#f5f5dc',
|
|
30
|
+
bisque: '#ffe4c4', black: '#000000', blanchedalmond: '#ffebcd',
|
|
31
|
+
blue: '#0000ff', blueviolet: '#8a2be2', brown: '#a52a2a',
|
|
32
|
+
burlywood: '#deb887', cadetblue: '#5f9ea0', chartreuse: '#7fff00',
|
|
33
|
+
chocolate: '#d2691e', coral: '#ff7f50', cornflowerblue: '#6495ed',
|
|
34
|
+
cornsilk: '#fff8dc', crimson: '#dc143c', cyan: '#00ffff',
|
|
35
|
+
darkblue: '#00008b', darkcyan: '#008b8b', darkgoldenrod: '#b8860b',
|
|
36
|
+
darkgray: '#a9a9a9', darkgreen: '#006400', darkkhaki: '#bdb76b',
|
|
37
|
+
darkmagenta: '#8b008b', darkolivegreen: '#556b2f', darkorange: '#ff8c00',
|
|
38
|
+
darkorchid: '#9932cc', darkred: '#8b0000', darksalmon: '#e9967a',
|
|
39
|
+
darkseagreen: '#8fbc8f', darkslateblue: '#483d8b', darkslategray: '#2f4f4f',
|
|
40
|
+
darkturquoise: '#00ced1', darkviolet: '#9400d3', deeppink: '#ff1493',
|
|
41
|
+
deepskyblue: '#00bfff', dimgray: '#696969', dodgerblue: '#1e90ff',
|
|
42
|
+
firebrick: '#b22222', floralwhite: '#fffaf0', forestgreen: '#228b22',
|
|
43
|
+
fuchsia: '#ff00ff', gainsboro: '#dcdcdc', ghostwhite: '#f8f8ff',
|
|
44
|
+
gold: '#ffd700', goldenrod: '#daa520', gray: '#808080',
|
|
45
|
+
green: '#008000', greenyellow: '#adff2f', honeydew: '#f0fff0',
|
|
46
|
+
hotpink: '#ff69b4', indianred: '#cd5c5c', indigo: '#4b0082',
|
|
47
|
+
ivory: '#fffff0', khaki: '#f0e68c', lavender: '#e6e6fa',
|
|
48
|
+
lavenderblush: '#fff0f5', lawngreen: '#7cfc00', lemonchiffon: '#fffacd',
|
|
49
|
+
lightblue: '#add8e6', lightcoral: '#f08080', lightcyan: '#e0ffff',
|
|
50
|
+
lightgoldenrodyellow: '#fafad2', lightgray: '#d3d3d3', lightgreen: '#90ee90',
|
|
51
|
+
lightpink: '#ffb6c1', lightsalmon: '#ffa07a', lightseagreen: '#20b2aa',
|
|
52
|
+
lightskyblue: '#87cefa', lightslategray: '#778899', lightsteelblue: '#b0c4de',
|
|
53
|
+
lightyellow: '#ffffe0', lime: '#00ff00', limegreen: '#32cd32',
|
|
54
|
+
linen: '#faf0e6', magenta: '#ff00ff', maroon: '#800000',
|
|
55
|
+
mediumaquamarine: '#66cdaa', mediumblue: '#0000cd', mediumorchid: '#ba55d3',
|
|
56
|
+
mediumpurple: '#9370db', mediumseagreen: '#3cb371', mediumslateblue: '#7b68ee',
|
|
57
|
+
mediumspringgreen: '#00fa9a', mediumturquoise: '#48d1cc', mediumvioletred: '#c71585',
|
|
58
|
+
midnightblue: '#191970', mintcream: '#f5fffa', mistyrose: '#ffe4e1',
|
|
59
|
+
moccasin: '#ffe4b5', navajowhite: '#ffdead', navy: '#000080',
|
|
60
|
+
oldlace: '#fdf5e6', olive: '#808000', olivedrab: '#6b8e23',
|
|
61
|
+
orange: '#ffa500', orangered: '#ff4500', orchid: '#da70d6',
|
|
62
|
+
palegoldenrod: '#eee8aa', palegreen: '#98fb98', paleturquoise: '#afeeee',
|
|
63
|
+
palevioletred: '#db7093', papayawhip: '#ffefd5', peachpuff: '#ffdab9',
|
|
64
|
+
peru: '#cd853f', pink: '#ffc0cb', plum: '#dda0dd',
|
|
65
|
+
powderblue: '#b0e0e6', purple: '#800080', rebeccapurple: '#663399',
|
|
66
|
+
red: '#ff0000', rosybrown: '#bc8f8f', royalblue: '#4169e1',
|
|
67
|
+
saddlebrown: '#8b4513', salmon: '#fa8072', sandybrown: '#f4a460',
|
|
68
|
+
seagreen: '#2e8b57', seashell: '#fff5ee', sienna: '#a0522d',
|
|
69
|
+
silver: '#c0c0c0', skyblue: '#87ceeb', slateblue: '#6a5acd',
|
|
70
|
+
slategray: '#708090', snow: '#fffafa', springgreen: '#00ff7f',
|
|
71
|
+
steelblue: '#4682b4', tan: '#d2b48c', teal: '#008080',
|
|
72
|
+
thistle: '#d8bfd8', tomato: '#ff6347', turquoise: '#40e0d0',
|
|
73
|
+
violet: '#ee82ee', wheat: '#f5deb3', white: '#ffffff',
|
|
74
|
+
whitesmoke: '#f5f5f5', yellow: '#ffff00', yellowgreen: '#9acd32',
|
|
75
|
+
};
|
|
76
|
+
|
|
77
|
+
export function hexToRgb(hex: string): RGB {
|
|
78
|
+
const result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})$/i.exec(hex);
|
|
79
|
+
if (!result || !result[1] || !result[2] || !result[3]) {
|
|
80
|
+
return { r: 255, g: 255, b: 255 };
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
r: parseInt(result[1], 16),
|
|
84
|
+
g: parseInt(result[2], 16),
|
|
85
|
+
b: parseInt(result[3], 16),
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
export function rgbToHex(r: number, g: number, b: number): string {
|
|
90
|
+
return '#' + [r, g, b].map(x => x.toString(16).padStart(2, '0')).join('');
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
export function hexTo256(hex: string): number {
|
|
94
|
+
const { r, g, b } = hexToRgb(hex);
|
|
95
|
+
|
|
96
|
+
if (r === g && g === b) {
|
|
97
|
+
if (r < 8) return 16;
|
|
98
|
+
if (r > 248) return 231;
|
|
99
|
+
return Math.round(((r - 8) / 247) * 24) + 232;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const ri = Math.round(r / 255 * 5);
|
|
103
|
+
const gi = Math.round(g / 255 * 5);
|
|
104
|
+
const bi = Math.round(b / 255 * 5);
|
|
105
|
+
|
|
106
|
+
return 16 + (36 * ri) + (6 * gi) + bi;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function colorToHex(color: string): string {
|
|
110
|
+
if (color.startsWith('#')) {
|
|
111
|
+
return color;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const named = CSS_NAMED_COLORS[color.toLowerCase()];
|
|
115
|
+
if (named) {
|
|
116
|
+
return named;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const rgbMatch = color.match(/rgba?\((\d+),\s*(\d+),\s*(\d+)/);
|
|
120
|
+
if (rgbMatch && rgbMatch[1] && rgbMatch[2] && rgbMatch[3]) {
|
|
121
|
+
return rgbToHex(
|
|
122
|
+
parseInt(rgbMatch[1]),
|
|
123
|
+
parseInt(rgbMatch[2]),
|
|
124
|
+
parseInt(rgbMatch[3])
|
|
125
|
+
);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return '#ffffff';
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function getANSIForeground(color: string, capability: ColorCapability): string {
|
|
132
|
+
if (capability === 'none') return '';
|
|
133
|
+
|
|
134
|
+
const lowerColor = color.toLowerCase();
|
|
135
|
+
|
|
136
|
+
if (capability === 'basic' && ANSI_16_COLORS[lowerColor]) {
|
|
137
|
+
return `\x1b[${ANSI_16_COLORS[lowerColor].fg}m`;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (capability === 'basic') {
|
|
141
|
+
const hex = colorToHex(color);
|
|
142
|
+
const nearestBasic = findNearestBasicColor(hex);
|
|
143
|
+
const basicColor = ANSI_16_COLORS[nearestBasic];
|
|
144
|
+
return basicColor ? `\x1b[${basicColor.fg}m` : '\x1b[37m';
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const hex = colorToHex(color);
|
|
148
|
+
const { r, g, b } = hexToRgb(hex);
|
|
149
|
+
return `\x1b[38;2;${r};${g};${b}m`;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
export function getANSIBackground(color: string, capability: ColorCapability): string {
|
|
153
|
+
if (capability === 'none') return '';
|
|
154
|
+
|
|
155
|
+
const lowerColor = color.toLowerCase();
|
|
156
|
+
|
|
157
|
+
if (capability === 'basic' && ANSI_16_COLORS[lowerColor]) {
|
|
158
|
+
return `\x1b[${ANSI_16_COLORS[lowerColor].bg}m`;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (capability === 'basic') {
|
|
162
|
+
const hex = colorToHex(color);
|
|
163
|
+
const nearestBasic = findNearestBasicColor(hex);
|
|
164
|
+
const basicColor = ANSI_16_COLORS[nearestBasic];
|
|
165
|
+
return basicColor ? `\x1b[${basicColor.bg}m` : '\x1b[47m';
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
const hex = colorToHex(color);
|
|
169
|
+
const { r, g, b } = hexToRgb(hex);
|
|
170
|
+
return `\x1b[48;2;${r};${g};${b}m`;
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
export function getANSI256Foreground(colorIndex: number): string {
|
|
174
|
+
return `\x1b[38;5;${colorIndex}m`;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
export function getANSI256Background(colorIndex: number): string {
|
|
178
|
+
return `\x1b[48;5;${colorIndex}m`;
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
function findNearestBasicColor(hex: string): string {
|
|
182
|
+
const { r, g, b } = hexToRgb(hex);
|
|
183
|
+
const basicColors: Record<string, RGB> = {
|
|
184
|
+
black: { r: 0, g: 0, b: 0 },
|
|
185
|
+
red: { r: 205, g: 0, b: 0 },
|
|
186
|
+
green: { r: 0, g: 205, b: 0 },
|
|
187
|
+
yellow: { r: 205, g: 205, b: 0 },
|
|
188
|
+
blue: { r: 0, g: 0, b: 238 },
|
|
189
|
+
magenta: { r: 205, g: 0, b: 205 },
|
|
190
|
+
cyan: { r: 0, g: 205, b: 205 },
|
|
191
|
+
white: { r: 229, g: 229, b: 229 },
|
|
192
|
+
};
|
|
193
|
+
|
|
194
|
+
let nearest = 'white';
|
|
195
|
+
let minDistance = Infinity;
|
|
196
|
+
|
|
197
|
+
for (const [name, rgb] of Object.entries(basicColors)) {
|
|
198
|
+
const distance = Math.sqrt(
|
|
199
|
+
Math.pow(r - rgb.r, 2) +
|
|
200
|
+
Math.pow(g - rgb.g, 2) +
|
|
201
|
+
Math.pow(b - rgb.b, 2)
|
|
202
|
+
);
|
|
203
|
+
if (distance < minDistance) {
|
|
204
|
+
minDistance = distance;
|
|
205
|
+
nearest = name;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
return nearest;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
export function extractGradientColors(gradient: string): string[] {
|
|
213
|
+
const hexMatches = gradient.match(/#[a-fA-F0-9]{6}/g) || [];
|
|
214
|
+
const rgbMatches = gradient.match(/rgba?\([^)]+\)/g) || [];
|
|
215
|
+
const namedMatches = gradient.match(/,\s*([a-z]+)(?:\s|,|\))/gi) || [];
|
|
216
|
+
|
|
217
|
+
const colors: string[] = [
|
|
218
|
+
...hexMatches,
|
|
219
|
+
...rgbMatches.map(colorToHex),
|
|
220
|
+
...namedMatches.map(m => {
|
|
221
|
+
const name = m.replace(/[,\s)]/g, '').toLowerCase();
|
|
222
|
+
return CSS_NAMED_COLORS[name] || null;
|
|
223
|
+
}).filter((c): c is string => c !== null)
|
|
224
|
+
];
|
|
225
|
+
|
|
226
|
+
return colors.length > 0 ? colors : ['#ffffff'];
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export function gradientToSingleColor(gradient: string): string {
|
|
230
|
+
const colors = extractGradientColors(gradient);
|
|
231
|
+
if (colors.length === 0) return '#ffffff';
|
|
232
|
+
if (colors.length === 1) return colors[0] ?? '#ffffff';
|
|
233
|
+
|
|
234
|
+
const rgbs = colors.map(c => hexToRgb(colorToHex(c)));
|
|
235
|
+
const avgR = Math.round(rgbs.reduce((sum, rgb) => sum + rgb.r, 0) / rgbs.length);
|
|
236
|
+
const avgG = Math.round(rgbs.reduce((sum, rgb) => sum + rgb.g, 0) / rgbs.length);
|
|
237
|
+
const avgB = Math.round(rgbs.reduce((sum, rgb) => sum + rgb.b, 0) / rgbs.length);
|
|
238
|
+
|
|
239
|
+
return rgbToHex(avgR, avgG, avgB);
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
export function cssColorToANSI(
|
|
243
|
+
cssColor: string,
|
|
244
|
+
capability: ColorCapability,
|
|
245
|
+
isBackground: boolean = false
|
|
246
|
+
): string {
|
|
247
|
+
if (capability === 'none') return '';
|
|
248
|
+
|
|
249
|
+
let resolvedColor: string;
|
|
250
|
+
|
|
251
|
+
if (cssColor.includes('gradient')) {
|
|
252
|
+
resolvedColor = gradientToSingleColor(cssColor);
|
|
253
|
+
} else {
|
|
254
|
+
resolvedColor = colorToHex(cssColor);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
return isBackground
|
|
258
|
+
? getANSIBackground(resolvedColor, capability)
|
|
259
|
+
: getANSIForeground(resolvedColor, capability);
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
export const ANSI = {
|
|
263
|
+
reset: '\x1b[0m',
|
|
264
|
+
bold: '\x1b[1m',
|
|
265
|
+
dim: '\x1b[2m',
|
|
266
|
+
italic: '\x1b[3m',
|
|
267
|
+
underline: '\x1b[4m',
|
|
268
|
+
blink: '\x1b[5m',
|
|
269
|
+
inverse: '\x1b[7m',
|
|
270
|
+
hidden: '\x1b[8m',
|
|
271
|
+
strikethrough: '\x1b[9m',
|
|
272
|
+
|
|
273
|
+
fg: {
|
|
274
|
+
black: '\x1b[30m',
|
|
275
|
+
red: '\x1b[31m',
|
|
276
|
+
green: '\x1b[32m',
|
|
277
|
+
yellow: '\x1b[33m',
|
|
278
|
+
blue: '\x1b[34m',
|
|
279
|
+
magenta: '\x1b[35m',
|
|
280
|
+
cyan: '\x1b[36m',
|
|
281
|
+
white: '\x1b[37m',
|
|
282
|
+
gray: '\x1b[90m',
|
|
283
|
+
brightRed: '\x1b[91m',
|
|
284
|
+
brightGreen: '\x1b[92m',
|
|
285
|
+
brightYellow: '\x1b[93m',
|
|
286
|
+
brightBlue: '\x1b[94m',
|
|
287
|
+
brightMagenta: '\x1b[95m',
|
|
288
|
+
brightCyan: '\x1b[96m',
|
|
289
|
+
brightWhite: '\x1b[97m',
|
|
290
|
+
},
|
|
291
|
+
|
|
292
|
+
bg: {
|
|
293
|
+
black: '\x1b[40m',
|
|
294
|
+
red: '\x1b[41m',
|
|
295
|
+
green: '\x1b[42m',
|
|
296
|
+
yellow: '\x1b[43m',
|
|
297
|
+
blue: '\x1b[44m',
|
|
298
|
+
magenta: '\x1b[45m',
|
|
299
|
+
cyan: '\x1b[46m',
|
|
300
|
+
white: '\x1b[47m',
|
|
301
|
+
gray: '\x1b[100m',
|
|
302
|
+
brightRed: '\x1b[101m',
|
|
303
|
+
brightGreen: '\x1b[102m',
|
|
304
|
+
brightYellow: '\x1b[103m',
|
|
305
|
+
brightBlue: '\x1b[104m',
|
|
306
|
+
brightMagenta: '\x1b[105m',
|
|
307
|
+
brightCyan: '\x1b[106m',
|
|
308
|
+
brightWhite: '\x1b[107m',
|
|
309
|
+
},
|
|
310
|
+
|
|
311
|
+
rgb: (r: number, g: number, b: number) => `\x1b[38;2;${r};${g};${b}m`,
|
|
312
|
+
bgRgb: (r: number, g: number, b: number) => `\x1b[48;2;${r};${g};${b}m`,
|
|
313
|
+
color256: (n: number) => `\x1b[38;5;${n}m`,
|
|
314
|
+
bgColor256: (n: number) => `\x1b[48;5;${n}m`,
|
|
315
|
+
};
|