@gesslar/toolkit 3.25.0 → 3.27.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -9
- package/src/node/index.js +1 -0
- package/src/node/lib/DirectoryObject.js +23 -11
- package/src/node/lib/Font.js +263 -0
- package/src/node/lib/Sass.js +1 -1
- package/src/node/lib/Tantrum.js +1 -1
- package/src/node/lib/Term.js +351 -10
- package/src/node/lib/Util.js +1 -1
- package/types/node/index.d.ts +1 -0
- package/types/node/lib/DirectoryObject.d.ts +2 -2
- package/types/node/lib/DirectoryObject.d.ts.map +1 -1
- package/types/node/lib/Font.d.ts +113 -0
- package/types/node/lib/Font.d.ts.map +1 -0
- package/types/node/lib/Sass.d.ts +1 -1
- package/types/node/lib/Sass.d.ts.map +1 -1
- package/types/node/lib/Tantrum.d.ts +1 -1
- package/types/node/lib/Tantrum.d.ts.map +1 -1
- package/types/node/lib/Term.d.ts +150 -3
- package/types/node/lib/Term.d.ts.map +1 -1
- package/types/node/lib/Util.d.ts +1 -1
- package/types/node/lib/Util.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
"name": "gesslar",
|
|
6
6
|
"url": "https://gesslar.dev"
|
|
7
7
|
},
|
|
8
|
-
"version": "3.
|
|
8
|
+
"version": "3.27.0",
|
|
9
9
|
"license": "Unlicense",
|
|
10
10
|
"homepage": "https://github.com/gesslar/toolkit#readme",
|
|
11
11
|
"repository": {
|
|
@@ -52,22 +52,17 @@
|
|
|
52
52
|
"node": ">=24.13.0"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@eslint/js": "^9.39.2",
|
|
56
55
|
"@gesslar/colours": "^0.8.0",
|
|
57
|
-
"@stylistic/eslint-plugin": "^5.7.0",
|
|
58
56
|
"ajv": "^8.17.1",
|
|
59
|
-
"globals": "^17.0.0",
|
|
60
57
|
"json5": "^2.2.3",
|
|
61
|
-
"
|
|
58
|
+
"supports-color": "^10.2.2",
|
|
62
59
|
"yaml": "^2.8.2"
|
|
63
60
|
},
|
|
64
61
|
"devDependencies": {
|
|
65
62
|
"@gesslar/uglier": "^1.2.0",
|
|
66
63
|
"eslint": "^9.39.2",
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"typescript": "^5.9.3",
|
|
70
|
-
"typescript-eslint": "^8.53.1"
|
|
64
|
+
"happy-dom": "^20.3.7",
|
|
65
|
+
"typescript": "^5.9.3"
|
|
71
66
|
},
|
|
72
67
|
"scripts": {
|
|
73
68
|
"types": "node -e \"require('fs').rmSync('types',{recursive:true,force:true});\" && tsc -p tsconfig.types.json",
|
package/src/node/index.js
CHANGED
|
@@ -18,6 +18,7 @@ export {default as Cache} from "./lib/Cache.js"
|
|
|
18
18
|
export {default as DirectoryObject} from "./lib/DirectoryObject.js"
|
|
19
19
|
export {default as FileObject} from "./lib/FileObject.js"
|
|
20
20
|
export {default as FileSystem} from "./lib/FileSystem.js"
|
|
21
|
+
export {default as Font} from "./lib/Font.js"
|
|
21
22
|
export {default as Glog} from "./lib/Glog.js"
|
|
22
23
|
export {default as Notify} from "./lib/Notify.js"
|
|
23
24
|
export {default as Term} from "./lib/Term.js"
|
|
@@ -315,7 +315,10 @@ export default class DirectoryObject extends FS {
|
|
|
315
315
|
* const {files} = await dir.read("*.js")
|
|
316
316
|
* console.log(files) // Only .js files in ./src
|
|
317
317
|
*/
|
|
318
|
-
async read(pat="") {
|
|
318
|
+
async read(pat="", options={}) {
|
|
319
|
+
Valid.type(pat, "String")
|
|
320
|
+
Valid.type(options, "Object")
|
|
321
|
+
|
|
319
322
|
const withFileTypes = true
|
|
320
323
|
const url = this.url
|
|
321
324
|
|
|
@@ -325,10 +328,13 @@ export default class DirectoryObject extends FS {
|
|
|
325
328
|
const found = !pat
|
|
326
329
|
? await readdir(url, {withFileTypes})
|
|
327
330
|
: await Array.fromAsync(
|
|
328
|
-
glob(pat, {
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
331
|
+
glob(pat, Object.assign({},
|
|
332
|
+
options,
|
|
333
|
+
{ // nice try overwriting my options, tho
|
|
334
|
+
cwd: this.path,
|
|
335
|
+
withFileTypes,
|
|
336
|
+
})
|
|
337
|
+
)
|
|
332
338
|
)
|
|
333
339
|
|
|
334
340
|
const files = found
|
|
@@ -365,13 +371,19 @@ export default class DirectoryObject extends FS {
|
|
|
365
371
|
* // Find all package.json files recursively
|
|
366
372
|
* const {files} = await dir.glob("**\/package.json")
|
|
367
373
|
*/
|
|
368
|
-
async glob(pat="") {
|
|
374
|
+
async glob(pat="", options={}) {
|
|
375
|
+
Valid.type(pat, "String")
|
|
376
|
+
Valid.type(options, "Object")
|
|
377
|
+
|
|
369
378
|
const withFileTypes = true
|
|
370
379
|
const found = await Array.fromAsync(
|
|
371
|
-
glob(pat, {
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
380
|
+
glob(pat, Object.assign({},
|
|
381
|
+
options,
|
|
382
|
+
{ // teeheeheeeee
|
|
383
|
+
cwd: this.path,
|
|
384
|
+
withFileTypes,
|
|
385
|
+
})
|
|
386
|
+
)
|
|
375
387
|
)
|
|
376
388
|
|
|
377
389
|
const files = [], directories = []
|
|
@@ -392,7 +404,7 @@ export default class DirectoryObject extends FS {
|
|
|
392
404
|
|
|
393
405
|
directories.push(directory)
|
|
394
406
|
} else {
|
|
395
|
-
throw Sass.new(`wtf is this? ${e}`)
|
|
407
|
+
throw Sass.new(`wtf is this? ${JSON.stringify(e)}`)
|
|
396
408
|
}
|
|
397
409
|
}
|
|
398
410
|
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Font.js
|
|
3
|
+
* @description Utility class for detecting Nerd Fonts installed on the system.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import os from "os"
|
|
7
|
+
import {promisify} from "node:util"
|
|
8
|
+
import child_process from "node:child_process"
|
|
9
|
+
|
|
10
|
+
import DirectoryObject from "./DirectoryObject.js"
|
|
11
|
+
import FS from "./FileSystem.js"
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @import {FileObject} from "./FileObject.js"
|
|
15
|
+
*/
|
|
16
|
+
|
|
17
|
+
const execFile = promisify(child_process.execFile)
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* Utility class for detecting and identifying Nerd Fonts installed on the system.
|
|
21
|
+
* Supports Windows, macOS, and Linux platforms.
|
|
22
|
+
*
|
|
23
|
+
* Nerd Fonts are patched fonts that include additional glyphs such as icons,
|
|
24
|
+
* file type symbols, and powerline characters commonly used in terminal applications.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* // Check if any Nerd Fonts are installed
|
|
28
|
+
* const hasNerd = await Font.hasNerdFonts()
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* // Get list of installed Nerd Fonts
|
|
32
|
+
* const fonts = await Font.findNerdFonts()
|
|
33
|
+
* console.log(fonts) // ["FiraCode", "JetBrainsMono", ...]
|
|
34
|
+
*/
|
|
35
|
+
export default class Font {
|
|
36
|
+
static #cache = new Map()
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Finds all Nerd Fonts installed on the system.
|
|
40
|
+
* Detects the current platform and uses platform-specific methods
|
|
41
|
+
* to locate font files or query the font database.
|
|
42
|
+
*
|
|
43
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names, or empty array if none found.
|
|
44
|
+
* @example
|
|
45
|
+
* const nerdFonts = await Font.findNerdFonts()
|
|
46
|
+
* console.log(nerdFonts) // ["FiraCode Nerd Font", "JetBrains Mono NF", ...]
|
|
47
|
+
*/
|
|
48
|
+
static async findNerdFonts() {
|
|
49
|
+
if(!this.#cache.has("nerdFonts")) {
|
|
50
|
+
const platform = os.platform()
|
|
51
|
+
|
|
52
|
+
if(platform === "win32")
|
|
53
|
+
this.#cache.set("nerdFonts", this.#findNerdFontsWindows())
|
|
54
|
+
else if(platform === "darwin")
|
|
55
|
+
this.#cache.set("nerdFonts", this.#findNerdFontsMac())
|
|
56
|
+
else if(platform === "linux")
|
|
57
|
+
this.#cache.set("nerdFonts", this.#findNerdFontsLinux())
|
|
58
|
+
else
|
|
59
|
+
this.#cache.set("nerdFonts", [])
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return this.#cache.get("nerdFonts")
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* Checks whether any Nerd Fonts are installed on the system.
|
|
67
|
+
*
|
|
68
|
+
* @returns {Promise<boolean>} True if at least one Nerd Font is installed.
|
|
69
|
+
* @example
|
|
70
|
+
* if(await Font.hasNerdFonts()) {
|
|
71
|
+
* console.log("Nerd Fonts available - using fancy icons!")
|
|
72
|
+
* }
|
|
73
|
+
*/
|
|
74
|
+
static async hasNerdFonts() {
|
|
75
|
+
return (await this.findNerdFonts()).length > 0
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Gets the base family names of installed Nerd Fonts.
|
|
80
|
+
* Strips the "NF" or "Nerd Font" suffix to return the core font name.
|
|
81
|
+
*
|
|
82
|
+
* @returns {Promise<Array<string>>} Array of base font family names.
|
|
83
|
+
* @example
|
|
84
|
+
* const families = await Font.getNerdFontFamilies()
|
|
85
|
+
* console.log(families) // ["FiraCode", "JetBrains Mono", ...]
|
|
86
|
+
*/
|
|
87
|
+
static async getNerdFontFamilies() {
|
|
88
|
+
const fonts = await this.findNerdFonts()
|
|
89
|
+
|
|
90
|
+
// Strip the NF or Nerd Font suffix to get base name
|
|
91
|
+
return fonts.map(f => f.replace(/\s*(NF|Nerd\s*Font.*)$/i, "").trim())
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Strips font style suffixes from a font name.
|
|
96
|
+
*
|
|
97
|
+
* @param {string} fontName - The font name to clean.
|
|
98
|
+
* @returns {string} The font name without style suffixes.
|
|
99
|
+
* @private
|
|
100
|
+
*/
|
|
101
|
+
static #stripStyles(fontName) {
|
|
102
|
+
return fontName.replace(/[_-]?(Bold|Italic|Regular|Light|Medium|SemiBold|Black|Thin|ExtraLight|ExtraBold|Heavy)(Italic)?$/i, "").trim()
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Tests if a font name matches any Nerd Font naming patterns.
|
|
107
|
+
*
|
|
108
|
+
* @param {string} fontName - The font name to test.
|
|
109
|
+
* @param {Array<RegExp>} tests - Array of regex patterns to match against.
|
|
110
|
+
* @returns {boolean} True if the font name matches any pattern.
|
|
111
|
+
* @private
|
|
112
|
+
*/
|
|
113
|
+
static #isNerdFontName(fontName, tests) {
|
|
114
|
+
return tests.some(e => e.test(fontName))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/**
|
|
118
|
+
* Finds Nerd Fonts on Windows by scanning system and user font directories.
|
|
119
|
+
*
|
|
120
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names.
|
|
121
|
+
* @private
|
|
122
|
+
*/
|
|
123
|
+
static async #findNerdFontsWindows() {
|
|
124
|
+
const fontDirs = [
|
|
125
|
+
new DirectoryObject(FS.resolvePath(
|
|
126
|
+
process.env.WINDIR || "C:/Windows",
|
|
127
|
+
"/Fonts"
|
|
128
|
+
))
|
|
129
|
+
]
|
|
130
|
+
|
|
131
|
+
if(process.env.LOCALAPPDATA)
|
|
132
|
+
fontDirs.push(new DirectoryObject(FS.resolvePath(
|
|
133
|
+
process.env.LOCALAPPDATA,
|
|
134
|
+
"Microsoft/Windows/Fonts"
|
|
135
|
+
)))
|
|
136
|
+
|
|
137
|
+
const fontFiles = []
|
|
138
|
+
|
|
139
|
+
for(const fontDir of fontDirs) {
|
|
140
|
+
try {
|
|
141
|
+
if(!await fontDir.exists)
|
|
142
|
+
continue
|
|
143
|
+
|
|
144
|
+
const {files} = await fontDir.read("*.{ttf,otf}")
|
|
145
|
+
|
|
146
|
+
fontFiles.push(...files)
|
|
147
|
+
} catch {
|
|
148
|
+
// Directory doesn't exist or isn't accessible
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
this.#cache.set("nerdFonts", this.#identifyNerdFonts(fontFiles))
|
|
153
|
+
|
|
154
|
+
return this.#cache.get("nerdFonts")
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Finds Nerd Fonts on macOS by scanning system and user font directories.
|
|
159
|
+
*
|
|
160
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names.
|
|
161
|
+
* @private
|
|
162
|
+
*/
|
|
163
|
+
static async #findNerdFontsMac() {
|
|
164
|
+
const fontDirs = [
|
|
165
|
+
new DirectoryObject("/Library/Fonts")
|
|
166
|
+
]
|
|
167
|
+
|
|
168
|
+
if(process.env.HOME) {
|
|
169
|
+
fontDirs.push(new DirectoryObject(FS.resolvePath(process.env.HOME, "Library/Fonts")))
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const fontFiles = []
|
|
173
|
+
|
|
174
|
+
for(const fontDir of fontDirs) {
|
|
175
|
+
try {
|
|
176
|
+
if(!await fontDir.exists)
|
|
177
|
+
continue
|
|
178
|
+
|
|
179
|
+
const {files} = await fontDir.glob("**/*.{ttf,otf}")
|
|
180
|
+
|
|
181
|
+
fontFiles.push(...files)
|
|
182
|
+
} catch {
|
|
183
|
+
// Directory doesn't exist or isn't accessible
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
return this.#identifyNerdFonts(fontFiles)
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Finds Nerd Fonts on Linux using the fc-list command.
|
|
192
|
+
*
|
|
193
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names.
|
|
194
|
+
* @private
|
|
195
|
+
*/
|
|
196
|
+
static async #findNerdFontsLinux() {
|
|
197
|
+
try {
|
|
198
|
+
const {stdout: fonts} = await execFile(
|
|
199
|
+
"fc-list",
|
|
200
|
+
[":", "family"],
|
|
201
|
+
{encoding: "utf8"}
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
const nerdFonts = fonts
|
|
205
|
+
.split("\n")
|
|
206
|
+
.filter(line => line.trim())
|
|
207
|
+
.filter(f => this.#isNerdFontName(f, this.#nerdTestsLinux))
|
|
208
|
+
.map(line => line.split(",")[0].trim())
|
|
209
|
+
.filter((font, idx, arr) => arr.indexOf(font) === idx)
|
|
210
|
+
.sort()
|
|
211
|
+
|
|
212
|
+
return nerdFonts
|
|
213
|
+
} catch {
|
|
214
|
+
return []
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/** @type {Array<RegExp>} Patterns to identify Nerd Fonts by filename */
|
|
219
|
+
static #nerdTests = [/nerd/i, / nf[_\s.-]/i]
|
|
220
|
+
|
|
221
|
+
/** @type {Array<RegExp>} Patterns to identify Nerd Fonts in fc-list output */
|
|
222
|
+
static #nerdTestsLinux = [/nerd font/i, /\bnf\b/i]
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* Identifies Nerd Fonts from a list of font file objects.
|
|
226
|
+
*
|
|
227
|
+
* @param {Array<FileObject>} fileObjects - Array of FileObject instances representing font files.
|
|
228
|
+
* @returns {Array<string>} Sorted array of unique Nerd Font family names.
|
|
229
|
+
* @private
|
|
230
|
+
*/
|
|
231
|
+
static #identifyNerdFonts(fileObjects) {
|
|
232
|
+
const nerdFonts = new Set()
|
|
233
|
+
|
|
234
|
+
for(const file of fileObjects) {
|
|
235
|
+
const name = file.module
|
|
236
|
+
|
|
237
|
+
if(this.#isNerdFontName(name, this.#nerdTests)) {
|
|
238
|
+
nerdFonts.add(this.#stripStyles(name))
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return Array.from(nerdFonts).sort()
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Gets spinner animation frames appropriate for the current font environment.
|
|
247
|
+
* Returns Unicode braille characters if Nerd Fonts are available,
|
|
248
|
+
* otherwise returns ASCII fallback characters.
|
|
249
|
+
*
|
|
250
|
+
* @returns {Promise<Array<string>>} Promise resolving to array of spinner frame characters.
|
|
251
|
+
* @example
|
|
252
|
+
* const frames = await Font.spinFrames
|
|
253
|
+
* // With Nerd Fonts: ["⠋", "⠙", "⠹", ...]
|
|
254
|
+
* // Without: ["|", "/", "-", "\\"]
|
|
255
|
+
*/
|
|
256
|
+
static get spinFrames() {
|
|
257
|
+
return this.hasNerdFonts().then(has =>
|
|
258
|
+
has
|
|
259
|
+
? ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
|
260
|
+
: ["|", "/", "-", "\\"]
|
|
261
|
+
)
|
|
262
|
+
}
|
|
263
|
+
}
|
package/src/node/lib/Sass.js
CHANGED
package/src/node/lib/Tantrum.js
CHANGED
package/src/node/lib/Term.js
CHANGED
|
@@ -1,11 +1,69 @@
|
|
|
1
|
-
import console from "node:console"
|
|
1
|
+
import console, {Console} from "node:console"
|
|
2
2
|
import process from "node:process"
|
|
3
|
-
import {Console} from "node:console"
|
|
4
3
|
import {Writable} from "node:stream"
|
|
4
|
+
import supportsColor from "supports-color"
|
|
5
|
+
import {stripVTControlCharacters} from "node:util"
|
|
5
6
|
|
|
6
7
|
import Sass from "./Sass.js"
|
|
7
8
|
|
|
8
9
|
export default class Term {
|
|
10
|
+
static #cache = new Map()
|
|
11
|
+
|
|
12
|
+
static #preformat(text) {
|
|
13
|
+
return this.hasColor
|
|
14
|
+
? text
|
|
15
|
+
: stripVTControlCharacters(text)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Terminal width in columns.
|
|
20
|
+
*
|
|
21
|
+
* @type {number | undefined}
|
|
22
|
+
*/
|
|
23
|
+
static get columns() {
|
|
24
|
+
return process.stdout.columns
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Terminal height in rows.
|
|
29
|
+
*
|
|
30
|
+
* @type {number | undefined}
|
|
31
|
+
*/
|
|
32
|
+
static get rows() {
|
|
33
|
+
return process.stdout.rows
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Terminal dimensions as an object.
|
|
38
|
+
*
|
|
39
|
+
* @type {{columns: number | undefined, rows: number | undefined}}
|
|
40
|
+
*/
|
|
41
|
+
static get dim() {
|
|
42
|
+
return {columns: this.columns, rows: this.rows}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Whether the terminal is interactive (TTY and not in CI).
|
|
47
|
+
*
|
|
48
|
+
* @type {boolean}
|
|
49
|
+
*/
|
|
50
|
+
static get isInteractive() {
|
|
51
|
+
return this.#cache.has("isInteractive")
|
|
52
|
+
? this.#cache.get("isInteractive")
|
|
53
|
+
: this.#cache.set("isInteractive", Boolean(process.stdout.isTTY && !process.env.CI)).get("isInteractive")
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Whether the terminal supports color output.
|
|
58
|
+
*
|
|
59
|
+
* @type {boolean}
|
|
60
|
+
*/
|
|
61
|
+
static get hasColor() {
|
|
62
|
+
return this.#cache.has("hasColor")
|
|
63
|
+
? this.#cache.get("hasColor")
|
|
64
|
+
: this.#cache.set("hasColor", Boolean(supportsColor.stdout)).get("hasColor")
|
|
65
|
+
}
|
|
66
|
+
|
|
9
67
|
/**
|
|
10
68
|
* Log an informational message.
|
|
11
69
|
*
|
|
@@ -126,13 +184,13 @@ export default class Term {
|
|
|
126
184
|
// Keep: top border (line 0), data rows (line 3+)
|
|
127
185
|
const modified = [lines[0], ...lines.slice(3)]
|
|
128
186
|
|
|
129
|
-
|
|
187
|
+
this.write(modified.join("\n"))
|
|
130
188
|
} else if(showHeader) {
|
|
131
189
|
// Keep header but remove quotes if requested
|
|
132
|
-
|
|
190
|
+
this.write(processed)
|
|
133
191
|
} else {
|
|
134
192
|
// Fallback: just output as-is if format unexpected
|
|
135
|
-
|
|
193
|
+
this.write(processed)
|
|
136
194
|
}
|
|
137
195
|
}
|
|
138
196
|
|
|
@@ -241,18 +299,301 @@ export default class Term {
|
|
|
241
299
|
return `${brackets[0]}${text}${brackets[1]}`
|
|
242
300
|
}
|
|
243
301
|
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
302
|
+
/**
|
|
303
|
+
* ANSI escape sequence to move cursor to start of line.
|
|
304
|
+
*
|
|
305
|
+
* @type {string}
|
|
306
|
+
*/
|
|
307
|
+
static get start() {
|
|
308
|
+
return `\r`
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Move cursor to start of line (interactive terminals only).
|
|
313
|
+
*
|
|
314
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
315
|
+
*/
|
|
316
|
+
static moveStart() {
|
|
317
|
+
this.isInteractive && this.write(this.start)
|
|
318
|
+
|
|
319
|
+
return this
|
|
247
320
|
}
|
|
248
321
|
|
|
249
|
-
|
|
250
|
-
|
|
322
|
+
/**
|
|
323
|
+
* ANSI escape sequence to move cursor to end of line.
|
|
324
|
+
*
|
|
325
|
+
* @type {string}
|
|
326
|
+
*/
|
|
327
|
+
static get end() {
|
|
328
|
+
return `\x1b[${this.columns}G`
|
|
251
329
|
}
|
|
252
330
|
|
|
331
|
+
/**
|
|
332
|
+
* Move cursor to end of line (interactive terminals only).
|
|
333
|
+
*
|
|
334
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
335
|
+
*/
|
|
336
|
+
static moveEnd() {
|
|
337
|
+
this.isInteractive && this.write(this.end)
|
|
338
|
+
|
|
339
|
+
return this
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
/**
|
|
343
|
+
* ANSI escape sequence to move cursor up one line.
|
|
344
|
+
*
|
|
345
|
+
* @type {string}
|
|
346
|
+
*/
|
|
347
|
+
static get up() {
|
|
348
|
+
return `\x1b[1A`
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Move cursor up by specified number of lines (interactive terminals only).
|
|
353
|
+
*
|
|
354
|
+
* @param {number} num - Number of lines to move up.
|
|
355
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
356
|
+
*/
|
|
357
|
+
static moveUp(num) {
|
|
358
|
+
this.isInteractive && this.write(this.up.repeat(num))
|
|
359
|
+
|
|
360
|
+
return this
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
/**
|
|
364
|
+
* Hide the terminal cursor (interactive terminals only).
|
|
365
|
+
*
|
|
366
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
367
|
+
*/
|
|
368
|
+
static hideCursor() {
|
|
369
|
+
this.isInteractive && this.write("\x1b[?25l")
|
|
370
|
+
|
|
371
|
+
return this
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Show the terminal cursor (interactive terminals only).
|
|
376
|
+
*
|
|
377
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
378
|
+
*/
|
|
379
|
+
static showCursor() {
|
|
380
|
+
this.isInteractive && this.write("\x1b[?25h")
|
|
381
|
+
|
|
382
|
+
return this
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/**
|
|
386
|
+
* Whether the terminal is in character (raw) input mode.
|
|
387
|
+
*
|
|
388
|
+
* @type {boolean}
|
|
389
|
+
*/
|
|
390
|
+
static get isCharMode() {
|
|
391
|
+
if(!this.isInteractive)
|
|
392
|
+
return false
|
|
393
|
+
|
|
394
|
+
return process.stdin.isRaw
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Whether the terminal is in line (buffered) input mode.
|
|
399
|
+
*
|
|
400
|
+
* @type {boolean}
|
|
401
|
+
*/
|
|
402
|
+
static get isLineMode() {
|
|
403
|
+
if(!this.isInteractive)
|
|
404
|
+
return false
|
|
405
|
+
|
|
406
|
+
return !this.isCharMode
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Set terminal to character mode (raw input, interactive terminals only).
|
|
411
|
+
*
|
|
412
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
413
|
+
*/
|
|
414
|
+
static setCharMode() {
|
|
415
|
+
this.isInteractive && process.stdin.setRawMode(true)
|
|
416
|
+
|
|
417
|
+
return this
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
/**
|
|
421
|
+
* Set terminal to line mode (buffered input, interactive terminals only).
|
|
422
|
+
*
|
|
423
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
424
|
+
*/
|
|
425
|
+
static setLineMode() {
|
|
426
|
+
this.isInteractive && process.stdin.setRawMode(false)
|
|
427
|
+
|
|
428
|
+
return this
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* Clear the current line (interactive terminals only).
|
|
433
|
+
*
|
|
434
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
435
|
+
*/
|
|
436
|
+
static clearLine() {
|
|
437
|
+
this.isInteractive && this.write(`\x1b[2K`)
|
|
438
|
+
|
|
439
|
+
return this
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Clear multiple lines by moving up and clearing each (interactive terminals only).
|
|
444
|
+
*
|
|
445
|
+
* @param {number} num - Number of lines to clear.
|
|
446
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
447
|
+
*/
|
|
448
|
+
static clearLines(num) {
|
|
449
|
+
while(num--)
|
|
450
|
+
this.clearLine().moveUp()
|
|
451
|
+
|
|
452
|
+
return this
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Write output to stdout asynchronously (fire-and-forget).
|
|
457
|
+
*
|
|
458
|
+
* @param {string} output - The string to write.
|
|
459
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
460
|
+
*/
|
|
461
|
+
static write(output) {
|
|
462
|
+
this.directWrite(output).catch(console.error)
|
|
463
|
+
|
|
464
|
+
return this
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
/**
|
|
468
|
+
* Returns a promise that resolves with the next chunk of data from stdin.
|
|
469
|
+
* If in Char Mode, it resolves on Enter, Ctrl+D, or the ANSI 'R' terminator.
|
|
470
|
+
*
|
|
471
|
+
* @param {(text: string) => boolean} [terminator] - Optional callback to check if input is complete.
|
|
472
|
+
* @returns {Promise<string>} Resolves with the input data.
|
|
473
|
+
*/
|
|
474
|
+
static data(terminator = () => false) {
|
|
475
|
+
process.stdin.resume()
|
|
476
|
+
|
|
477
|
+
return new Promise((resolve, reject) => {
|
|
478
|
+
const chunks = []
|
|
479
|
+
|
|
480
|
+
function onData(chunk) {
|
|
481
|
+
const s = chunk.toString()
|
|
482
|
+
chunks.push(chunk)
|
|
483
|
+
|
|
484
|
+
const result = terminator(s)
|
|
485
|
+
|
|
486
|
+
if(result)
|
|
487
|
+
return onEnd()
|
|
488
|
+
|
|
489
|
+
if(Term.isCharMode) {
|
|
490
|
+
// Resolve on Enter, Ctrl+D
|
|
491
|
+
if(s === "\r" || s === "\n" || s === "\u0004")
|
|
492
|
+
return onEnd()
|
|
493
|
+
|
|
494
|
+
// Standard CLI escape: Ctrl+C
|
|
495
|
+
if(s === "\u0003")
|
|
496
|
+
process.exit()
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
function onEnd() {
|
|
501
|
+
cleanup()
|
|
502
|
+
|
|
503
|
+
const result = (chunks.length > 0 && typeof chunks[0] === "string")
|
|
504
|
+
? chunks.join("")
|
|
505
|
+
: Buffer.concat(chunks).toString()
|
|
506
|
+
|
|
507
|
+
resolve(result)
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
function onError(err) {
|
|
511
|
+
cleanup()
|
|
512
|
+
reject(err)
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
function cleanup() {
|
|
516
|
+
process.stdin.off("data", onData)
|
|
517
|
+
process.stdin.off("end", onEnd)
|
|
518
|
+
process.stdin.off("error", onError)
|
|
519
|
+
|
|
520
|
+
// ALWAYS pause when the specific task is done.
|
|
521
|
+
// It can be resumed by the next caller.
|
|
522
|
+
process.stdin.pause()
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
process.stdin.on("data", onData)
|
|
526
|
+
process.stdin.once("end", onEnd)
|
|
527
|
+
process.stdin.once("error", onError)
|
|
528
|
+
})
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
/**
|
|
532
|
+
* Gets the current cursor position in the terminal.
|
|
533
|
+
*
|
|
534
|
+
* @returns {Promise<[number, number]>} Resolves with [x, y] cursor position.
|
|
535
|
+
*/
|
|
536
|
+
static async getCursorPosition() {
|
|
537
|
+
const result = [0, 0]
|
|
538
|
+
|
|
539
|
+
if(!this.isInteractive)
|
|
540
|
+
return result
|
|
541
|
+
|
|
542
|
+
const prevRawMode = this.isCharMode
|
|
543
|
+
|
|
544
|
+
// 1. Force Raw Mode so the terminal sends the report immediately
|
|
545
|
+
this.setCharMode()
|
|
546
|
+
process.stdin.setEncoding("utf8")
|
|
547
|
+
|
|
548
|
+
// 2. Start the listener FIRST (do not await yet)
|
|
549
|
+
const dataPromise = this.data((text => {
|
|
550
|
+
return this.isCharMode && text.endsWith("R")
|
|
551
|
+
}).bind(this))
|
|
552
|
+
|
|
553
|
+
// 3. Write to stdout AFTER the listener is ready
|
|
554
|
+
this.write("\x1b[6n")
|
|
555
|
+
|
|
556
|
+
// 4. Now await the response
|
|
557
|
+
const positionData = await dataPromise
|
|
558
|
+
|
|
559
|
+
// 5. Restore the previous mode
|
|
560
|
+
prevRawMode ? this.setCharMode() : this.setLineMode()
|
|
561
|
+
|
|
562
|
+
const match = /\x1b\[(?<y>\d+);(?<x>\d+)R/.exec(positionData)
|
|
563
|
+
|
|
564
|
+
if(!match)
|
|
565
|
+
return result
|
|
566
|
+
|
|
567
|
+
const {x, y} = match.groups
|
|
568
|
+
|
|
569
|
+
// ANSI returns [row;col], which is [y;x]
|
|
570
|
+
return [parseInt(x, 10), parseInt(y, 10)]
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
/**
|
|
574
|
+
* Write output to stdout and return a promise that resolves when complete.
|
|
575
|
+
*
|
|
576
|
+
* @param {string} output - The string to write.
|
|
577
|
+
* @returns {Promise<void>} Resolves when write completes.
|
|
578
|
+
*/
|
|
253
579
|
static directWrite(output) {
|
|
254
580
|
return new Promise(resolve => {
|
|
255
581
|
process.stdout.write(output, () => resolve())
|
|
256
582
|
})
|
|
257
583
|
}
|
|
584
|
+
|
|
585
|
+
// Spinner frames - using Braille patterns (widely supported)
|
|
586
|
+
// Falls back to ASCII when spinimate is implemented with proper detection
|
|
587
|
+
static #spinFrames = ["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"]
|
|
588
|
+
|
|
589
|
+
// static async spinimate(delay=300, options = {position: {x: 0,y: 0}}) {
|
|
590
|
+
// const spinFrames = await this.#spinFrames
|
|
591
|
+
// const {x, y} = options?.position ?? {}
|
|
592
|
+
|
|
593
|
+
// if(!isNaN(shiftX) && !isNaN(shiftY)) {
|
|
594
|
+
// setTimeout(delay, () => {
|
|
595
|
+
|
|
596
|
+
// })
|
|
597
|
+
// }
|
|
598
|
+
// }
|
|
258
599
|
}
|
package/src/node/lib/Util.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {createHash} from "node:crypto"
|
|
2
2
|
import {EventEmitter} from "node:events"
|
|
3
|
-
import
|
|
3
|
+
import BrowserUtil from "../../browser/lib/Util.js"
|
|
4
4
|
import Sass from "./Sass.js"
|
|
5
5
|
import process from "node:process"
|
|
6
6
|
import JSON5 from "json5"
|
package/types/node/index.d.ts
CHANGED
|
@@ -11,6 +11,7 @@ export { default as Cache } from "./lib/Cache.js";
|
|
|
11
11
|
export { default as DirectoryObject } from "./lib/DirectoryObject.js";
|
|
12
12
|
export { default as FileObject } from "./lib/FileObject.js";
|
|
13
13
|
export { default as FileSystem } from "./lib/FileSystem.js";
|
|
14
|
+
export { default as Font } from "./lib/Font.js";
|
|
14
15
|
export { default as Glog } from "./lib/Glog.js";
|
|
15
16
|
export { default as Notify } from "./lib/Notify.js";
|
|
16
17
|
export { default as Term } from "./lib/Term.js";
|
|
@@ -175,7 +175,7 @@ export default class DirectoryObject extends FS {
|
|
|
175
175
|
* const {files} = await dir.read("*.js")
|
|
176
176
|
* console.log(files) // Only .js files in ./src
|
|
177
177
|
*/
|
|
178
|
-
read(pat?: string): Promise<{
|
|
178
|
+
read(pat?: string, options?: {}): Promise<{
|
|
179
179
|
files: Array<FileObject>;
|
|
180
180
|
directories: Array<DirectoryObject>;
|
|
181
181
|
}>;
|
|
@@ -198,7 +198,7 @@ export default class DirectoryObject extends FS {
|
|
|
198
198
|
* // Find all package.json files recursively
|
|
199
199
|
* const {files} = await dir.glob("**\/package.json")
|
|
200
200
|
*/
|
|
201
|
-
glob(pat?: string): Promise<{
|
|
201
|
+
glob(pat?: string, options?: {}): Promise<{
|
|
202
202
|
files: Array<FileObject | FileObject>;
|
|
203
203
|
directories: Array<DirectoryObject>;
|
|
204
204
|
}>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/DirectoryObject.js"],"names":[],"mappings":"AAgBA;;;;GAIG;AAEH;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH;IAuDE;;;;;;;;;OASG;IACH,kBALa,eAAe,CAO3B;IA7CD;;;;OAIG;IACH,uBAFW,MAAM,OAAC,EA4BjB;IAyBD;;;;OAIG;IACH,cAFa,OAAO,CAAC,OAAO,CAAC,CAI5B;IAED;;;;OAIG;IACH,gBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,YAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,WAFa,GAAG,CAIf;IAED;;;;OAIG;IACH,YAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,cAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,iBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,WAFa,MAAM,CAIlB;IAED;;;;;;;OAOG;IACH,aALa,KAAK,CAAC,MAAM,CAAC,CAOzB;IAED;;;;;;;;;;;;OAYG;IACH,cARa,eAAe,GAAC,IAAI,CAsBhC;IAED;;;;OAIG;IACH,mBAFa,OAAO,CAInB;IAmBD;;;;;;;;;;;;;;;;;OAiBG;IACH,WAZW,MAAM,
|
|
1
|
+
{"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/DirectoryObject.js"],"names":[],"mappings":"AAgBA;;;;GAIG;AAEH;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH;IAuDE;;;;;;;;;OASG;IACH,kBALa,eAAe,CAO3B;IA7CD;;;;OAIG;IACH,uBAFW,MAAM,OAAC,EA4BjB;IAyBD;;;;OAIG;IACH,cAFa,OAAO,CAAC,OAAO,CAAC,CAI5B;IAED;;;;OAIG;IACH,gBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,YAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,WAFa,GAAG,CAIf;IAED;;;;OAIG;IACH,YAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,cAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,iBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,WAFa,MAAM,CAIlB;IAED;;;;;;;OAOG;IACH,aALa,KAAK,CAAC,MAAM,CAAC,CAOzB;IAED;;;;;;;;;;;;OAYG;IACH,cARa,eAAe,GAAC,IAAI,CAsBhC;IAED;;;;OAIG;IACH,mBAFa,OAAO,CAInB;IAmBD;;;;;;;;;;;;;;;;;OAiBG;IACH,WAZW,MAAM,iBACJ,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;KAAC,CAAC,CA8CpF;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,WAZW,MAAM,iBACJ,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,UAAU,GAAC,UAAU,CAAC,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;KAAC,CAAC,CAiD/F;IAED;;;;;;;;;;;;OAYG;IACH,uBARW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAuBzB;IAyBD;;;;;;;;;;;;;;;OAeG;IACH,cAZa,eAAe,CAc3B;IAED;;;;;;;;;;;;;;OAcG;IACH,UARa,OAAO,CAAC,IAAI,CAAC,CAkBzB;IAED;;;;;OAKG;IACH,kBAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAM5B;IAED;;;;;OAKG;IACH,sBAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAO5B;IAED;;;;;;;;;;;;OAYG;IACH,sBAPW,MAAM,GACJ,eAAe,CA6B3B;IAED;;;;;;;;;;;OAWG;IACH,kBAPW,MAAM,GACJ,UAAU,CA6BtB;;CACF;;UAnlBa,MAAY;QAAC,KAAK,EAAE,eAAe,CAAC;QAAC,IAAI,EAAE,OAAO,CAAA;KAAC;eACnD,MAAY,aAAa;;;;;;iBAMzB,OAAO;;;;eACP,MAAM,GAAC,IAAI;;;;YACX,MAAM,GAAC,IAAI;;;;UACX,MAAM,GAAC,IAAI;;;;YACX,eAAe,GAAC,SAAS;;;;gBACzB,MAAM,GAAC,IAAI;;;;UACX,MAAM,GAAC,IAAI;;;;SACX,MAAM,GAAC,IAAI;;;;cACX,MAAM,GAAC,IAAI;;;;WACX,KAAK,CAAC,MAAM,CAAC,GAAC,IAAI;;;;SAClB,GAAG,GAAC,IAAI;;eAvBP,iBAAiB;uBADT,iBAAiB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility class for detecting and identifying Nerd Fonts installed on the system.
|
|
3
|
+
* Supports Windows, macOS, and Linux platforms.
|
|
4
|
+
*
|
|
5
|
+
* Nerd Fonts are patched fonts that include additional glyphs such as icons,
|
|
6
|
+
* file type symbols, and powerline characters commonly used in terminal applications.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* // Check if any Nerd Fonts are installed
|
|
10
|
+
* const hasNerd = await Font.hasNerdFonts()
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Get list of installed Nerd Fonts
|
|
14
|
+
* const fonts = await Font.findNerdFonts()
|
|
15
|
+
* console.log(fonts) // ["FiraCode", "JetBrainsMono", ...]
|
|
16
|
+
*/
|
|
17
|
+
export default class Font {
|
|
18
|
+
static "__#private@#cache": Map<any, any>;
|
|
19
|
+
/**
|
|
20
|
+
* Finds all Nerd Fonts installed on the system.
|
|
21
|
+
* Detects the current platform and uses platform-specific methods
|
|
22
|
+
* to locate font files or query the font database.
|
|
23
|
+
*
|
|
24
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names, or empty array if none found.
|
|
25
|
+
* @example
|
|
26
|
+
* const nerdFonts = await Font.findNerdFonts()
|
|
27
|
+
* console.log(nerdFonts) // ["FiraCode Nerd Font", "JetBrains Mono NF", ...]
|
|
28
|
+
*/
|
|
29
|
+
static findNerdFonts(): Promise<Array<string>>;
|
|
30
|
+
/**
|
|
31
|
+
* Checks whether any Nerd Fonts are installed on the system.
|
|
32
|
+
*
|
|
33
|
+
* @returns {Promise<boolean>} True if at least one Nerd Font is installed.
|
|
34
|
+
* @example
|
|
35
|
+
* if(await Font.hasNerdFonts()) {
|
|
36
|
+
* console.log("Nerd Fonts available - using fancy icons!")
|
|
37
|
+
* }
|
|
38
|
+
*/
|
|
39
|
+
static hasNerdFonts(): Promise<boolean>;
|
|
40
|
+
/**
|
|
41
|
+
* Gets the base family names of installed Nerd Fonts.
|
|
42
|
+
* Strips the "NF" or "Nerd Font" suffix to return the core font name.
|
|
43
|
+
*
|
|
44
|
+
* @returns {Promise<Array<string>>} Array of base font family names.
|
|
45
|
+
* @example
|
|
46
|
+
* const families = await Font.getNerdFontFamilies()
|
|
47
|
+
* console.log(families) // ["FiraCode", "JetBrains Mono", ...]
|
|
48
|
+
*/
|
|
49
|
+
static getNerdFontFamilies(): Promise<Array<string>>;
|
|
50
|
+
/**
|
|
51
|
+
* Strips font style suffixes from a font name.
|
|
52
|
+
*
|
|
53
|
+
* @param {string} fontName - The font name to clean.
|
|
54
|
+
* @returns {string} The font name without style suffixes.
|
|
55
|
+
* @private
|
|
56
|
+
*/
|
|
57
|
+
private static "__#private@#stripStyles";
|
|
58
|
+
/**
|
|
59
|
+
* Tests if a font name matches any Nerd Font naming patterns.
|
|
60
|
+
*
|
|
61
|
+
* @param {string} fontName - The font name to test.
|
|
62
|
+
* @param {Array<RegExp>} tests - Array of regex patterns to match against.
|
|
63
|
+
* @returns {boolean} True if the font name matches any pattern.
|
|
64
|
+
* @private
|
|
65
|
+
*/
|
|
66
|
+
private static "__#private@#isNerdFontName";
|
|
67
|
+
/**
|
|
68
|
+
* Finds Nerd Fonts on Windows by scanning system and user font directories.
|
|
69
|
+
*
|
|
70
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names.
|
|
71
|
+
* @private
|
|
72
|
+
*/
|
|
73
|
+
private static "__#private@#findNerdFontsWindows";
|
|
74
|
+
/**
|
|
75
|
+
* Finds Nerd Fonts on macOS by scanning system and user font directories.
|
|
76
|
+
*
|
|
77
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names.
|
|
78
|
+
* @private
|
|
79
|
+
*/
|
|
80
|
+
private static "__#private@#findNerdFontsMac";
|
|
81
|
+
/**
|
|
82
|
+
* Finds Nerd Fonts on Linux using the fc-list command.
|
|
83
|
+
*
|
|
84
|
+
* @returns {Promise<Array<string>>} Array of Nerd Font family names.
|
|
85
|
+
* @private
|
|
86
|
+
*/
|
|
87
|
+
private static "__#private@#findNerdFontsLinux";
|
|
88
|
+
/** @type {Array<RegExp>} Patterns to identify Nerd Fonts by filename */
|
|
89
|
+
static "__#private@#nerdTests": Array<RegExp>;
|
|
90
|
+
/** @type {Array<RegExp>} Patterns to identify Nerd Fonts in fc-list output */
|
|
91
|
+
static "__#private@#nerdTestsLinux": Array<RegExp>;
|
|
92
|
+
/**
|
|
93
|
+
* Identifies Nerd Fonts from a list of font file objects.
|
|
94
|
+
*
|
|
95
|
+
* @param {Array<FileObject>} fileObjects - Array of FileObject instances representing font files.
|
|
96
|
+
* @returns {Array<string>} Sorted array of unique Nerd Font family names.
|
|
97
|
+
* @private
|
|
98
|
+
*/
|
|
99
|
+
private static "__#private@#identifyNerdFonts";
|
|
100
|
+
/**
|
|
101
|
+
* Gets spinner animation frames appropriate for the current font environment.
|
|
102
|
+
* Returns Unicode braille characters if Nerd Fonts are available,
|
|
103
|
+
* otherwise returns ASCII fallback characters.
|
|
104
|
+
*
|
|
105
|
+
* @returns {Promise<Array<string>>} Promise resolving to array of spinner frame characters.
|
|
106
|
+
* @example
|
|
107
|
+
* const frames = await Font.spinFrames
|
|
108
|
+
* // With Nerd Fonts: ["⠋", "⠙", "⠹", ...]
|
|
109
|
+
* // Without: ["|", "/", "-", "\\"]
|
|
110
|
+
*/
|
|
111
|
+
static get spinFrames(): Promise<Array<string>>;
|
|
112
|
+
}
|
|
113
|
+
//# sourceMappingURL=Font.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Font.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Font.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;;GAeG;AACH;IACE,0CAAyB;IAEzB;;;;;;;;;OASG;IACH,wBALa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAoBlC;IAED;;;;;;;;OAQG;IACH,uBANa,OAAO,CAAC,OAAO,CAAC,CAQ5B;IAED;;;;;;;;OAQG;IACH,8BALa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAUlC;IAED;;;;;;OAMG;IACH,yCAEC;IAED;;;;;;;OAOG;IACH,4CAEC;IAED;;;;;OAKG;IACH,kDAgCC;IAED;;;;;OAKG;IACH,8CAyBC;IAED;;;;;OAKG;IACH,gDAoBC;IAED,wEAAwE;IACxE,gCADW,KAAK,CAAC,MAAM,CAAC,CACoB;IAE5C,8EAA8E;IAC9E,qCADW,KAAK,CAAC,MAAM,CAAC,CAC0B;IAElD;;;;;;OAMG;IACH,+CAYC;IAED;;;;;;;;;;OAUG;IACH,yBANa,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAYlC;CACF"}
|
package/types/node/lib/Sass.d.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sass.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Sass.js"],"names":[],"mappings":"AAgBA;;;GAGG;AACH;;CAgFC;
|
|
1
|
+
{"version":3,"file":"Sass.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Sass.js"],"names":[],"mappings":"AAgBA;;;GAGG;AACH;;CAgFC;wBAvFuB,2BAA2B"}
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
export default class Tantrum extends BrowserTantrum {
|
|
6
6
|
constructor(message: any, errors?: any[]);
|
|
7
7
|
}
|
|
8
|
-
import
|
|
8
|
+
import BrowserTantrum from "../../browser/lib/Tantrum.js";
|
|
9
9
|
//# sourceMappingURL=Tantrum.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tantrum.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Tantrum.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH;IACE,0CAEC;CA0BF;
|
|
1
|
+
{"version":3,"file":"Tantrum.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Tantrum.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH;IACE,0CAEC;CA0BF;2BArC0B,8BAA8B"}
|
package/types/node/lib/Term.d.ts
CHANGED
|
@@ -1,4 +1,39 @@
|
|
|
1
1
|
export default class Term {
|
|
2
|
+
static "__#private@#cache": Map<any, any>;
|
|
3
|
+
static "__#private@#preformat"(text: any): any;
|
|
4
|
+
/**
|
|
5
|
+
* Terminal width in columns.
|
|
6
|
+
*
|
|
7
|
+
* @type {number | undefined}
|
|
8
|
+
*/
|
|
9
|
+
static get columns(): number | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* Terminal height in rows.
|
|
12
|
+
*
|
|
13
|
+
* @type {number | undefined}
|
|
14
|
+
*/
|
|
15
|
+
static get rows(): number | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* Terminal dimensions as an object.
|
|
18
|
+
*
|
|
19
|
+
* @type {{columns: number | undefined, rows: number | undefined}}
|
|
20
|
+
*/
|
|
21
|
+
static get dim(): {
|
|
22
|
+
columns: number | undefined;
|
|
23
|
+
rows: number | undefined;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Whether the terminal is interactive (TTY and not in CI).
|
|
27
|
+
*
|
|
28
|
+
* @type {boolean}
|
|
29
|
+
*/
|
|
30
|
+
static get isInteractive(): boolean;
|
|
31
|
+
/**
|
|
32
|
+
* Whether the terminal supports color output.
|
|
33
|
+
*
|
|
34
|
+
* @type {boolean}
|
|
35
|
+
*/
|
|
36
|
+
static get hasColor(): boolean;
|
|
2
37
|
/**
|
|
3
38
|
* Log an informational message.
|
|
4
39
|
*
|
|
@@ -120,8 +155,120 @@ export default class Term {
|
|
|
120
155
|
* @throws {Sass} If any element of `parts` is not a string.
|
|
121
156
|
*/
|
|
122
157
|
static terminalBracket([level, text, brackets]: Array<string>): string;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
158
|
+
/**
|
|
159
|
+
* ANSI escape sequence to move cursor to start of line.
|
|
160
|
+
*
|
|
161
|
+
* @type {string}
|
|
162
|
+
*/
|
|
163
|
+
static get start(): string;
|
|
164
|
+
/**
|
|
165
|
+
* Move cursor to start of line (interactive terminals only).
|
|
166
|
+
*
|
|
167
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
168
|
+
*/
|
|
169
|
+
static moveStart(): typeof Term;
|
|
170
|
+
/**
|
|
171
|
+
* ANSI escape sequence to move cursor to end of line.
|
|
172
|
+
*
|
|
173
|
+
* @type {string}
|
|
174
|
+
*/
|
|
175
|
+
static get end(): string;
|
|
176
|
+
/**
|
|
177
|
+
* Move cursor to end of line (interactive terminals only).
|
|
178
|
+
*
|
|
179
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
180
|
+
*/
|
|
181
|
+
static moveEnd(): typeof Term;
|
|
182
|
+
/**
|
|
183
|
+
* ANSI escape sequence to move cursor up one line.
|
|
184
|
+
*
|
|
185
|
+
* @type {string}
|
|
186
|
+
*/
|
|
187
|
+
static get up(): string;
|
|
188
|
+
/**
|
|
189
|
+
* Move cursor up by specified number of lines (interactive terminals only).
|
|
190
|
+
*
|
|
191
|
+
* @param {number} num - Number of lines to move up.
|
|
192
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
193
|
+
*/
|
|
194
|
+
static moveUp(num: number): typeof Term;
|
|
195
|
+
/**
|
|
196
|
+
* Hide the terminal cursor (interactive terminals only).
|
|
197
|
+
*
|
|
198
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
199
|
+
*/
|
|
200
|
+
static hideCursor(): typeof Term;
|
|
201
|
+
/**
|
|
202
|
+
* Show the terminal cursor (interactive terminals only).
|
|
203
|
+
*
|
|
204
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
205
|
+
*/
|
|
206
|
+
static showCursor(): typeof Term;
|
|
207
|
+
/**
|
|
208
|
+
* Whether the terminal is in character (raw) input mode.
|
|
209
|
+
*
|
|
210
|
+
* @type {boolean}
|
|
211
|
+
*/
|
|
212
|
+
static get isCharMode(): boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Whether the terminal is in line (buffered) input mode.
|
|
215
|
+
*
|
|
216
|
+
* @type {boolean}
|
|
217
|
+
*/
|
|
218
|
+
static get isLineMode(): boolean;
|
|
219
|
+
/**
|
|
220
|
+
* Set terminal to character mode (raw input, interactive terminals only).
|
|
221
|
+
*
|
|
222
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
223
|
+
*/
|
|
224
|
+
static setCharMode(): typeof Term;
|
|
225
|
+
/**
|
|
226
|
+
* Set terminal to line mode (buffered input, interactive terminals only).
|
|
227
|
+
*
|
|
228
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
229
|
+
*/
|
|
230
|
+
static setLineMode(): typeof Term;
|
|
231
|
+
/**
|
|
232
|
+
* Clear the current line (interactive terminals only).
|
|
233
|
+
*
|
|
234
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
235
|
+
*/
|
|
236
|
+
static clearLine(): typeof Term;
|
|
237
|
+
/**
|
|
238
|
+
* Clear multiple lines by moving up and clearing each (interactive terminals only).
|
|
239
|
+
*
|
|
240
|
+
* @param {number} num - Number of lines to clear.
|
|
241
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
242
|
+
*/
|
|
243
|
+
static clearLines(num: number): typeof Term;
|
|
244
|
+
/**
|
|
245
|
+
* Write output to stdout asynchronously (fire-and-forget).
|
|
246
|
+
*
|
|
247
|
+
* @param {string} output - The string to write.
|
|
248
|
+
* @returns {typeof Term} The Term class for chaining.
|
|
249
|
+
*/
|
|
250
|
+
static write(output: string): typeof Term;
|
|
251
|
+
/**
|
|
252
|
+
* Returns a promise that resolves with the next chunk of data from stdin.
|
|
253
|
+
* If in Char Mode, it resolves on Enter, Ctrl+D, or the ANSI 'R' terminator.
|
|
254
|
+
*
|
|
255
|
+
* @param {(text: string) => boolean} [terminator] - Optional callback to check if input is complete.
|
|
256
|
+
* @returns {Promise<string>} Resolves with the input data.
|
|
257
|
+
*/
|
|
258
|
+
static data(terminator?: (text: string) => boolean): Promise<string>;
|
|
259
|
+
/**
|
|
260
|
+
* Gets the current cursor position in the terminal.
|
|
261
|
+
*
|
|
262
|
+
* @returns {Promise<[number, number]>} Resolves with [x, y] cursor position.
|
|
263
|
+
*/
|
|
264
|
+
static getCursorPosition(): Promise<[number, number]>;
|
|
265
|
+
/**
|
|
266
|
+
* Write output to stdout and return a promise that resolves when complete.
|
|
267
|
+
*
|
|
268
|
+
* @param {string} output - The string to write.
|
|
269
|
+
* @returns {Promise<void>} Resolves when write completes.
|
|
270
|
+
*/
|
|
271
|
+
static directWrite(output: string): Promise<void>;
|
|
272
|
+
static "__#private@#spinFrames": string[];
|
|
126
273
|
}
|
|
127
274
|
//# sourceMappingURL=Term.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Term.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Term.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Term.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Term.js"],"names":[],"mappings":"AAQA;IACE,0CAAyB;IAEzB,+CAIC;IAED;;;;OAIG;IACH,sBAFU,MAAM,GAAG,SAAS,CAI3B;IAED;;;;OAIG;IACH,mBAFU,MAAM,GAAG,SAAS,CAI3B;IAED;;;;OAIG;IACH,kBAFU;QAAC,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,SAAS,CAAA;KAAC,CAIhE;IAED;;;;OAIG;IACH,4BAFU,OAAO,CAMhB;IAED;;;;OAIG;IACH,uBAFU,OAAO,CAMhB;IAED;;;;OAIG;IACH,oBAFc,OAAO,EAAA,QAIpB;IAED;;;;OAIG;IACH,qBAFc,OAAO,EAAA,QAIpB;IAED;;;;OAIG;IACH,qBAFc,OAAO,EAAA,QAIpB;IAED;;;;OAIG;IACH,sBAFc,OAAO,EAAA,QAIpB;IAED;;;;OAIG;IACH,sBAFc,OAAO,EAAA,QAIpB;IAED;;;;OAIG;IACH,sBAFc,OAAO,EAAA,QAIpB;IAED;;OAEG;IACH,wBAEC;IAED;;;;;;;;OAQG;IACH,0BANW,MAAM,QAAQ,YAEtB;QAAgC,UAAU,GAAlC,KAAK,CAAC,MAAM,CAAC;QACK,UAAU,GAA5B,OAAO;QACW,aAAa,GAA/B,OAAO;KACjB,QA2DA;IAED;;;;;;;;;;;;;;OAcG;IACH,oBALW,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,eAEjD;QAAyB,MAAM,EAAvB,OAAO;KACf,GAAU,IAAI,CAOhB;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,gCAHW,MAAM,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,GAClE,IAAI,CA4BhB;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,gDAJW,KAAK,CAAC,MAAM,CAAC,GACX,MAAM,CASlB;IAED;;;;OAIG;IACH,oBAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,oBAFa,OAAO,IAAI,CAMvB;IAED;;;;OAIG;IACH,kBAFU,MAAM,CAIf;IAED;;;;OAIG;IACH,kBAFa,OAAO,IAAI,CAMvB;IAED;;;;OAIG;IACH,iBAFU,MAAM,CAIf;IAED;;;;;OAKG;IACH,mBAHW,MAAM,GACJ,OAAO,IAAI,CAMvB;IAED;;;;OAIG;IACH,qBAFa,OAAO,IAAI,CAMvB;IAED;;;;OAIG;IACH,qBAFa,OAAO,IAAI,CAMvB;IAED;;;;OAIG;IACH,yBAFU,OAAO,CAOhB;IAED;;;;OAIG;IACH,yBAFU,OAAO,CAOhB;IAED;;;;OAIG;IACH,sBAFa,OAAO,IAAI,CAMvB;IAED;;;;OAIG;IACH,sBAFa,OAAO,IAAI,CAMvB;IAED;;;;OAIG;IACH,oBAFa,OAAO,IAAI,CAMvB;IAED;;;;;OAKG;IACH,uBAHW,MAAM,GACJ,OAAO,IAAI,CAOvB;IAED;;;;;OAKG;IACH,qBAHW,MAAM,GACJ,OAAO,IAAI,CAMvB;IAED;;;;;;OAMG;IACH,yBAHW,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,GACvB,OAAO,CAAC,MAAM,CAAC,CAyD3B;IAED;;;;OAIG;IACH,4BAFa,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAqCrC;IAED;;;;;OAKG;IACH,2BAHW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAMzB;IAID,0CAAuE;CAYxE"}
|
package/types/node/lib/Util.d.ts
CHANGED
|
@@ -96,5 +96,5 @@ export default class Util extends BrowserUtil {
|
|
|
96
96
|
*/
|
|
97
97
|
static getEnv(ev: string, def?: unknown): unknown;
|
|
98
98
|
}
|
|
99
|
-
import
|
|
99
|
+
import BrowserUtil from "../../browser/lib/Util.js";
|
|
100
100
|
//# sourceMappingURL=Util.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Util.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Util.js"],"names":[],"mappings":"AAQA;;;GAGG;AACH;IACE;;;;;OAKG;IACH,iBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,mCAHW,MAAM,GACJ,KAAK,CAAC,MAAM,CAAC,CAazB;IAED;;;;;;;;OAQG;IACH,+CALW,MAAM,SACN,MAAM,WACH,OAAO,EAAA,GACR,OAAO,CAAC,IAAI,CAAC,CAmBzB;IAED;;;;;;;;;;;;OAYG;IACH,0BALW,YAAY,SACZ,MAAM,WACH,OAAO,EAAA,GACR,OAAO,CAAC,IAAI,CAAC,CAgBzB;IAED;;;;;;;;;;OAUG;IACH,+BALW,MAAM,SACN,MAAM,WACH,OAAO,EAAA,GACR,OAAO,CAAC,IAAI,CAAC,CAoBzB;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,kBALW,MAAM,QACN,OAAO,GACL,OAAO,CAmBnB;CACF;
|
|
1
|
+
{"version":3,"file":"Util.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Util.js"],"names":[],"mappings":"AAQA;;;GAGG;AACH;IACE;;;;;OAKG;IACH,iBAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACH,mCAHW,MAAM,GACJ,KAAK,CAAC,MAAM,CAAC,CAazB;IAED;;;;;;;;OAQG;IACH,+CALW,MAAM,SACN,MAAM,WACH,OAAO,EAAA,GACR,OAAO,CAAC,IAAI,CAAC,CAmBzB;IAED;;;;;;;;;;;;OAYG;IACH,0BALW,YAAY,SACZ,MAAM,WACH,OAAO,EAAA,GACR,OAAO,CAAC,IAAI,CAAC,CAgBzB;IAED;;;;;;;;;;OAUG;IACH,+BALW,MAAM,SACN,MAAM,WACH,OAAO,EAAA,GACR,OAAO,CAAC,IAAI,CAAC,CAoBzB;IAED;;;;;;;;;;;;;;;;;;;;;;OAsBG;IACH,kBALW,MAAM,QACN,OAAO,GACL,OAAO,CAmBnB;CACF;wBA1LuB,2BAA2B"}
|