colorino 0.1.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/LICENSE.MD +21 -0
- package/README.md +239 -0
- package/dist/browser.cjs +61 -0
- package/dist/browser.d.cts +7 -0
- package/dist/browser.d.mts +7 -0
- package/dist/browser.d.ts +7 -0
- package/dist/browser.mjs +58 -0
- package/dist/node.cjs +194 -0
- package/dist/node.d.cts +7 -0
- package/dist/node.d.mts +7 -0
- package/dist/node.d.ts +7 -0
- package/dist/node.mjs +191 -0
- package/dist/shared/colorino.BCUN0J9y.cjs +210 -0
- package/dist/shared/colorino.V5I9NhYv.d.cts +89 -0
- package/dist/shared/colorino.V5I9NhYv.d.mts +89 -0
- package/dist/shared/colorino.V5I9NhYv.d.ts +89 -0
- package/dist/shared/colorino.xxLMfJFV.mjs +204 -0
- package/package.json +90 -0
package/LICENSE.MD
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 simwai
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT of OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,239 @@
|
|
|
1
|
+
# 🎨 Colorino
|
|
2
|
+
|
|
3
|
+
**The zero-configuration, context-aware `console` logger for Node.js and the browser.**
|
|
4
|
+
|
|
5
|
+
Colorino automatically adapts its palette to your terminal or browser DevTools theme.
|
|
6
|
+
|
|
7
|
+
***
|
|
8
|
+
|
|
9
|
+
## Table of Contents
|
|
10
|
+
|
|
11
|
+
- [Why use Colorino?](#why-use-colorino)
|
|
12
|
+
- [Features](#features)
|
|
13
|
+
- [Installation](#installation)
|
|
14
|
+
- [Usage](#usage)
|
|
15
|
+
- [Quick Start](#quick-start)
|
|
16
|
+
- [Creating a Custom Logger](#creating-a-custom-logger)
|
|
17
|
+
- [Options & Theme Overrides](#options--theme-overrides)
|
|
18
|
+
- [Customization](#customization)
|
|
19
|
+
- [Supported Environment Variables](#supported-environment-variables)
|
|
20
|
+
- [Colorino vs. Chalk](#colorino-vs-chalk)
|
|
21
|
+
- [API Reference](#api-reference)
|
|
22
|
+
- [Extending Colorino](#extending-colorino)
|
|
23
|
+
- [Contributing](#contributing)
|
|
24
|
+
- [License](#license)
|
|
25
|
+
|
|
26
|
+
***
|
|
27
|
+
|
|
28
|
+
## Why use Colorino?
|
|
29
|
+
|
|
30
|
+
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.
|
|
31
|
+
|
|
32
|
+
Colorino is different: it’s a "batteries-included" logging facade with beautiful, theme-aware colors and a familiar API—no learning curve, no configuration. Instantly upgrade your logs everywhere.
|
|
33
|
+
|
|
34
|
+
***
|
|
35
|
+
|
|
36
|
+
## Features
|
|
37
|
+
|
|
38
|
+
- 🎨 **Smart Theming:** Automatically detects *dark/light* mode and uses a coordinated color palette.
|
|
39
|
+
- 🤝 **Familiar API:** If you know `console.log`, you already know Colorino: all standard log levels are supported.
|
|
40
|
+
- 🔀 **Environment-Aware:** Works in **Node.js** (ANSI color and truecolor) and all major **Browsers** (CSS styles).
|
|
41
|
+
- ⚡️ **Fast, Lightweight:** Minimal dependencies, works great in modern frameworks and CLIs.
|
|
42
|
+
- 🔒 **Robust:** Handles bad inputs and weird environments safely.
|
|
43
|
+
- 🛠️ **Customizable:** Override individual log colors for your own branding.
|
|
44
|
+
|
|
45
|
+
***
|
|
46
|
+
|
|
47
|
+
## Installation
|
|
48
|
+
|
|
49
|
+
```sh
|
|
50
|
+
npm install colorino
|
|
51
|
+
# or
|
|
52
|
+
yarn add colorino
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
***
|
|
56
|
+
|
|
57
|
+
## Usage
|
|
58
|
+
|
|
59
|
+
### Quick Start
|
|
60
|
+
|
|
61
|
+
Just import the default instance and log away!
|
|
62
|
+
|
|
63
|
+
```typescript
|
|
64
|
+
import { colorino } from 'colorino'
|
|
65
|
+
|
|
66
|
+
// All log levels automatically themed
|
|
67
|
+
colorino.error('A critical error!')
|
|
68
|
+
colorino.warn('A warning message.')
|
|
69
|
+
colorino.info('Useful info logging.')
|
|
70
|
+
colorino.log('A plain log.')
|
|
71
|
+
colorino.debug('Debug with objects:', { x: 5, y: 9 })
|
|
72
|
+
colorino.trace('Tracing app start...')
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
***
|
|
76
|
+
|
|
77
|
+
### Creating a Custom Logger
|
|
78
|
+
|
|
79
|
+
Need your own colors or different settings?
|
|
80
|
+
Use the factory to create as many loggers as you want (each with its own palette and options):
|
|
81
|
+
|
|
82
|
+
```typescript
|
|
83
|
+
import { createColorino } from 'colorino'
|
|
84
|
+
|
|
85
|
+
const myLogger = createColorino(
|
|
86
|
+
{ // Palette (partial)
|
|
87
|
+
error: '#ff007b',
|
|
88
|
+
info: '#3498db'
|
|
89
|
+
},
|
|
90
|
+
{ disableWarnings: true } // Options (see below)
|
|
91
|
+
)
|
|
92
|
+
myLogger.error('Critical!')
|
|
93
|
+
myLogger.info('Rebranded info!')
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
***
|
|
97
|
+
|
|
98
|
+
### Options & Theme Overrides
|
|
99
|
+
|
|
100
|
+
Both `createColorino(palette?, options?)` and `new Colorino(palette?, options?)` accept:
|
|
101
|
+
|
|
102
|
+
| Option | Type | Default | Description |
|
|
103
|
+
|--------------------|----------------------|-------------|--------------------------------------------------------------------------------|
|
|
104
|
+
| `disableWarnings` | `boolean` | `false` | Suppress warnings when color support can't be detected or is disabled |
|
|
105
|
+
| `theme` | `'dark' \| 'light' \| 'unknown'` | *(auto)* | Override auto-theme detection: force `'dark'` or `'light'` for palette selection |
|
|
106
|
+
|
|
107
|
+
#### Example: Forcing a theme
|
|
108
|
+
|
|
109
|
+
If the auto-contrast and theme detection doesn't work (e.g., in some CI/CD, headless, or basic terminals), **force the color scheme**:
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
import { createColorino } from 'colorino'
|
|
113
|
+
|
|
114
|
+
// Force dark palette regardless of environment
|
|
115
|
+
const forcedDarkLogger = createColorino({}, { theme: 'dark' })
|
|
116
|
+
|
|
117
|
+
forcedDarkLogger.info('This will always use dark-friendly colors.')
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
> **Tip:**
|
|
121
|
+
> Forcing `'dark'` or `'light'` bypasses automatic theming, ensuring predictable colors in environments with unknown or unsupported theme detection (like some CI pipelines, dumb terminals, or minimal browsers).
|
|
122
|
+
|
|
123
|
+
***
|
|
124
|
+
|
|
125
|
+
### Customization
|
|
126
|
+
|
|
127
|
+
Use your brand colors or tweak log levels as desired. Unspecified colors use the smart palette.
|
|
128
|
+
|
|
129
|
+
```typescript
|
|
130
|
+
import { Colorino } from 'colorino'
|
|
131
|
+
|
|
132
|
+
// Custom error color; others use theme defaults
|
|
133
|
+
const myLogger = new Colorino({ error: '#ff007b' })
|
|
134
|
+
|
|
135
|
+
myLogger.error('Oh no!')
|
|
136
|
+
myLogger.info('Still styled by theme.')
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
***
|
|
140
|
+
|
|
141
|
+
### Supported Environment Variables
|
|
142
|
+
|
|
143
|
+
Colorino auto-detects your environment and color support, but you can override behavior using these standard environment variables (compatible with Chalk):
|
|
144
|
+
|
|
145
|
+
| Variable | Effect | Example |
|
|
146
|
+
|------------------|---------------------------------------------------|--------------------------|
|
|
147
|
+
| `NO_COLOR` | Forces *no color* output | `NO_COLOR=1 node app.js` |
|
|
148
|
+
| `FORCE_COLOR` | Forces color (`1`=ANSI, `2`=256, `3`=truecolor) | `FORCE_COLOR=3 node app.js` |
|
|
149
|
+
| `CLICOLOR` | `"0"` disables color | `CLICOLOR=0 node app.js` |
|
|
150
|
+
| `CLICOLOR_FORCE` | Non-`"0"` value enables color even if not a TTY | `CLICOLOR_FORCE=1 node app.js` |
|
|
151
|
+
| `TERM` | Terminal type, can increase/decrease support | `TERM=xterm-256color` |
|
|
152
|
+
| `COLORTERM` | `'truecolor'` or `'24bit'` enables truecolor | `COLORTERM=truecolor` |
|
|
153
|
+
| `WT_SESSION` | Detected for Windows Terminal (enables color) | |
|
|
154
|
+
| `CI` | Many CI platforms default to *no color* | `CI=1 node app.js` |
|
|
155
|
+
|
|
156
|
+
***
|
|
157
|
+
|
|
158
|
+
## Colorino vs. Chalk
|
|
159
|
+
|
|
160
|
+
| Feature | 🎨 **Colorino** | 🖍️ **Chalk** |
|
|
161
|
+
|-------------------|----------------------------------|------------------|
|
|
162
|
+
| Out-of-box logs | ✔ themed, all log levels | ✘ string styling |
|
|
163
|
+
| Zero-config | ✔ | ✘ manual, per-use|
|
|
164
|
+
| Node + browser | ✔ | ✘ (Node only) |
|
|
165
|
+
| CSS console logs | ✔ | ✘ |
|
|
166
|
+
| Extendable class | ✔ | ✘ |
|
|
167
|
+
|
|
168
|
+
***
|
|
169
|
+
|
|
170
|
+
## API Reference
|
|
171
|
+
|
|
172
|
+
### colorino (default export)
|
|
173
|
+
|
|
174
|
+
Preconfigured logger.
|
|
175
|
+
|
|
176
|
+
- `.log(...args)`
|
|
177
|
+
- `.info(...args)`
|
|
178
|
+
- `.warn(...args)`
|
|
179
|
+
- `.error(...args)`
|
|
180
|
+
- `.debug(...args)`
|
|
181
|
+
- `.trace(...args)`
|
|
182
|
+
|
|
183
|
+
### new Colorino(palette?, options?)
|
|
184
|
+
|
|
185
|
+
- `palette` (`Partial<Palette>`): Override colors for log types.
|
|
186
|
+
- `options` (`{ disableWarnings?: boolean; theme?: 'dark' | 'light' | 'unknown' }`): Control warnings and explicit theme.
|
|
187
|
+
|
|
188
|
+
***
|
|
189
|
+
|
|
190
|
+
## Extending Colorino
|
|
191
|
+
|
|
192
|
+
Example: Add a `fatal()` logger for critical errors.
|
|
193
|
+
|
|
194
|
+
```typescript
|
|
195
|
+
import { Colorino, type Palette } from 'colorino'
|
|
196
|
+
|
|
197
|
+
export class MyLogger extends Colorino {
|
|
198
|
+
constructor(palette?: Partial<Palette>, options?: { disableWarnings?: boolean }) {
|
|
199
|
+
super(palette, options)
|
|
200
|
+
}
|
|
201
|
+
public fatal(...args: unknown[]): void {
|
|
202
|
+
super.error(...args)
|
|
203
|
+
if (typeof process !== 'undefined' && process.exit) {
|
|
204
|
+
process.exit(1)
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Usage:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
const logger = new MyLogger({ error: '#d92626' })
|
|
214
|
+
|
|
215
|
+
logger.info('Starting!')
|
|
216
|
+
logger.fatal('Missing config: Exiting')
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
***
|
|
220
|
+
|
|
221
|
+
## Contributing
|
|
222
|
+
|
|
223
|
+
PRs and issues welcome!
|
|
224
|
+
|
|
225
|
+
1. Fork the repo.
|
|
226
|
+
2. Make a branch (`git checkout -b feat/my-feature`)
|
|
227
|
+
3. Add your change, with tests.
|
|
228
|
+
4. Run `npm test` to ensure all tests pass in both Node and browser.
|
|
229
|
+
5. Open a Pull Request.
|
|
230
|
+
|
|
231
|
+
***
|
|
232
|
+
|
|
233
|
+
## License
|
|
234
|
+
|
|
235
|
+
MIT
|
|
236
|
+
|
|
237
|
+
***
|
|
238
|
+
|
|
239
|
+
> *Note:* When running tests, browser output is simulated. Visual styling only appears in real browsers/devtools, but Colorino always routes logs correctly for every environment.
|
package/dist/browser.cjs
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const theme = require('./shared/colorino.BCUN0J9y.cjs');
|
|
4
|
+
require('neverthrow');
|
|
5
|
+
|
|
6
|
+
class BrowserColorSupportDetector {
|
|
7
|
+
constructor(_window, _navigator, _overrideTheme) {
|
|
8
|
+
this._window = _window;
|
|
9
|
+
this._navigator = _navigator;
|
|
10
|
+
this._overrideTheme = _overrideTheme;
|
|
11
|
+
}
|
|
12
|
+
isBrowserEnv() {
|
|
13
|
+
return !!this._window && !!this._navigator?.userAgent;
|
|
14
|
+
}
|
|
15
|
+
getColorLevel() {
|
|
16
|
+
if (!this.isBrowserEnv()) {
|
|
17
|
+
return theme.ColorLevel.NO_COLOR;
|
|
18
|
+
}
|
|
19
|
+
const userAgent = this._navigator.userAgent.toLowerCase();
|
|
20
|
+
if (userAgent.includes("chrome")) return theme.ColorLevel.ANSI256;
|
|
21
|
+
if (userAgent.includes("firefox")) return theme.ColorLevel.ANSI256;
|
|
22
|
+
return theme.ColorLevel.ANSI256;
|
|
23
|
+
}
|
|
24
|
+
getTheme() {
|
|
25
|
+
if (this._overrideTheme) {
|
|
26
|
+
return this._overrideTheme;
|
|
27
|
+
}
|
|
28
|
+
if (!this.isBrowserEnv()) {
|
|
29
|
+
return "unknown";
|
|
30
|
+
}
|
|
31
|
+
if (this._window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
32
|
+
return "dark";
|
|
33
|
+
}
|
|
34
|
+
if (this._window.matchMedia("(prefers-color-scheme: light)").matches) {
|
|
35
|
+
return "light";
|
|
36
|
+
}
|
|
37
|
+
return "unknown";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
function createColorino(palette, options = {}) {
|
|
42
|
+
const validator = new theme.InputValidator();
|
|
43
|
+
const browserDetector = new BrowserColorSupportDetector(
|
|
44
|
+
window,
|
|
45
|
+
navigator,
|
|
46
|
+
options.theme
|
|
47
|
+
);
|
|
48
|
+
return new theme.Colorino(
|
|
49
|
+
palette,
|
|
50
|
+
validator,
|
|
51
|
+
browserDetector,
|
|
52
|
+
// Always use browser detector
|
|
53
|
+
void 0,
|
|
54
|
+
// Node detector is never available
|
|
55
|
+
options
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
const colorino = createColorino(theme.darkDraculaPalette);
|
|
59
|
+
|
|
60
|
+
exports.colorino = colorino;
|
|
61
|
+
exports.createColorino = createColorino;
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { P as Palette, C as ColorinoOptions, a as Colorino } from './shared/colorino.V5I9NhYv.cjs';
|
|
2
|
+
import 'neverthrow';
|
|
3
|
+
|
|
4
|
+
declare function createColorino(palette: Palette, options?: ColorinoOptions): Colorino;
|
|
5
|
+
declare const colorino: Colorino;
|
|
6
|
+
|
|
7
|
+
export { colorino, createColorino };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { P as Palette, C as ColorinoOptions, a as Colorino } from './shared/colorino.V5I9NhYv.mjs';
|
|
2
|
+
import 'neverthrow';
|
|
3
|
+
|
|
4
|
+
declare function createColorino(palette: Palette, options?: ColorinoOptions): Colorino;
|
|
5
|
+
declare const colorino: Colorino;
|
|
6
|
+
|
|
7
|
+
export { colorino, createColorino };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { P as Palette, C as ColorinoOptions, a as Colorino } from './shared/colorino.V5I9NhYv.js';
|
|
2
|
+
import 'neverthrow';
|
|
3
|
+
|
|
4
|
+
declare function createColorino(palette: Palette, options?: ColorinoOptions): Colorino;
|
|
5
|
+
declare const colorino: Colorino;
|
|
6
|
+
|
|
7
|
+
export { colorino, createColorino };
|
package/dist/browser.mjs
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { C as ColorLevel, a as Colorino, I as InputValidator, d as darkDraculaPalette } from './shared/colorino.xxLMfJFV.mjs';
|
|
2
|
+
import 'neverthrow';
|
|
3
|
+
|
|
4
|
+
class BrowserColorSupportDetector {
|
|
5
|
+
constructor(_window, _navigator, _overrideTheme) {
|
|
6
|
+
this._window = _window;
|
|
7
|
+
this._navigator = _navigator;
|
|
8
|
+
this._overrideTheme = _overrideTheme;
|
|
9
|
+
}
|
|
10
|
+
isBrowserEnv() {
|
|
11
|
+
return !!this._window && !!this._navigator?.userAgent;
|
|
12
|
+
}
|
|
13
|
+
getColorLevel() {
|
|
14
|
+
if (!this.isBrowserEnv()) {
|
|
15
|
+
return ColorLevel.NO_COLOR;
|
|
16
|
+
}
|
|
17
|
+
const userAgent = this._navigator.userAgent.toLowerCase();
|
|
18
|
+
if (userAgent.includes("chrome")) return ColorLevel.ANSI256;
|
|
19
|
+
if (userAgent.includes("firefox")) return ColorLevel.ANSI256;
|
|
20
|
+
return ColorLevel.ANSI256;
|
|
21
|
+
}
|
|
22
|
+
getTheme() {
|
|
23
|
+
if (this._overrideTheme) {
|
|
24
|
+
return this._overrideTheme;
|
|
25
|
+
}
|
|
26
|
+
if (!this.isBrowserEnv()) {
|
|
27
|
+
return "unknown";
|
|
28
|
+
}
|
|
29
|
+
if (this._window.matchMedia("(prefers-color-scheme: dark)").matches) {
|
|
30
|
+
return "dark";
|
|
31
|
+
}
|
|
32
|
+
if (this._window.matchMedia("(prefers-color-scheme: light)").matches) {
|
|
33
|
+
return "light";
|
|
34
|
+
}
|
|
35
|
+
return "unknown";
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function createColorino(palette, options = {}) {
|
|
40
|
+
const validator = new InputValidator();
|
|
41
|
+
const browserDetector = new BrowserColorSupportDetector(
|
|
42
|
+
window,
|
|
43
|
+
navigator,
|
|
44
|
+
options.theme
|
|
45
|
+
);
|
|
46
|
+
return new Colorino(
|
|
47
|
+
palette,
|
|
48
|
+
validator,
|
|
49
|
+
browserDetector,
|
|
50
|
+
// Always use browser detector
|
|
51
|
+
void 0,
|
|
52
|
+
// Node detector is never available
|
|
53
|
+
options
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
const colorino = createColorino(darkDraculaPalette);
|
|
57
|
+
|
|
58
|
+
export { colorino, createColorino };
|
package/dist/node.cjs
ADDED
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const theme = require('./shared/colorino.BCUN0J9y.cjs');
|
|
4
|
+
const neverthrow = require('neverthrow');
|
|
5
|
+
|
|
6
|
+
class OscThemeQuerier {
|
|
7
|
+
constructor(_stdin, _stdout, _timeout = 300, _cacheTtl = 36e5) {
|
|
8
|
+
this._stdin = _stdin;
|
|
9
|
+
this._stdout = _stdout;
|
|
10
|
+
this._timeout = _timeout;
|
|
11
|
+
this._cacheTtl = _cacheTtl;
|
|
12
|
+
}
|
|
13
|
+
cachedResult;
|
|
14
|
+
cacheTimestamp;
|
|
15
|
+
async query() {
|
|
16
|
+
if (!this._stdout.isTTY || typeof this._stdin.setRawMode !== "function") {
|
|
17
|
+
return neverthrow.err(new theme.OscQueryError("Not a TTY environment"));
|
|
18
|
+
}
|
|
19
|
+
const now = Date.now();
|
|
20
|
+
if (this.cachedResult !== void 0 && this.cacheTimestamp !== void 0 && now - this.cacheTimestamp < this._cacheTtl) {
|
|
21
|
+
return this.cachedResult;
|
|
22
|
+
}
|
|
23
|
+
const result = await this._performQuery();
|
|
24
|
+
this.cachedResult = result;
|
|
25
|
+
this.cacheTimestamp = now;
|
|
26
|
+
return result;
|
|
27
|
+
}
|
|
28
|
+
async _performQuery() {
|
|
29
|
+
return new Promise((resolve) => {
|
|
30
|
+
const originalRawMode = this._stdin.isRaw;
|
|
31
|
+
let buffer = "";
|
|
32
|
+
let isResolved = false;
|
|
33
|
+
const cleanup = () => {
|
|
34
|
+
if (isResolved) return;
|
|
35
|
+
isResolved = true;
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
this._stdin.removeListener("data", onData);
|
|
38
|
+
this._stdin.setRawMode(originalRawMode);
|
|
39
|
+
};
|
|
40
|
+
const onData = (chunk) => {
|
|
41
|
+
buffer += chunk.toString();
|
|
42
|
+
const parseResult = this._parseResponse(buffer);
|
|
43
|
+
if (parseResult.isOk()) {
|
|
44
|
+
cleanup();
|
|
45
|
+
resolve(parseResult);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
const timer = setTimeout(() => {
|
|
49
|
+
cleanup();
|
|
50
|
+
resolve(
|
|
51
|
+
neverthrow.err(new theme.OscQueryError("OSC query timeout - terminal did not respond"))
|
|
52
|
+
);
|
|
53
|
+
}, this._timeout);
|
|
54
|
+
this._stdin.setRawMode(true);
|
|
55
|
+
this._stdin.on("data", onData);
|
|
56
|
+
this._stdout.write("\x1B]11;?\x1B\\");
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
_parseResponse(response) {
|
|
60
|
+
const rgbMatch = response.match(
|
|
61
|
+
/rgb:([0-9a-f]{2,4})\/([0-9a-f]{2,4})\/([0-9a-f]{2,4})/i
|
|
62
|
+
);
|
|
63
|
+
if (!rgbMatch) {
|
|
64
|
+
return neverthrow.err(new theme.OscQueryError("No valid OSC response found in buffer"));
|
|
65
|
+
}
|
|
66
|
+
const red = this._normalizeHex(rgbMatch[1]);
|
|
67
|
+
const green = this._normalizeHex(rgbMatch[2]);
|
|
68
|
+
const blue = this._normalizeHex(rgbMatch[3]);
|
|
69
|
+
const luminance = this._calculateLuminance(red, green, blue);
|
|
70
|
+
return neverthrow.ok(luminance < 0.5 ? "dark" : "light");
|
|
71
|
+
}
|
|
72
|
+
_normalizeHex(hexValue) {
|
|
73
|
+
const normalized = hexValue.padEnd(4, "0").slice(0, 2);
|
|
74
|
+
return parseInt(normalized, 16);
|
|
75
|
+
}
|
|
76
|
+
_calculateLuminance(red, green, blue) {
|
|
77
|
+
return (0.299 * red + 0.587 * green + 0.114 * blue) / 255;
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
class NodeColorSupportDetector {
|
|
82
|
+
constructor(_process, overrideTheme) {
|
|
83
|
+
this._process = _process;
|
|
84
|
+
if (!this.isNodeEnv()) return;
|
|
85
|
+
const processEnv = _process.env;
|
|
86
|
+
this._envForceColor = processEnv["FORCE_COLOR"];
|
|
87
|
+
this._envNoColor = processEnv["NO_COLOR"];
|
|
88
|
+
this._envTerm = processEnv["TERM"];
|
|
89
|
+
this._envColorTerm = processEnv["COLORTERM"];
|
|
90
|
+
this._envCliColor = processEnv["CLICOLOR"];
|
|
91
|
+
this._envCliColorForce = processEnv["CLICOLOR_FORCE"];
|
|
92
|
+
this._envWtSession = processEnv["WT_SESSION"];
|
|
93
|
+
this._isTTY = !!_process.stdout.isTTY;
|
|
94
|
+
this._overrideTheme = overrideTheme;
|
|
95
|
+
if (!this._overrideTheme && this._isTTY && typeof this._process.stdin.setRawMode === "function") {
|
|
96
|
+
this._querier = new OscThemeQuerier(
|
|
97
|
+
this._process.stdin,
|
|
98
|
+
this._process.stdout
|
|
99
|
+
);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
_envForceColor;
|
|
103
|
+
_envTerm;
|
|
104
|
+
_envColorTerm;
|
|
105
|
+
_envNoColor;
|
|
106
|
+
_envCliColor;
|
|
107
|
+
_envCliColorForce;
|
|
108
|
+
_envWtSession;
|
|
109
|
+
_isTTY;
|
|
110
|
+
_querier;
|
|
111
|
+
_overrideTheme;
|
|
112
|
+
isNodeEnv() {
|
|
113
|
+
return typeof this._process !== "undefined";
|
|
114
|
+
}
|
|
115
|
+
getColorLevel() {
|
|
116
|
+
if (this._envNoColor !== void 0) {
|
|
117
|
+
return theme.ColorLevel.NO_COLOR;
|
|
118
|
+
}
|
|
119
|
+
if (this._envForceColor !== void 0) {
|
|
120
|
+
if (this._envForceColor === "0" || this._envForceColor === "false") {
|
|
121
|
+
return theme.ColorLevel.NO_COLOR;
|
|
122
|
+
}
|
|
123
|
+
if (this._envForceColor === "1" || this._envForceColor === "true") {
|
|
124
|
+
return theme.ColorLevel.ANSI;
|
|
125
|
+
}
|
|
126
|
+
const level = parseInt(this._envForceColor, 10);
|
|
127
|
+
if (level >= 0 && level <= 3) {
|
|
128
|
+
return level;
|
|
129
|
+
}
|
|
130
|
+
return theme.ColorLevel.ANSI;
|
|
131
|
+
}
|
|
132
|
+
const isForced = this._envCliColorForce !== void 0 && this._envCliColorForce !== "0";
|
|
133
|
+
if (!this._isTTY && !isForced) {
|
|
134
|
+
return theme.ColorLevel.NO_COLOR;
|
|
135
|
+
}
|
|
136
|
+
if (this._envTerm === "dumb") {
|
|
137
|
+
return theme.ColorLevel.NO_COLOR;
|
|
138
|
+
}
|
|
139
|
+
if (this._envColorTerm === "truecolor" || this._envColorTerm === "24bit") {
|
|
140
|
+
return theme.ColorLevel.TRUECOLOR;
|
|
141
|
+
}
|
|
142
|
+
if (this._envWtSession !== void 0) {
|
|
143
|
+
return theme.ColorLevel.TRUECOLOR;
|
|
144
|
+
}
|
|
145
|
+
if (this._envTerm) {
|
|
146
|
+
if (/^xterm-kitty$/.test(this._envTerm) || /^xterm-ghostty$/.test(this._envTerm) || /^wezterm$/.test(this._envTerm) || /-truecolor$/.test(this._envTerm)) {
|
|
147
|
+
return theme.ColorLevel.TRUECOLOR;
|
|
148
|
+
}
|
|
149
|
+
if (/-256(color)?$/i.test(this._envTerm)) {
|
|
150
|
+
return theme.ColorLevel.ANSI256;
|
|
151
|
+
}
|
|
152
|
+
if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(
|
|
153
|
+
this._envTerm
|
|
154
|
+
)) {
|
|
155
|
+
return theme.ColorLevel.ANSI;
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
if (this._envColorTerm) {
|
|
159
|
+
return theme.ColorLevel.ANSI;
|
|
160
|
+
}
|
|
161
|
+
if (this._envCliColor !== void 0 && this._envCliColor !== "0") {
|
|
162
|
+
return theme.ColorLevel.ANSI;
|
|
163
|
+
}
|
|
164
|
+
return this._isTTY ? theme.ColorLevel.ANSI : theme.ColorLevel.NO_COLOR;
|
|
165
|
+
}
|
|
166
|
+
async getTheme() {
|
|
167
|
+
if (this._overrideTheme) {
|
|
168
|
+
return this._overrideTheme;
|
|
169
|
+
}
|
|
170
|
+
if (!this.isNodeEnv() || !this._isTTY || !this._querier) {
|
|
171
|
+
return "unknown";
|
|
172
|
+
}
|
|
173
|
+
const result = await this._querier.query();
|
|
174
|
+
return result.unwrapOr("unknown");
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function createColorino(palette, options = {}) {
|
|
179
|
+
const validator = new theme.InputValidator();
|
|
180
|
+
const nodeDetector = new NodeColorSupportDetector(process, options.theme);
|
|
181
|
+
return new theme.Colorino(
|
|
182
|
+
palette,
|
|
183
|
+
validator,
|
|
184
|
+
void 0,
|
|
185
|
+
// Browser detector is never available
|
|
186
|
+
nodeDetector,
|
|
187
|
+
// Always use node detector
|
|
188
|
+
options
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
const colorino = createColorino(theme.darkDraculaPalette);
|
|
192
|
+
|
|
193
|
+
exports.colorino = colorino;
|
|
194
|
+
exports.createColorino = createColorino;
|
package/dist/node.d.cts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { P as Palette, C as ColorinoOptions, a as Colorino } from './shared/colorino.V5I9NhYv.cjs';
|
|
2
|
+
import 'neverthrow';
|
|
3
|
+
|
|
4
|
+
declare function createColorino(palette: Palette, options?: ColorinoOptions): Colorino;
|
|
5
|
+
declare const colorino: Colorino;
|
|
6
|
+
|
|
7
|
+
export { colorino, createColorino };
|
package/dist/node.d.mts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { P as Palette, C as ColorinoOptions, a as Colorino } from './shared/colorino.V5I9NhYv.mjs';
|
|
2
|
+
import 'neverthrow';
|
|
3
|
+
|
|
4
|
+
declare function createColorino(palette: Palette, options?: ColorinoOptions): Colorino;
|
|
5
|
+
declare const colorino: Colorino;
|
|
6
|
+
|
|
7
|
+
export { colorino, createColorino };
|
package/dist/node.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { P as Palette, C as ColorinoOptions, a as Colorino } from './shared/colorino.V5I9NhYv.js';
|
|
2
|
+
import 'neverthrow';
|
|
3
|
+
|
|
4
|
+
declare function createColorino(palette: Palette, options?: ColorinoOptions): Colorino;
|
|
5
|
+
declare const colorino: Colorino;
|
|
6
|
+
|
|
7
|
+
export { colorino, createColorino };
|