@gesslar/toolkit 0.5.0 → 0.7.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 +8 -8
- package/src/lib/Collection.js +132 -17
- package/src/lib/Contract.js +1 -1
- package/src/lib/Data.js +27 -18
- package/src/lib/DirectoryObject.js +1 -1
- package/src/lib/FS.js +10 -0
- package/src/lib/Glog.js +27 -10
- package/src/lib/Logger.js +3 -0
- package/src/lib/Sass.js +6 -1
- package/src/lib/Tantrum.js +43 -0
- package/src/lib/TypeSpec.js +11 -7
- package/src/lib/Util.js +82 -0
- package/src/lib/Valid.js +24 -6
- package/src/types/Collection.d.ts +6 -1
- package/src/types/Contract.d.ts +27 -27
- package/src/types/Data.d.ts +23 -23
- package/src/types/FS.d.ts +3 -3
- package/src/types/Glog.d.ts +302 -49
- package/src/types/Sass.d.ts +1 -1
- package/src/types/Schemer.d.ts +29 -29
- package/src/types/Tantrum.d.ts +10 -10
- package/src/types/Term.d.ts +1 -1
- package/src/types/Terms.d.ts +21 -21
- package/src/types/Type.d.ts +1 -1
- package/src/types/Util.d.ts +20 -2
- package/src/types/index.d.ts +17 -23
- package/src/types/index.d.ts.map +1 -0
- package/src/types/lib/Cache.d.ts +28 -0
- package/src/types/lib/Cache.d.ts.map +1 -0
- package/src/types/lib/Collection.d.ts +246 -0
- package/src/types/lib/Collection.d.ts.map +1 -0
- package/src/types/lib/Contract.d.ts +72 -0
- package/src/types/lib/Contract.d.ts.map +1 -0
- package/src/types/lib/Data.d.ts +189 -0
- package/src/types/lib/Data.d.ts.map +1 -0
- package/src/types/lib/DirectoryObject.d.ts +148 -0
- package/src/types/lib/DirectoryObject.d.ts.map +1 -0
- package/src/types/lib/FS.d.ts +70 -0
- package/src/types/lib/FS.d.ts.map +1 -0
- package/src/types/lib/FileObject.d.ts +189 -0
- package/src/types/lib/FileObject.d.ts.map +1 -0
- package/src/types/lib/Glog.d.ts +113 -0
- package/src/types/lib/Glog.d.ts.map +1 -0
- package/src/types/lib/Logger.d.ts +46 -0
- package/src/types/lib/Logger.d.ts.map +1 -0
- package/src/types/lib/Sass.d.ts +62 -0
- package/src/types/lib/Sass.d.ts.map +1 -0
- package/src/types/lib/Schemer.d.ts +23 -0
- package/src/types/lib/Schemer.d.ts.map +1 -0
- package/src/types/lib/Tantrum.d.ts +50 -0
- package/src/types/lib/Tantrum.d.ts.map +1 -0
- package/src/types/lib/Term.d.ts +103 -0
- package/src/types/lib/Term.d.ts.map +1 -0
- package/src/types/lib/Terms.d.ts +24 -0
- package/src/types/lib/Terms.d.ts.map +1 -0
- package/src/types/lib/TypeSpec.d.ts +92 -0
- package/src/types/lib/TypeSpec.d.ts.map +1 -0
- package/src/types/lib/Util.d.ts +197 -0
- package/src/types/lib/Util.d.ts.map +1 -0
- package/src/types/lib/Valid.d.ts +33 -0
- package/src/types/lib/Valid.d.ts.map +1 -0
- package/src/lib/Action.js +0 -283
- package/src/lib/ActionBuilder.js +0 -144
- package/src/lib/ActionRunner.js +0 -79
- package/src/lib/Hooks.js +0 -194
- package/src/lib/Piper.js +0 -155
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gesslar/toolkit",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Get in, bitches, we're going toolkitting.",
|
|
5
5
|
"main": "./src/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -20,12 +20,12 @@
|
|
|
20
20
|
"node": ">=20"
|
|
21
21
|
},
|
|
22
22
|
"scripts": {
|
|
23
|
+
"types:build": "tsc -p tsconfig.types.json",
|
|
23
24
|
"lint": "eslint src/",
|
|
24
25
|
"lint:fix": "eslint src/ --fix",
|
|
25
26
|
"submit": "npm publish --access public",
|
|
26
27
|
"update": "npx npm-check-updates -u && npm install",
|
|
27
28
|
"test": "node --test tests/unit/*.test.js",
|
|
28
|
-
"test:unit": "node --test tests/unit/*.test.js",
|
|
29
29
|
"pr": "gt submit --publish --restack --ai"
|
|
30
30
|
},
|
|
31
31
|
"repository": {
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"yaml": "^2.8.1"
|
|
58
58
|
},
|
|
59
59
|
"devDependencies": {
|
|
60
|
-
"@stylistic/eslint-plugin": "^5.
|
|
61
|
-
"@types/node": "^24.
|
|
62
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
63
|
-
"@typescript-eslint/parser": "^8.
|
|
64
|
-
"eslint": "^9.
|
|
65
|
-
"eslint-plugin-jsdoc": "^
|
|
60
|
+
"@stylistic/eslint-plugin": "^5.5.0",
|
|
61
|
+
"@types/node": "^24.9.1",
|
|
62
|
+
"@typescript-eslint/eslint-plugin": "^8.46.2",
|
|
63
|
+
"@typescript-eslint/parser": "^8.46.2",
|
|
64
|
+
"eslint": "^9.38.0",
|
|
65
|
+
"eslint-plugin-jsdoc": "^61.1.8"
|
|
66
66
|
}
|
|
67
67
|
}
|
package/src/lib/Collection.js
CHANGED
|
@@ -1,9 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Collection.js
|
|
3
|
+
*
|
|
4
|
+
* Provides utility functions for working with collections (arrays, objects, sets, maps).
|
|
5
|
+
* Includes methods for iteration, transformation, validation, and manipulation of
|
|
6
|
+
* various collection types.
|
|
7
|
+
*/
|
|
8
|
+
|
|
1
9
|
import Data from "./Data.js"
|
|
2
10
|
import Valid from "./Valid.js"
|
|
3
11
|
import Sass from "./Sass.js"
|
|
4
12
|
import Util from "./Util.js"
|
|
5
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Utility class for collection operations.
|
|
16
|
+
* Provides static methods for working with arrays, objects, sets, and maps.
|
|
17
|
+
*/
|
|
6
18
|
export default class Collection {
|
|
19
|
+
/**
|
|
20
|
+
* Evaluates an array with a predicate function, optionally in reverse order.
|
|
21
|
+
* Returns the first truthy result from the predicate.
|
|
22
|
+
*
|
|
23
|
+
* @param {Array<unknown>} collection - The array to evaluate
|
|
24
|
+
* @param {(value: unknown, index: number, array: Array<unknown>) => unknown} predicate - Function to evaluate each element
|
|
25
|
+
* @param {boolean} [forward] - Whether to iterate forward (true) or backward (false). Defaults to true
|
|
26
|
+
* @returns {unknown|undefined} The first truthy result from the predicate, or undefined
|
|
27
|
+
* @throws {Sass} If collection is not an array or predicate is not a function
|
|
28
|
+
*/
|
|
7
29
|
static evalArray(collection, predicate, forward=true) {
|
|
8
30
|
const req = "Array"
|
|
9
31
|
const type = Data.typeOf(collection)
|
|
@@ -24,6 +46,15 @@ export default class Collection {
|
|
|
24
46
|
}
|
|
25
47
|
}
|
|
26
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Evaluates an object with a predicate function.
|
|
51
|
+
* Returns the first truthy result from the predicate.
|
|
52
|
+
*
|
|
53
|
+
* @param {object} collection - The object to evaluate
|
|
54
|
+
* @param {(value: unknown, key: string, object: object) => unknown} predicate - Function to evaluate each property
|
|
55
|
+
* @returns {unknown|undefined} The first truthy result from the predicate, or undefined
|
|
56
|
+
* @throws {Sass} If collection is not an object or predicate is not a function
|
|
57
|
+
*/
|
|
27
58
|
static evalObject(collection, predicate) {
|
|
28
59
|
const req = "Object"
|
|
29
60
|
const type = Data.typeOf(collection)
|
|
@@ -42,6 +73,15 @@ export default class Collection {
|
|
|
42
73
|
}
|
|
43
74
|
}
|
|
44
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Evaluates a Set with a predicate function.
|
|
78
|
+
* Returns the first truthy result from the predicate.
|
|
79
|
+
*
|
|
80
|
+
* @param {Set<unknown>} collection - The Set to evaluate
|
|
81
|
+
* @param {(value: unknown, set: Set<unknown>) => unknown} predicate - Function to evaluate each element
|
|
82
|
+
* @returns {unknown|undefined} The first truthy result from the predicate, or undefined
|
|
83
|
+
* @throws {Sass} If collection is not a Set or predicate is not a function
|
|
84
|
+
*/
|
|
45
85
|
static evalSet(collection, predicate) {
|
|
46
86
|
const req = "Set"
|
|
47
87
|
const type = Data.typeOf(collection)
|
|
@@ -60,6 +100,16 @@ export default class Collection {
|
|
|
60
100
|
}
|
|
61
101
|
}
|
|
62
102
|
|
|
103
|
+
/**
|
|
104
|
+
* Evaluates a Map with a predicate function, optionally in reverse order.
|
|
105
|
+
* Returns the first truthy result from the predicate.
|
|
106
|
+
*
|
|
107
|
+
* @param {Map<unknown, unknown>} collection - The Map to evaluate
|
|
108
|
+
* @param {(value: unknown, key: unknown, map: Map<unknown, unknown>) => unknown} predicate - Function to evaluate each entry
|
|
109
|
+
* @param {boolean} [forward] - Whether to iterate forward (true) or backward (false). Defaults to true
|
|
110
|
+
* @returns {unknown|undefined} The first truthy result from the predicate, or undefined
|
|
111
|
+
* @throws {Sass} If collection is not a Map or predicate is not a function
|
|
112
|
+
*/
|
|
63
113
|
static evalMap(collection, predicate, forward=true) {
|
|
64
114
|
const req = "Map"
|
|
65
115
|
const type = Data.typeOf(collection)
|
|
@@ -80,12 +130,27 @@ export default class Collection {
|
|
|
80
130
|
}
|
|
81
131
|
}
|
|
82
132
|
|
|
133
|
+
/**
|
|
134
|
+
* Zips two arrays together into an array of pairs.
|
|
135
|
+
* The resulting array length equals the shorter input array.
|
|
136
|
+
*
|
|
137
|
+
* @param {Array<unknown>} array1 - The first array
|
|
138
|
+
* @param {Array<unknown>} array2 - The second array
|
|
139
|
+
* @returns {Array<[unknown, unknown]>} Array of paired elements
|
|
140
|
+
*/
|
|
83
141
|
static zip(array1, array2) {
|
|
84
142
|
const minLength = Math.min(array1.length, array2.length)
|
|
85
143
|
|
|
86
144
|
return Array.from({length: minLength}, (_, i) => [array1[i], array2[i]])
|
|
87
145
|
}
|
|
88
146
|
|
|
147
|
+
/**
|
|
148
|
+
* Unzips an array of pairs into separate arrays.
|
|
149
|
+
* Transposes a 2D array structure.
|
|
150
|
+
*
|
|
151
|
+
* @param {Array<Array<unknown>>} array - Array of arrays to unzip
|
|
152
|
+
* @returns {Array<Array<unknown>>} Array of unzipped arrays, or empty array for invalid input
|
|
153
|
+
*/
|
|
89
154
|
static unzip(array) {
|
|
90
155
|
if(!Array.isArray(array) || array.length === 0) {
|
|
91
156
|
return [] // Handle empty or invalid input
|
|
@@ -108,6 +173,15 @@ export default class Collection {
|
|
|
108
173
|
return unzipped
|
|
109
174
|
}
|
|
110
175
|
|
|
176
|
+
/**
|
|
177
|
+
* Maps an array using an async function, processing items sequentially.
|
|
178
|
+
* Unlike Promise.all(array.map()), this processes one item at a time.
|
|
179
|
+
*
|
|
180
|
+
* @param {Array<unknown>} array - The array to map
|
|
181
|
+
* @param {(item: unknown) => Promise<unknown>} asyncFn - Async function to apply to each element
|
|
182
|
+
* @returns {Promise<Array<unknown>>} Promise resolving to the mapped array
|
|
183
|
+
* @throws {Sass} If array is not an Array or asyncFn is not a function
|
|
184
|
+
*/
|
|
111
185
|
static async asyncMap(array, asyncFn) {
|
|
112
186
|
const req = "Array"
|
|
113
187
|
const type = Data.typeOf(array)
|
|
@@ -128,9 +202,8 @@ export default class Collection {
|
|
|
128
202
|
/**
|
|
129
203
|
* Checks if all elements in an array are of a specified type
|
|
130
204
|
*
|
|
131
|
-
* @param {Array} arr - The array to check
|
|
132
|
-
* @param {string} type - The type to check for (optional, defaults to the
|
|
133
|
-
* type of the first element)
|
|
205
|
+
* @param {Array<unknown>} arr - The array to check
|
|
206
|
+
* @param {string} [type] - The type to check for (optional, defaults to the type of the first element)
|
|
134
207
|
* @returns {boolean} Whether all elements are of the specified type
|
|
135
208
|
*/
|
|
136
209
|
static isArrayUniform(arr, type) {
|
|
@@ -155,8 +228,8 @@ export default class Collection {
|
|
|
155
228
|
/**
|
|
156
229
|
* Checks if an array is unique
|
|
157
230
|
*
|
|
158
|
-
* @param {Array} arr - The array of which to remove duplicates
|
|
159
|
-
* @returns {Array} The unique elements of the array
|
|
231
|
+
* @param {Array<unknown>} arr - The array of which to remove duplicates
|
|
232
|
+
* @returns {Array<unknown>} The unique elements of the array
|
|
160
233
|
*/
|
|
161
234
|
static isArrayUnique(arr) {
|
|
162
235
|
const req = "Array"
|
|
@@ -170,9 +243,9 @@ export default class Collection {
|
|
|
170
243
|
/**
|
|
171
244
|
* Returns the intersection of two arrays.
|
|
172
245
|
*
|
|
173
|
-
* @param {Array} arr1 - The first array.
|
|
174
|
-
* @param {Array} arr2 - The second array.
|
|
175
|
-
* @returns {Array} The intersection of the two arrays.
|
|
246
|
+
* @param {Array<unknown>} arr1 - The first array.
|
|
247
|
+
* @param {Array<unknown>} arr2 - The second array.
|
|
248
|
+
* @returns {Array<unknown>} The intersection of the two arrays.
|
|
176
249
|
*/
|
|
177
250
|
static intersection(arr1, arr2) {
|
|
178
251
|
const req = "Array"
|
|
@@ -198,8 +271,8 @@ export default class Collection {
|
|
|
198
271
|
* Collection.intersects([1, 2, 3], [3, 4, 5]) // returns true
|
|
199
272
|
* Collection.intersects(["a", "b"], ["c", "d"]) // returns false
|
|
200
273
|
*
|
|
201
|
-
* @param {Array} arr1 - The first array to check for intersection.
|
|
202
|
-
* @param {Array} arr2 - The second array to check for intersection.
|
|
274
|
+
* @param {Array<unknown>} arr1 - The first array to check for intersection.
|
|
275
|
+
* @param {Array<unknown>} arr2 - The second array to check for intersection.
|
|
203
276
|
* @returns {boolean} True if any element is shared between the arrays, false otherwise.
|
|
204
277
|
*/
|
|
205
278
|
static intersects(arr1, arr2) {
|
|
@@ -219,11 +292,11 @@ export default class Collection {
|
|
|
219
292
|
* Pads an array to a specified length with a value. This operation
|
|
220
293
|
* occurs in-place.
|
|
221
294
|
*
|
|
222
|
-
* @param {Array} arr - The array to pad.
|
|
295
|
+
* @param {Array<unknown>} arr - The array to pad.
|
|
223
296
|
* @param {number} length - The length to pad the array to.
|
|
224
297
|
* @param {unknown} value - The value to pad the array with.
|
|
225
|
-
* @param {number} position - The position to pad the array at.
|
|
226
|
-
* @returns {Array} The padded array.
|
|
298
|
+
* @param {number} [position] - The position to pad the array at. Defaults to 0
|
|
299
|
+
* @returns {Array<unknown>} The padded array.
|
|
227
300
|
*/
|
|
228
301
|
static arrayPad(arr, length, value, position = 0) {
|
|
229
302
|
const req = "Array"
|
|
@@ -254,9 +327,9 @@ export default class Collection {
|
|
|
254
327
|
* Filters an array asynchronously using a predicate function.
|
|
255
328
|
* Applies the predicate to all items in parallel and returns filtered results.
|
|
256
329
|
*
|
|
257
|
-
* @param {Array} arr - The array to filter
|
|
258
|
-
* @param {
|
|
259
|
-
* @returns {Promise<Array
|
|
330
|
+
* @param {Array<unknown>} arr - The array to filter
|
|
331
|
+
* @param {(value: unknown, index: number, array: Array<unknown>) => Promise<boolean>} predicate - Async predicate function that returns a promise resolving to boolean
|
|
332
|
+
* @returns {Promise<Array<unknown>>} Promise resolving to the filtered array
|
|
260
333
|
*/
|
|
261
334
|
static async asyncFilter(arr, predicate) {
|
|
262
335
|
const req = "Array"
|
|
@@ -468,7 +541,7 @@ export default class Collection {
|
|
|
468
541
|
|
|
469
542
|
if(
|
|
470
543
|
!Data.isType(spec, "Array", {allowEmpty: false}) &&
|
|
471
|
-
!Data.isType(spec, "
|
|
544
|
+
!Data.isType(spec, "Function")
|
|
472
545
|
)
|
|
473
546
|
throw Sass.new("Spec must be an array or a function.")
|
|
474
547
|
|
|
@@ -498,6 +571,15 @@ export default class Collection {
|
|
|
498
571
|
return result
|
|
499
572
|
}
|
|
500
573
|
|
|
574
|
+
/**
|
|
575
|
+
* Trims falsy values from both ends of an array (in-place).
|
|
576
|
+
* Optionally preserves specific falsy values.
|
|
577
|
+
*
|
|
578
|
+
* @param {Array<unknown>} arr - The array to trim
|
|
579
|
+
* @param {Array<unknown>} [except] - Values to preserve even if falsy. Defaults to empty array
|
|
580
|
+
* @returns {Array<unknown>} The trimmed array (same reference, modified in-place)
|
|
581
|
+
* @throws {Sass} If arr is not an Array or except is not an Array
|
|
582
|
+
*/
|
|
501
583
|
static trimArray(arr, except=[]) {
|
|
502
584
|
Valid.type(arr, "Array")
|
|
503
585
|
Valid.type(except, "Array")
|
|
@@ -508,6 +590,15 @@ export default class Collection {
|
|
|
508
590
|
return arr
|
|
509
591
|
}
|
|
510
592
|
|
|
593
|
+
/**
|
|
594
|
+
* Trims falsy values from the right end of an array (in-place).
|
|
595
|
+
* Optionally preserves specific falsy values.
|
|
596
|
+
*
|
|
597
|
+
* @param {Array<unknown>} arr - The array to trim
|
|
598
|
+
* @param {Array<unknown>} [except] - Values to preserve even if falsy. Defaults to empty array
|
|
599
|
+
* @returns {Array<unknown>} The trimmed array (same reference, modified in-place)
|
|
600
|
+
* @throws {Sass} If arr is not an Array or except is not an Array
|
|
601
|
+
*/
|
|
511
602
|
static trimArrayRight(arr, except=[]) {
|
|
512
603
|
Valid.type(arr, "Array")
|
|
513
604
|
Valid.type(except, "Array")
|
|
@@ -519,6 +610,15 @@ export default class Collection {
|
|
|
519
610
|
return arr
|
|
520
611
|
}
|
|
521
612
|
|
|
613
|
+
/**
|
|
614
|
+
* Trims falsy values from the left end of an array (in-place).
|
|
615
|
+
* Optionally preserves specific falsy values.
|
|
616
|
+
*
|
|
617
|
+
* @param {Array<unknown>} arr - The array to trim
|
|
618
|
+
* @param {Array<unknown>} [except] - Values to preserve even if falsy. Defaults to empty array
|
|
619
|
+
* @returns {Array<unknown>} The trimmed array (same reference, modified in-place)
|
|
620
|
+
* @throws {Sass} If arr is not an Array or except is not an Array
|
|
621
|
+
*/
|
|
522
622
|
static trimArrayLeft(arr, except=[]) {
|
|
523
623
|
Valid.type(arr, "Array")
|
|
524
624
|
Valid.type(except, "Array")
|
|
@@ -535,6 +635,14 @@ export default class Collection {
|
|
|
535
635
|
return arr
|
|
536
636
|
}
|
|
537
637
|
|
|
638
|
+
/**
|
|
639
|
+
* Transposes an array of objects into an object of arrays.
|
|
640
|
+
* Collects values for each key across all objects into arrays.
|
|
641
|
+
*
|
|
642
|
+
* @param {Array<object>} objects - Array of plain objects to transpose
|
|
643
|
+
* @returns {object} Object with keys from input objects, values as arrays
|
|
644
|
+
* @throws {Sass} If objects is not an Array or contains non-plain objects
|
|
645
|
+
*/
|
|
538
646
|
static transposeObjects(objects) {
|
|
539
647
|
const req = "Array"
|
|
540
648
|
const type = Data.typeOf(objects)
|
|
@@ -560,6 +668,13 @@ export default class Collection {
|
|
|
560
668
|
}, {})
|
|
561
669
|
}
|
|
562
670
|
|
|
671
|
+
/**
|
|
672
|
+
* Flattens an array (or nested array) of objects and transposes them.
|
|
673
|
+
* Combines flat() and transposeObjects() operations.
|
|
674
|
+
*
|
|
675
|
+
* @param {Array<object>|Array<Array<object>>} input - Array or nested array of objects
|
|
676
|
+
* @returns {object} Transposed object with arrays of values
|
|
677
|
+
*/
|
|
563
678
|
static flattenObjectArray(input) {
|
|
564
679
|
const flattened = Array.isArray(input) ? input.flat() : input
|
|
565
680
|
|
package/src/lib/Contract.js
CHANGED
|
@@ -156,7 +156,7 @@ export default class Contract {
|
|
|
156
156
|
*
|
|
157
157
|
* @param {object} providerTerms - Terms offered by provider
|
|
158
158
|
* @param {object} consumerTerms - Terms expected by consumer
|
|
159
|
-
* @param {Array} stack - Stack trace for nested validation
|
|
159
|
+
* @param {Array<string>} stack - Stack trace for nested validation
|
|
160
160
|
* @returns {object} Result with status and errors
|
|
161
161
|
* @private
|
|
162
162
|
*/
|
package/src/lib/Data.js
CHANGED
|
@@ -17,17 +17,18 @@ export default class Data {
|
|
|
17
17
|
*/
|
|
18
18
|
static primitives = Object.freeze([
|
|
19
19
|
// Primitives
|
|
20
|
-
"
|
|
21
|
-
"Null",
|
|
20
|
+
"Bigint",
|
|
22
21
|
"Boolean",
|
|
22
|
+
"Class",
|
|
23
|
+
"Null",
|
|
23
24
|
"Number",
|
|
24
|
-
"Bigint",
|
|
25
25
|
"String",
|
|
26
26
|
"Symbol",
|
|
27
|
+
"Undefined",
|
|
27
28
|
|
|
28
29
|
// Object Categories from typeof
|
|
29
|
-
"Object",
|
|
30
30
|
"Function",
|
|
31
|
+
"Object",
|
|
31
32
|
])
|
|
32
33
|
|
|
33
34
|
/**
|
|
@@ -38,21 +39,21 @@ export default class Data {
|
|
|
38
39
|
*/
|
|
39
40
|
static constructors = Object.freeze([
|
|
40
41
|
// Object Constructors
|
|
41
|
-
"Object",
|
|
42
42
|
"Array",
|
|
43
|
-
"Function",
|
|
44
43
|
"Date",
|
|
45
|
-
"RegExp",
|
|
46
44
|
"Error",
|
|
45
|
+
"Float32Array",
|
|
46
|
+
"Float64Array",
|
|
47
|
+
"Function",
|
|
48
|
+
"Int8Array",
|
|
47
49
|
"Map",
|
|
50
|
+
"Object",
|
|
51
|
+
"Promise",
|
|
52
|
+
"RegExp",
|
|
48
53
|
"Set",
|
|
54
|
+
"Uint8Array",
|
|
49
55
|
"WeakMap",
|
|
50
56
|
"WeakSet",
|
|
51
|
-
"Promise",
|
|
52
|
-
"Int8Array",
|
|
53
|
-
"Uint8Array",
|
|
54
|
-
"Float32Array",
|
|
55
|
-
"Float64Array",
|
|
56
57
|
])
|
|
57
58
|
|
|
58
59
|
/**
|
|
@@ -123,7 +124,7 @@ export default class Data {
|
|
|
123
124
|
? type
|
|
124
125
|
: Data.newTypeSpec(type, options)
|
|
125
126
|
|
|
126
|
-
return typeSpec.
|
|
127
|
+
return typeSpec.matches(value, options)
|
|
127
128
|
}
|
|
128
129
|
|
|
129
130
|
/**
|
|
@@ -134,9 +135,8 @@ export default class Data {
|
|
|
134
135
|
*/
|
|
135
136
|
static isValidType(type) {
|
|
136
137
|
// Allow built-in types
|
|
137
|
-
if(Data.dataTypes.includes(type))
|
|
138
|
+
if(Data.dataTypes.includes(type))
|
|
138
139
|
return true
|
|
139
|
-
}
|
|
140
140
|
|
|
141
141
|
// Allow custom classes (PascalCase starting with capital letter)
|
|
142
142
|
return /^[A-Z][a-zA-Z0-9]*$/.test(type)
|
|
@@ -155,6 +155,15 @@ export default class Data {
|
|
|
155
155
|
if(!Data.isValidType(type))
|
|
156
156
|
return false
|
|
157
157
|
|
|
158
|
+
// We gotta do classes up front. Ugh.
|
|
159
|
+
if(/^[Cc]lass$/.test(type)) {
|
|
160
|
+
if(typeof value === "function" &&
|
|
161
|
+
value.prototype &&
|
|
162
|
+
value.prototype.constructor === value)
|
|
163
|
+
|
|
164
|
+
return true
|
|
165
|
+
}
|
|
166
|
+
|
|
158
167
|
const valueType = Data.typeOf(value)
|
|
159
168
|
|
|
160
169
|
// Special cases that need extra validation
|
|
@@ -327,9 +336,9 @@ export default class Data {
|
|
|
327
336
|
* Filters an array asynchronously using a predicate function.
|
|
328
337
|
* Applies the predicate to all items in parallel and returns filtered results.
|
|
329
338
|
*
|
|
330
|
-
* @param {Array} arr - The array to filter
|
|
331
|
-
* @param {
|
|
332
|
-
* @returns {Promise<Array
|
|
339
|
+
* @param {Array<unknown>} arr - The array to filter
|
|
340
|
+
* @param {(value: unknown) => Promise<boolean>} predicate - Async predicate function that returns a promise resolving to boolean
|
|
341
|
+
* @returns {Promise<Array<unknown>>} Promise resolving to the filtered array
|
|
333
342
|
*/
|
|
334
343
|
static async asyncFilter(arr, predicate) {
|
|
335
344
|
const results = await Promise.all(arr.map(predicate))
|
|
@@ -191,7 +191,7 @@ export default class DirectoryObject extends FS {
|
|
|
191
191
|
/**
|
|
192
192
|
* Returns the directory path split into segments.
|
|
193
193
|
*
|
|
194
|
-
* @returns {string
|
|
194
|
+
* @returns {Array<string>} Array of path segments
|
|
195
195
|
* @example
|
|
196
196
|
* const dir = new DirectoryObject('/path/to/directory')
|
|
197
197
|
* console.log(dir.trail) // ['', 'path', 'to', 'directory']
|
package/src/lib/FS.js
CHANGED
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file FS.js
|
|
3
|
+
*
|
|
4
|
+
* File system utilities for path manipulation, file discovery, and path resolution.
|
|
5
|
+
* Provides glob-based file search, URI conversion, and intelligent path merging.
|
|
6
|
+
*/
|
|
7
|
+
|
|
1
8
|
import {globby} from "globby"
|
|
2
9
|
import path from "node:path"
|
|
3
10
|
import url from "node:url"
|
|
@@ -14,6 +21,9 @@ const fdType = Object.freeze(
|
|
|
14
21
|
await Collection.allocateObject(upperFdTypes, fdTypes)
|
|
15
22
|
)
|
|
16
23
|
|
|
24
|
+
/**
|
|
25
|
+
* File system utility class for path operations and file discovery.
|
|
26
|
+
*/
|
|
17
27
|
export default class FS {
|
|
18
28
|
static fdTypes = fdTypes
|
|
19
29
|
static upperFdTypes = upperFdTypes
|
package/src/lib/Glog.js
CHANGED
|
@@ -1,11 +1,6 @@
|
|
|
1
|
-
import c from "@gesslar/colours"
|
|
2
|
-
|
|
3
|
-
import Data from "./Data.js"
|
|
4
|
-
import Term from "./Term.js"
|
|
5
|
-
import Util from "./Util.js"
|
|
6
|
-
// ErrorStackParser will be dynamically imported when needed
|
|
7
|
-
|
|
8
1
|
/**
|
|
2
|
+
* @file Glog.js
|
|
3
|
+
*
|
|
9
4
|
* Enhanced Global logging utility that combines simple logging with advanced Logger features.
|
|
10
5
|
*
|
|
11
6
|
* Can be used in multiple ways:
|
|
@@ -16,6 +11,13 @@ import Util from "./Util.js"
|
|
|
16
11
|
* 5. Traditional logger: logger.debug("message", level)
|
|
17
12
|
*/
|
|
18
13
|
|
|
14
|
+
import c from "@gesslar/colours"
|
|
15
|
+
|
|
16
|
+
import Data from "./Data.js"
|
|
17
|
+
import Term from "./Term.js"
|
|
18
|
+
import Util from "./Util.js"
|
|
19
|
+
// ErrorStackParser will be dynamically imported when needed
|
|
20
|
+
|
|
19
21
|
// Enhanced color system using @gesslar/colours
|
|
20
22
|
export const loggerColours = {
|
|
21
23
|
debug: [
|
|
@@ -238,10 +240,24 @@ class Glog {
|
|
|
238
240
|
}
|
|
239
241
|
|
|
240
242
|
// Traditional logger methods
|
|
241
|
-
|
|
243
|
+
/**
|
|
244
|
+
* Log a debug message with specified verbosity level.
|
|
245
|
+
* Level 0 means debug OFF - use levels 1-4 for actual debug output.
|
|
246
|
+
* Debug messages only show when logLevel > 0.
|
|
247
|
+
*
|
|
248
|
+
* @param {string} message - Debug message to log
|
|
249
|
+
* @param {number} level - Debug verbosity level (1-4, default: 1)
|
|
250
|
+
* @param {...unknown} arg - Additional arguments to log
|
|
251
|
+
* @throws {Error} If level < 1 (level 0 = debug OFF)
|
|
252
|
+
*/
|
|
253
|
+
debug(message, level = 1, ...arg) {
|
|
254
|
+
if(level < 1) {
|
|
255
|
+
throw new Error("Debug level must be >= 1 (level 0 = debug OFF)")
|
|
256
|
+
}
|
|
257
|
+
|
|
242
258
|
const currentLevel = this.#logLevel || Glog.logLevel
|
|
243
259
|
|
|
244
|
-
if(level <= currentLevel) {
|
|
260
|
+
if(currentLevel > 0 && level <= currentLevel) {
|
|
245
261
|
Term.debug(this.#compose("debug", message, level), ...arg)
|
|
246
262
|
}
|
|
247
263
|
}
|
|
@@ -370,10 +386,11 @@ export default new Proxy(Glog, {
|
|
|
370
386
|
return new target(...argumentsList)
|
|
371
387
|
},
|
|
372
388
|
get(target, prop) {
|
|
389
|
+
// Hide execute method from public API
|
|
373
390
|
if(prop === "execute") {
|
|
374
391
|
return undefined
|
|
375
392
|
}
|
|
376
393
|
|
|
377
|
-
return target
|
|
394
|
+
return Reflect.get(target, prop)
|
|
378
395
|
}
|
|
379
396
|
})
|
package/src/lib/Logger.js
CHANGED
package/src/lib/Sass.js
CHANGED
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
*/
|
|
13
13
|
|
|
14
14
|
import Term from "./Term.js"
|
|
15
|
+
import Tantrum from "./Tantrum.js"
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Custom error class for toolkit errors.
|
|
@@ -149,15 +150,19 @@ export default class Sass extends Error {
|
|
|
149
150
|
* other errors. Otherwise creates a new Sass instance.
|
|
150
151
|
*
|
|
151
152
|
* @param {string} message - The error message
|
|
152
|
-
* @param {Error|Sass} [error] - Optional existing error to wrap or enhance
|
|
153
|
+
* @param {Error|Sass|Tantrum} [error] - Optional existing error to wrap or enhance
|
|
153
154
|
* @returns {Sass} New or enhanced Sass instance
|
|
154
155
|
*/
|
|
155
156
|
static new(message, error) {
|
|
156
157
|
if(error) {
|
|
158
|
+
if(error instanceof Tantrum)
|
|
159
|
+
return Tantrum.new(message, error)
|
|
160
|
+
|
|
157
161
|
return error instanceof Sass
|
|
158
162
|
? error.addTrace(message)
|
|
159
163
|
: Sass.from(error, message)
|
|
160
164
|
} else {
|
|
165
|
+
|
|
161
166
|
return new Sass(message)
|
|
162
167
|
}
|
|
163
168
|
}
|
package/src/lib/Tantrum.js
CHANGED
|
@@ -17,6 +17,8 @@ import Term from "./Term.js"
|
|
|
17
17
|
* Automatically wraps plain errors in Sass instances for consistent reporting.
|
|
18
18
|
*/
|
|
19
19
|
export default class Tantrum extends AggregateError {
|
|
20
|
+
#trace = []
|
|
21
|
+
|
|
20
22
|
/**
|
|
21
23
|
* Creates a new Tantrum instance.
|
|
22
24
|
*
|
|
@@ -38,6 +40,41 @@ export default class Tantrum extends AggregateError {
|
|
|
38
40
|
super(wrappedErrors, message)
|
|
39
41
|
this.name = "Tantrum"
|
|
40
42
|
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Adds a trace message and returns this instance for chaining.
|
|
46
|
+
*
|
|
47
|
+
* @param {string} message - The trace message to add
|
|
48
|
+
* @param {Error|Sass} [_error] - Optional error (currently unused, reserved for future use)
|
|
49
|
+
* @returns {this} This Tantrum instance for method chaining
|
|
50
|
+
*/
|
|
51
|
+
addTrace(message, _error) {
|
|
52
|
+
if(typeof message !== "string")
|
|
53
|
+
throw Sass.new(`Tantrum.addTrace expected string, got ${JSON.stringify(message)}`)
|
|
54
|
+
|
|
55
|
+
this.trace = message
|
|
56
|
+
|
|
57
|
+
return this
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Gets the error trace array.
|
|
62
|
+
*
|
|
63
|
+
* @returns {Array<string>} Array of trace messages
|
|
64
|
+
*/
|
|
65
|
+
get trace() {
|
|
66
|
+
return this.#trace
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Adds a message to the beginning of the trace array.
|
|
71
|
+
*
|
|
72
|
+
* @param {string} message - The trace message to add
|
|
73
|
+
*/
|
|
74
|
+
set trace(message) {
|
|
75
|
+
this.#trace.unshift(message)
|
|
76
|
+
}
|
|
77
|
+
|
|
41
78
|
/**
|
|
42
79
|
* Reports all aggregated errors to the terminal with formatted output.
|
|
43
80
|
*
|
|
@@ -49,6 +86,9 @@ export default class Tantrum extends AggregateError {
|
|
|
49
86
|
this.message
|
|
50
87
|
)
|
|
51
88
|
|
|
89
|
+
if(this.trace)
|
|
90
|
+
Term.error(this.trace.join("\n"))
|
|
91
|
+
|
|
52
92
|
Term.error()
|
|
53
93
|
|
|
54
94
|
this.errors.forEach(error => {
|
|
@@ -64,6 +104,9 @@ export default class Tantrum extends AggregateError {
|
|
|
64
104
|
* @returns {Tantrum} New Tantrum instance
|
|
65
105
|
*/
|
|
66
106
|
static new(message, errors = []) {
|
|
107
|
+
if(errors instanceof Tantrum)
|
|
108
|
+
return errors.addTrace(message)
|
|
109
|
+
|
|
67
110
|
return new Tantrum(message, errors)
|
|
68
111
|
}
|
|
69
112
|
}
|
package/src/lib/TypeSpec.js
CHANGED
|
@@ -138,23 +138,27 @@ export default class TypeSpec {
|
|
|
138
138
|
* @param {boolean} options.allowEmpty - Whether empty values are allowed
|
|
139
139
|
* @returns {boolean} True if the value matches any type specification
|
|
140
140
|
*/
|
|
141
|
+
matches(value, options) {
|
|
142
|
+
return this.match(value,options).length > 0
|
|
143
|
+
}
|
|
144
|
+
|
|
141
145
|
match(value, options) {
|
|
142
146
|
const allowEmpty = options?.allowEmpty ?? true
|
|
143
147
|
const empty = Data.isEmpty(value)
|
|
144
148
|
|
|
145
|
-
// If we have a list of types, because the string was validly parsed,
|
|
146
|
-
//
|
|
147
|
-
//
|
|
149
|
+
// If we have a list of types, because the string was validly parsed, we
|
|
150
|
+
// need to ensure that all of the types that were parsed are valid types in
|
|
151
|
+
// JavaScript.
|
|
148
152
|
if(this.length && !this.every(t => Data.isValidType(t.typeName)))
|
|
149
|
-
return
|
|
153
|
+
return []
|
|
150
154
|
|
|
151
155
|
// Now, let's do some checking with the types, respecting the array flag
|
|
152
156
|
// with the value
|
|
153
157
|
const valueType = Data.typeOf(value)
|
|
154
158
|
const isArray = valueType === "Array"
|
|
155
159
|
|
|
156
|
-
// We need to ensure that we match the type and the consistency of the
|
|
157
|
-
// in an array, if it is an array and an array is allowed.
|
|
160
|
+
// We need to ensure that we match the type and the consistency of the
|
|
161
|
+
// types in an array, if it is an array and an array is allowed.
|
|
158
162
|
const matchingTypeSpec = this.filter(spec => {
|
|
159
163
|
const {typeName: allowedType, array: allowedArray} = spec
|
|
160
164
|
|
|
@@ -187,7 +191,7 @@ export default class TypeSpec {
|
|
|
187
191
|
return false
|
|
188
192
|
})
|
|
189
193
|
|
|
190
|
-
return matchingTypeSpec
|
|
194
|
+
return matchingTypeSpec
|
|
191
195
|
}
|
|
192
196
|
|
|
193
197
|
/**
|