@gesslar/toolkit 3.9.0 → 3.12.3

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.
@@ -4,13 +4,16 @@
4
4
  * to the OS's temporary directory tree.
5
5
  */
6
6
 
7
- import fs from "node:fs"
7
+ import fs, {mkdirSync, mkdtempSync} from "node:fs"
8
8
  import os from "node:os"
9
9
  import path from "node:path"
10
10
 
11
- import CappedDirectoryObject from "./CappedDirectoryObject.js"
12
11
  import Data from "../browser/lib/Data.js"
12
+ import CappedDirectoryObject from "./CappedDirectoryObject.js"
13
+ import DirectoryObject from "./DirectoryObject.js"
14
+ import FS from "./FS.js"
13
15
  import Sass from "./Sass.js"
16
+ import Valid from "./Valid.js"
14
17
 
15
18
  /**
16
19
  * TempDirectoryObject extends CappedDirectoryObject with the cap set to
@@ -23,6 +26,8 @@ import Sass from "./Sass.js"
23
26
  * @augments CappedDirectoryObject
24
27
  */
25
28
  export default class TempDirectoryObject extends CappedDirectoryObject {
29
+ #tmpReal
30
+ #tmpCap
26
31
 
27
32
  /**
28
33
  * Constructs a TempDirectoryObject instance and creates the directory.
@@ -34,7 +39,7 @@ export default class TempDirectoryObject extends CappedDirectoryObject {
34
39
  * is provided without a parent, creates a new directory with a unique suffix.
35
40
  * If a parent is provided, creates a subdirectory within that parent.
36
41
  *
37
- * @param {string?} [name] - Base name for the temp directory (if empty/null, uses OS temp dir)
42
+ * @param {string?} [directory] - Base name for the temp directory (if empty/null, uses OS temp dir)
38
43
  * @param {TempDirectoryObject?} [parent] - Optional parent temporary directory
39
44
  * @throws {Sass} If name is absolute
40
45
  * @throws {Sass} If name is empty (when parent is provided)
@@ -43,172 +48,118 @@ export default class TempDirectoryObject extends CappedDirectoryObject {
43
48
  * @throws {Sass} If parent's lineage does not trace back to the OS temp directory
44
49
  * @throws {Sass} If directory creation fails
45
50
  * @example
46
- * // Use OS temp directory directly
47
- * const temp = new TempDirectoryObject()
48
- * console.log(temp.path) // "/tmp"
49
- *
50
- * @example
51
51
  * // Create with unique name
52
52
  * const temp = new TempDirectoryObject("myapp")
53
- * console.log(temp.path) // "/tmp/myapp-ABC123"
54
- *
55
- * @example
56
- * // Nested temp directories
57
- * const parent = new TempDirectoryObject("parent")
58
- * const child = new TempDirectoryObject("child", parent)
59
- * await parent.remove() // Removes both parent and child
53
+ * console.log(temp.path) // "/"
54
+ * console.log(temp.real.path) // "/tmp/myapp-ABC123"
60
55
  */
61
- constructor(name, parent=null) {
62
- let dirPath
63
- let cappedParent = parent
64
-
65
- if(!parent) {
66
- // No parent: need to create a capped parent at tmpdir first
67
- cappedParent = new CappedDirectoryObject(os.tmpdir(), null, true)
68
-
69
- if(name) {
70
- // Check if name is a simple name (no separators, not absolute)
71
- const isSimpleName = !path.isAbsolute(name) &&
72
- !name.includes("/") &&
73
- !name.includes("\\") &&
74
- !name.includes(path.sep)
75
-
76
- if(isSimpleName) {
77
- // Simple name: add unique suffix
78
- const prefix = name.endsWith("-") ? name : `${name}-`
79
- const uniqueSuffix =
80
- Math.random()
81
- .toString(36)
82
- .substring(2, 8)
83
- .toUpperCase()
84
- dirPath = `${prefix}${uniqueSuffix}`
85
- } else {
86
- // Complex path: use as-is, let CappedDirectoryObject handle coercion
87
- dirPath = name
88
- }
89
- } else {
90
- // No name: use tmpdir itself (no parent)
91
- dirPath = os.tmpdir()
92
- cappedParent = null
93
- }
94
- } else {
95
- // With parent: validate it's a proper temp directory parent
96
- if(!Data.isType(parent, "CappedDirectoryObject")) {
97
- throw Sass.new(
98
- "Parent must be a CappedDirectoryObject or TempDirectoryObject."
99
- )
100
- }
101
-
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)) {
107
- throw Sass.new(
108
- `Parent must be capped to OS temp directory (${tmpdir}) or a subdirectory thereof, ` +
109
- `got cap: ${parent.cap}`
110
- )
111
- }
112
-
113
- dirPath = name || ""
114
- if(!dirPath) {
115
- throw Sass.new("Name must not be empty when parent is provided.")
116
- }
117
- }
56
+ constructor(directory, source=null) {
57
+ Valid.type(source, "Null|TempDirectoryObject")
58
+
59
+ directory ||= "temp"
60
+ directory = Data.append(directory, source ? "" : "-")
118
61
 
119
- // Call parent constructor with new signature
120
- super(dirPath, cappedParent, true)
62
+ const parentRealPath = source?.real.path ?? os.tmpdir()
121
63
 
122
- // Temp-specific behavior: create directory immediately
123
- this.#createDirectory()
64
+ if(source && path.isAbsolute(directory)) {
65
+ const {root} = FS.pathParts(directory)
124
66
 
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()
67
+ directory = Data.chopLeft(directory, root)
130
68
  }
131
- }
132
69
 
