@gesslar/toolkit 3.42.0 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/package.json +4 -4
- package/src/browser/lib/Collection.js +1 -2
- package/src/browser/lib/Data.js +4 -4
- package/src/browser/lib/TypeSpec.js +115 -39
- package/src/node/index.js +2 -1
- package/src/node/lib/Cache.js +105 -35
- package/src/node/lib/Data.js +49 -0
- package/src/node/lib/DirectoryObject.js +4 -7
- package/src/node/lib/FileObject.js +89 -53
- package/src/node/lib/FileSystem.js +47 -2
- package/src/node/lib/Font.js +1 -1
- package/src/node/lib/Glog.js +47 -28
- package/src/node/lib/Notify.js +6 -6
- package/src/node/lib/Sass.js +3 -6
- package/src/node/lib/Term.js +11 -11
- package/src/node/lib/Util.js +3 -3
- package/src/node/lib/Valid.js +3 -6
- package/src/node/lib/Watcher.js +118 -0
- package/types/browser/lib/Collection.d.ts.map +1 -1
- package/types/browser/lib/Data.d.ts +2 -8
- package/types/browser/lib/Data.d.ts.map +1 -1
- package/types/browser/lib/TypeSpec.d.ts +21 -36
- package/types/browser/lib/TypeSpec.d.ts.map +1 -1
- package/types/node/index.d.ts +2 -1
- package/types/node/lib/Cache.d.ts +36 -5
- package/types/node/lib/Cache.d.ts.map +1 -1
- package/types/node/lib/Data.d.ts +19 -0
- package/types/node/lib/Data.d.ts.map +1 -0
- package/types/node/lib/DirectoryObject.d.ts +6 -5
- package/types/node/lib/DirectoryObject.d.ts.map +1 -1
- package/types/node/lib/FileObject.d.ts +54 -26
- package/types/node/lib/FileObject.d.ts.map +1 -1
- package/types/node/lib/FileSystem.d.ts +19 -0
- package/types/node/lib/FileSystem.d.ts.map +1 -1
- package/types/node/lib/Glog.d.ts +2 -2
- package/types/node/lib/Glog.d.ts.map +1 -1
- package/types/node/lib/Notify.d.ts +10 -10
- package/types/node/lib/Notify.d.ts.map +1 -1
- package/types/node/lib/Sass.d.ts +7 -0
- package/types/node/lib/Sass.d.ts.map +1 -1
- package/types/node/lib/Term.d.ts +2 -9
- package/types/node/lib/Term.d.ts.map +1 -1
- package/types/node/lib/Util.d.ts +6 -6
- package/types/node/lib/Util.d.ts.map +1 -1
- package/types/node/lib/Valid.d.ts.map +1 -1
- package/types/node/lib/Watcher.d.ts +38 -0
- package/types/node/lib/Watcher.d.ts.map +1 -0
|
@@ -4,14 +4,13 @@
|
|
|
4
4
|
* resolution and existence checks.
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
|
-
import
|
|
7
|
+
import {Buffer} from "node:buffer"
|
|
8
8
|
import fs from "node:fs/promises"
|
|
9
|
-
import YAML from "yaml"
|
|
10
9
|
import {URL} from "node:url"
|
|
11
|
-
import {Buffer} from "node:buffer"
|
|
12
10
|
import {inspect} from "node:util"
|
|
13
11
|
|
|
14
|
-
import
|
|
12
|
+
import Cache from "./Cache.js"
|
|
13
|
+
import Data from "./Data.js"
|
|
15
14
|
import DirectoryObject from "./DirectoryObject.js"
|
|
16
15
|
import FS from "./FileSystem.js"
|
|
17
16
|
import Sass from "./Sass.js"
|
|
@@ -33,19 +32,6 @@ import Valid from "./Valid.js"
|
|
|
33
32
|
*/
|
|
34
33
|
|
|
35
34
|
export default class FileObject extends FS {
|
|
36
|
-
/**
|
|
37
|
-
* Configuration mapping data types to their respective parser modules for loadData method.
|
|
38
|
-
* Each parser module must have a .parse() method that accepts a string and returns parsed data.
|
|
39
|
-
*
|
|
40
|
-
* @type {{[key: string]: Array<typeof JSON5 | typeof YAML>}}
|
|
41
|
-
*/
|
|
42
|
-
static dataLoaderConfig = Object.freeze({
|
|
43
|
-
json5: [JSON5],
|
|
44
|
-
json: [JSON5],
|
|
45
|
-
yaml: [YAML],
|
|
46
|
-
any: [JSON5, YAML]
|
|
47
|
-
})
|
|
48
|
-
|
|
49
35
|
/**
|
|
50
36
|
* @type {object}
|
|
51
37
|
* @property {string|null} supplied - User-supplied path
|
|
@@ -70,6 +56,8 @@ export default class FileObject extends FS {
|
|
|
70
56
|
real: null,
|
|
71
57
|
})
|
|
72
58
|
|
|
59
|
+
#cache = null
|
|
60
|
+
|
|
73
61
|
/**
|
|
74
62
|
* Constructs a FileObject instance.
|
|
75
63
|
*
|
|
@@ -162,6 +150,7 @@ export default class FileObject extends FS {
|
|
|
162
150
|
extension: this.extension,
|
|
163
151
|
isFile: this.isFile,
|
|
164
152
|
parentPath: this.parentPath,
|
|
153
|
+
cached: this.cached
|
|
165
154
|
}
|
|
166
155
|
}
|
|
167
156
|
|
|
@@ -377,17 +366,74 @@ export default class FileObject extends FS {
|
|
|
377
366
|
}
|
|
378
367
|
}
|
|
379
368
|
|
|
369
|
+
/**
|
|
370
|
+
* Whether this FileObject has an active cache attached.
|
|
371
|
+
*
|
|
372
|
+
* @returns {boolean} True if a Cache instance is attached
|
|
373
|
+
*/
|
|
374
|
+
get cached() {
|
|
375
|
+
return Data.isType(this.#cache, "Cache")
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Attaches a Cache instance to this FileObject for caching read and
|
|
380
|
+
* loadData results. If no cache is provided, a new Cache is created.
|
|
381
|
+
*
|
|
382
|
+
* @param {Cache} [cache] - The Cache instance to attach
|
|
383
|
+
* @returns {FileObject} This FileObject for chaining
|
|
384
|
+
* @throws {Sass} If a cache is already attached
|
|
385
|
+
*/
|
|
386
|
+
withCache(cache) {
|
|
387
|
+
Valid.type(cache, "Undefined|Cache")
|
|
388
|
+
Valid.assert(!this.#cache, "Cache already set. Remove the cache before re-assigning.")
|
|
389
|
+
|
|
390
|
+
cache ??= new Cache()
|
|
391
|
+
|
|
392
|
+
this.#cache = cache
|
|
393
|
+
|
|
394
|
+
return this
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Removes the attached cache, clearing any cached data for this file first.
|
|
399
|
+
*
|
|
400
|
+
* @returns {FileObject} This FileObject for chaining
|
|
401
|
+
*/
|
|
402
|
+
removeCache() {
|
|
403
|
+
this.resetCache()
|
|
404
|
+
this.#cache = null
|
|
405
|
+
|
|
406
|
+
return this
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* Clears cached data for this file without removing the cache itself.
|
|
411
|
+
*
|
|
412
|
+
* @returns {FileObject} This FileObject for chaining
|
|
413
|
+
*/
|
|
414
|
+
resetCache() {
|
|
415
|
+
this.#cache?.resetCache(this)
|
|
416
|
+
|
|
417
|
+
return this
|
|
418
|
+
}
|
|
419
|
+
|
|
380
420
|
/**
|
|
381
421
|
* Reads the content of a file asynchronously.
|
|
382
422
|
*
|
|
383
|
-
* @param {
|
|
423
|
+
* @param {object} [options] - Read options
|
|
424
|
+
* @param {string} [options.encoding="utf8"] - The encoding to read the file as
|
|
425
|
+
* @param {boolean} [options.skipCache=false] - If true, bypass the cache
|
|
384
426
|
* @returns {Promise<string>} The file contents
|
|
385
427
|
*/
|
|
386
|
-
async read(encoding="utf8") {
|
|
428
|
+
async read({encoding="utf8", skipCache=false} = {}) {
|
|
387
429
|
const filePath = this.path
|
|
388
430
|
|
|
431
|
+
if(this.#cache && skipCache === false)
|
|
432
|
+
return await this.#cache.loadFromCache(
|
|
433
|
+
this, {encoding})
|
|
434
|
+
|
|
389
435
|
if(!(await this.exists))
|
|
390
|
-
throw Sass.new(`No such file '${
|
|
436
|
+
throw Sass.new(`No such file '${this}'`)
|
|
391
437
|
|
|
392
438
|
return await fs.readFile(filePath, encoding)
|
|
393
439
|
}
|
|
@@ -419,7 +465,7 @@ export default class FileObject extends FS {
|
|
|
419
465
|
*
|
|
420
466
|
* @param {string} content - The content to write
|
|
421
467
|
* @param {string} [encoding] - The encoding in which to write (default: "utf8")
|
|
422
|
-
* @returns {Promise<
|
|
468
|
+
* @returns {Promise<undefined>}
|
|
423
469
|
* @throws {Sass} If the file URL is invalid or the parent directory doesn't exist
|
|
424
470
|
* @example
|
|
425
471
|
* const file = new FileObject('./output/data.json')
|
|
@@ -444,7 +490,7 @@ export default class FileObject extends FS {
|
|
|
444
490
|
* Supports ArrayBuffer, TypedArrays (Uint8Array, etc.), Blob, and Node Buffer types.
|
|
445
491
|
*
|
|
446
492
|
* @param {ArrayBuffer|Blob|Buffer} data - The binary data to write
|
|
447
|
-
* @returns {Promise<
|
|
493
|
+
* @returns {Promise<undefined>}
|
|
448
494
|
* @throws {Sass} If the file URL is invalid
|
|
449
495
|
* @throws {Sass} If the parent directory doesn't exist
|
|
450
496
|
* @throws {Sass} If the data is not a valid binary type
|
|
@@ -471,44 +517,34 @@ export default class FileObject extends FS {
|
|
|
471
517
|
}
|
|
472
518
|
|
|
473
519
|
/**
|
|
474
|
-
* Loads an object from JSON or YAML file.
|
|
475
|
-
*
|
|
520
|
+
* Loads an object from JSON or YAML file. Attempts to parse content as JSON5
|
|
521
|
+
* first, then falls back to YAML if specified.
|
|
476
522
|
*
|
|
477
|
-
* @param {
|
|
478
|
-
* @param {string} [
|
|
523
|
+
* @param {object} [options] - Load options
|
|
524
|
+
* @param {string} [options.type="any"] - The expected type of data to parse ("json", "json5", "yaml", or "any")
|
|
525
|
+
* @param {string} [options.encoding="utf8"] - The encoding to read the file as
|
|
526
|
+
* @param {boolean} [options.skipCache=false] - If true, bypass the cache
|
|
479
527
|
* @returns {Promise<unknown>} The parsed data object
|
|
480
528
|
* @throws {Sass} If the content cannot be parsed or type is unsupported
|
|
481
529
|
* @example
|
|
482
530
|
* const configFile = new FileObject('./config.json5')
|
|
483
|
-
* const config = await configFile.loadData('json5')
|
|
531
|
+
* const config = await configFile.loadData({type: 'json5'})
|
|
484
532
|
*
|
|
485
533
|
* // Auto-detect format
|
|
486
|
-
* const data = await configFile.loadData(
|
|
487
|
-
*/
|
|
488
|
-
async loadData(type="any", encoding="utf8") {
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
if(!toTry)
|
|
499
|
-
throw Sass.new(`Unsupported data type '${type}'. Supported types: json, json5, yaml.`)
|
|
500
|
-
|
|
501
|
-
for(const format of toTry) {
|
|
502
|
-
try {
|
|
503
|
-
const result = format.parse(content)
|
|
504
|
-
|
|
505
|
-
return result
|
|
506
|
-
} catch {
|
|
507
|
-
// nothing to see here
|
|
508
|
-
}
|
|
509
|
-
}
|
|
534
|
+
* const data = await configFile.loadData()
|
|
535
|
+
*/
|
|
536
|
+
async loadData({type="any", encoding="utf8", skipCache=false} = {}) {
|
|
537
|
+
if(this.#cache && skipCache === false)
|
|
538
|
+
return await this.#cache.loadDataFromCache(
|
|
539
|
+
this, {encoding, type})
|
|
540
|
+
|
|
541
|
+
if(!(await this.exists))
|
|
542
|
+
throw Sass.new(`No such file '${this}'`)
|
|
543
|
+
|
|
544
|
+
const content = await this.read({encoding, skipCache})
|
|
545
|
+
const result = Data.textAsData(content, type)
|
|
510
546
|
|
|
511
|
-
|
|
547
|
+
return result
|
|
512
548
|
}
|
|
513
549
|
|
|
514
550
|
/**
|
|
@@ -610,7 +646,7 @@ export default class FileObject extends FS {
|
|
|
610
646
|
/**
|
|
611
647
|
* Deletes the file from the filesystem.
|
|
612
648
|
*
|
|
613
|
-
* @returns {Promise<
|
|
649
|
+
* @returns {Promise<undefined>} Resolves when file is deleted
|
|
614
650
|
* @throws {Sass} If the file URL is invalid
|
|
615
651
|
* @throws {Sass} If the file does not exist
|
|
616
652
|
* @example
|
|
@@ -11,12 +11,14 @@
|
|
|
11
11
|
import path from "node:path"
|
|
12
12
|
import url from "node:url"
|
|
13
13
|
|
|
14
|
+
import Collection from "../../browser/lib/Collection.js"
|
|
14
15
|
import Data from "../../browser/lib/Data.js"
|
|
16
|
+
import Glog from "./Glog.js"
|
|
15
17
|
import Valid from "./Valid.js"
|
|
16
|
-
import
|
|
18
|
+
import Watcher from "./Watcher.js"
|
|
17
19
|
|
|
18
20
|
/**
|
|
19
|
-
* @import
|
|
21
|
+
* @import Sass from "./Sass.js"
|
|
20
22
|
*/
|
|
21
23
|
|
|
22
24
|
const fdTypes = Object.freeze(["file", "directory"])
|
|
@@ -33,6 +35,8 @@ export default class FileSystem {
|
|
|
33
35
|
static upperFdTypes = upperFdTypes
|
|
34
36
|
static fdType = fdType
|
|
35
37
|
|
|
38
|
+
#watcher = null
|
|
39
|
+
|
|
36
40
|
/**
|
|
37
41
|
* Compute the relative path from another file or directory to this instance.
|
|
38
42
|
*
|
|
@@ -53,6 +57,47 @@ export default class FileSystem {
|
|
|
53
57
|
return FileSystem.relativeOrAbsolute(fileOrDirectoryObject, this)
|
|
54
58
|
}
|
|
55
59
|
|
|
60
|
+
/**
|
|
61
|
+
* Watch this file or directory for changes.
|
|
62
|
+
*
|
|
63
|
+
* @param {object} [options] - Watch options
|
|
64
|
+
* @param {Function} [options.onChange] - Callback invoked on change
|
|
65
|
+
* @param {number} [options.debounceMs] - Debounce interval in milliseconds
|
|
66
|
+
* @param {boolean} [options.persistent] - Keep the process alive while watching
|
|
67
|
+
* @returns {Promise<undefined>}
|
|
68
|
+
*/
|
|
69
|
+
async watch(options={}) {
|
|
70
|
+
Valid.type(options, "Object")
|
|
71
|
+
|
|
72
|
+
const localOptions = Collection.cloneObject(options)
|
|
73
|
+
|
|
74
|
+
const {onChange} = localOptions ?? {}
|
|
75
|
+
Valid.type(onChange, "Undefined|Function")
|
|
76
|
+
|
|
77
|
+
delete localOptions.onChange
|
|
78
|
+
|
|
79
|
+
this.stopWatching()
|
|
80
|
+
|
|
81
|
+
this.#watcher = new Watcher()
|
|
82
|
+
|
|
83
|
+
await this.#watcher.watch(this, Object.assign({},
|
|
84
|
+
localOptions,
|
|
85
|
+
{
|
|
86
|
+
onChange: onChange ?? (() => {
|
|
87
|
+
Glog(`${this} changed somehow.`)
|
|
88
|
+
})
|
|
89
|
+
}
|
|
90
|
+
))
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Stop watching this file or directory for changes.
|
|
95
|
+
*/
|
|
96
|
+
stopWatching() {
|
|
97
|
+
this.#watcher?.stopWatching()
|
|
98
|
+
this.#watcher = null
|
|
99
|
+
}
|
|
100
|
+
|
|
56
101
|
/**
|
|
57
102
|
* Fix slashes in a path
|
|
58
103
|
*
|
package/src/node/lib/Font.js
CHANGED
package/src/node/lib/Glog.js
CHANGED
|
@@ -11,12 +11,24 @@
|
|
|
11
11
|
* 5. Traditional logger: logger.debug("message", level)
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
|
+
import {createRequire} from "node:module"
|
|
15
|
+
|
|
14
16
|
import c from "@gesslar/colours"
|
|
15
17
|
|
|
16
18
|
import Data from "../../browser/lib/Data.js"
|
|
17
19
|
import Term from "./Term.js"
|
|
18
20
|
import Util from "../../browser/lib/Util.js"
|
|
19
21
|
|
|
22
|
+
// Auto-detect VS Code extension environment
|
|
23
|
+
let vscodeApi = null
|
|
24
|
+
try {
|
|
25
|
+
const _require = createRequire(import.meta.url)
|
|
26
|
+
|
|
27
|
+
vscodeApi = _require("vscode")
|
|
28
|
+
} catch {
|
|
29
|
+
// Not in a VS Code extension environment
|
|
30
|
+
}
|
|
31
|
+
|
|
20
32
|
/**
|
|
21
33
|
* Default colour configuration for logger output using @gesslar/colours format
|
|
22
34
|
*
|
|
@@ -61,16 +73,6 @@ export const logSymbols = {
|
|
|
61
73
|
success: "✓"
|
|
62
74
|
}
|
|
63
75
|
|
|
64
|
-
// Set up convenient aliases for common log colours
|
|
65
|
-
c.alias.set("debug", "{F033}")
|
|
66
|
-
c.alias.set("info", "{F036}")
|
|
67
|
-
c.alias.set("warn", "{F214}")
|
|
68
|
-
c.alias.set("error", "{F196}")
|
|
69
|
-
c.alias.set("success", "{F046}")
|
|
70
|
-
c.alias.set("muted", "{F244}")
|
|
71
|
-
c.alias.set("bold", "{<B}")
|
|
72
|
-
c.alias.set("dim", "{<D}")
|
|
73
|
-
|
|
74
76
|
class Glog {
|
|
75
77
|
// Static properties (for global usage)
|
|
76
78
|
static logLevel = 0
|
|
@@ -90,9 +92,9 @@ class Glog {
|
|
|
90
92
|
#tagsAsStrings = false
|
|
91
93
|
#displayName = true
|
|
92
94
|
#symbols = null
|
|
93
|
-
#
|
|
94
|
-
#
|
|
95
|
-
#
|
|
95
|
+
#vscodeWindow = null
|
|
96
|
+
#vscodeApi = null
|
|
97
|
+
#outputChannel = null
|
|
96
98
|
|
|
97
99
|
/**
|
|
98
100
|
* Create a new Glog logger instance with optional configuration
|
|
@@ -107,23 +109,18 @@ class Glog {
|
|
|
107
109
|
* @param {boolean} [options.stackTrace=false] - Enable stack trace extraction
|
|
108
110
|
* @param {boolean} [options.tagsAsStrings=false] - Use string tags instead of symbols
|
|
109
111
|
* @param {boolean} [options.displayName=true] - Display logger name in output
|
|
110
|
-
* @param {
|
|
112
|
+
* @param {object} [options.vscode] - VS Code API object (auto-detected if not provided)
|
|
111
113
|
*/
|
|
112
114
|
constructor(options = {}) {
|
|
113
115
|
this.setOptions(options)
|
|
114
116
|
this.constructor.name = "Glog"
|
|
115
117
|
|
|
116
|
-
// VSCode integration
|
|
117
|
-
|
|
118
|
-
try {
|
|
119
|
-
const vscode = require("vscode")
|
|
118
|
+
// VSCode integration - prefer passed-in vscode, fall back to auto-detected
|
|
119
|
+
const vsapi = options.vscode ?? vscodeApi
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
} catch {
|
|
125
|
-
// VSCode not available, ignore
|
|
126
|
-
}
|
|
121
|
+
if(vsapi) {
|
|
122
|
+
this.#vscodeApi = vsapi
|
|
123
|
+
this.#vscodeWindow = vsapi.window
|
|
127
124
|
}
|
|
128
125
|
}
|
|
129
126
|
|
|
@@ -514,6 +511,23 @@ class Glog {
|
|
|
514
511
|
}
|
|
515
512
|
}
|
|
516
513
|
|
|
514
|
+
get #channel() {
|
|
515
|
+
if(!this.#outputChannel && this.#vscodeApi) {
|
|
516
|
+
const name = this.#name || "Log"
|
|
517
|
+
|
|
518
|
+
this.#outputChannel = this.#vscodeApi.window.createOutputChannel(name)
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
return this.#outputChannel
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
#appendToChannel(level, message, ...arg) {
|
|
525
|
+
const timestamp = new Date().toISOString()
|
|
526
|
+
const parts = [timestamp, `[${level.toUpperCase()}]`, message, ...arg].join(" ")
|
|
527
|
+
|
|
528
|
+
this.#channel?.appendLine(parts)
|
|
529
|
+
}
|
|
530
|
+
|
|
517
531
|
#compose(level, message, debugLevel = 0) {
|
|
518
532
|
const colours = this.#colours || Glog.colours || loggerColours
|
|
519
533
|
const name = this.#name || Glog.name || "Log"
|
|
@@ -603,8 +617,10 @@ class Glog {
|
|
|
603
617
|
|
|
604
618
|
const currentLevel = this.#logLevel || Glog.logLevel
|
|
605
619
|
|
|
606
|
-
if(currentLevel > 0 && level <= currentLevel)
|
|
620
|
+
if(currentLevel > 0 && level <= currentLevel) {
|
|
607
621
|
Term.debug(this.#compose("debug", message, level), ...arg)
|
|
622
|
+
this.#appendToChannel("debug", message, ...arg)
|
|
623
|
+
}
|
|
608
624
|
}
|
|
609
625
|
|
|
610
626
|
/**
|
|
@@ -615,7 +631,8 @@ class Glog {
|
|
|
615
631
|
*/
|
|
616
632
|
info(message, ...arg) {
|
|
617
633
|
Term.info(this.#compose("info", message), ...arg)
|
|
618
|
-
this.#
|
|
634
|
+
this.#appendToChannel("info", message, ...arg)
|
|
635
|
+
this.#vscodeWindow?.showInformationMessage(message)
|
|
619
636
|
}
|
|
620
637
|
|
|
621
638
|
/**
|
|
@@ -626,7 +643,8 @@ class Glog {
|
|
|
626
643
|
*/
|
|
627
644
|
warn(message, ...arg) {
|
|
628
645
|
Term.warn(this.#compose("warn", message), ...arg)
|
|
629
|
-
this.#
|
|
646
|
+
this.#appendToChannel("warn", message, ...arg)
|
|
647
|
+
this.#vscodeWindow?.showWarningMessage(message)
|
|
630
648
|
}
|
|
631
649
|
|
|
632
650
|
/**
|
|
@@ -637,7 +655,8 @@ class Glog {
|
|
|
637
655
|
*/
|
|
638
656
|
error(message, ...arg) {
|
|
639
657
|
Term.error(this.#compose("error", message), ...arg)
|
|
640
|
-
this.#
|
|
658
|
+
this.#appendToChannel("error", message, ...arg)
|
|
659
|
+
this.#vscodeWindow?.showErrorMessage(message)
|
|
641
660
|
}
|
|
642
661
|
|
|
643
662
|
/**
|
package/src/node/lib/Notify.js
CHANGED
|
@@ -31,7 +31,7 @@ export class Notify {
|
|
|
31
31
|
*
|
|
32
32
|
* @param {string} type - Event name to dispatch.
|
|
33
33
|
* @param {unknown} [payload] - Data to send with the event.
|
|
34
|
-
* @returns {
|
|
34
|
+
* @returns {undefined}
|
|
35
35
|
*/
|
|
36
36
|
emit(type, payload=undefined) {
|
|
37
37
|
Valid.type(type, "String", {allowEmpty: false})
|
|
@@ -46,7 +46,7 @@ export class Notify {
|
|
|
46
46
|
*
|
|
47
47
|
* @param {string} type - Event name to dispatch.
|
|
48
48
|
* @param {unknown} [payload] - Data to send with the event.
|
|
49
|
-
* @returns {Promise<
|
|
49
|
+
* @returns {Promise<undefined>} Resolves when all listeners have completed.
|
|
50
50
|
*/
|
|
51
51
|
async asyncEmit(type, payload) {
|
|
52
52
|
Valid.type(type, "String", {allowEmpty: false})
|
|
@@ -74,10 +74,10 @@ export class Notify {
|
|
|
74
74
|
* Registers a listener for the given event type.
|
|
75
75
|
*
|
|
76
76
|
* @param {string} type - Event name to listen for.
|
|
77
|
-
* @param {(payload: unknown) =>
|
|
77
|
+
* @param {(payload: unknown) => undefined} handler - Listener callback.
|
|
78
78
|
* @param {EventEmitter} [emitter] - The EventEmitter to attach to. Default is internal emitter.
|
|
79
79
|
* @param {NotifyEventOptions} [options] - Options for the listener.
|
|
80
|
-
* @returns {() =>
|
|
80
|
+
* @returns {() => undefined} Dispose function to unregister the handler.
|
|
81
81
|
*/
|
|
82
82
|
on(type, handler, emitter=this.#emitter, options=undefined) {
|
|
83
83
|
Valid.type(type, "String", {allowEmpty: false})
|
|
@@ -96,9 +96,9 @@ export class Notify {
|
|
|
96
96
|
* Removes a previously registered listener for the given event type.
|
|
97
97
|
*
|
|
98
98
|
* @param {string} type - Event name to remove.
|
|
99
|
-
* @param {(payload: unknown) =>
|
|
99
|
+
* @param {(payload: unknown) => undefined} handler - Listener callback to detach.
|
|
100
100
|
* @param {EventEmitter} [emitter] - The EventEmitter from which to remove. Default is internal emitter.
|
|
101
|
-
* @returns {
|
|
101
|
+
* @returns {undefined}
|
|
102
102
|
*/
|
|
103
103
|
off(type, handler, emitter=this.#emitter) {
|
|
104
104
|
Valid.type(type, "String", {allowEmpty: false})
|
package/src/node/lib/Sass.js
CHANGED
|
@@ -24,20 +24,17 @@ export default class Sass extends BrowserSass {
|
|
|
24
24
|
* Optionally includes detailed stack trace information.
|
|
25
25
|
*
|
|
26
26
|
* @param {boolean} [nerdMode] - Whether to include detailed stack trace
|
|
27
|
-
* @param {boolean} [isNested] - Whether this is a nested error report
|
|
28
27
|
*/
|
|
29
|
-
report(nerdMode=false
|
|
30
|
-
if(isNested)
|
|
31
|
-
Term.error()
|
|
32
|
-
|
|
28
|
+
report(nerdMode=false) {
|
|
33
29
|
Term.group(
|
|
30
|
+
"\r\n" +
|
|
34
31
|
`${Term.terminalBracket(["error", "Something Went Wrong"])}\n` +
|
|
35
32
|
this.trace.join("\n")
|
|
36
33
|
)
|
|
37
34
|
|
|
38
35
|
if(nerdMode) {
|
|
39
36
|
Term.error(
|
|
40
|
-
"\n" +
|
|
37
|
+
"\r\n" +
|
|
41
38
|
`${Term.terminalBracket(["error", "Nerd Victuals"])}\n` +
|
|
42
39
|
this.#fullBodyMassage(this.stack)
|
|
43
40
|
)
|
package/src/node/lib/Term.js
CHANGED
|
@@ -12,22 +12,22 @@ import Sass from "./Sass.js"
|
|
|
12
12
|
|
|
13
13
|
c.alias.set("success", "{F035}")
|
|
14
14
|
c.alias.set("info", "{F033}")
|
|
15
|
-
c.alias.set("warn", "{
|
|
16
|
-
c.alias.set("error", "{
|
|
17
|
-
|
|
15
|
+
c.alias.set("warn", "{F214}")
|
|
16
|
+
c.alias.set("error", "{F124}")
|
|
17
|
+
|
|
18
|
+
c.alias.set("debug", "{F033}")
|
|
19
|
+
|
|
20
|
+
c.alias.set("modified", "{F099}")
|
|
21
|
+
|
|
22
|
+
c.alias.set("muted", "{F244}")
|
|
23
|
+
c.alias.set("bold", "{<B}")
|
|
24
|
+
c.alias.set("dim", "{<D}")
|
|
18
25
|
|
|
19
26
|
/**
|
|
20
27
|
* Terminal output utilities with ANSI colour support.
|
|
21
28
|
*
|
|
22
29
|
* Provides console logging wrappers, cursor control, and formatted message
|
|
23
30
|
* output with colour styling via `@gesslar/colours`.
|
|
24
|
-
*
|
|
25
|
-
* Predefined colour aliases:
|
|
26
|
-
* - `success` - green (F035)
|
|
27
|
-
* - `info` - blue (F033)
|
|
28
|
-
* - `warn` - orange (F208)
|
|
29
|
-
* - `error` - red (F032)
|
|
30
|
-
* - `modified` - purple (F147)
|
|
31
31
|
*/
|
|
32
32
|
export default class Term {
|
|
33
33
|
static #cache = new Map()
|
|
@@ -230,7 +230,7 @@ export default class Term {
|
|
|
230
230
|
* @param {string | Array<string | [string, string]>} args - Message or segments.
|
|
231
231
|
* @param {object} [options] - Behaviour flags.
|
|
232
232
|
* @param {boolean} options.silent - When true, suppress output.
|
|
233
|
-
* @returns {
|
|
233
|
+
* @returns {undefined}
|
|
234
234
|
*/
|
|
235
235
|
static status(args, {silent=false} = {}) {
|
|
236
236
|
if(silent)
|
package/src/node/lib/Util.js
CHANGED
|
@@ -65,7 +65,7 @@ export default class Util extends BrowserUtil {
|
|
|
65
65
|
* @param {object} emitter - The emitter object (already validated)
|
|
66
66
|
* @param {string} event - The event name to emit
|
|
67
67
|
* @param {...unknown} args - Arguments to pass to event listeners
|
|
68
|
-
* @returns {Promise<
|
|
68
|
+
* @returns {Promise<undefined>} Resolves when all listeners have completed
|
|
69
69
|
*/
|
|
70
70
|
static async #performAsyncEmit(emitter, event, ...args) {
|
|
71
71
|
const listeners = emitter.listeners(event)
|
|
@@ -97,7 +97,7 @@ export default class Util extends BrowserUtil {
|
|
|
97
97
|
* @param {EventEmitter} emitter - The EventEmitter instance to emit on
|
|
98
98
|
* @param {string} event - The event name to emit
|
|
99
99
|
* @param {...unknown} args - Arguments to pass to event listeners
|
|
100
|
-
* @returns {Promise<
|
|
100
|
+
* @returns {Promise<undefined>} Resolves when all listeners have completed
|
|
101
101
|
*/
|
|
102
102
|
static async asyncEmit(emitter, event, ...args) {
|
|
103
103
|
try {
|
|
@@ -124,7 +124,7 @@ export default class Util extends BrowserUtil {
|
|
|
124
124
|
* @param {object} emitter - Any object with EventEmitter-like interface
|
|
125
125
|
* @param {string} event - The event name to emit
|
|
126
126
|
* @param {...unknown} args - Arguments to pass to event listeners
|
|
127
|
-
* @returns {Promise<
|
|
127
|
+
* @returns {Promise<undefined>} Resolves when all listeners have completed, but no grapes.
|
|
128
128
|
*/
|
|
129
129
|
static async asyncEmitQuack(emitter, event, ...args) {
|
|
130
130
|
try {
|
package/src/node/lib/Valid.js
CHANGED
|
@@ -51,17 +51,14 @@ export default class Valid {
|
|
|
51
51
|
* met (optional)
|
|
52
52
|
*/
|
|
53
53
|
static assert(condition, message, arg = null) {
|
|
54
|
-
if(!Data.isType(condition, "boolean"))
|
|
54
|
+
if(!Data.isType(condition, "boolean"))
|
|
55
55
|
throw Sass.new(`Condition must be a boolean, got ${condition}`)
|
|
56
|
-
}
|
|
57
56
|
|
|
58
|
-
if(!Data.isType(message, "string"))
|
|
57
|
+
if(!Data.isType(message, "string"))
|
|
59
58
|
throw Sass.new(`Message must be a string, got ${message}`)
|
|
60
|
-
}
|
|
61
59
|
|
|
62
|
-
if(!(arg === null || arg === undefined || typeof arg === "number"))
|
|
60
|
+
if(!(arg === null || arg === undefined || typeof arg === "number"))
|
|
63
61
|
throw Sass.new(`Arg must be a number, got ${arg}`)
|
|
64
|
-
}
|
|
65
62
|
|
|
66
63
|
if(!condition)
|
|
67
64
|
throw Sass.new(`${message}${arg ? `: ${arg}` : ""}`)
|