@gesslar/toolkit 3.17.0 → 3.20.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 +2 -2
- package/src/browser/lib/Promised.js +21 -11
- package/src/node/index.js +1 -1
- package/src/node/lib/DirectoryObject.js +7 -4
- package/src/node/lib/FileObject.js +33 -15
- package/src/node/lib/FileSystem.js +21 -30
- package/src/node/lib/Glog.js +304 -53
- package/src/node/lib/VFileObject.js +3 -4
- package/types/browser/lib/Promised.d.ts +8 -8
- package/types/browser/lib/Promised.d.ts.map +1 -1
- package/types/node/index.d.ts +1 -1
- package/types/node/lib/DirectoryObject.d.ts.map +1 -1
- package/types/node/lib/FileObject.d.ts +10 -0
- package/types/node/lib/FileObject.d.ts.map +1 -1
- package/types/node/lib/FileSystem.d.ts +13 -16
- package/types/node/lib/FileSystem.d.ts.map +1 -1
- package/types/node/lib/Glog.d.ts +239 -64
- package/types/node/lib/Glog.d.ts.map +1 -1
- package/types/node/lib/VFileObject.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.20.0",
|
|
9
9
|
"license": "Unlicense",
|
|
10
10
|
"homepage": "https://github.com/gesslar/toolkit#readme",
|
|
11
11
|
"repository": {
|
|
@@ -60,7 +60,7 @@
|
|
|
60
60
|
"devDependencies": {
|
|
61
61
|
"@gesslar/uglier": "^0.6.0",
|
|
62
62
|
"eslint": "^9.39.2",
|
|
63
|
-
"happy-dom": "^20.0
|
|
63
|
+
"happy-dom": "^20.1.0",
|
|
64
64
|
"typescript": "^5.9.3"
|
|
65
65
|
},
|
|
66
66
|
"scripts": {
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import Tantrum from "./Tantrum.js"
|
|
2
|
+
import Valid from "./Valid.js"
|
|
2
3
|
|
|
3
4
|
/**
|
|
4
5
|
* Utility class providing helper functions for working with Promises,
|
|
@@ -13,9 +14,24 @@ export default class Promised {
|
|
|
13
14
|
* @returns {Promise<Array<unknown>>} Results of all promises
|
|
14
15
|
*/
|
|
15
16
|
static async await(promises) {
|
|
17
|
+
Valid.type(promises, "Promise[]")
|
|
18
|
+
|
|
16
19
|
return await Promise.all(promises)
|
|
17
20
|
}
|
|
18
21
|
|
|
22
|
+
/**
|
|
23
|
+
* Returns the first promise to resolve or reject from an array of promises.
|
|
24
|
+
* Wrapper around Promise.race for consistency with other utility methods.
|
|
25
|
+
*
|
|
26
|
+
* @param {Array<Promise<unknown>>} promises - Array of promises to race
|
|
27
|
+
* @returns {Promise<unknown>} Result of the first settled promise
|
|
28
|
+
*/
|
|
29
|
+
static async race(promises) {
|
|
30
|
+
Valid.type(promises, "Promise[]")
|
|
31
|
+
|
|
32
|
+
return await Promise.race(promises)
|
|
33
|
+
}
|
|
34
|
+
|
|
19
35
|
/**
|
|
20
36
|
* Settles all promises (both fulfilled and rejected) in parallel.
|
|
21
37
|
* Wrapper around Promise.allSettled for consistency with other utility methods.
|
|
@@ -24,6 +40,8 @@ export default class Promised {
|
|
|
24
40
|
* @returns {Promise<Array<{status: 'fulfilled'|'rejected', value?: unknown, reason?: unknown}>>} Results of all settled promises with status and value/reason
|
|
25
41
|
*/
|
|
26
42
|
static async settle(promises) {
|
|
43
|
+
Valid.type(promises, "Promise[]")
|
|
44
|
+
|
|
27
45
|
return await Promise.allSettled(promises)
|
|
28
46
|
}
|
|
29
47
|
|
|
@@ -101,20 +119,12 @@ export default class Promised {
|
|
|
101
119
|
* @throws {Tantrum} Throws a Tantrum error with rejection reasons
|
|
102
120
|
*/
|
|
103
121
|
static throw(message="GIGO", settled) {
|
|
122
|
+
Valid.type(message, "String", {allowEmpty: false})
|
|
123
|
+
Valid.type(settled, "Array")
|
|
124
|
+
|
|
104
125
|
const rejected = this.rejected(settled)
|
|
105
126
|
const reasons = this.reasons(rejected)
|
|
106
127
|
|
|
107
128
|
throw Tantrum.new(message, reasons)
|
|
108
129
|
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* Returns the first promise to resolve or reject from an array of promises.
|
|
112
|
-
* Wrapper around Promise.race for consistency with other utility methods.
|
|
113
|
-
*
|
|
114
|
-
* @param {Array<Promise<unknown>>} promises - Array of promises to race
|
|
115
|
-
* @returns {Promise<unknown>} Result of the first settled promise
|
|
116
|
-
*/
|
|
117
|
-
static async race(promises) {
|
|
118
|
-
return await Promise.race(promises)
|
|
119
|
-
}
|
|
120
130
|
}
|
package/src/node/index.js
CHANGED
|
@@ -17,7 +17,7 @@ export {default as Util} from "./lib/Util.js"
|
|
|
17
17
|
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
|
-
export {default as
|
|
20
|
+
export {default as FileSystem} from "./lib/FileSystem.js"
|
|
21
21
|
export {default as Glog} from "./lib/Glog.js"
|
|
22
22
|
export {default as Notify} from "./lib/Notify.js"
|
|
23
23
|
export {default as TempDirectoryObject} from "./lib/TempDirectoryObject.js"
|
|
@@ -368,26 +368,29 @@ export default class DirectoryObject extends FS {
|
|
|
368
368
|
const files = [], directories = []
|
|
369
369
|
const virtual = this.isVirtual
|
|
370
370
|
|
|
371
|
-
|
|
371
|
+
for(const e of found) {
|
|
372
372
|
if(e.isFile()) {
|
|
373
373
|
const {name, parentPath} = e
|
|
374
374
|
const resolved = FS.resolvePath(parentPath, name)
|
|
375
375
|
|
|
376
376
|
const file = virtual
|
|
377
|
-
? new VFileObject(resolved, this)
|
|
377
|
+
? new VFileObject(path.relative(this.real.path, resolved), this)
|
|
378
378
|
: new FileObject(resolved, this)
|
|
379
379
|
|
|
380
380
|
files.push(file)
|
|
381
381
|
} else if(e.isDirectory()) {
|
|
382
382
|
const {name, parentPath} = e
|
|
383
383
|
const resolved = FS.resolvePath(parentPath, name)
|
|
384
|
-
const
|
|
384
|
+
const relativePath = virtual
|
|
385
|
+
? path.relative(this.real.path, resolved)
|
|
386
|
+
: resolved
|
|
387
|
+
const directory = new this.constructor(relativePath, this)
|
|
385
388
|
|
|
386
389
|
directories.push(directory)
|
|
387
390
|
} else {
|
|
388
391
|
throw Sass.new(`wtf is this? ${e}`)
|
|
389
392
|
}
|
|
390
|
-
}
|
|
393
|
+
}
|
|
391
394
|
|
|
392
395
|
return {files, directories}
|
|
393
396
|
}
|
|
@@ -69,6 +69,24 @@ export default class FileObject extends FS {
|
|
|
69
69
|
parentPath: null,
|
|
70
70
|
})
|
|
71
71
|
|
|
72
|
+
/**
|
|
73
|
+
* Strip root from absolute path to make it relative.
|
|
74
|
+
* Used for virtual filesystem path resolution.
|
|
75
|
+
*
|
|
76
|
+
* @private
|
|
77
|
+
* @static
|
|
78
|
+
* @param {string} pathName - The path to convert
|
|
79
|
+
* @returns {string} Path with root stripped, or original if already relative
|
|
80
|
+
*/
|
|
81
|
+
static #absoluteToRelative(pathName) {
|
|
82
|
+
if(!path.isAbsolute(pathName))
|
|
83
|
+
return pathName
|
|
84
|
+
|
|
85
|
+
const {root} = FS.pathParts(pathName)
|
|
86
|
+
|
|
87
|
+
return Data.chopLeft(pathName, root)
|
|
88
|
+
}
|
|
89
|
+
|
|
72
90
|
/**
|
|
73
91
|
* Constructs a FileObject instance.
|
|
74
92
|
*
|
|
@@ -82,40 +100,41 @@ export default class FileObject extends FS {
|
|
|
82
100
|
Valid.type(parent, "Null|String|DirectoryObject", {allowEmpty: false})
|
|
83
101
|
|
|
84
102
|
const normalizedFile = FS.fixSlashes(submitted)
|
|
85
|
-
const
|
|
86
|
-
?
|
|
103
|
+
const absOrRelPath = path.isAbsolute(normalizedFile) && parent
|
|
104
|
+
? FileObject.#absoluteToRelative(normalizedFile)
|
|
87
105
|
: normalizedFile
|
|
88
|
-
const {dir, base, ext, name} = FS.pathParts(
|
|
106
|
+
const {dir, base, ext, name} = FS.pathParts(absOrRelPath)
|
|
89
107
|
|
|
90
108
|
const [parentObject, fullPath] = (() => {
|
|
91
109
|
if(Data.isType(parent, "String")) {
|
|
92
|
-
const
|
|
93
|
-
const {dir} = FS.pathParts(
|
|
110
|
+
const resolved = FS.resolvePath(parent, absOrRelPath)
|
|
111
|
+
const {dir} = FS.pathParts(resolved)
|
|
94
112
|
|
|
95
113
|
return [
|
|
96
114
|
new DirectoryObject(dir),
|
|
97
|
-
|
|
115
|
+
resolved,
|
|
98
116
|
]
|
|
99
117
|
}
|
|
100
118
|
|
|
101
119
|
if(Data.isType(parent, "DirectoryObject")) {
|
|
102
|
-
const
|
|
103
|
-
const
|
|
120
|
+
const parentPath = parent.path
|
|
121
|
+
const resolved = FS.resolvePath(parentPath, absOrRelPath)
|
|
122
|
+
const parts = FS.pathParts(resolved)
|
|
104
123
|
|
|
105
124
|
return [
|
|
106
|
-
parent.path === dir
|
|
125
|
+
parent.path === parts.dir
|
|
107
126
|
? parent
|
|
108
|
-
: new parent.constructor(dir, parent),
|
|
109
|
-
|
|
127
|
+
: new parent.constructor(parts.dir, parent),
|
|
128
|
+
resolved,
|
|
110
129
|
]
|
|
111
130
|
}
|
|
112
131
|
|
|
113
132
|
const directory = new DirectoryObject(dir)
|
|
114
|
-
const
|
|
133
|
+
const resolved = FS.resolvePath(directory.path, absOrRelPath)
|
|
115
134
|
|
|
116
135
|
return [
|
|
117
136
|
directory,
|
|
118
|
-
|
|
137
|
+
resolved,
|
|
119
138
|
]
|
|
120
139
|
})()
|
|
121
140
|
|
|
@@ -439,9 +458,8 @@ export default class FileObject extends FS {
|
|
|
439
458
|
any: [JSON5,YAML]
|
|
440
459
|
}[normalizedType]
|
|
441
460
|
|
|
442
|
-
if(!toTry)
|
|
461
|
+
if(!toTry)
|
|
443
462
|
throw Sass.new(`Unsupported data type '${type}'. Supported types: json, json5, yaml.`)
|
|
444
|
-
}
|
|
445
463
|
|
|
446
464
|
for(const format of toTry) {
|
|
447
465
|
try {
|
|
@@ -49,7 +49,7 @@ export default class FileSystem {
|
|
|
49
49
|
1
|
|
50
50
|
)
|
|
51
51
|
|
|
52
|
-
return FileSystem.
|
|
52
|
+
return FileSystem.relativeOrAbsolute(fileOrDirectoryObject, this)
|
|
53
53
|
}
|
|
54
54
|
|
|
55
55
|
/**
|
|
@@ -104,7 +104,7 @@ export default class FileSystem {
|
|
|
104
104
|
* @param {FileObject|DirectoryObject} to - The target file or directory object
|
|
105
105
|
* @returns {string} The relative path from `from` to `to`, or the absolute path if not reachable
|
|
106
106
|
*/
|
|
107
|
-
static
|
|
107
|
+
static relativeOrAbsolute(from, to) {
|
|
108
108
|
const fromBasePath = from.isDirectory
|
|
109
109
|
? from.path
|
|
110
110
|
: from.parent?.path ?? path.dirname(from.path)
|
|
@@ -116,6 +116,25 @@ export default class FileSystem {
|
|
|
116
116
|
: relative
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/**
|
|
120
|
+
* Computes the relative path from one file or directory to another.
|
|
121
|
+
*
|
|
122
|
+
* If the target is outside the source (i.e., the relative path starts with
|
|
123
|
+
* ".."), returns the absolute path to the target instead.
|
|
124
|
+
*
|
|
125
|
+
* @static
|
|
126
|
+
* @param {string} from - The source file or directory object
|
|
127
|
+
* @param {string} to - The target file or directory object
|
|
128
|
+
* @returns {string} The relative path from `from` to `to`, or the absolute path if not reachable
|
|
129
|
+
*/
|
|
130
|
+
static relativeOrAbsolutePath(from, to) {
|
|
131
|
+
const relative = path.relative(from, to)
|
|
132
|
+
|
|
133
|
+
return relative.startsWith("..")
|
|
134
|
+
? to
|
|
135
|
+
: relative
|
|
136
|
+
}
|
|
137
|
+
|
|
119
138
|
/**
|
|
120
139
|
* Merge two paths by finding overlapping segments and combining them
|
|
121
140
|
* efficiently
|
|
@@ -356,32 +375,4 @@ export default class FileSystem {
|
|
|
356
375
|
|
|
357
376
|
return this.resolvePath(cap, target)
|
|
358
377
|
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Convert an absolute path to a relative format by removing the root component.
|
|
362
|
-
* By default, keeps a leading separator (making it "absolute-like relative").
|
|
363
|
-
* Use forceActuallyRelative to get a truly relative path without leading separator.
|
|
364
|
-
*
|
|
365
|
-
* @static
|
|
366
|
-
* @param {string} pathToCheck - The path to convert (returned unchanged if already relative)
|
|
367
|
-
* @param {boolean} [forceActuallyRelative=false] - If true, removes leading separator for truly relative path
|
|
368
|
-
* @returns {string} The relative path (with or without leading separator based on forceActuallyRelative)
|
|
369
|
-
* @example
|
|
370
|
-
* FS.absoluteToRelative("/home/user/docs") // "/home/user/docs" (with leading /)
|
|
371
|
-
* FS.absoluteToRelative("/home/user/docs", true) // "home/user/docs" (truly relative)
|
|
372
|
-
* FS.absoluteToRelative("relative/path") // "relative/path" (unchanged)
|
|
373
|
-
*/
|
|
374
|
-
static absoluteToRelative(pathToCheck, forceActuallyRelative=false) {
|
|
375
|
-
if(!path.isAbsolute(pathToCheck))
|
|
376
|
-
return pathToCheck
|
|
377
|
-
|
|
378
|
-
const {root} = this.pathParts(pathToCheck)
|
|
379
|
-
const sep = path.sep
|
|
380
|
-
const chopped = Data.chopLeft(pathToCheck, root)
|
|
381
|
-
const absolute = forceActuallyRelative
|
|
382
|
-
? chopped
|
|
383
|
-
: Data.prepend(chopped, sep)
|
|
384
|
-
|
|
385
|
-
return absolute
|
|
386
|
-
}
|
|
387
378
|
}
|