133
- /**
134
- * TempDirectoryObject does not support fromCwd() since it is specifically
135
- * designed to work within the OS temporary directory tree.
136
- *
137
- * @throws {Sass} Always throws an error
138
- */
139
- static fromCwd() {
140
- throw Sass.new(
141
- "TempDirectoryObject.fromCwd() is not supported. " +
142
- "Use CappedDirectoryObject.fromCwd() instead if you need to cap at the current working directory."
143
- )
144
- }
70
+ let realTempDirectoryPath, toSuper
145
71
 
146
- /**
147
- * Creates the directory synchronously on the filesystem.
148
- *
149
- * @private
150
- * @throws {Sass} If directory creation fails
151
- */
152
- #createDirectory() {
153
- try {
154
- // Use recursive: true to create parent directories as needed
155
- fs.mkdirSync(this.realPath, {recursive: true})
156
- } catch(e) {
157
- // EEXIST is fine - directory already exists
158
- if(e.code !== "EEXIST") {
159
- throw Sass.new(
160
- `Unable to create temporary directory '${this.realPath}': ${e.message}`
161
- )
162
- }
72
+ if(source) {
73
+ toSuper = `/${directory}`
74
+ realTempDirectoryPath =
75
+ FS.mergeOverlappingPaths(parentRealPath, directory)
76
+ if(!fs.existsSync(realTempDirectoryPath))
77
+ mkdirSync(realTempDirectoryPath)
78
+ } else {
79
+ realTempDirectoryPath =
80
+ mkdtempSync(FS.mergeOverlappingPaths(os.tmpdir(), directory))
81
+ toSuper = path.resolve(path.sep)
163
82
  }
83
+
84
+ super(toSuper, source)
85
+
86
+ this.#tmpReal = new DirectoryObject(realTempDirectoryPath)
87
+ this.#tmpCap = source?.cap ?? this
88
+ }
89
+
90
+ get isTemporary() {
91
+ return true
164
92
  }
165
93
 
