@gesslar/toolkit 0.2.8 → 0.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 +4 -2
- package/src/index.js +1 -0
- package/src/lib/ActionBuilder.js +144 -0
- package/src/lib/ActionRunner.js +109 -0
- package/src/lib/BaseActionManager.js +246 -0
- package/src/lib/BaseHookManager.js +206 -0
- package/src/lib/Glog.js +324 -86
- package/src/lib/Logger.js +182 -0
- package/src/lib/Piper.js +181 -0
- package/src/lib/Sass.js +2 -4
- package/src/lib/Tantrum.js +69 -0
- package/src/types/Tantrum.d.ts +81 -0
- package/src/types/index.d.ts +1 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/*
|
|
2
|
+
For formatting console info, see:
|
|
3
|
+
https://nodejs.org/docs/latest-v22.x/api/util.html#utilformatformat-args
|
|
4
|
+
|
|
5
|
+
* %s: String will be used to convert all values except BigInt, Object and -0.
|
|
6
|
+
BigInt values will be represented with an n and Objects that have no
|
|
7
|
+
user defined toString function are inspected using util.inspect() with
|
|
8
|
+
options { depth: 0, colors: false, compact: 3 }.
|
|
9
|
+
* %d: Number will be used to convert all values except BigInt and Symbol.
|
|
10
|
+
* %i: parseInt(value, 10) is used for all values except BigInt and Symbol.
|
|
11
|
+
* %f: parseFloat(value) is used for all values expect Symbol.
|
|
12
|
+
* %j: JSON. Replaced with the string '[Circular]' if the argument contains
|
|
13
|
+
circular references.
|
|
14
|
+
* %o: Object. A string representation of an object with generic JavaScript
|
|
15
|
+
object formatting. Similar to util.inspect() with options { showHidden:
|
|
16
|
+
true, showProxy: true }. This will show the full object including non-
|
|
17
|
+
enumerable properties and proxies.
|
|
18
|
+
* %O: Object. A string representation of an object with generic JavaScript
|
|
19
|
+
object formatting. Similar to util.inspect() without options. This will
|
|
20
|
+
show the full object not including non-enumerable properties and
|
|
21
|
+
proxies.
|
|
22
|
+
* %%: single percent sign ('%'). This does not consume an argument.
|
|
23
|
+
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
import ErrorStackParser from "error-stack-parser"
|
|
27
|
+
import console from "node:console"
|
|
28
|
+
import {Environment} from "./Core.js"
|
|
29
|
+
import {FileObject, Util} from "@gesslar/toolkit"
|
|
30
|
+
|
|
31
|
+
export const loggerColours = {
|
|
32
|
+
debug: [
|
|
33
|
+
"\x1b[38;5;19m", // Debug level 0: Dark blue
|
|
34
|
+
"\x1b[38;5;27m", // Debug level 1: Medium blue
|
|
35
|
+
"\x1b[38;5;33m", // Debug level 2: Light blue
|
|
36
|
+
"\x1b[38;5;39m", // Debug level 3: Teal
|
|
37
|
+
"\x1b[38;5;44m", // Debug level 4: Blue-tinted cyan
|
|
38
|
+
],
|
|
39
|
+
info: "\x1b[38;5;36m", // Medium Spring Green
|
|
40
|
+
warn: "\x1b[38;5;214m", // Orange1
|
|
41
|
+
error: "\x1b[38;5;196m", // Red1
|
|
42
|
+
reset: "\x1b[0m", // Reset
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Logger class
|
|
47
|
+
*
|
|
48
|
+
* Log levels:
|
|
49
|
+
* - debug: Debugging information
|
|
50
|
+
* - Debug levels
|
|
51
|
+
* - 0: No/critical debug information, not error level, but, should be
|
|
52
|
+
* logged
|
|
53
|
+
* - 1: Basic debug information, startup, shutdown, etc
|
|
54
|
+
* - 2: Intermediate debug information, discovery, starting to get more
|
|
55
|
+
* detailed
|
|
56
|
+
* - 3: Detailed debug information, parsing, processing, etc
|
|
57
|
+
* - 4: Very detailed debug information, nerd mode!
|
|
58
|
+
* - warn: Warning information
|
|
59
|
+
* - info: Informational information
|
|
60
|
+
* - error: Error information
|
|
61
|
+
*/
|
|
62
|
+
|
|
63
|
+
export default class Logger {
|
|
64
|
+
#name = null
|
|
65
|
+
#debugLevel = 0
|
|
66
|
+
|
|
67
|
+
constructor(options) {
|
|
68
|
+
this.#name = "BeDoc"
|
|
69
|
+
if(options) {
|
|
70
|
+
this.setOptions(options)
|
|
71
|
+
if(options.env === Environment.EXTENSION) {
|
|
72
|
+
const vscode = import("vscode")
|
|
73
|
+
|
|
74
|
+
this.vscodeError = vscode.window.showErrorMessage
|
|
75
|
+
this.vscodeWarn = vscode.window.showWarningMessage
|
|
76
|
+
this.vscodeInfo = vscode.window.showInformationMessage
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
get name() {
|
|
82
|
+
return this.#name
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
get debugLevel() {
|
|
86
|
+
return this.#debugLevel
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
get options() {
|
|
90
|
+
return {
|
|
91
|
+
name: this.#name,
|
|
92
|
+
debugLevel: this.#debugLevel,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
setOptions(options) {
|
|
97
|
+
this.#name = options.name ?? this.#name
|
|
98
|
+
this.#debugLevel = options.debugLevel
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
#compose(level, message, debugLevel = 0) {
|
|
102
|
+
const tag = Util.capitalize(level)
|
|
103
|
+
|
|
104
|
+
if(level === "debug")
|
|
105
|
+
return `[${this.#name}] ${loggerColours[level][debugLevel]}${tag}${loggerColours.reset}: ${message}`
|
|
106
|
+
|
|
107
|
+
return `[${this.#name}] ${loggerColours[level]}${tag}${loggerColours.reset}: ${message}`
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
lastStackLine(error = new Error(), stepsRemoved = 3) {
|
|
111
|
+
const stack = ErrorStackParser.parse(error)
|
|
112
|
+
|
|
113
|
+
return stack[stepsRemoved]
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
extractFileFunction(level = 0) {
|
|
117
|
+
const frame = this.lastStackLine()
|
|
118
|
+
const {
|
|
119
|
+
functionName: func,
|
|
120
|
+
fileName: file,
|
|
121
|
+
lineNumber: line,
|
|
122
|
+
columnNumber: col,
|
|
123
|
+
} = frame
|
|
124
|
+
|
|
125
|
+
const tempFile = new FileObject(file)
|
|
126
|
+
const {module, uri} = tempFile
|
|
127
|
+
|
|
128
|
+
let functionName = func ?? "anonymous"
|
|
129
|
+
|
|
130
|
+
if(functionName.startsWith("#"))
|
|
131
|
+
functionName = `${module}.${functionName}`
|
|
132
|
+
|
|
133
|
+
const methodName = /\[as \w+\]$/.test(functionName)
|
|
134
|
+
? /\[as (\w+)\]/.exec(functionName)[1]
|
|
135
|
+
: null
|
|
136
|
+
|
|
137
|
+
if(methodName) {
|
|
138
|
+
functionName = functionName.replace(/\[as \w+\]$/, "")
|
|
139
|
+
functionName = `${functionName}{${methodName}}`
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
if(/^async /.test(functionName))
|
|
143
|
+
functionName = functionName.replace(/^async /, "(async)")
|
|
144
|
+
|
|
145
|
+
let result = functionName
|
|
146
|
+
|
|
147
|
+
if(level >= 2)
|
|
148
|
+
result = `${result}:${line}:${col}`
|
|
149
|
+
|
|
150
|
+
if(level >= 3)
|
|
151
|
+
result = `${uri} ${result}`
|
|
152
|
+
|
|
153
|
+
return result
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
newDebug(tag) {
|
|
157
|
+
return function(message, level, ...arg) {
|
|
158
|
+
tag = this.extractFileFunction(this.#debugLevel)
|
|
159
|
+
this.debug(`[${tag}] ${message}`, level, ...arg)
|
|
160
|
+
}.bind(this)
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
debug(message, level = 0, ...arg) {
|
|
164
|
+
if(level <= (this.debugLevel ?? 4))
|
|
165
|
+
console.debug(this.#compose("debug", message, level), ...arg)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
warn(message, ...arg) {
|
|
169
|
+
console.warn(this.#compose("warn", message), ...arg)
|
|
170
|
+
this.vscodeWarn?.(JSON.stringify(message))
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
info(message, ...arg) {
|
|
174
|
+
console.info(this.#compose("info", message), ...arg)
|
|
175
|
+
this.vscodeInfo?.(JSON.stringify(message))
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
error(message, ...arg) {
|
|
179
|
+
console.error(this.#compose("error", message), ...arg)
|
|
180
|
+
this.vscodeError?.(JSON.stringify(message))
|
|
181
|
+
}
|
|
182
|
+
}
|
package/src/lib/Piper.js
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generic Pipeline - Process items through a series of steps with concurrency control
|
|
3
|
+
*
|
|
4
|
+
* This abstraction handles:
|
|
5
|
+
* - Concurrent processing with configurable limits
|
|
6
|
+
* - Pipeline of processing steps
|
|
7
|
+
* - Result categorization (success/warning/error)
|
|
8
|
+
* - Setup/cleanup lifecycle hooks
|
|
9
|
+
* - Error handling and reporting
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
export default class Piper {
|
|
13
|
+
#succeeded = []
|
|
14
|
+
#warned = []
|
|
15
|
+
#errored = []
|
|
16
|
+
#steps = []
|
|
17
|
+
#setupHooks = []
|
|
18
|
+
#cleanupHooks = []
|
|
19
|
+
#logger
|
|
20
|
+
|
|
21
|
+
constructor(options = {}) {
|
|
22
|
+
this.#logger = options.logger || {newDebug: () => () => {}}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Add a processing step to the pipeline
|
|
27
|
+
*
|
|
28
|
+
* @param {(context: object) => Promise<object>} stepFn - Function that processes an item: (context) => Promise<result>
|
|
29
|
+
* @param {object} options - Step options (name, required, etc.)
|
|
30
|
+
* @returns {Piper} The pipeline instance (for chaining)
|
|
31
|
+
*/
|
|
32
|
+
addStep(stepFn, options = {}) {
|
|
33
|
+
this.#steps.push({
|
|
34
|
+
fn: stepFn,
|
|
35
|
+
name: options.name || `Step ${this.#steps.length + 1}`,
|
|
36
|
+
required: options.required !== false, // Default to required
|
|
37
|
+
...options
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
return this
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Add setup hook that runs before processing starts
|
|
45
|
+
*
|
|
46
|
+
* @param {() => Promise<void>} setupFn - Setup function: () => Promise<void>
|
|
47
|
+
* @returns {Piper} The pipeline instance (for chaining)
|
|
48
|
+
*/
|
|
49
|
+
addSetup(setupFn) {
|
|
50
|
+
this.#setupHooks.push(setupFn)
|
|
51
|
+
|
|
52
|
+
return this
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Add cleanup hook that runs after processing completes
|
|
57
|
+
*
|
|
58
|
+
* @param {() => Promise<void>} cleanupFn - Cleanup function: () => Promise<void>
|
|
59
|
+
* @returns {Piper} The pipeline instance (for chaining)
|
|
60
|
+
*/
|
|
61
|
+
addCleanup(cleanupFn) {
|
|
62
|
+
this.#cleanupHooks.push(cleanupFn)
|
|
63
|
+
|
|
64
|
+
return this
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Process items through the pipeline with concurrency control
|
|
69
|
+
*
|
|
70
|
+
* @param {Array} items - Items to process
|
|
71
|
+
* @param {number} maxConcurrent - Maximum concurrent items to process
|
|
72
|
+
* @returns {Promise<object>} - Results object with succeeded, warned, errored arrays
|
|
73
|
+
*/
|
|
74
|
+
async pipe(items, maxConcurrent = 10) {
|
|
75
|
+
const itemQueue = [...items]
|
|
76
|
+
const activePromises = []
|
|
77
|
+
|
|
78
|
+
// Run setup hooks
|
|
79
|
+
await Promise.allSettled(this.#setupHooks.map(hook => hook()))
|
|
80
|
+
|
|
81
|
+
const processNextItem = item => {
|
|
82
|
+
return this.#processItem(item).then(result => {
|
|
83
|
+
// Categorize result
|
|
84
|
+
if(result.status === "success") {
|
|
85
|
+
this.#succeeded.push({input: item, ...result})
|
|
86
|
+
} else if(result.status === "warning") {
|
|
87
|
+
this.#warned.push({input: item, ...result})
|
|
88
|
+
} else {
|
|
89
|
+
this.#errored.push({input: item, ...result})
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
// Process next item if queue has items
|
|
93
|
+
if(itemQueue.length > 0) {
|
|
94
|
+
const nextItem = itemQueue.shift()
|
|
95
|
+
|
|
96
|
+
return processNextItem(nextItem)
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Fill initial concurrent slots
|
|
102
|
+
while(activePromises.length < maxConcurrent && itemQueue.length > 0) {
|
|
103
|
+
const item = itemQueue.shift()
|
|
104
|
+
|
|
105
|
+
activePromises.push(processNextItem(item))
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Wait for all processing to complete
|
|
109
|
+
await Promise.allSettled(activePromises)
|
|
110
|
+
|
|
111
|
+
// Run cleanup hooks
|
|
112
|
+
await Promise.allSettled(this.#cleanupHooks.map(hook => hook()))
|
|
113
|
+
|
|
114
|
+
return {
|
|
115
|
+
succeeded: this.#succeeded,
|
|
116
|
+
warned: this.#warned,
|
|
117
|
+
errored: this.#errored
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Process a single item through all pipeline steps
|
|
123
|
+
*
|
|
124
|
+
* @param {object} item - The item to process
|
|
125
|
+
* @returns {Promise<object>} Result object with status and data
|
|
126
|
+
* @private
|
|
127
|
+
*/
|
|
128
|
+
async #processItem(item) {
|
|
129
|
+
const debug = this.#logger.newDebug()
|
|
130
|
+
const context = {item, data: {}}
|
|
131
|
+
|
|
132
|
+
try {
|
|
133
|
+
// Execute each step in sequence
|
|
134
|
+
for(const step of this.#steps) {
|
|
135
|
+
debug(`Executing step: ${step.name}`, 2)
|
|
136
|
+
|
|
137
|
+
const result = await step.fn(context)
|
|
138
|
+
|
|
139
|
+
// Handle step result
|
|
140
|
+
if(result && typeof result === "object") {
|
|
141
|
+
if(result.status === "error") {
|
|
142
|
+
return result
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
if(result.status === "warning" && step.required) {
|
|
146
|
+
return result
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// Merge result data into context for next steps
|
|
150
|
+
context.data = {...context.data, ...result.data}
|
|
151
|
+
context.status = result.status || context.status
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
return {
|
|
156
|
+
status: context.status || "success",
|
|
157
|
+
...context.data
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
} catch(error) {
|
|
161
|
+
return {
|
|
162
|
+
status: "error",
|
|
163
|
+
error,
|
|
164
|
+
item
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Clear results (useful for reusing pipeline instance)
|
|
171
|
+
*
|
|
172
|
+
* @returns {Piper} The pipeline instance (for chaining)
|
|
173
|
+
*/
|
|
174
|
+
clearResults() {
|
|
175
|
+
this.#succeeded = []
|
|
176
|
+
this.#warned = []
|
|
177
|
+
this.#errored = []
|
|
178
|
+
|
|
179
|
+
return this
|
|
180
|
+
}
|
|
181
|
+
}
|
package/src/lib/Sass.js
CHANGED
|
@@ -102,10 +102,8 @@ export default class Sass extends Error {
|
|
|
102
102
|
* @returns {string|undefined} Formatted stack trace or undefined
|
|
103
103
|
*/
|
|
104
104
|
#fullBodyMassage(stack) {
|
|
105
|
-
// Remove the first line, it's already been reported
|
|
106
|
-
|
|
107
105
|
stack = stack ?? ""
|
|
108
|
-
|
|
106
|
+
// Remove the first line, it's already been reported
|
|
109
107
|
const {rest} = stack.match(/^.*?\n(?<rest>[\s\S]+)$/m)?.groups ?? {}
|
|
110
108
|
const lines = []
|
|
111
109
|
|
|
@@ -114,7 +112,7 @@ export default class Sass extends Error {
|
|
|
114
112
|
...rest
|
|
115
113
|
.split("\n")
|
|
116
114
|
.map(line => {
|
|
117
|
-
const at = line.match(/^\s{4}at\s(?<at>.*)$/)?.groups?.at ??
|
|
115
|
+
const at = line.match(/^\s{4}at\s(?<at>.*)$/)?.groups?.at ?? ""
|
|
118
116
|
|
|
119
117
|
return at
|
|
120
118
|
? `* ${at}`
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file Tantrum.js
|
|
3
|
+
*
|
|
4
|
+
* Defines the Tantrum class, a custom AggregateError type for toolkit
|
|
5
|
+
* that collects multiple errors with Sass-style reporting.
|
|
6
|
+
*
|
|
7
|
+
* Auto-wraps plain Error objects in Sass instances while preserving
|
|
8
|
+
* existing Sass errors, providing consistent formatted output for
|
|
9
|
+
* multiple error scenarios.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
import Sass from "./Sass.js"
|
|
13
|
+
import Term from "./Term.js"
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Custom aggregate error class that extends AggregateError.
|
|
17
|
+
* Automatically wraps plain errors in Sass instances for consistent reporting.
|
|
18
|
+
*/
|
|
19
|
+
export default class Tantrum extends AggregateError {
|
|
20
|
+
/**
|
|
21
|
+
* Creates a new Tantrum instance.
|
|
22
|
+
*
|
|
23
|
+
* @param {string} message - The aggregate error message
|
|
24
|
+
* @param {Array<Error|Sass>} errors - Array of errors to aggregate
|
|
25
|
+
*/
|
|
26
|
+
constructor(message, errors = []) {
|
|
27
|
+
// Auto-wrap plain errors in Sass, keep existing Sass instances
|
|
28
|
+
const wrappedErrors = errors.map(error => {
|
|
29
|
+
if(error instanceof Sass)
|
|
30
|
+
return error
|
|
31
|
+
|
|
32
|
+
if(!(error instanceof Error))
|
|
33
|
+
throw new TypeError(`All items in errors array must be Error instances, got: ${typeof error}`)
|
|
34
|
+
|
|
35
|
+
return Sass.new(error.message, error)
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
super(wrappedErrors, message)
|
|
39
|
+
this.name = "Tantrum"
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Reports all aggregated errors to the terminal with formatted output.
|
|
43
|
+
*
|
|
44
|
+
* @param {boolean} [nerdMode] - Whether to include detailed stack traces
|
|
45
|
+
*/
|
|
46
|
+
report(nerdMode = false) {
|
|
47
|
+
Term.error(
|
|
48
|
+
`${Term.terminalBracket(["error", "Tantrum Incoming"])} (${this.errors.length} errors)\n` +
|
|
49
|
+
this.message
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
Term.error()
|
|
53
|
+
|
|
54
|
+
this.errors.forEach(error => {
|
|
55
|
+
error.report(nerdMode)
|
|
56
|
+
})
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Factory method to create a Tantrum instance.
|
|
61
|
+
*
|
|
62
|
+
* @param {string} message - The aggregate error message
|
|
63
|
+
* @param {Array<Error|Sass>} errors - Array of errors to aggregate
|
|
64
|
+
* @returns {Tantrum} New Tantrum instance
|
|
65
|
+
*/
|
|
66
|
+
static new(message, errors = []) {
|
|
67
|
+
return new Tantrum(message, errors)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Implementation: ../lib/Tantrum.js
|
|
2
|
+
// Type definitions for Tantrum aggregate error class
|
|
3
|
+
|
|
4
|
+
import Sass from './Sass'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Custom aggregate error class that extends AggregateError.
|
|
8
|
+
*
|
|
9
|
+
* Automatically wraps plain Error objects in Sass instances while preserving
|
|
10
|
+
* existing Sass errors, providing consistent formatted reporting for
|
|
11
|
+
* multiple error scenarios.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```typescript
|
|
15
|
+
* // Collect multiple errors and throw as a bundle
|
|
16
|
+
* const errors = [new Error("thing 1"), sassError, new Error("thing 3")]
|
|
17
|
+
* throw Tantrum.new("Multiple validation failures", errors)
|
|
18
|
+
*
|
|
19
|
+
* // Later, in error handling:
|
|
20
|
+
* catch (error) {
|
|
21
|
+
* if (error instanceof Tantrum) {
|
|
22
|
+
* error.report() // Reports all errors with Sass formatting
|
|
23
|
+
* }
|
|
24
|
+
* }
|
|
25
|
+
* ```
|
|
26
|
+
*/
|
|
27
|
+
export default class Tantrum extends AggregateError {
|
|
28
|
+
/**
|
|
29
|
+
* Creates a new Tantrum instance.
|
|
30
|
+
* Plain Error objects are automatically wrapped in Sass instances.
|
|
31
|
+
*
|
|
32
|
+
* @param message - The aggregate error message describing the overall failure
|
|
33
|
+
* @param errors - Array of errors to aggregate (mix of Error and Sass instances allowed)
|
|
34
|
+
*/
|
|
35
|
+
constructor(message: string, errors?: Array<Error | Sass>)
|
|
36
|
+
|
|
37
|
+
/** Name of the error class */
|
|
38
|
+
readonly name: 'Tantrum'
|
|
39
|
+
|
|
40
|
+
/** Array of aggregated errors (all wrapped as Sass instances) */
|
|
41
|
+
readonly errors: Array<Sass>
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Reports all aggregated errors to the terminal with formatted output.
|
|
45
|
+
* Shows a header with error count, then delegates to each Sass instance
|
|
46
|
+
* for individual error reporting.
|
|
47
|
+
*
|
|
48
|
+
* @param nerdMode - Whether to include detailed stack traces in output
|
|
49
|
+
*
|
|
50
|
+
* @example
|
|
51
|
+
* ```typescript
|
|
52
|
+
* try {
|
|
53
|
+
* throw Tantrum.new("Batch failed", [error1, error2])
|
|
54
|
+
* } catch (tantrum) {
|
|
55
|
+
* tantrum.report() // User-friendly output
|
|
56
|
+
* tantrum.report(true) // Includes full stack traces
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
report(nerdMode?: boolean): void
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Factory method to create a Tantrum instance.
|
|
64
|
+
* Follows the same pattern as Sass.new() for consistency.
|
|
65
|
+
*
|
|
66
|
+
* @param message - The aggregate error message
|
|
67
|
+
* @param errors - Array of errors to aggregate
|
|
68
|
+
* @returns New Tantrum instance with all errors wrapped as Sass
|
|
69
|
+
*
|
|
70
|
+
* @example
|
|
71
|
+
* ```typescript
|
|
72
|
+
* // Typical usage pattern
|
|
73
|
+
* throw Tantrum.new("Someone ate all my Runts!", [
|
|
74
|
+
* emptyRuntsBoxError,
|
|
75
|
+
* emptyRuntsBoxError,
|
|
76
|
+
* emptyRuntsBoxError
|
|
77
|
+
* ])
|
|
78
|
+
* ```
|
|
79
|
+
*/
|
|
80
|
+
static new(message: string, errors?: Array<Error | Sass>): Tantrum
|
|
81
|
+
}
|
package/src/types/index.d.ts
CHANGED
|
@@ -10,6 +10,7 @@ export { default as Collection } from './Collection.js'
|
|
|
10
10
|
export { default as Data } from './Data.js'
|
|
11
11
|
export { default as Glog } from './Glog.js'
|
|
12
12
|
export { default as Sass } from './Sass.js'
|
|
13
|
+
export { default as Tantrum } from './Tantrum.js'
|
|
13
14
|
export { default as Term } from './Term.js'
|
|
14
15
|
export { default as Type } from './Type.js'
|
|
15
16
|
export { default as Util } from './Util.js'
|