Changed Desktop

This commit is contained in:
DerGrumpf 2025-09-10 11:48:22 +02:00
parent 6804d95a08
commit d099faf68a
4591 changed files with 1612898 additions and 51 deletions

2
.gitignore vendored
View File

@ -4,3 +4,5 @@ result/
.DS_Store .DS_Store
.pre-commit-config.yaml .pre-commit-config.yaml
logs/ logs/
avatar/pallete.*
cache/

View File

Before

Width:  |  Height:  |  Size: 1.8 MiB

After

Width:  |  Height:  |  Size: 1.8 MiB

BIN
avatar/avatar_high.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 MiB

BIN
avatar/avatar_no_bg.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

BIN
avatar/avatar_talking.gif Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 23 MiB

BIN
avatar/avatar_talking.mp4 Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 MiB

Binary file not shown.

BIN
avatar/palette.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1011 B

1
cache/npm/global/bin/oh-my-logo vendored Symbolic link
View File

@ -0,0 +1 @@
../lib/node_modules/oh-my-logo/dist/index.js

27
cache/npm/global/lib/node_modules/oh-my-logo/LICENSE generated vendored Normal file
View File

@ -0,0 +1,27 @@
SPDX-License-Identifier: MIT AND CC0-1.0
AI provenance notice:
Portions generated with Anthropic Claude are dedicated to the
public domain under CC01.0; all copyrighteligible code remains under MIT.
MIT License
Copyright (c) 2025 Yuki Shindo
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

550
cache/npm/global/lib/node_modules/oh-my-logo/README.md generated vendored Normal file
View File

