colorino 0.13.2 → 0.14.1

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
@@ -1,8 +1,414 @@
1
- import { C as ColorLevel, d as determineBaseTheme, t as themePalettes, M as MyColorino, I as InputValidator } from './shared/colorino.vAejLjBp.mjs';
1
+ import { err, ok } from 'neverthrow';
2
2
  import { spawnSync } from 'node:child_process';
3
3
  import { fileURLToPath } from 'node:url';
4
4
  import { dirname, join } from 'node:path';
5
5
 
6
+ const ColorinoBrowserColorized = Symbol("colorino.browserColorized");
7
+ const ColorinoBrowserObject = Symbol("colorino.browserObject");
8
+
9
+ var ColorLevel = /* @__PURE__ */ ((ColorLevel2) => {
10
+ ColorLevel2[ColorLevel2["NO_COLOR"] = 0] = "NO_COLOR";
11
+ ColorLevel2[ColorLevel2["ANSI"] = 1] = "ANSI";
12
+ ColorLevel2[ColorLevel2["ANSI256"] = 2] = "ANSI256";
13
+ ColorLevel2[ColorLevel2["TRUECOLOR"] = 3] = "TRUECOLOR";
14
+ return ColorLevel2;
15
+ })(ColorLevel || {});
16
+
17
+ class TypeValidator {
18
+ static isNull(value) {
19
+ return value === null;
20
+ }
21
+ static isUndefined(value) {
22
+ return value === void 0;
23
+ }
24
+ static isNullOrUndefined(value) {
25
+ return value == null;
26
+ }
27
+ static isObject(value) {
28
+ return typeof value === "object" && value !== null;
29
+ }
30
+ static isString(value) {
31
+ return typeof value === "string" || value instanceof String;
32
+ }
33
+ static isArray(value) {
34
+ return Array.isArray(value);
35
+ }
36
+ static isError(value) {
37
+ return value instanceof Error;
38
+ }
39
+ static isBrowserColorizedArg(value) {
40
+ return TypeValidator.isObject(value) && ColorinoBrowserColorized in value;
41
+ }
42
+ static isBrowserObjectArg(value) {
43
+ return TypeValidator.isObject(value) && ColorinoBrowserObject in value;
44
+ }
45
+ static isAnsiColoredString(value) {
46
+ return TypeValidator.isString(value) && /\x1b\[[0-9;]*m/.test(value.toString());
47
+ }
48
+ static isFormattableObject(value) {
49
+ return TypeValidator.isObject(value) && !TypeValidator.isError(value) && !TypeValidator.isBrowserColorizedArg(value) && !TypeValidator.isString(value);
50
+ }
51
+ static isConsoleMethod(level) {
52
+ return ["log", "info", "warn", "error", "trace", "debug"].includes(level);
53
+ }
54
+ }
55
+
56
+ class AbstractColorino {
57
+ constructor(initialPalette, _userPalette, _validator, colorLevel, _options = {}) {
58
+ this._userPalette = _userPalette;
59
+ this._validator = _validator;
60
+ this._options = _options;
61
+ this._palette = initialPalette;
62
+ const validatePaletteResult = this._validator.validatePalette(this._palette);
63
+ if (validatePaletteResult.isErr()) throw validatePaletteResult.error;
64
+ this._colorLevel = colorLevel;
65
+ }
66
+ _alreadyWarned = false;
67
+ _colorLevel;
68
+ _palette;
69
+ log(...args) {
70
+ this._out("log", args);
71
+ }
72
+ info(...args) {
73
+ this._out("info", args);
74
+ }
75
+ warn(...args) {
76
+ this._out("warn", args);
77
+ }
78
+ error(...args) {
79
+ this._out("error", args);
80
+ }
81
+ trace(...args) {
82
+ this._out("trace", args);
83
+ }
84
+ debug(...args) {
85
+ this._out("debug", args);
86
+ }
87
+ colorize(text, hex) {
88
+ if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
89
+ return text;
90
+ }
91
+ if (this.isBrowser()) {
92
+ return {
93
+ [ColorinoBrowserColorized]: true,
94
+ text,
95
+ hex
96
+ };
97
+ }
98
+ const ansiPrefix = this._toAnsiPrefix(hex);
99
+ if (!ansiPrefix) {
100
+ return text;
101
+ }
102
+ return `${ansiPrefix}${text}\x1B[0m`;
103
+ }
104
+ _out(level, args) {
105
+ const consoleMethod = TypeValidator.isConsoleMethod(level) ? level : "log";
106
+ const processedArgs = this.processArgs(args);
107
+ if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
108
+ this.output(consoleMethod, processedArgs);
109
+ return;
110
+ }
111
+ const coloredArgs = this.applyColors(consoleMethod, processedArgs);
112
+ this.output(consoleMethod, coloredArgs);
113
+ }
114
+ _toAnsiPrefix(_hex) {
115
+ return "";
116
+ }
117
+ _formatValue(value, maxDepth = this._options.maxDepth ?? 5) {
118
+ const seen = /* @__PURE__ */ new WeakSet();
119
+ const sanitizeArray = (items, depth) => {
120
+ return items.map((item) => sanitize(item, depth));
121
+ };
122
+ const sanitizeObject = (obj, depth) => {
123
+ const result = {};
124
+ for (const key in obj) {
125
+ result[key] = sanitize(obj[key], depth);
126
+ }
127
+ return result;
128
+ };
129
+ const sanitize = (val, currentDepth) => {
130
+ if (TypeValidator.isNullOrUndefined(val) || !TypeValidator.isObject(val)) {
131
+ return val;
132
+ }
133
+ if (seen.has(val)) return "[Circular]";
134
+ seen.add(val);
135
+ if (currentDepth >= maxDepth) return "[Object]";
136
+ const nextDepth = currentDepth + 1;
137
+ if (TypeValidator.isArray(val)) {
138
+ return sanitizeArray(val, nextDepth);
139
+ }
140
+ return sanitizeObject(val, nextDepth);
141
+ };
142
+ return JSON.stringify(sanitize(value, 0), null, 2);
143
+ }
144
+ _filterStack(stack) {
145
+ return stack.split("\n").filter((line) => !line.match(/.*colorino.*/gi)).join("\n");
146
+ }
147
+ _cleanErrorStack(error) {
148
+ if (!error.stack) return error;
149
+ const cleanStack = this._filterStack(error.stack);
150
+ const cloned = Object.create(Object.getPrototypeOf(error));
151
+ Object.assign(cloned, error);
152
+ cloned.stack = cleanStack;
153
+ return cloned;
154
+ }
155
+ _printCleanTrace(args) {
156
+ const error = new Error();
157
+ if (error.stack) {
158
+ const cleanStack = this._filterStack(error.stack);
159
+ console.log(...args, `
160
+ ${cleanStack}`);
161
+ } else {
162
+ console.log(...args);
163
+ }
164
+ }
165
+ }
166
+
167
+ function hexToRgb(hex) {
168
+ const match = hex.toString().match(/[a-f0-9]{6}|[a-f0-9]{3}/i);
169
+ if (!match) {
170
+ return [0, 0, 0];
171
+ }
172
+ let colorString = match[0];
173
+ if (match[0].length === 3) {
174
+ colorString = [...colorString].map((char) => char + char).join("");
175
+ }
176
+ const integer = parseInt(colorString, 16);
177
+ const r = integer >> 16 & 255;
178
+ const g = integer >> 8 & 255;
179
+ const b = integer & 255;
180
+ return [r, g, b];
181
+ }
182
+ function rgbToAnsi256(rgb) {
183
+ const [r, g, b] = rgb;
184
+ if (r === g && g === b) {
185
+ if (r < 8) return 16;
186
+ if (r > 248) return 231;
187
+ return Math.round((r - 8) / 247 * 24) + 232;
188
+ }
189
+ return 16 + 36 * Math.round(r / 255 * 5) + 6 * Math.round(g / 255 * 5) + Math.round(b / 255 * 5);
190
+ }
191
+ function rgbToHsvValue(rgb) {
192
+ const r = rgb[0] / 255;
193
+ const g = rgb[1] / 255;
194
+ const b = rgb[2] / 255;
195
+ const v = Math.max(r, g, b);
196
+ return v * 100;
197
+ }
198
+ function rgbToAnsi16(rgb) {
199
+ const [r, g, b] = rgb;
200
+ const value = rgbToHsvValue(rgb);
201
+ const roundedValue = Math.round(value / 50);
202
+ if (roundedValue === 0) {
203
+ return 30;
204
+ }
205
+ let ansi = 30 + (Math.round(b / 255) << 2 | Math.round(g / 255) << 1 | Math.round(r / 255));
206
+ if (roundedValue === 2) {
207
+ ansi += 60;
208
+ }
209
+ return ansi;
210
+ }
211
+ const colorConverter = {
212
+ hex: {
213
+ toRgb: hexToRgb,
214
+ toAnsi16: (hex) => rgbToAnsi16(hexToRgb(hex)),
215
+ toAnsi256: (hex) => rgbToAnsi256(hexToRgb(hex))
216
+ }};
217
+
218
+ class ColorinoNode extends AbstractColorino {
219
+ constructor(initialPalette, userPalette, validator, colorLevel, options = {}) {
220
+ super(initialPalette, userPalette, validator, colorLevel, options);
221
+ this._maybeWarnUser();
222
+ }
223
+ applyColors(consoleMethod, args) {
224
+ const paletteHex = this._palette[consoleMethod];
225
+ const prefix = this._toAnsiPrefix(paletteHex);
226
+ if (!prefix) return args;
227
+ return args.map((arg) => {
228
+ if (!TypeValidator.isString(arg)) return arg;
229
+ if (TypeValidator.isAnsiColoredString(arg)) return arg;
230
+ return `${prefix}${String(arg)}\x1B[0m`;
231
+ });
232
+ }
233
+ output(consoleMethod, args) {
234
+ if (consoleMethod === "trace") {
235
+ this._printCleanTrace(args);
236
+ } else {
237
+ console[consoleMethod](...args);
238
+ }
239
+ }
240
+ processArgs(args) {
241
+ const processedArgs = [];
242
+ let previousWasObject = false;
243
+ for (const arg of args) {
244
+ if (TypeValidator.isBrowserColorizedArg(arg)) {
245
+ processedArgs.push(arg);
246
+ previousWasObject = false;
247
+ continue;
248
+ }
249
+ if (TypeValidator.isFormattableObject(arg)) {
250
+ processedArgs.push(`
251
+ ${this._formatValue(arg)}`);
252
+ previousWasObject = true;
253
+ } else if (TypeValidator.isError(arg)) {
254
+ processedArgs.push("\n", this._cleanErrorStack(arg));
255
+ previousWasObject = true;
256
+ } else {
257
+ if (TypeValidator.isString(arg) && previousWasObject) {
258
+ processedArgs.push(`
259
+ ${arg}`);
260
+ } else {
261
+ processedArgs.push(arg);
262
+ }
263
+ previousWasObject = false;
264
+ }
265
+ }
266
+ return processedArgs;
267
+ }
268
+ isBrowser() {
269
+ return false;
270
+ }
271
+ _toAnsiPrefix(hex) {
272
+ if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
273
+ return "";
274
+ }
275
+ switch (this._colorLevel) {
276
+ case ColorLevel.TRUECOLOR: {
277
+ const [r, g, b] = colorConverter.hex.toRgb(hex);
278
+ return `\x1B[38;2;${r};${g};${b}m`;
279
+ }
280
+ case ColorLevel.ANSI256: {
281
+ const code = colorConverter.hex.toAnsi256(hex);
282
+ return `\x1B[38;5;${code}m`;
283
+ }
284
+ case ColorLevel.ANSI:
285
+ default: {
286
+ const code = colorConverter.hex.toAnsi16(hex);
287
+ return `\x1B[${code}m`;
288
+ }
289
+ }
290
+ }
291
+ _maybeWarnUser() {
292
+ if (this._alreadyWarned) return;
293
+ this._alreadyWarned = true;
294
+ console.warn(
295
+ "No ANSI color support detected in this terminal. See https://github.com/chalk/supports-color#support-matrix to learn how to enable terminal color."
296
+ );
297
+ }
298
+ }
299
+
300
+ const catppuccinMochaPalette = {
301
+ log: "#cdd6f4",
302
+ // Text
303
+ info: "#89b4fa",
304
+ // Blue
305
+ warn: "#f9e2af",
306
+ // Yellow
307
+ error: "#f38ba8",
308
+ // Red
309
+ debug: "#a6adc8",
310
+ // Subtext0
311
+ trace: "#9399b2"
312
+ // Subtext1
313
+ };
314
+ const catppuccinLattePalette = {
315
+ log: "#4c4f69",
316
+ // Text
317
+ info: "#1e66f5",
318
+ // Blue
319
+ warn: "#df8e1d",
320
+ // Yellow
321
+ error: "#d20f39",
322
+ // Red
323
+ debug: "#7c7f93",
324
+ // Subtext0
325
+ trace: "#8c8fa1"
326
+ // Subtext1
327
+ };
328
+ const draculaPalette = {
329
+ log: "#f8f8f2",
330
+ // Foreground
331
+ info: "#8be9fd",
332
+ // Cyan
333
+ warn: "#f1fa8c",
334
+ // Yellow
335
+ error: "#ff5555",
336
+ // Red
337
+ debug: "#bd93f9",
338
+ // Purple
339
+ trace: "#6272a4"
340
+ // Comment
341
+ };
342
+ const githubLightPalette = {
343
+ log: "#24292e",
344
+ // Text
345
+ info: "#0366d6",
346
+ // Blue
347
+ warn: "#f9a002",
348
+ // Yellow
349
+ error: "#d73a49",
350
+ // Red
351
+ debug: "#586069",
352
+ // Gray
353
+ trace: "#6a737d"
354
+ // Gray-light
355
+ };
356
+
357
+ const themePalettes = {
358
+ "catppuccin-mocha": catppuccinMochaPalette,
359
+ "catppuccin-latte": catppuccinLattePalette,
360
+ dracula: draculaPalette,
361
+ "github-light": githubLightPalette
362
+ };
363
+ const defaultDarkTheme = "dracula";
364
+ const defaultLightTheme = "github-light";
365
+ function isThemeName(theme) {
366
+ return theme in themePalettes;
367
+ }
368
+
369
+ function determineBaseTheme(themeOpt, detectedBrowserTheme) {
370
+ let baseThemeName;
371
+ if (isThemeName(themeOpt)) {
372
+ baseThemeName = themeOpt;
373
+ } else if (themeOpt === "light") {
374
+ baseThemeName = defaultLightTheme;
375
+ } else if (themeOpt === "dark") {
376
+ baseThemeName = defaultDarkTheme;
377
+ } else {
378
+ baseThemeName = detectedBrowserTheme === "light" ? defaultLightTheme : defaultDarkTheme;
379
+ }
380
+ return baseThemeName;
381
+ }
382
+
383
+ class InputValidationError extends Error {
384
+ constructor(message) {
385
+ super(message);
386
+ this.name = "InputValidationError";
387
+ Object.setPrototypeOf(this, InputValidationError.prototype);
388
+ }
389
+ }
390
+
391
+ class InputValidator {
392
+ validateHex(hex) {
393
+ const trimmedHex = hex.trim();
394
+ const isHexValid = /^#[0-9A-F]{6}$/i.test(trimmedHex);
395
+ if (!isHexValid) {
396
+ return err(new InputValidationError(`Invalid hex color: '${hex}'`));
397
+ }
398
+ return ok(true);
399
+ }
400
+ validatePalette(palette) {
401
+ for (const level in palette) {
402
+ const hex = palette[level];
403
+ const result = this.validateHex(hex);
404
+ if (result.isErr()) {
405
+ return err(result.error);
406
+ }
407
+ }
408
+ return ok(true);
409
+ }
410
+ }
411
+
6
412
  const __dirname$1 = dirname(fileURLToPath(import.meta.url));
