@gesslar/toolkit 3.7.0 → 3.8.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 +1 -1
- package/src/lib/CappedDirectoryObject.js +45 -14
- package/src/lib/DirectoryObject.js +30 -1
- package/src/lib/TempDirectoryObject.js +13 -4
- package/src/types/lib/CappedDirectoryObject.d.ts +22 -0
- package/src/types/lib/CappedDirectoryObject.d.ts.map +1 -1
- package/src/types/lib/DirectoryObject.d.ts +18 -0
- package/src/types/lib/DirectoryObject.d.ts.map +1 -1
- package/src/types/lib/TempDirectoryObject.d.ts.map +1 -1
package/package.json
CHANGED
|
@@ -132,6 +132,16 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
132
132
|
}
|
|
133
133
|
}
|
|
134
134
|
|
|
135
|
+
/**
|
|
136
|
+
* Re-caps this directory to itself, making it the new root of the capped tree.
|
|
137
|
+
* This is a protected method intended for use by subclasses like TempDirectoryObject.
|
|
138
|
+
*
|
|
139
|
+
* @protected
|
|
140
|
+
*/
|
|
141
|
+
_recapToSelf() {
|
|
142
|
+
this.#cap = this.#realPath
|
|
143
|
+
}
|
|
144
|
+
|
|
135
145
|
/**
|
|
136
146
|
* Returns the cap path for this directory.
|
|
137
147
|
*
|
|
@@ -221,14 +231,14 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
221
231
|
* Returns the parent directory of this capped directory.
|
|
222
232
|
* Returns null only if this directory is at the cap (the "root" of the capped tree).
|
|
223
233
|
*
|
|
224
|
-
* Note: The returned parent is a
|
|
225
|
-
*
|
|
234
|
+
* Note: The returned parent is a CappedDirectoryObject with the same cap.
|
|
235
|
+
* This maintains the capping behavior throughout the directory hierarchy.
|
|
226
236
|
*
|
|
227
|
-
* @returns {
|
|
237
|
+
* @returns {CappedDirectoryObject|null} Parent directory or null if at cap root
|
|
228
238
|
* @example
|
|
229
239
|
* const capped = new TempDirectoryObject("myapp")
|
|
230
240
|
* const subdir = capped.getDirectory("data")
|
|
231
|
-
* console.log(subdir.parent.path) // Returns parent
|
|
241
|
+
* console.log(subdir.parent.path) // Returns parent CappedDirectoryObject
|
|
232
242
|
* console.log(capped.parent) // null (at cap root)
|
|
233
243
|
*/
|
|
234
244
|
get parent() {
|
|
@@ -239,13 +249,17 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
239
249
|
return null
|
|
240
250
|
}
|
|
241
251
|
|
|
242
|
-
//
|
|
252
|
+
// Compute parent's real path
|
|
243
253
|
const parentPath = path.dirname(this.#realPath)
|
|
244
254
|
const isRoot = parentPath === this.#realPath
|
|
245
255
|
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
256
|
+
if(isRoot) {
|
|
257
|
+
return null
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Compute relative path from current to parent (just "..")
|
|
261
|
+
// Then use getDirectory to create the parent, which preserves the class type
|
|
262
|
+
return this.getDirectory("..")
|
|
249
263
|
}
|
|
250
264
|
|
|
251
265
|
/**
|
|
@@ -264,9 +278,24 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
264
278
|
*/
|
|
265
279
|
toJSON() {
|
|
266
280
|
const capResolved = path.resolve(this.#cap)
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
281
|
+
let parentPath
|
|
282
|
+
|
|
283
|
+
if(this.#realPath === capResolved) {
|
|
284
|
+
// At cap root, no parent
|
|
285
|
+
parentPath = null
|
|
286
|
+
} else {
|
|
287
|
+
// Compute parent's virtual path
|
|
288
|
+
const parentReal = path.dirname(this.#realPath)
|
|
289
|
+
const relative = path.relative(capResolved, parentReal)
|
|
290
|
+
|
|
291
|
+
// If parent is cap root or empty, return "/"
|
|
292
|
+
if(!relative || relative === ".") {
|
|
293
|
+
parentPath = "/"
|
|
294
|
+
} else {
|
|
295
|
+
// Return parent's virtual path with leading slash
|
|
296
|
+
parentPath = "/" + relative.split(path.sep).join("/")
|
|
297
|
+
}
|
|
298
|
+
}
|
|
270
299
|
|
|
271
300
|
return {
|
|
272
301
|
supplied: this.supplied,
|
|
@@ -278,6 +307,7 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
278
307
|
isFile: this.isFile,
|
|
279
308
|
isDirectory: this.isDirectory,
|
|
280
309
|
parent: parentPath,
|
|
310
|
+
root: this.root.path,
|
|
281
311
|
real: this.real.toJSON()
|
|
282
312
|
}
|
|
283
313
|
}
|
|
@@ -436,10 +466,11 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
436
466
|
// Start at cap root
|
|
437
467
|
let current = this.#createCappedAtRoot()
|
|
438
468
|
|
|
439
|
-
// Traverse each segment,
|
|
440
|
-
// (not subclass instances, to avoid constructor signature issues)
|
|
469
|
+
// Traverse each segment, using constructor to preserve class type
|
|
441
470
|
for(const segment of segments) {
|
|
442
|
-
|
|
471
|
+
// Use simple name constructor to preserve subclass type
|
|
472
|
+
// Works for both CappedDirectoryObject and TempDirectoryObject
|
|
473
|
+
current = new this.constructor(segment, current, this.temporary)
|
|
443
474
|
}
|
|
444
475
|
|
|
445
476
|
return current
|
|
@@ -157,7 +157,8 @@ export default class DirectoryObject extends FS {
|
|
|
157
157
|
extension: this.extension,
|
|
158
158
|
isFile: this.isFile,
|
|
159
159
|
isDirectory: this.isDirectory,
|
|
160
|
-
parent: this.parent ? this.parent.path : null
|
|
160
|
+
parent: this.parent ? this.parent.path : null,
|
|
161
|
+
root: this.root.path
|
|
161
162
|
}
|
|
162
163
|
}
|
|
163
164
|
|
|
@@ -294,6 +295,34 @@ export default class DirectoryObject extends FS {
|
|
|
294
295
|
return this.#parent
|
|
295
296
|
}
|
|
296
297
|
|
|
298
|
+
/**
|
|
299
|
+
* Returns the root directory of the filesystem.
|
|
300
|
+
*
|
|
301
|
+
* For DirectoryObject, this walks up to the filesystem root.
|
|
302
|
+
* For CappedDirectoryObject, this returns the cap root.
|
|
303
|
+
*
|
|
304
|
+
* @returns {DirectoryObject} The root directory
|
|
305
|
+
* @example
|
|
306
|
+
* const dir = new DirectoryObject("/usr/local/bin")
|
|
307
|
+
* console.log(dir.root.path) // "/"
|
|
308
|
+
*
|
|
309
|
+
* @example
|
|
310
|
+
* const capped = new CappedDirectoryObject("/projects/myapp")
|
|
311
|
+
* const sub = capped.getDirectory("src/lib")
|
|
312
|
+
* console.log(sub.root.path) // "/" (virtual, cap root)
|
|
313
|
+
* console.log(sub.root.real.path) // "/projects/myapp"
|
|
314
|
+
*/
|
|
315
|
+
get root() {
|
|
316
|
+
// Walk up until we find a directory with no parent
|
|
317
|
+
let current = this
|
|
318
|
+
|
|
319
|
+
while(current.parent !== null) {
|
|
320
|
+
current = current.parent
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return current
|
|
324
|
+
}
|
|
325
|
+
|
|
297
326
|
/**
|
|
298
327
|
* Recursively removes a temporary directory and all its contents.
|
|
299
328
|
*
|
|
@@ -99,11 +99,13 @@ export default class TempDirectoryObject extends CappedDirectoryObject {
|
|
|
99
99
|
)
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
-
// SECURITY: Ensure parent's cap is tmpdir (prevent escape to other caps)
|
|
103
|
-
const tmpdir = os.tmpdir()
|
|
104
|
-
|
|
102
|
+
// SECURITY: Ensure parent's cap is within tmpdir (prevent escape to other caps)
|
|
103
|
+
const tmpdir = path.resolve(os.tmpdir())
|
|
104
|
+
const parentCap = path.resolve(parent.cap)
|
|
105
|
+
|
|
106
|
+
if(!parentCap.startsWith(tmpdir)) {
|
|
105
107
|
throw Sass.new(
|
|
106
|
-
`Parent must be capped to OS temp directory (${tmpdir}), ` +
|
|
108
|
+
`Parent must be capped to OS temp directory (${tmpdir}) or a subdirectory thereof, ` +
|
|
107
109
|
`got cap: ${parent.cap}`
|
|
108
110
|
)
|
|
109
111
|
}
|
|
@@ -119,6 +121,13 @@ export default class TempDirectoryObject extends CappedDirectoryObject {
|
|
|
119
121
|
|
|
120
122
|
// Temp-specific behavior: create directory immediately
|
|
121
123
|
this.#createDirectory()
|
|
124
|
+
|
|
125
|
+
// Re-cap to the temp directory itself for consistent behavior with CappedDirectoryObject
|
|
126
|
+
// This makes temp.cap === temp.real.path and temp.parent === null
|
|
127
|
+
if(!parent) {
|
|
128
|
+
// Only re-cap if this is a root temp directory (no TempDirectoryObject parent)
|
|
129
|
+
this._recapToSelf()
|
|
130
|
+
}
|
|
122
131
|
}
|
|
123
132
|
|
|
124
133
|
/**
|
|
@@ -37,6 +37,13 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
37
37
|
* // path: /home/user/.cache/etc/config, cap: /home/user/.cache
|
|
38
38
|
*/
|
|
39
39
|
constructor(dirPath: string, parent?: CappedDirectoryObject | null, temporary?: boolean);
|
|
40
|
+
/**
|
|
41
|
+
* Re-caps this directory to itself, making it the new root of the capped tree.
|
|
42
|
+
* This is a protected method intended for use by subclasses like TempDirectoryObject.
|
|
43
|
+
*
|
|
44
|
+
* @protected
|
|
45
|
+
*/
|
|
46
|
+
protected _recapToSelf(): void;
|
|
40
47
|
/**
|
|
41
48
|
* Returns the cap path for this directory.
|
|
42
49
|
*
|
|
@@ -75,6 +82,21 @@ export default class CappedDirectoryObject extends DirectoryObject {
|
|
|
75
82
|
* subdir.real.parent // Can traverse outside the cap
|
|
76
83
|
*/
|
|
77
84
|
get real(): DirectoryObject;
|
|
85
|
+
/**
|
|
86
|
+
* Returns the parent directory of this capped directory.
|
|
87
|
+
* Returns null only if this directory is at the cap (the "root" of the capped tree).
|
|
88
|
+
*
|
|
89
|
+
* Note: The returned parent is a CappedDirectoryObject with the same cap.
|
|
90
|
+
* This maintains the capping behavior throughout the directory hierarchy.
|
|
91
|
+
*
|
|
92
|
+
* @returns {CappedDirectoryObject|null} Parent directory or null if at cap root
|
|
93
|
+
* @example
|
|
94
|
+
* const capped = new TempDirectoryObject("myapp")
|
|
95
|
+
* const subdir = capped.getDirectory("data")
|
|
96
|
+
* console.log(subdir.parent.path) // Returns parent CappedDirectoryObject
|
|
97
|
+
* console.log(capped.parent) // null (at cap root)
|
|
98
|
+
*/
|
|
99
|
+
get parent(): CappedDirectoryObject | null;
|
|
78
100
|
/**
|
|
79
101
|
* Returns the URL with virtual path (cap-relative).
|
|
80
102
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CappedDirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/CappedDirectoryObject.js"],"names":[],"mappings":"AAkBA;;;;;;;;GAQG;AACH;IAGE;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,qBArBW,MAAM,WACN,qBAAqB,OAAC,cACtB,OAAO,EA0EjB;IAqBD;;;;OAIG;IACH,WAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,cAFa,OAAO,CAInB;IAED;;;;;OAKG;IACH,0BAFa,MAAM,CAIlB;IAqCD;;;;;;;;;;;;;;;;;OAiBG;IACH,YAba,eAAe,CAe3B;
|
|
1
|
+
{"version":3,"file":"CappedDirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/CappedDirectoryObject.js"],"names":[],"mappings":"AAkBA;;;;;;;;GAQG;AACH;IAGE;;;;;;;;;;;;;;;;;;;;;;;;;;;OA2BG;IACH,qBArBW,MAAM,WACN,qBAAqB,OAAC,cACtB,OAAO,EA0EjB;IAqBD;;;;;OAKG;IACH,+BAEC;IAED;;;;OAIG;IACH,WAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,cAFa,OAAO,CAInB;IAED;;;;;OAKG;IACH,0BAFa,MAAM,CAIlB;IAqCD;;;;;;;;;;;;;;;;;OAiBG;IACH,YAba,eAAe,CAe3B;IAED;;;;;;;;;;;;;OAaG;IACH,cAPa,qBAAqB,GAAC,IAAI,CA0BtC;IAED;;;;OAIG;IACH,WAFa,GAAG,CAIf;IAqFD;;;;OAIG;IACH,cAFa,SAAS,CAAC,eAAe,CAAC,CAItC;IAED;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,sBAjBW,MAAM,GACJ,qBAAqB,CAiEjC;IAsID;;;;;OAKG;IACH,WAHW,MAAM,GACJ,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,WAAW,QAAO;KAAC,CAAC,CAgBnE;;CA8DF;4BAloB2B,sBAAsB;uBAC3B,iBAAiB"}
|
|
@@ -139,6 +139,24 @@ export default class DirectoryObject extends FS {
|
|
|
139
139
|
* console.log(root.parent) // null
|
|
140
140
|
*/
|
|
141
141
|
get parent(): DirectoryObject | null;
|
|
142
|
+
/**
|
|
143
|
+
* Returns the root directory of the filesystem.
|
|
144
|
+
*
|
|
145
|
+
* For DirectoryObject, this walks up to the filesystem root.
|
|
146
|
+
* For CappedDirectoryObject, this returns the cap root.
|
|
147
|
+
*
|
|
148
|
+
* @returns {DirectoryObject} The root directory
|
|
149
|
+
* @example
|
|
150
|
+
* const dir = new DirectoryObject("/usr/local/bin")
|
|
151
|
+
* console.log(dir.root.path) // "/"
|
|
152
|
+
*
|
|
153
|
+
* @example
|
|
154
|
+
* const capped = new CappedDirectoryObject("/projects/myapp")
|
|
155
|
+
* const sub = capped.getDirectory("src/lib")
|
|
156
|
+
* console.log(sub.root.path) // "/" (virtual, cap root)
|
|
157
|
+
* console.log(sub.root.real.path) // "/projects/myapp"
|
|
158
|
+
*/
|
|
159
|
+
get root(): DirectoryObject;
|
|
142
160
|
/**
|
|
143
161
|
* Recursively removes a temporary directory and all its contents.
|
|
144
162
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/DirectoryObject.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH;
|
|
1
|
+
{"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/DirectoryObject.js"],"names":[],"mappings":"AAgBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgDG;AACH;uBAsGe,MAAM;IAnEnB;;;;;OAKG;IACH,yCAFW,OAAO,EA6BjB;IAWD;;;;OAIG;IACH,UAFa,MAAM,CAelB;IAWD;;;;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;;;;OAIG;IACH,iBAFa,OAAO,CAInB;IAED;;;;;;;;;;;;OAYG;IACH,cARa,eAAe,GAAC,IAAI,CAwBhC;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,YAXa,eAAe,CAoB3B;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,UATa,OAAO,CAAC,IAAI,CAAC,CA0BzB;IAED;;;;OAIG;IACH,cAFa,OAAO,CAInB;IAED;;;;OAIG;IACH,mBAFa,OAAO,CAInB;IAiBD;;;;;;;;;;;;;;;OAeG;IACH,WAZW,MAAM,GACJ,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;KAAC,CAAC,CAoCpF;IAED;;;;;;;;;;;;OAYG;IACH,uBARW,MAAM,GACJ,OAAO,CAAC,IAAI,CAAC,CAqBzB;IA8BD;;;;;;;;;;;;;;;OAeG;IACH,cAZa,MAAM,CAclB;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;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,sBAdW,MAAM,GACJ,eAAe,CAoB3B;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,kBAbW,MAAM,GACJ,UAAU,CAkBtB;;CACF;eAnmBc,SAAS;uBACD,iBAAiB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TempDirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/TempDirectoryObject.js"],"names":[],"mappings":"AAcA;;;;;;;;;GASG;AACH;IAEE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,mBAxBW,MAAM,OAAC,WACP,mBAAmB,OAAC,
|
|
1
|
+
{"version":3,"file":"TempDirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/TempDirectoryObject.js"],"names":[],"mappings":"AAcA;;;;;;;;;GASG;AACH;IAEE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAiCG;IACH,mBAxBW,MAAM,OAAC,WACP,mBAAmB,OAAC,EA6F9B;IAsBD;;;;;;;;;;;;;;OAcG;IACH,sBAVW,MAAM,GACJ,mBAAmB,CAY/B;IAED;;;;;;;;;;;;;;OAcG;IACH,kBAVW,MAAM,GACJ,UAAU,CAYtB;;CAUF;kCA9LiC,4BAA4B"}
|