colorino 0.4.0 → 0.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "colorino",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "A super simple colorized logger that gets the most out of your terminal",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -45,10 +45,11 @@
45
45
  "build": "unbuild",
46
46
  "format": "oxlint --fix && oxfmt",
47
47
  "test:all": "npm run test:node && npm run test:browser",
48
- "test:node": "vitest run --config vitest.config.ts",
49
- "test:browser": "vitest run --config vitest.browser.config.ts",
50
- "test:coverage": "vitest run --config vitest.config.ts --coverage",
51
- "test:ui": "vitest --ui --config vitest.config.ts",
48
+ "test:node": "vitest run --project=node",
49
+ "test:browser": "vitest run --project=chromium --browser=chromium",
50
+ "test:watch": "vitest",
51
+ "test:coverage": "vitest run --coverage",
52
+ "test:ui": "vitest --ui",
52
53
  "version:patch": "npm version patch",
53
54
  "version:minor": "npm version minor",
54
55
  "version:major": "npm version major",
@@ -61,18 +62,20 @@
61
62
  "neverthrow": "^8.2.0"
62
63
  },
63
64
  "devDependencies": {
64
- "@sindresorhus/tsconfig": "^8.1.0",
65
+ "@playwright/test": "^1.57.0",
65
66
  "@types/node": "^24.9.2",
66
- "@vitest/coverage-v8": "^4.0.6",
67
- "@vitest/ui": "^4.0.6",
67
+ "@vitest/browser-playwright": "^4.0.15",
68
+ "@vitest/coverage-v8": "^4.0.15",
69
+ "@vitest/ui": "^4.0.15",
68
70
  "husky": "^9.0.0",
69
- "jsdom": "^27.1.0",
70
71
  "lint-staged": "^15.2.0",
71
72
  "oxfmt": "^0.9.0",
72
73
  "oxlint": "^0.2.0",
74
+ "playwright": "^1.57.0",
73
75
  "tsx": "^4.20.6",
76
+ "typescript": "^5.9.3",
74
77
  "unbuild": "^3.6.1",
75
- "vitest": "^4.0.6"
78
+ "vitest": "^4.0.15"
76
79
  },
