colorino 0.12.7 → 0.13.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/README.md +73 -53
- package/dist/browser.bundle.cjs +133 -39
- package/dist/browser.bundle.mjs +133 -39
- package/dist/browser.cjs +1 -1
- package/dist/browser.d.cts +2 -2
- package/dist/browser.d.mts +2 -2
- package/dist/browser.d.ts +2 -2
- package/dist/browser.mjs +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.d.cts +2 -2
- package/dist/node.d.mts +2 -2
- package/dist/node.d.ts +2 -2
- package/dist/node.mjs +1 -1
- package/dist/shared/{colorino.ClDpLv-k.mjs → colorino.DEvR4n1Y.mjs} +133 -39
- package/dist/shared/{colorino.BgxwS1Lc.cjs → colorino.Dcy2ipG7.cjs} +133 -39
- package/dist/shared/{colorino.DWWtObdr.d.ts → colorino.FdIbpxRG.d.cts} +1 -0
- package/dist/shared/{colorino.DWWtObdr.d.cts → colorino.FdIbpxRG.d.mts} +1 -0
- package/dist/shared/{colorino.DWWtObdr.d.mts → colorino.FdIbpxRG.d.ts} +1 -0
- package/package.json +21 -19
package/README.md
CHANGED
|
@@ -20,12 +20,13 @@ Colorino automatically adapts its palette to your terminal or browser DevTools t
|
|
|
20
20
|
- [Examples](#5-3-2)
|
|
21
21
|
- [Customization](#5-4)
|
|
22
22
|
- [Supported Environment Variables](#5-5)
|
|
23
|
+
- [Colorize Helper (Manual Overrides)](#5-6)
|
|
23
24
|
- [Colorino vs. Chalk](#6)
|
|
24
25
|
- [API Reference](#7)
|
|
25
26
|
- [1. `colorino` (default instance)](#7-1)
|
|
26
27
|
- [2. `createColorino(palette?, options?)` (factory)](#7-2)
|
|
27
28
|
- [Extending Colorino](#8)
|
|
28
|
-
- [Use
|
|
29
|
+
- [Use Case: Automatic File/Context Info](#8-1)
|
|
29
30
|
- [Internals & Dependencies](#9)
|
|
30
31
|
- [Why This Pattern?](#9-1)
|
|
31
32
|
- [License](#10)
|
|
@@ -36,11 +37,11 @@ Colorino automatically adapts its palette to your terminal or browser DevTools t
|
|
|
36
37
|
|
|
37
38
|
Plain `console.log` is colorless and inconsistent. Libraries like `chalk` let you style strings, but you have to decorate every message and manually manage color choices.
|
|
38
39
|
|
|
39
|
-
Colorino is different: it’s a "batteries-included" logging facade with beautiful, theme-aware colors and a familiar API
|
|
40
|
+
Colorino is different: it’s a "batteries-included" logging facade with beautiful, theme-aware colors and a familiar API. Instantly upgrade your logs everywhere.
|
|
40
41
|
|
|
41
42
|
## <a id="2"></a>Features
|
|
42
43
|
|
|
43
|
-
- 🎨 **Smart Theming:** Automatically detects
|
|
44
|
+
- 🎨 **Smart Theming:** Automatically detects _dark/light_ mode and applies a high‑contrast base palette by default (Dracula for dark, GitHub Light for light); opt into a coordinated theme preset when you want richer colors.
|
|
44
45
|
- 🤘 **Graceful Color Degradation**: Accepts rich colors (hex/RGB) and automatically down‑samples to the best ANSI‑16/ANSI‑256/Truecolor match for the current environment.
|
|
45
46
|
- 🤝 **Familiar API:** If you know `console.log`, you already know Colorino: all standard log levels are supported.
|
|
46
47
|
- 🔀 **Environment-Aware:** Works in **Node.js** (ANSI color and truecolor) and all major **Browsers** (CSS styles).
|
|
@@ -65,10 +66,10 @@ You can use Colorino directly in the browser without any build step.
|
|
|
65
66
|
<html>
|
|
66
67
|
<head>
|
|
67
68
|
<script type="module">
|
|
68
|
-
import { colorino } from 'https://unpkg.com/colorino/dist/browser.bundle.mjs'
|
|
69
|
+
import { colorino } from 'https://unpkg.com/colorino/dist/browser.bundle.mjs'
|
|
69
70
|
|
|
70
|
-
colorino.info('Hello from the browser!')
|
|
71
|
-
colorino.error('Something went wrong')
|
|
71
|
+
colorino.info('Hello from the browser!')
|
|
72
|
+
colorino.error('Something went wrong')
|
|
72
73
|
</script>
|
|
73
74
|
</head>
|
|
74
75
|
<body></body>
|
|
@@ -118,9 +119,10 @@ Use the factory to create as many loggers as you want (each with its own palette
|
|
|
118
119
|
import { createColorino } from 'colorino'
|
|
119
120
|
|
|
120
121
|
const myLogger = createColorino(
|
|
121
|
-
{
|
|
122
|
+
{
|
|
123
|
+
// Palette (partial)
|
|
122
124
|
error: '#ff007b',
|
|
123
|
-
info: '#3498db'
|
|
125
|
+
info: '#3498db',
|
|
124
126
|
},
|
|
125
127
|
{ disableWarnings: true } // Options (see below)
|
|
126
128
|
)
|
|
@@ -132,17 +134,17 @@ myLogger.info('Rebranded info!')
|
|
|
132
134
|
|
|
133
135
|
`createColorino(palette?, options?)` accepts:
|
|
134
136
|
|
|
135
|
-
| Option | Type
|
|
136
|
-
|
|
137
|
-
| `disableWarnings` | `boolean`
|
|
138
|
-
| `theme` | `ThemeOption` (see below)
|
|
139
|
-
| `disableOscProbe` | `boolean`
|
|
140
|
-
| `maxDepth` | `number`
|
|
137
|
+
| Option | Type | Default | Description |
|
|
138
|
+
| ----------------- | ------------------------- | -------- | -------------------------------------------------------------------------- |
|
|
139
|
+
| `disableWarnings` | `boolean` | `false` | Suppress warnings when color support can't be detected or is disabled. |
|
|
140
|
+
| `theme` | `ThemeOption` (see below) | `'auto'` | Control the active color theme or force a specific mode. |
|
|
141
|
+
| `disableOscProbe` | `boolean` | `false` | Disable OSC 11 terminal theme probing (use only env heuristics for theme). |
|
|
142
|
+
| `maxDepth` | `number` | `5` | Maximum depth when pretty-printing objects in log output. |
|
|
141
143
|
|
|
142
144
|
**`theme` accepts three types of values:**
|
|
143
145
|
|
|
144
146
|
1. **`'auto'`** (Default): Automatically detects your terminal or browser theme (dark/light) and applies the matching default preset.
|
|
145
|
-
When combined with `disableOscProbe: true`, only environment variables are used for theme detection (no OSC 11 probe).
|
|
147
|
+
When combined with `disableOscProbe: true`, only environment variables are used for theme detection (no OSC 11 probe).
|
|
146
148
|
2. **`'dark' | 'light'`**: Forces the logger into a specific mode using the default preset for that mode.
|
|
147
149
|
3. **`ThemeName`**: Forces a specific built-in palette (e.g., `'dracula'`).
|
|
148
150
|
|
|
@@ -150,12 +152,12 @@ When combined with `disableOscProbe: true`, only environment variables are used
|
|
|
150
152
|
|
|
151
153
|
Pass any of these names to the `theme` option to use a specific palette:
|
|
152
154
|
|
|
153
|
-
| Theme Name | Type
|
|
154
|
-
|
|
155
|
-
| `'dracula'` | **Dark** (High Contrast)
|
|
156
|
-
| `'catppuccin-mocha'` | **Dark** (Low Contrast)
|
|
157
|
-
| `'github-light'` | **Light** (High Contrast)| Clean, sharp, high-contrast.
|
|
158
|
-
| `'catppuccin-latte'` | **Light** (Low Contrast)
|
|
155
|
+
| Theme Name | Type | Description |
|
|
156
|
+
| -------------------- | ------------------------- | --------------------------------------- |
|
|
157
|
+
| `'dracula'` | **Dark** (High Contrast) | Vibrant pinks, purples, and cyans. |
|
|
158
|
+
| `'catppuccin-mocha'` | **Dark** (Low Contrast) | Soothing pastel colors. |
|
|
159
|
+
| `'github-light'` | **Light** (High Contrast) | Clean, sharp, high-contrast. |
|
|
160
|
+
| `'catppuccin-latte'` | **Light** (Low Contrast) | Warm, cozy light mode with soft colors. |
|
|
159
161
|
|
|
160
162
|
In auto mode, Colorino uses dracula in dark environments and github-light in light environments.
|
|
161
163
|
|
|
@@ -166,14 +168,14 @@ Set only the colors you care about; everything else uses the detected base theme
|
|
|
166
168
|
|
|
167
169
|
```typescript
|
|
168
170
|
// Only customize error and warn
|
|
169
|
-
const myLogger = createColorino({
|
|
171
|
+
const myLogger = createColorino({
|
|
170
172
|
error: '#ff007b',
|
|
171
|
-
warn: '#ffa500'
|
|
173
|
+
warn: '#ffa500',
|
|
172
174
|
})
|
|
173
175
|
|
|
174
176
|
// Detected dark terminal (uses dracula as base):
|
|
175
177
|
// - error: #ff007b (your custom red)
|
|
176
|
-
// - warn: #ffa500 (your custom orange)
|
|
178
|
+
// - warn: #ffa500 (your custom orange)
|
|
177
179
|
// - info: #8be9fd (dracula cyan)
|
|
178
180
|
// - log: #f8f8f2 (dracula foreground)
|
|
179
181
|
// - debug: #bd93f9 (dracula purple)
|
|
@@ -201,10 +203,7 @@ Overlay your own colors on top of a built-in theme.
|
|
|
201
203
|
|
|
202
204
|
```typescript
|
|
203
205
|
// Use GitHub Light but with a custom error color
|
|
204
|
-
const myLogger = createColorino(
|
|
205
|
-
{ error: '#ff007b' },
|
|
206
|
-
{ theme: 'github-light' }
|
|
207
|
-
)
|
|
206
|
+
const myLogger = createColorino({ error: '#ff007b' }, { theme: 'github-light' })
|
|
208
207
|
```
|
|
209
208
|
|
|
210
209
|
**4. Force a specific mode (uses defaults):**
|
|
@@ -220,11 +219,11 @@ const darkLogger = createColorino({}, { theme: 'dark' })
|
|
|
220
219
|
|
|
221
220
|
### <a id="5-4"></a>Customization
|
|
222
221
|
|
|
223
|
-
Use your brand colors by passing a partial palette to the `createColorino` factory. Any log levels you don't specify will use the detected
|
|
222
|
+
Use your brand colors by passing a partial palette to the `createColorino` factory. Any log levels you don't specify will use the detected default colors unless you explicitly select a theme preset.
|
|
224
223
|
|
|
225
224
|
Colorino always targets the highest color fidelity supported by the environment. If your palette uses hex colors but only ANSI‑16 is available, Colorino computes the nearest ANSI color so your branding stays recognizable, even on limited terminals.
|
|
226
225
|
|
|
227
|
-
If you pass an invalid color value (e.g. malformed hex) in a custom palette, Colorino throws an InputValidationError at creation time so broken palettes fail fast.
|
|
226
|
+
If you pass an invalid color value (e.g. malformed hex) in a custom palette, Colorino throws an `InputValidationError` at creation time so broken palettes fail fast.
|
|
228
227
|
|
|
229
228
|
```typescript
|
|
230
229
|
import { createColorino } from 'colorino'
|
|
@@ -240,26 +239,41 @@ myLogger.info('Still styled by theme.') // Uses the default theme color
|
|
|
240
239
|
|
|
241
240
|
Colorino auto-detects your environment and color support, but you can override behavior using these standard environment variables (compatible with Chalk):
|
|
242
241
|
|
|
243
|
-
| Variable
|
|
244
|
-
|
|
245
|
-
| `NO_COLOR`
|
|
246
|
-
| `FORCE_COLOR`
|
|
247
|
-
| `CLICOLOR`
|
|
248
|
-
| `CLICOLOR_FORCE
|
|
249
|
-
| `TERM`
|
|
250
|
-
| `COLORTERM`
|
|
251
|
-
| `WT_SESSION`
|
|
252
|
-
| `CI`
|
|
242
|
+
| Variable | Effect | Example |
|
|
243
|
+
| ---------------- | --------------------------------------------------------------------- | ------------------------------ |
|
|
244
|
+
| `NO_COLOR` | Forces no color output | `NO_COLOR=1 node app.js` |
|
|
245
|
+
| `FORCE_COLOR` | Forces color level: `0`=off, `1`=ANSI‑16, `2`=ANSI‑256, `3`=Truecolor | `FORCE_COLOR=3 node app.js` |
|
|
246
|
+
| `CLICOLOR` | `"0"` disables color | `CLICOLOR=0 node app.js` |
|
|
247
|
+
| `CLICOLOR_FORCE` | Non‑`"0"` value enables color even if not a TTY | `CLICOLOR_FORCE=1 node app.js` |
|
|
248
|
+
| `TERM` | Terminal type; may influence color support | `TERM=xterm-256color` |
|
|
249
|
+
| `COLORTERM` | `'truecolor'` or `'24bit'` enables truecolor | `COLORTERM=truecolor` |
|
|
250
|
+
| `WT_SESSION` | Enables color detection for Windows Terminal | |
|
|
251
|
+
| `CI` | Many CI platforms default to no color | `CI=1 node app.js` |
|
|
252
|
+
|
|
253
|
+
### <a id="5-6"></a>Colorize Helper (Manual Overrides)
|
|
254
|
+
|
|
255
|
+
Sometimes you want full control over a single piece of text without changing your global palette, e.g. when you use a mostly neutral theme but still want to highlight a keyword.
|
|
256
|
+
|
|
257
|
+
Colorino exposes a small `colorize(text, hex)` helper on every logger instance:
|
|
258
|
+
|
|
259
|
+
```ts
|
|
260
|
+
import { colorino } from 'colorino'
|
|
261
|
+
|
|
262
|
+
const important = colorino.colorize('IMPORTANT', '#ff5733')
|
|
263
|
+
colorino.info(important, 'Something happened')
|
|
264
|
+
```
|
|
265
|
+
|
|
266
|
+
When color is disabled (for example via `NO_COLOR=1` or lack of support), `colorize` returns the plain input string, so your logs stay readable.
|
|
253
267
|
|
|
254
268
|
## <a id="6"></a>Colorino vs. Chalk
|
|
255
269
|
|
|
256
|
-
| Feature
|
|
257
|
-
|
|
258
|
-
| Out-of-box logs
|
|
259
|
-
| Zero-config
|
|
260
|
-
| Node + browser
|
|
261
|
-
| CSS console logs
|
|
262
|
-
| Extensible / Composable
|
|
270
|
+
| Feature | 🎨 **Colorino** | 🖍️ **Chalk** |
|
|
271
|
+
| ----------------------- | ------------------------ | ----------------- |
|
|
272
|
+
| Out-of-box logs | ✔ themed, all log levels | ✘ string styling |
|
|
273
|
+
| Zero-config | ✔ | ✘ manual, per-use |
|
|
274
|
+
| Node + browser | ✔ | ✘ (Node only) |
|
|
275
|
+
| CSS console logs | ✔ | ✘ |
|
|
276
|
+
| Extensible / Composable | ✔ (via factory) | ✘ |
|
|
263
277
|
|
|
264
278
|
## <a id="7"></a>API Reference
|
|
265
279
|
|
|
@@ -289,12 +303,17 @@ A factory function to create your own customized logger instances.
|
|
|
289
303
|
|
|
290
304
|
Colorino is designed for composition: create a base logger via `createColorino()`, then extend it by inheriting from the base and overriding only the methods you need.
|
|
291
305
|
|
|
292
|
-
### <a id="8-1"></a>Use
|
|
306
|
+
### <a id="8-1"></a>Use Case: Automatic File/Context Info
|
|
293
307
|
|
|
294
308
|
This example prefixes every `.info()` and `.error()` call with best‑effort caller context (file/line) derived from a synthetic `Error` stack.
|
|
295
309
|
|
|
296
310
|
```ts
|
|
297
|
-
import {
|
|
311
|
+
import {
|
|
312
|
+
createColorino,
|
|
313
|
+
type Colorino,
|
|
314
|
+
type ColorinoOptions,
|
|
315
|
+
type Palette,
|
|
316
|
+
} from 'colorino'
|
|
298
317
|
|
|
299
318
|
function getCallerContext(): string {
|
|
300
319
|
const err = new Error()
|
|
@@ -318,15 +337,16 @@ function getCallerContext(): string {
|
|
|
318
337
|
|
|
319
338
|
export function createContextLogger(
|
|
320
339
|
palette?: Partial<Palette>,
|
|
321
|
-
options?: ColorinoOptions
|
|
340
|
+
options?: ColorinoOptions
|
|
322
341
|
): Colorino {
|
|
323
342
|
const base = createColorino(palette, options)
|
|
324
343
|
|
|
325
344
|
// Inherit all default methods from the base logger...
|
|
326
|
-
const logger = Object.create(base) as Colorino // Object.create uses `base` as the prototype.
|
|
345
|
+
const logger = Object.create(base) as Colorino // Object.create uses `base` as the prototype.
|
|
327
346
|
|
|
328
347
|
// ...and override only what you need.
|
|
329
|
-
Object.assign(logger, {
|
|
348
|
+
Object.assign(logger, {
|
|
349
|
+
// Object.assign copies these methods onto `logger`.
|
|
330
350
|
info(...args: unknown[]) {
|
|
331
351
|
base.info(`[${getCallerContext()}]`, ...args)
|
|
332
352
|
},
|
|
@@ -359,4 +379,4 @@ logger.error('Failed to load user', { id: 456 })
|
|
|
359
379
|
|
|
360
380
|
## <a id="10"></a>License
|
|
361
381
|
|
|
362
|
-
[MIT](LICENSE.md)
|
|
382
|
+
[MIT](LICENSE.md)
|
package/dist/browser.bundle.cjs
CHANGED
|
@@ -62,6 +62,8 @@ var ColorLevel = /* @__PURE__ */ ((ColorLevel2) => {
|
|
|
62
62
|
function isConsoleMethod(level) {
|
|
63
63
|
return ["log", "info", "warn", "error", "trace", "debug"].includes(level);
|
|
64
64
|
}
|
|
65
|
+
const ColorinoBrowserColorized = Symbol("colorino.browserColorized");
|
|
66
|
+
const ColorinoBrowserObject = Symbol("colorino.browserObject");
|
|
65
67
|
|
|
66
68
|
const catppuccinMochaPalette = {
|
|
67
69
|
log: "#cdd6f4",
|
|
@@ -146,6 +148,33 @@ function determineBaseTheme(themeOpt, detectedBrowserTheme) {
|
|
|
146
148
|
return baseThemeName;
|
|
147
149
|
}
|
|
148
150
|
|
|
151
|
+
class TypeValidator {
|
|
152
|
+
static isNull(value) {
|
|
153
|
+
return value === null;
|
|
154
|
+
}
|
|
155
|
+
static isObject(value) {
|
|
156
|
+
return typeof value === "object" && value !== null;
|
|
157
|
+
}
|
|
158
|
+
static isString(value) {
|
|
159
|
+
return typeof value === "string";
|
|
160
|
+
}
|
|
161
|
+
static isError(value) {
|
|
162
|
+
return value instanceof Error;
|
|
163
|
+
}
|
|
164
|
+
static isBrowserColorizedArg(value) {
|
|
165
|
+
return typeof value === "object" && value !== null && ColorinoBrowserColorized in value;
|
|
166
|
+
}
|
|
167
|
+
static isBrowserObjectArg(value) {
|
|
168
|
+
return typeof value === "object" && value !== null && ColorinoBrowserObject in value;
|
|
169
|
+
}
|
|
170
|
+
static isAnsiColoredString(value) {
|
|
171
|
+
return TypeValidator.isString(value) && /\x1b\[[0-9;]*m/.test(value);
|
|
172
|
+
}
|
|
173
|
+
static isFormattableObject(value) {
|
|
174
|
+
return TypeValidator.isObject(value) && !TypeValidator.isError(value) && !TypeValidator.isBrowserColorizedArg(value);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
149
178
|
class MyColorino {
|
|
150
179
|
constructor(initialPalette, _userPalette, _validator, _browserColorSupportDetector, _nodeColorSupportDetector, _options = {}) {
|
|
151
180
|
this._userPalette = _userPalette;
|
|
@@ -164,7 +193,7 @@ class MyColorino {
|
|
|
164
193
|
const themeOpt = this._options.theme ?? "auto";
|
|
165
194
|
if (themeOpt === "auto" && this._nodeColorSupportDetector) {
|
|
166
195
|
this._nodeColorSupportDetector.onTheme((resolvedTheme) => {
|
|
167
|
-
this.
|
|
196
|
+
this._applyResolvedTheme(resolvedTheme);
|
|
168
197
|
});
|
|
169
198
|
}
|
|
170
199
|
}
|
|
@@ -172,12 +201,6 @@ class MyColorino {
|
|
|
172
201
|
_colorLevel;
|
|
173
202
|
isBrowser;
|
|
174
203
|
_palette;
|
|
175
|
-
_appllyResolvedTheme(resolvedTheme) {
|
|
176
|
-
const themeOpt = this._options.theme ?? "auto";
|
|
177
|
-
const baseThemeName = determineBaseTheme(themeOpt, resolvedTheme);
|
|
178
|
-
const basePalette = themePalettes[baseThemeName];
|
|
179
|
-
this._palette = { ...basePalette, ...this._userPalette };
|
|
180
|
-
}
|
|
181
204
|
log(...args) {
|
|
182
205
|
this._out("log", args);
|
|
183
206
|
}
|
|
@@ -196,6 +219,32 @@ class MyColorino {
|
|
|
196
219
|
debug(...args) {
|
|
197
220
|
this._out("debug", args);
|
|
198
221
|
}
|
|
222
|
+
colorize(text, hex) {
|
|
223
|
+
if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
|
|
224
|
+
return text;
|
|
225
|
+
}
|
|
226
|
+
if (this.isBrowser) {
|
|
227
|
+
return {
|
|
228
|
+
[ColorinoBrowserColorized]: true,
|
|
229
|
+
text,
|
|
230
|
+
hex
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
const ansiPrefix = this._toAnsiPrefix(hex);
|
|
234
|
+
if (!ansiPrefix) {
|
|
235
|
+
return text;
|
|
236
|
+
}
|
|
237
|
+
return `${ansiPrefix}${text}\x1B[0m`;
|
|
238
|
+
}
|
|
239
|
+
_isAnsiColoredString(value) {
|
|
240
|
+
return typeof value === "string" && /\x1b\[[0-9;]*m/.test(value);
|
|
241
|
+
}
|
|
242
|
+
_applyResolvedTheme(resolvedTheme) {
|
|
243
|
+
const themeOpt = this._options.theme ?? "auto";
|
|
244
|
+
const baseThemeName = determineBaseTheme(themeOpt, resolvedTheme);
|
|
245
|
+
const basePalette = themePalettes[baseThemeName];
|
|
246
|
+
this._palette = { ...basePalette, ...this._userPalette };
|
|
247
|
+
}
|
|
199
248
|
_detectColorSupport() {
|
|
200
249
|
if (this.isBrowser) {
|
|
201
250
|
return this._browserColorSupportDetector?.getColorLevel() ?? "UnknownEnv";
|
|
@@ -215,7 +264,7 @@ class MyColorino {
|
|
|
215
264
|
_formatValue(value, maxDepth = this._options.maxDepth ?? 5) {
|
|
216
265
|
const seen = /* @__PURE__ */ new WeakSet();
|
|
217
266
|
const sanitize = (val, currentDepth) => {
|
|
218
|
-
if (val
|
|
267
|
+
if (val == null || typeof val !== "object") return val;
|
|
219
268
|
if (seen.has(val)) return "[Circular]";
|
|
220
269
|
seen.add(val);
|
|
221
270
|
if (currentDepth >= maxDepth) return "[Object]";
|
|
@@ -233,21 +282,36 @@ class MyColorino {
|
|
|
233
282
|
};
|
|
234
283
|
return JSON.stringify(sanitize(value, 0), null, 2);
|
|
235
284
|
}
|
|
285
|
+
_normalizeString(value) {
|
|
286
|
+
if (value instanceof String) return value.valueOf();
|
|
287
|
+
return value;
|
|
288
|
+
}
|
|
236
289
|
_processArgs(args) {
|
|
237
290
|
const processedArgs = [];
|
|
238
291
|
let previousWasObject = false;
|
|
239
|
-
for (const
|
|
240
|
-
const
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
292
|
+
for (const rawArg of args) {
|
|
293
|
+
const arg = this._normalizeString(rawArg);
|
|
294
|
+
if (TypeValidator.isBrowserColorizedArg(arg)) {
|
|
295
|
+
processedArgs.push(arg);
|
|
296
|
+
previousWasObject = false;
|
|
297
|
+
continue;
|
|
298
|
+
}
|
|
299
|
+
if (TypeValidator.isFormattableObject(arg)) {
|
|
300
|
+
if (this.isBrowser) {
|
|
301
|
+
processedArgs.push({
|
|
302
|
+
[ColorinoBrowserObject]: true,
|
|
303
|
+
value: arg
|
|
304
|
+
});
|
|
305
|
+
} else {
|
|
306
|
+
processedArgs.push(`
|
|
244
307
|
${this._formatValue(arg)}`);
|
|
308
|
+
}
|
|
245
309
|
previousWasObject = true;
|
|
246
|
-
} else if (isError) {
|
|
310
|
+
} else if (TypeValidator.isError(arg)) {
|
|
247
311
|
processedArgs.push("\n", this._cleanErrorStack(arg));
|
|
248
312
|
previousWasObject = true;
|
|
249
313
|
} else {
|
|
250
|
-
if (
|
|
314
|
+
if (TypeValidator.isString(arg) && previousWasObject) {
|
|
251
315
|
processedArgs.push(`
|
|
252
316
|
${arg}`);
|
|
253
317
|
} else {
|
|
@@ -259,48 +323,78 @@ ${arg}`);
|
|
|
259
323
|
return processedArgs;
|
|
260
324
|
}
|
|
261
325
|
_applyBrowserColors(consoleMethod, args) {
|
|
262
|
-
const
|
|
263
|
-
|
|
264
|
-
|
|
326
|
+
const formatParts = [];
|
|
327
|
+
const cssArgs = [];
|
|
328
|
+
const otherArgs = [];
|
|
329
|
+
const paletteHex = this._palette[consoleMethod];
|
|
330
|
+
for (const rawArg of args) {
|
|
331
|
+
const arg = this._normalizeString(rawArg);
|
|
332
|
+
if (TypeValidator.isBrowserColorizedArg(arg)) {
|
|
333
|
+
formatParts.push(`%c${arg.text}`);
|
|
334
|
+
cssArgs.push(`color:${arg.hex}`);
|
|
335
|
+
continue;
|
|
336
|
+
}
|
|
337
|
+
if (TypeValidator.isBrowserObjectArg(arg)) {
|
|
338
|
+
formatParts.push("%o");
|
|
339
|
+
otherArgs.push(arg.value);
|
|
340
|
+
continue;
|
|
341
|
+
}
|
|
342
|
+
if (TypeValidator.isString(arg)) {
|
|
343
|
+
formatParts.push(`%c${arg}`);
|
|
344
|
+
cssArgs.push(`color:${paletteHex}`);
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
formatParts.push("%o");
|
|
348
|
+
otherArgs.push(arg);
|
|
265
349
|
}
|
|
266
|
-
|
|
350
|
+
if (formatParts.length === 0) {
|
|
351
|
+
return args;
|
|
352
|
+
}
|
|
353
|
+
return [formatParts.join(""), ...cssArgs, ...otherArgs];
|
|
267
354
|
}
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
355
|
+
_toAnsiPrefix(hex) {
|
|
356
|
+
if (this._colorLevel === ColorLevel.NO_COLOR || this._colorLevel === "UnknownEnv") {
|
|
357
|
+
return "";
|
|
358
|
+
}
|
|
271
359
|
switch (this._colorLevel) {
|
|
272
360
|
case ColorLevel.TRUECOLOR: {
|
|
273
361
|
const [r, g, b] = colorConverter.hex.toRgb(hex);
|
|
274
|
-
|
|
275
|
-
break;
|
|
362
|
+
return `\x1B[38;2;${r};${g};${b}m`;
|
|
276
363
|
}
|
|
277
364
|
case ColorLevel.ANSI256: {
|
|
278
365
|
const code = colorConverter.hex.toAnsi256(hex);
|
|
279
|
-
|
|
280
|
-
break;
|
|
366
|
+
return `\x1B[38;5;${code}m`;
|
|
281
367
|
}
|
|
282
368
|
case ColorLevel.ANSI:
|
|
283
369
|
default: {
|
|
284
370
|
const code = colorConverter.hex.toAnsi16(hex);
|
|
285
|
-
|
|
286
|
-
break;
|
|
371
|
+
return `\x1B[${code}m`;
|
|
287
372
|
}
|
|
288
373
|
}
|
|
374
|
+
}
|
|
375
|
+
_applyNodeColors(consoleMethod, args) {
|
|
289
376
|
const coloredArgs = [...args];
|
|
290
377
|
const firstStringIndex = coloredArgs.findIndex(
|
|
291
378
|
(arg) => typeof arg === "string"
|
|
292
379
|
);
|
|
293
|
-
if (firstStringIndex
|
|
294
|
-
|
|
380
|
+
if (firstStringIndex === -1) {
|
|
381
|
+
return coloredArgs;
|
|
382
|
+
}
|
|
383
|
+
const first = coloredArgs[firstStringIndex];
|
|
384
|
+
if (this._isAnsiColoredString(first)) {
|
|
385
|
+
return coloredArgs;
|
|
386
|
+
}
|
|
387
|
+
const hex = this._palette[consoleMethod];
|
|
388
|
+
const ansiPrefix = this._toAnsiPrefix(hex);
|
|
389
|
+
if (!ansiPrefix) {
|
|
390
|
+
return coloredArgs;
|
|
295
391
|
}
|
|
392
|
+
coloredArgs[firstStringIndex] = `${ansiPrefix}${String(first)}\x1B[0m`;
|
|
296
393
|
return coloredArgs;
|
|
297
394
|
}
|
|
298
395
|
_output(consoleMethod, args) {
|
|
299
|
-
if (consoleMethod === "trace")
|
|
300
|
-
|
|
301
|
-
} else {
|
|
302
|
-
console[consoleMethod](...args);
|
|
303
|
-
}
|
|
396
|
+
if (consoleMethod === "trace") this._printCleanTrace(args);
|
|
397
|
+
else console[consoleMethod](...args);
|
|
304
398
|
}
|
|
305
399
|
_out(level, args) {
|
|
306
400
|
const consoleMethod = isConsoleMethod(level) ? level : "log";
|
|
@@ -822,11 +916,11 @@ class Err {
|
|
|
822
916
|
}
|
|
823
917
|
Result.fromThrowable;
|
|
824
918
|
|
|
825
|
-
class
|
|
919
|
+
class InputValidationError extends Error {
|
|
826
920
|
constructor(message) {
|
|
827
921
|
super(message);
|
|
828
|
-
this.name = "
|
|
829
|
-
Object.setPrototypeOf(this,
|
|
922
|
+
this.name = "InputValidationError";
|
|
923
|
+
Object.setPrototypeOf(this, InputValidationError.prototype);
|
|
830
924
|
}
|
|
831
925
|
}
|
|
832
926
|
|
|
@@ -835,7 +929,7 @@ class InputValidator {
|
|
|
835
929
|
const trimmedHex = hex.trim();
|
|
836
930
|
const isHexValid = /^#[0-9A-F]{6}$/i.test(trimmedHex);
|
|
837
931
|
if (!isHexValid) {
|
|
838
|
-
return err(new
|
|
932
|
+
return err(new InputValidationError(`Invalid hex color: '${hex}'`));
|
|
839
933
|
}
|
|
840
934
|
return ok(true);
|
|
841
935
|
}
|