@ -0,0 +1,550 @@
# oh-my-logo
[![Mentioned in Awesome Gemini CLI](https://awesome.re/mentioned-badge.svg)](https://github.com/Piebald-AI/awesome-gemini-cli)
![Logo](https://raw.githubusercontent.com/shinshin86/oh-my-logo/main/images/logo.png)
Create stunning ASCII art logos with beautiful gradient colors in your terminal! Perfect for project banners, startup logos, or just making your terminal look awesome.
You can also create stunning animations like these by using it as a library in your programs!
![GIF Demo](https://raw.githubusercontent.com/shinshin86/oh-my-logo/refs/heads/main/images/demo.gif)
![GIF Demo 2](https://raw.githubusercontent.com/shinshin86/oh-my-logo/main/images/demo2.gif)
The logos produced by `oh-my-logo` are CC0 (public domain); feel free to use them anywhere.
## ✨ Features
- 🎨 **Two Rendering Modes**: Choose between outlined ASCII art or filled block characters
- 🌈 **13 Beautiful Palettes**: From sunset gradients to matrix green
- 📐 **Gradient Directions**: Vertical, horizontal, and diagonal gradients
- 🔤 **Multi-line Support**: Create logos with multiple lines of text
- ⚡ **Zero Dependencies**: Run instantly with `npx` - no installation required
- 🎛️ **Customizable**: Use different fonts and create your own color schemes
- 🎭 **Shadow Styles**: Customize shadow effects in filled mode with different block fonts
- 🔄 **Letter Spacing**: For `--filled` mode: character spacing for different visual densities
- 🔄 **Reverse Gradients**: Flip color palettes for unique effects
## 🚀 Quick Start
No installation needed! Try it right now:
```bash
npx oh-my-logo "HELLO WORLD"
```
Want filled characters? Add the `--filled` flag:
```bash
npx oh-my-logo "YOUR LOGO" sunset --filled
```
### 🆕 New in v0.3.0
**Customize shadow styles in filled mode:**
```bash
# Box-drawing shadows (default)
npx oh-my-logo "STYLE" fire --filled --block-font block
# Minimal sleek shadows
npx oh-my-logo "STYLE" fire --filled --block-font chrome
# Dotted/shaded shadows
npx oh-my-logo "STYLE" fire --filled --block-font shade
```
**Control letter spacing for block fonts:**
```bash
# Wide spacing (5 spaces between letters)
npx oh-my-logo "WIDE" ocean --filled --letter-spacing 5
# Tight spacing (no spaces)
npx oh-my-logo "TIGHT" ocean --filled --letter-spacing 0
```
**Reverse gradients for unique effects:**
```bash
# Reverse any color palette
npx oh-my-logo "REVERSE" sunset --reverse-gradient
# Works with filled mode too
npx oh-my-logo "REVERSE" sunset --filled --reverse-gradient
```
## 📦 Installation
### Global Installation (CLI)
```bash
npm install -g oh-my-logo
```
### Or Use Directly with npx
```bash
npx oh-my-logo "Your Text"
```
### As a Library
```bash
npm install oh-my-logo
```
## 🎯 Usage
### CLI Usage
```bash
oh-my-logo <text> [palette] [options]
```
### Library Usage
```javascript
import { render, renderFilled, PALETTES, getPaletteNames } from 'oh-my-logo';
// Basic ASCII art rendering
const logo = await render('HELLO WORLD', {
palette: 'sunset',
direction: 'horizontal'
});
console.log(logo);
// Using custom colors
const customLogo = await render('MY BRAND', {
palette: ['#ff0000', '#00ff00', '#0000ff'],
font: 'Big',
direction: 'diagonal'
});
console.log(customLogo);
// Filled block characters
await renderFilled('AWESOME', {
palette: 'fire'
});
// Filled with custom shadow style
await renderFilled('SHADOW', {
palette: 'sunset',
font: 'shade' // Use dotted shadow effect
});
// Filled with wide letter spacing
await renderFilled('WIDE', {
palette: 'fire',
letterSpacing: 3
});
// TypeScript usage
import { render, RenderOptions, PaletteName } from 'oh-my-logo';
const options: RenderOptions = {
palette: 'ocean' as PaletteName,
direction: 'vertical',
font: 'Standard'
};
const typedLogo = await render('TYPESCRIPT', options);
console.log(typedLogo);
// Access palette information
console.log('Available palettes:', getPaletteNames());
console.log('Sunset colors:', PALETTES.sunset);
```
### Arguments
- **`<text>`**: Text to display
- Use `"\n"` for newlines: `"LINE1\nLINE2"`
- Use `"-"` to read from stdin
- **`[palette]`**: Color palette name (default: `grad-blue`)
### Options
| Option | Description | Default |
|--------|-------------|---------|
| `-f, --font <name>` | Figlet font name | `Standard` |
| `-d, --direction <dir>` | Gradient direction (`vertical`, `horizontal`, `diagonal`) | `vertical` |
| `--filled` | Use filled block characters instead of outlined ASCII | `false` |
| `--block-font <font>` | Font for filled mode (`3d`, `block`, `chrome`, `grid`, `huge`, `pallet`, `shade`, `simple`, `simple3d`, `simpleBlock`, `slick`, `tiny`)
| `--letter-spacing <n>` | Letter spacing for filled mode (integer spaces between characters, 0+) | `1` |
| `--reverse-gradient` | Reverse gradient colors | `false` |
| `-l, --list-palettes` | Show all available color palettes | - |
| `--gallery` | Render text in all available palettes | - |
| `--color` | Force color output (useful for pipes) | - |
| `--no-color` | Disable color output | - |
| `-v, --version` | Show version number | - |
| `-h, --help` | Show help information | - |
## 🎨 Available Palettes (13 Total)
View all palettes with preview colors:
```bash
npx oh-my-logo "" --list-palettes
```
| Palette | Colors | Description |
|---------|--------|-------------|
| `grad-blue` | `#4ea8ff → #7f88ff` | Blue gradient (default) |
| `sunset` | `#ff9966 → #ff5e62 → #ffa34e` | Warm sunset colors |
| `dawn` | `#00c6ff → #0072ff` | Cool morning blues |
| `nebula` | `#654ea3 → #eaafc8` | Purple space nebula |
| `ocean` | `#667eea → #764ba2` | Deep ocean blues |
| `fire` | `#ff0844 → #ffb199` | Intense fire colors |
| `forest` | `#134e5e → #71b280` | Natural green tones |
| `gold` | `#f7971e → #ffd200` | Luxurious gold gradient |
| `purple` | `#667db6 → #0082c8 → #0078ff` | Royal purple to blue |
| `mint` | `#00d2ff → #3a7bd5` | Fresh mint colors |
| `coral` | `#ff9a9e → #fecfef` | Soft coral pink |
| `matrix` | `#00ff41 → #008f11` | Classic matrix green |
| `mono` | `#f07178 → #f07178` | Single coral color |
## 💡 Examples
### Basic Usage
```bash
# Simple logo with default blue gradient
npx oh-my-logo "STARTUP"
# Multi-line company logo
npx oh-my-logo "MY\nCOMPANY" sunset
# Matrix-style hacker text
npx oh-my-logo "HACK THE PLANET" matrix --filled
```
### Different Rendering Modes
```bash
# Outlined ASCII art (default)
npx oh-my-logo "CODE" fire
# Filled block characters
npx oh-my-logo "CODE" fire --filled
# Filled with different shadow styles
npx oh-my-logo "CODE" fire --filled --block-font chrome # Minimal box shadows
npx oh-my-logo "CODE" fire --filled --block-font shade # Dotted shadow effect
npx oh-my-logo "CODE" fire --filled --block-font simpleBlock # Simple ASCII shadows
```
### Shadow Styles (--filled mode only)
Customize the shadow characters in filled mode with `--block-font`:
#### Visual Comparison of Shadow Styles
**`block` (default)** - Box-drawing shadows:
```
██╗ ██╗ ██╗
██║ ██║ ██║
███████║ ██║
██╔══██║ ██║
██║ ██║ ██║
╚═╝ ╚═╝ ╚═╝
```
**`chrome`** - Minimal sleek shadows:
```
╦ ╦ ╦
╠═╣ ║
╩ ╩ ╩
```
**`shade`** - Dotted shadow effect:
```
░░░░░░░░░
░█░░█░███
░█░░█░ █
░████░░█
░█ █░░█
░█░░█░███
░ ░░ ░
░░░░░░░░░
```
**`simpleBlock`** - Basic ASCII shadows:
```
_| _| _|_|_|
_| _| _|
_|_|_|_| _|
_| _| _|
_| _| _|_|_|
```
```bash
# Try different shadow styles
npx oh-my-logo "SHADOW" sunset --filled --block-font block
npx oh-my-logo "SHADOW" sunset --filled --block-font chrome
npx oh-my-logo "SHADOW" sunset --filled --block-font shade
npx oh-my-logo "SHADOW" sunset --filled --block-font simpleBlock
```
### Letter Spacing Control
Adjust the spacing between characters for different visual densities:
```bash
# Default spacing (1 space)
npx oh-my-logo "HI" --filled
# Output: ██╗ ██╗
# Wide spacing (3 spaces)
npx oh-my-logo "HI" --filled --letter-spacing 3
# Output: ██╗ ██╗
# No spacing (touching)
npx oh-my-logo "HI" --filled --letter-spacing 0
# Output: ██╗██╗
# Note: Decimals are truncated (3.7 becomes 3)
npx oh-my-logo "HI" --filled --letter-spacing 3.7 # Uses 3 spaces
```
### Reverse Gradient Effect
Flip any color palette for unique visual effects:
```bash
# Normal sunset gradient (red → orange)
npx oh-my-logo "GRADIENT" sunset
# Reversed sunset gradient (orange → red)
npx oh-my-logo "GRADIENT" sunset --reverse-gradient
# Works with filled mode too
npx oh-my-logo "GRADIENT" sunset --filled --reverse-gradient
```
### Gradient Directions
```bash
# Vertical gradient (default)
npx oh-my-logo "LOGO" ocean
# Horizontal gradient
npx oh-my-logo "LOGO" ocean -d horizontal
# Diagonal gradient
npx oh-my-logo "LOGO" ocean -d diagonal
```
### Custom Fonts
```bash
# List available fonts (depends on your figlet installation)
figlet -f
# Use a different font
npx oh-my-logo "RETRO" purple -f "Big"
```
### Pipeline and Scripting
```bash
# Read from stdin
echo "DYNAMIC LOGO" | npx oh-my-logo - gold --filled
# Force colors in scripts
npx oh-my-logo "DEPLOY SUCCESS" forest --color
# Plain text output
npx oh-my-logo "LOG ENTRY" --no-color
```
### Gallery Mode
```bash
# Display text in all available palettes
npx oh-my-logo "PREVIEW" --gallery
# Gallery with filled characters
npx oh-my-logo "COLORS" --gallery --filled
# Compare multi-line text across all palettes
npx oh-my-logo "MY\nLOGO" --gallery
# Gallery with custom font
npx oh-my-logo "STYLES" --gallery -f Big
```
## 🎭 Use Cases
- **Project Banners**: Add eye-catching headers to your README files
- **Terminal Startup**: Display your company logo when opening terminals
- **CI/CD Pipelines**: Make deployment logs more visually appealing
- **Development Tools**: Brand your CLI applications
- **Presentations**: Create stunning terminal demos
- **Personal Branding**: Add flair to your shell prompt or scripts
## ⚙️ Environment Variables
| Variable | Description | Example |
|----------|-------------|---------|
| `OHMYLOGO_FONT` | Default figlet font | `export OHMYLOGO_FONT="Big"` |
## 📚 Library API
### Core Functions
#### `render(text, options?)`
Renders ASCII art with gradient colors.
```typescript
async function render(text: string, options?: RenderOptions): Promise<string>
```
- **text** (string): Text to display
- **options.palette** (PaletteName | string[]): Color palette name or custom colors
- **options.font** (string): Figlet font name (default: 'Standard')
- **options.direction** ('vertical' | 'horizontal' | 'diagonal'): Gradient direction
Returns: `Promise<string>` - The colored ASCII art
#### `renderFilled(text, options?)`
Renders filled block characters with gradient.
```typescript
async function renderFilled(text: string, options?: RenderInkOptions): Promise<void>
```
- **text** (string): Text to display
- **options.palette** (PaletteName | string[]): Color palette name or custom colors
- **options.font** (BlockFont): Shadow style ('block' | 'chrome' | 'shade' | 'simpleBlock' | '3d')
- **options.letterSpacing** (number): Integer number of spaces between characters (0 or greater, default: 1)
Returns: `Promise<void>` - Renders directly to stdout
### Palette Functions
- **`PALETTES`**: Object containing all built-in color palettes
- **`resolvePalette(name)`**: Get palette colors by name
- **`getPaletteNames()`**: Get array of all palette names
- **`getDefaultPalette()`**: Get the default palette colors
- **`getPalettePreview(name)`**: Get a preview string of palette colors
### Type Definitions
```typescript
type PaletteName = 'grad-blue' | 'sunset' | 'dawn' | 'nebula' | 'ocean' |
'fire' | 'forest' | 'gold' | 'purple' | 'mint' |
'coral' | 'matrix' | 'mono';
interface RenderOptions {
palette?: PaletteName | string[];
font?: string;
direction?: 'vertical' | 'horizontal' | 'diagonal';
}
type BlockFont = '3d' | 'block' | 'chrome' | 'console' | 'grid' |
'huge' | 'pallet' | 'shade' | 'simple' | 'simple3d' |
'simpleBlock' | 'slick' | 'tiny';
interface RenderInkOptions {
palette?: PaletteName | string[];
font?: BlockFont;
letterSpacing?: number;
}
```
## 🛠️ Development
Want to contribute or customize?
```bash
git clone https://github.com/yourusername/oh-my-logo.git
cd oh-my-logo
npm install
# Development mode
npm run dev -- "TEST" sunset --filled
# Build
npm run build
# Test the built version
node dist/index.js "HELLO" matrix --filled
```
### 🧪 Testing
Run the test suite with Vitest:
```bash
# Run all tests in watch mode
npm run test
# Run tests once (CI mode)
npm run test:coverage
# Run tests with UI
npm run test:ui
# Run specific test file
npm test -- src/__tests__/cli.test.ts
```
The test suite includes:
- Unit tests for all library functions
- CLI integration tests
- Color palette validation
- Error handling scenarios
- TTY/color detection logic
Tests are located in `src/__tests__/` with the following structure:
- `cli.test.ts` - CLI command line behavior
- `lib.test.ts` - Library API functions
- `palettes.test.ts` - Color palette system
- `renderer.test.ts` - ASCII art rendering
- `utils/` - Utility function tests
### Testing Terminal Stability
A test script is provided to verify that the `--filled` mode properly cleans up terminal state:
```bash
# Run terminal stability stress test
./scripts/test-filled-mode.sh
```
This script:
- Runs 55 consecutive renders (5 iterations × 11 fonts)
- Tests all available fonts with random color palettes
- Verifies terminal display remains intact after extensive use
- Helps detect any terminal corruption issues
This is particularly useful for:
- Testing after making changes to the Ink renderer
- Verifying terminal compatibility with different environments
- Stress testing the `--filled` mode implementation
### Adding New Palettes
Edit `src/palettes.ts` to add your own color combinations:
```typescript
export const PALETTES = {
// ... existing palettes
'my-palette': ['#ff0000', '#00ff00', '#0000ff'],
} as const;
```
## 🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request. Whether it's:
- 🎨 New color palettes
- 🔧 Bug fixes
- ✨ New features
- 📖 Documentation improvements
## 📄 License
MIT AND CC0-1.0
---
**Made with ❤️ for the terminal lovers**
*Transform your boring text into stunning visual logos!*

View File

@ -0,0 +1,6 @@
import type { CFontProps } from 'ink-big-text';
export declare function renderInkLogo(text: string, palette: string[], options?: {
font?: CFontProps['font'];
letterSpacing?: number;
}): Promise<void>;
//# sourceMappingURL=InkRenderer.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"InkRenderer.d.ts","sourceRoot":"","sources":["../src/InkRenderer.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAiC/C,wBAAgB,aAAa,CAC3B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EAAE,EACjB,OAAO,CAAC,EAAE;IAAE,IAAI,CAAC,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAAC,aAAa,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D,OAAO,CAAC,IAAI,CAAC,CA0Bf"}

View File

@ -0,0 +1,30 @@
import { jsx as _jsx } from "react/jsx-runtime";
import { render } from 'ink';
import BigText from 'ink-big-text';
import Gradient from 'ink-gradient';
const Logo = ({ text, colors, font = 'block', letterSpacing, }) => {
// ink-gradient with custom colors
if (colors.length > 0) {
return (_jsx(Gradient, { colors: colors, children: _jsx(BigText, { text: text, font: font, letterSpacing: letterSpacing }) }));
}
// Default gradient
return (_jsx(Gradient, { name: "rainbow", children: _jsx(BigText, { text: text, font: font, letterSpacing: letterSpacing }) }));
};
export function renderInkLogo(text, palette, options) {
return new Promise((resolve) => {
const { unmount } = render(_jsx(Logo, { text: text, colors: palette, font: options?.font, letterSpacing: options?.letterSpacing }));
// Automatically unmount after rendering to allow process to exit
setTimeout(() => {
unmount();
// Reset terminal state to prevent corruption
// SGR reset (colors, styles)
process.stdout.write('\x1b[0m');
// Ensure cursor is visible
process.stdout.write('\x1b[?25h');
// Clear to end of line to remove any artifacts
process.stdout.write('\x1b[K');
resolve();
}, 100);
});
}
//# sourceMappingURL=InkRenderer.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"InkRenderer.js","sourceRoot":"","sources":["../src/InkRenderer.tsx"],"names":[],"mappings":";AACA,OAAO,EAAE,MAAM,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,OAAO,MAAM,cAAc,CAAC;AAEnC,OAAO,QAAQ,MAAM,cAAc,CAAC;AASpC,MAAM,IAAI,GAAwB,CAAC,EACjC,IAAI,EACJ,MAAM,EACN,IAAI,GAAG,OAAO,EACd,aAAa,GACd,EAAE,EAAE;IACH,kCAAkC;IAClC,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CACL,KAAC,QAAQ,IAAC,MAAM,EAAE,MAAM,YACtB,KAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,aAAa,GAAI,GACxD,CACZ,CAAC;IACJ,CAAC;IAED,mBAAmB;IACnB,OAAO,CACL,KAAC,QAAQ,IAAC,IAAI,EAAC,SAAS,YACtB,KAAC,OAAO,IAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,aAAa,EAAE,aAAa,GAAI,GACxD,CACZ,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,UAAU,aAAa,CAC3B,IAAY,EACZ,OAAiB,EACjB,OAA+D;IAE/D,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE;QAC7B,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,CACxB,KAAC,IAAI,IACH,IAAI,EAAE,IAAI,EACV,MAAM,EAAE,OAAO,EACf,IAAI,EAAE,OAAO,EAAE,IAAI,EACnB,aAAa,EAAE,OAAO,EAAE,aAAa,GACrC,CACH,CAAC;QAEF,iEAAiE;QACjE,UAAU,CAAC,GAAG,EAAE;YACd,OAAO,EAAE,CAAC;YAEV,6CAA6C;YAC7C,6BAA6B;YAC7B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC;YAChC,2BAA2B;YAC3B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;YAClC,+CAA+C;YAC/C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC;YAE/B,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,GAAG,CAAC,CAAC;IACV,CAAC,CAAC,CAAC;AACL,CAAC"}

View File

@ -0,0 +1,3 @@
#!/usr/bin/env node
export {};
//# sourceMappingURL=index.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}

151
cache/npm/global/lib/node_modules/oh-my-logo/dist/index.js generated vendored Executable file
View File

@ -0,0 +1,151 @@
#!/usr/bin/env node
import { Command } from 'commander';
import { render, renderFilled, getPaletteNames, getPalettePreview, DEFAULT_FONT, DEFAULT_PALETTE, resolveColors, } from './lib.js';
import { shouldUseColor, stripAnsiCodes } from './utils/stdout.js';
import { PaletteError, InputError } from './utils/errors.js';
import { readFileSync } from 'fs';
import { fileURLToPath } from 'url';
import { dirname, join } from 'path';
const __filename = fileURLToPath(import.meta.url);
const __dirname = dirname(__filename);
const packageJson = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
const program = new Command();
program
.name('oh-my-logo')
.description('Display giant ASCII art logos with colorful gradients in your terminal')
.version(packageJson.version)
.argument('[text]', 'Text to display (use "\\n" for newlines or "-" for stdin)')
.argument('[palette]', 'Color palette to use', DEFAULT_PALETTE)
.option('-f, --font <name>', 'Figlet font name', process.env.OHMYLOGO_FONT || DEFAULT_FONT)
.option('-l, --list-palettes', 'List available palettes')
.option('--gallery', 'Render text in all available palettes')
.option('--color', 'Force color output even in pipes')
.option('--no-color', 'Disable color output')
.option('-d, --direction <dir>', 'Gradient direction: horizontal, vertical, or diagonal', 'vertical')
.option('--filled', 'Use filled characters instead of outlined ASCII art')
.option('--block-font <font>', 'Font for filled mode (3d, block, chrome, grid, huge, pallet, shade, simple, simple3d, simpleBlock, slick, tiny)', 'block')
.option('--letter-spacing <number>', 'Letter spacing for filled mode', parseInt)
.option('--reverse-gradient', 'Reverse gradient colors')
.action(async (text, paletteArg, options) => {
try {
if (options.listPalettes) {
console.log('Available palettes:');
getPaletteNames().forEach((name) => {
const preview = getPalettePreview(name);
console.log(` - ${name.padEnd(12)} ${preview}`);
});
process.exit(0);
}
if (!text) {
throw new InputError('Text is required when not using --list-palettes or --gallery');
}
if (options.gallery) {
// Render in all palettes
let inputText = text;
if (text === '-') {
inputText = readFileSync(0, 'utf-8').trim();
}
if (!inputText || inputText.trim() === '') {
throw new InputError('Text must not be empty');
}
inputText = inputText.replace(/\\n/g, '\n');
const paletteNames = getPaletteNames();
for (const paletteName of paletteNames) {
console.log(`\n=== ${paletteName.toUpperCase()}${options.reverseGradient ? ' (reversed)' : ''} ===\n`);
let paletteColors = resolveColors(paletteName);
if (options.reverseGradient) {
paletteColors = [...paletteColors].reverse();
}
if (options.filled) {
// Validate letter spacing
if (options.letterSpacing !== undefined &&
options.letterSpacing < 0) {
throw new InputError('Letter spacing must be 0 or greater');
}
await renderFilled(inputText, {
palette: paletteColors,
font: options.blockFont,
letterSpacing: options.letterSpacing,
});
}
else {
const logo = await render(inputText, {
palette: paletteColors,
font: options.font,
direction: options.direction,
});
const useColor = shouldUseColor({
forceColor: options.color,
noColor: !options.color && options.noColor,
});
const output = useColor ? logo : stripAnsiCodes(logo);
console.log(output);
}
}
process.exit(0);
}
if (!text) {
throw new InputError('Text is required when not using --list-palettes');
}
let inputText = text;
if (text === '-') {
inputText = readFileSync(0, 'utf-8').trim();
}
if (!inputText || inputText.trim() === '') {
throw new InputError('Text must not be empty');
}
inputText = inputText.replace(/\\n/g, '\n');
// Validate and resolve palette
let paletteColors;
try {
paletteColors = resolveColors(paletteArg);
}
catch {
if (paletteArg !== DEFAULT_PALETTE) {
throw new PaletteError(paletteArg);
}
paletteColors = resolveColors(DEFAULT_PALETTE);
}
// Reverse colors if requested
if (options.reverseGradient) {
paletteColors = [...paletteColors].reverse();
}
if (options.filled) {
// Validate letter spacing
if (options.letterSpacing !== undefined && options.letterSpacing < 0) {
throw new InputError('Letter spacing must be 0 or greater');
}
// Use Ink for filled characters
await renderFilled(inputText, {
palette: paletteColors,
font: options.blockFont,
letterSpacing: options.letterSpacing,
});
}
else {
// Use figlet for outlined ASCII art
const logo = await render(inputText, {
palette: paletteColors,
font: options.font,
direction: options.direction,
});
const useColor = shouldUseColor({
forceColor: options.color,
noColor: !options.color && options.noColor,
});
const output = useColor ? logo : stripAnsiCodes(logo);
console.log(output);
}
}
catch (error) {
if (error instanceof Error) {
console.error(`Error: ${error.message}`);
}
else {
console.error('An unexpected error occurred');
}
process.exit(1);
}
});
program.parse();
//# sourceMappingURL=index.js.map

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,22 @@
import { PALETTES, type PaletteName, resolvePalette, getPaletteNames, getDefaultPalette, getPalettePreview } from './palettes.js';
import type { Fonts } from 'figlet';
export declare const DEFAULT_PALETTE: PaletteName;
export declare const DEFAULT_FONT = "Standard";
export declare const DEFAULT_DIRECTION = "vertical";
export interface RenderOptions {
palette?: PaletteName | string[] | string;
font?: Fonts | string;
direction?: 'vertical' | 'horizontal' | 'diagonal';
}
export type BlockFont = '3d' | 'block' | 'chrome' | 'grid' | 'huge' | 'pallet' | 'shade' | 'simple' | 'simple3d' | 'simpleBlock' | 'slick' | 'tiny';
export interface RenderInkOptions {
palette?: PaletteName | string[] | string;
font?: BlockFont;
letterSpacing?: number;
}
export declare function resolveColors(palette: PaletteName | string[] | string): string[];
export declare function render(text: string, options?: RenderOptions): Promise<string>;
export declare function renderFilled(text: string, options?: RenderInkOptions): Promise<void>;
export { PALETTES, type PaletteName, resolvePalette, getPaletteNames, getDefaultPalette, getPalettePreview, };
export type { Fonts };
//# sourceMappingURL=lib.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"lib.d.ts","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,QAAQ,EACR,KAAK,WAAW,EAChB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAEpC,eAAO,MAAM,eAAe,EAAE,WAAyB,CAAC;AACxD,eAAO,MAAM,YAAY,aAAa,CAAC;AACvC,eAAO,MAAM,iBAAiB,aAAa,CAAC;AAE5C,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1C,IAAI,CAAC,EAAE,KAAK,GAAG,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,UAAU,GAAG,YAAY,GAAG,UAAU,CAAC;CACpD;AAID,MAAM,MAAM,SAAS,GACjB,IAAI,GACJ,OAAO,GACP,QAAQ,GACR,MAAM,GACN,MAAM,GACN,QAAQ,GACR,OAAO,GACP,QAAQ,GACR,UAAU,GACV,aAAa,GACb,OAAO,GACP,MAAM,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC;IAC1C,IAAI,CAAC,EAAE,SAAS,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,aAAa,CAC3B,OAAO,EAAE,WAAW,GAAG,MAAM,EAAE,GAAG,MAAM,GACvC,MAAM,EAAE,CAWV;AAED,wBAAsB,MAAM,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,MAAM,CAAC,CASjB;AAED,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,IAAI,CAAC,CAUf;AAED,OAAO,EACL,QAAQ,EACR,KAAK,WAAW,EAChB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,CAAC;AAEF,YAAY,EAAE,KAAK,EAAE,CAAC"}

View File

@ -0,0 +1,32 @@
import { renderLogo } from './renderer.js';
import { renderInkLogo } from './InkRenderer.js';
import { PALETTES, resolvePalette, getPaletteNames, getDefaultPalette, getPalettePreview, } from './palettes.js';
export const DEFAULT_PALETTE = 'grad-blue';
export const DEFAULT_FONT = 'Standard';
export const DEFAULT_DIRECTION = 'vertical';
export function resolveColors(palette) {
if (Array.isArray(palette)) {
return palette;
}
const colors = resolvePalette(palette);
if (!colors) {
throw new Error(`Unknown palette: ${palette}`);
}
return colors;
}
export async function render(text, options = {}) {
const { palette = DEFAULT_PALETTE, font = DEFAULT_FONT, direction = DEFAULT_DIRECTION, } = options;
const paletteColors = resolveColors(palette);
return renderLogo(text, paletteColors, font, direction);
}
export async function renderFilled(text, options = {}) {
const { palette = DEFAULT_PALETTE, font, letterSpacing } = options;
// Validate letter spacing
if (letterSpacing !== undefined && letterSpacing < 0) {
throw new Error('Letter spacing must be 0 or greater');
}
const paletteColors = resolveColors(palette);
return renderInkLogo(text, paletteColors, { font, letterSpacing });
}
export { PALETTES, resolvePalette, getPaletteNames, getDefaultPalette, getPalettePreview, };
//# sourceMappingURL=lib.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"lib.js","sourceRoot":"","sources":["../src/lib.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EACL,QAAQ,EAER,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,MAAM,eAAe,CAAC;AAGvB,MAAM,CAAC,MAAM,eAAe,GAAgB,WAAW,CAAC;AACxD,MAAM,CAAC,MAAM,YAAY,GAAG,UAAU,CAAC;AACvC,MAAM,CAAC,MAAM,iBAAiB,GAAG,UAAU,CAAC;AA8B5C,MAAM,UAAU,aAAa,CAC3B,OAAwC;IAExC,IAAI,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;QAC3B,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,MAAM,MAAM,GAAG,cAAc,CAAC,OAAO,CAAC,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CAAC,oBAAoB,OAAO,EAAE,CAAC,CAAC;IACjD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,IAAY,EACZ,UAAyB,EAAE;IAE3B,MAAM,EACJ,OAAO,GAAG,eAAe,EACzB,IAAI,GAAG,YAAY,EACnB,SAAS,GAAG,iBAAiB,GAC9B,GAAG,OAAO,CAAC;IAEZ,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,UAAU,CAAC,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,SAAS,CAAC,CAAC;AAC1D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAChC,IAAY,EACZ,UAA4B,EAAE;IAE9B,MAAM,EAAE,OAAO,GAAG,eAAe,EAAE,IAAI,EAAE,aAAa,EAAE,GAAG,OAAO,CAAC;IAEnE,0BAA0B;IAC1B,IAAI,aAAa,KAAK,SAAS,IAAI,aAAa,GAAG,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC;IACzD,CAAC;IAED,MAAM,aAAa,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAC7C,OAAO,aAAa,CAAC,IAAI,EAAE,aAAa,EAAE,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAC;AACrE,CAAC;AAED,OAAO,EACL,QAAQ,EAER,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,iBAAiB,GAClB,CAAC"}

View File

@ -0,0 +1,21 @@
export declare const PALETTES: {
readonly 'grad-blue': readonly ["#4ea8ff", "#7f88ff"];
readonly sunset: readonly ["#ff9966", "#ff5e62", "#ffa34e"];
readonly dawn: readonly ["#00c6ff", "#0072ff"];
readonly nebula: readonly ["#654ea3", "#eaafc8"];
readonly mono: readonly ["#f07178", "#f07178"];
readonly ocean: readonly ["#667eea", "#764ba2"];
readonly fire: readonly ["#ff0844", "#ffb199"];
readonly forest: readonly ["#134e5e", "#71b280"];
readonly gold: readonly ["#f7971e", "#ffd200"];
readonly purple: readonly ["#667db6", "#0082c8", "#0078ff"];
readonly mint: readonly ["#00d2ff", "#3a7bd5"];
readonly coral: readonly ["#ff9a9e", "#fecfef"];
readonly matrix: readonly ["#00ff41", "#008f11"];
};
export type PaletteName = keyof typeof PALETTES;
export declare function resolvePalette(name: string): string[] | null;
export declare function getPaletteNames(): string[];
export declare function getDefaultPalette(): string[];
export declare function getPalettePreview(name: PaletteName): string;
//# sourceMappingURL=palettes.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"palettes.d.ts","sourceRoot":"","sources":["../src/palettes.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,QAAQ;;;;;;;;;;;;;;CAcX,CAAC;AAEX,MAAM,MAAM,WAAW,GAAG,MAAM,OAAO,QAAQ,CAAC;AAEhD,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAI5D;AAED,wBAAgB,eAAe,IAAI,MAAM,EAAE,CAE1C;AAED,wBAAgB,iBAAiB,IAAI,MAAM,EAAE,CAE5C;AAED,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,WAAW,GAAG,MAAM,CAG3D"}

View File

@ -0,0 +1,31 @@
export const PALETTES = {
'grad-blue': ['#4ea8ff', '#7f88ff'],
sunset: ['#ff9966', '#ff5e62', '#ffa34e'],
dawn: ['#00c6ff', '#0072ff'],
nebula: ['#654ea3', '#eaafc8'],
mono: ['#f07178', '#f07178'],
ocean: ['#667eea', '#764ba2'],
fire: ['#ff0844', '#ffb199'],
forest: ['#134e5e', '#71b280'],
gold: ['#f7971e', '#ffd200'],
purple: ['#667db6', '#0082c8', '#0078ff'],
mint: ['#00d2ff', '#3a7bd5'],
coral: ['#ff9a9e', '#fecfef'],
matrix: ['#00ff41', '#008f11'],
};
export function resolvePalette(name) {
const paletteName = name;
const palette = PALETTES[paletteName];
return palette ? [...palette] : null;
}
export function getPaletteNames() {
return Object.keys(PALETTES);
}
export function getDefaultPalette() {
return [...PALETTES['grad-blue']];
}
export function getPalettePreview(name) {
const colors = PALETTES[name];
return colors.join(' → ');
}
//# sourceMappingURL=palettes.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"palettes.js","sourceRoot":"","sources":["../src/palettes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,QAAQ,GAAG;IACtB,WAAW,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IACnC,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;IACzC,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5B,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5B,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC7B,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5B,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC9B,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5B,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC;IACzC,IAAI,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC5B,KAAK,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;IAC7B,MAAM,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC;CACtB,CAAC;AAIX,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,MAAM,WAAW,GAAG,IAAmB,CAAC;IACxC,MAAM,OAAO,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC;IACtC,OAAO,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC/B,CAAC;AAED,MAAM,UAAU,iBAAiB;IAC/B,OAAO,CAAC,GAAG,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,IAAiB;IACjD,MAAM,MAAM,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC9B,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;AAC5B,CAAC"}

View File

@ -0,0 +1,2 @@
export declare function renderLogo(text: string, palette: string[], font?: string, direction?: string): string;
//# sourceMappingURL=renderer.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"renderer.d.ts","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAIA,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EAAE,EACjB,IAAI,GAAE,MAAmB,EACzB,SAAS,GAAE,MAAmB,GAC7B,MAAM,CA6DR"}

View File

@ -0,0 +1,61 @@
import figlet from 'figlet';
import gradient from 'gradient-string';
import { FontError } from './utils/errors.js';
export function renderLogo(text, palette, font = 'Standard', direction = 'vertical') {
try {
const asciiArt = figlet.textSync(text, {
font: font,
horizontalLayout: 'default',
verticalLayout: 'default',
width: 80,
whitespaceBreak: true,
});
// Create gradient function
const gradientFn = gradient(palette);
let coloredArt;
switch (direction) {
case 'horizontal':
// Apply gradient horizontally (left to right on each line)
const lines = asciiArt.split('\n');
const coloredLines = lines.map((line) => {
if (line.trim() === '') {
return line;
}
return gradientFn(line);
});
coloredArt = coloredLines.join('\n');
break;
case 'diagonal':
// Create a custom diagonal gradient by applying different gradients per line
const diagonalLines = asciiArt.split('\n');
const lineCount = diagonalLines.length;
coloredArt = diagonalLines
.map((line, index) => {
if (line.trim() === '') {
return line;
}
// Create a gradient that shifts based on line position
const shiftedPalette = palette.map((color, colorIndex) => {
const shift = (index / lineCount) * palette.length;
return palette[Math.floor(colorIndex + shift) % palette.length];
});
return gradient(shiftedPalette)(line);
})
.join('\n');
break;
case 'vertical':
default:
// Apply gradient vertically (top to bottom across all lines)
coloredArt = gradientFn.multiline(asciiArt);
break;
}
return coloredArt;
}
catch (error) {
if (error instanceof Error && error.message.includes('font')) {
throw new FontError(font);
}
throw error;
}
}
//# sourceMappingURL=renderer.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"renderer.js","sourceRoot":"","sources":["../src/renderer.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAC5B,OAAO,QAAQ,MAAM,iBAAiB,CAAC;AACvC,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAE9C,MAAM,UAAU,UAAU,CACxB,IAAY,EACZ,OAAiB,EACjB,OAAe,UAAU,EACzB,YAAoB,UAAU;IAE9B,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE;YACrC,IAAI,EAAE,IAAoB;YAC1B,gBAAgB,EAAE,SAAS;YAC3B,cAAc,EAAE,SAAS;YACzB,KAAK,EAAE,EAAE;YACT,eAAe,EAAE,IAAI;SACtB,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC;QAErC,IAAI,UAAkB,CAAC;QAEvB,QAAQ,SAAS,EAAE,CAAC;YAClB,KAAK,YAAY;gBACf,2DAA2D;gBAC3D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACnC,MAAM,YAAY,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;oBACtC,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;wBACvB,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,OAAO,UAAU,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC,CAAC,CAAC;gBACH,UAAU,GAAG,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACrC,MAAM;YAER,KAAK,UAAU;gBACb,6EAA6E;gBAC7E,MAAM,aAAa,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBAC3C,MAAM,SAAS,GAAG,aAAa,CAAC,MAAM,CAAC;gBACvC,UAAU,GAAG,aAAa;qBACvB,GAAG,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE;oBACnB,IAAI,IAAI,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;wBACvB,OAAO,IAAI,CAAC;oBACd,CAAC;oBACD,uDAAuD;oBACvD,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,UAAU,EAAE,EAAE;wBACvD,MAAM,KAAK,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC;wBACnD,OAAO,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;oBAClE,CAAC,CAAC,CAAC;oBACH,OAAO,QAAQ,CAAC,cAAc,CAAC,CAAC,IAAI,CAAC,CAAC;gBACxC,CAAC,CAAC;qBACD,IAAI,CAAC,IAAI,CAAC,CAAC;gBACd,MAAM;YAER,KAAK,UAAU,CAAC;YAChB;gBACE,6DAA6D;gBAC7D,UAAU,GAAG,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;gBAC5C,MAAM;QACV,CAAC;QAED,OAAO,UAAU,CAAC;IACpB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7D,MAAM,IAAI,SAAS,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;QACD,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}

View File

@ -0,0 +1,16 @@
export declare class OhMyLogoError extends Error {
constructor(message: string);
}
export declare class PaletteError extends OhMyLogoError {
readonly palette: string;
constructor(paletteName: string);
}
export declare class InputError extends OhMyLogoError {
readonly input: string;
constructor(input: string);
}
export declare class FontError extends OhMyLogoError {
readonly font: string;
constructor(fontName: string);
}
//# sourceMappingURL=errors.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,qBAAa,aAAc,SAAQ,KAAK;gBAC1B,OAAO,EAAE,MAAM;CAI5B;AAED,qBAAa,YAAa,SAAQ,aAAa;IAC7C,SAAgB,OAAO,EAAE,MAAM,CAAC;gBAEpB,WAAW,EAAE,MAAM;CAIhC;AAED,qBAAa,UAAW,SAAQ,aAAa;IAC3C,SAAgB,KAAK,EAAE,MAAM,CAAC;gBAElB,KAAK,EAAE,MAAM;CAI1B;AAED,qBAAa,SAAU,SAAQ,aAAa;IAC1C,SAAgB,IAAI,EAAE,MAAM,CAAC;gBAEjB,QAAQ,EAAE,MAAM;CAI7B"}

View File

@ -0,0 +1,28 @@
export class OhMyLogoError extends Error {
constructor(message) {
super(message);
this.name = this.constructor.name;
}
}
export class PaletteError extends OhMyLogoError {
palette;
constructor(paletteName) {
super(`Unknown palette: ${paletteName}`);
this.palette = paletteName;
}
}
export class InputError extends OhMyLogoError {
input;
constructor(input) {
super(`Invalid input: ${input}`);
this.input = input;
}
}
export class FontError extends OhMyLogoError {
font;
constructor(fontName) {
super(`Font not found: ${fontName}`);
this.font = fontName;
}
}
//# sourceMappingURL=errors.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA,MAAM,OAAO,aAAc,SAAQ,KAAK;IACtC,YAAY,OAAe;QACzB,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC;IACpC,CAAC;CACF;AAED,MAAM,OAAO,YAAa,SAAQ,aAAa;IAC7B,OAAO,CAAS;IAEhC,YAAY,WAAmB;QAC7B,KAAK,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,GAAG,WAAW,CAAC;IAC7B,CAAC;CACF;AAED,MAAM,OAAO,UAAW,SAAQ,aAAa;IAC3B,KAAK,CAAS;IAE9B,YAAY,KAAa;QACvB,KAAK,CAAC,kBAAkB,KAAK,EAAE,CAAC,CAAC;QACjC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACrB,CAAC;CACF;AAED,MAAM,OAAO,SAAU,SAAQ,aAAa;IAC1B,IAAI,CAAS;IAE7B,YAAY,QAAgB;QAC1B,KAAK,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,GAAG,QAAQ,CAAC;IACvB,CAAC;CACF"}

View File

@ -0,0 +1,7 @@
export interface ColorOptions {
forceColor?: boolean;
noColor?: boolean;
}
export declare function shouldUseColor(options?: ColorOptions): boolean;
export declare function stripAnsiCodes(text: string): string;
//# sourceMappingURL=stdout.d.ts.map

View File

@ -0,0 +1 @@
{"version":3,"file":"stdout.d.ts","sourceRoot":"","sources":["../../src/utils/stdout.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,YAAY;IAC3B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,wBAAgB,cAAc,CAAC,OAAO,GAAE,YAAiB,GAAG,OAAO,CA4BlE;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAInD"}

View File

@ -0,0 +1,30 @@
export function shouldUseColor(options = {}) {
// Force color takes highest precedence
if (options.forceColor) {
return true;
}
// No color option
if (options.noColor) {
return false;
}
// Check NO_COLOR environment variable
if (process.env.NO_COLOR) {
return false;
}
// Check FORCE_COLOR environment variable
if (process.env.FORCE_COLOR) {
return true;
}
// Check if running in CI with color support
if (process.env.CI && (process.env.COLORTERM || process.env.TERM_PROGRAM)) {
return true;
}
// Default to TTY detection
return process.stdout.isTTY ?? false;
}
export function stripAnsiCodes(text) {
// More comprehensive regex for ANSI escape sequences
const ansiRegex = /\u001b\[[0-9;]*[a-zA-Z]/g;
return text.replace(ansiRegex, '');
}
//# sourceMappingURL=stdout.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"stdout.js","sourceRoot":"","sources":["../../src/utils/stdout.ts"],"names":[],"mappings":"AAKA,MAAM,UAAU,cAAc,CAAC,UAAwB,EAAE;IACvD,uCAAuC;IACvC,IAAI,OAAO,CAAC,UAAU,EAAE,CAAC;QACvB,OAAO,IAAI,CAAC;IACd,CAAC;IAED,kBAAkB;IAClB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,sCAAsC;IACtC,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,yCAAyC;IACzC,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,EAAE,CAAC;QAC5B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4CAA4C;IAC5C,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,EAAE,CAAC;QAC1E,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2BAA2B;IAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,KAAK,CAAC;AACvC,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,IAAY;IACzC,qDAAqD;IACrD,MAAM,SAAS,GAAG,0BAA0B,CAAC;IAC7C,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC;AACrC,CAAC"}

View File

@ -0,0 +1 @@
../cfonts/bin/index.js

View File

@ -0,0 +1 @@
../figlet/bin/index.js

View File

@ -0,0 +1 @@
../is-in-ci/cli.js

View File

@ -0,0 +1 @@
../loose-envify/cli.js

View File

@ -0,0 +1 @@
../window-size/cli.js

View File

@ -0,0 +1,248 @@
# @alcalzone/ansi-tokenize
> Efficiently modify strings containing [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles)
If you find yourself modifying styled strings repeatedly, alternatives like [`slice-ansi`](https://github.com/chalk/slice-ansi/) may end up doing a lot of unnecessary work by re-parsing the string each time. This module provides a way to parse the string into an array of tokens (characters or ANSI codes), which can then be modified and re-serialized into a styled string.
## Install
```
$ npm install @alcalzone/ansi-tokenize
```
## Usage
### Tokenize a string
```js
import { tokenize } from "@alcalzone/ansi-tokenize";
// red "foo", followed by unstyled "bar"
const str = "\x1B[31mfoo\x1B[39mbar";
const tokens = tokenize(str);
// tokens will now look like this:
[
{
type: "ansi",
code: "\x1B[31m",
endCode: "\x1B[39m",
},
{
type: "char",
value: "f",
fullWidth: false,
},
{
type: "char",
value: "o",
fullWidth: false,
},
{
type: "char",
value: "o",
fullWidth: false,
},
{
type: "ansi",
code: "\x1B[39m",
endCode: "\x1B[39m",
},
{
type: "char",
value: "b",
fullWidth: false,
},
{
type: "char",
value: "a",
fullWidth: false,
},
{
type: "char",
value: "r",
fullWidth: false,
},
];
```
Each token is either a character
```ts
export interface Char {
type: "char";
value: string;
fullWidth: boolean;
}
```
where
- `value` is the string representation of the character
- `fullWidth` is `true` if the character is full width (takes up 2 characters in monospace, like CJK characters)
or an ANSI code
```ts
export interface AnsiCode {
type: "ansi";
code: string;
endCode: string;
}
```
where
- `code` is the ANSI code that starts the style
- and `endCode` is the corresponding ANSI code that ends the style.
An `AnsiCode` can also be an end code, in which case `code` and `endCode` will be the same.
### Convert an array of tokens into an array of "styled" chars
This representation is a 1:1 mapping of the original string, but not very useful for modifying the string. The `styledCharsFromTokens` function converts a token array to an array of characters, where each character has an all currently active styles associated with it:
```ts
export interface StyledChar {
type: "char";
value: string;
fullWidth: boolean;
styles: AnsiCode[];
}
```
Using the above example:
```js
import { tokenize, styledCharsFromTokens } from "@alcalzone/ansi-tokenize";
// red "foo", followed by unstyled "bar"
const str = "\x1B[31mfoo\x1B[39mbar";
const tokens = tokenize(str);
const styledChars = styledCharsFromTokens(tokens);
// styledChars will contain the following:
[
{
type: "char",
value: "f",
fullWidth: false,
styles: [
{
type: "ansi",
code: "\x1B[31m",
endCode: "\x1B[39m",
},
],
},
{
type: "char",
value: "o",
fullWidth: false,
styles: [
{
type: "ansi",
code: "\x1B[31m",
endCode: "\x1B[39m",
},
],
},
{
type: "char",
value: "o",
fullWidth: false,
styles: [
{
type: "ansi",
code: "\x1B[31m",
endCode: "\x1B[39m",
},
],
},
{
type: "char",
value: "b",
fullWidth: false,
styles: [],
},
{
type: "char",
value: "a",
fullWidth: false,
styles: [],
},
{
type: "char",
value: "r",
fullWidth: false,
styles: [],
},
];
```
### Modify an array of styled characters
For modification simply edit the items in the array as necessary, as long as the following rules are followed:
1. The `code` and `endCode` properties must match. You can use the `ansi-styles` module to do this.
2. The `fullWidth` property must be correct. You can use the `is-fullwidth-code-point` module to do this, or if working with multiple strings, turn those into styled char arrays first.
E.g. to make the first `o` blue and bold:
```js
import ansiStyles from "ansi-styles";
// ... include the above code
styledChars[1].styles = [
{
type: "ansi",
code: ansiStyles.blue.open,
endCode: ansiStyles.blue.close,
},
{
type: "ansi",
code: ansiStyles.bold.open,
endCode: ansiStyles.bold.close,
},
];
```
### Serialize a styled character array back to a string
The `styledCharsToString` function converts a styled character array back to a string:
```js
import { styledCharsToString } from "@alcalzone/ansi-tokenize";
// ... include the above code
const strOut = styledCharsToString(styledChars);
// str will now be '\x1B[31mf\x1B[34m\x1B[1mo\x1B[22m\x1B[31mo\x1B[39mbar'
```
This automatically figures out the least amount of escape codes necessary to achieve the desired result, as long as the `styles` arrays contain no unnecessary styles, e.g. blue + red foreground.
## Changelog
<!--
Placeholder for next release:
### __WORK IN PROGRESS__
-->
### 0.1.3 (2023-09-07)
- Fix: Support links
### 0.1.2 (2023-08-07)
- Fix: Reduce minimum Node.js version to `14.13.1`
### 0.1.1 (2023-04-05)
- Fix: Active styles are now correctly reset at the end of the string
### 0.1.0 (2023-03-20)
Initial release

View File

@ -0,0 +1,11 @@
import type { AnsiCode } from "./tokenize.js";
export declare const ESCAPES: Set<number>;
export declare const endCodesSet: Set<string>;
export declare const linkStartCodePrefix = "\u001B]8;;";
export declare const linkStartCodePrefixCharCodes: number[];
export declare const linkCodeSuffix = "\u0007";
export declare const linkCodeSuffixCharCode: number;
export declare const linkEndCode: string;
export declare function getLinkStartCode(url: string): string;
export declare function getEndCode(code: string): string;
export declare function ansiCodesToString(codes: AnsiCode[]): string;

View File

@ -0,0 +1,41 @@
import ansiStyles from "ansi-styles";
export const ESCAPES = new Set([27, 155]); // \x1b and \x9b
export const endCodesSet = new Set();
const endCodesMap = new Map();
for (const [start, end] of ansiStyles.codes) {
endCodesSet.add(ansiStyles.color.ansi(end));
endCodesMap.set(ansiStyles.color.ansi(start), ansiStyles.color.ansi(end));
}
export const linkStartCodePrefix = "\x1B]8;;";
export const linkStartCodePrefixCharCodes = linkStartCodePrefix
.split("")
.map((char) => char.charCodeAt(0));
export const linkCodeSuffix = "\x07";
export const linkCodeSuffixCharCode = linkCodeSuffix.charCodeAt(0);
export const linkEndCode = `\x1B]8;;${linkCodeSuffix}`;
export function getLinkStartCode(url) {
return `${linkStartCodePrefix}${url}${linkCodeSuffix}`;
}
export function getEndCode(code) {
if (endCodesSet.has(code))
return code;
if (endCodesMap.has(code))
return endCodesMap.get(code);
if (code.startsWith(linkStartCodePrefix))
return linkEndCode;
code = code.slice(2);
if (code.includes(";")) {
code = code[0] + "0";
}
const ret = ansiStyles.codes.get(parseInt(code, 10));
if (ret) {
return ansiStyles.color.ansi(ret);
}
else {
return ansiStyles.reset.open;
}
}
export function ansiCodesToString(codes) {
return codes.map((code) => code.code).join("");
}
//# sourceMappingURL=ansiCodes.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"ansiCodes.js","sourceRoot":"","sources":["../src/ansiCodes.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AAGrC,MAAM,CAAC,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,gBAAgB;AAE3D,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,GAAG,EAAU,CAAC;AAC7C,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAC;AAC9C,KAAK,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,IAAI,UAAU,CAAC,KAAK,EAAE;IAC5C,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,EAAE,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;CAC1E;AAED,MAAM,CAAC,MAAM,mBAAmB,GAAG,UAAU,CAAC;AAC9C,MAAM,CAAC,MAAM,4BAA4B,GAAG,mBAAmB;KAC7D,KAAK,CAAC,EAAE,CAAC;KACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC;AACpC,MAAM,CAAC,MAAM,cAAc,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,MAAM,sBAAsB,GAAG,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AACnE,MAAM,CAAC,MAAM,WAAW,GAAG,WAAW,cAAc,EAAE,CAAC;AAEvD,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC3C,OAAO,GAAG,mBAAmB,GAAG,GAAG,GAAG,cAAc,EAAE,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,IAAY;IACtC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACvC,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC;QAAE,OAAO,WAAW,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;IAEzD,IAAI,IAAI,CAAC,UAAU,CAAC,mBAAmB,CAAC;QAAE,OAAO,WAAW,CAAC;IAE7D,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACrB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE;QACvB,IAAI,GAAG,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;KACrB;IACD,MAAM,GAAG,GAAG,UAAU,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,CAAC;IACrD,IAAI,GAAG,EAAE;QACR,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;KAClC;SAAM;QACN,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC;KAC7B;AACF,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAiB;IAClD,OAAO,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAChD,CAAC"}

View File

@ -0,0 +1,6 @@
import type { AnsiCode } from "./tokenize.js";
/**
* Returns the minimum amount of ANSI codes necessary to get from the compound style `from` to `to`.
* Both `from` and `to` are expected to be reduced.
*/
export declare function diffAnsiCodes(from: AnsiCode[], to: AnsiCode[]): AnsiCode[];

View File

@ -0,0 +1,17 @@
import { undoAnsiCodes } from "./undo.js";
/**
* Returns the minimum amount of ANSI codes necessary to get from the compound style `from` to `to`.
* Both `from` and `to` are expected to be reduced.
*/
export function diffAnsiCodes(from, to) {
const endCodesInTo = new Set(to.map((code) => code.endCode));
const startCodesInFrom = new Set(from.map((code) => code.code));
return [
// Ignore all styles in `from` that are not overwritten or removed by `to`
// Disable all styles in `from` that are removed in `to`
...undoAnsiCodes(from.filter((code) => !endCodesInTo.has(code.endCode))),
// Add all styles in `to` that don't exist in `from`
...to.filter((code) => !startCodesInFrom.has(code.code)),
];
}
//# sourceMappingURL=diff.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../src/diff.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAE1C;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,IAAgB,EAAE,EAAc;IAC7D,MAAM,YAAY,GAAG,IAAI,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;IAC7D,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;IAEhE,OAAO;QACN,0EAA0E;QAC1E,wDAAwD;QACxD,GAAG,aAAa,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,YAAY,CAAC,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC;QACxE,oDAAoD;QACpD,GAAG,EAAE,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;KACxD,CAAC;AACH,CAAC"}

View File

@ -0,0 +1,6 @@
export { ansiCodesToString } from "./ansiCodes.js";
export { diffAnsiCodes } from "./diff.js";
export { reduceAnsiCodes, reduceAnsiCodesIncremental } from "./reduce.js";
export * from "./styledChars.js";
export * from "./tokenize.js";
export { undoAnsiCodes } from "./undo.js";

View File

@ -0,0 +1,7 @@
export { ansiCodesToString } from "./ansiCodes.js";
export { diffAnsiCodes } from "./diff.js";
export { reduceAnsiCodes, reduceAnsiCodesIncremental } from "./reduce.js";
export * from "./styledChars.js";
export * from "./tokenize.js";
export { undoAnsiCodes } from "./undo.js";
//# sourceMappingURL=index.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,eAAe,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAC1E,cAAc,kBAAkB,CAAC;AACjC,cAAc,eAAe,CAAC;AAC9B,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC"}

View File

@ -0,0 +1,5 @@
import type { AnsiCode } from "./tokenize.js";
/** Reduces the given array of ANSI codes to the minimum necessary to render with the same style */
export declare function reduceAnsiCodes(codes: AnsiCode[]): AnsiCode[];
/** Like {@link reduceAnsiCodes}, but assumes that `codes` is already reduced. Further reductions are only done for the items in `newCodes`. */
export declare function reduceAnsiCodesIncremental(codes: AnsiCode[], newCodes: AnsiCode[]): AnsiCode[];

View File

@ -0,0 +1,27 @@
import ansiStyles from "ansi-styles";
import { endCodesSet } from "./ansiCodes.js";
/** Reduces the given array of ANSI codes to the minimum necessary to render with the same style */
export function reduceAnsiCodes(codes) {
return reduceAnsiCodesIncremental([], codes);
}
/** Like {@link reduceAnsiCodes}, but assumes that `codes` is already reduced. Further reductions are only done for the items in `newCodes`. */
export function reduceAnsiCodesIncremental(codes, newCodes) {
let ret = [...codes];
for (const code of newCodes) {
if (code.code === ansiStyles.reset.open) {
// Reset code, disable all codes
ret = [];
}
else if (endCodesSet.has(code.code)) {
// This is an end code, disable all matching start codes
ret = ret.filter((retCode) => retCode.endCode !== code.code);
}
else {
// This is a start code. Disable all styles this "overrides", then enable it
ret = ret.filter((retCode) => retCode.endCode !== code.endCode);
ret.push(code);
}
}
return ret;
}
//# sourceMappingURL=reduce.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"reduce.js","sourceRoot":"","sources":["../src/reduce.ts"],"names":[],"mappings":"AAAA,OAAO,UAAU,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAG7C,mGAAmG;AACnG,MAAM,UAAU,eAAe,CAAC,KAAiB;IAChD,OAAO,0BAA0B,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;AAC9C,CAAC;AAED,+IAA+I;AAC/I,MAAM,UAAU,0BAA0B,CAAC,KAAiB,EAAE,QAAoB;IACjF,IAAI,GAAG,GAAe,CAAC,GAAG,KAAK,CAAC,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE;QAC5B,IAAI,IAAI,CAAC,IAAI,KAAK,UAAU,CAAC,KAAK,CAAC,IAAI,EAAE;YACxC,gCAAgC;YAChC,GAAG,GAAG,EAAE,CAAC;SACT;aAAM,IAAI,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;YACtC,wDAAwD;YACxD,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,IAAI,CAAC,CAAC;SAC7D;aAAM;YACN,4EAA4E;YAC5E,GAAG,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,OAAO,KAAK,IAAI,CAAC,OAAO,CAAC,CAAC;YAChE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;SACf;KACD;IAED,OAAO,GAAG,CAAC;AACZ,CAAC"}

View File

@ -0,0 +1,6 @@
import type { AnsiCode, Char, Token } from "./tokenize.js";
export interface StyledChar extends Char {
styles: AnsiCode[];
}
export declare function styledCharsFromTokens(tokens: Token[]): StyledChar[];
export declare function styledCharsToString(chars: StyledChar[]): string;

View File

@ -0,0 +1,38 @@
import { ansiCodesToString } from "./ansiCodes.js";
import { diffAnsiCodes } from "./diff.js";
import { reduceAnsiCodesIncremental } from "./reduce.js";
export function styledCharsFromTokens(tokens) {
let codes = [];
const ret = [];
for (const token of tokens) {
if (token.type === "ansi") {
codes = reduceAnsiCodesIncremental(codes, [token]);
}
else if (token.type === "char") {
ret.push({
...token,
styles: [...codes],
});
}
}
return ret;
}
export function styledCharsToString(chars) {
let ret = "";
for (let i = 0; i < chars.length; i++) {
const char = chars[i];
if (i === 0) {
ret += ansiCodesToString(char.styles);
}
else {
ret += ansiCodesToString(diffAnsiCodes(chars[i - 1].styles, char.styles));
}
ret += char.value;
// reset active styles at the end of the string
if (i === chars.length - 1) {
ret += ansiCodesToString(diffAnsiCodes(char.styles, []));
}
}
return ret;
}
//# sourceMappingURL=styledChars.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"styledChars.js","sourceRoot":"","sources":["../src/styledChars.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,WAAW,CAAC;AAC1C,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAOzD,MAAM,UAAU,qBAAqB,CAAC,MAAe;IACpD,IAAI,KAAK,GAAe,EAAE,CAAC;IAC3B,MAAM,GAAG,GAAiB,EAAE,CAAC;IAC7B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE;QAC3B,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE;YAC1B,KAAK,GAAG,0BAA0B,CAAC,KAAK,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC;SACnD;aAAM,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE;YACjC,GAAG,CAAC,IAAI,CAAC;gBACR,GAAG,KAAK;gBACR,MAAM,EAAE,CAAC,GAAG,KAAK,CAAC;aAClB,CAAC,CAAC;SACH;KACD;IACD,OAAO,GAAG,CAAC;AACZ,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAmB;IACtD,IAAI,GAAG,GAAG,EAAE,CAAC;IACb,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE;QACtC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QACtB,IAAI,CAAC,KAAK,CAAC,EAAE;YACZ,GAAG,IAAI,iBAAiB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;SACtC;aAAM;YACN,GAAG,IAAI,iBAAiB,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC;SAC1E;QACD,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC;QAClB,+CAA+C;QAC/C,IAAI,CAAC,KAAK,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;YAC3B,GAAG,IAAI,iBAAiB,CAAC,aAAa,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,CAAC;SACzD;KACD;IACD,OAAO,GAAG,CAAC;AACZ,CAAC"}

View File

@ -0,0 +1,12 @@
export interface AnsiCode {
type: "ansi";
code: string;
endCode: string;
}
export interface Char {
type: "char";
value: string;
fullWidth: boolean;
}
export type Token = AnsiCode | Char;
export declare function tokenize(str: string, endChar?: number): Token[];

View File

@ -0,0 +1,70 @@
import isFullwidthCodePoint from "is-fullwidth-code-point";
import { ESCAPES, getEndCode, linkStartCodePrefix, linkStartCodePrefixCharCodes, } from "./ansiCodes.js";
function findNumberIndex(str) {
for (let index = 0; index < str.length; index++) {
const charCode = str.charCodeAt(index);
if (charCode >= 48 && charCode <= 57) {
return index;
}
}
return -1;
}
function parseLinkCode(string, offset) {
string = string.slice(offset);
for (let index = 1; index < linkStartCodePrefixCharCodes.length; index++) {
if (string.charCodeAt(index) !== linkStartCodePrefixCharCodes[index]) {
return undefined;
}
}
// This is a link code (with or without the URL part). Find the end of it.
const endIndex = string.indexOf("\x07", linkStartCodePrefix.length);
if (endIndex === -1)
return undefined;
return string.slice(0, endIndex + 1);
}
function parseAnsiCode(string, offset) {
string = string.slice(offset, offset + 19);
const startIndex = findNumberIndex(string);
if (startIndex !== -1) {
let endIndex = string.indexOf("m", startIndex);
if (endIndex === -1) {
endIndex = string.length;
}
return string.slice(0, endIndex + 1);
}
}
export function tokenize(str, endChar = Number.POSITIVE_INFINITY) {
const ret = [];
let index = 0;
let visible = 0;
while (index < str.length) {
const codePoint = str.codePointAt(index);
if (ESCAPES.has(codePoint)) {
// TODO: We should probably decide on the next character ("[" or "]") which code path to take.
const code = parseLinkCode(str, index) || parseAnsiCode(str, index);
if (code) {
ret.push({
type: "ansi",
code,
endCode: getEndCode(code),
});
index += code.length;
continue;
}
}
const fullWidth = isFullwidthCodePoint(codePoint);
const character = String.fromCodePoint(codePoint);
ret.push({
type: "char",
value: character,
fullWidth,
});
index += character.length;
visible += fullWidth ? 2 : character.length;
if (visible >= endChar) {
break;
}
}
return ret;
}
//# sourceMappingURL=tokenize.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"tokenize.js","sourceRoot":"","sources":["../src/tokenize.ts"],"names":[],"mappings":"AAAA,OAAO,oBAAoB,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EACN,OAAO,EACP,UAAU,EACV,mBAAmB,EACnB,4BAA4B,GAC5B,MAAM,gBAAgB,CAAC;AAgBxB,SAAS,eAAe,CAAC,GAAW;IACnC,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QAChD,MAAM,QAAQ,GAAG,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvC,IAAI,QAAQ,IAAI,EAAE,IAAI,QAAQ,IAAI,EAAE,EAAE;YACrC,OAAO,KAAK,CAAC;SACb;KACD;IAED,OAAO,CAAC,CAAC,CAAC;AACX,CAAC;AAED,SAAS,aAAa,CAAC,MAAc,EAAE,MAAc;IACpD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC9B,KAAK,IAAI,KAAK,GAAG,CAAC,EAAE,KAAK,GAAG,4BAA4B,CAAC,MAAM,EAAE,KAAK,EAAE,EAAE;QACzE,IAAI,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,KAAK,4BAA4B,CAAC,KAAK,CAAC,EAAE;YACrE,OAAO,SAAS,CAAC;SACjB;KACD;IACD,0EAA0E;IAC1E,MAAM,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,CAAC,MAAM,CAAC,CAAC;IACpE,IAAI,QAAQ,KAAK,CAAC,CAAC;QAAE,OAAO,SAAS,CAAC;IAEtC,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,SAAS,aAAa,CAAC,MAAc,EAAE,MAAc;IACpD,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,EAAE,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC;IAC3C,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE;QACtB,IAAI,QAAQ,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QAC/C,IAAI,QAAQ,KAAK,CAAC,CAAC,EAAE;YACpB,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC;SACzB;QAED,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,QAAQ,GAAG,CAAC,CAAC,CAAC;KACrC;AACF,CAAC;AAED,MAAM,UAAU,QAAQ,CAAC,GAAW,EAAE,UAAkB,MAAM,CAAC,iBAAiB;IAC/E,MAAM,GAAG,GAAY,EAAE,CAAC;IAExB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,OAAO,KAAK,GAAG,GAAG,CAAC,MAAM,EAAE;QAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,WAAW,CAAC,KAAK,CAAE,CAAC;QAE1C,IAAI,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE;YAC3B,8FAA8F;YAC9F,MAAM,IAAI,GAAG,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,aAAa,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;YACpE,IAAI,IAAI,EAAE;gBACT,GAAG,CAAC,IAAI,CAAC;oBACR,IAAI,EAAE,MAAM;oBACZ,IAAI;oBACJ,OAAO,EAAE,UAAU,CAAC,IAAI,CAAC;iBACzB,CAAC,CAAC;gBACH,KAAK,IAAI,IAAI,CAAC,MAAM,CAAC;gBACrB,SAAS;aACT;SACD;QAED,MAAM,SAAS,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAC;QAClD,MAAM,SAAS,GAAG,MAAM,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC;QAElD,GAAG,CAAC,IAAI,CAAC;YACR,IAAI,EAAE,MAAM;YACZ,KAAK,EAAE,SAAS;YAChB,SAAS;SACT,CAAC,CAAC;QAEH,KAAK,IAAI,SAAS,CAAC,MAAM,CAAC;QAC1B,OAAO,IAAI,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,MAAM,CAAC;QAE5C,IAAI,OAAO,IAAI,OAAO,EAAE;YACvB,MAAM;SACN;KACD;IAED,OAAO,GAAG,CAAC;AACZ,CAAC"}

View File

@ -0,0 +1,3 @@
import type { AnsiCode } from "./tokenize.js";
/** Returns the combination of ANSI codes needed to undo the given ANSI codes */
export declare function undoAnsiCodes(codes: AnsiCode[]): AnsiCode[];

View File

@ -0,0 +1,11 @@
import { reduceAnsiCodes } from "./reduce.js";
/** Returns the combination of ANSI codes needed to undo the given ANSI codes */
export function undoAnsiCodes(codes) {
return reduceAnsiCodes(codes)
.reverse()
.map((code) => ({
...code,
code: code.endCode,
}));
}
//# sourceMappingURL=undo.js.map

View File

@ -0,0 +1 @@
{"version":3,"file":"undo.js","sourceRoot":"","sources":["../src/undo.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAG9C,gFAAgF;AAChF,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC9C,OAAO,eAAe,CAAC,KAAK,CAAC;SAC3B,OAAO,EAAE;SACT,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACf,GAAG,IAAI;QACP,IAAI,EAAE,IAAI,CAAC,OAAO;KAClB,CAAC,CAAC,CAAC;AACN,CAAC"}

View File

@ -0,0 +1,236 @@
export type CSPair = { // eslint-disable-line @typescript-eslint/naming-convention
/**
The ANSI terminal control sequence for starting this style.
*/
readonly open: string;
/**
The ANSI terminal control sequence for ending this style.
*/
readonly close: string;
};
export type ColorBase = {
/**
The ANSI terminal control sequence for ending this color.
*/
readonly close: string;
ansi(code: number): string;
ansi256(code: number): string;
ansi16m(red: number, green: number, blue: number): string;
};
export type Modifier = {
/**
Resets the current color chain.
*/
readonly reset: CSPair;
/**
Make text bold.
*/
readonly bold: CSPair;
/**
Emitting only a small amount of light.
*/
readonly dim: CSPair;
/**
Make text italic. (Not widely supported)
*/
readonly italic: CSPair;
/**
Make text underline. (Not widely supported)
*/
readonly underline: CSPair;
/**
Make text overline.
Supported on VTE-based terminals, the GNOME terminal, mintty, and Git Bash.
*/
readonly overline: CSPair;
/**
Inverse background and foreground colors.
*/
readonly inverse: CSPair;
/**
Prints the text, but makes it invisible.
*/
readonly hidden: CSPair;
/**
Puts a horizontal line through the center of the text. (Not widely supported)
*/
readonly strikethrough: CSPair;
};
export type ForegroundColor = {
readonly black: CSPair;
readonly red: CSPair;
readonly green: CSPair;
readonly yellow: CSPair;
readonly blue: CSPair;
readonly cyan: CSPair;
readonly magenta: CSPair;
readonly white: CSPair;
/**
Alias for `blackBright`.
*/
readonly gray: CSPair;
/**
Alias for `blackBright`.
*/
readonly grey: CSPair;
readonly blackBright: CSPair;
readonly redBright: CSPair;
readonly greenBright: CSPair;
readonly yellowBright: CSPair;
readonly blueBright: CSPair;
readonly cyanBright: CSPair;
readonly magentaBright: CSPair;
readonly whiteBright: CSPair;
};
export type BackgroundColor = {
readonly bgBlack: CSPair;
readonly bgRed: CSPair;
readonly bgGreen: CSPair;
readonly bgYellow: CSPair;
readonly bgBlue: CSPair;
readonly bgCyan: CSPair;
readonly bgMagenta: CSPair;
readonly bgWhite: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGray: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGrey: CSPair;
readonly bgBlackBright: CSPair;
readonly bgRedBright: CSPair;
readonly bgGreenBright: CSPair;
readonly bgYellowBright: CSPair;
readonly bgBlueBright: CSPair;
readonly bgCyanBright: CSPair;
readonly bgMagentaBright: CSPair;
readonly bgWhiteBright: CSPair;
};
export type ConvertColor = {
/**
Convert from the RGB color space to the ANSI 256 color space.
@param red - (`0...255`)
@param green - (`0...255`)
@param blue - (`0...255`)
*/
rgbToAnsi256(red: number, green: number, blue: number): number;
/**
Convert from the RGB HEX color space to the RGB color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToRgb(hex: string): [red: number, green: number, blue: number];
/**
Convert from the RGB HEX color space to the ANSI 256 color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToAnsi256(hex: string): number;
/**
Convert from the ANSI 256 color space to the ANSI 16 color space.
@param code - A number representing the ANSI 256 color.
*/
ansi256ToAnsi(code: number): number;
/**
Convert from the RGB color space to the ANSI 16 color space.
@param red - (`0...255`)
@param green - (`0...255`)
@param blue - (`0...255`)
*/
rgbToAnsi(red: number, green: number, blue: number): number;
/**
Convert from the RGB HEX color space to the ANSI 16 color space.
@param hex - A hexadecimal string containing RGB data.
*/
hexToAnsi(hex: string): number;
};
/**
Basic modifier names.
*/
export type ModifierName = keyof Modifier;
/**
Basic foreground color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type ForegroundColorName = keyof ForegroundColor;
/**
Basic background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type BackgroundColorName = keyof BackgroundColor;
/**
Basic color names. The combination of foreground and background color names.
[More colors here.](https://github.com/chalk/chalk/blob/main/readme.md#256-and-truecolor-color-support)
*/
export type ColorName = ForegroundColorName | BackgroundColorName;
/**
Basic modifier names.
*/
export const modifierNames: readonly ModifierName[];
/**
Basic foreground color names.
*/
export const foregroundColorNames: readonly ForegroundColorName[];
/**
Basic background color names.
*/
export const backgroundColorNames: readonly BackgroundColorName[];
/*
Basic color names. The combination of foreground and background color names.
*/
export const colorNames: readonly ColorName[];
declare const ansiStyles: {
readonly modifier: Modifier;
readonly color: ColorBase & ForegroundColor;
readonly bgColor: ColorBase & BackgroundColor;
readonly codes: ReadonlyMap<number, number>;
} & ForegroundColor & BackgroundColor & Modifier & ConvertColor;
export default ansiStyles;

View File

@ -0,0 +1,223 @@
const ANSI_BACKGROUND_OFFSET = 10;
const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
const styles = {
modifier: {
reset: [0, 0],
// 21 isn't widely supported and 22 does the same thing
bold: [1, 22],
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
overline: [53, 55],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29],
},
color: {
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
// Bright color
blackBright: [90, 39],
gray: [90, 39], // Alias of `blackBright`
grey: [90, 39], // Alias of `blackBright`
redBright: [91, 39],
greenBright: [92, 39],
yellowBright: [93, 39],
blueBright: [94, 39],
magentaBright: [95, 39],
cyanBright: [96, 39],
whiteBright: [97, 39],
},
bgColor: {
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49],
// Bright color
bgBlackBright: [100, 49],
bgGray: [100, 49], // Alias of `bgBlackBright`
bgGrey: [100, 49], // Alias of `bgBlackBright`
bgRedBright: [101, 49],
bgGreenBright: [102, 49],
bgYellowBright: [103, 49],
bgBlueBright: [104, 49],
bgMagentaBright: [105, 49],
bgCyanBright: [106, 49],
bgWhiteBright: [107, 49],
},
};
export const modifierNames = Object.keys(styles.modifier);
export const foregroundColorNames = Object.keys(styles.color);
export const backgroundColorNames = Object.keys(styles.bgColor);
export const colorNames = [...foregroundColorNames, ...backgroundColorNames];
function assembleStyles() {
const codes = new Map();
for (const [groupName, group] of Object.entries(styles)) {
for (const [styleName, style] of Object.entries(group)) {
styles[styleName] = {
open: `\u001B[${style[0]}m`,
close: `\u001B[${style[1]}m`,
};
group[styleName] = styles[styleName];
codes.set(style[0], style[1]);
}
Object.defineProperty(styles, groupName, {
value: group,
enumerable: false,
});
}
Object.defineProperty(styles, 'codes', {
value: codes,
enumerable: false,
});
styles.color.close = '\u001B[39m';
styles.bgColor.close = '\u001B[49m';
styles.color.ansi = wrapAnsi16();
styles.color.ansi256 = wrapAnsi256();
styles.color.ansi16m = wrapAnsi16m();
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
// From https://github.com/Qix-/color-convert/blob/3f0e0d4e92e235796ccb17f6e85c72094a651f49/conversions.js
Object.defineProperties(styles, {
rgbToAnsi256: {
value(red, green, blue) {
// We use the extended greyscale palette here, with the exception of
// black and white. normal palette only has 4 greyscale shades.
if (red === green && green === blue) {
if (red < 8) {
return 16;
}
if (red > 248) {
return 231;
}
return Math.round(((red - 8) / 247) * 24) + 232;
}
return 16
+ (36 * Math.round(red / 255 * 5))
+ (6 * Math.round(green / 255 * 5))
+ Math.round(blue / 255 * 5);
},
enumerable: false,
},
hexToRgb: {
value(hex) {
const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
if (!matches) {
return [0, 0, 0];
}
let [colorString] = matches;
if (colorString.length === 3) {
colorString = [...colorString].map(character => character + character).join('');
}
const integer = Number.parseInt(colorString, 16);
return [
/* eslint-disable no-bitwise */
(integer >> 16) & 0xFF,
(integer >> 8) & 0xFF,
integer & 0xFF,
/* eslint-enable no-bitwise */
];
},
enumerable: false,
},
hexToAnsi256: {
value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
enumerable: false,
},
ansi256ToAnsi: {
value(code) {
if (code < 8) {
return 30 + code;
}
if (code < 16) {
return 90 + (code - 8);
}
let red;
let green;
let blue;
if (code >= 232) {
red = (((code - 232) * 10) + 8) / 255;
green = red;
blue = red;
} else {
code -= 16;
const remainder = code % 36;
red = Math.floor(code / 36) / 5;
green = Math.floor(remainder / 6) / 5;
blue = (remainder % 6) / 5;
}
const value = Math.max(red, green, blue) * 2;
if (value === 0) {
return 30;
}
// eslint-disable-next-line no-bitwise
let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
if (value === 2) {
result += 60;
}
return result;
},
enumerable: false,
},
rgbToAnsi: {
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
enumerable: false,
},
hexToAnsi: {
value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
enumerable: false,
},
});
return styles;
}
const ansiStyles = assembleStyles();
export default ansiStyles;

View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,54 @@
{
"name": "ansi-styles",
"version": "6.2.3",
"description": "ANSI escape codes for styling strings in the terminal",
"license": "MIT",
"repository": "chalk/ansi-styles",
"funding": "https://github.com/chalk/ansi-styles?sponsor=1",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"engines": {
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd",
"screenshot": "svg-term --command='node screenshot' --out=screenshot.svg --padding=3 --width=55 --height=3 --at=1000 --no-cursor"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"devDependencies": {
"ava": "^6.1.3",
"svg-term-cli": "^2.1.1",
"tsd": "^0.31.1",
"xo": "^0.58.0"
}
}

View File

@ -0,0 +1,173 @@
# ansi-styles
> [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
![](screenshot.png)
## Install
```sh
npm install ansi-styles
```
## Usage
```js
import styles from 'ansi-styles';
console.log(`${styles.green.open}Hello world!${styles.green.close}`);
// Color conversion between 256/truecolor
// NOTE: When converting from truecolor to 256 colors, the original color
// may be degraded to fit the new color palette. This means terminals
// that do not support 16 million colors will best-match the
// original color.
console.log(`${styles.color.ansi(styles.rgbToAnsi(199, 20, 250))}Hello World${styles.color.close}`)
console.log(`${styles.color.ansi256(styles.rgbToAnsi256(199, 20, 250))}Hello World${styles.color.close}`)
console.log(`${styles.color.ansi16m(...styles.hexToRgb('#abcdef'))}Hello World${styles.color.close}`)
```
## API
### `open` and `close`
Each style has an `open` and `close` property.
### `modifierNames`, `foregroundColorNames`, `backgroundColorNames`, and `colorNames`
All supported style strings are exposed as an array of strings for convenience. `colorNames` is the combination of `foregroundColorNames` and `backgroundColorNames`.
This can be useful if you need to validate input:
```js
import {modifierNames, foregroundColorNames} from 'ansi-styles';
console.log(modifierNames.includes('bold'));
//=> true
console.log(foregroundColorNames.includes('pink'));
//=> false
```
## Styles
### Modifiers
- `reset`
- `bold`
- `dim`
- `italic` *(Not widely supported)*
- `underline`
- `overline` *Supported on VTE-based terminals, the GNOME terminal, mintty, and Git Bash.*
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
### Colors
- `black`
- `red`
- `green`
- `yellow`
- `blue`
- `magenta`
- `cyan`
- `white`
- `blackBright` (alias: `gray`, `grey`)
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright` (alias: `bgGray`, `bgGrey`)
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`
## Advanced usage
By default, you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
- `styles.modifier`
- `styles.color`
- `styles.bgColor`
###### Example
```js
import styles from 'ansi-styles';
console.log(styles.color.green.open);
```
Raw escape codes (i.e. without the CSI escape prefix `\u001B[` and render mode postfix `m`) are available under `styles.codes`, which returns a `Map` with the open codes as keys and close codes as values.
###### Example
```js
import styles from 'ansi-styles';
console.log(styles.codes.get(36));
//=> 39
```
## 16 / 256 / 16 million (TrueColor) support
`ansi-styles` allows converting between various color formats and ANSI escapes, with support for 16, 256 and [16 million colors](https://gist.github.com/XVilka/8346728).
The following color spaces are supported:
- `rgb`
- `hex`
- `ansi256`
- `ansi`
To use these, call the associated conversion function with the intended output, for example:
```js
import styles from 'ansi-styles';
styles.color.ansi(styles.rgbToAnsi(100, 200, 15)); // RGB to 16 color ansi foreground code
styles.bgColor.ansi(styles.hexToAnsi('#C0FFEE')); // HEX to 16 color ansi foreground code
styles.color.ansi256(styles.rgbToAnsi256(100, 200, 15)); // RGB to 256 color ansi foreground code
styles.bgColor.ansi256(styles.hexToAnsi256('#C0FFEE')); // HEX to 256 color ansi foreground code
styles.color.ansi16m(100, 200, 15); // RGB to 16 million color foreground code
styles.bgColor.ansi16m(...styles.hexToRgb('#C0FFEE')); // Hex (RGB) to 16 million color foreground code
```
## Related
- [ansi-escapes](https://github.com/sindresorhus/ansi-escapes) - ANSI escape codes for manipulating the terminal
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## For enterprise
Available as part of the Tidelift Subscription.
The maintainers of `ansi-styles` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-ansi-styles?utm_source=npm-ansi-styles&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)

View File

@ -0,0 +1,63 @@
{
"name": "@alcalzone/ansi-tokenize",
"version": "0.1.3",
"description": "Efficiently modify strings containing ANSI escape codes",
"publishConfig": {
"access": "public"
},
"author": {
"name": "AlCalzone",
"email": "d.griesel@gmx.net"
},
"license": "MIT",
"type": "module",
"module": "build/index.js",
"types": "build/index.d.ts",
"exports": {
".": {
"types": "./build/index.d.ts",
"import": "./build/index.js"
},
"./package.json": "./package.json"
},
"files": [
"build"
],
"engines": {
"node": ">=14.13.1"
},
"devDependencies": {
"@alcalzone/release-script": "~3.5.9",
"@alcalzone/release-script-plugin-license": "~3.5.9",
"@tsconfig/node14": "^14.1.0",
"@types/node": "^14.18.54",
"@typescript-eslint/eslint-plugin": "^5.55.0",
"@typescript-eslint/parser": "^5.55.0",
"ava": "^4.3.3",
"eslint": "^8.36.0",
"eslint-config-prettier": "^8.7.0",
"eslint-plugin-prettier": "^4.2.1",
"prettier": "^2.8.4",
"source-map-support": "^0.5.21",
"ts-node": "^10.9.1",
"tsx": "^3.12.8",
"typescript": "^5.0.2"
},
"dependencies": {
"ansi-styles": "^6.2.1",
"is-fullwidth-code-point": "^4.0.0"
},
"scripts": {
"prepare": "tsc -p tsconfig.build.json",
"build": "tsc -p tsconfig.build.json",
"test": "NODE_OPTIONS='--loader tsx' ava",
"lint": "eslint .",
"release": "release-script"
},
"ava": {
"extensions": {
"ts": "module"
}
},
"packageManager": "yarn@3.5.0"
}

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

View File

@ -0,0 +1,56 @@
# Installation
> `npm install --save @types/gradient-string`
# Summary
This package contains type definitions for gradient-string (https://github.com/bokub/gradient-string).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/gradient-string.
## [index.d.ts](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/gradient-string/index.d.ts)
````ts
import tinycolor = require("tinycolor2");
declare namespace gradient {
interface PositionedColorInput {
color: tinycolor.ColorInput;
pos: number;
}
interface Gradient {
(message?: string, opt?: Options): string;
multiline(message?: string, opt?: Options): string;
}
interface Options {
interpolation?: string | undefined;
hsvSpin?: string | undefined;
}
const atlas: Gradient;
const cristal: Gradient;
const teen: Gradient;
const mind: Gradient;
const morning: Gradient;
const vice: Gradient;
const passion: Gradient;
const fruit: Gradient;
const instagram: Gradient;
const retro: Gradient;
const summer: Gradient;
const rainbow: Gradient;
const pastel: Gradient;
}
declare function gradient(colors: tinycolor.ColorInput[] | gradient.PositionedColorInput[]): gradient.Gradient;
declare function gradient(...colors: tinycolor.ColorInput[]): gradient.Gradient;
declare function gradient(...colors: gradient.PositionedColorInput[]): gradient.Gradient;
export = gradient;
````
### Additional Details
* Last updated: Wed, 03 Apr 2024 18:35:48 GMT
* Dependencies: [@types/tinycolor2](https://npmjs.com/package/@types/tinycolor2)
# Credits
These definitions were written by .

View File

@ -0,0 +1,37 @@
import tinycolor = require("tinycolor2");
declare namespace gradient {
interface PositionedColorInput {
color: tinycolor.ColorInput;
pos: number;
}
interface Gradient {
(message?: string, opt?: Options): string;
multiline(message?: string, opt?: Options): string;
}
interface Options {
interpolation?: string | undefined;
hsvSpin?: string | undefined;
}
const atlas: Gradient;
const cristal: Gradient;
const teen: Gradient;
const mind: Gradient;
const morning: Gradient;
const vice: Gradient;
const passion: Gradient;
const fruit: Gradient;
const instagram: Gradient;
const retro: Gradient;
const summer: Gradient;
const rainbow: Gradient;
const pastel: Gradient;
}
declare function gradient(colors: tinycolor.ColorInput[] | gradient.PositionedColorInput[]): gradient.Gradient;
declare function gradient(...colors: tinycolor.ColorInput[]): gradient.Gradient;
declare function gradient(...colors: gradient.PositionedColorInput[]): gradient.Gradient;
export = gradient;

View File

@ -0,0 +1,21 @@
{
"name": "@types/gradient-string",
"version": "1.1.6",
"description": "TypeScript definitions for gradient-string",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/gradient-string",
"license": "MIT",
"contributors": [],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/gradient-string"
},
"scripts": {},
"dependencies": {
"@types/tinycolor2": "*"
},
"typesPublisherContentHash": "ac608d4ab91cb5bab93a4c480779954da0a943061db546bb59769826f934caaf",
"typeScriptVersion": "4.7"
}

View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE

View File

@ -0,0 +1,15 @@
# Installation
> `npm install --save @types/tinycolor2`
# Summary
This package contains type definitions for tinycolor2 (https://github.com/bgrins/TinyColor).
# Details
Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/tinycolor2.
### Additional Details
* Last updated: Tue, 07 Nov 2023 15:11:36 GMT
* Dependencies: none
# Credits
These definitions were written by [Mordechai Zuber](https://github.com/M-Zuber), [Geert Jansen](https://github.com/geertjansen), and [Niels van Hoorn](https://github.com/nvh).

View File

@ -0,0 +1,663 @@
declare namespace tinycolor {
type ColorInputWithoutInstance =
| string
| ColorFormats.PRGB
| ColorFormats.PRGBA
| ColorFormats.RGB
| ColorFormats.RGBA
| ColorFormats.HSL
| ColorFormats.HSLA
| ColorFormats.HSV
| ColorFormats.HSVA;
type ColorInput = ColorInputWithoutInstance | Instance;
namespace ColorFormats {
interface Alpha {
a: number;
}
interface PRGB {
r: string;
g: string;
b: string;
}
interface PRGBA extends PRGB, Alpha {}
interface RGB {
r: number;
g: number;
b: number;
}
interface RGBA extends RGB, Alpha {}
interface HSL {
h: number;
s: number;
l: number;
}
interface HSLA extends HSL, Alpha {}
interface HSV {
h: number;
s: number;
v: number;
}
interface HSVA extends HSV {
a: number;
}
}
interface ConstructorOptions {
format?: string | undefined;
gradientType?: boolean | undefined;
}
interface WCAG2Options {
level?: "AA" | "AAA" | undefined;
size?: "large" | "small" | undefined;
}
interface MostReadableArgs extends WCAG2Options {
includeFallbackColors?: boolean | undefined;
}
interface Constructor {
/**
* Create a tinycolor instance of the color named.
*
* @param color - the color as one of the valid color input format.
*/
new(color?: ColorInput, opts?: ConstructorOptions): Instance;
(color?: ColorInput, opts?: ConstructorOptions): Instance;
/**
* Create a tinycolor instance based off the relative values.
* Works with any color formats
*
* @param ratio - the relative color/hue values to apply to the new instance.
*/
fromRatio(ratio?: ColorInputWithoutInstance): Instance;
/**
* Compares two colors. Each colors can be any color inputs.
*/
equals(color1?: ColorInput, color2?: ColorInput): boolean;
/**
* Returns a random color
*/
random(): Instance;
mix(color1: ColorInput, color2: ColorInput, amount?: number): Instance;
/**
* Compares the two colors and returns the constrast between two colors as a number.
*
* @param color1 - the first color to be used in the comparison.
* @param color2 - the second color to be used in the comparison.
*/
readability(color1: ColorInput, color2: ColorInput): number;
/**
* Ensure that foreground and background color combinations meet WCAG2 guidelines.
*
* @param color1 - the fore color wanted.
* @param color2 - the back color wanted.
* @param wcag2 - WCAG option. If the entire object is absent, function use the default of {level:"AA",size:"small"}.
* @param wcag2.level - The 'level' property states 'AA' or 'AAA'
* if missing or invalid, it defaults to 'AA'
* @param wcag2.size - The 'size' property states 'large' or 'small'
* if missing or invalid, it defaults to 'small'.
*/
isReadable(color1: ColorInput, color2: ColorInput, wcag2?: WCAG2Options): boolean;
/**
* Given a base color and a list of possible foreground or background colors for that base,
* returns the most readable color. Optionally returns Black or White if the most readable color is unreadable.
*
* @param color - the base color.
* @param colorsToCompare - array of colors to pick the most readable one from.
* @param args - and object with extra arguments
*/
mostReadable(baseColor: ColorInput, colorList: ColorInput[], args?: MostReadableArgs): Instance;
/**
* key: 'real' color name
* value: hex value ex. names["red"] --> "f00"
*/
names: {
aliceblue: "f0f8ff";
antiquewhite: "faebd7";
aqua: "0ff";
aquamarine: "7fffd4";
azure: "f0ffff";
beige: "f5f5dc";
bisque: "ffe4c4";
black: "000";
blanchedalmond: "ffebcd";
blue: "00f";
blueviolet: "8a2be2";
brown: "a52a2a";
burlywood: "deb887";
burntsienna: "ea7e5d";
cadetblue: "5f9ea0";
chartreuse: "7fff00";
chocolate: "d2691e";
coral: "ff7f50";
cornflowerblue: "6495ed";
cornsilk: "fff8dc";
crimson: "dc143c";
cyan: "0ff";
darkblue: "00008b";
darkcyan: "008b8b";
darkgoldenrod: "b8860b";
darkgray: "a9a9a9";
darkgreen: "006400";
darkgrey: "a9a9a9";
darkkhaki: "bdb76b";
darkmagenta: "8b008b";
darkolivegreen: "556b2f";
darkorange: "ff8c00";
darkorchid: "9932cc";
darkred: "8b0000";
darksalmon: "e9967a";
darkseagreen: "8fbc8f";
darkslateblue: "483d8b";
darkslategray: "2f4f4f";
darkslategrey: "2f4f4f";
darkturquoise: "00ced1";
darkviolet: "9400d3";
deeppink: "ff1493";
deepskyblue: "00bfff";
dimgray: "696969";
dimgrey: "696969";
dodgerblue: "1e90ff";
firebrick: "b22222";
floralwhite: "fffaf0";
forestgreen: "228b22";
fuchsia: "f0f";
gainsboro: "dcdcdc";
ghostwhite: "f8f8ff";
gold: "ffd700";
goldenrod: "daa520";
gray: "808080";
green: "008000";
greenyellow: "adff2f";
grey: "808080";
honeydew: "f0fff0";
hotpink: "ff69b4";
indianred: "cd5c5c";
indigo: "4b0082";
ivory: "fffff0";
khaki: "f0e68c";
lavender: "e6e6fa";
lavenderblush: "fff0f5";
lawngreen: "7cfc00";
lemonchiffon: "fffacd";
lightblue: "add8e6";
lightcoral: "f08080";
lightcyan: "e0ffff";
lightgoldenrodyellow: "fafad2";
lightgray: "d3d3d3";
lightgreen: "90ee90";
lightgrey: "d3d3d3";
lightpink: "ffb6c1";
lightsalmon: "ffa07a";
lightseagreen: "20b2aa";
lightskyblue: "87cefa";
lightslategray: "789";
lightslategrey: "789";
lightsteelblue: "b0c4de";
lightyellow: "ffffe0";
lime: "0f0";
limegreen: "32cd32";
linen: "faf0e6";
magenta: "f0f";
maroon: "800000";
mediumaquamarine: "66cdaa";
mediumblue: "0000cd";
mediumorchid: "ba55d3";
mediumpurple: "9370db";
mediumseagreen: "3cb371";
mediumslateblue: "7b68ee";
mediumspringgreen: "00fa9a";
mediumturquoise: "48d1cc";
mediumvioletred: "c71585";
midnightblue: "191970";
mintcream: "f5fffa";
mistyrose: "ffe4e1";
moccasin: "ffe4b5";
navajowhite: "ffdead";
navy: "000080";
oldlace: "fdf5e6";
olive: "808000";
olivedrab: "6b8e23";
orange: "ffa500";
orangered: "ff4500";
orchid: "da70d6";
palegoldenrod: "eee8aa";
palegreen: "98fb98";
paleturquoise: "afeeee";
palevioletred: "db7093";
papayawhip: "ffefd5";
peachpuff: "ffdab9";
peru: "cd853f";
pink: "ffc0cb";
plum: "dda0dd";
powderblue: "b0e0e6";
purple: "800080";
rebeccapurple: "663399";
red: "f00";
rosybrown: "bc8f8f";
royalblue: "4169e1";
saddlebrown: "8b4513";
salmon: "fa8072";
sandybrown: "f4a460";
seagreen: "2e8b57";
seashell: "fff5ee";
sienna: "a0522d";
silver: "c0c0c0";
skyblue: "87ceeb";
slateblue: "6a5acd";
slategray: "708090";
slategrey: "708090";
snow: "fffafa";
springgreen: "00ff7f";
steelblue: "4682b4";
tan: "d2b48c";
teal: "008080";
thistle: "d8bfd8";
tomato: "ff6347";
turquoise: "40e0d0";
violet: "ee82ee";
wheat: "f5deb3";
white: "fff";
whitesmoke: "f5f5f5";
yellow: "ff0";
yellowgreen: "9acd32";
};
/**
* key: hex value
* value: string name ex. hexnames["f00"] --> "red"
*/
hexNames: {
"f0f8ff": "aliceblue";
"faebd7": "antiquewhite";
"0ff": "aqua" | "cyan";
"7fffd4": "aquamarine";
"f0ffff": "azure";
"f5f5dc": "beige";
"ffe4c4": "bisque";
"000": "black";
"ffebcd": "blanchedalmond";
"00f": "blue";
"8a2be2": "blueviolet";
"a52a2a": "brown";
"deb887": "burlywood";
"ea7e5d": "burntsienna";
"5f9ea0": "cadetblue";
"7fff00": "chartreuse";
"d2691e": "chocolate";
"ff7f50": "coral";
"6495ed": "cornflowerblue";
"fff8dc": "cornsilk";
"dc143c": "crimson";
"00008b": "darkblue";
"008b8b": "darkcyan";
"b8860b": "darkgoldenrod";
"a9a9a9": "darkgray" | "darkgrey";
"006400": "darkgreen";
"bdb76b": "darkkhaki";
"8b008b": "darkmagenta";
"556b2f": "darkolivegreen";
"ff8c00": "darkorange";
"9932cc": "darkorchid";
"8b0000": "darkred";
"e9967a": "darksalmon";
"8fbc8f": "darkseagreen";
"483d8b": "darkslateblue";
"2f4f4f": "darkslategray" | "darkslategrey";
"00ced1": "darkturquoise";
"9400d3": "darkviolet";
"ff1493": "deeppink";
"00bfff": "deepskyblue";
"696969": "dimgray" | "dimgrey";
"1e90ff": "dodgerblue";
"b22222": "firebrick";
"fffaf0": "floralwhite";
"228b22": "forestgreen";
"f0f": "fuchsia" | "magenta";
"dcdcdc": "gainsboro";
"f8f8ff": "ghostwhite";
"ffd700": "gold";
"daa520": "goldenrod";
"808080": "gray" | "grey";
"008000": "green";
"adff2f": "greenyellow";
"f0fff0": "honeydew";
"ff69b4": "hotpink";
"cd5c5c": "indianred";
"4b0082": "indigo";
"fffff0": "ivory";
"f0e68c": "khaki";
"e6e6fa": "lavender";
"fff0f5": "lavenderblush";
"7cfc00": "lawngreen";
"fffacd": "lemonchiffon";
"add8e6": "lightblue";
"f08080": "lightcoral";
"e0ffff": "lightcyan";
"fafad2": "lightgoldenrodyellow";
"d3d3d3": "lightgray" | "lightgrey";
"90ee90": "lightgreen";
"ffb6c1": "lightpink";
"ffa07a": "lightsalmon";
"20b2aa": "lightseagreen";
"87cefa": "lightskyblue";
"789": "lightslategray" | "lightslategrey";
"b0c4de": "lightsteelblue";
"ffffe0": "lightyellow";
"0f0": "lime";
"32cd32": "limegreen";
"faf0e6": "linen";
"800000": "maroon";
"66cdaa": "mediumaquamarine";
"0000cd": "mediumblue";
"ba55d3": "mediumorchid";
"9370db": "mediumpurple";
"3cb371": "mediumseagreen";
"7b68ee": "mediumslateblue";
"00fa9a": "mediumspringgreen";
"48d1cc": "mediumturquoise";
"c71585": "mediumvioletred";
"191970": "midnightblue";
"f5fffa": "mintcream";
"ffe4e1": "mistyrose";
"ffe4b5": "moccasin";
"ffdead": "navajowhite";
"000080": "navy";
"fdf5e6": "oldlace";
"808000": "olive";
"6b8e23": "olivedrab";
"ffa500": "orange";
"ff4500": "orangered";
"da70d6": "orchid";
"eee8aa": "palegoldenrod";
"98fb98": "palegreen";
"afeeee": "paleturquoise";
"db7093": "palevioletred";
"ffefd5": "papayawhip";
"ffdab9": "peachpuff";
"cd853f": "peru";
"ffc0cb": "pink";
"dda0dd": "plum";
"b0e0e6": "powderblue";
"800080": "purple";
"663399": "rebeccapurple";
"f00": "red";
"bc8f8f": "rosybrown";
"4169e1": "royalblue";
"8b4513": "saddlebrown";
"fa8072": "salmon";
"f4a460": "sandybrown";
"2e8b57": "seagreen";
"fff5ee": "seashell";
"a0522d": "sienna";
"c0c0c0": "silver";
"87ceeb": "skyblue";
"6a5acd": "slateblue";
"708090": "slategray" | "slategrey";
"fffafa": "snow";
"00ff7f": "springgreen";
"4682b4": "steelblue";
"d2b48c": "tan";
"008080": "teal";
"d8bfd8": "thistle";
"ff6347": "tomato";
"40e0d0": "turquoise";
"ee82ee": "violet";
"f5deb3": "wheat";
"fff": "white";
"f5f5f5": "whitesmoke";
"ff0": "yellow";
"9acd32": "yellowgreen";
};
}
interface Instance {
/**
* Return an indication whether the color's perceived brightness is dark.
*/
isDark(): boolean;
/**
* Return an indication whether the color's perceived brightness is light.
*/
isLight(): boolean;
/**
* Return an indication whether the color was successfully parsed.
*/
isValid(): boolean;
/**
* Returns the input passed into the constructer used to create the tinycolor instance.
*/
getOriginalInput(): ColorInput;
/**
* Returns the format used to create the tinycolor instance.
*/
getFormat(): string;
/**
* Returns the alpha value of the color
*/
getAlpha(): number;
/**
* Returns the perceived brightness of the color, from 0-255.
*/
getBrightness(): number;
/**
* Returns the perceived luminance of a color, from 0-1.
*/
getLuminance(): number;
/**
* Sets the alpha value on the current color.
*
* @param alpha - The new alpha value. The accepted range is 0-1.
*/
setAlpha(alpha: number): Instance;
/**
* Returns the object as a HSVA object.
*/
toHsv(): ColorFormats.HSVA;
/**
* Returns the hsva values interpolated into a string with the following format:
* "hsva(xxx, xxx, xxx, xx)".
*/
toHsvString(): string;
/**
* Returns the object as a HSLA object.
*/
toHsl(): ColorFormats.HSLA;
/**
* Returns the hsla values interpolated into a string with the following format:
* "hsla(xxx, xxx, xxx, xx)".
*/
toHslString(): string;
/**
* Returns the hex value of the color.
*/
toHex(): string;
/**
* Returns the hex value of the color -with a # appened.
*/
toHexString(): string;
/**
* Returns the hex 8 value of the color.
*/
toHex8(): string;
/**
* Returns the hex 8 value of the color -with a # appened.
*/
toHex8String(): string;
/**
* Returns the object as a RGBA object.
*/
toRgb(): ColorFormats.RGBA;
/**
* Returns the RGBA values interpolated into a string with the following format:
* "RGBA(xxx, xxx, xxx, xx)".
*/
toRgbString(): string;
/**
* Returns the object as a RGBA object.
*/
toPercentageRgb(): ColorFormats.PRGBA;
/**
* Returns the RGBA relative values interpolated into a string with the following format:
* "RGBA(xxx, xxx, xxx, xx)".
*/
toPercentageRgbString(): string;
/**
* The 'real' name of the color -if there is one.
*/
toName(): string | false;
/**
* Returns the color represented as a Microsoft filter for use in old versions of IE.
*/
toFilter(): string;
/**
* String representation of the color.
*
* @param format - The format to be used when displaying the string representation.
* The accepted values are: "rgb", "prgb", "hex6", "hex3", "hex8", "name", "hsl", "hsv".
*/
toString(format?: "rgb" | "prgb" | "hex" | "hex6" | "hex3" | "hex4" | "hex8" | "name" | "hsl" | "hsv"): string;
/**
* Gets a new instance with the current color
*/
clone(): Instance;
/**
* Lighten the color a given amount. Providing 100 will always return white.
*
* @param amount - The amount to lighten by. The valid range is 0 to 100.
* Default value: 10.
*/
lighten(amount?: number): Instance;
/**
* Brighten the color a given amount.
*
* @param amount - The amount to brighten by. The valid range is 0 to 100.
* Default value: 10.
*/
brighten(amount?: number): Instance;
/**
* Darken the color a given amount.
* Providing 100 will always return black.
*
* @param amount - The amount to darken by. The valid range is 0 to 100.
* Default value: 10.
*/
darken(amount?: number): Instance;
/**
* Desaturate the color a given amount.
* Providing 100 will is the same as calling greyscale.
*
* @param amount - The amount to desaturate by. The valid range is 0 to 100.
* Default value: 10.
*/
desaturate(amount?: number): Instance;
/**
* Saturate the color a given amount.
*
* @param amount - The amount to saturate by. The valid range is 0 to 100.
* Default value: 10.
*/
saturate(amount?: number): Instance;
/**
* Completely desaturates a color into greyscale.
* Same as calling desaturate(100).
*/
greyscale(): Instance;
/**
* Spin the hue a given amount. Calling with 0, 360, or -360 will do nothing.
*
* @param amount - The amount to spin by. The valid range is -360 to 360.
*/
spin(amount: number): Instance;
/**
* Gets an analogous color scheme based off of the current color.
*
* @param results - The amount of results to return.
* Default value: 6.
* @param slices - The amount to slice the input color by.
* Default value: 30.
*/
analogous(results?: number, slices?: number): Instance[];
/**
* Gets the complement of the current color
*/
complement(): Instance;
/**
* Gets a monochromatic color scheme based off of the current color.
*
* @param results - The amount of results to return.
* Default value: 6.
*/
monochromatic(results?: number): Instance[];
/**
* Gets a split complement color scheme based off of the current color.
*/
splitcomplement(): [Instance, Instance, Instance];
/**
* Gets a triad based off of the current color.
*/
triad(): [Instance, Instance, Instance];
/**
* Gets a tetrad based off of the current color.
*/
tetrad(): [Instance, Instance, Instance, Instance];
}
}
declare const tinycolor: tinycolor.Constructor;
export = tinycolor;
export as namespace tinycolor;

View File

@ -0,0 +1,35 @@
{
"name": "@types/tinycolor2",
"version": "1.4.6",
"description": "TypeScript definitions for tinycolor2",
"homepage": "https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/tinycolor2",
"license": "MIT",
"contributors": [
{
"name": "Mordechai Zuber",
"githubUsername": "M-Zuber",
"url": "https://github.com/M-Zuber"
},
{
"name": "Geert Jansen",
"githubUsername": "geertjansen",
"url": "https://github.com/geertjansen"
},
{
"name": "Niels van Hoorn",
"githubUsername": "nvh",
"url": "https://github.com/nvh"
}
],
"main": "",
"types": "index.d.ts",
"repository": {
"type": "git",
"url": "https://github.com/DefinitelyTyped/DefinitelyTyped.git",
"directory": "types/tinycolor2"
},
"scripts": {},
"dependencies": {},
"typesPublisherContentHash": "c26276aefe032ca2f9187a5df23f239a447b4191d50a1417e8b9c916a20f29c0",
"typeScriptVersion": "4.5"
}

View File

@ -0,0 +1,292 @@
// From https://github.com/sindresorhus/type-fest
type Primitive =
| null // eslint-disable-line @typescript-eslint/ban-types
| undefined
| string
| number
| boolean
| symbol
| bigint;
type LiteralUnion<LiteralType, BaseType extends Primitive> =
| LiteralType
| (BaseType & Record<never, never>);
// -
export type ImageOptions = {
/**
The width is given as a number followed by a unit, or the word `'auto'`.
- `N`: N character cells.
- `Npx`: N pixels.
- `N%`: N percent of the session's width or height.
- `auto`: The image's inherent size will be used to determine an appropriate dimension.
*/
readonly width?: LiteralUnion<'auto', number | string>;
/**
The height is given as a number followed by a unit, or the word `'auto'`.
- `N`: N character cells.
- `Npx`: N pixels.
- `N%`: N percent of the session's width or height.
- `auto`: The image's inherent size will be used to determine an appropriate dimension.
*/
readonly height?: LiteralUnion<'auto', number | string>;
/**
@default true
*/
readonly preserveAspectRatio?: boolean;
};
export type AnnotationOptions = {
/**
Nonzero number of columns to annotate.
Default: The remainder of the line.
*/
readonly length?: number;
/**
Starting X coordinate.
Must be used with `y` and `length`.
Default: The cursor position
*/
readonly x?: number;
/**
Starting Y coordinate.
Must be used with `x` and `length`.
Default: Cursor position.
*/
readonly y?: number;
/**
Create a "hidden" annotation.
Annotations created this way can be shown using the "Show Annotations" iTerm command.
*/
readonly isHidden?: boolean;
};
/**
Set the absolute position of the cursor. `x0` `y0` is the top left of the screen.
*/
export function cursorTo(x: number, y?: number): string;
/**
Set the position of the cursor relative to its current position.
*/
export function cursorMove(x: number, y?: number): string;
/**
Move cursor up a specific amount of rows.
@param count - Count of rows to move up. Default is `1`.
*/
export function cursorUp(count?: number): string;
/**
Move cursor down a specific amount of rows.
@param count - Count of rows to move down. Default is `1`.
*/
export function cursorDown(count?: number): string;
/**
Move cursor forward a specific amount of rows.
@param count - Count of rows to move forward. Default is `1`.
*/
export function cursorForward(count?: number): string;
/**
Move cursor backward a specific amount of rows.
@param count - Count of rows to move backward. Default is `1`.
*/
export function cursorBackward(count?: number): string;
/**
Move cursor to the left side.
*/
export const cursorLeft: string;
/**
Save cursor position.
*/
export const cursorSavePosition: string;
/**
Restore saved cursor position.
*/
export const cursorRestorePosition: string;
/**
Get cursor position.
*/
export const cursorGetPosition: string;
/**
Move cursor to the next line.
*/
export const cursorNextLine: string;
/**
Move cursor to the previous line.
*/
export const cursorPrevLine: string;
/**
Hide cursor.
*/
export const cursorHide: string;
/**
Show cursor.
*/
export const cursorShow: string;
/**
Erase from the current cursor position up the specified amount of rows.
@param count - Count of rows to erase.
*/
export function eraseLines(count: number): string;
/**
Erase from the current cursor position to the end of the current line.
*/
export const eraseEndLine: string;
/**
Erase from the current cursor position to the start of the current line.
*/
export const eraseStartLine: string;
/**
Erase the entire current line.
*/
export const eraseLine: string;
/**
Erase the screen from the current line down to the bottom of the screen.
*/
export const eraseDown: string;
/**
Erase the screen from the current line up to the top of the screen.
*/
export const eraseUp: string;
/**
Erase the screen and move the cursor the top left position.
*/
export const eraseScreen: string;
/**
Scroll display up one line.
*/
export const scrollUp: string;
/**
Scroll display down one line.
*/
export const scrollDown: string;
/**
Clear only the visible terminal screen (viewport) without affecting scrollback buffer or terminal state.
This is a safer alternative to `clearScreen` that works consistently across terminals.
*/
export const clearViewport: string;
/**
Clear the terminal screen.
**Warning:** Uses RIS (Reset to Initial State) which may also:
- Clear scrollback buffer in some terminals (xterm.js, VTE)
- Reset terminal modes and state
- Not behave consistently across different terminals
Consider using `clearViewport` for safer viewport-only clearing.
*/
export const clearScreen: string;
/**
Clear the whole terminal, including scrollback buffer. (Not just the visible part of it)
*/
export const clearTerminal: string;
/**
Enter the [alternative screen](https://terminalguide.namepad.de/mode/p47/).
*/
export const enterAlternativeScreen: string;
/**
Exit the [alternative screen](https://terminalguide.namepad.de/mode/p47/), assuming `enterAlternativeScreen` was called before.
*/
export const exitAlternativeScreen: string;
/**
Output a beeping sound.
*/
export const beep: string;
/**
Create a clickable link.
[Supported terminals.](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda) Use [`supports-hyperlinks`](https://github.com/jamestalmage/supports-hyperlinks) to detect link support.
*/
export function link(text: string, url: string): string;
/**
Display an image.
See [term-img](https://github.com/sindresorhus/term-img) for a higher-level module.
@param data - Image data. Usually read in with `fs.readFile()`.
*/
export function image(data: Uint8Array, options?: ImageOptions): string;
export const iTerm: {
/**
[Inform iTerm2](https://www.iterm2.com/documentation-escape-codes.html) of the current directory to help semantic history and enable [Cmd-clicking relative paths](https://coderwall.com/p/b7e82q/quickly-open-files-in-iterm-with-cmd-click).
@param cwd - Current directory. Default: `process.cwd()`.
*/
setCwd(cwd?: string): string,
/**
An annotation looks like this when shown:
![screenshot of iTerm annotation](https://user-images.githubusercontent.com/924465/64382136-b60ac700-cfe9-11e9-8a35-9682e8dc4b72.png)
See the [iTerm Proprietary Escape Codes documentation](https://iterm2.com/documentation-escape-codes.html) for more information.
@param message - The message to display within the annotation. The `|` character is disallowed and will be stripped.
@returns An escape code which will create an annotation when printed in iTerm2.
*/
annotation(message: string, options?: AnnotationOptions): string
};
export const ConEmu: {
/**
[Inform ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC) about shell current working directory.
@param cwd - Current directory. Default: `process.cwd()`.
*/
setCwd(cwd?: string): string
};
/**
Set the current working directory for both iTerm2 and ConEmu.
@param cwd - Current directory. Default: `process.cwd()`.
*/
export function setCwd(cwd?: string): string;

View File

@ -0,0 +1,171 @@
import process from 'node:process';
import {isBrowser} from 'environment';
const ESC = '\u001B[';
const OSC = '\u001B]';
const BEL = '\u0007';
const SEP = ';';
const isTerminalApp = !isBrowser && process.env.TERM_PROGRAM === 'Apple_Terminal';
const isWindows = !isBrowser && process.platform === 'win32';
const cwdFunction = isBrowser ? () => {
throw new Error('`process.cwd()` only works in Node.js, not the browser.');
} : process.cwd;
export const cursorTo = (x, y) => {
if (typeof x !== 'number') {
throw new TypeError('The `x` argument is required');
}
if (typeof y !== 'number') {
return ESC + (x + 1) + 'G';
}
return ESC + (y + 1) + SEP + (x + 1) + 'H';
};
export const cursorMove = (x, y) => {
if (typeof x !== 'number') {
throw new TypeError('The `x` argument is required');
}
let returnValue = '';
if (x < 0) {
returnValue += ESC + (-x) + 'D';
} else if (x > 0) {
returnValue += ESC + x + 'C';
}
if (y < 0) {
returnValue += ESC + (-y) + 'A';
} else if (y > 0) {
returnValue += ESC + y + 'B';
}
return returnValue;
};
export const cursorUp = (count = 1) => ESC + count + 'A';
export const cursorDown = (count = 1) => ESC + count + 'B';
export const cursorForward = (count = 1) => ESC + count + 'C';
export const cursorBackward = (count = 1) => ESC + count + 'D';
export const cursorLeft = ESC + 'G';
export const cursorSavePosition = isTerminalApp ? '\u001B7' : ESC + 's';
export const cursorRestorePosition = isTerminalApp ? '\u001B8' : ESC + 'u';
export const cursorGetPosition = ESC + '6n';
export const cursorNextLine = ESC + 'E';
export const cursorPrevLine = ESC + 'F';
export const cursorHide = ESC + '?25l';
export const cursorShow = ESC + '?25h';
export const eraseLines = count => {
let clear = '';
for (let i = 0; i < count; i++) {
clear += eraseLine + (i < count - 1 ? cursorUp() : '');
}
if (count) {
clear += cursorLeft;
}
return clear;
};
export const eraseEndLine = ESC + 'K';
export const eraseStartLine = ESC + '1K';
export const eraseLine = ESC + '2K';
export const eraseDown = ESC + 'J';
export const eraseUp = ESC + '1J';
export const eraseScreen = ESC + '2J';
export const scrollUp = ESC + 'S';
export const scrollDown = ESC + 'T';
export const clearScreen = '\u001Bc';
export const clearViewport = `${eraseScreen}${ESC}H`;
export const clearTerminal = isWindows
? `${eraseScreen}${ESC}0f`
// 1. Erases the screen (Only done in case `2` is not supported)
// 2. Erases the whole screen including scrollback buffer
// 3. Moves cursor to the top-left position
// More info: https://www.real-world-systems.com/docs/ANSIcode.html
: `${eraseScreen}${ESC}3J${ESC}H`;
export const enterAlternativeScreen = ESC + '?1049h';
export const exitAlternativeScreen = ESC + '?1049l';
export const beep = BEL;
export const link = (text, url) => [
OSC,
'8',
SEP,
SEP,
url,
BEL,
text,
OSC,
'8',
SEP,
SEP,
BEL,
].join('');
export const image = (data, options = {}) => {
let returnValue = `${OSC}1337;File=inline=1`;
if (options.width) {
returnValue += `;width=${options.width}`;
}
if (options.height) {
returnValue += `;height=${options.height}`;
}
if (options.preserveAspectRatio === false) {
returnValue += ';preserveAspectRatio=0';
}
return returnValue + ':' + Buffer.from(data).toString('base64') + BEL;
};
export const iTerm = {
setCwd: (cwd = cwdFunction()) => `${OSC}50;CurrentDir=${cwd}${BEL}`,
annotation(message, options = {}) {
let returnValue = `${OSC}1337;`;
const hasX = options.x !== undefined;
const hasY = options.y !== undefined;
if ((hasX || hasY) && !(hasX && hasY && options.length !== undefined)) {
throw new Error('`x`, `y` and `length` must be defined when `x` or `y` is defined');
}
message = message.replaceAll('|', '');
returnValue += options.isHidden ? 'AddHiddenAnnotation=' : 'AddAnnotation=';
if (options.length > 0) {
returnValue += (
hasX
? [message, options.length, options.x, options.y]
: [options.length, message]
).join('|');
} else {
returnValue += message;
}
return returnValue + BEL;
},
};
export const ConEmu = {
setCwd: (cwd = cwdFunction()) => `${OSC}9;9;${cwd}${BEL}`,
};
export const setCwd = (cwd = cwdFunction()) => iTerm.setCwd(cwd) + ConEmu.setCwd(cwd);

View File

@ -0,0 +1,2 @@
export * from './base.js';
export * as default from './base.js';

View File

@ -0,0 +1,2 @@
export * from './base.js';
export * as default from './base.js';

View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,70 @@
{
"name": "ansi-escapes",
"version": "7.1.0",
"description": "ANSI escape codes for manipulating the terminal",
"license": "MIT",
"repository": "sindresorhus/ansi-escapes",
"funding": "https://github.com/sponsors/sindresorhus",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": {
"types": "./index.d.ts",
"default": "./index.js"
},
"sideEffects": false,
"engines": {
"node": ">=18"
},
"scripts": {
"test": "ava && tsd",
"//test": "xo && ava && tsd"
},
"files": [
"index.js",
"index.d.ts",
"base.js",
"base.d.ts"
],
"keywords": [
"ansi",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"escapes",
"formatting",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text",
"vt100",
"sequence",
"control",
"code",
"codes",
"cursor",
"iterm",
"iterm2",
"clear",
"screen",
"erase",
"scrollback"
],
"dependencies": {
"environment": "^1.0.0"
},
"devDependencies": {
"@types/node": "20.12.8",
"ava": "^6.1.2",
"tsd": "0.31.0",
"xo": "^0.58.0"
}
}

View File

@ -0,0 +1,284 @@
# ansi-escapes
> [ANSI escape codes](https://www2.ccs.neu.edu/research/gpc/VonaUtils/vona/terminal/vtansi.htm) for manipulating the terminal
## Install
```sh
npm install ansi-escapes
```
## Usage
```js
import ansiEscapes from 'ansi-escapes';
// Moves the cursor two rows up and to the left
process.stdout.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft);
//=> '\u001B[2A\u001B[1000D'
```
Or use named exports...
```js
import {cursorUp, cursorLeft} from 'ansi-escapes';
// etc, as above...
```
**You can also use it in the browser with Xterm.js:**
```js
import ansiEscapes from 'ansi-escapes';
import {Terminal} from 'xterm';
import 'xterm/css/xterm.css';
const terminal = new Terminal({…});
// Moves the cursor two rows up and to the left
terminal.write(ansiEscapes.cursorUp(2) + ansiEscapes.cursorLeft);
//=> '\u001B[2A\u001B[1000D'
```
## API
### cursorTo(x, y?)
Set the absolute position of the cursor. `x0` `y0` is the top left of the screen.
### cursorMove(x, y?)
Set the position of the cursor relative to its current position.
### cursorUp(count)
Move cursor up a specific amount of rows. Default is `1`.
### cursorDown(count)
Move cursor down a specific amount of rows. Default is `1`.
### cursorForward(count)
Move cursor forward a specific amount of columns. Default is `1`.
### cursorBackward(count)
Move cursor backward a specific amount of columns. Default is `1`.
### cursorLeft
Move cursor to the left side.
### cursorSavePosition
Save cursor position.
### cursorRestorePosition
Restore saved cursor position.
### cursorGetPosition
Get cursor position.
### cursorNextLine
Move cursor to the next line.
### cursorPrevLine
Move cursor to the previous line.
### cursorHide
Hide cursor.
### cursorShow
Show cursor.
### eraseLines(count)
Erase from the current cursor position up the specified amount of rows.
### eraseEndLine
Erase from the current cursor position to the end of the current line.
### eraseStartLine
Erase from the current cursor position to the start of the current line.
### eraseLine
Erase the entire current line.
### eraseDown
Erase the screen from the current line down to the bottom of the screen.
### eraseUp
Erase the screen from the current line up to the top of the screen.
### eraseScreen
Erase the screen and move the cursor the top left position.
### scrollUp
Scroll display up one line.
### scrollDown
Scroll display down one line.
### clearViewport
Clear only the visible terminal screen (viewport) without affecting scrollback buffer or terminal state.
This is a safer alternative to `clearScreen` that works consistently across terminals.
### clearScreen
Clear the terminal screen.
> [!WARNING]
> This uses RIS (Reset to Initial State) which may also clear scrollback buffer in some terminals (xterm.js, VTE) and reset terminal modes. Consider using `clearViewport()` for safer viewport-only clearing.
### clearTerminal
Clear the whole terminal, including scrollback buffer. (Not just the visible part of it)
### enterAlternativeScreen
Enter the [alternative screen](https://terminalguide.namepad.de/mode/p47/).
### exitAlternativeScreen
Exit the [alternative screen](https://terminalguide.namepad.de/mode/p47/), assuming `enterAlternativeScreen` was called before.
### beep
Output a beeping sound.
### link(text, url)
Create a clickable link.
[Supported terminals.](https://gist.github.com/egmontkob/eb114294efbcd5adb1944c9f3cb5feda) Use [`supports-hyperlinks`](https://github.com/jamestalmage/supports-hyperlinks) to detect link support.
### image(filePath, options?)
Display an image.
See [term-img](https://github.com/sindresorhus/term-img) for a higher-level module.
#### input
Type: `Buffer`
Buffer of an image. Usually read in with `fs.readFile()`.
#### options
Type: `object`
##### width
##### height
Type: `string | number`
The width and height are given as a number followed by a unit, or the word "auto".
- `N`: N character cells.
- `Npx`: N pixels.
- `N%`: N percent of the session's width or height.
- `auto`: The image's inherent size will be used to determine an appropriate dimension.
##### preserveAspectRatio
Type: `boolean`\
Default: `true`
### setCwd(path?)
Type: `string`\
Default: `process.cwd()`
Set the current working directory for both iTerm2 and ConEmu.
### iTerm.setCwd(path?)
Type: `string`\
Default: `process.cwd()`
[Inform iTerm2](https://www.iterm2.com/documentation-escape-codes.html) of the current directory to help semantic history and enable [Cmd-clicking relative paths](https://coderwall.com/p/b7e82q/quickly-open-files-in-iterm-with-cmd-click).
### ConEmu.setCwd(path?)
Type: `string`\
Default: `process.cwd()`
[Inform ConEmu](https://conemu.github.io/en/AnsiEscapeCodes.html#ConEmu_specific_OSC) about shell current working directory.
### iTerm.annotation(message, options?)
Creates an escape code to display an "annotation" in iTerm2.
An annotation looks like this when shown:
<img src="https://user-images.githubusercontent.com/924465/64382136-b60ac700-cfe9-11e9-8a35-9682e8dc4b72.png" width="500">
See the [iTerm Proprietary Escape Codes documentation](https://iterm2.com/documentation-escape-codes.html) for more information.
#### message
Type: `string`
The message to display within the annotation.
The `|` character is disallowed and will be stripped.
#### options
Type: `object`
##### length
Type: `number`\
Default: The remainder of the line
Nonzero number of columns to annotate.
##### x
Type: `number`\
Default: Cursor position
Starting X coordinate.
Must be used with `y` and `length`.
##### y
Type: `number`\
Default: Cursor position
Starting Y coordinate.
Must be used with `x` and `length`.
##### isHidden
Type: `boolean`\
Default: `false`
Create a "hidden" annotation.
Annotations created this way can be shown using the "Show Annotations" iTerm command.
## Related
- [ansi-styles](https://github.com/chalk/ansi-styles) - ANSI escape codes for styling strings in the terminal

View File

@ -0,0 +1,33 @@
export type Options = {
/**
Match only the first ANSI escape.
@default false
*/
readonly onlyFirst: boolean;
};
/**
Regular expression for matching ANSI escape codes.
@example
```
import ansiRegex from 'ansi-regex';
ansiRegex().test('\u001B[4mcake\u001B[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001B[4mcake\u001B[0m'.match(ansiRegex());
//=> ['\u001B[4m', '\u001B[0m']
'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true}));
//=> ['\u001B[4m']
'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex());
//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007']
```
*/
export default function ansiRegex(options?: Options): RegExp;

View File

@ -0,0 +1,14 @@
export default function ansiRegex({onlyFirst = false} = {}) {
// Valid string terminator sequences are BEL, ESC\, and 0x9c
const ST = '(?:\\u0007|\\u001B\\u005C|\\u009C)';
// OSC sequences only: ESC ] ... ST (non-greedy until the first ST)
const osc = `(?:\\u001B\\][\\s\\S]*?${ST})`;
// CSI and related: ESC/C1, optional intermediates, optional params (supports ; and :) then final byte
const csi = '[\\u001B\\u009B][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]';
const pattern = `${osc}|${csi}`;
return new RegExp(pattern, onlyFirst ? undefined : 'g');
}

View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (https://sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,61 @@
{
"name": "ansi-regex",
"version": "6.2.2",
"description": "Regular expression for matching ANSI escape codes",
"license": "MIT",
"repository": "chalk/ansi-regex",
"funding": "https://github.com/chalk/ansi-regex?sponsor=1",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "https://sindresorhus.com"
},
"type": "module",
"exports": "./index.js",
"types": "./index.d.ts",
"sideEffects": false,
"engines": {
"node": ">=12"
},
"scripts": {
"test": "xo && ava && tsd",
"view-supported": "node fixtures/view-codes.js"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"command-line",
"text",
"regex",
"regexp",
"re",
"match",
"test",
"find",
"pattern"
],
"devDependencies": {
"ansi-escapes": "^5.0.0",
"ava": "^3.15.0",
"tsd": "^0.21.0",
"xo": "^0.54.2"
}
}

View File

@ -0,0 +1,66 @@
# ansi-regex
> Regular expression for matching [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code)
## Install
```sh
npm install ansi-regex
```
## Usage
```js
import ansiRegex from 'ansi-regex';
ansiRegex().test('\u001B[4mcake\u001B[0m');
//=> true
ansiRegex().test('cake');
//=> false
'\u001B[4mcake\u001B[0m'.match(ansiRegex());
//=> ['\u001B[4m', '\u001B[0m']
'\u001B[4mcake\u001B[0m'.match(ansiRegex({onlyFirst: true}));
//=> ['\u001B[4m']
'\u001B]8;;https://github.com\u0007click\u001B]8;;\u0007'.match(ansiRegex());
//=> ['\u001B]8;;https://github.com\u0007', '\u001B]8;;\u0007']
```
## API
### ansiRegex(options?)
Returns a regex for matching ANSI escape codes.
#### options
Type: `object`
##### onlyFirst
Type: `boolean`\
Default: `false` *(Matches any ANSI escape codes in a string)*
Match only the first ANSI escape.
## Important
If you run the regex against untrusted user input in a server context, you should [give it a timeout](https://github.com/sindresorhus/super-regex).
**I do not consider [ReDoS](https://blog.yossarian.net/2022/12/28/ReDoS-vulnerabilities-and-misaligned-incentives) a valid vulnerability for this package.**
## FAQ
### Why do you test for codes not in the ECMA 48 standard?
Some of the codes we run as a test are codes that we acquired finding various lists of non-standard or manufacturer specific codes. We test for both standard and non-standard codes, as most of them follow the same or similar format and can be safely matched in strings without the risk of removing actual string content. There are a few non-standard control codes that do not follow the traditional format (i.e. they end in numbers) thus forcing us to exclude them from the test because we cannot reliably match them.
On the historical side, those ECMA standards were established in the early 90's whereas the VT100, for example, was designed in the mid/late 70's. At that point in time, control codes were still pretty ungoverned and engineers used them for a multitude of things, namely to activate hardware ports that may have been proprietary. Somewhere else you see a similar 'anarchy' of codes is in the x86 architecture for processors; there are a ton of "interrupts" that can mean different things on certain brands of processors, most of which have been phased out.
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)

View File

@ -0,0 +1,345 @@
declare type CSSColor =
| 'aliceblue'
| 'antiquewhite'
| 'aqua'
| 'aquamarine'
| 'azure'
| 'beige'
| 'bisque'
| 'black'
| 'blanchedalmond'
| 'blue'
| 'blueviolet'
| 'brown'
| 'burlywood'
| 'cadetblue'
| 'chartreuse'
| 'chocolate'
| 'coral'
| 'cornflowerblue'
| 'cornsilk'
| 'crimson'
| 'cyan'
| 'darkblue'
| 'darkcyan'
| 'darkgoldenrod'
| 'darkgray'
| 'darkgreen'
| 'darkgrey'
| 'darkkhaki'
| 'darkmagenta'
| 'darkolivegreen'
| 'darkorange'
| 'darkorchid'
| 'darkred'
| 'darksalmon'
| 'darkseagreen'
| 'darkslateblue'
| 'darkslategray'
| 'darkslategrey'
| 'darkturquoise'
| 'darkviolet'
| 'deeppink'
| 'deepskyblue'
| 'dimgray'
| 'dimgrey'
| 'dodgerblue'
| 'firebrick'
| 'floralwhite'
| 'forestgreen'
| 'fuchsia'
| 'gainsboro'
| 'ghostwhite'
| 'gold'
| 'goldenrod'
| 'gray'
| 'green'
| 'greenyellow'
| 'grey'
| 'honeydew'
| 'hotpink'
| 'indianred'
| 'indigo'
| 'ivory'
| 'khaki'
| 'lavender'
| 'lavenderblush'
| 'lawngreen'
| 'lemonchiffon'
| 'lightblue'
| 'lightcoral'
| 'lightcyan'
| 'lightgoldenrodyellow'
| 'lightgray'
| 'lightgreen'
| 'lightgrey'
| 'lightpink'
| 'lightsalmon'
| 'lightseagreen'
| 'lightskyblue'
| 'lightslategray'
| 'lightslategrey'
| 'lightsteelblue'
| 'lightyellow'
| 'lime'
| 'limegreen'
| 'linen'
| 'magenta'
| 'maroon'
| 'mediumaquamarine'
| 'mediumblue'
| 'mediumorchid'
| 'mediumpurple'
| 'mediumseagreen'
| 'mediumslateblue'
| 'mediumspringgreen'
| 'mediumturquoise'
| 'mediumvioletred'
| 'midnightblue'
| 'mintcream'
| 'mistyrose'
| 'moccasin'
| 'navajowhite'
| 'navy'
| 'oldlace'
| 'olive'
| 'olivedrab'
| 'orange'
| 'orangered'
| 'orchid'
| 'palegoldenrod'
| 'palegreen'
| 'paleturquoise'
| 'palevioletred'
| 'papayawhip'
| 'peachpuff'
| 'peru'
| 'pink'
| 'plum'
| 'powderblue'
| 'purple'
| 'rebeccapurple'
| 'red'
| 'rosybrown'
| 'royalblue'
| 'saddlebrown'
| 'salmon'
| 'sandybrown'
| 'seagreen'
| 'seashell'
| 'sienna'
| 'silver'
| 'skyblue'
| 'slateblue'
| 'slategray'
| 'slategrey'
| 'snow'
| 'springgreen'
| 'steelblue'
| 'tan'
| 'teal'
| 'thistle'
| 'tomato'
| 'turquoise'
| 'violet'
| 'wheat'
| 'white'
| 'whitesmoke'
| 'yellow'
| 'yellowgreen';
declare namespace ansiStyles {
interface ColorConvert {
/**
The RGB color space.
@param red - (`0`-`255`)
@param green - (`0`-`255`)
@param blue - (`0`-`255`)
*/
rgb(red: number, green: number, blue: number): string;
/**
The RGB HEX color space.
@param hex - A hexadecimal string containing RGB data.
*/
hex(hex: string): string;
/**
@param keyword - A CSS color name.
*/
keyword(keyword: CSSColor): string;
/**
The HSL color space.
@param hue - (`0`-`360`)
@param saturation - (`0`-`100`)
@param lightness - (`0`-`100`)
*/
hsl(hue: number, saturation: number, lightness: number): string;
/**
The HSV color space.
@param hue - (`0`-`360`)
@param saturation - (`0`-`100`)
@param value - (`0`-`100`)
*/
hsv(hue: number, saturation: number, value: number): string;
/**
The HSV color space.
@param hue - (`0`-`360`)
@param whiteness - (`0`-`100`)
@param blackness - (`0`-`100`)
*/
hwb(hue: number, whiteness: number, blackness: number): string;
/**
Use a [4-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#3/4-bit) to set text color.
*/
ansi(ansi: number): string;
/**
Use an [8-bit unsigned number](https://en.wikipedia.org/wiki/ANSI_escape_code#8-bit) to set text color.
*/
ansi256(ansi: number): string;
}
interface CSPair {
/**
The ANSI terminal control sequence for starting this style.
*/
readonly open: string;
/**
The ANSI terminal control sequence for ending this style.
*/
readonly close: string;
}
interface ColorBase {
readonly ansi: ColorConvert;
readonly ansi256: ColorConvert;
readonly ansi16m: ColorConvert;
/**
The ANSI terminal control sequence for ending this color.
*/
readonly close: string;
}
interface Modifier {
/**
Resets the current color chain.
*/
readonly reset: CSPair;
/**
Make text bold.
*/
readonly bold: CSPair;
/**
Emitting only a small amount of light.
*/
readonly dim: CSPair;
/**
Make text italic. (Not widely supported)
*/
readonly italic: CSPair;
/**
Make text underline. (Not widely supported)
*/
readonly underline: CSPair;
/**
Inverse background and foreground colors.
*/
readonly inverse: CSPair;
/**
Prints the text, but makes it invisible.
*/
readonly hidden: CSPair;
/**
Puts a horizontal line through the center of the text. (Not widely supported)
*/
readonly strikethrough: CSPair;
}
interface ForegroundColor {
readonly black: CSPair;
readonly red: CSPair;
readonly green: CSPair;
readonly yellow: CSPair;
readonly blue: CSPair;
readonly cyan: CSPair;
readonly magenta: CSPair;
readonly white: CSPair;
/**
Alias for `blackBright`.
*/
readonly gray: CSPair;
/**
Alias for `blackBright`.
*/
readonly grey: CSPair;
readonly blackBright: CSPair;
readonly redBright: CSPair;
readonly greenBright: CSPair;
readonly yellowBright: CSPair;
readonly blueBright: CSPair;
readonly cyanBright: CSPair;
readonly magentaBright: CSPair;
readonly whiteBright: CSPair;
}
interface BackgroundColor {
readonly bgBlack: CSPair;
readonly bgRed: CSPair;
readonly bgGreen: CSPair;
readonly bgYellow: CSPair;
readonly bgBlue: CSPair;
readonly bgCyan: CSPair;
readonly bgMagenta: CSPair;
readonly bgWhite: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGray: CSPair;
/**
Alias for `bgBlackBright`.
*/
readonly bgGrey: CSPair;
readonly bgBlackBright: CSPair;
readonly bgRedBright: CSPair;
readonly bgGreenBright: CSPair;
readonly bgYellowBright: CSPair;
readonly bgBlueBright: CSPair;
readonly bgCyanBright: CSPair;
readonly bgMagentaBright: CSPair;
readonly bgWhiteBright: CSPair;
}
}
declare const ansiStyles: {
readonly modifier: ansiStyles.Modifier;
readonly color: ansiStyles.ForegroundColor & ansiStyles.ColorBase;
readonly bgColor: ansiStyles.BackgroundColor & ansiStyles.ColorBase;
readonly codes: ReadonlyMap<number, number>;
} & ansiStyles.BackgroundColor & ansiStyles.ForegroundColor & ansiStyles.Modifier;
export = ansiStyles;

View File

@ -0,0 +1,163 @@
'use strict';
const wrapAnsi16 = (fn, offset) => (...args) => {
const code = fn(...args);
return `\u001B[${code + offset}m`;
};
const wrapAnsi256 = (fn, offset) => (...args) => {
const code = fn(...args);
return `\u001B[${38 + offset};5;${code}m`;
};
const wrapAnsi16m = (fn, offset) => (...args) => {
const rgb = fn(...args);
return `\u001B[${38 + offset};2;${rgb[0]};${rgb[1]};${rgb[2]}m`;
};
const ansi2ansi = n => n;
const rgb2rgb = (r, g, b) => [r, g, b];
const setLazyProperty = (object, property, get) => {
Object.defineProperty(object, property, {
get: () => {
const value = get();
Object.defineProperty(object, property, {
value,
enumerable: true,
configurable: true
});
return value;
},
enumerable: true,
configurable: true
});
};
/** @type {typeof import('color-convert')} */
let colorConvert;
const makeDynamicStyles = (wrap, targetSpace, identity, isBackground) => {
if (colorConvert === undefined) {
colorConvert = require('color-convert');
}
const offset = isBackground ? 10 : 0;
const styles = {};
for (const [sourceSpace, suite] of Object.entries(colorConvert)) {
const name = sourceSpace === 'ansi16' ? 'ansi' : sourceSpace;
if (sourceSpace === targetSpace) {
styles[name] = wrap(identity, offset);
} else if (typeof suite === 'object') {
styles[name] = wrap(suite[targetSpace], offset);
}
}
return styles;
};
function assembleStyles() {
const codes = new Map();
const styles = {
modifier: {
reset: [0, 0],
// 21 isn't widely supported and 22 does the same thing
bold: [1, 22],
dim: [2, 22],
italic: [3, 23],
underline: [4, 24],
inverse: [7, 27],
hidden: [8, 28],
strikethrough: [9, 29]
},
color: {
black: [30, 39],
red: [31, 39],
green: [32, 39],
yellow: [33, 39],
blue: [34, 39],
magenta: [35, 39],
cyan: [36, 39],
white: [37, 39],
// Bright color
blackBright: [90, 39],
redBright: [91, 39],
greenBright: [92, 39],
yellowBright: [93, 39],
blueBright: [94, 39],
magentaBright: [95, 39],
cyanBright: [96, 39],
whiteBright: [97, 39]
},
bgColor: {
bgBlack: [40, 49],
bgRed: [41, 49],
bgGreen: [42, 49],
bgYellow: [43, 49],
bgBlue: [44, 49],
bgMagenta: [45, 49],
bgCyan: [46, 49],
bgWhite: [47, 49],
// Bright color
bgBlackBright: [100, 49],
bgRedBright: [101, 49],
bgGreenBright: [102, 49],
bgYellowBright: [103, 49],
bgBlueBright: [104, 49],
bgMagentaBright: [105, 49],
bgCyanBright: [106, 49],
bgWhiteBright: [107, 49]
}
};
// Alias bright black as gray (and grey)
styles.color.gray = styles.color.blackBright;
styles.bgColor.bgGray = styles.bgColor.bgBlackBright;
styles.color.grey = styles.color.blackBright;
styles.bgColor.bgGrey = styles.bgColor.bgBlackBright;
for (const [groupName, group] of Object.entries(styles)) {
for (const [styleName, style] of Object.entries(group)) {
styles[styleName] = {
open: `\u001B[${style[0]}m`,
close: `\u001B[${style[1]}m`
};
group[styleName] = styles[styleName];
codes.set(style[0], style[1]);
}
Object.defineProperty(styles, groupName, {
value: group,
enumerable: false
});
}
Object.defineProperty(styles, 'codes', {
value: codes,
enumerable: false
});
styles.color.close = '\u001B[39m';
styles.bgColor.close = '\u001B[49m';
setLazyProperty(styles.color, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, false));
setLazyProperty(styles.color, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, false));
setLazyProperty(styles.color, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, false));
setLazyProperty(styles.bgColor, 'ansi', () => makeDynamicStyles(wrapAnsi16, 'ansi16', ansi2ansi, true));
setLazyProperty(styles.bgColor, 'ansi256', () => makeDynamicStyles(wrapAnsi256, 'ansi256', ansi2ansi, true));
setLazyProperty(styles.bgColor, 'ansi16m', () => makeDynamicStyles(wrapAnsi16m, 'rgb', rgb2rgb, true));
return styles;
}
// Make the export immutable
Object.defineProperty(module, 'exports', {
enumerable: true,
get: assembleStyles
});

View File

@ -0,0 +1,9 @@
MIT License
Copyright (c) Sindre Sorhus <sindresorhus@gmail.com> (sindresorhus.com)
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

View File

@ -0,0 +1,56 @@
{
"name": "ansi-styles",
"version": "4.3.0",
"description": "ANSI escape codes for styling strings in the terminal",
"license": "MIT",
"repository": "chalk/ansi-styles",
"funding": "https://github.com/chalk/ansi-styles?sponsor=1",
"author": {
"name": "Sindre Sorhus",
"email": "sindresorhus@gmail.com",
"url": "sindresorhus.com"
},
"engines": {
"node": ">=8"
},
"scripts": {
"test": "xo && ava && tsd",
"screenshot": "svg-term --command='node screenshot' --out=screenshot.svg --padding=3 --width=55 --height=3 --at=1000 --no-cursor"
},
"files": [
"index.js",
"index.d.ts"
],
"keywords": [
"ansi",
"styles",
"color",
"colour",
"colors",
"terminal",
"console",
"cli",
"string",
"tty",
"escape",
"formatting",
"rgb",
"256",
"shell",
"xterm",
"log",
"logging",
"command-line",
"text"
],
"dependencies": {
"color-convert": "^2.0.1"
},
"devDependencies": {
"@types/color-convert": "^1.9.0",
"ava": "^2.3.0",
"svg-term-cli": "^2.1.1",
"tsd": "^0.11.0",
"xo": "^0.25.3"
}
}

View File

@ -0,0 +1,152 @@
# ansi-styles [![Build Status](https://travis-ci.org/chalk/ansi-styles.svg?branch=master)](https://travis-ci.org/chalk/ansi-styles)
> [ANSI escape codes](https://en.wikipedia.org/wiki/ANSI_escape_code#Colors_and_Styles) for styling strings in the terminal
You probably want the higher-level [chalk](https://github.com/chalk/chalk) module for styling your strings.
<img src="screenshot.svg" width="900">
## Install
```
$ npm install ansi-styles
```
## Usage
```js
const style = require('ansi-styles');
console.log(`${style.green.open}Hello world!${style.green.close}`);
// Color conversion between 16/256/truecolor
// NOTE: If conversion goes to 16 colors or 256 colors, the original color
// may be degraded to fit that color palette. This means terminals
// that do not support 16 million colors will best-match the
// original color.
console.log(style.bgColor.ansi.hsl(120, 80, 72) + 'Hello world!' + style.bgColor.close);
console.log(style.color.ansi256.rgb(199, 20, 250) + 'Hello world!' + style.color.close);
console.log(style.color.ansi16m.hex('#abcdef') + 'Hello world!' + style.color.close);
```
## API
Each style has an `open` and `close` property.
## Styles
### Modifiers
- `reset`
- `bold`
- `dim`
- `italic` *(Not widely supported)*
- `underline`
- `inverse`
- `hidden`
- `strikethrough` *(Not widely supported)*
### Colors
- `black`
- `red`
- `green`
- `yellow`
- `blue`
- `magenta`
- `cyan`
- `white`
- `blackBright` (alias: `gray`, `grey`)
- `redBright`
- `greenBright`
- `yellowBright`
- `blueBright`
- `magentaBright`
- `cyanBright`
- `whiteBright`
### Background colors
- `bgBlack`
- `bgRed`
- `bgGreen`
- `bgYellow`
- `bgBlue`
- `bgMagenta`
- `bgCyan`
- `bgWhite`
- `bgBlackBright` (alias: `bgGray`, `bgGrey`)
- `bgRedBright`
- `bgGreenBright`
- `bgYellowBright`
- `bgBlueBright`
- `bgMagentaBright`
- `bgCyanBright`
- `bgWhiteBright`
## Advanced usage
By default, you get a map of styles, but the styles are also available as groups. They are non-enumerable so they don't show up unless you access them explicitly. This makes it easier to expose only a subset in a higher-level module.
- `style.modifier`
- `style.color`
- `style.bgColor`
###### Example
```js
console.log(style.color.green.open);
```
Raw escape codes (i.e. without the CSI escape prefix `\u001B[` and render mode postfix `m`) are available under `style.codes`, which returns a `Map` with the open codes as keys and close codes as values.
###### Example
```js
console.log(style.codes.get(36));
//=> 39
```
## [256 / 16 million (TrueColor) support](https://gist.github.com/XVilka/8346728)
`ansi-styles` uses the [`color-convert`](https://github.com/Qix-/color-convert) package to allow for converting between various colors and ANSI escapes, with support for 256 and 16 million colors.
The following color spaces from `color-convert` are supported:
- `rgb`
- `hex`
- `keyword`
- `hsl`
- `hsv`
- `hwb`
- `ansi`
- `ansi256`
To use these, call the associated conversion function with the intended output, for example:
```js
style.color.ansi.rgb(100, 200, 15); // RGB to 16 color ansi foreground code
style.bgColor.ansi.rgb(100, 200, 15); // RGB to 16 color ansi background code
style.color.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code
style.bgColor.ansi256.hsl(120, 100, 60); // HSL to 256 color ansi foreground code
style.color.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color foreground code
style.bgColor.ansi16m.hex('#C0FFEE'); // Hex (RGB) to 16 million color background code
```
## Related
- [ansi-escapes](https://github.com/sindresorhus/ansi-escapes) - ANSI escape codes for manipulating the terminal
## Maintainers
- [Sindre Sorhus](https://github.com/sindresorhus)
- [Josh Junon](https://github.com/qix-)
## For enterprise
Available as part of the Tidelift Subscription.
The maintainers of `ansi-styles` and thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source dependencies you use to build your applications. Save time, reduce risk, and improve code health, while paying the maintainers of the exact dependencies you use. [Learn more.](https://tidelift.com/subscription/pkg/npm-ansi-styles?utm_source=npm-ansi-styles&utm_medium=referral&utm_campaign=enterprise&utm_term=repo)

View File

@ -0,0 +1,50 @@
export interface Options {
/**
Bind only the given methods.
*/
readonly include?: ReadonlyArray<string | RegExp>;
/**
Bind methods except for the given methods.
*/
readonly exclude?: ReadonlyArray<string | RegExp>;
}
/**
Automatically bind methods to their class instance.
@param self - An object with methods to bind.
@example
```
import autoBind from 'auto-bind';
class Unicorn {
constructor(name) {
this.name = name;
autoBind(this);
}
message() {
return `${this.name} is awesome!`;
}
}
const unicorn = new Unicorn('Rainbow');
// Grab the method off the class instance
const message = unicorn.message;
// Still bound to the class instance
message();
//=> 'Rainbow is awesome!'
// Without `autoBind(this)`, the above would have resulted in
message();
//=> Error: Cannot read property 'name' of undefined
```
*/
export default function autoBind<SelfType extends Record<string, any>>( // This has to use `any` to be compatible with classes.
self: SelfType,
options?: Options
): SelfType;

View File

@ -0,0 +1,41 @@
// Gets all non-builtin properties up the prototype chain.
const getAllProperties = object => {
const properties = new Set();
do {
for (const key of Reflect.ownKeys(object)) {
properties.add([object, key]);
}
} while ((object = Reflect.getPrototypeOf(object)) && object !== Object.prototype);
return properties;
};
export default function autoBind(self, {include, exclude} = {}) {
const filter = key => {
const match = pattern => typeof pattern === 'string' ? key === pattern : pattern.test(key);
if (include) {
return include.some(match); // eslint-disable-line unicorn/no-array-callback-reference
}
if (exclude) {
return !exclude.some(match); // eslint-disable-line unicorn/no-array-callback-reference
}
return true;
};
for (const [object, key] of getAllProperties(self.constructor.prototype)) {
if (key === 'constructor' || !filter(key)) {
continue;
}
const descriptor = Reflect.getOwnPropertyDescriptor(object, key);
if (descriptor && typeof descriptor.value === 'function') {
self[key] = self[key].bind(self);
}
}
return self;
}

Some files were not shown because too many files have changed in this diff Show More