@gesslar/toolkit 5.2.0 → 5.3.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 CHANGED
@@ -5,7 +5,7 @@
5
5
  "name": "gesslar",
6
6
  "url": "https://gesslar.dev"
7
7
  },
8
- "version": "5.2.0",
8
+ "version": "5.3.0",
9
9
  "license": "0BSD",
10
10
  "homepage": "https://github.com/gesslar/toolkit#readme",
11
11
  "repository": {
@@ -89,17 +89,15 @@ export default class Sass extends Error {
89
89
  )
90
90
  }
91
91
 
92
- if(this.cause) {
92
+ if(this.cause && nerdMode) {
93
93
  if(typeof this.cause.report === "function") {
94
- if(nerdMode) {
95
- console.error(
96
- "\n" +
97
- `[error] Caused By`
98
- )
99
- }
94
+ console.error(
95
+ "\n" +
96
+ `[error] Caused By`
97
+ )
100
98
 
101
99
  this.cause.report(nerdMode, true)
102
- } else if(nerdMode && this.cause.stack) {
100
+ } else if(this.cause.stack) {
103
101
  console.error()
104
102
  console.group()
105
103
  console.error(
@@ -4,7 +4,7 @@
4
4
  * resolution and existence checks.
5
5
  */
6
6
 
7
- import {glob, mkdir, readdir, rmdir, stat} from "node:fs/promises"
7
+ import {glob, lstat, mkdir, readdir, rmdir, stat} from "node:fs/promises"
8
8
  import path, {relative} from "node:path"
9
9
  import {URL} from "node:url"
10
10
  import {inspect} from "node:util"
@@ -59,6 +59,7 @@ import Valid from "./Valid.js"
59
59
  * @property {boolean} isDirectory - Always true
60
60
  * @property {DirectoryObject|null} parent - The parent directory (null if root)
61
61
  * @property {Promise<boolean>} exists - Whether the directory exists (async getter)
62
+ * @property {Promise<("none"|"symbolic"|null)>} linkType - The link kind at this path (async)
62
63
  *
63
64
  * @example
64
65
  * // Basic usage
@@ -225,6 +226,28 @@ export default class DirectoryObject extends FS {
225
226
  return this.#directoryExists()
226
227
  }
227
228
 
229
+ /**
230
+ * Reports the link kind at this path. Reads the filesystem on every
231
+ * access, like {@link DirectoryObject#exists}, and throws under the
232
+ * same conditions: if the path exists but is not a directory (broken
233
+ * symlink, symlink to a non-directory, or a regular file), this throws
234
+ * a {@link Sass} error rather than returning a misleading value.
235
+ *
236
+ * - `"symbolic"` - a symlink whose target is a directory that exists
237
+ * - `"none"` - a regular directory
238
+ * - `null` - the path does not exist at all
239
+ *
240
+ * Hard links are not reported for directories: most filesystems do not
241
+ * allow hard-linked directories at all, and `nlink` on a directory is
242
+ * not a usable signal (it counts `.` and each subdirectory's `..`).
243
+ *
244
+ * @returns {Promise<"none"|"symbolic"|null>} The link kind
245
+ * @throws {Sass} If the path exists but does not resolve to a directory
246
+ */
247
+ get linkType() {
248
+ return this.#directoryLinkType()
249
+ }
250
+
228
251
  /**
229
252
  * Return the path as passed to the constructor.
230
253
  *
@@ -363,13 +386,47 @@ export default class DirectoryObject extends FS {
363
386
  }
364
387
  }
365
388
 
389
+ /**
390
+ * Resolves the link kind at this path.
391
+ *
392
+ * @private
393
+ * @returns {Promise<"none"|"symbolic"|null>} The link kind
394
+ */
395
+ async #directoryLinkType() {
396
+ try {
397
+ const linkStats = await lstat(this.path).catch(error => error.code === "ENOENT" ? null : error)
398
+
399
+ if(linkStats instanceof Error)
400
+ throw linkStats
401
+
402
+ if(linkStats === null)
403
+ return null
404
+
405
+ if(linkStats.isSymbolicLink()) {
406
+ const targetStats = await stat(this.path)
407
+
408
+ if(!targetStats.isDirectory())
409
+ throw Sass.new(`Path exists but is not a directory: '${this.path}'`)
410
+
411
+ return "symbolic"
412
+ }
413
+
414
+ if(!linkStats.isDirectory())
415
+ throw Sass.new(`Path exists but is not a directory: '${this.path}'`)
416
+
417
+ return "none"
418
+ } catch(error) {
419
+ throw Sass.new(`Determining link type of '${this.path}'`, error)
420
+ }
421
+ }
422
+
366
423
  /**
367
424
  * Lists the contents of a directory, optionally filtered by a glob pattern.
368
425
  *
369
426
  * Returns FileObject and DirectoryObject instances. Symbolic links are
370
427
  * resolved to their target type: links to files appear in `files`, links
371
- * to directories appear in `directories`. Broken symlinks propagate the
372
- * stat error to the caller.
428
+ * to directories appear in `directories`. Broken symlinks (where the
429
+ * target does not exist) appear in `files` so they can be unlinked.
373
430
  *
374
431
  * @async
375
432
  * @param {string} [pat=""] - Optional glob pattern to filter results (e.g., "*.txt", "test-*")
@@ -415,8 +472,8 @@ export default class DirectoryObject extends FS {
415
472
  *
416
473
  * Returns FileObject and DirectoryObject instances. Symbolic links are
417
474
  * resolved to their target type: links to files appear in `files`, links
418
- * to directories appear in `directories`. Broken symlinks propagate the
419
- * stat error to the caller.
475
+ * to directories appear in `directories`. Broken symlinks (where the
476
+ * target does not exist) appear in `files` so they can be unlinked.
420
477
  *
421
478
  * @async
422
479
  * @param {string} [pat=""] - Glob pattern to filter results
@@ -451,7 +508,8 @@ export default class DirectoryObject extends FS {
451
508
  /**
452
509
  * Categorizes an array of Dirent objects into files and directories.
453
510
  * Resolves symbolic links to their target type via `fs.stat()`. Broken
454
- * symlinks propagate the stat error to the caller.
511
+ * symlinks (where the target does not exist) are categorized as files
512
+ * so they can be unlinked.
455
513
  *
456
514
  * @private
457
515
  * @param {Array<import("node:fs").Dirent>} dirents - Directory entries to categorize
@@ -471,12 +529,19 @@ export default class DirectoryObject extends FS {
471
529
  } else if(dirent.isDirectory()) {
472
530
  result.directories.push(new this.constructor(fullPath))
473
531
  } else if(dirent.isSymbolicLink()) {
474
- const stats = await stat(fullPath)
475
-
476
- if(stats.isFile())
477
- result.files.push(new FileObject(fullPath, this))
478
- else if(stats.isDirectory())
479
- result.directories.push(new this.constructor(fullPath))
532
+ try {
533
+ const stats = await stat(fullPath)
534
+
535
+ if(stats.isFile())
536
+ result.files.push(new FileObject(fullPath, this))
537
+ else if(stats.isDirectory())
538
+ result.directories.push(new this.constructor(fullPath))
539
+ } catch(error) {
540
+ if(error.code === "ENOENT")
541
+ result.files.push(new FileObject(fullPath, this))
542
+ else
543
+ throw error
544
+ }
480
545
  }
481
546
  }
482
547
 
@@ -29,6 +29,7 @@ import Valid from "./Valid.js"
29
29
  * @property {boolean} isFile - Always true for files
30
30
  * @property {DirectoryObject} parent - The parent directory object
31
31
  * @property {Promise<boolean>} exists - Whether the file exists (async)
32
+ * @property {Promise<("none"|"symbolic"|"broken"|"hard"|null)>} linkType - The link kind at this path (async)
32
33
  */
33
34
 
34
35
  export default class FileObject extends FS {
@@ -200,6 +201,24 @@ export default class FileObject extends FS {
200
201
  return this.#fileExists()
201
202
  }
202
203
 
204
+ /**
205
+ * Reports the link kind at this path. Reads the filesystem on every
206
+ * access, like {@link FileObject#exists}.
207
+ *
208
+ * - `"symbolic"` - a symlink whose target exists
209
+ * - `"broken"` - a symlink whose target does not exist
210
+ * - `"hard"` - a regular file with additional hard links (`nlink > 1`).
211
+ * Hard links are inode-level and indistinguishable from each other,
212
+ * so this only reports that *some* other entry shares the inode.
213
+ * - `"none"` - a regular file with no links
214
+ * - `null` - the path does not exist
215
+ *
216
+ * @returns {Promise<"none"|"symbolic"|"broken"|"hard"|null>} The link kind
217
+ */
218
+ get linkType() {
219
+ return this.#fileLinkType()
220
+ }
221
+
203
222
  /**
204
223
  * Return the normalized path that was provided to the constructor.
205
224
  *
@@ -328,7 +347,7 @@ export default class FileObject extends FS {
328
347
  */
329
348
  async #fileExists() {
330
349
  try {
331
- const stats = await fs.stat(this.path).catch(error => error.code === "ENOENT" ? null : error)
350
+ const stats = await fs.lstat(this.path).catch(error => error.code === "ENOENT" ? null : error)
332
351
 
333
352
  if(stats instanceof Error)
334
353
  throw stats
@@ -336,7 +355,7 @@ export default class FileObject extends FS {
336
355
  if(stats === null)
337
356
  return false
338
357
 
339
- if(!stats.isFile())
358
+ if(!stats.isFile() && !stats.isSymbolicLink())
340
359
  throw Sass.new(`Path exists but is not a file: '${this.path}'`)
341
360
 
342
361
  return true
@@ -345,6 +364,47 @@ export default class FileObject extends FS {
345
364
  }
346
365
  }
347
366
 
367
+ /**
368
+ * Resolves the link kind at this path.
369
+ *
370
+ * @private
371
+ * @returns {Promise<"none"|"symbolic"|"broken"|"hard"|null>} The link kind
372
+ */
373
+ async #fileLinkType() {
374
+ try {
375
+ const stats = await fs.lstat(this.path).catch(error => error.code === "ENOENT" ? null : error)
376
+
377
+ if(stats instanceof Error)
378
+ throw stats
379
+
380
+ if(stats === null)
381
+ return null
382
+
383
+ if(stats.isSymbolicLink()) {
384
+ try {
385
+ await fs.stat(this.path)
386
+
387
+ return "symbolic"
388
+ } catch(error) {
389
+ if(error.code === "ENOENT")
390
+ return "broken"
391
+
392
+ throw error
393
+ }
394
+ }
395
+
396
+ if(!stats.isFile())
397
+ throw Sass.new(`Path exists but is not a file: '${this.path}'`)
398
+
399
+ if(stats.nlink > 1)
400
+ return "hard"
401
+
402
+ return "none"
403
+ } catch(error) {
404
+ throw Sass.new(`Determining link type of '${this.path}'`, error)
405
+ }
406
+ }
407
+
348
408
  /**
349
409
  * Determines the size of a file.
350
410
  *
@@ -40,17 +40,15 @@ export default class Sass extends BrowserSass {
40
40
  )
41
41
  }
42
42
 
43
- if(this.cause) {
43
+ if(this.cause && nerdMode) {
44
44
  if(typeof this.cause.report === "function") {
45
- if(nerdMode) {
46
- Term.error(
47
- "\n" +
48
- `${Term.terminalBracket(["error", "Caused By"])}`
49
- )
50
- }
45
+ Term.error(
46
+ "\n" +
47
+ `${Term.terminalBracket(["error", "Caused By"])}`
48
+ )
51
49
 
52
50
  this.cause.report(nerdMode, true)
53
- } else if(nerdMode && this.cause.stack) {
51
+ } else if(this.cause.stack) {
54
52
  Term.error()
55
53
  Term.group()
56
54
  Term.error(
@@ -1 +1 @@
1
- {"version":3,"file":"Sass.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/Sass.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH;IAgIE;;;;;;;;OAQG;IACH,mBALW,KAAK,WACL,MAAM,GACJ,IAAI,CAahB;IAED;;;;;;;;OAQG;IACH,sBAJW,MAAM,UACN,KAAK,GAAC,IAAI,GAAC,OAAO,GAChB,IAAI,CAchB;IAvKD;;;;;OAKG;IACH,qBAHW,MAAM,WACH,OAAO,EAAA,EAMpB;IAWD;;;;OAIG;IACH,mBAFW,MAAM,EAIhB;IAhBD;;;;OAIG;IACH,aAFa,KAAK,CAAC,MAAM,CAAC,CAIzB;IAWD;;;;;OAKG;IACH,kBAHW,MAAM,GACJ,IAAI,CAShB;IAED;;;;;;OAMG;IACH,kBAHW,OAAO,aACP,OAAO,QAyCjB;;CA6EF;oBAjLmB,cAAc"}
1
+ {"version":3,"file":"Sass.d.ts","sourceRoot":"","sources":["../../../src/browser/lib/Sass.js"],"names":[],"mappings":"AAeA;;;GAGG;AACH;IA8HE;;;;;;;;OAQG;IACH,mBALW,KAAK,WACL,MAAM,GACJ,IAAI,CAahB;IAED;;;;;;;;OAQG;IACH,sBAJW,MAAM,UACN,KAAK,GAAC,IAAI,GAAC,OAAO,GAChB,IAAI,CAchB;IArKD;;;;;OAKG;IACH,qBAHW,MAAM,WACH,OAAO,EAAA,EAMpB;IAWD;;;;OAIG;IACH,mBAFW,MAAM,EAIhB;IAhBD;;;;OAIG;IACH,aAFa,KAAK,CAAC,MAAM,CAAC,CAIzB;IAWD;;;;;OAKG;IACH,kBAHW,MAAM,GACJ,IAAI,CAShB;IAED;;;;;;OAMG;IACH,kBAHW,OAAO,aACP,OAAO,QAuCjB;;CA6EF;oBA/KmB,cAAc"}
@@ -40,6 +40,7 @@
40
40
  * @property {boolean} isDirectory - Always true
41
41
  * @property {DirectoryObject|null} parent - The parent directory (null if root)
42
42
  * @property {Promise<boolean>} exists - Whether the directory exists (async getter)
43
+ * @property {Promise<("none"|"symbolic"|null)>} linkType - The link kind at this path (async)
43
44
  *
44
45
  * @example
45
46
  * // Basic usage
@@ -100,6 +101,25 @@ export default class DirectoryObject extends FS {
100
101
  * @returns {Promise<boolean>} - A Promise that resolves to true or false
101
102
  */
102
103
  get exists(): Promise<boolean>;
104
+ /**
105
+ * Reports the link kind at this path. Reads the filesystem on every
106
+ * access, like {@link DirectoryObject#exists}, and throws under the
107
+ * same conditions: if the path exists but is not a directory (broken
108
+ * symlink, symlink to a non-directory, or a regular file), this throws
109
+ * a {@link Sass} error rather than returning a misleading value.
110
+ *
111
+ * - `"symbolic"` - a symlink whose target is a directory that exists
112
+ * - `"none"` - a regular directory
113
+ * - `null` - the path does not exist at all
114
+ *
115
+ * Hard links are not reported for directories: most filesystems do not
116
+ * allow hard-linked directories at all, and `nlink` on a directory is
117
+ * not a usable signal (it counts `.` and each subdirectory's `..`).
118
+ *
119
+ * @returns {Promise<"none"|"symbolic"|null>} The link kind
120
+ * @throws {Sass} If the path exists but does not resolve to a directory
121
+ */
122
+ get linkType(): Promise<"none" | "symbolic" | null>;
103
123
  /**
104
124
  * Return the path as passed to the constructor.
105
125
  *
@@ -176,8 +196,8 @@ export default class DirectoryObject extends FS {
176
196
  *
177
197
  * Returns FileObject and DirectoryObject instances. Symbolic links are
178
198
  * resolved to their target type: links to files appear in `files`, links
179
- * to directories appear in `directories`. Broken symlinks propagate the
180
- * stat error to the caller.
199
+ * to directories appear in `directories`. Broken symlinks (where the
200
+ * target does not exist) appear in `files` so they can be unlinked.
181
201
  *
182
202
  * @async
183
203
  * @param {string} [pat=""] - Optional glob pattern to filter results (e.g., "*.txt", "test-*")
@@ -202,8 +222,8 @@ export default class DirectoryObject extends FS {
202
222
  *
203
223
  * Returns FileObject and DirectoryObject instances. Symbolic links are
204
224
  * resolved to their target type: links to files appear in `files`, links
205
- * to directories appear in `directories`. Broken symlinks propagate the
206
- * stat error to the caller.
225
+ * to directories appear in `directories`. Broken symlinks (where the
226
+ * target does not exist) appear in `files` so they can be unlinked.
207
227
  *
208
228
  * @async
209
229
  * @param {string} [pat=""] - Glob pattern to filter results
@@ -1 +1 @@
1
- {"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/DirectoryObject.js"],"names":[],"mappings":"AAiBA;;;;GAIG;AAEH;;;;;;;;;;;;;;GAcG;AAEH;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AACH;yBAoGa,MAAM,WACN,MAAM,oBAEJ,MAAM;IAhDnB;;;;;;;;;OASG;IACH,kBALa,eAAe,CAO3B;IA7CD;;;;OAIG;IACH,uBAFW,MAAM,OAAC,EA4BjB;IAyBD;;;;OAIG;IACH,UAFa,MAAM,CAclB;IA8BD;;;;OAIG;IACH,WAFa,MAAM,CAIlB;IAED;;;;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;IA2BD;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,WAZW,MAAM,iBACJ,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;KAAC,CAAC,CAkCpF;IAED;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,WAXW,MAAM,iBACJ,OAAO,CAAC;QAAC,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,CAAC;QAAC,WAAW,EAAE,KAAK,CAAC,eAAe,CAAC,CAAA;KAAC,CAAC,CA0BpF;IAqCD;;;;;;;;;;;;OAYG;IACH,uBARW,MAAM,GACJ,OAAO,CAAC,SAAS,CAAC,CAuB9B;IAyBD;;;;;;;;;;;;;;;OAeG;IACH,cAZa,eAAe,CAc3B;IAED;;;;;;;;;;;;;;OAcG;IACH,UARa,OAAO,CAAC,SAAS,CAAC,CAkB9B;IAED;;;;;OAKG;IACH,kBAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAM5B;IAED;;;;;OAKG;IACH,sBAHW,MAAM,GACJ,OAAO,CAAC,OAAO,CAAC,CAM5B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,sBAbW,MAAM,GACJ,eAAe,CAgC3B;IAED;;;;;;;;;;;;;;;;;;;;;;;;;OAyBG;IACH,kBAbW,MAAM,GACJ,UAAU,CAgCtB;IA/fD;;;;;;;OAOG;IACH,2BAHW,QAAQ,GAAC,QAAQ,GAAC,SAAS,GACzB,MAAM,GAAC,MAAM,CAQzB;;CAkfF;;UA9qBa,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"}
1
+ {"version":3,"file":"DirectoryObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/DirectoryObject.js"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@
11
11
  * @property {boolean} isFile - Always true for files
12
12
  * @property {DirectoryObject} parent - The parent directory object
13
13
  * @property {Promise<boolean>} exists - Whether the file exists (async)
14
+ * @property {Promise<("none"|"symbolic"|"broken"|"hard"|null)>} linkType - The link kind at this path (async)
14
15
  */
15
16
  export default class FileObject extends FS {
16
17
  [x: number]: (depth: number, options: object, ins: Function) => string;
@@ -52,6 +53,21 @@ export default class FileObject extends FS {
52
53
  * @returns {Promise<boolean>} - A Promise that resolves to true or false
53
54
  */
54
55
  get exists(): Promise<boolean>;
56
+ /**
57
+ * Reports the link kind at this path. Reads the filesystem on every
58
+ * access, like {@link FileObject#exists}.
59
+ *
60
+ * - `"symbolic"` - a symlink whose target exists
61
+ * - `"broken"` - a symlink whose target does not exist
62
+ * - `"hard"` - a regular file with additional hard links (`nlink > 1`).
63
+ * Hard links are inode-level and indistinguishable from each other,
64
+ * so this only reports that *some* other entry shares the inode.
65
+ * - `"none"` - a regular file with no links
66
+ * - `null` - the path does not exist
67
+ *
68
+ * @returns {Promise<"none"|"symbolic"|"broken"|"hard"|null>} The link kind
69
+ */
70
+ get linkType(): Promise<"none" | "symbolic" | "broken" | "hard" | null>;
55
71
  /**
56
72
  * Return the normalized path that was provided to the constructor.
57
73
  *
@@ -1 +1 @@
1
- {"version":3,"file":"FileObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/FileObject.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;GAaG;AAEH;yBA8Ha,MAAM,WACN,MAAM,oBAEJ,MAAM;IAggBnB;;;;;;;;;;;OAWG;IACH,kBAPa,UAAU,CAsCtB;IAjpBD;;;;;OAKG;IACH,uBAHW,MAAM,WACN,eAAe,GAAC,MAAM,GAAC,IAAI,EA+DrC;IAWD;;;;OAIG;IACH,UAFa,MAAM,CAalB;IA8BD;;;;OAIG;IACH,WAFa,MAAM,CAIlB;IAED;;;;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;IACD;;;;OAIG;IACH,cAFa,OAAO,CAInB;IAED;;;;;;;;;;;;;;OAcG;IACH,cAFa,eAAe,CAI3B;IAED;;;;OAIG;IACH,kBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,WAFa,OAAO,CAAC,OAAO,CAAC,CAU5B;IAED;;;;OAIG;IACH,YAFa,OAAO,CAAC,OAAO,CAAC,CAU5B;IA2BD;;;;OAIG;IACH,QAFa,OAAO,CAAC,MAAM,OAAC,CAAC,CAU5B;IAED;;;;;OAKG;IACH,YAFa,OAAO,CAAC,IAAI,OAAC,CAAC,CAU1B;IAED;;;;OAIG;IACH,cAFa,OAAO,CAInB;IAED;;;;;;;OAOG;IACH,kBAJW,KAAK,GACH,UAAU,CAYtB;IAED;;;;OAIG;IACH,eAFa,UAAU,CAOtB;IAED;;;;OAIG;IACH,cAFa,UAAU,CAMtB;IAED;;;;;;;OAOG;IACH,+BAJG;QAAyB,QAAQ,GAAzB,MAAM;QACY,SAAS,GAA3B,OAAO;KACf,GAAU,OAAO,CAAC,MAAM,CAAC,CAa3B;IAED;;;;;;;;;;;OAWG;IACH,cARa,OAAO,CAAC,MAAM,CAAC,CAe3B;IAED;;;;;;;;;;;OAWG;IACH,eARW,MAAM,aACN,MAAM,GACJ,OAAO,CAAC,SAAS,CAAC,CAiB9B;IAED;;;;;;;;;;;;;;;OAeG;IACH,kBAXW,WAAW,GAAC,IAAI,GAAC,MAAM,GACrB,OAAO,CAAC,SAAS,CAAC,CAwB9B;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,yCAZG;QAAyB,IAAI,GAArB,MAAM;QACW,QAAQ,GAAzB,MAAM;QACY,SAAS,GAA3B,OAAO;KACf,GAAU,OAAO,CAAC,OAAO,CAAC,CAqB5B;IAED;;;;OAIG;IACH,UAFa,OAAO,CAAC,MAAM,CAAC,CAS3B;IAED;;;;;;;;;;;;OAYG;IACH,kBATW,MAAM,GACJ,OAAO,CAAC,UAAU,CAAC,CAyB/B;IAED;;;;;;;;;;;;;OAaG;IACH,kBATW,MAAM,GACJ,OAAO,CAAC,UAAU,CAAC,CA0C/B;IAED;;;;;;;;;OASG;IACH,UAPa,OAAO,CAAC,SAAS,CAAC,CAc9B;IAxfD;;;;;;;OAOG;IACH,2BAHW,QAAQ,GAAC,QAAQ,GAAC,SAAS,GACzB,MAAM,GAAC,MAAM,CAQzB;;CAwhBF;eAhsBc,iBAAiB;4BADJ,sBAAsB;kBAFhC,YAAY"}
1
+ {"version":3,"file":"FileObject.d.ts","sourceRoot":"","sources":["../../../src/node/lib/FileObject.js"],"names":[],"mappings":"AAkBA;;;;;;;;;;;;;;GAcG;AAEH;yBA8Ha,MAAM,WACN,MAAM,oBAEJ,MAAM;IA2jBnB;;;;;;;;;;;OAWG;IACH,kBAPa,UAAU,CAsCtB;IA5sBD;;;;;OAKG;IACH,uBAHW,MAAM,WACN,eAAe,GAAC,MAAM,GAAC,IAAI,EA+DrC;IAWD;;;;OAIG;IACH,UAFa,MAAM,CAalB;IA8BD;;;;OAIG;IACH,WAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,cAFa,OAAO,CAAC,OAAO,CAAC,CAI5B;IAED;;;;;;;;;;;;;OAaG;IACH,gBAFa,OAAO,CAAC,MAAM,GAAC,UAAU,GAAC,QAAQ,GAAC,MAAM,GAAC,IAAI,CAAC,CAI3D;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;IACD;;;;OAIG;IACH,cAFa,OAAO,CAInB;IAED;;;;;;;;;;;;;;OAcG;IACH,cAFa,eAAe,CAI3B;IAED;;;;OAIG;IACH,kBAFa,MAAM,CAIlB;IAED;;;;OAIG;IACH,WAFa,OAAO,CAAC,OAAO,CAAC,CAU5B;IAED;;;;OAIG;IACH,YAFa,OAAO,CAAC,OAAO,CAAC,CAU5B;IAoED;;;;OAIG;IACH,QAFa,OAAO,CAAC,MAAM,OAAC,CAAC,CAU5B;IAED;;;;;OAKG;IACH,YAFa,OAAO,CAAC,IAAI,OAAC,CAAC,CAU1B;IAED;;;;OAIG;IACH,cAFa,OAAO,CAInB;IAED;;;;;;;OAOG;IACH,kBAJW,KAAK,GACH,UAAU,CAYtB;IAED;;;;OAIG;IACH,eAFa,UAAU,CAOtB;IAED;;;;OAIG;IACH,cAFa,UAAU,CAMtB;IAED;;;;;;;OAOG;IACH,+BAJG;QAAyB,QAAQ,GAAzB,MAAM;QACY,SAAS,GAA3B,OAAO;KACf,GAAU,OAAO,CAAC,MAAM,CAAC,CAa3B;IAED;;;;;;;;;;;OAWG;IACH,cARa,OAAO,CAAC,MAAM,CAAC,CAe3B;IAED;;;;;;;;;;;OAWG;IACH,eARW,MAAM,aACN,MAAM,GACJ,OAAO,CAAC,SAAS,CAAC,CAiB9B;IAED;;;;;;;;;;;;;;;OAeG;IACH,kBAXW,WAAW,GAAC,IAAI,GAAC,MAAM,GACrB,OAAO,CAAC,SAAS,CAAC,CAwB9B;IAED;;;;;;;;;;;;;;;;OAgBG;IACH,yCAZG;QAAyB,IAAI,GAArB,MAAM;QACW,QAAQ,GAAzB,MAAM;QACY,SAAS,GAA3B,OAAO;KACf,GAAU,OAAO,CAAC,OAAO,CAAC,CAqB5B;IAED;;;;OAIG;IACH,UAFa,OAAO,CAAC,MAAM,CAAC,CAS3B;IAED;;;;;;;;;;;;OAYG;IACH,kBATW,MAAM,GACJ,OAAO,CAAC,UAAU,CAAC,CAyB/B;IAED;;;;;;;;;;;;;OAaG;IACH,kBATW,MAAM,GACJ,OAAO,CAAC,UAAU,CAAC,CA0C/B;IAED;;;;;;;;;OASG;IACH,UAPa,OAAO,CAAC,SAAS,CAAC,CAc9B;IAnjBD;;;;;;;OAOG;IACH,2BAHW,QAAQ,GAAC,QAAQ,GAAC,SAAS,GACzB,MAAM,GAAC,MAAM,CAQzB;;CAmlBF;eA5vBc,iBAAiB;4BADJ,sBAAsB;kBAFhC,YAAY"}
@@ -1 +1 @@
1
- {"version":3,"file":"Sass.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Sass.js"],"names":[],"mappings":"AAgBA;;;GAGG;AACH;IACE;;;;;OAKG;IACH,kBAFW,OAAO,QAuCjB;;CAiCF;wBApFuB,2BAA2B"}
1
+ {"version":3,"file":"Sass.d.ts","sourceRoot":"","sources":["../../../src/node/lib/Sass.js"],"names":[],"mappings":"AAgBA;;;GAGG;AACH;IACE;;;;;OAKG;IACH,kBAFW,OAAO,QAqCjB;;CAiCF;wBAlFuB,2BAA2B"}
@@ -1,4 +1,4 @@
1
- // @gesslar/toolkit v5.2.0 - ES module bundle
1
+ // @gesslar/toolkit v5.3.0 - ES module bundle
2
2
  /**
3
3
  * @file Tantrum.js
4
4
  *
@@ -208,17 +208,15 @@ class Sass extends Error {
208
208
  );
209
209
  }
210
210
 
211
- if(this.cause) {
211
+ if(this.cause && nerdMode) {
212
212
  if(typeof this.cause.report === "function") {
213
- if(nerdMode) {
214
- console.error(
215
- "\n" +
216
- `[error] Caused By`
217
- );
218
- }
213
+ console.error(
214
+ "\n" +
215
+ `[error] Caused By`
216
+ );
219
217
 
220
218
  this.cause.report(nerdMode, true);
221
- } else if(nerdMode && this.cause.stack) {
219
+ } else if(this.cause.stack) {
222
220
  console.error();
223
221
  console.group();
224
222
  console.error(
@@ -1,4 +1,4 @@
1
- // @gesslar/toolkit v5.2.0 - UMD bundle
1
+ // @gesslar/toolkit v5.3.0 - UMD bundle
2
2
  (function (global, factory) {
3
3
  typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
4
4
  typeof define === 'function' && define.amd ? define(['exports'], factory) :
@@ -214,17 +214,15 @@
214
214
  );
215
215
  }
216
216
 
217
- if(this.cause) {
217
+ if(this.cause && nerdMode) {
218
218
  if(typeof this.cause.report === "function") {
219
- if(nerdMode) {
220
- console.error(
221
- "\n" +
222
- `[error] Caused By`
223
- );
224
- }
219
+ console.error(
220
+ "\n" +
221
+ `[error] Caused By`
222
+ );
225
223
 
226
224
  this.cause.report(nerdMode, true);
227
- } else if(nerdMode && this.cause.stack) {
225
+ } else if(this.cause.stack) {
228
226
  console.error();
229
227
  console.group();
230
228
  console.error(