166
94
  /**
167
- * Creates a new TempDirectoryObject by extending this directory's path.
95
+ * Returns a plain DirectoryObject representing the actual filesystem location.
96
+ * This provides an "escape hatch" from the capped environment to interact
97
+ * with the real filesystem when needed.
168
98
  *
169
- * Validates that the resulting path remains within the temp directory tree.
170
- *
171
- * @param {string} newPath - The path segment to append
172
- * @returns {TempDirectoryObject} A new TempDirectoryObject with the extended path
173
- * @throws {Sass} If the path would escape the temp directory
174
- * @throws {Sass} If the path is absolute
175
- * @throws {Sass} If the path contains traversal (..)
99
+ * @returns {DirectoryObject} Uncapped directory object at the real filesystem path
176
100
  * @example
177
101
  * const temp = new TempDirectoryObject("myapp")
178
- * const subDir = temp.getDirectory("data")
179
- * console.log(subDir.path) // "/tmp/myapp-ABC123/data"
102
+ * const subdir = temp.getDirectory("data")
103
+ *
104
+ * // Work within the capped environment (virtual paths)
105
+ * console.log(subdir.path) // "/data" (virtual)
106
+ * subdir.getFile("config.json") // Stays within cap
107
+ *
108
+ * // Break out to real filesystem when needed
109
+ * console.log(subdir.real.path) // "/tmp/myapp-ABC123/data" (real)
110
+ * subdir.real.parent // Can traverse outside the cap
180
111
  */