77
80
  "lint-staged": {
78
81
  "*.{ts,json}": [
@@ -82,7 +85,7 @@
82
85
  "*.ts": "vitest related --run"
83
86
  },
84
87
  "engines": {
85
- "node": ">=16.0.0",
88
+ "node": ">=17.0.0",
86
89
  "npm": ">=8.0.0"
87
90
  },
88
91
  "publishConfig": {
@@ -1,281 +0,0 @@
1
- import { err, ok } from 'neverthrow';
2
-
3
- function hexToRgb(hex) {
4
- const match = hex.toString().match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
5
- if (!match) {
6
- return [0, 0, 0];
7
- }
8
- let colorString = match[0];
9
- if (match[0].length === 3) {
10
- colorString = [...colorString].map((char) => char + char).join("");
11
- }
12
- const integer = parseInt(colorString, 16);
13
- const r = integer >> 16 & 255;
14
- const g = integer >> 8 & 255;
15
- const b = integer & 255;
16
- return [r, g, b];
17
- }
18
- function rgbToAnsi256(rgb) {
19
- const [r, g, b] = rgb;
20
- if (r === g && g === b) {
21
- if (r < 8) return 16;
22
- if (r > 248) return 231;
23
- return Math.round((r - 8) / 247 * 24) + 232;
24
- }
25
- return 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
26
- }
27
- function rgbToHsvValue(rgb) {
28
- const r = rgb[0] / 255;
29
- const g = rgb[1] / 255;
30
- const b = rgb[2] / 255;
31
- const v = Math.max(r, g, b);
32
- return v * 100;
33
- }
34
- function rgbToAnsi16(rgb) {
35
- const [r, g, b] = rgb;
36
- const value = rgbToHsvValue(rgb);
37
- const roundedValue = Math.round(value / 50);
38
- if (roundedValue === 0) {
39
- return 30;
40
- }
41
- let ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
42
- if (roundedValue === 2) {
43
- ansi += 60;
44
- }
45
- return ansi;
46
- }
47
- const colorConverter = {
48
- hex: {
49
- toRgb: hexToRgb,
50
- toAnsi16: (hex) => rgbToAnsi16(hexToRgb(hex)),
51
- toAnsi256: (hex) => rgbToAnsi256(hexToRgb(hex))
52
- }};
53
-
54
- var ColorLevel = /* @__PURE__ */ ((ColorLevel2) => {
55
- ColorLevel2[ColorLevel2["NO_COLOR"] = 0] = "NO_COLOR";
56
- ColorLevel2[ColorLevel2["ANSI"] = 1] = "ANSI";
57
- ColorLevel2[ColorLevel2["ANSI256"] = 2] = "ANSI256";
58
- ColorLevel2[ColorLevel2["TRUECOLOR"] = 3] = "TRUECOLOR";
59
- return ColorLevel2;
60
- })(ColorLevel || {});
61
-
62
- function isConsoleMethod(level) {
63
- return ["log", "info", "warn", "error", "trace", "debug"].includes(level);
64
- }
65
-
66
- class Colorino {
67
- constructor(_palette, _validator, _browserColorSupportDetector, _nodeColorSupportDetector, _options = {}) {
68
- this._palette = _palette;
69
- this._validator = _validator;
70
- this._browserColorSupportDetector = _browserColorSupportDetector;
71
- this._nodeColorSupportDetector = _nodeColorSupportDetector;
72
- this._options = _options;
73
- this.isBrowser = !!this._browserColorSupportDetector;
74
- this._colorLevel = this._detectColorSupport();
75
- const validatePaletteResult = this._validator.validatePalette(this._palette);
76
- if (validatePaletteResult.isErr()) throw validatePaletteResult.error;
77
- if (!this.isBrowser && (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") && !this._options.disableWarnings) {
78
- this._maybeWarnUser();
79
- }
80
- }
81
- _alreadyWarned = false;
82
- _colorLevel;
83
- isBrowser;
84
- log(...args) {
85
- this._out("log", args);
86
- }
87
- info(...args) {
88
- this._out("info", args);
89
- }
90
- warn(...args) {
91
- this._out("warn", args);
92
- }
93
- error(...args) {
94
- this._out("error", args);
95
- }
96
- trace(...args) {
97
- this._out("trace", args);
98
- }
99
- debug(...args) {
100
- this._out("debug", args);
101
- }
102
- _detectColorSupport() {
103
- if (this.isBrowser) {
104
- return this._browserColorSupportDetector?.getColorLevel() ?? "UnknownEnv";
105
- }
106
- if (this._nodeColorSupportDetector?.isNodeEnv()) {
107
- return this._nodeColorSupportDetector?.getColorLevel() ?? "UnknownEnv";
108
- }
109
- return "UnknownEnv";
110
- }
111
- _maybeWarnUser() {
112
- if (this._alreadyWarned) return;
113
- this._alreadyWarned = true;
114
- console.warn(
115
- "[Colorino] No ANSI color support detected in this terminal. See [https://github.com/chalk/supports-color#support-matrix](https://github.com/chalk/supports-color#support-matrix) to learn how to enable terminal color."
116
- );
117
- }
118
- _out(level, args) {
119
- const consoleMethod = isConsoleMethod(level) ? level : "log";
120
- if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
121
- if (level === "trace") console.trace(...args);
122
- else console[consoleMethod](...args);
123
- return;
124
- }
125
- if (this.isBrowser) {
126
- const hex2 = this._palette[level];
127
- if (typeof args[0] === "string") {
128
- console[consoleMethod](`%c${args[0]}`, `color:${hex2}`, ...args.slice(1));
129
- } else {
130
- console[consoleMethod](...args);
131
- }
132
- return;
133
- }
134
- const hex = this._palette[level];
135
- let ansiCode;
136
- switch (this._colorLevel) {
137
- case ColorLevel.TRUECOLOR: {
138
- const [r, g, b] = colorConverter.hex.toRgb(hex);
139
- ansiCode = `\x1B[38;2;${r};${g};${b}m`;
140
- break;
141
- }
142
- case ColorLevel.ANSI256: {
143
- const code = colorConverter.hex.toAnsi256(hex);
144
- ansiCode = `\x1B[38;5;${code}m`;
145
- break;
146
- }
147
- case ColorLevel.ANSI:
148
- default: {
149
- const code = colorConverter.hex.toAnsi16(hex);
150
- ansiCode = `\x1B[${code}m`;
151
- break;
152
- }
153
- }
154
- const processedArgs = [...args];
155
- const firstStringIndex = processedArgs.findIndex(
156
- (arg) => typeof arg === "string"
157
- );
158
- if (firstStringIndex !== -1) {
159
- processedArgs[firstStringIndex] = `${ansiCode}${processedArgs[firstStringIndex]}\x1B[0m`;
160
- }
161
- if (level === "trace") {
162
- console.trace(...processedArgs);
163
- } else {
164
- console[consoleMethod](...processedArgs);
165
- }
166
- }
167
- }
168
-
169
- class ColorinoError extends Error {
170
- constructor(message) {
171
- super(message);
172
- this.name = "ColorinoError";
173
- Object.setPrototypeOf(this, ColorinoError.prototype);
174
- }
175
- }
176
-
177
- class InputValidator {
178
- validateHex(hex) {
179
- const trimmedHex = hex.trim();
180
- const isHexValid = /^#[0-9A-F]{6}$/i.test(trimmedHex);
181
- if (!isHexValid) {
182
- return err(new ColorinoError(`Invalid hex color: '${hex}'`));
183
- }
184
- return ok(true);
185
- }
186
- validatePalette(palette) {
187
- for (const level in palette) {
188
- const hex = palette[level];
189
- const result = this.validateHex(hex);
190
- if (result.isErr()) {
191
- return err(result.error);
192
- }
193
- }
194
- return ok(true);
195
- }
196
- }
197
-
198
- const catppuccinMochaPalette = {
199
- log: "#cdd6f4",
200
- // Text
201
- info: "#89b4fa",
202
- // Blue
203
- warn: "#f9e2af",
204
- // Yellow
205
- error: "#f38ba8",
206
- // Red
207
- debug: "#a6adc8",
208
- // Subtext0
209
- trace: "#9399b2"
210
- // Subtext1
211
- };
212
- const catppuccinLattePalette = {
213
- log: "#4c4f69",
214
- // Text
215
- info: "#1e66f5",
216
- // Blue
217
- warn: "#df8e1d",
218
- // Yellow
219
- error: "#d20f39",
220
- // Red
221
- debug: "#7c7f93",
222
- // Subtext0
223
- trace: "#8c8fa1"
224
- // Subtext1
225
- };
226
- const draculaPalette = {
227
- log: "#f8f8f2",
228
- // Foreground
229
- info: "#8be9fd",
230
- // Cyan
231
- warn: "#f1fa8c",
232
- // Yellow
233
- error: "#ff5555",
234
- // Red
235
- debug: "#bd93f9",
236
- // Purple
237
- trace: "#6272a4"
238
- // Comment
239
- };
240
- const githubLightPalette = {
241
- log: "#24292e",
242
- // Text
243
- info: "#0366d6",
244
- // Blue
245
- warn: "#f9a002",
246
- // Yellow
247
- error: "#d73a49",
248
- // Red
249
- debug: "#586069",
250
- // Gray
251
- trace: "#6a737d"
252
- // Gray-light
253
- };
254
-
255
- const themePalettes = {
256
- "catppuccin-mocha": catppuccinMochaPalette,
257
- "catppuccin-latte": catppuccinLattePalette,
258
- dracula: draculaPalette,
259
- "github-light": githubLightPalette
260
- };
261
- const defaultDarkTheme = "catppuccin-mocha";
262
- const defaultLightTheme = "github-light";
263
- function isThemeName(theme) {
264
- return theme in themePalettes;
265
- }
266
-
267
- function determineBaseTheme(themeOpt, detectedBrowserTheme) {
268
- let baseThemeName;
269
- if (isThemeName(themeOpt)) {
270
- baseThemeName = themeOpt;
271
- } else if (themeOpt === "light") {
272
- baseThemeName = defaultLightTheme;
273
- } else if (themeOpt === "dark") {
274
- baseThemeName = defaultDarkTheme;
275
- } else {
276
- baseThemeName = detectedBrowserTheme === "light" ? defaultLightTheme : defaultDarkTheme;
277
- }
278
- return baseThemeName;
279
- }
280
-
281
- export { ColorLevel as C, InputValidator as I, Colorino as a, determineBaseTheme as d, themePalettes as t };
@@ -1,287 +0,0 @@
1
- 'use strict';
2
-
3
- const neverthrow = require('neverthrow');
4
-
5
- function hexToRgb(hex) {
6
- const match = hex.toString().match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
7
- if (!match) {
8
- return [0, 0, 0];
9
- }
10
- let colorString = match[0];
11
- if (match[0].length === 3) {
12
- colorString = [...colorString].map((char) => char + char).join("");
13
- }
14
- const integer = parseInt(colorString, 16);
15
- const r = integer >> 16 & 255;
16
- const g = integer >> 8 & 255;
17
- const b = integer & 255;
18
- return [r, g, b];
19
- }
20
- function rgbToAnsi256(rgb) {
21
- const [r, g, b] = rgb;
22
- if (r === g && g === b) {
23
- if (r < 8) return 16;
24
- if (r > 248) return 231;
25
- return Math.round((r - 8) / 247 * 24) + 232;
26
- }
27
- return 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
28
- }
29
- function rgbToHsvValue(rgb) {
30
- const r = rgb[0] / 255;
31
- const g = rgb[1] / 255;
32
- const b = rgb[2] / 255;
33
- const v = Math.max(r, g, b);
34
- return v * 100;
35
- }
36
- function rgbToAnsi16(rgb) {
37
- const [r, g, b] = rgb;
38
- const value = rgbToHsvValue(rgb);
39
- const roundedValue = Math.round(value / 50);
40
- if (roundedValue === 0) {
41
- return 30;
42
- }
43
- let ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
44
- if (roundedValue === 2) {
45
- ansi += 60;
46
- }
47
- return ansi;
48
- }
49
- const colorConverter = {
50
- hex: {
51
- toRgb: hexToRgb,
52
- toAnsi16: (hex) => rgbToAnsi16(hexToRgb(hex)),
53
- toAnsi256: (hex) => rgbToAnsi256(hexToRgb(hex))
54
- }};
55
-
56
- var ColorLevel = /* @__PURE__ */ ((ColorLevel2) => {
57
- ColorLevel2[ColorLevel2["NO_COLOR"] = 0] = "NO_COLOR";
58
- ColorLevel2[ColorLevel2["ANSI"] = 1] = "ANSI";
59
- ColorLevel2[ColorLevel2["ANSI256"] = 2] = "ANSI256";
60
- ColorLevel2[ColorLevel2["TRUECOLOR"] = 3] = "TRUECOLOR";
61
- return ColorLevel2;
62
- })(ColorLevel || {});
63
-
64
- function isConsoleMethod(level) {
65
- return ["log", "info", "warn", "error", "trace", "debug"].includes(level);
66
- }
67
-
68
- class Colorino {
69
- constructor(_palette, _validator, _browserColorSupportDetector, _nodeColorSupportDetector, _options = {}) {
70
- this._palette = _palette;
71
- this._validator = _validator;
72
- this._browserColorSupportDetector = _browserColorSupportDetector;
73
- this._nodeColorSupportDetector = _nodeColorSupportDetector;
74
- this._options = _options;
75
- this.isBrowser = !!this._browserColorSupportDetector;
76
- this._colorLevel = this._detectColorSupport();
77
- const validatePaletteResult = this._validator.validatePalette(this._palette);
78
- if (validatePaletteResult.isErr()) throw validatePaletteResult.error;
79
- if (!this.isBrowser && (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") && !this._options.disableWarnings) {
80
- this._maybeWarnUser();
81
- }
82
- }
83
- _alreadyWarned = false;
84
- _colorLevel;
85
- isBrowser;
86
- log(...args) {
87
- this._out("log", args);
88
- }
89
- info(...args) {
90
- this._out("info", args);
91
- }
92
- warn(...args) {
93
- this._out("warn", args);
94
- }
95
- error(...args) {
96
- this._out("error", args);
97
- }
98
- trace(...args) {
99
- this._out("trace", args);
100
- }
101
- debug(...args) {
102
- this._out("debug", args);
103
- }
104
- _detectColorSupport() {
105
- if (this.isBrowser) {
106
- return this._browserColorSupportDetector?.getColorLevel() ?? "UnknownEnv";
107
- }
108
- if (this._nodeColorSupportDetector?.isNodeEnv()) {
109
- return this._nodeColorSupportDetector?.getColorLevel() ?? "UnknownEnv";
110
- }
111
- return "UnknownEnv";
112
- }
113
- _maybeWarnUser() {
114
- if (this._alreadyWarned) return;
115
- this._alreadyWarned = true;
116
- console.warn(
117
- "[Colorino] No ANSI color support detected in this terminal. See [https://github.com/chalk/supports-color#support-matrix](https://github.com/chalk/supports-color#support-matrix) to learn how to enable terminal color."
118
- );
119
- }
120
- _out(level, args) {
121
- const consoleMethod = isConsoleMethod(level) ? level : "log";
122
- if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
123
- if (level === "trace") console.trace(...args);
124
- else console[consoleMethod](...args);
125
- return;
126
- }
127
- if (this.isBrowser) {
128
- const hex2 = this._palette[level];
129
- if (typeof args[0] === "string") {
130
- console[consoleMethod](`%c${args[0]}`, `color:${hex2}`, ...args.slice(1));
131
- } else {
132
- console[consoleMethod](...args);
133
- }
134
- return;
135
- }
136
- const hex = this._palette[level];
137
- let ansiCode;
138
- switch (this._colorLevel) {
139
- case ColorLevel.TRUECOLOR: {
140
- const [r, g, b] = colorConverter.hex.toRgb(hex);
141
- ansiCode = `\x1B[38;2;${r};${g};${b}m`;
142
- break;
143
- }
144
- case ColorLevel.ANSI256: {
145
- const code = colorConverter.hex.toAnsi256(hex);
146
- ansiCode = `\x1B[38;5;${code}m`;
147
- break;
148
- }
149
- case ColorLevel.ANSI:
150
- default: {
151
- const code = colorConverter.hex.toAnsi16(hex);
152
- ansiCode = `\x1B[${code}m`;
153
- break;
154
- }
155
- }
156
- const processedArgs = [...args];
157
- const firstStringIndex = processedArgs.findIndex(
158
- (arg) => typeof arg === "string"
159
- );
160
- if (firstStringIndex !== -1) {
161
- processedArgs[firstStringIndex] = `${ansiCode}${processedArgs[firstStringIndex]}\x1B[0m`;
162
- }
163
- if (level === "trace") {
164
- console.trace(...processedArgs);
165
- } else {
166
- console[consoleMethod](...processedArgs);
167
- }
168
- }
169
- }
170
-
171
- class ColorinoError extends Error {
172
- constructor(message) {
173
- super(message);
174
- this.name = "ColorinoError";
175
- Object.setPrototypeOf(this, ColorinoError.prototype);
176
- }
177
- }
178
-
179
- class InputValidator {
180
- validateHex(hex) {
181
- const trimmedHex = hex.trim();
182
- const isHexValid = /^#[0-9A-F]{6}$/i.test(trimmedHex);
183
- if (!isHexValid) {
184
- return neverthrow.err(new ColorinoError(`Invalid hex color: '${hex}'`));
185
- }
186
- return neverthrow.ok(true);
187
- }
188
- validatePalette(palette) {
189
- for (const level in palette) {
190
- const hex = palette[level];
191
- const result = this.validateHex(hex);
192
- if (result.isErr()) {
193
- return neverthrow.err(result.error);
194
- }
195
- }
196
- return neverthrow.ok(true);
197
- }
198
- }
199
-
200
- const catppuccinMochaPalette = {
201
- log: "#cdd6f4",
202
- // Text
203
- info: "#89b4fa",
204
- // Blue
205
- warn: "#f9e2af",
206
- // Yellow
207
- error: "#f38ba8",
208
- // Red
209
- debug: "#a6adc8",
210
- // Subtext0
211
- trace: "#9399b2"
212
- // Subtext1
213
- };
214
- const catppuccinLattePalette = {
215
- log: "#4c4f69",
216
- // Text
217
- info: "#1e66f5",
218
- // Blue
219
- warn: "#df8e1d",
220
- // Yellow
221
- error: "#d20f39",
222
- // Red
223
- debug: "#7c7f93",
224
- // Subtext0
225
- trace: "#8c8fa1"
226
- // Subtext1
227
- };
228
- const draculaPalette = {
229
- log: "#f8f8f2",
230
- // Foreground
231
- info: "#8be9fd",
232
- // Cyan
233
- warn: "#f1fa8c",
234
- // Yellow
235
- error: "#ff5555",
236
- // Red
237
- debug: "#bd93f9",
238
- // Purple
239
- trace: "#6272a4"
240
- // Comment
241
- };
242
- const githubLightPalette = {
243
- log: "#24292e",
244
- // Text
245
- info: "#0366d6",
246
- // Blue
247
- warn: "#f9a002",
248
- // Yellow
249
- error: "#d73a49",
250
- // Red
251
- debug: "#586069",
252
- // Gray
253
- trace: "#6a737d"
254
- // Gray-light
255
- };
256
-
257
- const themePalettes = {
258
- "catppuccin-mocha": catppuccinMochaPalette,
259
- "catppuccin-latte": catppuccinLattePalette,
260
- dracula: draculaPalette,
261
- "github-light": githubLightPalette
262
- };
263
- const defaultDarkTheme = "catppuccin-mocha";
264
- const defaultLightTheme = "github-light";
265
- function isThemeName(theme) {
266
- return theme in themePalettes;
267
- }
268
-
269
- function determineBaseTheme(themeOpt, detectedBrowserTheme) {
270
- let baseThemeName;
271
- if (isThemeName(themeOpt)) {
272
- baseThemeName = themeOpt;
273
- } else if (themeOpt === "light") {
274
- baseThemeName = defaultLightTheme;
275
- } else if (themeOpt === "dark") {
276
- baseThemeName = defaultDarkTheme;
277
- } else {
278
- baseThemeName = detectedBrowserTheme === "light" ? defaultLightTheme : defaultDarkTheme;
279
- }
280
- return baseThemeName;
281
- }
282
-
283
- exports.ColorLevel = ColorLevel;
284
- exports.Colorino = Colorino;
285
- exports.InputValidator = InputValidator;
286
- exports.determineBaseTheme = determineBaseTheme;
287
- exports.themePalettes = themePalettes;