7
413
  function getTerminalThemeSync() {
8
414
  const scriptPath = join(__dirname$1, "osc-child-probe.js");
@@ -134,12 +540,12 @@ function createColorino(userPalette = {}, options = {}) {
134
540
  const baseThemeName = determineBaseTheme(themeOpt, detectedTerminalTheme);
135
541
  const basePalette = themePalettes[baseThemeName];
136
542
  const finalPalette = { ...basePalette, ...userPalette };
137
- return new MyColorino(
543
+ const colorLevel = nodeDetector.isNodeEnv() ? nodeDetector.getColorLevel() ?? "UnknownEnv" : "UnknownEnv";
544
+ return new ColorinoNode(
138
545
  finalPalette,
139
546
  userPalette,
140
547
  validator,
141
- void 0,
142
- nodeDetector,
548
+ colorLevel,
143
549
  options
144
550
  );
145
551
  }
package/package.json CHANGED
@@ -1,15 +1,15 @@
1
1
  {
2
2
  "name": "colorino",
3
- "version": "0.13.2",
3
+ "version": "0.14.1",
4
4
  "description": "A super simple colorized logger that gets the most out of your terminal",
5
5
  "keywords": [
6
6
  "ansi",
7
+ "chalk",
7
8
  "color",
8
9
  "console",
10
+ "kuler",
9
11
  "logger",
10
- "terminal",
11
- "chalk",
12
- "kuler"
12
+ "terminal"
13
13
  ],
14
14
  "homepage": "https://github.com/simwai/colorino",
15
15
  "bugs": {
@@ -28,27 +28,34 @@
28
28
  "README.md"
29
29
  ],
30
30
  "type": "module",
31
- "main": "./dist/node.cjs",
31
+ "main": "./dist/node.mjs",
32
32
  "module": "./dist/browser.mjs",
33
33
  "types": "./dist/browser.d.ts",
34
+ "unpkg": "./dist/cdn.min.js",
35
+ "jsdelivr": "./dist/cdn.min.js",
34
36
  "exports": {
35
37
  "node": {
36
38
  "types": "./dist/node.d.ts",
37
39
  "import": "./dist/node.mjs",
38
40
  "require": "./dist/node.cjs"
39
41
  },
42
+ "script": "./dist/cdn.min.js",
40
43
  "browser": {
41
44
  "types": "./dist/browser.d.ts",
42
45
  "import": "./dist/browser.mjs",
43
- "require": "./dist/browser.cjs"
46
+ "default": "./dist/browser.mjs"
47
+ },
48
+ "default": {
49
+ "types": "./dist/browser.d.ts",
50
+ "import": "./dist/browser.mjs",
51
+ "default": "./dist/browser.mjs"
44
52
  }
45
53
  },
46
54
  "publishConfig": {
47
55
  "access": "public"
48
56
  },
49
57
  "scripts": {
50
- "bundle:browser": "node --loader ts-node/esm node_modules/rollup/dist/bin/rollup -c rollup.browser.config.ts",
51
- "build": "unbuild && npm run bundle:browser",
58
+ "build": "unbuild",
52
59
  "format": "oxlint --fix && oxfmt",
53
60
  "test:all": "npm run test:node && npm run test:browser",
54
61
  "test:node": "vitest run --project=node",
@@ -72,7 +79,7 @@
72
79
  "@playwright/test": "^1.57.0",
73
80
  "@rollup/plugin-commonjs": "^29.0.0",
74
81
  "@rollup/plugin-node-resolve": "^16.0.3",
75
- "@swc/core": "^1.15.8",
82
+ "@rollup/plugin-terser": "^0.4.4",
76
83
  "@types/node": "^24.9.2",
77
84
  "@vitest/browser-playwright": "^4.0.15",
78
85
  "@vitest/coverage-v8": "^4.0.15",
@@ -84,7 +91,6 @@
84
91
  "oxfmt": "^0.23.0",
85
92
  "oxlint": "^0.2.0",
86
93
  "playwright": "^1.57.0",
87
- "rollup": "^4.54.0",
88
94
  "ts-node": "^10.9.2",
89
95
  "tsx": "^4.20.6",
90
96
  "typescript": "^5.9.3",
@@ -99,7 +105,7 @@
99
105
  "*.ts": "vitest related --run"
100
106
  },
101
107
  "engines": {
102
- "node": ">=17.0.0",
103
- "npm": ">=8.0.0"
108
+ "node": ">=20.0.0",
109
+ "npm": ">=9.6.4"
104
110
  }
105
111
  }