yoctomarkdown 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.husky/pre-commit +1 -0
- package/.prettierrc +1 -0
- package/AGENTS.md +6 -0
- package/README.md +95 -0
- package/biome.json +34 -0
- package/bun.lock +378 -0
- package/knip.json +1 -0
- package/package.json +34 -0
- package/spec.md +193 -0
- package/src/cli.ts +76 -0
- package/src/index.ts +153 -0
- package/src/themes.ts +60 -0
- package/tests/cli.test.ts +30 -0
- package/tests/index.test.ts +80 -0
- package/tsconfig.json +29 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
bun run check
|
package/.prettierrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "singleQuote": false }
|
package/AGENTS.md
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
- [spec.md](spec.md) is maintained by the user, only edit when asked directly by the user. It contains the specification for the project. Use it as the source of truth
|
|
2
|
+
- Maintain a healthy codebase, without excessive abstractions or high complexity patterns. Keep tests focused and dependable.
|
|
3
|
+
- Run `bun run check` before committing to run jscpd, knip, and typescript typecheck. Keep the code pristine at all times.
|
|
4
|
+
- Run `bun run format` to format code using prettier.
|
|
5
|
+
- Clean temporary files before commiting.
|
|
6
|
+
- Use convential commits message formatting.
|
package/README.md
ADDED
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
# yoctomarkdown
|
|
2
|
+
|
|
3
|
+
A small, fast, Bun-native Markdown highlighter for terminal output.
|
|
4
|
+
|
|
5
|
+
`yoctomarkdown` reads Markdown and writes ANSI-colored text to stdout or returns it as a string. It focuses on simple, fast, incremental rendering for CLI and programmatic use, supporting a practical subset of Markdown specifically for terminal display.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Incremental processing**: Stream chunks of Markdown without buffering the entire document.
|
|
10
|
+
- **Terminal optimized**: Styles headings, code blocks, lists, and more using `yoctocolors`.
|
|
11
|
+
- **Flexible**: Use it as a library (`highlightSync`, `createHighlighter`) or as a CLI tool.
|
|
12
|
+
- **Fast**: Built for the Bun runtime.
|
|
13
|
+
|
|
14
|
+
## Installation
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bun add yoctomarkdown
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
### CLI
|
|
23
|
+
|
|
24
|
+
Run via the command line:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
# Read from a file
|
|
28
|
+
yoctomarkdown README.md
|
|
29
|
+
|
|
30
|
+
# Read from stdin
|
|
31
|
+
cat README.md | yoctomarkdown
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
**Options:**
|
|
35
|
+
|
|
36
|
+
- `-t, --theme <name>`: Theme to use (`16`, `256`, `truecolor`, `minimal`, `none`). Defaults to `16`.
|
|
37
|
+
- `-w, --wrap <n|auto|0>`: Word wrapping length. Defaults to `auto` (terminal width).
|
|
38
|
+
- `-h, --help`: Show help.
|
|
39
|
+
|
|
40
|
+
### Library API
|
|
41
|
+
|
|
42
|
+
You can use `yoctomarkdown` programmatically in two ways: synchronously for complete strings, or incrementally via the highlighter.
|
|
43
|
+
|
|
44
|
+
#### Synchronous
|
|
45
|
+
|
|
46
|
+
```typescript
|
|
47
|
+
import { highlightSync } from "yoctomarkdown";
|
|
48
|
+
|
|
49
|
+
const markdown = "# Hello World\n\nThis is **bold** text.";
|
|
50
|
+
const output = highlightSync(markdown, { theme: "truecolor" });
|
|
51
|
+
console.log(output);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
#### Streaming / Incremental
|
|
55
|
+
|
|
56
|
+
```typescript
|
|
57
|
+
import { createHighlighter } from "yoctomarkdown";
|
|
58
|
+
|
|
59
|
+
const highlighter = createHighlighter({ theme: "16" });
|
|
60
|
+
|
|
61
|
+
process.stdout.write(highlighter.write("# Chunk 1\n"));
|
|
62
|
+
process.stdout.write(highlighter.write("Some *italic* text in Chunk 2.\n"));
|
|
63
|
+
process.stdout.write(highlighter.end());
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Options
|
|
67
|
+
|
|
68
|
+
```typescript
|
|
69
|
+
interface Options {
|
|
70
|
+
theme?: "16" | "256" | "truecolor" | "minimal" | "none" | Theme; // default: "16"
|
|
71
|
+
tabWidth?: number; // default: 2
|
|
72
|
+
wordWrap?: number | "auto" | 0; // default: "auto"
|
|
73
|
+
yieldEvery?: number; // default: 1000
|
|
74
|
+
}
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Supported Markdown
|
|
78
|
+
|
|
79
|
+
- Headings (`#`, `##`, `###`)
|
|
80
|
+
- Bold (`**text**`) and Italic (`*text*`)
|
|
81
|
+
- Inline code (` \`code\` `) and Fenced code blocks (` ``` `)
|
|
82
|
+
- Links (`[text](url)`)
|
|
83
|
+
- Lists (`-`, `*`, `1.`)
|
|
84
|
+
- Blockquotes (`>`)
|
|
85
|
+
- Horizontal rules (`---`)
|
|
86
|
+
|
|
87
|
+
Unsupported Markdown elements are preserved as plain text.
|
|
88
|
+
|
|
89
|
+
## Scripts
|
|
90
|
+
|
|
91
|
+
To contribute or develop locally, the following commands are available:
|
|
92
|
+
|
|
93
|
+
- `bun run check`: Runs formatting, linting, typechecking, and duplication checks.
|
|
94
|
+
- `bun run format`: Formats code using Prettier.
|
|
95
|
+
- `bun test`: Runs tests.
|
package/biome.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://biomejs.dev/schemas/2.4.7/schema.json",
|
|
3
|
+
"vcs": {
|
|
4
|
+
"enabled": true,
|
|
5
|
+
"clientKind": "git",
|
|
6
|
+
"useIgnoreFile": true
|
|
7
|
+
},
|
|
8
|
+
"files": {
|
|
9
|
+
"ignoreUnknown": false
|
|
10
|
+
},
|
|
11
|
+
"formatter": {
|
|
12
|
+
"enabled": false,
|
|
13
|
+
"indentStyle": "tab"
|
|
14
|
+
},
|
|
15
|
+
"linter": {
|
|
16
|
+
"enabled": true,
|
|
17
|
+
"rules": {
|
|
18
|
+
"recommended": true
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"javascript": {
|
|
22
|
+
"formatter": {
|
|
23
|
+
"quoteStyle": "double"
|
|
24
|
+
}
|
|
25
|
+
},
|
|
26
|
+
"assist": {
|
|
27
|
+
"enabled": true,
|
|
28
|
+
"actions": {
|
|
29
|
+
"source": {
|
|
30
|
+
"organizeImports": "on"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
}
|
package/bun.lock
ADDED
|
@@ -0,0 +1,378 @@
|
|
|
1
|
+
{
|
|
2
|
+
"lockfileVersion": 1,
|
|
3
|
+
"configVersion": 1,
|
|
4
|
+
"workspaces": {
|
|
5
|
+
"": {
|
|
6
|
+
"name": "yoctomarkdown",
|
|
7
|
+
"dependencies": {
|
|
8
|
+
"yoctocolors": "^2.1.2",
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@biomejs/biome": "^2.4.7",
|
|
12
|
+
"@types/bun": "latest",
|
|
13
|
+
"husky": "^9.1.7",
|
|
14
|
+
"jscpd": "^4.0.8",
|
|
15
|
+
"knip": "^5.86.0",
|
|
16
|
+
"prettier": "^3.8.1",
|
|
17
|
+
},
|
|
18
|
+
"peerDependencies": {
|
|
19
|
+
"typescript": "^5.9.3",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
"packages": {
|
|
24
|
+
"@babel/helper-string-parser": ["@babel/helper-string-parser@7.27.1", "", {}, "sha512-qMlSxKbpRlAridDExk92nSobyDdpPijUq2DW6oDnUqd0iOGxmQjyqhMIihI9+zv4LPyZdRje2cavWPbCbWm3eA=="],
|
|
25
|
+
|
|
26
|
+
"@babel/helper-validator-identifier": ["@babel/helper-validator-identifier@7.28.5", "", {}, "sha512-qSs4ifwzKJSV39ucNjsvc6WVHs6b7S03sOh2OcHF9UHfVPqWWALUsNUVzhSBiItjRZoLHx7nIarVjqKVusUZ1Q=="],
|
|
27
|
+
|
|
28
|
+
"@babel/parser": ["@babel/parser@7.29.0", "", { "dependencies": { "@babel/types": "^7.29.0" }, "bin": "./bin/babel-parser.js" }, "sha512-IyDgFV5GeDUVX4YdF/3CPULtVGSXXMLh1xVIgdCgxApktqnQV0r7/8Nqthg+8YLGaAtdyIlo2qIdZrbCv4+7ww=="],
|
|
29
|
+
|
|
30
|
+
"@babel/types": ["@babel/types@7.29.0", "", { "dependencies": { "@babel/helper-string-parser": "^7.27.1", "@babel/helper-validator-identifier": "^7.28.5" } }, "sha512-LwdZHpScM4Qz8Xw2iKSzS+cfglZzJGvofQICy7W7v4caru4EaAmyUuO6BGrbyQ2mYV11W0U8j5mBhd14dd3B0A=="],
|
|
31
|
+
|
|
32
|
+
"@biomejs/biome": ["@biomejs/biome@2.4.7", "", { "optionalDependencies": { "@biomejs/cli-darwin-arm64": "2.4.7", "@biomejs/cli-darwin-x64": "2.4.7", "@biomejs/cli-linux-arm64": "2.4.7", "@biomejs/cli-linux-arm64-musl": "2.4.7", "@biomejs/cli-linux-x64": "2.4.7", "@biomejs/cli-linux-x64-musl": "2.4.7", "@biomejs/cli-win32-arm64": "2.4.7", "@biomejs/cli-win32-x64": "2.4.7" }, "bin": { "biome": "bin/biome" } }, "sha512-vXrgcmNGZ4lpdwZSpMf1hWw1aWS6B+SyeSYKTLrNsiUsAdSRN0J4d/7mF3ogJFbIwFFSOL3wT92Zzxia/d5/ng=="],
|
|
33
|
+
|
|
34
|
+
"@biomejs/cli-darwin-arm64": ["@biomejs/cli-darwin-arm64@2.4.7", "", { "os": "darwin", "cpu": "arm64" }, "sha512-Oo0cF5mHzmvDmTXw8XSjhCia8K6YrZnk7aCS54+/HxyMdZMruMO3nfpDsrlar/EQWe41r1qrwKiCa2QDYHDzWA=="],
|
|
35
|
+
|
|
36
|
+
"@biomejs/cli-darwin-x64": ["@biomejs/cli-darwin-x64@2.4.7", "", { "os": "darwin", "cpu": "x64" }, "sha512-I+cOG3sd/7HdFtvDSnF9QQPrWguUH7zrkIMMykM3PtfWU9soTcS2yRb9Myq6MHmzbeCT08D1UmY+BaiMl5CcoQ=="],
|
|
37
|
+
|
|
38
|
+
"@biomejs/cli-linux-arm64": ["@biomejs/cli-linux-arm64@2.4.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-om6FugwmibzfP/6ALj5WRDVSND4H2G9X0nkI1HZpp2ySf9lW2j0X68oQSaHEnls6666oy4KDsc5RFjT4m0kV0w=="],
|
|
39
|
+
|
|
40
|
+
"@biomejs/cli-linux-arm64-musl": ["@biomejs/cli-linux-arm64-musl@2.4.7", "", { "os": "linux", "cpu": "arm64" }, "sha512-I2NvM9KPb09jWml93O2/5WMfNR7Lee5Latag1JThDRMURVhPX74p9UDnyTw3Ae6cE1DgXfw7sqQgX7rkvpc0vw=="],
|
|
41
|
+
|
|
42
|
+
"@biomejs/cli-linux-x64": ["@biomejs/cli-linux-x64@2.4.7", "", { "os": "linux", "cpu": "x64" }, "sha512-bV8/uo2Tj+gumnk4sUdkerWyCPRabaZdv88IpbmDWARQQoA/Q0YaqPz1a+LSEDIL7OfrnPi9Hq1Llz4ZIGyIQQ=="],
|
|
43
|
+
|
|
44
|
+
"@biomejs/cli-linux-x64-musl": ["@biomejs/cli-linux-x64-musl@2.4.7", "", { "os": "linux", "cpu": "x64" }, "sha512-00kx4YrBMU8374zd2wHuRV5wseh0rom5HqRND+vDldJPrWwQw+mzd/d8byI9hPx926CG+vWzq6AeiT7Yi5y59g=="],
|
|
45
|
+
|
|
46
|
+
"@biomejs/cli-win32-arm64": ["@biomejs/cli-win32-arm64@2.4.7", "", { "os": "win32", "cpu": "arm64" }, "sha512-hOUHBMlFCvDhu3WCq6vaBoG0dp0LkWxSEnEEsxxXvOa9TfT6ZBnbh72A/xBM7CBYB7WgwqboetzFEVDnMxelyw=="],
|
|
47
|
+
|
|
48
|
+
"@biomejs/cli-win32-x64": ["@biomejs/cli-win32-x64@2.4.7", "", { "os": "win32", "cpu": "x64" }, "sha512-qEpGjSkPC3qX4ycbMUthXvi9CkRq7kZpkqMY1OyhmYlYLnANnooDQ7hDerM8+0NJ+DZKVnsIc07h30XOpt7LtQ=="],
|
|
49
|
+
|
|
50
|
+
"@colors/colors": ["@colors/colors@1.5.0", "", {}, "sha512-ooWCrlZP11i8GImSjTHYHLkvFDP48nS4+204nGb1RiX/WXYHmJA2III9/e2DWVabCESdW7hBAEzHRqUn9OUVvQ=="],
|
|
51
|
+
|
|
52
|
+
"@emnapi/core": ["@emnapi/core@1.9.0", "", { "dependencies": { "@emnapi/wasi-threads": "1.2.0", "tslib": "^2.4.0" } }, "sha512-0DQ98G9ZQZOxfUcQn1waV2yS8aWdZ6kJMbYCJB3oUBecjWYO1fqJ+a1DRfPF3O5JEkwqwP1A9QEN/9mYm2Yd0w=="],
|
|
53
|
+
|
|
54
|
+
"@emnapi/runtime": ["@emnapi/runtime@1.9.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-QN75eB0IH2ywSpRpNddCRfQIhmJYBCJ1x5Lb3IscKAL8bMnVAKnRg8dCoXbHzVLLH7P38N2Z3mtulB7W0J0FKw=="],
|
|
55
|
+
|
|
56
|
+
"@emnapi/wasi-threads": ["@emnapi/wasi-threads@1.2.0", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-N10dEJNSsUx41Z6pZsXU8FjPjpBEplgH24sfkmITrBED1/U2Esum9F3lfLrMjKHHjmi557zQn7kR9R+XWXu5Rg=="],
|
|
57
|
+
|
|
58
|
+
"@jscpd/badge-reporter": ["@jscpd/badge-reporter@4.0.4", "", { "dependencies": { "badgen": "^3.2.3", "colors": "^1.4.0", "fs-extra": "^11.2.0" } }, "sha512-I9b4MmLXPM2vo0SxSUWnNGKcA4PjQlD3GzXvFK60z43cN/EIdLbOq3FVwCL+dg2obUqGXKIzAm7EsDFTg0D+mQ=="],
|
|
59
|
+
|
|
60
|
+
"@jscpd/core": ["@jscpd/core@4.0.4", "", { "dependencies": { "eventemitter3": "^5.0.1" } }, "sha512-QGMT3iXEX1fI6lgjPH+x8eyJwhwr2KkpSF5uBpjC0Z5Xloj0yFTFLtwJT+RhxP/Ob4WYrtx2jvpKB269oIwgMQ=="],
|
|
61
|
+
|
|
62
|
+
"@jscpd/finder": ["@jscpd/finder@4.0.4", "", { "dependencies": { "@jscpd/core": "4.0.4", "@jscpd/tokenizer": "4.0.4", "blamer": "^1.0.6", "bytes": "^3.1.2", "cli-table3": "^0.6.5", "colors": "^1.4.0", "fast-glob": "^3.3.2", "fs-extra": "^11.2.0", "markdown-table": "^2.0.0", "pug": "^3.0.3" } }, "sha512-qVUWY7Nzuvfd5OIk+n7/5CM98LmFroLqblRXAI2gDABwZrc7qS+WH2SNr0qoUq0f4OqwM+piiwKvwL/VDNn/Cg=="],
|
|
63
|
+
|
|
64
|
+
"@jscpd/html-reporter": ["@jscpd/html-reporter@4.0.4", "", { "dependencies": { "colors": "1.4.0", "fs-extra": "^11.2.0", "pug": "^3.0.3" } }, "sha512-YiepyeYkeH74Kx59PJRdUdonznct0wHPFkf6FLQN+mCBoy6leAWCcOfHtcexnp+UsBFDlItG5nRdKrDSxSH+Kg=="],
|
|
65
|
+
|
|
66
|
+
"@jscpd/tokenizer": ["@jscpd/tokenizer@4.0.4", "", { "dependencies": { "@jscpd/core": "4.0.4", "reprism": "^0.0.11", "spark-md5": "^3.0.2" } }, "sha512-xxYYY/qaLah/FlwogEbGIxx9CjDO+G9E6qawcy26WwrflzJb6wsnhjwdneN6Wb0RNCDsqvzY+bzG453jsin4UQ=="],
|
|
67
|
+
|
|
68
|
+
"@napi-rs/wasm-runtime": ["@napi-rs/wasm-runtime@1.1.1", "", { "dependencies": { "@emnapi/core": "^1.7.1", "@emnapi/runtime": "^1.7.1", "@tybys/wasm-util": "^0.10.1" } }, "sha512-p64ah1M1ld8xjWv3qbvFwHiFVWrq1yFvV4f7w+mzaqiR4IlSgkqhcRdHwsGgomwzBH51sRY4NEowLxnaBjcW/A=="],
|
|
69
|
+
|
|
70
|
+
"@nodelib/fs.scandir": ["@nodelib/fs.scandir@2.1.5", "", { "dependencies": { "@nodelib/fs.stat": "2.0.5", "run-parallel": "^1.1.9" } }, "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g=="],
|
|
71
|
+
|
|
72
|
+
"@nodelib/fs.stat": ["@nodelib/fs.stat@2.0.5", "", {}, "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A=="],
|
|
73
|
+
|
|
74
|
+
"@nodelib/fs.walk": ["@nodelib/fs.walk@1.2.8", "", { "dependencies": { "@nodelib/fs.scandir": "2.1.5", "fastq": "^1.6.0" } }, "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg=="],
|
|
75
|
+
|
|
76
|
+
"@oxc-resolver/binding-android-arm-eabi": ["@oxc-resolver/binding-android-arm-eabi@11.19.1", "", { "os": "android", "cpu": "arm" }, "sha512-aUs47y+xyXHUKlbhqHUjBABjvycq6YSD7bpxSW7vplUmdzAlJ93yXY6ZR0c1o1x5A/QKbENCvs3+NlY8IpIVzg=="],
|
|
77
|
+
|
|
78
|
+
"@oxc-resolver/binding-android-arm64": ["@oxc-resolver/binding-android-arm64@11.19.1", "", { "os": "android", "cpu": "arm64" }, "sha512-oolbkRX+m7Pq2LNjr/kKgYeC7bRDMVTWPgxBGMjSpZi/+UskVo4jsMU3MLheZV55jL6c3rNelPl4oD60ggYmqA=="],
|
|
79
|
+
|
|
80
|
+
"@oxc-resolver/binding-darwin-arm64": ["@oxc-resolver/binding-darwin-arm64@11.19.1", "", { "os": "darwin", "cpu": "arm64" }, "sha512-nUC6d2i3R5B12sUW4O646qD5cnMXf2oBGPLIIeaRfU9doJRORAbE2SGv4eW6rMqhD+G7nf2Y8TTJTLiiO3Q/dQ=="],
|
|
81
|
+
|
|
82
|
+
"@oxc-resolver/binding-darwin-x64": ["@oxc-resolver/binding-darwin-x64@11.19.1", "", { "os": "darwin", "cpu": "x64" }, "sha512-cV50vE5+uAgNcFa3QY1JOeKDSkM/9ReIcc/9wn4TavhW/itkDGrXhw9jaKnkQnGbjJ198Yh5nbX/Gr2mr4Z5jQ=="],
|
|
83
|
+
|
|
84
|
+
"@oxc-resolver/binding-freebsd-x64": ["@oxc-resolver/binding-freebsd-x64@11.19.1", "", { "os": "freebsd", "cpu": "x64" }, "sha512-xZOQiYGFxtk48PBKff+Zwoym7ScPAIVp4c14lfLxizO2LTTTJe5sx9vQNGrBymrf/vatSPNMD4FgsaaRigPkqw=="],
|
|
85
|
+
|
|
86
|
+
"@oxc-resolver/binding-linux-arm-gnueabihf": ["@oxc-resolver/binding-linux-arm-gnueabihf@11.19.1", "", { "os": "linux", "cpu": "arm" }, "sha512-lXZYWAC6kaGe/ky2su94e9jN9t6M0/6c+GrSlCqL//XO1cxi5lpAhnJYdyrKfm0ZEr/c7RNyAx3P7FSBcBd5+A=="],
|
|
87
|
+
|
|
88
|
+
"@oxc-resolver/binding-linux-arm-musleabihf": ["@oxc-resolver/binding-linux-arm-musleabihf@11.19.1", "", { "os": "linux", "cpu": "arm" }, "sha512-veG1kKsuK5+t2IsO9q0DErYVSw2azvCVvWHnfTOS73WE0STdLLB7Q1bB9WR+yHPQM76ASkFyRbogWo1GR1+WbQ=="],
|
|
89
|
+
|
|
90
|
+
"@oxc-resolver/binding-linux-arm64-gnu": ["@oxc-resolver/binding-linux-arm64-gnu@11.19.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-heV2+jmXyYnUrpUXSPugqWDRpnsQcDm2AX4wzTuvgdlZfoNYO0O3W2AVpJYaDn9AG4JdM6Kxom8+foE7/BcSig=="],
|
|
91
|
+
|
|
92
|
+
"@oxc-resolver/binding-linux-arm64-musl": ["@oxc-resolver/binding-linux-arm64-musl@11.19.1", "", { "os": "linux", "cpu": "arm64" }, "sha512-jvo2Pjs1c9KPxMuMPIeQsgu0mOJF9rEb3y3TdpsrqwxRM+AN6/nDDwv45n5ZrUnQMsdBy5gIabioMKnQfWo9ew=="],
|
|
93
|
+
|
|
94
|
+
"@oxc-resolver/binding-linux-ppc64-gnu": ["@oxc-resolver/binding-linux-ppc64-gnu@11.19.1", "", { "os": "linux", "cpu": "ppc64" }, "sha512-vLmdNxWCdN7Uo5suays6A/+ywBby2PWBBPXctWPg5V0+eVuzsJxgAn6MMB4mPlshskYbppjpN2Zg83ArHze9gQ=="],
|
|
95
|
+
|
|
96
|
+
"@oxc-resolver/binding-linux-riscv64-gnu": ["@oxc-resolver/binding-linux-riscv64-gnu@11.19.1", "", { "os": "linux", "cpu": "none" }, "sha512-/b+WgR+VTSBxzgOhDO7TlMXC1ufPIMR6Vj1zN+/x+MnyXGW7prTLzU9eW85Aj7Th7CCEG9ArCbTeqxCzFWdg2w=="],
|
|
97
|
+
|
|
98
|
+
"@oxc-resolver/binding-linux-riscv64-musl": ["@oxc-resolver/binding-linux-riscv64-musl@11.19.1", "", { "os": "linux", "cpu": "none" }, "sha512-YlRdeWb9j42p29ROh+h4eg/OQ3dTJlpHSa+84pUM9+p6i3djtPz1q55yLJhgW9XfDch7FN1pQ/Vd6YP+xfRIuw=="],
|
|
99
|
+
|
|
100
|
+
"@oxc-resolver/binding-linux-s390x-gnu": ["@oxc-resolver/binding-linux-s390x-gnu@11.19.1", "", { "os": "linux", "cpu": "s390x" }, "sha512-EDpafVOQWF8/MJynsjOGFThcqhRHy417sRyLfQmeiamJ8qVhSKAn2Dn2VVKUGCjVB9C46VGjhNo7nOPUi1x6uA=="],
|
|
101
|
+
|
|
102
|
+
"@oxc-resolver/binding-linux-x64-gnu": ["@oxc-resolver/binding-linux-x64-gnu@11.19.1", "", { "os": "linux", "cpu": "x64" }, "sha512-NxjZe+rqWhr+RT8/Ik+5ptA3oz7tUw361Wa5RWQXKnfqwSSHdHyrw6IdcTfYuml9dM856AlKWZIUXDmA9kkiBQ=="],
|
|
103
|
+
|
|
104
|
+
"@oxc-resolver/binding-linux-x64-musl": ["@oxc-resolver/binding-linux-x64-musl@11.19.1", "", { "os": "linux", "cpu": "x64" }, "sha512-cM/hQwsO3ReJg5kR+SpI69DMfvNCp+A/eVR4b4YClE5bVZwz8rh2Nh05InhwI5HR/9cArbEkzMjcKgTHS6UaNw=="],
|
|
105
|
+
|
|
106
|
+
"@oxc-resolver/binding-openharmony-arm64": ["@oxc-resolver/binding-openharmony-arm64@11.19.1", "", { "os": "none", "cpu": "arm64" }, "sha512-QF080IowFB0+9Rh6RcD19bdgh49BpQHUW5TajG1qvWHvmrQznTZZjYlgE2ltLXyKY+qs4F/v5xuX1XS7Is+3qA=="],
|
|
107
|
+
|
|
108
|
+
"@oxc-resolver/binding-wasm32-wasi": ["@oxc-resolver/binding-wasm32-wasi@11.19.1", "", { "dependencies": { "@napi-rs/wasm-runtime": "^1.1.1" }, "cpu": "none" }, "sha512-w8UCKhX826cP/ZLokXDS6+milN8y4X7zidsAttEdWlVoamTNf6lhBJldaWr3ukTDiye7s4HRcuPEPOXNC432Vg=="],
|
|
109
|
+
|
|
110
|
+
"@oxc-resolver/binding-win32-arm64-msvc": ["@oxc-resolver/binding-win32-arm64-msvc@11.19.1", "", { "os": "win32", "cpu": "arm64" }, "sha512-nJ4AsUVZrVKwnU/QRdzPCCrO0TrabBqgJ8pJhXITdZGYOV28TIYystV1VFLbQ7DtAcaBHpocT5/ZJnF78YJPtQ=="],
|
|
111
|
+
|
|
112
|
+
"@oxc-resolver/binding-win32-ia32-msvc": ["@oxc-resolver/binding-win32-ia32-msvc@11.19.1", "", { "os": "win32", "cpu": "ia32" }, "sha512-EW+ND5q2Tl+a3pH81l1QbfgbF3HmqgwLfDfVithRFheac8OTcnbXt/JxqD2GbDkb7xYEqy1zNaVFRr3oeG8npA=="],
|
|
113
|
+
|
|
114
|
+
"@oxc-resolver/binding-win32-x64-msvc": ["@oxc-resolver/binding-win32-x64-msvc@11.19.1", "", { "os": "win32", "cpu": "x64" }, "sha512-6hIU3RQu45B+VNTY4Ru8ppFwjVS/S5qwYyGhBotmjxfEKk41I2DlGtRfGJndZ5+6lneE2pwloqunlOyZuX/XAw=="],
|
|
115
|
+
|
|
116
|
+
"@tybys/wasm-util": ["@tybys/wasm-util@0.10.1", "", { "dependencies": { "tslib": "^2.4.0" } }, "sha512-9tTaPJLSiejZKx+Bmog4uSubteqTvFrVrURwkmHixBo0G4seD0zUxp98E1DzUBJxLQ3NPwXrGKDiVjwx/DpPsg=="],
|
|
117
|
+
|
|
118
|
+
"@types/bun": ["@types/bun@1.3.10", "", { "dependencies": { "bun-types": "1.3.10" } }, "sha512-0+rlrUrOrTSskibryHbvQkDOWRJwJZqZlxrUs1u4oOoTln8+WIXBPmAuCF35SWB2z4Zl3E84Nl/D0P7803nigQ=="],
|
|
119
|
+
|
|
120
|
+
"@types/node": ["@types/node@25.5.0", "", { "dependencies": { "undici-types": "~7.18.0" } }, "sha512-jp2P3tQMSxWugkCUKLRPVUpGaL5MVFwF8RDuSRztfwgN1wmqJeMSbKlnEtQqU8UrhTmzEmZdu2I6v2dpp7XIxw=="],
|
|
121
|
+
|
|
122
|
+
"@types/sarif": ["@types/sarif@2.1.7", "", {}, "sha512-kRz0VEkJqWLf1LLVN4pT1cg1Z9wAuvI6L97V3m2f5B76Tg8d413ddvLBPTEHAZJlnn4XSvu0FkZtViCQGVyrXQ=="],
|
|
123
|
+
|
|
124
|
+
"acorn": ["acorn@7.4.1", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A=="],
|
|
125
|
+
|
|
126
|
+
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
|
|
127
|
+
|
|
128
|
+
"asap": ["asap@2.0.6", "", {}, "sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA=="],
|
|
129
|
+
|
|
130
|
+
"assert-never": ["assert-never@1.4.0", "", {}, "sha512-5oJg84os6NMQNl27T9LnZkvvqzvAnHu03ShCnoj6bsJwS7L8AO4lf+C/XjK/nvzEqQB744moC6V128RucQd1jA=="],
|
|
131
|
+
|
|
132
|
+
"babel-walk": ["babel-walk@3.0.0-canary-5", "", { "dependencies": { "@babel/types": "^7.9.6" } }, "sha512-GAwkz0AihzY5bkwIY5QDR+LvsRQgB/B+1foMPvi0FZPMl5fjD7ICiznUiBdLYMH1QYe6vqu4gWYytZOccLouFw=="],
|
|
133
|
+
|
|
134
|
+
"badgen": ["badgen@3.2.3", "", {}, "sha512-svDuwkc63E/z0ky3drpUppB83s/nlgDciH9m+STwwQoWyq7yCgew1qEfJ+9axkKdNq7MskByptWUN9j1PGMwFA=="],
|
|
135
|
+
|
|
136
|
+
"blamer": ["blamer@1.0.7", "", { "dependencies": { "execa": "^4.0.0", "which": "^2.0.2" } }, "sha512-GbBStl/EVlSWkiJQBZps3H1iARBrC7vt++Jb/TTmCNu/jZ04VW7tSN1nScbFXBUy1AN+jzeL7Zep9sbQxLhXKA=="],
|
|
137
|
+
|
|
138
|
+
"braces": ["braces@3.0.3", "", { "dependencies": { "fill-range": "^7.1.1" } }, "sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA=="],
|
|
139
|
+
|
|
140
|
+
"bun-types": ["bun-types@1.3.10", "", { "dependencies": { "@types/node": "*" } }, "sha512-tcpfCCl6XWo6nCVnpcVrxQ+9AYN1iqMIzgrSKYMB/fjLtV2eyAVEg7AxQJuCq/26R6HpKWykQXuSOq/21RYcbg=="],
|
|
141
|
+
|
|
142
|
+
"bytes": ["bytes@3.1.2", "", {}, "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg=="],
|
|
143
|
+
|
|
144
|
+
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
|
|
145
|
+
|
|
146
|
+
"call-bound": ["call-bound@1.0.4", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "get-intrinsic": "^1.3.0" } }, "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg=="],
|
|
147
|
+
|
|
148
|
+
"character-parser": ["character-parser@2.2.0", "", { "dependencies": { "is-regex": "^1.0.3" } }, "sha512-+UqJQjFEFaTAs3bNsF2j2kEN1baG/zghZbdqoYEDxGZtJo9LBzl1A+m0D4n3qKx8N2FNv8/Xp6yV9mQmBuptaw=="],
|
|
149
|
+
|
|
150
|
+
"cli-table3": ["cli-table3@0.6.5", "", { "dependencies": { "string-width": "^4.2.0" }, "optionalDependencies": { "@colors/colors": "1.5.0" } }, "sha512-+W/5efTR7y5HRD7gACw9yQjqMVvEMLBHmboM/kPWam+H+Hmyrgjh6YncVKK122YZkXrLudzTuAukUw9FnMf7IQ=="],
|
|
151
|
+
|
|
152
|
+
"colors": ["colors@1.4.0", "", {}, "sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA=="],
|
|
153
|
+
|
|
154
|
+
"commander": ["commander@5.1.0", "", {}, "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg=="],
|
|
155
|
+
|
|
156
|
+
"constantinople": ["constantinople@4.0.1", "", { "dependencies": { "@babel/parser": "^7.6.0", "@babel/types": "^7.6.1" } }, "sha512-vCrqcSIq4//Gx74TXXCGnHpulY1dskqLTFGDmhrGxzeXL8lF8kvXv6mpNWlJj1uD4DW23D4ljAqbY4RRaaUZIw=="],
|
|
157
|
+
|
|
158
|
+
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
|
|
159
|
+
|
|
160
|
+
"doctypes": ["doctypes@1.1.0", "", {}, "sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ=="],
|
|
161
|
+
|
|
162
|
+
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
|
|
163
|
+
|
|
164
|
+
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
|
|
165
|
+
|
|
166
|
+
"end-of-stream": ["end-of-stream@1.4.5", "", { "dependencies": { "once": "^1.4.0" } }, "sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg=="],
|
|
167
|
+
|
|
168
|
+
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
|
|
169
|
+
|
|
170
|
+
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
|
|
171
|
+
|
|
172
|
+
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
|
|
173
|
+
|
|
174
|
+
"eventemitter3": ["eventemitter3@5.0.4", "", {}, "sha512-mlsTRyGaPBjPedk6Bvw+aqbsXDtoAyAzm5MO7JgU+yVRyMQ5O8bD4Kcci7BS85f93veegeCPkL8R4GLClnjLFw=="],
|
|
175
|
+
|
|
176
|
+
"execa": ["execa@4.1.0", "", { "dependencies": { "cross-spawn": "^7.0.0", "get-stream": "^5.0.0", "human-signals": "^1.1.1", "is-stream": "^2.0.0", "merge-stream": "^2.0.0", "npm-run-path": "^4.0.0", "onetime": "^5.1.0", "signal-exit": "^3.0.2", "strip-final-newline": "^2.0.0" } }, "sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA=="],
|
|
177
|
+
|
|
178
|
+
"fast-glob": ["fast-glob@3.3.3", "", { "dependencies": { "@nodelib/fs.stat": "^2.0.2", "@nodelib/fs.walk": "^1.2.3", "glob-parent": "^5.1.2", "merge2": "^1.3.0", "micromatch": "^4.0.8" } }, "sha512-7MptL8U0cqcFdzIzwOTHoilX9x5BrNqye7Z/LuC7kCMRio1EMSyqRK3BEAUD7sXRq4iT4AzTVuZdhgQ2TCvYLg=="],
|
|
179
|
+
|
|
180
|
+
"fastq": ["fastq@1.20.1", "", { "dependencies": { "reusify": "^1.0.4" } }, "sha512-GGToxJ/w1x32s/D2EKND7kTil4n8OVk/9mycTc4VDza13lOvpUZTGX3mFSCtV9ksdGBVzvsyAVLM6mHFThxXxw=="],
|
|
181
|
+
|
|
182
|
+
"fd-package-json": ["fd-package-json@2.0.0", "", { "dependencies": { "walk-up-path": "^4.0.0" } }, "sha512-jKmm9YtsNXN789RS/0mSzOC1NUq9mkVd65vbSSVsKdjGvYXBuE4oWe2QOEoFeRmJg+lPuZxpmrfFclNhoRMneQ=="],
|
|
183
|
+
|
|
184
|
+
"fill-range": ["fill-range@7.1.1", "", { "dependencies": { "to-regex-range": "^5.0.1" } }, "sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg=="],
|
|
185
|
+
|
|
186
|
+
"formatly": ["formatly@0.3.0", "", { "dependencies": { "fd-package-json": "^2.0.0" }, "bin": { "formatly": "bin/index.mjs" } }, "sha512-9XNj/o4wrRFyhSMJOvsuyMwy8aUfBaZ1VrqHVfohyXf0Sw0e+yfKG+xZaY3arGCOMdwFsqObtzVOc1gU9KiT9w=="],
|
|
187
|
+
|
|
188
|
+
"fs-extra": ["fs-extra@11.3.4", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-CTXd6rk/M3/ULNQj8FBqBWHYBVYybQ3VPBw0xGKFe3tuH7ytT6ACnvzpIQ3UZtB8yvUKC2cXn1a+x+5EVQLovA=="],
|
|
189
|
+
|
|
190
|
+
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
|
|
191
|
+
|
|
192
|
+
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
|
|
193
|
+
|
|
194
|
+
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
|
|
195
|
+
|
|
196
|
+
"get-stream": ["get-stream@5.2.0", "", { "dependencies": { "pump": "^3.0.0" } }, "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA=="],
|
|
197
|
+
|
|
198
|
+
"gitignore-to-glob": ["gitignore-to-glob@0.3.0", "", {}, "sha512-mk74BdnK7lIwDHnotHddx1wsjMOFIThpLY3cPNniJ/2fA/tlLzHnFxIdR+4sLOu5KGgQJdij4kjJ2RoUNnCNMA=="],
|
|
199
|
+
|
|
200
|
+
"glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
|
|
201
|
+
|
|
202
|
+
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
|
|
203
|
+
|
|
204
|
+
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
|
|
205
|
+
|
|
206
|
+
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
|
|
207
|
+
|
|
208
|
+
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
|
|
209
|
+
|
|
210
|
+
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
|
|
211
|
+
|
|
212
|
+
"human-signals": ["human-signals@1.1.1", "", {}, "sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw=="],
|
|
213
|
+
|
|
214
|
+
"husky": ["husky@9.1.7", "", { "bin": { "husky": "bin.js" } }, "sha512-5gs5ytaNjBrh5Ow3zrvdUUY+0VxIuWVL4i9irt6friV+BqdCfmV11CQTWMiBYWHbXhco+J1kHfTOUkePhCDvMA=="],
|
|
215
|
+
|
|
216
|
+
"is-core-module": ["is-core-module@2.16.1", "", { "dependencies": { "hasown": "^2.0.2" } }, "sha512-UfoeMA6fIJ8wTYFEUjelnaGI67v6+N7qXJEvQuIGa99l4xsCruSYOVSQ0uPANn4dAzm8lkYPaKLrrijLq7x23w=="],
|
|
217
|
+
|
|
218
|
+
"is-expression": ["is-expression@4.0.0", "", { "dependencies": { "acorn": "^7.1.1", "object-assign": "^4.1.1" } }, "sha512-zMIXX63sxzG3XrkHkrAPvm/OVZVSCPNkwMHU8oTX7/U3AL78I0QXCEICXUM13BIa8TYGZ68PiTKfQz3yaTNr4A=="],
|
|
219
|
+
|
|
220
|
+
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
|
|
221
|
+
|
|
222
|
+
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
|
|
223
|
+
|
|
224
|
+
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
|
|
225
|
+
|
|
226
|
+
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
|
|
227
|
+
|
|
228
|
+
"is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="],
|
|
229
|
+
|
|
230
|
+
"is-regex": ["is-regex@1.2.1", "", { "dependencies": { "call-bound": "^1.0.2", "gopd": "^1.2.0", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-MjYsKHO5O7mCsmRGxWcLWheFqN9DJ/2TmngvjKXihe6efViPqc274+Fx/4fYj/r03+ESvBdTXK0V6tA3rgez1g=="],
|
|
231
|
+
|
|
232
|
+
"is-stream": ["is-stream@2.0.1", "", {}, "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="],
|
|
233
|
+
|
|
234
|
+
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
|
|
235
|
+
|
|
236
|
+
"jiti": ["jiti@2.6.1", "", { "bin": { "jiti": "lib/jiti-cli.mjs" } }, "sha512-ekilCSN1jwRvIbgeg/57YFh8qQDNbwDb9xT/qu2DAHbFFZUicIl4ygVaAvzveMhMVr3LnpSKTNnwt8PoOfmKhQ=="],
|
|
237
|
+
|
|
238
|
+
"js-stringify": ["js-stringify@1.0.2", "", {}, "sha512-rtS5ATOo2Q5k1G+DADISilDA6lv79zIiwFd6CcjuIxGKLFm5C+RLImRscVap9k55i+MOZwgliw+NejvkLuGD5g=="],
|
|
239
|
+
|
|
240
|
+
"jscpd": ["jscpd@4.0.8", "", { "dependencies": { "@jscpd/badge-reporter": "4.0.4", "@jscpd/core": "4.0.4", "@jscpd/finder": "4.0.4", "@jscpd/html-reporter": "4.0.4", "@jscpd/tokenizer": "4.0.4", "colors": "^1.4.0", "commander": "^5.0.0", "fs-extra": "^11.2.0", "gitignore-to-glob": "^0.3.0", "jscpd-sarif-reporter": "4.0.6" }, "bin": { "jscpd": "bin/jscpd" } }, "sha512-d2VNT/2Hv4dxT2/59He8Lyda4DYOxPRyRG9zBaOpTZAqJCVf2xLrBlZkT8Va6Lo9u3X2qz8Bpq4HrDi4JsrQhA=="],
|
|
241
|
+
|
|
242
|
+
"jscpd-sarif-reporter": ["jscpd-sarif-reporter@4.0.6", "", { "dependencies": { "colors": "^1.4.0", "fs-extra": "^11.2.0", "node-sarif-builder": "^3.4.0" } }, "sha512-b9Sm3IPZ3+m8Lwa4gZa+4/LhDhlc/ZLEsLXKSOy1DANQ6kx0ueqZT+fUHWEdQ6m0o3+RIVIa7DmvLSojQD05ng=="],
|
|
243
|
+
|
|
244
|
+
"jsonfile": ["jsonfile@6.2.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-FGuPw30AdOIUTRMC2OMRtQV+jkVj2cfPqSeWXv1NEAJ1qZ5zb1X6z1mFhbfOB/iy3ssJCD+3KuZ8r8C3uVFlAg=="],
|
|
245
|
+
|
|
246
|
+
"jstransformer": ["jstransformer@1.0.0", "", { "dependencies": { "is-promise": "^2.0.0", "promise": "^7.0.1" } }, "sha512-C9YK3Rf8q6VAPDCCU9fnqo3mAfOH6vUGnMcP4AQAYIEpWtfGLpwOTmZ+igtdK5y+VvI2n3CyYSzy4Qh34eq24A=="],
|
|
247
|
+
|
|
248
|
+
"knip": ["knip@5.86.0", "", { "dependencies": { "@nodelib/fs.walk": "^1.2.3", "fast-glob": "^3.3.3", "formatly": "^0.3.0", "jiti": "^2.6.0", "minimist": "^1.2.8", "oxc-resolver": "^11.19.1", "picocolors": "^1.1.1", "picomatch": "^4.0.1", "smol-toml": "^1.5.2", "strip-json-comments": "5.0.3", "unbash": "^2.2.0", "yaml": "^2.8.2", "zod": "^4.1.11" }, "peerDependencies": { "@types/node": ">=18", "typescript": ">=5.0.4 <7" }, "bin": { "knip": "bin/knip.js", "knip-bun": "bin/knip-bun.js" } }, "sha512-tGpRCbP+L+VysXnAp1bHTLQ0k/SdC3M3oX18+Cpiqax1qdS25iuCPzpK8LVmAKARZv0Ijri81Wq09Rzk0JTl+Q=="],
|
|
249
|
+
|
|
250
|
+
"markdown-table": ["markdown-table@2.0.0", "", { "dependencies": { "repeat-string": "^1.0.0" } }, "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A=="],
|
|
251
|
+
|
|
252
|
+
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
|
|
253
|
+
|
|
254
|
+
"merge-stream": ["merge-stream@2.0.0", "", {}, "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="],
|
|
255
|
+
|
|
256
|
+
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
|
|
257
|
+
|
|
258
|
+
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
|
|
259
|
+
|
|
260
|
+
"mimic-fn": ["mimic-fn@2.1.0", "", {}, "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="],
|
|
261
|
+
|
|
262
|
+
"minimist": ["minimist@1.2.8", "", {}, "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA=="],
|
|
263
|
+
|
|
264
|
+
"node-sarif-builder": ["node-sarif-builder@3.4.0", "", { "dependencies": { "@types/sarif": "^2.1.7", "fs-extra": "^11.1.1" } }, "sha512-tGnJW6OKRii9u/b2WiUViTJS+h7Apxx17qsMUjsUeNDiMMX5ZFf8F8Fcz7PAQ6omvOxHZtvDTmOYKJQwmfpjeg=="],
|
|
265
|
+
|
|
266
|
+
"npm-run-path": ["npm-run-path@4.0.1", "", { "dependencies": { "path-key": "^3.0.0" } }, "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw=="],
|
|
267
|
+
|
|
268
|
+
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
|
|
269
|
+
|
|
270
|
+
"once": ["once@1.4.0", "", { "dependencies": { "wrappy": "1" } }, "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w=="],
|
|
271
|
+
|
|
272
|
+
"onetime": ["onetime@5.1.2", "", { "dependencies": { "mimic-fn": "^2.1.0" } }, "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg=="],
|
|
273
|
+
|
|
274
|
+
"oxc-resolver": ["oxc-resolver@11.19.1", "", { "optionalDependencies": { "@oxc-resolver/binding-android-arm-eabi": "11.19.1", "@oxc-resolver/binding-android-arm64": "11.19.1", "@oxc-resolver/binding-darwin-arm64": "11.19.1", "@oxc-resolver/binding-darwin-x64": "11.19.1", "@oxc-resolver/binding-freebsd-x64": "11.19.1", "@oxc-resolver/binding-linux-arm-gnueabihf": "11.19.1", "@oxc-resolver/binding-linux-arm-musleabihf": "11.19.1", "@oxc-resolver/binding-linux-arm64-gnu": "11.19.1", "@oxc-resolver/binding-linux-arm64-musl": "11.19.1", "@oxc-resolver/binding-linux-ppc64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-gnu": "11.19.1", "@oxc-resolver/binding-linux-riscv64-musl": "11.19.1", "@oxc-resolver/binding-linux-s390x-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-gnu": "11.19.1", "@oxc-resolver/binding-linux-x64-musl": "11.19.1", "@oxc-resolver/binding-openharmony-arm64": "11.19.1", "@oxc-resolver/binding-wasm32-wasi": "11.19.1", "@oxc-resolver/binding-win32-arm64-msvc": "11.19.1", "@oxc-resolver/binding-win32-ia32-msvc": "11.19.1", "@oxc-resolver/binding-win32-x64-msvc": "11.19.1" } }, "sha512-qE/CIg/spwrTBFt5aKmwe3ifeDdLfA2NESN30E42X/lII5ClF8V7Wt6WIJhcGZjp0/Q+nQ+9vgxGk//xZNX2hg=="],
|
|
275
|
+
|
|
276
|
+
"path-key": ["path-key@3.1.1", "", {}, "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="],
|
|
277
|
+
|
|
278
|
+
"path-parse": ["path-parse@1.0.7", "", {}, "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="],
|
|
279
|
+
|
|
280
|
+
"picocolors": ["picocolors@1.1.1", "", {}, "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA=="],
|
|
281
|
+
|
|
282
|
+
"picomatch": ["picomatch@4.0.3", "", {}, "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q=="],
|
|
283
|
+
|
|
284
|
+
"prettier": ["prettier@3.8.1", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-UOnG6LftzbdaHZcKoPFtOcCKztrQ57WkHDeRD9t/PTQtmT0NHSeWWepj6pS0z/N7+08BHFDQVUrfmfMRcZwbMg=="],
|
|
285
|
+
|
|
286
|
+
"promise": ["promise@7.3.1", "", { "dependencies": { "asap": "~2.0.3" } }, "sha512-nolQXZ/4L+bP/UGlkfaIujX9BKxGwmQ9OT4mOt5yvy8iK1h3wqTEJCijzGANTCCl9nWjY41juyAn2K3Q1hLLTg=="],
|
|
287
|
+
|
|
288
|
+
"pug": ["pug@3.0.4", "", { "dependencies": { "pug-code-gen": "^3.0.4", "pug-filters": "^4.0.0", "pug-lexer": "^5.0.1", "pug-linker": "^4.0.0", "pug-load": "^3.0.0", "pug-parser": "^6.0.0", "pug-runtime": "^3.0.1", "pug-strip-comments": "^2.0.0" } }, "sha512-kFfq5mMzrS7+wrl5pLJzZEzemx34OQ0w4SARfhy/3yxTlhbstsudDwJzhf1hP02yHzbjoVMSXUj/Sz6RNfMyXg=="],
|
|
289
|
+
|
|
290
|
+
"pug-attrs": ["pug-attrs@3.0.0", "", { "dependencies": { "constantinople": "^4.0.1", "js-stringify": "^1.0.2", "pug-runtime": "^3.0.0" } }, "sha512-azINV9dUtzPMFQktvTXciNAfAuVh/L/JCl0vtPCwvOA21uZrC08K/UnmrL+SXGEVc1FwzjW62+xw5S/uaLj6cA=="],
|
|
291
|
+
|
|
292
|
+
"pug-code-gen": ["pug-code-gen@3.0.4", "", { "dependencies": { "constantinople": "^4.0.1", "doctypes": "^1.1.0", "js-stringify": "^1.0.2", "pug-attrs": "^3.0.0", "pug-error": "^2.1.0", "pug-runtime": "^3.0.1", "void-elements": "^3.1.0", "with": "^7.0.0" } }, "sha512-6okWYIKdasTyXICyEtvobmTZAVX57JkzgzIi4iRJlin8kmhG+Xry2dsus+Mun/nGCn6F2U49haHI5mkELXB14g=="],
|
|
293
|
+
|
|
294
|
+
"pug-error": ["pug-error@2.1.0", "", {}, "sha512-lv7sU9e5Jk8IeUheHata6/UThZ7RK2jnaaNztxfPYUY+VxZyk/ePVaNZ/vwmH8WqGvDz3LrNYt/+gA55NDg6Pg=="],
|
|
295
|
+
|
|
296
|
+
"pug-filters": ["pug-filters@4.0.0", "", { "dependencies": { "constantinople": "^4.0.1", "jstransformer": "1.0.0", "pug-error": "^2.0.0", "pug-walk": "^2.0.0", "resolve": "^1.15.1" } }, "sha512-yeNFtq5Yxmfz0f9z2rMXGw/8/4i1cCFecw/Q7+D0V2DdtII5UvqE12VaZ2AY7ri6o5RNXiweGH79OCq+2RQU4A=="],
|
|
297
|
+
|
|
298
|
+
"pug-lexer": ["pug-lexer@5.0.1", "", { "dependencies": { "character-parser": "^2.2.0", "is-expression": "^4.0.0", "pug-error": "^2.0.0" } }, "sha512-0I6C62+keXlZPZkOJeVam9aBLVP2EnbeDw3An+k0/QlqdwH6rv8284nko14Na7c0TtqtogfWXcRoFE4O4Ff20w=="],
|
|
299
|
+
|
|
300
|
+
"pug-linker": ["pug-linker@4.0.0", "", { "dependencies": { "pug-error": "^2.0.0", "pug-walk": "^2.0.0" } }, "sha512-gjD1yzp0yxbQqnzBAdlhbgoJL5qIFJw78juN1NpTLt/mfPJ5VgC4BvkoD3G23qKzJtIIXBbcCt6FioLSFLOHdw=="],
|
|
301
|
+
|
|
302
|
+
"pug-load": ["pug-load@3.0.0", "", { "dependencies": { "object-assign": "^4.1.1", "pug-walk": "^2.0.0" } }, "sha512-OCjTEnhLWZBvS4zni/WUMjH2YSUosnsmjGBB1An7CsKQarYSWQ0GCVyd4eQPMFJqZ8w9xgs01QdiZXKVjk92EQ=="],
|
|
303
|
+
|
|
304
|
+
"pug-parser": ["pug-parser@6.0.0", "", { "dependencies": { "pug-error": "^2.0.0", "token-stream": "1.0.0" } }, "sha512-ukiYM/9cH6Cml+AOl5kETtM9NR3WulyVP2y4HOU45DyMim1IeP/OOiyEWRr6qk5I5klpsBnbuHpwKmTx6WURnw=="],
|
|
305
|
+
|
|
306
|
+
"pug-runtime": ["pug-runtime@3.0.1", "", {}, "sha512-L50zbvrQ35TkpHwv0G6aLSuueDRwc/97XdY8kL3tOT0FmhgG7UypU3VztfV/LATAvmUfYi4wNxSajhSAeNN+Kg=="],
|
|
307
|
+
|
|
308
|
+
"pug-strip-comments": ["pug-strip-comments@2.0.0", "", { "dependencies": { "pug-error": "^2.0.0" } }, "sha512-zo8DsDpH7eTkPHCXFeAk1xZXJbyoTfdPlNR0bK7rpOMuhBYb0f5qUVCO1xlsitYd3w5FQTK7zpNVKb3rZoUrrQ=="],
|
|
309
|
+
|
|
310
|
+
"pug-walk": ["pug-walk@2.0.0", "", {}, "sha512-yYELe9Q5q9IQhuvqsZNwA5hfPkMJ8u92bQLIMcsMxf/VADjNtEYptU+inlufAFYcWdHlwNfZOEnOOQrZrcyJCQ=="],
|
|
311
|
+
|
|
312
|
+
"pump": ["pump@3.0.4", "", { "dependencies": { "end-of-stream": "^1.1.0", "once": "^1.3.1" } }, "sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA=="],
|
|
313
|
+
|
|
314
|
+
"queue-microtask": ["queue-microtask@1.2.3", "", {}, "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A=="],
|
|
315
|
+
|
|
316
|
+
"repeat-string": ["repeat-string@1.6.1", "", {}, "sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w=="],
|
|
317
|
+
|
|
318
|
+
"reprism": ["reprism@0.0.11", "", {}, "sha512-VsxDR5QxZo08M/3nRypNlScw5r3rKeSOPdU/QhDmu3Ai3BJxHn/qgfXGWQp/tAxUtzwYNo9W6997JZR0tPLZsA=="],
|
|
319
|
+
|
|
320
|
+
"resolve": ["resolve@1.22.11", "", { "dependencies": { "is-core-module": "^2.16.1", "path-parse": "^1.0.7", "supports-preserve-symlinks-flag": "^1.0.0" }, "bin": { "resolve": "bin/resolve" } }, "sha512-RfqAvLnMl313r7c9oclB1HhUEAezcpLjz95wFH4LVuhk9JF/r22qmVP9AMmOU4vMX7Q8pN8jwNg/CSpdFnMjTQ=="],
|
|
321
|
+
|
|
322
|
+
"reusify": ["reusify@1.1.0", "", {}, "sha512-g6QUff04oZpHs0eG5p83rFLhHeV00ug/Yf9nZM6fLeUrPguBTkTQOdpAWWspMh55TZfVQDPaN3NQJfbVRAxdIw=="],
|
|
323
|
+
|
|
324
|
+
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
|
|
325
|
+
|
|
326
|
+
"shebang-command": ["shebang-command@2.0.0", "", { "dependencies": { "shebang-regex": "^3.0.0" } }, "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA=="],
|
|
327
|
+
|
|
328
|
+
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
|
|
329
|
+
|
|
330
|
+
"signal-exit": ["signal-exit@3.0.7", "", {}, "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="],
|
|
331
|
+
|
|
332
|
+
"smol-toml": ["smol-toml@1.6.0", "", {}, "sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw=="],
|
|
333
|
+
|
|
334
|
+
"spark-md5": ["spark-md5@3.0.2", "", {}, "sha512-wcFzz9cDfbuqe0FZzfi2or1sgyIrsDwmPwfZC4hiNidPdPINjeUwNfv5kldczoEAcjl9Y1L3SM7Uz2PUEQzxQw=="],
|
|
335
|
+
|
|
336
|
+
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
|
|
337
|
+
|
|
338
|
+
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
|
|
339
|
+
|
|
340
|
+
"strip-final-newline": ["strip-final-newline@2.0.0", "", {}, "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="],
|
|
341
|
+
|
|
342
|
+
"strip-json-comments": ["strip-json-comments@5.0.3", "", {}, "sha512-1tB5mhVo7U+ETBKNf92xT4hrQa3pm0MZ0PQvuDnWgAAGHDsfp4lPSpiS6psrSiet87wyGPh9ft6wmhOMQ0hDiw=="],
|
|
343
|
+
|
|
344
|
+
"supports-preserve-symlinks-flag": ["supports-preserve-symlinks-flag@1.0.0", "", {}, "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="],
|
|
345
|
+
|
|
346
|
+
"to-regex-range": ["to-regex-range@5.0.1", "", { "dependencies": { "is-number": "^7.0.0" } }, "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ=="],
|
|
347
|
+
|
|
348
|
+
"token-stream": ["token-stream@1.0.0", "", {}, "sha512-VSsyNPPW74RpHwR8Fc21uubwHY7wMDeJLys2IX5zJNih+OnAnaifKHo+1LHT7DAdloQ7apeaaWg8l7qnf/TnEg=="],
|
|
349
|
+
|
|
350
|
+
"tslib": ["tslib@2.8.1", "", {}, "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w=="],
|
|
351
|
+
|
|
352
|
+
"typescript": ["typescript@5.9.3", "", { "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" } }, "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw=="],
|
|
353
|
+
|
|
354
|
+
"unbash": ["unbash@2.2.0", "", {}, "sha512-X2wH19RAPZE3+ldGicOkoj/SIA83OIxcJ6Cuaw23hf8Xc6fQpvZXY0SftE2JgS0QhYLUG4uwodSI3R53keyh7w=="],
|
|
355
|
+
|
|
356
|
+
"undici-types": ["undici-types@7.18.2", "", {}, "sha512-AsuCzffGHJybSaRrmr5eHr81mwJU3kjw6M+uprWvCXiNeN9SOGwQ3Jn8jb8m3Z6izVgknn1R0FTCEAP2QrLY/w=="],
|
|
357
|
+
|
|
358
|
+
"universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
|
|
359
|
+
|
|
360
|
+
"void-elements": ["void-elements@3.1.0", "", {}, "sha512-Dhxzh5HZuiHQhbvTW9AMetFfBHDMYpo23Uo9btPXgdYP+3T5S+p+jgNy7spra+veYhBP2dCSgxR/i2Y02h5/6w=="],
|
|
361
|
+
|
|
362
|
+
"walk-up-path": ["walk-up-path@4.0.0", "", {}, "sha512-3hu+tD8YzSLGuFYtPRb48vdhKMi0KQV5sn+uWr8+7dMEq/2G/dtLrdDinkLjqq5TIbIBjYJ4Ax/n3YiaW7QM8A=="],
|
|
363
|
+
|
|
364
|
+
"which": ["which@2.0.2", "", { "dependencies": { "isexe": "^2.0.0" }, "bin": { "node-which": "./bin/node-which" } }, "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA=="],
|
|
365
|
+
|
|
366
|
+
"with": ["with@7.0.2", "", { "dependencies": { "@babel/parser": "^7.9.6", "@babel/types": "^7.9.6", "assert-never": "^1.2.1", "babel-walk": "3.0.0-canary-5" } }, "sha512-RNGKj82nUPg3g5ygxkQl0R937xLyho1J24ItRCBTr/m1YnZkzJy1hUiHUJrc/VlsDQzsCnInEGSg3bci0Lmd4w=="],
|
|
367
|
+
|
|
368
|
+
"wrappy": ["wrappy@1.0.2", "", {}, "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="],
|
|
369
|
+
|
|
370
|
+
"yaml": ["yaml@2.8.2", "", { "bin": { "yaml": "bin.mjs" } }, "sha512-mplynKqc1C2hTVYxd0PU2xQAc22TI1vShAYGksCCfxbn/dFwnHTNi1bvYsBTkhdUNtGIf5xNOg938rrSSYvS9A=="],
|
|
371
|
+
|
|
372
|
+
"yoctocolors": ["yoctocolors@2.1.2", "", {}, "sha512-CzhO+pFNo8ajLM2d2IW/R93ipy99LWjtwblvC1RsoSUMZgyLbYFr221TnSNT7GjGdYui6P459mw9JH/g/zW2ug=="],
|
|
373
|
+
|
|
374
|
+
"zod": ["zod@4.3.6", "", {}, "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg=="],
|
|
375
|
+
|
|
376
|
+
"micromatch/picomatch": ["picomatch@2.3.1", "", {}, "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="],
|
|
377
|
+
}
|
|
378
|
+
}
|
package/knip.json
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{ "ignoreBinaries": ["tsc", "src/cli.ts"] }
|
package/package.json
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "yoctomarkdown",
|
|
3
|
+
"version": "0.0.1",
|
|
4
|
+
"module": "src/index.ts",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"devDependencies": {
|
|
7
|
+
"@biomejs/biome": "^2.4.7",
|
|
8
|
+
"@types/bun": "latest",
|
|
9
|
+
"husky": "^9.1.7",
|
|
10
|
+
"jscpd": "^4.0.8",
|
|
11
|
+
"knip": "^5.86.0",
|
|
12
|
+
"prettier": "^3.8.1"
|
|
13
|
+
},
|
|
14
|
+
"peerDependencies": {
|
|
15
|
+
"typescript": "^5.9.3"
|
|
16
|
+
},
|
|
17
|
+
"dependencies": {
|
|
18
|
+
"yoctocolors": "^2.1.2"
|
|
19
|
+
},
|
|
20
|
+
"bin": {
|
|
21
|
+
"yoctomarkdown": "./src/cli.ts"
|
|
22
|
+
},
|
|
23
|
+
"scripts": {
|
|
24
|
+
"typecheck": "tsc --noEmit",
|
|
25
|
+
"knip": "knip",
|
|
26
|
+
"jscpd": "jscpd . --ignore \"node_modules/**\"",
|
|
27
|
+
"check": "bun run format:check && bun run lint && bun run typecheck && bun run knip && bun run jscpd",
|
|
28
|
+
"prepare": "husky",
|
|
29
|
+
"lint": "biome lint .",
|
|
30
|
+
"format": "prettier --write .",
|
|
31
|
+
"format:check": "prettier --check .",
|
|
32
|
+
"test": "bun test"
|
|
33
|
+
}
|
|
34
|
+
}
|
package/spec.md
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
# YoctoMarkdown Specification
|
|
2
|
+
|
|
3
|
+
YoctoMarkdown is a small Bun-native Markdown highlighter for terminal output.
|
|
4
|
+
It reads Markdown and writes ANSI-colored text to stdout or returns it as a string.
|
|
5
|
+
The focus is simple, fast, incremental rendering for CLI and Programmatic use.
|
|
6
|
+
|
|
7
|
+
## Overview
|
|
8
|
+
|
|
9
|
+
YoctoMarkdown MUST:
|
|
10
|
+
|
|
11
|
+
- accept Markdown from a complete string, a file, or a stream
|
|
12
|
+
- process input incrementally
|
|
13
|
+
- render supported Markdown syntax as ANSI-styled terminal text
|
|
14
|
+
- preserve unsupported or malformed Markdown as plain text
|
|
15
|
+
- avoid buffering the full document when used in streaming mode
|
|
16
|
+
|
|
17
|
+
YoctoMarkdown is not a full CommonMark implementation.
|
|
18
|
+
It supports a small, practical subset intended for terminal display.
|
|
19
|
+
|
|
20
|
+
## Dependencies
|
|
21
|
+
|
|
22
|
+
YoctoMarkdown is intended to use:
|
|
23
|
+
|
|
24
|
+
- **Bun** as the runtime, stream, and build tool
|
|
25
|
+
- **yoctocolors** from npm for ANSI color rendering - https://github.com/sindresorhus/yoctocolors
|
|
26
|
+
|
|
27
|
+
## Supported Markdown
|
|
28
|
+
|
|
29
|
+
Version 1 supports the following syntax:
|
|
30
|
+
|
|
31
|
+
| Element | Syntax | Behavior |
|
|
32
|
+
| ----------------- | ------------------ | ------------------ |
|
|
33
|
+
| Heading 1 | `# Title` | styled heading |
|
|
34
|
+
| Heading 2 | `## Title` | styled heading |
|
|
35
|
+
| Heading 3 | `### Title` | styled heading |
|
|
36
|
+
| Bold | `**text**` | styled inline text |
|
|
37
|
+
| Italic | `*text*` | styled inline text |
|
|
38
|
+
| Inline code | `` `code` `` | styled inline code |
|
|
39
|
+
| Fenced code block | ` ``` ` | styled block code |
|
|
40
|
+
| Link | `[text](url)` | styled link text |
|
|
41
|
+
| Unordered list | `- item`, `* item` | styled marker |
|
|
42
|
+
| Ordered list | `1. item` | styled marker |
|
|
43
|
+
| Blockquote | `> quote` | styled marker |
|
|
44
|
+
| Horizontal rule | `---` | styled rule |
|
|
45
|
+
| Plain text | any other text | unchanged text |
|
|
46
|
+
|
|
47
|
+
Unsupported syntax MUST be rendered as plain text.
|
|
48
|
+
|
|
49
|
+
## Parsing Rules
|
|
50
|
+
|
|
51
|
+
The parser is line-aware and incremental.
|
|
52
|
+
|
|
53
|
+
### Block rules
|
|
54
|
+
|
|
55
|
+
- Headings are recognized only at the start of a line.
|
|
56
|
+
- Only `#`, `##`, and `###` headings are supported.
|
|
57
|
+
- Fenced code blocks use triple backticks.
|
|
58
|
+
- Inside a fenced code block, all text is treated as code until a closing triple backtick fence is found.
|
|
59
|
+
- Horizontal rules are recognized only when the full trimmed line is `---`, `***`, or `___`.
|
|
60
|
+
- List and blockquote markers are recognized only at the start of a line.
|
|
61
|
+
|
|
62
|
+
### Inline rules
|
|
63
|
+
|
|
64
|
+
- Inline code has priority over other inline formatting.
|
|
65
|
+
- Links are recognized only in the form `[text](url)`.
|
|
66
|
+
- Bold uses `**text**`.
|
|
67
|
+
- Italic uses `*text*`.
|
|
68
|
+
- Nested or ambiguous inline formatting is not required to match full CommonMark behavior.
|
|
69
|
+
|
|
70
|
+
### Malformed input
|
|
71
|
+
|
|
72
|
+
- Incomplete inline constructs MAY remain buffered while more input is expected.
|
|
73
|
+
- At end of input, any unclosed inline construct MUST be emitted as plain text.
|
|
74
|
+
- An unclosed fenced code block MUST render as code until end of input.
|
|
75
|
+
|
|
76
|
+
## Streaming Behavior
|
|
77
|
+
|
|
78
|
+
Streaming mode MUST work chunk by chunk.
|
|
79
|
+
|
|
80
|
+
For each chunk:
|
|
81
|
+
|
|
82
|
+
1. append the chunk to an internal buffer
|
|
83
|
+
2. parse as much complete Markdown as possible
|
|
84
|
+
3. render completed output immediately
|
|
85
|
+
4. keep only unresolved trailing text in the buffer
|
|
86
|
+
|
|
87
|
+
The implementation MUST preserve enough state to handle syntax split across chunk boundaries.
|
|
88
|
+
|
|
89
|
+
## Rendering
|
|
90
|
+
|
|
91
|
+
Rendering maps recognized Markdown elements to ANSI styles.
|
|
92
|
+
|
|
93
|
+
The implementation MUST provide these built-in theme names:
|
|
94
|
+
|
|
95
|
+
- `16`
|
|
96
|
+
- `256`
|
|
97
|
+
- `truecolor`
|
|
98
|
+
- `minimal`
|
|
99
|
+
- `none`
|
|
100
|
+
|
|
101
|
+
Theme behavior:
|
|
102
|
+
|
|
103
|
+
- headings MUST be visually distinct from plain text
|
|
104
|
+
- bold and italic SHOULD be visually distinct from plain text
|
|
105
|
+
- code and code blocks MUST be visually distinct from surrounding text
|
|
106
|
+
- links SHOULD be visually distinct from plain text
|
|
107
|
+
- list and blockquote markers MAY be styled independently
|
|
108
|
+
- `none` MUST disable ANSI styling entirely
|
|
109
|
+
|
|
110
|
+
The exact colors are implementation-defined.
|
|
111
|
+
|
|
112
|
+
## Configuration
|
|
113
|
+
|
|
114
|
+
The implementation MUST support the following options:
|
|
115
|
+
|
|
116
|
+
```ts
|
|
117
|
+
interface Options {
|
|
118
|
+
theme?: "16" | "256" | "truecolor" | "minimal" | "none" | Theme;
|
|
119
|
+
tabWidth?: number;
|
|
120
|
+
wordWrap?: number | "auto" | 0;
|
|
121
|
+
yieldEvery?: number;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
Default values:
|
|
126
|
+
|
|
127
|
+
- `theme`: `'16'`
|
|
128
|
+
- `tabWidth`: `2`
|
|
129
|
+
- `wordWrap`: `'auto'`
|
|
130
|
+
- `yieldEvery`: `1000`
|
|
131
|
+
|
|
132
|
+
### Word wrap
|
|
133
|
+
|
|
134
|
+
If wrapping is enabled:
|
|
135
|
+
|
|
136
|
+
- `'auto'` means terminal width when available, otherwise `80`
|
|
137
|
+
- `0` disables wrapping
|
|
138
|
+
- ANSI escape sequences MUST NOT count toward visible width
|
|
139
|
+
|
|
140
|
+
## Library API
|
|
141
|
+
|
|
142
|
+
The library MUST expose:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
highlightSync(input: string, options?: Options): string
|
|
146
|
+
createHighlighter(options?: Options): Highlighter
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
```ts
|
|
150
|
+
interface Highlighter {
|
|
151
|
+
write(chunk: string | Uint8Array): string;
|
|
152
|
+
end(): string;
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Behavior:
|
|
157
|
+
|
|
158
|
+
- `highlightSync()` returns the fully rendered ANSI string for a complete input string
|
|
159
|
+
- `createHighlighter()` returns an incremental highlighter
|
|
160
|
+
- `write()` returns rendered output for the provided chunk
|
|
161
|
+
- `end()` flushes any remaining buffered text
|
|
162
|
+
|
|
163
|
+
## CLI
|
|
164
|
+
|
|
165
|
+
The CLI command is:
|
|
166
|
+
|
|
167
|
+
```text
|
|
168
|
+
yoctomarkdown [options] [file]
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
If `file` is provided, the CLI reads that file.
|
|
172
|
+
Otherwise, it reads from stdin.
|
|
173
|
+
|
|
174
|
+
Supported options:
|
|
175
|
+
|
|
176
|
+
- `-t, --theme <name>`
|
|
177
|
+
- `-w, --wrap <n|auto|0>`
|
|
178
|
+
- `-h, --help`
|
|
179
|
+
|
|
180
|
+
The CLI MUST:
|
|
181
|
+
|
|
182
|
+
- write rendered output to stdout
|
|
183
|
+
- write diagnostics to stderr
|
|
184
|
+
- exit with status `0` on success
|
|
185
|
+
- exit with non-zero status on input or argument errors
|
|
186
|
+
|
|
187
|
+
## Non-Goals
|
|
188
|
+
|
|
189
|
+
- full CommonMark compliance
|
|
190
|
+
- GFM extensions such as tables, task lists, or strikethrough
|
|
191
|
+
- HTML rendering
|
|
192
|
+
- syntax highlighting inside code blocks
|
|
193
|
+
- AST generation
|
package/src/cli.ts
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
import { readFileSync } from "node:fs";
|
|
3
|
+
import { parseArgs } from "node:util";
|
|
4
|
+
import { createHighlighter, type Options } from "./index";
|
|
5
|
+
|
|
6
|
+
const { values, positionals } = parseArgs({
|
|
7
|
+
args: Bun.argv.slice(2),
|
|
8
|
+
options: {
|
|
9
|
+
theme: { type: "string", short: "t" },
|
|
10
|
+
wrap: { type: "string", short: "w" },
|
|
11
|
+
help: { type: "boolean", short: "h" },
|
|
12
|
+
},
|
|
13
|
+
allowPositionals: true,
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
if (values.help) {
|
|
17
|
+
console.log(`
|
|
18
|
+
Usage: yoctomarkdown [options] [file]
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
-t, --theme <name> Theme to use: 16, 256, truecolor, minimal, none (default: 16)
|
|
22
|
+
-w, --wrap <n|auto|0> Word wrap setting (default: auto)
|
|
23
|
+
-h, --help Show this help message
|
|
24
|
+
`);
|
|
25
|
+
process.exit(0);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const themeName = values.theme || "16";
|
|
29
|
+
const validThemes = ["16", "256", "truecolor", "minimal", "none"];
|
|
30
|
+
if (!validThemes.includes(themeName)) {
|
|
31
|
+
console.error(`Invalid theme: ${themeName}`);
|
|
32
|
+
process.exit(1);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const wrapVal = values.wrap || "auto";
|
|
36
|
+
let wordWrap: number | "auto" | 0 = "auto";
|
|
37
|
+
if (wrapVal === "auto" || wrapVal === "0") {
|
|
38
|
+
wordWrap = wrapVal === "auto" ? "auto" : 0;
|
|
39
|
+
} else {
|
|
40
|
+
const n = parseInt(wrapVal, 10);
|
|
41
|
+
if (Number.isNaN(n) || n < 0) {
|
|
42
|
+
console.error(`Invalid wrap value: ${wrapVal}`);
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
wordWrap = n;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
const options: Options = {
|
|
49
|
+
theme: themeName as Options["theme"],
|
|
50
|
+
wordWrap,
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const highlighter = createHighlighter(options);
|
|
54
|
+
|
|
55
|
+
async function run() {
|
|
56
|
+
if (positionals.length > 0) {
|
|
57
|
+
const file = positionals[0] as string;
|
|
58
|
+
try {
|
|
59
|
+
const content = readFileSync(file, "utf8");
|
|
60
|
+
process.stdout.write(highlighter.write(content));
|
|
61
|
+
process.stdout.write(highlighter.end());
|
|
62
|
+
} catch (err: unknown) {
|
|
63
|
+
console.error(
|
|
64
|
+
`Error reading file: ${err instanceof Error ? err.message : String(err)}`,
|
|
65
|
+
);
|
|
66
|
+
process.exit(1);
|
|
67
|
+
}
|
|
68
|
+
} else {
|
|
69
|
+
for await (const chunk of process.stdin) {
|
|
70
|
+
process.stdout.write(highlighter.write(chunk));
|
|
71
|
+
}
|
|
72
|
+
process.stdout.write(highlighter.end());
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
run();
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
import { type Theme, themes } from "./themes";
|
|
2
|
+
|
|
3
|
+
export interface Options {
|
|
4
|
+
theme?: "16" | "256" | "truecolor" | "minimal" | "none" | Theme;
|
|
5
|
+
tabWidth?: number;
|
|
6
|
+
wordWrap?: number | "auto" | 0;
|
|
7
|
+
yieldEvery?: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export interface Highlighter {
|
|
11
|
+
write(chunk: string | Uint8Array): string;
|
|
12
|
+
end(): string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function resolveTheme(options?: Options): Theme {
|
|
16
|
+
const t = options?.theme || "16";
|
|
17
|
+
if (typeof t === "string") {
|
|
18
|
+
return (themes[t] || themes.none) as Theme;
|
|
19
|
+
}
|
|
20
|
+
return t as Theme;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export function highlightSync(input: string, options?: Options): string {
|
|
24
|
+
const highlighter = createHighlighter(options);
|
|
25
|
+
const out = highlighter.write(input);
|
|
26
|
+
return out + highlighter.end();
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
export function createHighlighter(options?: Options): Highlighter {
|
|
30
|
+
const theme = resolveTheme(options);
|
|
31
|
+
let buffer = "";
|
|
32
|
+
let inCodeBlock = false;
|
|
33
|
+
|
|
34
|
+
function parseInline(text: string): string {
|
|
35
|
+
let result = "";
|
|
36
|
+
let i = 0;
|
|
37
|
+
while (i < text.length) {
|
|
38
|
+
if (text.startsWith("`", i) && !text.startsWith("``", i)) {
|
|
39
|
+
const end = text.indexOf("`", i + 1);
|
|
40
|
+
if (end !== -1) {
|
|
41
|
+
result += theme.code(`\`${text.slice(i + 1, end)}\``);
|
|
42
|
+
i = end + 1;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (text.startsWith("**", i)) {
|
|
48
|
+
const end = text.indexOf("**", i + 2);
|
|
49
|
+
if (end !== -1) {
|
|
50
|
+
result += theme.bold(`**${text.slice(i + 2, end)}**`);
|
|
51
|
+
i = end + 2;
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (text.startsWith("*", i) && !text.startsWith("**", i)) {
|
|
57
|
+
const end = text.indexOf("*", i + 1);
|
|
58
|
+
if (end !== -1 && !text.startsWith("**", end)) {
|
|
59
|
+
result += theme.italic(`*${text.slice(i + 1, end)}*`);
|
|
60
|
+
i = end + 1;
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (text.startsWith("[", i)) {
|
|
66
|
+
const bracketEnd = text.indexOf("]", i + 1);
|
|
67
|
+
if (bracketEnd !== -1 && text.charAt(bracketEnd + 1) === "(") {
|
|
68
|
+
const parenEnd = text.indexOf(")", bracketEnd + 2);
|
|
69
|
+
if (parenEnd !== -1) {
|
|
70
|
+
result += theme.link(
|
|
71
|
+
`[${text.slice(i + 1, bracketEnd)}](${text.slice(bracketEnd + 2, parenEnd)})`,
|
|
72
|
+
);
|
|
73
|
+
i = parenEnd + 1;
|
|
74
|
+
continue;
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
result += text[i];
|
|
80
|
+
i++;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
return result;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
function parseLine(line: string, _isLastLine: boolean): string {
|
|
87
|
+
if (inCodeBlock) {
|
|
88
|
+
if (line.trim().startsWith("```")) {
|
|
89
|
+
inCodeBlock = false;
|
|
90
|
+
return theme.codeBlock(line);
|
|
91
|
+
}
|
|
92
|
+
return theme.codeBlock(line);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (line.trim().startsWith("```")) {
|
|
96
|
+
inCodeBlock = true;
|
|
97
|
+
return theme.codeBlock(line);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
const hrMatch = line.trim().match(/^(?:-{3,}|\*{3,}|_{3,})$/);
|
|
101
|
+
if (hrMatch) {
|
|
102
|
+
return theme.hr(line);
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const headingMatch = line.match(/^(#{1,3})\s+(.*)$/);
|
|
106
|
+
if (headingMatch) {
|
|
107
|
+
const hashes = headingMatch[1] ?? "";
|
|
108
|
+
const text = headingMatch[2] ?? "";
|
|
109
|
+
return theme.heading(`${hashes} ${parseInline(text)}`);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const bqMatch = line.match(/^(>\s+)(.*)$/);
|
|
113
|
+
if (bqMatch) {
|
|
114
|
+
return theme.blockquote(bqMatch[1] ?? "") + parseInline(bqMatch[2] ?? "");
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const ulMatch = line.match(/^([-*]\s+)(.*)$/);
|
|
118
|
+
if (ulMatch) {
|
|
119
|
+
return theme.listMarker(ulMatch[1] ?? "") + parseInline(ulMatch[2] ?? "");
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const olMatch = line.match(/^(\d+\.\s+)(.*)$/);
|
|
123
|
+
if (olMatch) {
|
|
124
|
+
return theme.listMarker(olMatch[1] ?? "") + parseInline(olMatch[2] ?? "");
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
return parseInline(line);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
return {
|
|
131
|
+
write(chunk: string | Uint8Array): string {
|
|
132
|
+
const text =
|
|
133
|
+
typeof chunk === "string" ? chunk : new TextDecoder().decode(chunk);
|
|
134
|
+
buffer += text;
|
|
135
|
+
|
|
136
|
+
const lines = buffer.split("\n");
|
|
137
|
+
buffer = lines.pop() ?? "";
|
|
138
|
+
|
|
139
|
+
return (
|
|
140
|
+
lines.map((line) => parseLine(line, false)).join("\n") +
|
|
141
|
+
(lines.length > 0 ? "\n" : "")
|
|
142
|
+
);
|
|
143
|
+
},
|
|
144
|
+
end(): string {
|
|
145
|
+
if (buffer.length > 0) {
|
|
146
|
+
const out = parseLine(buffer, true);
|
|
147
|
+
buffer = "";
|
|
148
|
+
return out;
|
|
149
|
+
}
|
|
150
|
+
return "";
|
|
151
|
+
},
|
|
152
|
+
};
|
|
153
|
+
}
|
package/src/themes.ts
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import * as colors from "yoctocolors";
|
|
2
|
+
|
|
3
|
+
export interface Theme {
|
|
4
|
+
heading: (text: string) => string;
|
|
5
|
+
bold: (text: string) => string;
|
|
6
|
+
italic: (text: string) => string;
|
|
7
|
+
code: (text: string) => string;
|
|
8
|
+
codeBlock: (text: string) => string;
|
|
9
|
+
link: (text: string) => string;
|
|
10
|
+
listMarker: (text: string) => string;
|
|
11
|
+
blockquote: (text: string) => string;
|
|
12
|
+
hr: (text: string) => string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const none: Theme = {
|
|
16
|
+
heading: (t) => t,
|
|
17
|
+
bold: (t) => t,
|
|
18
|
+
italic: (t) => t,
|
|
19
|
+
code: (t) => t,
|
|
20
|
+
codeBlock: (t) => t,
|
|
21
|
+
link: (t) => t,
|
|
22
|
+
listMarker: (t) => t,
|
|
23
|
+
blockquote: (t) => t,
|
|
24
|
+
hr: (t) => t,
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const minimal: Theme = {
|
|
28
|
+
heading: colors.bold,
|
|
29
|
+
bold: colors.bold,
|
|
30
|
+
italic: colors.italic,
|
|
31
|
+
code: colors.bgGray,
|
|
32
|
+
codeBlock: colors.dim,
|
|
33
|
+
link: colors.underline,
|
|
34
|
+
listMarker: colors.dim,
|
|
35
|
+
blockquote: colors.dim,
|
|
36
|
+
hr: colors.dim,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const ansi16: Theme = {
|
|
40
|
+
heading: (t) => colors.cyan(colors.bold(t)),
|
|
41
|
+
bold: colors.bold,
|
|
42
|
+
italic: colors.italic,
|
|
43
|
+
code: (t) => colors.bgBlack(colors.yellow(t)),
|
|
44
|
+
codeBlock: colors.yellow,
|
|
45
|
+
link: colors.blue,
|
|
46
|
+
listMarker: colors.magenta,
|
|
47
|
+
blockquote: colors.green,
|
|
48
|
+
hr: colors.gray,
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
const ansi256 = ansi16; // In a full implementation we might map specific 256 colors
|
|
52
|
+
const truecolor = ansi16; // Same
|
|
53
|
+
|
|
54
|
+
export const themes: Record<string, Theme> = {
|
|
55
|
+
none,
|
|
56
|
+
minimal,
|
|
57
|
+
"16": ansi16,
|
|
58
|
+
"256": ansi256,
|
|
59
|
+
truecolor: truecolor,
|
|
60
|
+
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { test, expect, describe } from "bun:test";
|
|
2
|
+
import { $ } from "bun";
|
|
3
|
+
|
|
4
|
+
describe("CLI tests", () => {
|
|
5
|
+
test("should render from stdin", async () => {
|
|
6
|
+
const result =
|
|
7
|
+
await $`echo "# Hello World" | bun src/cli.ts --theme none`.text();
|
|
8
|
+
expect(result).toContain("Hello World");
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
test("should render an existing file", async () => {
|
|
12
|
+
const result = await $`bun src/cli.ts spec.md --theme none`.text();
|
|
13
|
+
expect(result.length).toBeGreaterThan(100);
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
test("CLI performance test", async () => {
|
|
17
|
+
const largeMdPath = "large_temp.md";
|
|
18
|
+
await $`bun -e 'require("fs").writeFileSync("${largeMdPath}", "# Performance\\n\\nSome **bold** text here.\\n".repeat(5000))'`;
|
|
19
|
+
|
|
20
|
+
const start = performance.now();
|
|
21
|
+
await $`bun src/cli.ts ${largeMdPath} --theme none`.text();
|
|
22
|
+
const end = performance.now();
|
|
23
|
+
|
|
24
|
+
const duration = end - start;
|
|
25
|
+
console.log(`CLI Execution Time: ${duration.toFixed(2)}ms`);
|
|
26
|
+
expect(duration).toBeLessThan(500); // Process boot + execution should be under 500ms
|
|
27
|
+
|
|
28
|
+
await $`rm ${largeMdPath}`;
|
|
29
|
+
});
|
|
30
|
+
});
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
import { test, expect, describe } from "bun:test";
|
|
2
|
+
import { highlightSync, createHighlighter } from "../src/index";
|
|
3
|
+
|
|
4
|
+
describe("Programmatic Usage: highlightSync", () => {
|
|
5
|
+
test("should format basic markdown elements", () => {
|
|
6
|
+
const res = highlightSync("# Heading\n\n**bold** and *italic*", {
|
|
7
|
+
theme: "none",
|
|
8
|
+
});
|
|
9
|
+
expect(res).toContain("Heading");
|
|
10
|
+
expect(res).toContain("bold");
|
|
11
|
+
expect(res).toContain("italic");
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test("should format lists", () => {
|
|
15
|
+
const res = highlightSync("- Item 1\n- Item 2\n1. Number 1", {
|
|
16
|
+
theme: "none",
|
|
17
|
+
});
|
|
18
|
+
expect(res).toContain("Item 1");
|
|
19
|
+
expect(res).toContain("Item 2");
|
|
20
|
+
expect(res).toContain("Number 1");
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
test("performance test on large input", () => {
|
|
24
|
+
const largeMd = "# Heading\n\nSome **bold** text here.\n".repeat(5000);
|
|
25
|
+
const start = performance.now();
|
|
26
|
+
highlightSync(largeMd, { theme: "none" });
|
|
27
|
+
const end = performance.now();
|
|
28
|
+
|
|
29
|
+
const duration = end - start;
|
|
30
|
+
console.log(`Programmatic Parse Time: ${duration.toFixed(2)}ms`);
|
|
31
|
+
expect(duration).toBeLessThan(200); // 5000 lines should be fast
|
|
32
|
+
});
|
|
33
|
+
});
|
|
34
|
+
|
|
35
|
+
describe("Programmatic Usage: createHighlighter (Streaming)", () => {
|
|
36
|
+
test("should handle chunks without breaking output", () => {
|
|
37
|
+
const highlighter = createHighlighter({ theme: "none" });
|
|
38
|
+
let res = highlighter.write("# Hea");
|
|
39
|
+
res += highlighter.write("ding\n");
|
|
40
|
+
res += highlighter.write("\nSome **tex");
|
|
41
|
+
res += highlighter.write("t**\n");
|
|
42
|
+
res += highlighter.end();
|
|
43
|
+
|
|
44
|
+
expect(res).toContain("Heading");
|
|
45
|
+
expect(res).toContain("Some **text**");
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
test("should handle character by character streaming", () => {
|
|
49
|
+
const markdown =
|
|
50
|
+
"# Title\n\nThis is a **test** of *character* streaming.\n\n- item 1\n- item 2\n";
|
|
51
|
+
const highlighter = createHighlighter({ theme: "none" });
|
|
52
|
+
let res = "";
|
|
53
|
+
for (const char of markdown) {
|
|
54
|
+
res += highlighter.write(char);
|
|
55
|
+
}
|
|
56
|
+
res += highlighter.end();
|
|
57
|
+
|
|
58
|
+
const expected = highlightSync(markdown, { theme: "none" });
|
|
59
|
+
expect(res).toBe(expected);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
test("should handle random chunk sizes", () => {
|
|
63
|
+
const markdown =
|
|
64
|
+
"```javascript\nconst x = 1;\n```\n\n# Heading 2\n\nSome text with `code`.\n> Blockquote here\n\n1. One\n2. Two\n";
|
|
65
|
+
const highlighter = createHighlighter({ theme: "none" });
|
|
66
|
+
let res = "";
|
|
67
|
+
|
|
68
|
+
// Split into random chunks
|
|
69
|
+
let i = 0;
|
|
70
|
+
while (i < markdown.length) {
|
|
71
|
+
const chunkSize = Math.floor(Math.random() * 10) + 1;
|
|
72
|
+
res += highlighter.write(markdown.slice(i, i + chunkSize));
|
|
73
|
+
i += chunkSize;
|
|
74
|
+
}
|
|
75
|
+
res += highlighter.end();
|
|
76
|
+
|
|
77
|
+
const expected = highlightSync(markdown, { theme: "none" });
|
|
78
|
+
expect(res).toBe(expected);
|
|
79
|
+
});
|
|
80
|
+
});
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
// Environment setup & latest features
|
|
4
|
+
"lib": ["ESNext"],
|
|
5
|
+
"target": "ESNext",
|
|
6
|
+
"module": "Preserve",
|
|
7
|
+
"moduleDetection": "force",
|
|
8
|
+
"jsx": "react-jsx",
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
|
|
11
|
+
// Bundler mode
|
|
12
|
+
"moduleResolution": "bundler",
|
|
13
|
+
"allowImportingTsExtensions": true,
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"noEmit": true,
|
|
16
|
+
|
|
17
|
+
// Best practices
|
|
18
|
+
"strict": true,
|
|
19
|
+
"skipLibCheck": true,
|
|
20
|
+
"noFallthroughCasesInSwitch": true,
|
|
21
|
+
"noUncheckedIndexedAccess": true,
|
|
22
|
+
"noImplicitOverride": true,
|
|
23
|
+
|
|
24
|
+
// Some stricter flags (disabled by default)
|
|
25
|
+
"noUnusedLocals": false,
|
|
26
|
+
"noUnusedParameters": false,
|
|
27
|
+
"noPropertyAccessFromIndexSignature": false
|
|
28
|
+
}
|
|
29
|
+
}
|