@reliverse/relico 2.2.9 → 2.3.2
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 +134 -366
- package/dist/mod.d.ts +3 -60
- package/dist/mod.js +83 -453
- package/dist/types.d.ts +33 -0
- package/dist/types.js +0 -0
- package/package.json +36 -10
package/README.md
CHANGED
|
@@ -1,366 +1,134 @@
|
|
|
1
|
-
# Reliverse Relico
|
|
2
|
-
|
|
3
|
-
> @reliverse/relico is a
|
|
4
|
-
|
|
5
|
-
[sponsor](https://github.com/sponsors/blefnk) — [discord](https://discord.gg/Pb8uKbwpsJ) — [repo](https://github.com/reliverse/relico) — [npm](https://npmjs.com/@reliverse/relico)
|
|
6
|
-
|
|
7
|
-
## Why Relico?
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
- ⚡ **
|
|
12
|
-
- 🎨 **
|
|
13
|
-
-
|
|
14
|
-
-
|
|
15
|
-
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
##
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
##
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
- `re.red("...")`, `re.blue("...")`, `re.greenBright("...")`, ...
|
|
136
|
-
- `re.gray("...")`, `re.whiteBright("...")`
|
|
137
|
-
|
|
138
|
-
### Backgrounds
|
|
139
|
-
|
|
140
|
-
- `re.bgRed("...")`, `re.bgBlueBright("...")`, ...
|
|
141
|
-
|
|
142
|
-
### Text Effects
|
|
143
|
-
|
|
144
|
-
- `re.bold("...")`, `re.italic("...")`, `re.strikethrough("...")`, ...
|
|
145
|
-
|
|
146
|
-
All styles are **composable**:
|
|
147
|
-
|
|
148
|
-
```ts
|
|
149
|
-
// Classic way:
|
|
150
|
-
re.bold(re.bgBlue(re.white("YEP!")));
|
|
151
|
-
// Chained way (recommended):
|
|
152
|
-
const boldRed = chain(re.bold, re.red); // go to "chain() Function Examples" section to learn more
|
|
153
|
-
console.log(boldRed("This text is bold and red"));
|
|
154
|
-
```
|
|
155
|
-
|
|
156
|
-
### Supported Colors, Backgrounds & Modifiers
|
|
157
|
-
|
|
158
|
-
| **Modifiers** | **Base Colors** | **Bright Colors** | **Pastel Colors** | **Extra Colors** | **Grayscale** | **Backgrounds** | **Bright Backgrounds** | **Pastel Backgrounds** | **Extra Backgrounds** |
|
|
159
|
-
|---------------- |------------------ |------------------ |------------------ |------------------|------------------ |-----------------|----------------------- |----------------------- |---------------------- |
|
|
160
|
-
| `reset` | `black` | `blackBright` | `redPastel` | `orange` | `gray10` | `bgBlack` | `bgBlackBright` | `bgRedPastel` | `bgOrange` |
|
|
161
|
-
| `bold` | `red` | `redBright` | `greenPastel` | `pink` | `gray20` | `bgRed` | `bgRedBright` | `bgGreenPastel` | `bgPink` |
|
|
162
|
-
| `dim` | `green` | `greenBright` | `yellowPastel` | `purple` | `gray30` | `bgGreen` | `bgGreenBright` | `bgYellowPastel` | `bgPurple` |
|
|
163
|
-
| `italic` | `yellow` | `yellowBright` | `bluePastel` | `teal` | `gray40` | `bgYellow` | `bgYellowBright` | `bgBluePastel` | `bgTeal` |
|
|
164
|
-
| `underline` | `blue` | `blueBright` | `magentaPastel` | `lime` | `gray50`===`gray` | `bgBlue` | `bgBlueBright` | `bgMagentaPastel` | `bgLime` |
|
|
165
|
-
| `inverse` | `magenta` | `magentaBright` | `cyanPastel` | `brown` | `gray60` | `bgMagenta` | `bgMagentaBright` | `bgCyanPastel` | `bgBrown` |
|
|
166
|
-
| `strikethrough` | `cyan` | `cyanBright` | | `navy` | `gray70` | `bgCyan` | `bgCyanBright` | | `bgNavy` |
|
|
167
|
-
| `hidden` | `white` | `whiteBright` | | `maroon` | `gray80` | `bgWhite` | `bgWhiteBright` | | `bgMaroon` |
|
|
168
|
-
| | `gray`===`gray50` | | | `olive` | `gray90` | | | | `bgOlive` |
|
|
169
|
-
| | | | | `olive` | | | | | `bgSilver` |
|
|
170
|
-
|
|
171
|
-
### Want to Get Only Certain Colors?
|
|
172
|
-
|
|
173
|
-
```ts
|
|
174
|
-
import type { DefaultColorKeys } from "@reliverse/relico";
|
|
175
|
-
const brandColors: DefaultColorKeys[] = ["magentaBright", "maroon"];
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
## Color Detection
|
|
179
|
-
|
|
180
|
-
Relico detects your terminal's capability:
|
|
181
|
-
|
|
182
|
-
```ts
|
|
183
|
-
import { colorSupport } from "@reliverse/relico";
|
|
184
|
-
|
|
185
|
-
console.log(colorSupport.terminalName); // iTerm2, Windows Terminal, etc.
|
|
186
|
-
console.log(colorSupport.level); // 0, 1, 2, or 3
|
|
187
|
-
```
|
|
188
|
-
|
|
189
|
-
**Supports**:
|
|
190
|
-
|
|
191
|
-
- `NO_COLOR`
|
|
192
|
-
- `FORCE_COLOR=1` (or 0/2/3)
|
|
193
|
-
|
|
194
|
-
## Advanced Features
|
|
195
|
-
|
|
196
|
-
### Custom RGB + Hex
|
|
197
|
-
|
|
198
|
-
```ts
|
|
199
|
-
import { rgb, bgHex, hex } from "@reliverse/relico";
|
|
200
|
-
|
|
201
|
-
console.log(rgb(255, 105, 180)("Hot pink"));
|
|
202
|
-
console.log(bgHex("#1e90ff")("Dodger blue background"));
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
### Gradients & Rainbow
|
|
206
|
-
|
|
207
|
-
```ts
|
|
208
|
-
import { gradient, multiGradient, rainbow } from "@reliverse/relico";
|
|
209
|
-
|
|
210
|
-
console.log(rainbow("🎉 Woohoo!"));
|
|
211
|
-
console.log(gradient("From red to blue", "#ff0000", "#0000ff"));
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
## `chain()` Function
|
|
215
|
-
|
|
216
|
-
This function allows you to combine multiple color formatters into a single formatter function. This is useful for creating complex styles that apply multiple effects to text.
|
|
217
|
-
|
|
218
|
-
## Basic Usage
|
|
219
|
-
|
|
220
|
-
```typescript
|
|
221
|
-
import { re, chain } from "@reliverse/relico";
|
|
222
|
-
|
|
223
|
-
// Create a custom style that combines bold and red text
|
|
224
|
-
const boldRed = chain(re.bold, re.red);
|
|
225
|
-
console.log(boldRed("This text is bold and red"));
|
|
226
|
-
|
|
227
|
-
// Create a warning style with yellow text on a dark background
|
|
228
|
-
const warning = chain(re.yellow, re.bgBlack);
|
|
229
|
-
console.log(warning("Warning: This operation might take a while"));
|
|
230
|
-
|
|
231
|
-
// Chain three or more styles
|
|
232
|
-
const importantError = chain(re.bold, re.underline, re.red);
|
|
233
|
-
console.log(importantError("CRITICAL ERROR: System failure"));
|
|
234
|
-
```
|
|
235
|
-
|
|
236
|
-
## Creating Theme Combinations
|
|
237
|
-
|
|
238
|
-
```typescript
|
|
239
|
-
import { re, chain } from "@reliverse/relico";
|
|
240
|
-
|
|
241
|
-
// Create themed message styles
|
|
242
|
-
const successStyle = chain(re.bold, re.green);
|
|
243
|
-
const errorStyle = chain(re.bold, re.red);
|
|
244
|
-
const infoStyle = chain(re.blue, re.italic);
|
|
245
|
-
const warnStyle = chain(re.yellow, re.bold);
|
|
246
|
-
|
|
247
|
-
// Use them in your application
|
|
248
|
-
console.log(successStyle("✓ Operation completed successfully"));
|
|
249
|
-
console.log(errorStyle("✗ Failed to connect to server"));
|
|
250
|
-
console.log(infoStyle("ℹ Running in development mode"));
|
|
251
|
-
console.log(warnStyle("⚠ API rate limit approaching"));
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
## Custom RGB Combinations
|
|
255
|
-
|
|
256
|
-
```typescript
|
|
257
|
-
import { re, rgb, bgRgb, chain } from "@reliverse/relico";
|
|
258
|
-
|
|
259
|
-
// Create a custom color scheme with RGB values
|
|
260
|
-
const customHeader = chain(
|
|
261
|
-
rgb(255, 105, 180), // Hot pink text
|
|
262
|
-
bgRgb(25, 25, 25) // Dark gray background
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
// Create a "danger" style with custom red and bold
|
|
266
|
-
const danger = chain(
|
|
267
|
-
rgb(220, 20, 60), // Crimson text
|
|
268
|
-
re.bold,
|
|
269
|
-
re.underline
|
|
270
|
-
);
|
|
271
|
-
|
|
272
|
-
console.log(customHeader(" SYSTEM STATUS "));
|
|
273
|
-
console.log(danger("Danger: High voltage detected!"));
|
|
274
|
-
```
|
|
275
|
-
|
|
276
|
-
## Multiline Text Handling
|
|
277
|
-
|
|
278
|
-
The `chain()` function automatically handles multiline text to prevent style leakage:
|
|
279
|
-
|
|
280
|
-
```typescript
|
|
281
|
-
import { re, chain } from "@reliverse/relico";
|
|
282
|
-
|
|
283
|
-
const highlight = chain(re.bgYellow, re.black, re.bold);
|
|
284
|
-
|
|
285
|
-
const multilineText = `This is line one
|
|
286
|
-
This is line two
|
|
287
|
-
This is line three`;
|
|
288
|
-
|
|
289
|
-
// Each line is properly wrapped with start/end codes
|
|
290
|
-
console.log(highlight(multilineText));
|
|
291
|
-
```
|
|
292
|
-
|
|
293
|
-
## Creating a Simple Logger
|
|
294
|
-
|
|
295
|
-
```typescript
|
|
296
|
-
import { re, chain } from "@reliverse/relico";
|
|
297
|
-
|
|
298
|
-
// Create logger styles
|
|
299
|
-
const styles = {
|
|
300
|
-
info: chain(re.blue, re.bold),
|
|
301
|
-
success: chain(re.green, re.bold),
|
|
302
|
-
warning: chain(re.yellow, re.bold),
|
|
303
|
-
error: chain(re.red, re.bold),
|
|
304
|
-
debug: chain(re.magenta, re.dim)
|
|
305
|
-
};
|
|
306
|
-
|
|
307
|
-
// Simple logger implementation
|
|
308
|
-
const logger = {
|
|
309
|
-
info: (msg) => console.log(styles.info("INFO"), msg),
|
|
310
|
-
success: (msg) => console.log(styles.success("SUCCESS"), msg),
|
|
311
|
-
warning: (msg) => console.log(styles.warning("WARNING"), msg),
|
|
312
|
-
error: (msg) => console.log(styles.error("ERROR"), msg),
|
|
313
|
-
debug: (msg) => console.log(styles.debug("DEBUG"), msg)
|
|
314
|
-
};
|
|
315
|
-
|
|
316
|
-
// Usage
|
|
317
|
-
logger.info("Application started");
|
|
318
|
-
logger.success("Data loaded successfully");
|
|
319
|
-
logger.warn("Cache expired, refreshing data");
|
|
320
|
-
logger.error("Failed to connect to database");
|
|
321
|
-
logger.debug("Request payload: " + JSON.stringify({id: 123}));
|
|
322
|
-
```
|
|
323
|
-
|
|
324
|
-
This allows you to create powerful, reusable style combinations for your terminal applications.
|
|
325
|
-
|
|
326
|
-
## Local Playground
|
|
327
|
-
|
|
328
|
-
```bash
|
|
329
|
-
git clone https://github.com/reliverse/relico
|
|
330
|
-
cd relico
|
|
331
|
-
bun i
|
|
332
|
-
bun dev
|
|
333
|
-
```
|
|
334
|
-
|
|
335
|
-
Check `example/e-mod.ts` for all the fun.
|
|
336
|
-
|
|
337
|
-
## Use Cases
|
|
338
|
-
|
|
339
|
-
- Beautiful CLI banners & success/error messages
|
|
340
|
-
- Colored logger outputs
|
|
341
|
-
- DX-enhanced terminal tools
|
|
342
|
-
- Custom internal design systems for CLIs
|
|
343
|
-
|
|
344
|
-
## Related
|
|
345
|
-
|
|
346
|
-
- [`chalk`](https://github.com/chalk/chalk) — the classic
|
|
347
|
-
- [`kleur`](https://github.com/lukeed/kleur) — performance-driven
|
|
348
|
-
- [`colorette`](https://github.com/jorgebucaran/colorette) — super tiny
|
|
349
|
-
|
|
350
|
-
Relico draws inspiration from all — and goes beyond them with modern configs, types, theming, and composability.
|
|
351
|
-
|
|
352
|
-
## 🛠 Contributing
|
|
353
|
-
|
|
354
|
-
We'd love your help! Bug? Feature? Example? PR it!
|
|
355
|
-
Or hop into [Discord](https://discord.gg/Pb8uKbwpsJ) to discuss CLI theming and terminal art 💜
|
|
356
|
-
|
|
357
|
-
```bash
|
|
358
|
-
git clone https://github.com/reliverse/relico
|
|
359
|
-
cd relico
|
|
360
|
-
bun i
|
|
361
|
-
```
|
|
362
|
-
|
|
363
|
-
## License
|
|
364
|
-
|
|
365
|
-
MIT © [blefnk Nazar Kornienko](https://github.com/blefnk)
|
|
366
|
-
Part of the [Reliverse](https://github.com/reliverse) ecosystem
|
|
1
|
+
# Reliverse Relico
|
|
2
|
+
|
|
3
|
+
> @reliverse/relico is a simple, lightweight terminal styling toolkit with basic ANSI color support — built for simplicity and reliability.
|
|
4
|
+
|
|
5
|
+
[sponsor](https://github.com/sponsors/blefnk) — [discord](https://discord.gg/Pb8uKbwpsJ) — [repo](https://github.com/reliverse/relico) — [npm](https://npmjs.com/@reliverse/relico)
|
|
6
|
+
|
|
7
|
+
## Why Relico?
|
|
8
|
+
|
|
9
|
+
**Relico** provides essential terminal styling with a focus on simplicity and zero configuration. It gives you basic ANSI colors and text styles for CLI output without the complexity.
|
|
10
|
+
|
|
11
|
+
- ⚡ **Lightweight & simple** — type-safe, zero dependencies, zero configuration
|
|
12
|
+
- 🎨 **Basic ANSI colors** — foreground, background, and bright color variants
|
|
13
|
+
- 🧠 **Typed API** — with autocompletion and inline docs
|
|
14
|
+
- 🌿 **Respects your environment** — honors `NO_COLOR` and TTY detection
|
|
15
|
+
- 🛡️ **Cross-platform** — works in Node.js, Bun, and other JavaScript runtimes
|
|
16
|
+
|
|
17
|
+
<img src="./example/example.png" width="50%" alt="Available Relico colors" />
|
|
18
|
+
|
|
19
|
+
## Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
bun add @reliverse/relico
|
|
23
|
+
# bun • pnpm • yarn • npm
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import { relico } from "@reliverse/relico";
|
|
30
|
+
|
|
31
|
+
console.log(relico.red("Red text"));
|
|
32
|
+
console.log(relico.bold(relico.green("Bold green text")));
|
|
33
|
+
console.log(relico.bgBlue(relico.white("White text on blue background")));
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Available Colors & Styles
|
|
37
|
+
|
|
38
|
+
### Text Colors
|
|
39
|
+
|
|
40
|
+
- `rc.red("...")`, `rc.blue("...")`, `rc.green("...")`
|
|
41
|
+
- `rc.brightRed("...")`, `rc.brightBlue("...")`, `rc.brightGreen("...")`
|
|
42
|
+
- `rc.black("...")`, `rc.white("...")`, `rc.gray("...")`
|
|
43
|
+
|
|
44
|
+
### Background Colors
|
|
45
|
+
|
|
46
|
+
- `rc.bgRed("...")`, `rc.bgBlue("...")`, `rc.bgGreen("...")`
|
|
47
|
+
- `rc.bgYellow("...")`, `rc.bgMagenta("...")`, `rc.bgCyan("...")`
|
|
48
|
+
- `rc.bgWhite("...")`
|
|
49
|
+
|
|
50
|
+
### Text Styles
|
|
51
|
+
|
|
52
|
+
- `rc.bold("...")`, `rc.dim("...")`, `rc.italic("...")`
|
|
53
|
+
- `rc.underline("...")`, `rc.strikethrough("...")`
|
|
54
|
+
|
|
55
|
+
### Utilities
|
|
56
|
+
|
|
57
|
+
- `rc.reset("...")` - reset all styling
|
|
58
|
+
- `rc.strip(text)` - remove ANSI codes from text
|
|
59
|
+
|
|
60
|
+
Styles can be combined:
|
|
61
|
+
|
|
62
|
+
```ts
|
|
63
|
+
// Combine styles by nesting function calls:
|
|
64
|
+
console.log(relico.bold(relico.bgRed(relico.white("Warning!"))));
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Available Colors & Backgrounds
|
|
68
|
+
|
|
69
|
+
| **Text Colors** | **Bright Colors** | **Backgrounds** |
|
|
70
|
+
| --------------- | ----------------- | --------------- |
|
|
71
|
+
| `black` | `brightRed` | `bgRed` |
|
|
72
|
+
| `red` | `brightGreen` | `bgGreen` |
|
|
73
|
+
| `green` | `brightYellow` | `bgYellow` |
|
|
74
|
+
| `yellow` | `brightBlue` | `bgBlue` |
|
|
75
|
+
| `blue` | `brightMagenta` | `bgMagenta` |
|
|
76
|
+
| `magenta` | `brightCyan` | `bgCyan` |
|
|
77
|
+
| `cyan` | `brightWhite` | `bgWhite` |
|
|
78
|
+
| `white` | | |
|
|
79
|
+
| `gray` | | |
|
|
80
|
+
|
|
81
|
+
## Environment Support
|
|
82
|
+
|
|
83
|
+
Relico respects standard environment variables:
|
|
84
|
+
|
|
85
|
+
- `NO_COLOR` - disables all colors when set
|
|
86
|
+
- Automatic TTY detection - colors are disabled when not in a terminal
|
|
87
|
+
|
|
88
|
+
## Development
|
|
89
|
+
|
|
90
|
+
This package is part of the Dler monorepo. To work with it locally:
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
# Clone the monorepo
|
|
94
|
+
git clone https://github.com/reliverse/dler
|
|
95
|
+
cd dler
|
|
96
|
+
|
|
97
|
+
# Install dependencies
|
|
98
|
+
bun install
|
|
99
|
+
|
|
100
|
+
# Build the package
|
|
101
|
+
cd packages/relico
|
|
102
|
+
bun run build
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Use Cases
|
|
106
|
+
|
|
107
|
+
- Beautiful CLI banners & success/error messages
|
|
108
|
+
- Colored logger outputs
|
|
109
|
+
- DX-enhanced terminal tools
|
|
110
|
+
- Custom internal design systems for CLIs
|
|
111
|
+
|
|
112
|
+
## Related
|
|
113
|
+
|
|
114
|
+
- [`chalk`](https://github.com/chalk/chalk) — the classic
|
|
115
|
+
- [`kleur`](https://github.com/lukeed/kleur) — performance-driven
|
|
116
|
+
- [`colorette`](https://github.com/jorgebucaran/colorette) — super tiny
|
|
117
|
+
|
|
118
|
+
Relico draws inspiration from all — and goes beyond them with modern configs, types, theming, and composability.
|
|
119
|
+
|
|
120
|
+
## 🛠 Contributing
|
|
121
|
+
|
|
122
|
+
We'd love your help! Bug? Feature? Example? PR it!
|
|
123
|
+
Or hop into [Discord](https://discord.gg/Pb8uKbwpsJ) to discuss CLI theming and terminal art 💜
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
git clone https://github.com/reliverse/relico
|
|
127
|
+
cd relico
|
|
128
|
+
bun i
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
MIT © [blefnk Nazar Kornienko](https://github.com/blefnk)
|
|
134
|
+
Part of the [Reliverse](https://github.com/reliverse) ecosystem
|
package/dist/mod.d.ts
CHANGED
|
@@ -1,60 +1,3 @@
|
|
|
1
|
-
type
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
g: number;
|
|
5
|
-
b: number;
|
|
6
|
-
}
|
|
7
|
-
type SgrOp = {
|
|
8
|
-
kind: "style";
|
|
9
|
-
open: number[];
|
|
10
|
-
} | {
|
|
11
|
-
kind: "fg-basic";
|
|
12
|
-
idx: number;
|
|
13
|
-
bright: boolean;
|
|
14
|
-
} | {
|
|
15
|
-
kind: "bg-basic";
|
|
16
|
-
idx: number;
|
|
17
|
-
bright: boolean;
|
|
18
|
-
} | {
|
|
19
|
-
kind: "fg-256";
|
|
20
|
-
code: number;
|
|
21
|
-
} | {
|
|
22
|
-
kind: "bg-256";
|
|
23
|
-
code: number;
|
|
24
|
-
} | {
|
|
25
|
-
kind: "fg-true";
|
|
26
|
-
rgb: Rgb;
|
|
27
|
-
} | {
|
|
28
|
-
kind: "bg-true";
|
|
29
|
-
rgb: Rgb;
|
|
30
|
-
};
|
|
31
|
-
type ApplyInput = string | number;
|
|
32
|
-
type FormatCallable = ((input: ApplyInput) => string) & {
|
|
33
|
-
readonly [OP_SYMBOL]: SgrOp[];
|
|
34
|
-
};
|
|
35
|
-
export type BaseColorName = "black" | "red" | "green" | "yellow" | "blue" | "magenta" | "cyan" | "white" | "gray" | "orange" | "pink" | "purple" | "teal" | "lime" | "brown" | "navy" | "maroon" | "olive" | "silver";
|
|
36
|
-
export type ColorName = BaseColorName | BrightColorName | BgColorName;
|
|
37
|
-
export type BrightColorName = "blackBright" | "redBright" | "greenBright" | "yellowBright" | "blueBright" | "magentaBright" | "cyanBright" | "whiteBright" | "orangeBright" | "pinkBright" | "purpleBright" | "tealBright" | "limeBright" | "brownBright" | "navyBright" | "maroonBright" | "oliveBright" | "silverBright";
|
|
38
|
-
export type BgColorName = `bg${Capitalize<BaseColorName>}` | `bg${Capitalize<BrightColorName>}`;
|
|
39
|
-
export type ReStyleKey = "reset" | "bold" | "dim" | "italic" | "underline" | "inverse" | "hidden" | "strikethrough";
|
|
40
|
-
export type Re = FormatCallable & {
|
|
41
|
-
readonly [K in ReStyleKey]: Re;
|
|
42
|
-
} & {
|
|
43
|
-
readonly [K in ColorName]: Re;
|
|
44
|
-
} & {
|
|
45
|
-
readonly [K in BgColorName]: Re;
|
|
46
|
-
};
|
|
47
|
-
declare const OP_SYMBOL: unique symbol;
|
|
48
|
-
export declare const setColorLevel: (level: ColorLevel) => void;
|
|
49
|
-
export declare const re: Re;
|
|
50
|
-
export declare const chain: (...parts: FormatCallable[]) => Re;
|
|
51
|
-
type BunColorInput = {
|
|
52
|
-
r: number;
|
|
53
|
-
g: number;
|
|
54
|
-
b: number;
|
|
55
|
-
a?: number;
|
|
56
|
-
} | [number, number, number] | [number, number, number, number] | string | number | {
|
|
57
|
-
toString(): string;
|
|
58
|
-
};
|
|
59
|
-
export declare const color: (input: BunColorInput, isBg?: boolean) => Re;
|
|
60
|
-
export {};
|
|
1
|
+
import type { Colors } from "./types.js";
|
|
2
|
+
export declare const relico: Colors;
|
|
3
|
+
export declare const re: Colors;
|
package/dist/mod.js
CHANGED
|
@@ -1,455 +1,85 @@
|
|
|
1
|
-
const
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
throw new Error("Invalid color level");
|
|
42
|
-
}
|
|
43
|
-
CURRENT_LEVEL = level;
|
|
44
|
-
};
|
|
45
|
-
const clampByte = (n) => {
|
|
46
|
-
if (n <= MIN_BYTE || !Number.isFinite(n)) return MIN_BYTE;
|
|
47
|
-
if (n >= MAX_BYTE) return MAX_BYTE;
|
|
48
|
-
return Math.round(n);
|
|
49
|
-
};
|
|
50
|
-
const BASIC8 = Object.freeze([
|
|
51
|
-
Object.freeze({ r: 0, g: 0, b: 0 }),
|
|
52
|
-
Object.freeze({ r: 205, g: 0, b: 0 }),
|
|
53
|
-
Object.freeze({ r: 0, g: 205, b: 0 }),
|
|
54
|
-
Object.freeze({ r: 205, g: 205, b: 0 }),
|
|
55
|
-
Object.freeze({ r: 0, g: 0, b: 238 }),
|
|
56
|
-
Object.freeze({ r: 205, g: 0, b: 205 }),
|
|
57
|
-
Object.freeze({ r: 0, g: 205, b: 205 }),
|
|
58
|
-
Object.freeze({ r: 229, g: 229, b: 229 })
|
|
59
|
-
]);
|
|
60
|
-
const sgrCache = /* @__PURE__ */ new Map();
|
|
61
|
-
const sgr = (codes) => {
|
|
62
|
-
if (codes.length === 1) {
|
|
63
|
-
const code = codes[0];
|
|
64
|
-
const cached2 = sgrCache.get(String(code));
|
|
65
|
-
if (cached2) return cached2;
|
|
66
|
-
const seq2 = `\x1B[${code}m`;
|
|
67
|
-
sgrCache.set(String(code), seq2);
|
|
68
|
-
return seq2;
|
|
69
|
-
}
|
|
70
|
-
const key = codes.join(";");
|
|
71
|
-
const cached = sgrCache.get(key);
|
|
72
|
-
if (cached) return cached;
|
|
73
|
-
const seq = `\x1B[${key}m`;
|
|
74
|
-
sgrCache.set(key, seq);
|
|
75
|
-
return seq;
|
|
76
|
-
};
|
|
77
|
-
const nearestBasicIndex = (rgb) => {
|
|
78
|
-
if (IS_BUN) {
|
|
79
|
-
const ansiStr = Bun.color(rgb, "ansi-16");
|
|
80
|
-
if (ansiStr) {
|
|
81
|
-
const match = ansiStr.match(/38;5;(\d+)/);
|
|
82
|
-
if (match?.[1]) {
|
|
83
|
-
return Number.parseInt(match[1], 10) & 7;
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
let best = 0;
|
|
88
|
-
let bestDist = Number.POSITIVE_INFINITY;
|
|
89
|
-
for (let i = 0; i < 8; i++) {
|
|
90
|
-
const c = BASIC8[i];
|
|
91
|
-
const dr = c.r - rgb.r;
|
|
92
|
-
const dg = c.g - rgb.g;
|
|
93
|
-
const db = c.b - rgb.b;
|
|
94
|
-
if (dr === 0 && dg === 0 && db === 0) return i;
|
|
95
|
-
const d = dr * dr + dg * dg + db * db;
|
|
96
|
-
if (d < bestDist) {
|
|
97
|
-
bestDist = d;
|
|
98
|
-
best = i;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
return best;
|
|
102
|
-
};
|
|
103
|
-
const rgbToAnsi256 = (rgb) => {
|
|
104
|
-
if (IS_BUN) {
|
|
105
|
-
const ansiStr = Bun.color(rgb, "ansi-256");
|
|
106
|
-
if (ansiStr) {
|
|
107
|
-
const match = ansiStr.match(/38;5;(\d+)/);
|
|
108
|
-
if (match?.[1]) {
|
|
109
|
-
return Number.parseInt(match[1], 10);
|
|
110
|
-
}
|
|
1
|
+
const colorCodes = {
|
|
2
|
+
// Foreground colors
|
|
3
|
+
black: 30,
|
|
4
|
+
red: 31,
|
|
5
|
+
green: 32,
|
|
6
|
+
yellow: 33,
|
|
7
|
+
blue: 34,
|
|
8
|
+
magenta: 35,
|
|
9
|
+
cyan: 36,
|
|
10
|
+
white: 37,
|
|
11
|
+
gray: 90,
|
|
12
|
+
// Bright foreground colors
|
|
13
|
+
brightRed: 91,
|
|
14
|
+
brightGreen: 92,
|
|
15
|
+
brightYellow: 93,
|
|
16
|
+
brightBlue: 94,
|
|
17
|
+
brightMagenta: 95,
|
|
18
|
+
brightCyan: 96,
|
|
19
|
+
brightWhite: 97,
|
|
20
|
+
// Background colors
|
|
21
|
+
bgRed: 41,
|
|
22
|
+
bgGreen: 42,
|
|
23
|
+
bgYellow: 43,
|
|
24
|
+
bgBlue: 44,
|
|
25
|
+
bgMagenta: 45,
|
|
26
|
+
bgCyan: 46,
|
|
27
|
+
bgWhite: 47,
|
|
28
|
+
// Styles
|
|
29
|
+
bold: 1,
|
|
30
|
+
dim: 2,
|
|
31
|
+
italic: 3,
|
|
32
|
+
underline: 4,
|
|
33
|
+
strikethrough: 9,
|
|
34
|
+
// Reset
|
|
35
|
+
reset: 0
|
|
36
|
+
};
|
|
37
|
+
function createColorFunction(code) {
|
|
38
|
+
return (text) => {
|
|
39
|
+
if (!process.stdout.isTTY || process.env.NO_COLOR) {
|
|
40
|
+
return text;
|
|
111
41
|
}
|
|
112
|
-
|
|
113
|
-
if (rgb.r === rgb.g && rgb.g === rgb.b) {
|
|
114
|
-
if (rgb.r < ANSI_256_GRAYSCALE_MIN) return ANSI_256_BASE_OFFSET;
|
|
115
|
-
if (rgb.r > ANSI_256_GRAYSCALE_MAX) return ANSI_256_BRIGHT_THRESHOLD;
|
|
116
|
-
const step = Math.round(
|
|
117
|
-
(rgb.r - ANSI_256_GRAYSCALE_MIN) / ANSI_256_GRAYSCALE_RANGE * ANSI_256_GRAYSCALE_STEPS
|
|
118
|
-
);
|
|
119
|
-
return ANSI_256_GRAYSCALE_BASE + step;
|
|
120
|
-
}
|
|
121
|
-
const r = (rgb.r * ANSI_256_RGB_LEVELS + 127) / MAX_BYTE | 0;
|
|
122
|
-
const g = (rgb.g * ANSI_256_RGB_LEVELS + 127) / MAX_BYTE | 0;
|
|
123
|
-
const b = (rgb.b * ANSI_256_RGB_LEVELS + 127) / MAX_BYTE | 0;
|
|
124
|
-
return ANSI_256_BASE_OFFSET + r * ANSI_256_RGB_RED_MULTIPLIER + g * ANSI_256_RGB_GREEN_MULTIPLIER + b;
|
|
125
|
-
};
|
|
126
|
-
const NAMED_COLORS = {
|
|
127
|
-
black: "#000000",
|
|
128
|
-
red: "#ff0000",
|
|
129
|
-
green: "#00ff00",
|
|
130
|
-
yellow: "#ffff00",
|
|
131
|
-
blue: "#0000ff",
|
|
132
|
-
magenta: "#ff00ff",
|
|
133
|
-
cyan: "#00ffff",
|
|
134
|
-
white: "#ffffff",
|
|
135
|
-
gray: "#808080",
|
|
136
|
-
orange: "#ffa500",
|
|
137
|
-
pink: "#ffc0cb",
|
|
138
|
-
purple: "#800080",
|
|
139
|
-
teal: "#008080",
|
|
140
|
-
lime: "#00ff00",
|
|
141
|
-
brown: "#a52a2a",
|
|
142
|
-
navy: "#000080",
|
|
143
|
-
maroon: "#800000",
|
|
144
|
-
olive: "#808000",
|
|
145
|
-
silver: "#c0c0c0"
|
|
146
|
-
};
|
|
147
|
-
const rgbCache = /* @__PURE__ */ new Map();
|
|
148
|
-
for (const name of ["black", "white", "red", "green", "blue"]) {
|
|
149
|
-
const hex = NAMED_COLORS[name];
|
|
150
|
-
if (hex) {
|
|
151
|
-
const clean = hex.slice(1);
|
|
152
|
-
const r = Number.parseInt(clean.slice(0, 2), HEX_RADIX);
|
|
153
|
-
const g = Number.parseInt(clean.slice(2, 4), HEX_RADIX);
|
|
154
|
-
const b = Number.parseInt(clean.slice(4, 6), HEX_RADIX);
|
|
155
|
-
rgbCache.set(name, Object.freeze({ r, g, b }));
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
const mixWithWhite = (rgb, factor) => {
|
|
159
|
-
const invFactor = 1 - factor;
|
|
160
|
-
return {
|
|
161
|
-
r: clampByte(rgb.r * invFactor + WHITE_RGB * factor),
|
|
162
|
-
g: clampByte(rgb.g * invFactor + WHITE_RGB * factor),
|
|
163
|
-
b: clampByte(rgb.b * invFactor + WHITE_RGB * factor)
|
|
42
|
+
return `\x1B[${code}m${text}\x1B[0m`;
|
|
164
43
|
};
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
};
|
|
208
|
-
const parseColorName = (name) => {
|
|
209
|
-
if (!name) return { rgb: { r: 0, g: 0, b: 0 }, wantBright: false };
|
|
210
|
-
if (name.endsWith(BRIGHT_SUFFIX)) {
|
|
211
|
-
const base = toBaseName(name);
|
|
212
|
-
const rgb = fromNamed(base);
|
|
213
|
-
const rgbAdj = mixWithWhite(rgb, BRIGHT_MIX_FACTOR);
|
|
214
|
-
return { rgb: rgbAdj, wantBright: true };
|
|
215
|
-
}
|
|
216
|
-
return { rgb: fromNamed(name), wantBright: false };
|
|
217
|
-
};
|
|
218
|
-
const openForOp = (op) => {
|
|
219
|
-
if (CURRENT_LEVEL === COLOR_LEVEL_OFF) return "";
|
|
220
|
-
switch (op.kind) {
|
|
221
|
-
case "style":
|
|
222
|
-
return sgr(op.open);
|
|
223
|
-
case "fg-basic": {
|
|
224
|
-
const code = (op.bright ? SGR_FG_BRIGHT_BASE : SGR_FG_BASE) + op.idx;
|
|
225
|
-
return sgr([code]);
|
|
226
|
-
}
|
|
227
|
-
case "bg-basic": {
|
|
228
|
-
const code = (op.bright ? SGR_BG_BRIGHT_BASE : SGR_BG_BASE) + op.idx;
|
|
229
|
-
return sgr([code]);
|
|
230
|
-
}
|
|
231
|
-
case "fg-256": {
|
|
232
|
-
if (IS_BUN) {
|
|
233
|
-
const ansi = Bun.color(op.code, "ansi-256");
|
|
234
|
-
if (ansi) return ansi;
|
|
235
|
-
}
|
|
236
|
-
return `\x1B[38;5;${op.code}m`;
|
|
237
|
-
}
|
|
238
|
-
case "bg-256": {
|
|
239
|
-
if (IS_BUN) {
|
|
240
|
-
const fgAnsi = Bun.color(op.code, "ansi-256");
|
|
241
|
-
if (fgAnsi) return fgAnsi.replace("38;5;", "48;5;");
|
|
242
|
-
}
|
|
243
|
-
return `\x1B[48;5;${op.code}m`;
|
|
244
|
-
}
|
|
245
|
-
case "fg-true": {
|
|
246
|
-
if (IS_BUN) {
|
|
247
|
-
const ansi = Bun.color(op.rgb, "ansi-16m");
|
|
248
|
-
if (ansi) return ansi;
|
|
249
|
-
}
|
|
250
|
-
const { r, g, b } = op.rgb;
|
|
251
|
-
return `\x1B[38;2;${r};${g};${b}m`;
|
|
252
|
-
}
|
|
253
|
-
case "bg-true": {
|
|
254
|
-
if (IS_BUN) {
|
|
255
|
-
const fgAnsi = Bun.color(op.rgb, "ansi-16m");
|
|
256
|
-
if (fgAnsi) return fgAnsi.replace("38;2;", "48;2;");
|
|
257
|
-
}
|
|
258
|
-
const { r, g, b } = op.rgb;
|
|
259
|
-
return `\x1B[48;2;${r};${g};${b}m`;
|
|
260
|
-
}
|
|
261
|
-
default:
|
|
262
|
-
return "";
|
|
263
|
-
}
|
|
264
|
-
};
|
|
265
|
-
const opsToOpen = (ops) => {
|
|
266
|
-
if (CURRENT_LEVEL === COLOR_LEVEL_OFF) return "";
|
|
267
|
-
const len = ops.length;
|
|
268
|
-
if (len === 0) return "";
|
|
269
|
-
if (len === 1) return openForOp(ops[0]);
|
|
270
|
-
let result = "";
|
|
271
|
-
for (let i = 0; i < len; i++) {
|
|
272
|
-
result += openForOp(ops[i]);
|
|
273
|
-
}
|
|
274
|
-
return result;
|
|
275
|
-
};
|
|
276
|
-
const applyOpsToText = (ops, input) => {
|
|
277
|
-
const text = String(input);
|
|
278
|
-
const textLen = text.length;
|
|
279
|
-
if (CURRENT_LEVEL === COLOR_LEVEL_OFF || ops.length === 0 || textLen === 0) {
|
|
280
|
-
return text;
|
|
281
|
-
}
|
|
282
|
-
const open = opsToOpen(ops);
|
|
283
|
-
if (!open) return text;
|
|
284
|
-
const nlIdx = text.indexOf("\n");
|
|
285
|
-
if (nlIdx === -1) {
|
|
286
|
-
return `${open}${text}${RESET}`;
|
|
287
|
-
}
|
|
288
|
-
let result = "";
|
|
289
|
-
let start = 0;
|
|
290
|
-
while (start < textLen) {
|
|
291
|
-
const end = text.indexOf("\n", start);
|
|
292
|
-
if (end === -1) {
|
|
293
|
-
const line2 = text.slice(start);
|
|
294
|
-
if (line2) {
|
|
295
|
-
if (line2.endsWith("\r")) {
|
|
296
|
-
result += `${open}${line2.slice(0, -1)}\r${RESET}`;
|
|
297
|
-
} else {
|
|
298
|
-
result += `${open}${line2}${RESET}`;
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
break;
|
|
302
|
-
}
|
|
303
|
-
if (start > 0) result += "\n";
|
|
304
|
-
const line = text.slice(start, end);
|
|
305
|
-
if (line) {
|
|
306
|
-
if (line.endsWith("\r")) {
|
|
307
|
-
result += `${open}${line.slice(0, -1)}\r${RESET}`;
|
|
308
|
-
} else {
|
|
309
|
-
result += `${open}${line}${RESET}`;
|
|
310
|
-
}
|
|
311
|
-
} else {
|
|
312
|
-
result += `${open}${RESET}`;
|
|
313
|
-
}
|
|
314
|
-
start = end + 1;
|
|
315
|
-
}
|
|
316
|
-
return result;
|
|
317
|
-
};
|
|
318
|
-
const mkFgOpsFromRgb = (rgb, wantBright = false) => {
|
|
319
|
-
if (CURRENT_LEVEL === COLOR_LEVEL_BASIC) {
|
|
320
|
-
return [
|
|
321
|
-
{ kind: "fg-basic", idx: nearestBasicIndex(rgb), bright: wantBright }
|
|
322
|
-
];
|
|
323
|
-
}
|
|
324
|
-
if (CURRENT_LEVEL === COLOR_LEVEL_256) {
|
|
325
|
-
return [{ kind: "fg-256", code: rgbToAnsi256(rgb) }];
|
|
326
|
-
}
|
|
327
|
-
return [{ kind: "fg-true", rgb }];
|
|
328
|
-
};
|
|
329
|
-
const mkBgOpsFromRgb = (rgb, wantBright = false) => {
|
|
330
|
-
if (CURRENT_LEVEL === COLOR_LEVEL_BASIC) {
|
|
331
|
-
return [
|
|
332
|
-
{ kind: "bg-basic", idx: nearestBasicIndex(rgb), bright: wantBright }
|
|
333
|
-
];
|
|
334
|
-
}
|
|
335
|
-
if (CURRENT_LEVEL === COLOR_LEVEL_256) {
|
|
336
|
-
return [{ kind: "bg-256", code: rgbToAnsi256(rgb) }];
|
|
337
|
-
}
|
|
338
|
-
return [{ kind: "bg-true", rgb }];
|
|
339
|
-
};
|
|
340
|
-
const STYLE_TABLE = {
|
|
341
|
-
reset: Object.freeze({ kind: "style", open: [SGR_RESET] }),
|
|
342
|
-
bold: Object.freeze({ kind: "style", open: [SGR_BOLD] }),
|
|
343
|
-
dim: Object.freeze({ kind: "style", open: [SGR_DIM] }),
|
|
344
|
-
italic: Object.freeze({ kind: "style", open: [SGR_ITALIC] }),
|
|
345
|
-
underline: Object.freeze({ kind: "style", open: [SGR_UNDERLINE] }),
|
|
346
|
-
inverse: Object.freeze({ kind: "style", open: [SGR_INVERSE] }),
|
|
347
|
-
hidden: Object.freeze({ kind: "style", open: [SGR_HIDDEN] }),
|
|
348
|
-
strikethrough: Object.freeze({ kind: "style", open: [SGR_STRIKETHROUGH] })
|
|
349
|
-
};
|
|
350
|
-
const STYLE_KEYS = Object.freeze(
|
|
351
|
-
/* @__PURE__ */ new Set([
|
|
352
|
-
"reset",
|
|
353
|
-
"bold",
|
|
354
|
-
"dim",
|
|
355
|
-
"italic",
|
|
356
|
-
"underline",
|
|
357
|
-
"inverse",
|
|
358
|
-
"hidden",
|
|
359
|
-
"strikethrough"
|
|
360
|
-
])
|
|
361
|
-
);
|
|
362
|
-
const COLOR_KEYS = Object.freeze(new Set(Object.keys(NAMED_COLORS)));
|
|
363
|
-
const BRIGHT_COLOR_KEYS = Object.freeze(
|
|
364
|
-
new Set(Object.keys(NAMED_COLORS).map((name) => `${name}Bright`))
|
|
365
|
-
);
|
|
366
|
-
const BG_COLOR_KEYS = Object.freeze(
|
|
367
|
-
new Set(
|
|
368
|
-
Object.keys(NAMED_COLORS).map(
|
|
369
|
-
(name) => `bg${name[0]?.toUpperCase()}${name.slice(1)}`
|
|
370
|
-
)
|
|
371
|
-
)
|
|
372
|
-
);
|
|
373
|
-
const BG_BRIGHT_COLOR_KEYS = Object.freeze(
|
|
374
|
-
new Set(
|
|
375
|
-
Object.keys(NAMED_COLORS).map(
|
|
376
|
-
(name) => `bg${name[0]?.toUpperCase()}${name.slice(1)}Bright`
|
|
377
|
-
)
|
|
378
|
-
)
|
|
379
|
-
);
|
|
380
|
-
const isColorKey = (key) => COLOR_KEYS.has(key) || BRIGHT_COLOR_KEYS.has(key);
|
|
381
|
-
const isBgKey = (key) => {
|
|
382
|
-
const len = key.length;
|
|
383
|
-
if (len <= BG_PREFIX_LENGTH || key[0] !== "b" || key[1] !== "g") {
|
|
384
|
-
return false;
|
|
385
|
-
}
|
|
386
|
-
return BG_COLOR_KEYS.has(key) || BG_BRIGHT_COLOR_KEYS.has(key);
|
|
387
|
-
};
|
|
388
|
-
const proxyCache = /* @__PURE__ */ new WeakMap();
|
|
389
|
-
const callableProxy = (ops) => {
|
|
390
|
-
const cached = proxyCache.get(ops);
|
|
391
|
-
if (cached) return cached;
|
|
392
|
-
const base = ((input) => applyOpsToText(ops, input));
|
|
393
|
-
Object.defineProperty(base, OP_SYMBOL, {
|
|
394
|
-
value: ops,
|
|
395
|
-
enumerable: false,
|
|
396
|
-
configurable: false,
|
|
397
|
-
writable: false
|
|
398
|
-
});
|
|
399
|
-
const proxy = new Proxy(base, {
|
|
400
|
-
apply(_target, _thisArg, argArray) {
|
|
401
|
-
return applyOpsToText(ops, argArray[0]);
|
|
402
|
-
},
|
|
403
|
-
get(_target, prop) {
|
|
404
|
-
if (prop === OP_SYMBOL) return ops;
|
|
405
|
-
const key = String(prop);
|
|
406
|
-
if (STYLE_KEYS.has(key)) {
|
|
407
|
-
const op = STYLE_TABLE[key];
|
|
408
|
-
const newOps = [...ops, op];
|
|
409
|
-
return callableProxy(newOps);
|
|
410
|
-
}
|
|
411
|
-
if (isBgKey(key)) {
|
|
412
|
-
const colorName = key[2]?.toLowerCase() + key.slice(3);
|
|
413
|
-
const { rgb, wantBright } = parseColorName(colorName);
|
|
414
|
-
const bgOps = mkBgOpsFromRgb(rgb, wantBright);
|
|
415
|
-
const newOps = [...ops, ...bgOps];
|
|
416
|
-
return callableProxy(newOps);
|
|
417
|
-
}
|
|
418
|
-
if (isColorKey(key)) {
|
|
419
|
-
const { rgb, wantBright } = parseColorName(key);
|
|
420
|
-
const fgOps = mkFgOpsFromRgb(rgb, wantBright);
|
|
421
|
-
const newOps = [...ops, ...fgOps];
|
|
422
|
-
return callableProxy(newOps);
|
|
423
|
-
}
|
|
424
|
-
return proxy;
|
|
425
|
-
}
|
|
426
|
-
});
|
|
427
|
-
proxyCache.set(ops, proxy);
|
|
428
|
-
return proxy;
|
|
429
|
-
};
|
|
430
|
-
export const re = callableProxy([]);
|
|
431
|
-
export const chain = (...parts) => {
|
|
432
|
-
if (parts.length === 0) return re;
|
|
433
|
-
if (parts.length === 1) return parts[0];
|
|
434
|
-
const collected = [];
|
|
435
|
-
for (let i = 0; i < parts.length; i++) {
|
|
436
|
-
const ops = parts[i][OP_SYMBOL];
|
|
437
|
-
if (ops?.length) {
|
|
438
|
-
collected.push(...ops);
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
return callableProxy(collected);
|
|
442
|
-
};
|
|
443
|
-
export const color = (input, isBg = false) => {
|
|
444
|
-
if (!IS_BUN) {
|
|
445
|
-
if (typeof input === "object" && "r" in input && "g" in input && "b" in input) {
|
|
446
|
-
const ops2 = isBg ? mkBgOpsFromRgb(input, false) : mkFgOpsFromRgb(input, false);
|
|
447
|
-
return callableProxy(ops2);
|
|
448
|
-
}
|
|
449
|
-
return re;
|
|
450
|
-
}
|
|
451
|
-
const rgb = Bun.color(input, "{rgb}");
|
|
452
|
-
if (!rgb) return re;
|
|
453
|
-
const ops = isBg ? mkBgOpsFromRgb(rgb, false) : mkFgOpsFromRgb(rgb, false);
|
|
454
|
-
return callableProxy(ops);
|
|
455
|
-
};
|
|
44
|
+
}
|
|
45
|
+
function stripAnsi(text) {
|
|
46
|
+
return text.replace(/\x1b\[[0-9;]*m/g, "");
|
|
47
|
+
}
|
|
48
|
+
export const relico = {
|
|
49
|
+
// Basic colors
|
|
50
|
+
black: createColorFunction(colorCodes.black),
|
|
51
|
+
red: createColorFunction(colorCodes.red),
|
|
52
|
+
green: createColorFunction(colorCodes.green),
|
|
53
|
+
yellow: createColorFunction(colorCodes.yellow),
|
|
54
|
+
blue: createColorFunction(colorCodes.blue),
|
|
55
|
+
magenta: createColorFunction(colorCodes.magenta),
|
|
56
|
+
cyan: createColorFunction(colorCodes.cyan),
|
|
57
|
+
white: createColorFunction(colorCodes.white),
|
|
58
|
+
gray: createColorFunction(colorCodes.gray),
|
|
59
|
+
// Bright colors
|
|
60
|
+
brightRed: createColorFunction(colorCodes.brightRed),
|
|
61
|
+
brightGreen: createColorFunction(colorCodes.brightGreen),
|
|
62
|
+
brightYellow: createColorFunction(colorCodes.brightYellow),
|
|
63
|
+
brightBlue: createColorFunction(colorCodes.brightBlue),
|
|
64
|
+
brightMagenta: createColorFunction(colorCodes.brightMagenta),
|
|
65
|
+
brightCyan: createColorFunction(colorCodes.brightCyan),
|
|
66
|
+
brightWhite: createColorFunction(colorCodes.brightWhite),
|
|
67
|
+
// Background colors
|
|
68
|
+
bgRed: createColorFunction(colorCodes.bgRed),
|
|
69
|
+
bgGreen: createColorFunction(colorCodes.bgGreen),
|
|
70
|
+
bgYellow: createColorFunction(colorCodes.bgYellow),
|
|
71
|
+
bgBlue: createColorFunction(colorCodes.bgBlue),
|
|
72
|
+
bgMagenta: createColorFunction(colorCodes.bgMagenta),
|
|
73
|
+
bgCyan: createColorFunction(colorCodes.bgCyan),
|
|
74
|
+
bgWhite: createColorFunction(colorCodes.bgWhite),
|
|
75
|
+
// Styles
|
|
76
|
+
bold: createColorFunction(colorCodes.bold),
|
|
77
|
+
dim: createColorFunction(colorCodes.dim),
|
|
78
|
+
italic: createColorFunction(colorCodes.italic),
|
|
79
|
+
underline: createColorFunction(colorCodes.underline),
|
|
80
|
+
strikethrough: createColorFunction(colorCodes.strikethrough),
|
|
81
|
+
// Utilities
|
|
82
|
+
reset: createColorFunction(colorCodes.reset),
|
|
83
|
+
strip: stripAnsi
|
|
84
|
+
};
|
|
85
|
+
export const re = relico;
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export type ColorFunction = (text: string) => string;
|
|
2
|
+
export interface Colors {
|
|
3
|
+
black: ColorFunction;
|
|
4
|
+
red: ColorFunction;
|
|
5
|
+
green: ColorFunction;
|
|
6
|
+
yellow: ColorFunction;
|
|
7
|
+
blue: ColorFunction;
|
|
8
|
+
magenta: ColorFunction;
|
|
9
|
+
cyan: ColorFunction;
|
|
10
|
+
white: ColorFunction;
|
|
11
|
+
gray: ColorFunction;
|
|
12
|
+
brightRed: ColorFunction;
|
|
13
|
+
brightGreen: ColorFunction;
|
|
14
|
+
brightYellow: ColorFunction;
|
|
15
|
+
brightBlue: ColorFunction;
|
|
16
|
+
brightMagenta: ColorFunction;
|
|
17
|
+
brightCyan: ColorFunction;
|
|
18
|
+
brightWhite: ColorFunction;
|
|
19
|
+
bgRed: ColorFunction;
|
|
20
|
+
bgGreen: ColorFunction;
|
|
21
|
+
bgYellow: ColorFunction;
|
|
22
|
+
bgBlue: ColorFunction;
|
|
23
|
+
bgMagenta: ColorFunction;
|
|
24
|
+
bgCyan: ColorFunction;
|
|
25
|
+
bgWhite: ColorFunction;
|
|
26
|
+
bold: ColorFunction;
|
|
27
|
+
dim: ColorFunction;
|
|
28
|
+
italic: ColorFunction;
|
|
29
|
+
underline: ColorFunction;
|
|
30
|
+
strikethrough: ColorFunction;
|
|
31
|
+
reset: ColorFunction;
|
|
32
|
+
strip: (text: string) => string;
|
|
33
|
+
}
|
package/dist/types.js
ADDED
|
File without changes
|
package/package.json
CHANGED
|
@@ -1,22 +1,48 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@reliverse/relico",
|
|
3
|
-
"version": "2.2
|
|
4
|
-
"
|
|
3
|
+
"version": "2.3.2",
|
|
4
|
+
"description": "@reliverse/relico is a themeable, chainable, typed, truecolor-powered, modern terminal styling toolkit. Designed to make your CLI output colorful, accessible, and human-friendly. It gives you a flexible way to apply colors and styles, with reliability and a smart developer experience baked in. Built for humans, not just terminals.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"cli",
|
|
7
|
+
"prompts",
|
|
8
|
+
"rempts",
|
|
9
|
+
"spinner",
|
|
10
|
+
"terminal",
|
|
11
|
+
"utilities"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://github.com/reliverse/dler#readme",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/reliverse/dler/issues"
|
|
16
|
+
},
|
|
17
|
+
"license": "MIT",
|
|
18
|
+
"author": "blefnk",
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "https://github.com/reliverse/dler.git",
|
|
22
|
+
"directory": "packages/utils"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"dist",
|
|
26
|
+
"package.json",
|
|
27
|
+
"README.md"
|
|
28
|
+
],
|
|
5
29
|
"type": "module",
|
|
6
|
-
"
|
|
30
|
+
"module": "./dist/mod.js",
|
|
31
|
+
"types": "./dist/mod.d.ts",
|
|
7
32
|
"exports": {
|
|
8
33
|
".": {
|
|
9
34
|
"types": "./dist/mod.d.ts",
|
|
10
|
-
"
|
|
35
|
+
"import": "./dist/mod.js"
|
|
11
36
|
}
|
|
12
37
|
},
|
|
13
38
|
"publishConfig": {
|
|
14
39
|
"access": "public"
|
|
15
40
|
},
|
|
16
|
-
"dependencies": {
|
|
17
|
-
|
|
18
|
-
"
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
41
|
+
"dependencies": {
|
|
42
|
+
"@standard-schema/spec": "^1.1.0",
|
|
43
|
+
"@standard-schema/utils": "^0.3.0"
|
|
44
|
+
},
|
|
45
|
+
"engines": {
|
|
46
|
+
"bun": ">=1.3.5"
|
|
47
|
+
}
|
|
22
48
|
}
|