@gesslar/toolkit 3.27.0 → 3.29.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/index.js +1 -0
- package/src/browser/lib/Notify.js +3 -1
- package/src/node/index.js +1 -0
- package/src/node/lib/DirectoryObject.js +59 -33
- package/src/node/lib/FileSystem.js +37 -11
- package/src/node/lib/Notify.js +3 -1
- package/types/browser/index.d.ts +1 -1
- package/types/browser/lib/Notify.d.ts +17 -5
- package/types/browser/lib/Notify.d.ts.map +1 -1
- package/types/node/index.d.ts +1 -1
- package/types/node/lib/DirectoryObject.d.ts +30 -3
- package/types/node/lib/DirectoryObject.d.ts.map +1 -1
- package/types/node/lib/FileSystem.d.ts +29 -10
- package/types/node/lib/FileSystem.d.ts.map +1 -1
- package/types/node/lib/Notify.d.ts +13 -4
- package/types/node/lib/Notify.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.29.0",
|
|
9
9
|
"license": "Unlicense",
|
|
10
10
|
"homepage": "https://github.com/gesslar/toolkit#readme",
|
|
11
11
|
"repository": {
|
|
@@ -61,7 +61,7 @@
|
|
|
61
61
|
"devDependencies": {
|
|
62
62
|
"@gesslar/uglier": "^1.2.0",
|
|
63
63
|
"eslint": "^9.39.2",
|
|
64
|
-
"happy-dom": "^20.
|
|
64
|
+
"happy-dom": "^20.4.0",
|
|
65
65
|
"typescript": "^5.9.3"
|
|
66
66
|
},
|
|
67
67
|
"scripts": {
|
package/src/browser/index.js
CHANGED
|
@@ -8,6 +8,7 @@ export {Disposer as DisposerClass} from "./lib/Disposer.js"
|
|
|
8
8
|
export {default as HTML} from "./lib/HTML.js"
|
|
9
9
|
export {HTML as HTMLClass} from "./lib/HTML.js"
|
|
10
10
|
export {default as Notify} from "./lib/Notify.js"
|
|
11
|
+
export {Notify as NotifyClass} from "./lib/Notify.js"
|
|
11
12
|
export {default as Promised} from "./lib/Promised.js"
|
|
12
13
|
export {default as Sass} from "./lib/Sass.js"
|
|
13
14
|
export {default as Tantrum} from "./lib/Tantrum.js"
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
* @property {boolean} [cancelable] - Whether the event can be canceled.
|
|
11
11
|
* @property {boolean} [composed] - Whether the event can cross the shadow DOM boundary.
|
|
12
12
|
*/
|
|
13
|
-
export
|
|
13
|
+
export class Notify {
|
|
14
14
|
/** @type {string} Display name for debugging. */
|
|
15
15
|
name = "Notify"
|
|
16
16
|
|
|
@@ -87,3 +87,5 @@ export default new class Notify {
|
|
|
87
87
|
return {detail}
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
|
+
|
|
91
|
+
export default new Notify()
|
package/src/node/index.js
CHANGED
|
@@ -21,4 +21,5 @@ export {default as FileSystem} from "./lib/FileSystem.js"
|
|
|
21
21
|
export {default as Font} from "./lib/Font.js"
|
|
22
22
|
export {default as Glog} from "./lib/Glog.js"
|
|
23
23
|
export {default as Notify} from "./lib/Notify.js"
|
|
24
|
+
export {Notify as NotifyClass} from "./lib/Notify.js"
|
|
24
25
|
export {default as Term} from "./lib/Term.js"
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import {glob, mkdir, opendir, readdir, rmdir} from "node:fs/promises"
|
|
8
|
+
import {relative} from "node:path"
|
|
8
9
|
import path from "node:path"
|
|
9
10
|
import {URL} from "node:url"
|
|
10
11
|
|
|
@@ -540,75 +541,100 @@ export default class DirectoryObject extends FS {
|
|
|
540
541
|
/**
|
|
541
542
|
* Creates a new DirectoryObject by extending this directory's path.
|
|
542
543
|
*
|
|
544
|
+
* Paths are always resolved relative to THIS directory. Any attempt to
|
|
545
|
+
* escape via `..` or absolute paths is constrained - the `..` segments
|
|
546
|
+
* are stripped and the remaining path is resolved relative to this directory.
|
|
547
|
+
*
|
|
548
|
+
* On Windows, cross-drive absolute paths (e.g., `D:\foo` when base is `C:\`)
|
|
549
|
+
* are also constrained - the drive root is stripped and the path is resolved
|
|
550
|
+
* relative to this directory.
|
|
551
|
+
*
|
|
543
552
|
* Uses overlapping path segment detection to intelligently combine paths.
|
|
544
|
-
* Preserves the temporary flag from the current directory.
|
|
545
553
|
*
|
|
546
554
|
* @param {string} newPath - The path to append to this directory's path.
|
|
547
555
|
* @returns {DirectoryObject} A new DirectoryObject with the extended path.
|
|
548
556
|
* @example
|
|
549
557
|
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
550
|
-
* const subDir = dir.
|
|
558
|
+
* const subDir = dir.getDirectory("src/lib")
|
|
551
559
|
* console.log(subDir.path) // "/projects/git/toolkit/src/lib"
|
|
560
|
+
*
|
|
561
|
+
* @example
|
|
562
|
+
* // Path traversal is constrained to this directory
|
|
563
|
+
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
564
|
+
* const escaped = dir.getDirectory("../../../foo/bar")
|
|
565
|
+
* console.log(escaped.path) // "/projects/git/toolkit/foo/bar"
|
|
552
566
|
*/
|
|
553
567
|
getDirectory(newPath) {
|
|
554
568
|
Valid.type(newPath, "String", {allowEmpty: false})
|
|
555
569
|
|
|
556
|
-
//
|
|
557
|
-
if
|
|
558
|
-
throw Sass.new(`Absolute paths not allowed: ${newPath}`)
|
|
559
|
-
}
|
|
560
|
-
|
|
561
|
-
// Reject parent directory traversal
|
|
562
|
-
if(newPath.includes("..")) {
|
|
563
|
-
throw Sass.new(`Path traversal not allowed: ${newPath} contains '..'`)
|
|
564
|
-
}
|
|
565
|
-
|
|
570
|
+
// New direction: every path is relative to THIS path. Absolute?
|
|
571
|
+
// ../../../..? up to this path and then down again if required.
|
|
566
572
|
const thisPath = this.path
|
|
567
573
|
const merged = FS.mergeOverlappingPaths(thisPath, newPath)
|
|
568
574
|
const resolved = FS.resolvePath(thisPath, merged)
|
|
575
|
+
let local = relative(thisPath, resolved)
|
|
569
576
|
|
|
570
|
-
//
|
|
571
|
-
if(
|
|
572
|
-
|
|
573
|
-
|
|
577
|
+
// On Windows, cross-drive paths return absolute - strip the root
|
|
578
|
+
if(path.isAbsolute(local))
|
|
579
|
+
local = local.slice(path.parse(local).root.length)
|
|
580
|
+
|
|
581
|
+
const parts = local.split(this.sep)
|
|
582
|
+
|
|
583
|
+
while(parts[0] === "..")
|
|
584
|
+
parts.shift()
|
|
585
|
+
|
|
586
|
+
const newLocal = parts.join(this.sep)
|
|
574
587
|
|
|
575
|
-
return new this.constructor(
|
|
588
|
+
return new this.constructor(FS.resolvePath(this.path, newLocal))
|
|
576
589
|
}
|
|
577
590
|
|
|
578
591
|
/**
|
|
579
592
|
* Creates a new FileObject by extending this directory's path.
|
|
580
593
|
*
|
|
594
|
+
* Paths are always resolved relative to THIS directory. Any attempt to
|
|
595
|
+
* escape via `..` or absolute paths is constrained - the `..` segments
|
|
596
|
+
* are stripped and the remaining path is resolved relative to this directory.
|
|
597
|
+
*
|
|
598
|
+
* On Windows, cross-drive absolute paths (e.g., `D:\foo` when base is `C:\`)
|
|
599
|
+
* are also constrained - the drive root is stripped and the path is resolved
|
|
600
|
+
* relative to this directory.
|
|
601
|
+
*
|
|
581
602
|
* Uses overlapping path segment detection to intelligently combine paths.
|
|
582
603
|
*
|
|
583
604
|
* @param {string} filename - The filename to append to this directory's path.
|
|
584
605
|
* @returns {FileObject} A new FileObject with the extended path.
|
|
585
606
|
* @example
|
|
586
607
|
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
587
|
-
* const file = dir.
|
|
608
|
+
* const file = dir.getFile("package.json")
|
|
588
609
|
* console.log(file.path) // "/projects/git/toolkit/package.json"
|
|
610
|
+
*
|
|
611
|
+
* @example
|
|
612
|
+
* // Path traversal is constrained to this directory
|
|
613
|
+
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
614
|
+
* const escaped = dir.getFile("../../../foo/bar.js")
|
|
615
|
+
* console.log(escaped.path) // "/projects/git/toolkit/foo/bar.js"
|
|
589
616
|
*/
|
|
590
617
|
getFile(filename) {
|
|
591
618
|
Valid.type(filename, "String", {allowEmpty: false})
|
|
592
619
|
|
|
593
|
-
//
|
|
594
|
-
|
|
595
|
-
throw Sass.new(`Absolute paths not allowed: ${filename}`)
|
|
596
|
-
}
|
|
597
|
-
|
|
598
|
-
// Reject parent directory traversal
|
|
599
|
-
if(filename.includes("..")) {
|
|
600
|
-
throw Sass.new(`Path traversal not allowed: ${filename} contains '..'`)
|
|
601
|
-
}
|
|
602
|
-
|
|
620
|
+
// Every path is relative to THIS path. Absolute or .. paths
|
|
621
|
+
// are constrained to this directory.
|
|
603
622
|
const thisPath = this.path
|
|
604
623
|
const merged = FS.mergeOverlappingPaths(thisPath, filename)
|
|
605
624
|
const resolved = FS.resolvePath(thisPath, merged)
|
|
625
|
+
let local = relative(thisPath, resolved)
|
|
606
626
|
|
|
607
|
-
//
|
|
608
|
-
if(
|
|
609
|
-
|
|
610
|
-
|
|
627
|
+
// On Windows, cross-drive paths return absolute - strip the root
|
|
628
|
+
if(path.isAbsolute(local))
|
|
629
|
+
local = local.slice(path.parse(local).root.length)
|
|
630
|
+
|
|
631
|
+
const parts = local.split(this.sep)
|
|
632
|
+
|
|
633
|
+
while(parts[0] === "..")
|
|
634
|
+
parts.shift()
|
|
635
|
+
|
|
636
|
+
const newLocal = parts.join(this.sep)
|
|
611
637
|
|
|
612
|
-
return new FileObject(
|
|
638
|
+
return new FileObject(newLocal, this)
|
|
613
639
|
}
|
|
614
640
|
}
|
|
@@ -251,11 +251,11 @@ export default class FileSystem {
|
|
|
251
251
|
* @param {string} [sep=path.sep] - The path separator to use (defaults to system separator)
|
|
252
252
|
* @returns {string|null} The relative path, empty string if paths are identical, or null if no overlap found
|
|
253
253
|
* @example
|
|
254
|
-
* FS.
|
|
255
|
-
* FS.
|
|
256
|
-
* FS.
|
|
254
|
+
* FS.toLocalRelativePath("/projects/toolkit", "/projects/toolkit/src") // "src"
|
|
255
|
+
* FS.toLocalRelativePath("/home/user", "/home/user") // ""
|
|
256
|
+
* FS.toLocalRelativePath("/projects/app", "/other/path") // null
|
|
257
257
|
*/
|
|
258
|
-
static
|
|
258
|
+
static toLocalRelativePath(from, to, sep=path.sep) {
|
|
259
259
|
// If they're the same, just return ""
|
|
260
260
|
if(from === to)
|
|
261
261
|
return ""
|
|
@@ -276,20 +276,46 @@ export default class FileSystem {
|
|
|
276
276
|
}
|
|
277
277
|
|
|
278
278
|
/**
|
|
279
|
-
*
|
|
280
|
-
*
|
|
279
|
+
* Computes the relative path from one path to another using Node's path.relative.
|
|
280
|
+
*
|
|
281
|
+
* Unlike toLocalRelativePath which uses overlap detection, this method uses
|
|
282
|
+
* standard relative path calculation and may return paths with ".." segments.
|
|
283
|
+
*
|
|
284
|
+
* @static
|
|
285
|
+
* @param {string} from - The base path to calculate relative from
|
|
286
|
+
* @param {string} to - The target path to make relative
|
|
287
|
+
* @returns {string} The relative path, or empty string if paths are identical
|
|
288
|
+
* @example
|
|
289
|
+
* FS.toRelativePath("/home/user", "/home/user/docs") // "docs"
|
|
290
|
+
* FS.toRelativePath("/home/user", "/home/user") // ""
|
|
291
|
+
* FS.toRelativePath("/home/user", "/home/other") // "../other"
|
|
292
|
+
*/
|
|
293
|
+
static toRelativePath(from, to) {
|
|
294
|
+
// If they're the same, just return ""
|
|
295
|
+
if(from === to)
|
|
296
|
+
return ""
|
|
297
|
+
|
|
298
|
+
return path.relative(from, to)
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
/**
|
|
302
|
+
* Find where a path's final segment appears in another path, returning the
|
|
303
|
+
* portion of 'from' up to that overlap point.
|
|
304
|
+
*
|
|
305
|
+
* Looks for the last segment of `from` within `to`. If found, returns `from`
|
|
306
|
+
* sliced to the index where that segment appears in `to`.
|
|
281
307
|
*
|
|
282
308
|
* @static
|
|
283
|
-
* @param {string} from - The
|
|
284
|
-
* @param {string} to - The
|
|
309
|
+
* @param {string} from - The source path whose final segment to search for
|
|
310
|
+
* @param {string} to - The target path to search within
|
|
285
311
|
* @param {string} [sep=path.sep] - The path separator to use (defaults to system separator)
|
|
286
|
-
* @returns {string|null} The
|
|
312
|
+
* @returns {string|null} The sliced portion of from, the original path if identical, or null if no overlap
|
|
287
313
|
* @throws {Sass} If from is not a non-empty string
|
|
288
314
|
* @throws {Sass} If to is not a non-empty string
|
|
289
315
|
* @example
|
|
290
|
-
* FS.getCommonRootPath("/projects/toolkit
|
|
316
|
+
* FS.getCommonRootPath("/projects/toolkit", "/projects/toolkit/src") // "/projects/toolkit"
|
|
291
317
|
* FS.getCommonRootPath("/home/user", "/home/user") // "/home/user"
|
|
292
|
-
* FS.getCommonRootPath("/projects/app", "/other/path") // null
|
|
318
|
+
* FS.getCommonRootPath("/projects/app", "/other/path") // null (no overlap)
|
|
293
319
|
*/
|
|
294
320
|
static getCommonRootPath(from, to, sep=path.sep) {
|
|
295
321
|
Valid.type(from, "String", {allowEmpty: false})
|
package/src/node/lib/Notify.js
CHANGED
|
@@ -19,7 +19,7 @@ import Util from "./Util.js"
|
|
|
19
19
|
* Notify class provides a thin wrapper around EventEmitter for centralized
|
|
20
20
|
* event handling in Node.js applications. Mirrors the browser Notify API.
|
|
21
21
|
*/
|
|
22
|
-
export
|
|
22
|
+
export class Notify {
|
|
23
23
|
/** @type {string} Display name for debugging. */
|
|
24
24
|
name = "Notify"
|
|
25
25
|
|
|
@@ -106,3 +106,5 @@ export default new class Notify {
|
|
|
106
106
|
emitter.off(type, handler)
|
|
107
107
|
}
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
export default new Notify()
|
package/types/browser/index.d.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export { default as Collection } from "./lib/Collection.js";
|
|
2
2
|
export { default as Data } from "./lib/Data.js";
|
|
3
|
-
export { default as Notify } from "./lib/Notify.js";
|
|
4
3
|
export { default as Promised } from "./lib/Promised.js";
|
|
5
4
|
export { default as Sass } from "./lib/Sass.js";
|
|
6
5
|
export { default as Tantrum } from "./lib/Tantrum.js";
|
|
@@ -10,4 +9,5 @@ export { default as Util } from "./lib/Util.js";
|
|
|
10
9
|
export { default as Valid } from "./lib/Valid.js";
|
|
11
10
|
export { default as Disposer, Disposer as DisposerClass } from "./lib/Disposer.js";
|
|
12
11
|
export { default as HTML, HTML as HTMLClass } from "./lib/HTML.js";
|
|
12
|
+
export { default as Notify, Notify as NotifyClass } from "./lib/Notify.js";
|
|
13
13
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1,4 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Thin wrapper around `window` event handling to centralize emit/on/off
|
|
3
|
+
* helpers. Used to dispatch simple CustomEvents and manage listeners in one
|
|
4
|
+
* place.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* @typedef {object} NotifyEventOptions
|
|
8
|
+
* @property {boolean} [bubbles] - Whether the event bubbles up the DOM tree.
|
|
9
|
+
* @property {boolean} [cancelable] - Whether the event can be canceled.
|
|
10
|
+
* @property {boolean} [composed] - Whether the event can cross the shadow DOM boundary.
|
|
11
|
+
*/
|
|
12
|
+
export class Notify {
|
|
2
13
|
/** @type {string} Display name for debugging. */
|
|
3
14
|
name: string;
|
|
4
15
|
/**
|
|
@@ -29,7 +40,7 @@ declare const _default: {
|
|
|
29
40
|
* @param {boolean | object} [options] - Options to pass to addEventListener.
|
|
30
41
|
* @returns {() => void} Dispose function to unregister the handler.
|
|
31
42
|
*/
|
|
32
|
-
on(type: string, handler: (evt:
|
|
43
|
+
on(type: string, handler: (evt: Notify) => void, element?: HTMLElement | Window, options?: boolean | object): () => void;
|
|
33
44
|
/**
|
|
34
45
|
* Removes a previously registered listener for the given event type.
|
|
35
46
|
*
|
|
@@ -39,9 +50,10 @@ declare const _default: {
|
|
|
39
50
|
* @param {boolean | object} [options] - Options to pass to removeEventListener.
|
|
40
51
|
* @returns {void}
|
|
41
52
|
*/
|
|
42
|
-
off(type: string, handler: (evt:
|
|
43
|
-
|
|
44
|
-
}
|
|
53
|
+
off(type: string, handler: (evt: Notify) => void, element?: HTMLElement | Window, options?: boolean | object): void;
|
|
54
|
+
#private;
|
|
55
|
+
}
|
|
56
|
+
declare const _default: Notify;
|
|
45
57
|
export default _default;
|
|
46
58
|
export type NotifyEventOptions = {
|
|
47
59
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Notify.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/Notify.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Notify.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/Notify.js"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;GAKG;AACH;IACE,iDAAiD;IACjD,MADW,MAAM,CACF;IAEf;;;;;;;OAOG;IACH,WALW,MAAM,YACN,OAAO,YACP,OAAO,GAAG,kBAAkB,GAC1B,IAAI,CAKhB;IAED;;;;;;;OAOG;IACH,cALW,MAAM,YACN,OAAO,YACP,OAAO,GAAG,kBAAkB,GAC1B,OAAO,CAOnB;IAED;;;;;;;;;OASG;IACH,SANW,MAAM,WACN,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,YACrB,WAAW,GAAG,MAAM,YACpB,OAAO,GAAG,MAAM,GACd,MAAM,IAAI,CAYtB;IAED;;;;;;;;OAQG;IACH,UANW,MAAM,WACN,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,YACrB,WAAW,GAAG,MAAM,YACpB,OAAO,GAAG,MAAM,GACd,IAAI,CAIhB;;CAWF;;;;;;;cAhFa,OAAO;;;;iBACP,OAAO;;;;eACP,OAAO"}
|
package/types/node/index.d.ts
CHANGED
|
@@ -13,7 +13,7 @@ export { default as FileObject } from "./lib/FileObject.js";
|
|
|
13
13
|
export { default as FileSystem } from "./lib/FileSystem.js";
|
|
14
14
|
export { default as Font } from "./lib/Font.js";
|
|
15
15
|
export { default as Glog } from "./lib/Glog.js";
|
|
16
|
-
export { default as Notify } from "./lib/Notify.js";
|
|
17
16
|
export { default as Term } from "./lib/Term.js";
|
|
18
17
|
export { default as Disposer, Disposer as DisposerClass } from "../browser/lib/Disposer.js";
|
|
18
|
+
export { default as Notify, Notify as NotifyClass } from "./lib/Notify.js";
|
|
19
19
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -266,28 +266,55 @@ export default class DirectoryObject extends FS {
|
|
|
266
266
|
/**
|
|
267
267
|
* Creates a new DirectoryObject by extending this directory's path.
|
|
268
268
|
*
|
|
269
|
+
* Paths are always resolved relative to THIS directory. Any attempt to
|
|
270
|
+
* escape via `..` or absolute paths is constrained - the `..` segments
|
|
271
|
+
* are stripped and the remaining path is resolved relative to this directory.
|
|
272
|
+
*
|
|
273
|
+
* On Windows, cross-drive absolute paths (e.g., `D:\foo` when base is `C:\`)
|
|
274
|
+
* are also constrained - the drive root is stripped and the path is resolved
|
|
275
|
+
* relative to this directory.
|
|
276
|
+
*
|
|
269
277
|
* Uses overlapping path segment detection to intelligently combine paths.
|
|
270
|
-
* Preserves the temporary flag from the current directory.
|
|
271
278
|
*
|
|
272
279
|
* @param {string} newPath - The path to append to this directory's path.
|
|
273
280
|
* @returns {DirectoryObject} A new DirectoryObject with the extended path.
|
|
274
281
|
* @example
|
|
275
282
|
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
276
|
-
* const subDir = dir.
|
|
283
|
+
* const subDir = dir.getDirectory("src/lib")
|
|
277
284
|
* console.log(subDir.path) // "/projects/git/toolkit/src/lib"
|
|
285
|
+
*
|
|
286
|
+
* @example
|
|
287
|
+
* // Path traversal is constrained to this directory
|
|
288
|
+
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
289
|
+
* const escaped = dir.getDirectory("../../../foo/bar")
|
|
290
|
+
* console.log(escaped.path) // "/projects/git/toolkit/foo/bar"
|
|
278
291
|
*/
|
|
279
292
|
getDirectory(newPath: string): DirectoryObject;
|
|
280
293
|
/**
|
|
281
294
|
* Creates a new FileObject by extending this directory's path.
|
|
282
295
|
*
|
|
296
|
+
* Paths are always resolved relative to THIS directory. Any attempt to
|
|
297
|
+
* escape via `..` or absolute paths is constrained - the `..` segments
|
|
298
|
+
* are stripped and the remaining path is resolved relative to this directory.
|
|
299
|
+
*
|
|
300
|
+
* On Windows, cross-drive absolute paths (e.g., `D:\foo` when base is `C:\`)
|
|
301
|
+
* are also constrained - the drive root is stripped and the path is resolved
|
|
302
|
+
* relative to this directory.
|
|
303
|
+
*
|
|
283
304
|
* Uses overlapping path segment detection to intelligently combine paths.
|
|
284
305
|
*
|
|
285
306
|
* @param {string} filename - The filename to append to this directory's path.
|
|
286
307
|
* @returns {FileObject} A new FileObject with the extended path.
|
|
287
308
|
* @example
|
|
288
309
|
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
289
|
-
* const file = dir.
|
|
310
|
+
* const file = dir.getFile("package.json")
|
|
290
311
|
* console.log(file.path) // "/projects/git/toolkit/package.json"
|
|
312
|
+
*
|
|
313
|
+
* @example
|
|
314
|
+
* // Path traversal is constrained to this directory
|
|
315
|
+
* const dir = new DirectoryObject("/projects/git/toolkit")
|
|
316
|
+
* const escaped = dir.getFile("../../../foo/bar.js")
|
|
317
|
+
* console.log(escaped.path) // "/projects/git/toolkit/foo/bar.js"
|
|
291
318
|
*/
|
|
292
319
|
getFile(filename: string): FileObject;
|
|
293
320
|
#private;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/DirectoryObject.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/DirectoryObject.js"],"names":[],"mappings":"AAiBA;;;;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;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,sBAbW,MAAM,GACJ,eAAe,CAkC3B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,kBAbW,MAAM,GACJ,UAAU,CAkCtB;;CACF;;UA5mBa,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"}
|
|
@@ -101,26 +101,45 @@ export default class FileSystem {
|
|
|
101
101
|
* @param {string} [sep=path.sep] - The path separator to use (defaults to system separator)
|
|
102
102
|
* @returns {string|null} The relative path, empty string if paths are identical, or null if no overlap found
|
|
103
103
|
* @example
|
|
104
|
-
* FS.
|
|
104
|
+
* FS.toLocalRelativePath("/projects/toolkit", "/projects/toolkit/src") // "src"
|
|
105
|
+
* FS.toLocalRelativePath("/home/user", "/home/user") // ""
|
|
106
|
+
* FS.toLocalRelativePath("/projects/app", "/other/path") // null
|
|
107
|
+
*/
|
|
108
|
+
static toLocalRelativePath(from: string, to: string, sep?: string): string | null;
|
|
109
|
+
/**
|
|
110
|
+
* Computes the relative path from one path to another using Node's path.relative.
|
|
111
|
+
*
|
|
112
|
+
* Unlike toLocalRelativePath which uses overlap detection, this method uses
|
|
113
|
+
* standard relative path calculation and may return paths with ".." segments.
|
|
114
|
+
*
|
|
115
|
+
* @static
|
|
116
|
+
* @param {string} from - The base path to calculate relative from
|
|
117
|
+
* @param {string} to - The target path to make relative
|
|
118
|
+
* @returns {string} The relative path, or empty string if paths are identical
|
|
119
|
+
* @example
|
|
120
|
+
* FS.toRelativePath("/home/user", "/home/user/docs") // "docs"
|
|
105
121
|
* FS.toRelativePath("/home/user", "/home/user") // ""
|
|
106
|
-
* FS.toRelativePath("/
|
|
122
|
+
* FS.toRelativePath("/home/user", "/home/other") // "../other"
|
|
107
123
|
*/
|
|
108
|
-
static toRelativePath(from: string, to: string
|
|
124
|
+
static toRelativePath(from: string, to: string): string;
|
|
109
125
|
/**
|
|
110
|
-
* Find
|
|
111
|
-
*
|
|
126
|
+
* Find where a path's final segment appears in another path, returning the
|
|
127
|
+
* portion of 'from' up to that overlap point.
|
|
128
|
+
*
|
|
129
|
+
* Looks for the last segment of `from` within `to`. If found, returns `from`
|
|
130
|
+
* sliced to the index where that segment appears in `to`.
|
|
112
131
|
*
|
|
113
132
|
* @static
|
|
114
|
-
* @param {string} from - The
|
|
115
|
-
* @param {string} to - The
|
|
133
|
+
* @param {string} from - The source path whose final segment to search for
|
|
134
|
+
* @param {string} to - The target path to search within
|
|
116
135
|
* @param {string} [sep=path.sep] - The path separator to use (defaults to system separator)
|
|
117
|
-
* @returns {string|null} The
|
|
136
|
+
* @returns {string|null} The sliced portion of from, the original path if identical, or null if no overlap
|
|
118
137
|
* @throws {Sass} If from is not a non-empty string
|
|
119
138
|
* @throws {Sass} If to is not a non-empty string
|
|
120
139
|
* @example
|
|
121
|
-
* FS.getCommonRootPath("/projects/toolkit
|
|
140
|
+
* FS.getCommonRootPath("/projects/toolkit", "/projects/toolkit/src") // "/projects/toolkit"
|
|
122
141
|
* FS.getCommonRootPath("/home/user", "/home/user") // "/home/user"
|
|
123
|
-
* FS.getCommonRootPath("/projects/app", "/other/path") // null
|
|
142
|
+
* FS.getCommonRootPath("/projects/app", "/other/path") // null (no overlap)
|
|
124
143
|
*/
|
|
125
144
|
static getCommonRootPath(from: string, to: string, sep?: string): string | null;
|
|
126
145
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../../src/node/lib/FileSystem.js"],"names":[],"mappings":"AA2BA;;GAEG;AACH;IACE,kCAAwB;IACxB,uCAAkC;IAClC,mBAAsB;IAsBtB;;;;;;OAMG;IACH,4BAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;OAMG;IACH,2BAHW,MAAM,GACJ,MAAM,CAQlB;IAED;;;;;;;;OAQG;IACH,0BALW,MAAM,GACJ,MAAM,CAUlB;IAED;;;;;;;;;;OAUG;IACH,gCAJW,UAAU,GAAC,eAAe,MAC1B,UAAU,GAAC,eAAe,GACxB,MAAM,CAYlB;IAED;;;;;;;;;;OAUG;IACH,oCAJW,MAAM,MACN,MAAM,GACJ,MAAM,CAQlB;IAED;;;;;;;;;OASG;IACH,oCALW,MAAM,SACN,MAAM,QACN,MAAM,GACJ,MAAM,CA0BlB;IAED;;;;;;;;OAQG;IACH,6BAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAmClB;IAED;;;;;;;;;;;;OAYG;IACH,+BATW,MAAM,aACN,MAAM,GACJ,OAAO,CAcnB;IAED;;;;;;;;;;;;;;OAcG;IACH,
|
|
1
|
+
{"version":3,"file":"FileSystem.d.ts","sourceRoot":"","sources":["../../../src/node/lib/FileSystem.js"],"names":[],"mappings":"AA2BA;;GAEG;AACH;IACE,kCAAwB;IACxB,uCAAkC;IAClC,mBAAsB;IAsBtB;;;;;;OAMG;IACH,4BAHW,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;OAMG;IACH,2BAHW,MAAM,GACJ,MAAM,CAQlB;IAED;;;;;;;;OAQG;IACH,0BALW,MAAM,GACJ,MAAM,CAUlB;IAED;;;;;;;;;;OAUG;IACH,gCAJW,UAAU,GAAC,eAAe,MAC1B,UAAU,GAAC,eAAe,GACxB,MAAM,CAYlB;IAED;;;;;;;;;;OAUG;IACH,oCAJW,MAAM,MACN,MAAM,GACJ,MAAM,CAQlB;IAED;;;;;;;;;OASG;IACH,oCALW,MAAM,SACN,MAAM,QACN,MAAM,GACJ,MAAM,CA0BlB;IAED;;;;;;;;OAQG;IACH,6BAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAmClB;IAED;;;;;;;;;;;;OAYG;IACH,+BATW,MAAM,aACN,MAAM,GACJ,OAAO,CAcnB;IAED;;;;;;;;;;;;;;OAcG;IACH,iCATW,MAAM,MACN,MAAM,QACN,MAAM,GACJ,MAAM,GAAC,IAAI,CAwBvB;IAED;;;;;;;;;;;;;;OAcG;IACH,4BARW,MAAM,MACN,MAAM,GACJ,MAAM,CAYlB;IAED;;;;;;;;;;;;;;;;;;OAkBG;IACH,+BAXW,MAAM,MACN,MAAM,QACN,MAAM,GACJ,MAAM,GAAC,IAAI,CA+BvB;IAED;;;;;;;OAOG;IAEH;;;;;;;OAOG;IACH,2BAJW,MAAM;;;;cAXH,MAAM;;;;aACN,MAAM;;;;aACN,MAAM;;;;cACN,MAAM;;;;cACN,MAAM;MAenB;IAED;;;;OAIG;IACH,kBAFa,MAAM,CAIlB;IAnVD;;;;;;;;;OASG;IACH,kCAJW,UAAU,GAAC,eAAe,GACxB,MAAM,CAWlB;CAkUF;yBArWa,OAAO,iBAAiB,EAAE,OAAO;8BACjC,OAAO,sBAAsB,EAAE,OAAO"}
|
|
@@ -1,8 +1,15 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {object} NotifyEventOptions
|
|
3
|
+
* @property {boolean} [once] - Whether the listener should be invoked only once.
|
|
4
|
+
* @property {AbortSignal} [signal] - An AbortSignal to remove the listener.
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Notify class provides a thin wrapper around EventEmitter for centralized
|
|
8
|
+
* event handling in Node.js applications. Mirrors the browser Notify API.
|
|
9
|
+
*/
|
|
10
|
+
export class Notify {
|
|
2
11
|
/** @type {string} Display name for debugging. */
|
|
3
12
|
name: string;
|
|
4
|
-
/** @type {EventEmitter} Internal event emitter */
|
|
5
|
-
"__#private@#emitter": EventEmitter;
|
|
6
13
|
/**
|
|
7
14
|
* Emits an event without expecting a return value.
|
|
8
15
|
*
|
|
@@ -49,7 +56,9 @@ declare const _default: {
|
|
|
49
56
|
* @returns {void}
|
|
50
57
|
*/
|
|
51
58
|
off(type: string, handler: (payload: unknown) => void, emitter?: EventEmitter): void;
|
|
52
|
-
|
|
59
|
+
#private;
|
|
60
|
+
}
|
|
61
|
+
declare const _default: Notify;
|
|
53
62
|
export default _default;
|
|
54
63
|
export type NotifyEventOptions = {
|
|
55
64
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Notify.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Notify.js"],"names":[],"mappings":";
|
|
1
|
+
{"version":3,"file":"Notify.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Notify.js"],"names":[],"mappings":"AAWA;;;;GAIG;AAEH;;;GAGG;AACH;IACE,iDAAiD;IACjD,MADW,MAAM,CACF;IAKf;;;;;;OAMG;IACH,WAJW,MAAM,YACN,OAAO,GACL,IAAI,CAMhB;IAED;;;;;;;;OAQG;IACH,gBAJW,MAAM,YACN,OAAO,GACL,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;;;;;OAOG;IACH,cAJW,MAAM,YACN,OAAO,GACL,OAAO,CAQnB;IAED;;;;;;;;OAQG;IACH,SANW,MAAM,WACN,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,YAC1B,YAAY,YACZ,kBAAkB,GAChB,MAAM,IAAI,CAatB;IAED;;;;;;;OAOG;IACH,UALW,MAAM,WACN,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,YAC1B,YAAY,GACV,IAAI,CAMhB;;CACF;;;;;;;WA9Fa,OAAO;;;;aACP,WAAW"}
|