181
- getDirectory(newPath) {
182
- // Delegate to base class getDirectory() which will call TempDirectoryObject constructor
183
- return super.getDirectory(newPath)
112
+ get real() {
113
+ return this.#tmpReal
114
+ }
115
+
116
+ get cap() {
117
+ return this.#tmpCap
184
118
  }
185
119
 
186
120
  /**
187
- * Creates a new FileObject by extending this directory's path.
121
+ * Recursively removes a temporary directory and all its contents.
188
122
  *
189
- * Validates that the resulting path remains within the temp directory tree.
123
+ * This method will delete all files and subdirectories within this directory,
124
+ * then delete the directory itself. It only works on directories explicitly
125
+ * marked as temporary for safety.
190
126
  *
191
- * @param {string} filename - The filename to append
192
- * @returns {FileObject} A new FileObject with the extended path
193
- * @throws {Sass} If the path would escape the temp directory
194
- * @throws {Sass} If the path is absolute
195
- * @throws {Sass} If the path contains traversal (..)
127
+ * @async
128
+ * @returns {Promise<void>}
129
+ * @throws {Sass} If the directory is not marked as temporary
130
+ * @throws {Sass} If the directory deletion fails
196
131
  * @example
197
- * const temp = new TempDirectoryObject("myapp")
198
- * const file = temp.getFile("config.json")
199
- * console.log(file.path) // "/tmp/myapp-ABC123/config.json"
132
+ * const tempDir = new TempDirectoryObject("my-temp")
133
+ * await tempDir.assureExists()
134
+ * // ... use the directory ...
135
+ * await tempDir.remove() // Recursively deletes everything
200
136
  */
201
- getFile(filename) {
202
- // Delegate to base class getFile() which handles security checks
203
- return super.getFile(filename)
137
+ async remove() {
138
+ await this.#recurseDelete(this.real)
139
+ }
140
+
141
+ async #recurseDelete(directory) {
142
+ const {files, directories} = await directory.read()
143
+
144
+ // files first
145
+ for(const file of files)
146
+ await file.delete()
147
+
148
+ // now dir-ty dirs
149
+ for(const dir of directories)
150
+ await this.#recurseDelete(dir)
151
+
152
+ // byebyebyeeee 🕺🏾
153
+ await directory.delete()
204
154
  }
205
155
 
206
156
  /**
207
- * Returns a string representation of the TempDirectoryObject.
157
+ * TempDirectoryObject does not support fromCwd() since it is specifically
158
+ * designed to work within the OS temporary directory tree.
208
159
  *
209
- * @returns {string} string representation of the TempDirectoryObject
160
+ * @throws {Sass} Always throws an error
210
161
  */
211
- toString() {
212
- return `[TempDirectoryObject: ${this.path}]`
162
+ static fromCwd() {
163
+ throw Sass.new("TempDirectoryObject.fromCwd() is not supported.")
213
164
  }
214
165
  }
package/src/lib/Valid.js CHANGED
@@ -25,7 +25,7 @@ export default class Valid {
25
25
  static type(value, type, options) {
26
26
  Valid.assert(
27
27
  Data.isType(value, type, options),
28
- `Invalid type. Expected ${type}, got ${JSON.stringify(value)}`,
28
+ `Invalid type. Expected ${type}, got ${Data.typeOf(value)}`,
29
29
  1,
30
30
  )
31
31
  }
@@ -36,7 +36,7 @@ export default class Data {
36
36
  * @param {string} append - The string to append
37
37
  * @returns {string} The appended string
38
38
  */
39
- static appendString(string: string, append: string): string;
39
+ static append(string: string, append: string): string;
40
40
  /**
41
41
  * Prepends a string to another string if it does not already start with it.
42
42
  *
@@ -44,7 +44,51 @@ export default class Data {
44
44
  * @param {string} prepend - The string to prepend
45
45
  * @returns {string} The prepended string
46
46
  */
47
- static prependString(string: string, prepend: string): string;
47
+ static prepend(string: string, prepend: string): string;
48
+ /**
49
+ * Remove a suffix from the end of a string if present.
50
+ *
51
+ * @param {string} string - The string to process
52
+ * @param {string} toChop - The suffix to remove from the end
53
+ * @param {boolean} [caseInsensitive=false] - Whether to perform case-insensitive matching
54
+ * @returns {string} The string with suffix removed, or original if suffix not found
55
+ * @example
56
+ * Data.chopRight("hello.txt", ".txt") // "hello"
57
+ * Data.chopRight("Hello", "o") // "Hell"
58
+ * Data.chopRight("HELLO", "lo", true) // "HEL"
59
+ */
60
+ static chopRight(string: string, toChop: string, caseInsensitive?: boolean): string;
61
+ /**
62
+ * Remove a prefix from the beginning of a string if present.
63
+ *
64
+ * @param {string} string - The string to process
65
+ * @param {string} toChop - The prefix to remove from the beginning
66
+ * @param {boolean} [caseInsensitive=false] - Whether to perform case-insensitive matching
67
+ * @returns {string} The string with prefix removed, or original if prefix not found
68
+ * @example
69
+ * Data.chopLeft("hello.txt", "hello") // ".txt"
70
+ * Data.chopLeft("Hello", "H") // "ello"
71
+ * Data.chopLeft("HELLO", "he", true) // "LLO"
72
+ */
73
+ static chopLeft(string: string, toChop: string, caseInsensitive?: boolean): string;
74
+ /**
75
+ * Chop a string after the first occurence of another string.
76
+ *
77
+ * @param {string} string - The string to search
78
+ * @param {string} needle - The bit to chop after
79
+ * @param {boolean} caseInsensitive - Whether to search insensitive to case
80
+ * @returns {string} The remaining string
81
+ */
82
+ static chopAfter(string: string, needle: string, caseInsensitive?: boolean): string;
83
+ /**
84
+ * Chop a string before the first occurrence of another string.
85
+ *
86
+ * @param {string} string - The string to search
87
+ * @param {string} needle - The bit to chop before
88
+ * @param {boolean} caseInsensitive - Whether to search insensitive to case
89
+ * @returns {string} The remaining string
90
+ */
91
+ static chopBefore(string: string, needle: string, caseInsensitive?: boolean): string;
48
92
  /**
49
93
  * Creates a type spec from a string. A type spec is an array of objects
50
94
  * defining the type of a value and whether an array is expected.
@@ -1 +1 @@
1
- {"version":3,"file":"Data.d.ts","sourceRoot":"","sources":["../../../browser/lib/Data.js"],"names":[],"mappings":"AAUA;IACA;;;;;OAKG;IACD,mBAFQ,KAAK,CAAC,MAAM,CAAC,CAgBnB;IAEF;;;;;OAKG;IACH,qBAFU,KAAK,CAAC,MAAM,CAAC,CAmBrB;IAEF;;;;;;;OAOG;IACH,kBAFU,KAAK,CAAC,MAAM,CAAC,CAKrB;IAEF;;;;;OAKG;IACH,uBAFU,KAAK,CAAC,MAAM,CAAC,CAE6C;IAEpE;;;;;;OAMG;IACH,4BAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;OAMG;IACH,6BAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;OAOG;IACH,2BAJW,MAAM,WACN,MAAM,GACJ,KAAK,CAAC,MAAM,CAAC,CAIzB;IAED;;;;;;;OAOG;IACH,qBALW,OAAO,QACP,MAAM,GAAC,QAAQ,YACf,MAAM,GACJ,OAAO,CAQnB;IAED;;;;;OAKG;IACH,yBAHW,MAAM,GACJ,OAAO,CASnB;IAED;;;;;;;;OAQG;IACH,yBAJW,OAAO,QACP,MAAM,GACJ,OAAO,CAwBnB;IAED;;;;;OAKG;IACH,qBAHW,OAAO,GACL,MAAM,CAclB;IAED;;;;;OAKG;IACH,wBAHW,OAAO,GACL,OAAO,CAInB;IAED;;;;;;;;OAQG;IACH,sBALW,OAAO,oBACP,OAAO,GAEL,OAAO,CA2BnB;IAED;;;;;OAKG;IACH,6BAHW,MAAM,GACJ,MAAM,CAmBlB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,GACX,MAAM,CAiBlB;IAED;;;;;;;OAOG;IACH,2BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,SACb,OAAO,QAMjB;IAED;;;;;OAKG;IACH,+BAHc,MAAM,EAAA,GACP,MAAM,CAqBlB;IAED;;;;;;;OAOG;IACH,wBAJW,KAAK,CAAC,OAAO,CAAC,aACd,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAClC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAMnC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;OAOG;IACH,oBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,4BAbW,OAAO,GACL,OAAO,CA+BnB;IAED;;;;;;;;;;;;;;;OAeG;IACH,uBAXW,OAAO,GACL,OAAO,CAgBnB;CACF;qBA5aoB,eAAe"}
1
+ {"version":3,"file":"Data.d.ts","sourceRoot":"","sources":["../../../browser/lib/Data.js"],"names":[],"mappings":"AAUA;IACA;;;;;OAKG;IACD,mBAFQ,KAAK,CAAC,MAAM,CAAC,CAgBnB;IAEF;;;;;OAKG;IACH,qBAFU,KAAK,CAAC,MAAM,CAAC,CAmBrB;IAEF;;;;;;;OAOG;IACH,kBAFU,KAAK,CAAC,MAAM,CAAC,CAKrB;IAEF;;;;;OAKG;IACH,uBAFU,KAAK,CAAC,MAAM,CAAC,CAE2D;IAElF;;;;;;OAMG;IACH,sBAJW,MAAM,UACN,MAAM,GACJ,MAAM,CAMlB;IAED;;;;;;OAMG;IACH,uBAJW,MAAM,WACN,MAAM,GACJ,MAAM,CAMlB;IAED;;;;;;;;;;;OAWG;IACH,yBATW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;;;;;OAWG;IACH,wBATW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;OAOG;IACH,yBALW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAWlB;IAED;;;;;;;OAOG;IACH,0BALW,MAAM,UACN,MAAM,oBACN,OAAO,GACL,MAAM,CAYlB;IAED;;;;;;;OAOG;IACH,2BAJW,MAAM,WACN,MAAM,GACJ,KAAK,CAAC,MAAM,CAAC,CAIzB;IAED;;;;;;;OAOG;IACH,qBALW,OAAO,QACP,MAAM,GAAC,QAAQ,YACf,MAAM,GACJ,OAAO,CAQnB;IAED;;;;;OAKG;IACH,yBAHW,MAAM,GACJ,OAAO,CASnB;IAED;;;;;;;;OAQG;IACH,yBAJW,OAAO,QACP,MAAM,GACJ,OAAO,CAwBnB;IAED;;;;;OAKG;IACH,qBAHW,OAAO,GACL,MAAM,CAclB;IAED;;;;;OAKG;IACH,wBAHW,OAAO,GACL,OAAO,CAInB;IAED;;;;;;;;OAQG;IACH,sBALW,OAAO,oBACP,OAAO,GAEL,OAAO,CA8BnB;IAED;;;;;OAKG;IACH,6BAHW,MAAM,GACJ,MAAM,CAmBlB;IAED;;;;;;;OAOG;IACH,6BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,GACX,MAAM,CAiBlB;IAED;;;;;;;OAOG;IACH,2BAJW,MAAM,QACN,KAAK,CAAC,MAAM,CAAC,SACb,OAAO,QAMjB;IAED;;;;;OAKG;IACH,+BAHc,MAAM,EAAA,GACP,MAAM,CAqBlB;IAED;;;;;;;OAOG;IACH,wBAJW,KAAK,CAAC,OAAO,CAAC,aACd,CAAC,KAAK,EAAE,OAAO,KAAK,OAAO,CAAC,OAAO,CAAC,GAClC,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAMnC;IAED;;;;;;;OAOG;IACH,kBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,MAAM,CAIlB;IAED;;;;;;;OAOG;IACH,oBALW,MAAM,OACN,MAAM,OACN,MAAM,GACJ,OAAO,CAInB;IAED;;;;;;;;;;;;;;;;;;;OAmBG;IACH,4BAbW,OAAO,GACL,OAAO,CA+BnB;IAED;;;;;;;;;;;;;;;OAeG;IACH,uBAXW,OAAO,GACL,OAAO,CAgBnB;CACF;qBAhgBoB,eAAe"}
@@ -1 +1 @@
1
- {"version":3,"file":"TypeSpec.d.ts","sourceRoot":"","sources":["../../../browser/lib/TypeSpec.js"],"names":[],"mappings":"AAWA;;;GAGG;AACH;IAGE;;;;;OAKG;IACH,oBAHW,MAAM,WACN,OAAO,EAUjB;IAJC,aAAwB;IACxB,eAAgC;IAChC,6BAA2C;IAI7C;;;;OAIG;IACH,YAFa,MAAM,CAQlB;IAED;;;;OAIG;IACH,UAFa,OAAO,CASnB;IAED;;;;OAIG;IACH,kBAFW,CAAS,IAAO,EAAP,OAAO,KAAG,IAAI,QAIjC;IAED;;;;;OAKG;IACH,gBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,iBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;OAKG;IACH,cAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;;OAMG;IACH,iBAJW,CAAS,IAAO,EAAP,OAAO,EAAE,IAAO,EAAP,OAAO,KAAG,OAAO,gBACnC,OAAO,GACL,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,MAAM,GAAC,SAAS,CAI5B;IAED;;;;;;;;OAQG;IACH,eALW,OAAO,WACP,OAAO,GAEL,OAAO,CAInB;IAED,2CA2DC;;CAmDF"}
1
+ {"version":3,"file":"TypeSpec.d.ts","sourceRoot":"","sources":["../../../browser/lib/TypeSpec.js"],"names":[],"mappings":"AAWA;;;GAGG;AACH;IAGE;;;;;OAKG;IACH,oBAHW,MAAM,WACN,OAAO,EAUjB;IAJC,aAAwB;IACxB,eAAgC;IAChC,6BAA2C;IAI7C;;;;OAIG;IACH,YAFa,MAAM,CAQlB;IAED;;;;OAIG;IACH,UAFa,OAAO,CASnB;IAED;;;;OAIG;IACH,kBAFW,CAAS,IAAO,EAAP,OAAO,KAAG,IAAI,QAIjC;IAED;;;;;OAKG;IACH,gBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,OAAO,CAInB;IAED;;;;;OAKG;IACH,iBAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;OAKG;IACH,cAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,KAAK,CAAC,OAAO,CAAC,CAI1B;IAED;;;;;;OAMG;IACH,iBAJW,CAAS,IAAO,EAAP,OAAO,EAAE,IAAO,EAAP,OAAO,KAAG,OAAO,gBACnC,OAAO,GACL,OAAO,CAInB;IAED;;;;;OAKG;IACH,eAHW,CAAS,IAAO,EAAP,OAAO,KAAG,OAAO,GACxB,MAAM,GAAC,SAAS,CAI5B;IAED;;;;;;;;OAQG;IACH,eALW,OAAO,WACP,OAAO,GAEL,OAAO,CAInB;IAED,2CA6DC;;CAmDF"}
@@ -28,9 +28,8 @@ export default class CappedDirectoryObject extends DirectoryObject {
28
28
  * (virtual root). With a parent, the path is resolved relative to the parent's
29
29
  * cap using virtual path semantics (absolute paths treated as cap-relative).
30
30
  *
31
- * @param {string} [dirPath="."] - Directory path (becomes cap if no parent, else relative to parent's cap, defaults to current directory)
31
+ * @param {string} [directory="."] - Directory path (becomes cap if no parent, else relative to parent's cap, defaults to current directory)
32
32
  * @param {CappedDirectoryObject?} [parent] - Optional parent capped directory
33
- * @param {boolean} [temporary=false] - Whether this is a temporary directory
34
33
  * @throws {Sass} If parent is provided but not a CappedDirectoryObject
35
34
  * @throws {Sass} If the resulting path would escape the cap
36
35
  * @example
@@ -53,33 +52,34 @@ export default class CappedDirectoryObject extends DirectoryObject {
53
52
  * const config = new CappedDirectoryObject("/etc/config", cache)
54
53
  * // path: /home/user/.cache/etc/config, cap: /home/user/.cache
55
54
  */
56
- constructor(dirPath?: string, parent?: CappedDirectoryObject | null, temporary?: boolean);
55
+ constructor(directory?: string, source?: any);
57
56
  /**
58
- * Re-caps this directory to itself, making it the new root of the capped tree.
59
- * This is a protected method intended for use by subclasses like TempDirectoryObject.
57
+ * Indicates whether this directory is capped (constrained to a specific tree).
58
+ * Always returns true for CappedDirectoryObject instances.
60
59
  *
61
- * @protected
62
- */
63
- protected _recapToSelf(): void;
64
- /**
65
- * Returns the cap path for this directory.
60
+ * @returns {boolean} True for all CappedDirectoryObject instances
61
+ * @example
62
+ * const capped = new TempDirectoryObject("myapp")
63
+ * console.log(capped.isCapped) // true
66
64
  *
67
- * @returns {string} The cap directory path
65
+ * const regular = new DirectoryObject("/tmp")
66
+ * console.log(regular.isCapped) // false
68
67
  */
69
- get cap(): string;
68
+ get isCapped(): boolean;
70
69
  /**
71
- * Returns whether this directory is capped.
70
+ * Returns the cap (root) of the capped directory tree.
71
+ * For root CappedDirectoryObject instances, returns itself.
72
+ * For children, returns the inherited cap from the parent chain.
72
73
  *
73
- * @returns {boolean} Always true for CappedDirectoryObject instances
74
- */
75
- get capped(): boolean;
76
- /**
77
- * Returns the real filesystem path (for internal and subclass use).
74
+ * @returns {CappedDirectoryObject} The cap directory object (root of the capped tree)
75
+ * @example
76
+ * const temp = new TempDirectoryObject("myapp")
77
+ * console.log(temp.cap === temp) // true (root is its own cap)
78
78
  *
79
- * @protected
80
- * @returns {string} The actual filesystem path
79
+ * const subdir = temp.getDirectory("data")
80
+ * console.log(subdir.cap === temp) // true (child inherits parent's cap)
81
81
  */
82
- protected get realPath(): string;
82
+ get cap(): CappedDirectoryObject;
83
83
  /**
84
84
  * Returns a plain DirectoryObject representing the actual filesystem location.
85
85
  * This provides an "escape hatch" from the capped environment to interact
@@ -115,50 +115,25 @@ export default class CappedDirectoryObject extends DirectoryObject {
115
115
  */
116
116
  get parent(): CappedDirectoryObject | null;
117
117
  /**
118
- * Returns the URL with virtual path (cap-relative).
119
- *
120
- * @returns {URL} Virtual URL
121
- */
122
- get url(): URL;
123
- /**
124
- * Returns a generator that walks up to the cap.
125
- *
126
- * @returns {Generator<DirectoryObject>} Generator yielding parent directories
127
- */
128
- get walkUp(): Generator<DirectoryObject>;
129
- /**
130
- * Creates a new CappedDirectoryObject by extending this directory's path.
131
- *
132
- * All paths are coerced to remain within the cap directory tree:
133
- * - Absolute paths (e.g., "/foo") are treated as relative to the cap
134
- * - Parent traversal ("..") is allowed but clamped at the cap boundary
135
- * - The cap acts as the virtual root directory
118
+ * Returns the path of the parent directory.
119
+ * Returns null if this directory is at the cap root (no parent).
136
120
  *
137
- * @param {string} newPath - The path to resolve (can be absolute or contain ..)
138
- * @returns {CappedDirectoryObject} A new CappedDirectoryObject with the coerced path
121
+ * @returns {string|null} The parent directory path, or null if at cap root
139
122
  * @example
140
- * const capped = new TempDirectoryObject("myapp")
141
- * const subDir = capped.getDirectory("data")
142
- * console.log(subDir.path) // "/tmp/myapp-ABC123/data"
143
- *
144
- * @example
145
- * // Absolute paths are relative to cap
146
- * const abs = capped.getDirectory("/foo/bar")
147
- * console.log(abs.path) // "/tmp/myapp-ABC123/foo/bar"
123
+ * const temp = new TempDirectoryObject("myapp")
124
+ * console.log(temp.parentPath) // null (at cap root)
148
125
  *
149
- * @example
150
- * // Excessive .. traversal clamps to cap
151
- * const up = capped.getDirectory("../../../etc/passwd")
152
- * console.log(up.path) // "/tmp/myapp-ABC123" (clamped to cap)
126
+ * const subdir = temp.getDirectory("data")
127
+ * console.log(subdir.parentPath) // "/data" or similar (parent's virtual path)
153
128
  */
154
- getDirectory(newPath: string): CappedDirectoryObject;
129
+ get parentPath(): string | null;
155
130
  /**
156
131
  * Override read to use real filesystem path and return capped objects.
157
132
  *
158
133
  * @param {string} [pat=""] - Optional glob pattern
159
134
  * @returns {Promise<{files: Array<FileObject>, directories: Array}>} Directory contents
160
135
  */
161
- read(pat?: string): Promise<{
136
+ read(...arg: any[]): Promise<{
162
137
  files: Array<FileObject>;
163
138
  directories: any[];
164
139
  }>;
@@ -1 +1 @@
1
- {"version":3,"file":"CappedDirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/CappedDirectoryObject.js"],"names":[],"mappings":"AAkBA;;;;;;;;GAQG;AACH;IA2FE;;;;;;;;;;;OAWG;IACH,kBAPa,qBAAqB,CASjC;IAtGD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA+BG;IACH,sBAzBW,MAAM,WACN,qBAAqB,OAAC,cACtB,OAAO,EA6EjB;IAqCD;;;;;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;4BArpB2B,sBAAsB;uBAC3B,iBAAiB"}
1
+ {"version":3,"file":"CappedDirectoryObject.d.ts","sourceRoot":"","sources":["../../lib/CappedDirectoryObject.js"],"names":[],"mappings":"AAiBA;;;;;;;;GAQG;AACH;IAoEE;;;;;;;;;;;OAWG;IACH,kBAPa,qBAAqB,CASjC;IA5ED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,wBAxBW,MAAM,gBAqDhB;IAkBD;;;;;;;;;;;OAWG;IACH,gBARa,OAAO,CAUnB;IAED;;;;;;;;;;;;OAYG;IACH,WARa,qBAAqB,CAUjC;IAED;;;;;;;;;;;;;;;;;OAiBG;IACH,YAba,eAAe,CAe3B;IAED;;;;;;;;;;;;;OAaG;IACH,cAPa,qBAAqB,GAAC,IAAI,CAStC;IAED;;;;;;;;;;;OAWG;IACH,kBARa,MAAM,GAAC,IAAI,CAUvB;IAkCD;;;;;OAKG;IACH,qBAFa,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,WAAW,QAAO;KAAC,CAAC,CAUnE;;CA8BF;4BAvQ2B,sBAAsB;uBAC3B,iBAAiB"}