@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,206 @@
|
|
|
1
|
+
import { setTimeout as timeoutPromise } from "timers/promises"
|
|
2
|
+
import Collection from "./Collection.js"
|
|
3
|
+
import Data from "./Data.js"
|
|
4
|
+
import Sass from "./Sass.js"
|
|
5
|
+
import Valid from "./Valid.js"
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Generic base class for managing hooks with configurable event types.
|
|
9
|
+
* Provides common functionality for hook registration, execution, and lifecycle management.
|
|
10
|
+
* Designed to be extended by specific implementations.
|
|
11
|
+
*/
|
|
12
|
+
export default class BaseHookManager {
|
|
13
|
+
#hooksFile = null
|
|
14
|
+
#log = null
|
|
15
|
+
#hooks = null
|
|
16
|
+
#action = null
|
|
17
|
+
#timeout = 1000 // Default 1 second timeout
|
|
18
|
+
#allowedEvents = []
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {object} config - Configuration object
|
|
22
|
+
* @param {string|object} config.action - Action identifier or instance
|
|
23
|
+
* @param {object} config.hooksFile - File object containing hooks
|
|
24
|
+
* @param {object} config.logger - Logger instance
|
|
25
|
+
* @param {number} [config.timeOut=1000] - Hook execution timeout in milliseconds
|
|
26
|
+
* @param {string[]} [config.allowedEvents=[]] - Array of allowed event types for validation
|
|
27
|
+
*/
|
|
28
|
+
constructor({action, hooksFile, logger, timeOut = 1000, allowedEvents = []}) {
|
|
29
|
+
this.#action = action
|
|
30
|
+
this.#hooksFile = hooksFile
|
|
31
|
+
this.#log = logger
|
|
32
|
+
this.#timeout = timeOut
|
|
33
|
+
this.#allowedEvents = allowedEvents
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
get action() {
|
|
37
|
+
return this.#action
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
get hooksFile() {
|
|
41
|
+
return this.#hooksFile
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
get hooks() {
|
|
45
|
+
return this.#hooks
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
get log() {
|
|
49
|
+
return this.#log
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
get timeout() {
|
|
53
|
+
return this.#timeout
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
get allowedEvents() {
|
|
57
|
+
return this.#allowedEvents
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
get setup() {
|
|
61
|
+
return this.hooks?.setup || null
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
get cleanup() {
|
|
65
|
+
return this.hooks?.cleanup || null
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Static factory method to create and initialize a hook manager.
|
|
70
|
+
* Override loadHooks() in subclasses to customize hook loading logic.
|
|
71
|
+
*
|
|
72
|
+
* @param {object} config - Same as constructor config
|
|
73
|
+
* @returns {Promise<BaseHookManager|null>} Initialized hook manager or null if no hooks found
|
|
74
|
+
*/
|
|
75
|
+
static async new(config) {
|
|
76
|
+
const instance = new this(config)
|
|
77
|
+
const debug = instance.log.newDebug()
|
|
78
|
+
|
|
79
|
+
debug("Creating new HookManager instance with args: `%o`", 2, config)
|
|
80
|
+
|
|
81
|
+
const hooksFile = instance.hooksFile
|
|
82
|
+
|
|
83
|
+
debug("Loading hooks from `%s`", 2, hooksFile.uri)
|
|
84
|
+
|
|
85
|
+
debug("Checking hooks file exists: %j", 2, hooksFile)
|
|
86
|
+
|
|
87
|
+
try {
|
|
88
|
+
const hooksFileContent = await import(hooksFile.uri)
|
|
89
|
+
debug("Hooks file loaded successfully", 2)
|
|
90
|
+
|
|
91
|
+
if (!hooksFileContent)
|
|
92
|
+
throw new Error(`Hooks file is empty: ${hooksFile.uri}`)
|
|
93
|
+
|
|
94
|
+
const hooks = await instance.loadHooks(hooksFileContent)
|
|
95
|
+
|
|
96
|
+
if (Data.isEmpty(hooks))
|
|
97
|
+
return null
|
|
98
|
+
|
|
99
|
+
debug("Hooks found for action: `%s`", 2, instance.action)
|
|
100
|
+
|
|
101
|
+
if (!hooks)
|
|
102
|
+
return null
|
|
103
|
+
|
|
104
|
+
// Attach common properties to hooks
|
|
105
|
+
hooks.log = instance.log
|
|
106
|
+
hooks.timeout = instance.timeout
|
|
107
|
+
instance.#hooks = hooks
|
|
108
|
+
|
|
109
|
+
debug("Hooks loaded successfully for `%s`", 2, instance.action)
|
|
110
|
+
|
|
111
|
+
return instance
|
|
112
|
+
} catch (error) {
|
|
113
|
+
debug("Failed to load hooks: %s", 1, error.message)
|
|
114
|
+
return null
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* Load hooks from the imported hooks file content.
|
|
120
|
+
* Override in subclasses to customize hook loading logic.
|
|
121
|
+
*
|
|
122
|
+
* @param {object} hooksFileContent - Imported hooks file content
|
|
123
|
+
* @returns {Promise<object|null>} Loaded hooks object or null if no hooks found
|
|
124
|
+
* @protected
|
|
125
|
+
*/
|
|
126
|
+
async loadHooks(hooksFileContent) {
|
|
127
|
+
const hooks = hooksFileContent.default || hooksFileContent.Hooks
|
|
128
|
+
|
|
129
|
+
if (!hooks)
|
|
130
|
+
throw new Error(`\`${this.hooksFile.uri}\` contains no hooks.`)
|
|
131
|
+
|
|
132
|
+
// Default implementation: look for hooks by action name
|
|
133
|
+
const hooksObj = hooks[this.action]
|
|
134
|
+
|
|
135
|
+
return hooksObj || null
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
* Trigger a hook by event name.
|
|
140
|
+
*
|
|
141
|
+
* @param {string} event - The type of hook to trigger
|
|
142
|
+
* @param {object} args - The hook arguments as an object
|
|
143
|
+
* @returns {Promise<unknown>} The result of the hook
|
|
144
|
+
*/
|
|
145
|
+
async on(event, args) {
|
|
146
|
+
const debug = this.log.newDebug()
|
|
147
|
+
|
|
148
|
+
debug("Triggering hook for event `%s`", 4, event)
|
|
149
|
+
|
|
150
|
+
if (!event)
|
|
151
|
+
throw new Error("Event type is required for hook invocation")
|
|
152
|
+
|
|
153
|
+
// Validate event type if allowed events are configured
|
|
154
|
+
if (this.#allowedEvents.length > 0 && !this.#allowedEvents.includes(event))
|
|
155
|
+
throw new Error(`Invalid event type: ${event}. Allowed events: ${this.#allowedEvents.join(", ")}`)
|
|
156
|
+
|
|
157
|
+
const hook = this.hooks?.[event]
|
|
158
|
+
|
|
159
|
+
if (hook) {
|
|
160
|
+
Valid.type(hook, "function", `Hook "${event}" is not a function`)
|
|
161
|
+
|
|
162
|
+
const hookExecution = hook.call(this.hooks, args)
|
|
163
|
+
const hookTimeout = this.timeout
|
|
164
|
+
|
|
165
|
+
const expireAsync = () =>
|
|
166
|
+
timeoutPromise(
|
|
167
|
+
hookTimeout,
|
|
168
|
+
new Error(`Hook execution exceeded timeout of ${hookTimeout}ms`)
|
|
169
|
+
)
|
|
170
|
+
|
|
171
|
+
const result = await Promise.race([hookExecution, expireAsync()])
|
|
172
|
+
|
|
173
|
+
if (result?.status === "error")
|
|
174
|
+
throw Sass.new(result.error)
|
|
175
|
+
|
|
176
|
+
debug("Hook executed successfully for event: `%s`", 4, event)
|
|
177
|
+
|
|
178
|
+
return result
|
|
179
|
+
} else {
|
|
180
|
+
debug("No hook found for event: `%s`", 4, event)
|
|
181
|
+
return null
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Check if a hook exists for the given event.
|
|
187
|
+
*
|
|
188
|
+
* @param {string} event - Event name to check
|
|
189
|
+
* @returns {boolean} True if hook exists
|
|
190
|
+
*/
|
|
191
|
+
hasHook(event) {
|
|
192
|
+
return !!(this.hooks?.[event])
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
/**
|
|
196
|
+
* Get all available hook events.
|
|
197
|
+
*
|
|
198
|
+
* @returns {string[]} Array of available hook event names
|
|
199
|
+
*/
|
|
200
|
+
getAvailableEvents() {
|
|
201
|
+
return this.hooks ? Object.keys(this.hooks).filter(key =>
|
|
202
|
+
typeof this.hooks[key] === 'function' &&
|
|
203
|
+
!['setup', 'cleanup', 'log', 'timeout'].includes(key)
|
|
204
|
+
) : []
|
|
205
|
+
}
|
|
206
|
+
}
|
package/src/lib/Glog.js
CHANGED
|
@@ -1,136 +1,374 @@
|
|
|
1
1
|
import Data from "./Data.js"
|
|
2
|
-
import
|
|
2
|
+
import Util from "./Util.js"
|
|
3
|
+
import c from "@gesslar/colours"
|
|
4
|
+
import Term from "./Term.js"
|
|
5
|
+
// ErrorStackParser will be dynamically imported when needed
|
|
3
6
|
|
|
4
7
|
/**
|
|
5
|
-
* Global logging utility
|
|
6
|
-
* Provides a flexible logging system that can be used as both a class and
|
|
7
|
-
* a callable function, with support for log level filtering and custom
|
|
8
|
-
* prefixes for better log organization.
|
|
8
|
+
* Enhanced Global logging utility that combines simple logging with advanced Logger features.
|
|
9
9
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* // Log messages with different levels
|
|
18
|
-
* Glog(0, 'Critical error') // Always shown
|
|
19
|
-
* Glog(2, 'Debug info') // Shown if logLevel >= 2
|
|
20
|
-
* Glog('Simple message') // Level 0 by default
|
|
10
|
+
* Can be used in multiple ways:
|
|
11
|
+
* 1. Simple function call: Glog(data)
|
|
12
|
+
* 2. With levels: Glog(2, "debug message")
|
|
13
|
+
* 3. Configured instance: new Glog(options)
|
|
14
|
+
* 4. Fluent setup: Glog.create().withName("App").withColors()
|
|
15
|
+
* 5. Traditional logger: logger.debug("message", level)
|
|
21
16
|
*/
|
|
17
|
+
|
|
18
|
+
// Enhanced color system using @gesslar/colours
|
|
19
|
+
export const loggerColours = {
|
|
20
|
+
debug: [
|
|
21
|
+
"{F019}", // Debug level 0: Dark blue
|
|
22
|
+
"{F027}", // Debug level 1: Medium blue
|
|
23
|
+
"{F033}", // Debug level 2: Light blue
|
|
24
|
+
"{F039}", // Debug level 3: Teal
|
|
25
|
+
"{F044}", // Debug level 4: Blue-tinted cyan
|
|
26
|
+
],
|
|
27
|
+
info: "{F036}", // Medium Spring Green
|
|
28
|
+
warn: "{F214}", // Orange1
|
|
29
|
+
error: "{F196}", // Red1
|
|
30
|
+
reset: "{/}", // Reset
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
// Set up convenient aliases for common log colors
|
|
34
|
+
c.alias.set("debug", "{F033}")
|
|
35
|
+
c.alias.set("info", "{F036}")
|
|
36
|
+
c.alias.set("warn", "{F214}")
|
|
37
|
+
c.alias.set("error", "{F196}")
|
|
38
|
+
c.alias.set("success", "{F046}")
|
|
39
|
+
c.alias.set("muted", "{F244}")
|
|
40
|
+
c.alias.set("bold", "{<B}")
|
|
41
|
+
c.alias.set("dim", "{<D}")
|
|
42
|
+
|
|
22
43
|
class Glog {
|
|
23
|
-
|
|
44
|
+
// Static properties (for global usage)
|
|
24
45
|
static logLevel = 0
|
|
25
|
-
/** @type {string} Prefix to prepend to all log messages */
|
|
26
46
|
static logPrefix = ""
|
|
47
|
+
static colors = null
|
|
48
|
+
static stackTrace = false
|
|
49
|
+
static name = ""
|
|
50
|
+
|
|
51
|
+
// Instance properties (for configured loggers)
|
|
52
|
+
#logLevel = 0
|
|
53
|
+
#logPrefix = ""
|
|
54
|
+
#colors = null
|
|
55
|
+
#stackTrace = false
|
|
56
|
+
#name = ""
|
|
57
|
+
#vscodeError = null
|
|
58
|
+
#vscodeWarn = null
|
|
59
|
+
#vscodeInfo = null
|
|
60
|
+
|
|
61
|
+
constructor(options = {}) {
|
|
62
|
+
this.setOptions(options)
|
|
63
|
+
|
|
64
|
+
// VSCode integration if specified
|
|
65
|
+
if(options.env === "extension") {
|
|
66
|
+
try {
|
|
67
|
+
const vscode = require("vscode")
|
|
68
|
+
|
|
69
|
+
this.#vscodeError = vscode.window.showErrorMessage
|
|
70
|
+
this.#vscodeWarn = vscode.window.showWarningMessage
|
|
71
|
+
this.#vscodeInfo = vscode.window.showInformationMessage
|
|
72
|
+
} catch {
|
|
73
|
+
// VSCode not available, ignore
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// === CONFIGURATION METHODS ===
|
|
79
|
+
|
|
80
|
+
setOptions(options) {
|
|
81
|
+
this.#name = options.name ?? this.#name
|
|
82
|
+
this.#logLevel = options.debugLevel ?? options.logLevel ?? this.#logLevel
|
|
83
|
+
this.#logPrefix = options.prefix ?? this.#logPrefix
|
|
84
|
+
this.#colors = options.colors ?? this.#colors
|
|
85
|
+
this.#stackTrace = options.stackTrace ?? this.#stackTrace
|
|
86
|
+
|
|
87
|
+
return this
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// === STATIC CONFIGURATION (for global usage) ===
|
|
27
91
|
|
|
28
|
-
/**
|
|
29
|
-
* Sets the log prefix for all subsequent log messages.
|
|
30
|
-
* The prefix helps identify the source of log messages in complex
|
|
31
|
-
* applications with multiple components.
|
|
32
|
-
*
|
|
33
|
-
* @param {string} prefix - The prefix string to prepend to log messages
|
|
34
|
-
* @returns {typeof Glog} Returns the Glog class for method chaining
|
|
35
|
-
* @example
|
|
36
|
-
* Glog.setLogPrefix('[Database]')
|
|
37
|
-
* Glog('Connection established') // Output: [Database] Connection established
|
|
38
|
-
*/
|
|
39
92
|
static setLogPrefix(prefix) {
|
|
40
93
|
this.logPrefix = prefix
|
|
41
94
|
|
|
42
95
|
return this
|
|
43
96
|
}
|
|
44
97
|
|
|
45
|
-
/**
|
|
46
|
-
* Sets the minimum log level for messages to be displayed.
|
|
47
|
-
* Messages with a level higher than this threshold will be filtered out.
|
|
48
|
-
* Log levels range from 0 (critical) to 5 (verbose debug).
|
|
49
|
-
*
|
|
50
|
-
* @param {number} level - The minimum log level (0-5, clamped to range)
|
|
51
|
-
* @returns {typeof Glog} Returns the Glog class for method chaining
|
|
52
|
-
* @example
|
|
53
|
-
* Glog.setLogLevel(2) // Only show messages with level 0, 1, or 2
|
|
54
|
-
* Glog(1, 'Important') // Shown
|
|
55
|
-
* Glog(3, 'Verbose') // Hidden
|
|
56
|
-
*/
|
|
57
98
|
static setLogLevel(level) {
|
|
58
99
|
this.logLevel = Data.clamp(level, 0, 5)
|
|
59
100
|
|
|
60
101
|
return this
|
|
61
102
|
}
|
|
62
103
|
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
104
|
+
static withName(name) {
|
|
105
|
+
this.name = name
|
|
106
|
+
|
|
107
|
+
return this
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
static withColors(colors = loggerColours) {
|
|
111
|
+
this.colors = colors
|
|
112
|
+
|
|
113
|
+
return this
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
static withStackTrace(enabled = true) {
|
|
117
|
+
this.stackTrace = enabled
|
|
118
|
+
|
|
119
|
+
return this
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// === FLUENT INSTANCE CREATION ===
|
|
123
|
+
|
|
124
|
+
static create(options = {}) {
|
|
125
|
+
return new Glog(options)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
withName(name) {
|
|
129
|
+
this.#name = name
|
|
130
|
+
|
|
131
|
+
return this
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
withLogLevel(level) {
|
|
135
|
+
this.#logLevel = level
|
|
136
|
+
|
|
137
|
+
return this
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
withPrefix(prefix) {
|
|
141
|
+
this.#logPrefix = prefix
|
|
142
|
+
|
|
143
|
+
return this
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
withColors(colors = loggerColours) {
|
|
147
|
+
this.#colors = colors
|
|
148
|
+
|
|
149
|
+
return this
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
withStackTrace(enabled = true) {
|
|
153
|
+
this.#stackTrace = enabled
|
|
154
|
+
|
|
155
|
+
return this
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// === UTILITY METHODS ===
|
|
159
|
+
|
|
160
|
+
get name() {
|
|
161
|
+
return this.#name
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
get debugLevel() {
|
|
165
|
+
return this.#logLevel
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
get options() {
|
|
169
|
+
return {
|
|
170
|
+
name: this.#name,
|
|
171
|
+
debugLevel: this.#logLevel,
|
|
172
|
+
prefix: this.#logPrefix,
|
|
173
|
+
colors: this.#colors,
|
|
174
|
+
stackTrace: this.#stackTrace
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
#compose(level, message, debugLevel = 0) {
|
|
179
|
+
const colors = this.#colors || Glog.colors || loggerColours
|
|
180
|
+
const name = this.#name || Glog.name || "Log"
|
|
181
|
+
const tag = Util.capitalize(level)
|
|
182
|
+
|
|
183
|
+
if(!colors) {
|
|
184
|
+
return `[${name}] ${tag}: ${message}`
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
if(level === "debug") {
|
|
188
|
+
const colorCode = colors[level][debugLevel] || colors[level][0]
|
|
189
|
+
|
|
190
|
+
return c`[${name}] ${colorCode}${tag}{/}: ${message}`
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
return c`[${name}] ${colors[level]}${tag}{/}: ${message}`
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Stack trace functionality - simplified for now
|
|
197
|
+
extractFileFunction() {
|
|
198
|
+
// Simple fallback - just return a basic tag
|
|
199
|
+
return "caller"
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
newDebug(tag) {
|
|
203
|
+
return function(message, level, ...arg) {
|
|
204
|
+
if(this.#stackTrace || Glog.stackTrace) {
|
|
205
|
+
tag = this.extractFileFunction()
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
this.debug(`[${tag}] ${message}`, level, ...arg)
|
|
209
|
+
}.bind(this)
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
// === LOGGING METHODS ===
|
|
213
|
+
|
|
214
|
+
#log(...args) {
|
|
215
|
+
let level, rest
|
|
216
|
+
|
|
217
|
+
if(args.length === 0) {
|
|
218
|
+
[level = 0, rest = [""]] = []
|
|
219
|
+
} else if(args.length === 1) {
|
|
220
|
+
[rest, level = 0] = [args, 0]
|
|
221
|
+
} else {
|
|
222
|
+
[level, ...rest] = typeof args[0] === "number" ? args : [0, ...args]
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
const currentLevel = this.#logLevel || Glog.logLevel
|
|
226
|
+
|
|
227
|
+
if(level > currentLevel)
|
|
228
|
+
return
|
|
229
|
+
|
|
230
|
+
const prefix = this.#logPrefix || Glog.logPrefix
|
|
231
|
+
|
|
232
|
+
if(prefix) {
|
|
233
|
+
Term.log(prefix, ...rest)
|
|
234
|
+
} else {
|
|
235
|
+
Term.log(...rest)
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Traditional logger methods
|
|
240
|
+
debug(message, level = 0, ...arg) {
|
|
241
|
+
const currentLevel = this.#logLevel || Glog.logLevel
|
|
242
|
+
|
|
243
|
+
if(level <= currentLevel) {
|
|
244
|
+
Term.debug(this.#compose("debug", message, level), ...arg)
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
info(message, ...arg) {
|
|
249
|
+
Term.info(this.#compose("info", message), ...arg)
|
|
250
|
+
this.#vscodeInfo?.(JSON.stringify(message))
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
warn(message, ...arg) {
|
|
254
|
+
Term.warn(this.#compose("warn", message), ...arg)
|
|
255
|
+
this.#vscodeWarn?.(JSON.stringify(message))
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
error(message, ...arg) {
|
|
259
|
+
Term.error(this.#compose("error", message), ...arg)
|
|
260
|
+
this.#vscodeError?.(JSON.stringify(message))
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Core execute method for simple usage
|
|
264
|
+
static execute(...args) {
|
|
265
|
+
// Use static properties for global calls
|
|
75
266
|
let level, rest
|
|
76
267
|
|
|
77
268
|
if(args.length === 0) {
|
|
78
|
-
|
|
269
|
+
[level = 0, rest = [""]] = []
|
|
79
270
|
} else if(args.length === 1) {
|
|
80
|
-
|
|
271
|
+
[rest, level = 0] = [args, 0]
|
|
81
272
|
} else {
|
|
82
|
-
|
|
273
|
+
[level, ...rest] = typeof args[0] === "number" ? args : [0, ...args]
|
|
83
274
|
}
|
|
84
275
|
|
|
85
276
|
if(level > this.logLevel)
|
|
86
277
|
return
|
|
87
278
|
|
|
88
|
-
if(this.logPrefix)
|
|
89
|
-
|
|
90
|
-
else
|
|
91
|
-
|
|
279
|
+
if(this.logPrefix) {
|
|
280
|
+
Term.log(this.logPrefix, ...rest)
|
|
281
|
+
} else {
|
|
282
|
+
Term.log(...rest)
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
// Instance execute for configured loggers
|
|
287
|
+
execute(...args) {
|
|
288
|
+
this.#log(...args)
|
|
92
289
|
}
|
|
93
290
|
|
|
291
|
+
// === ENHANCED METHODS WITH @gesslar/colours ===
|
|
292
|
+
|
|
94
293
|
/**
|
|
95
|
-
*
|
|
96
|
-
* This method serves as the entry point for all logging operations,
|
|
97
|
-
* delegating to the private #log method for actual processing.
|
|
294
|
+
* Log a colorized message using template literals
|
|
98
295
|
*
|
|
99
|
-
* @param {
|
|
100
|
-
* @
|
|
101
|
-
* @example
|
|
102
|
-
* Glog.execute(0, 'Error:', error.message)
|
|
103
|
-
* Glog.execute('Simple message') // Level 0 assumed
|
|
296
|
+
* @param {Array<string>} strings - Template strings
|
|
297
|
+
* @param {...unknown} values - Template values
|
|
298
|
+
* @example logger.colorize`{success}Operation completed{/} in {bold}${time}ms{/}`
|
|
104
299
|
*/
|
|
105
|
-
|
|
106
|
-
|
|
300
|
+
colorize(strings, ...values) {
|
|
301
|
+
const message = c(strings, ...values)
|
|
302
|
+
const name = this.#name || Glog.name || "Log"
|
|
303
|
+
|
|
304
|
+
Term.log(`[${name}] ${message}`)
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
/**
|
|
308
|
+
* Static version of colorize for global usage
|
|
309
|
+
*
|
|
310
|
+
* @param {Array<string>} strings - Template strings
|
|
311
|
+
* @param {...unknown} values - Template values
|
|
312
|
+
*/
|
|
313
|
+
static colorize(strings, ...values) {
|
|
314
|
+
const message = c(strings, ...values)
|
|
315
|
+
const name = this.name || "Log"
|
|
316
|
+
|
|
317
|
+
Term.log(`[${name}] ${message}`)
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Log a success message with green color
|
|
322
|
+
*
|
|
323
|
+
* @param {string} message - Success message
|
|
324
|
+
* @param {...unknown} args - Additional arguments
|
|
325
|
+
*/
|
|
326
|
+
success(message, ...args) {
|
|
327
|
+
Term.log(c`[${this.#name || Glog.name || "Log"}] {success}Success{/}: ${message}`, ...args)
|
|
328
|
+
}
|
|
329
|
+
|
|
330
|
+
/**
|
|
331
|
+
* Static success method
|
|
332
|
+
*
|
|
333
|
+
* @param {string} message - Success message to log
|
|
334
|
+
* @param {...unknown} args - Additional arguments to log
|
|
335
|
+
*/
|
|
336
|
+
static success(message, ...args) {
|
|
337
|
+
Term.log(c`[${this.name || "Log"}] {success}Success{/}: ${message}`, ...args)
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Set a color alias for convenient usage
|
|
342
|
+
*
|
|
343
|
+
* @param {string} alias - Alias name
|
|
344
|
+
* @param {string} colorCode - Color code (e.g., "{F196}" or "{<B}")
|
|
345
|
+
* @returns {Glog} The Glog class for chaining.
|
|
346
|
+
*/
|
|
347
|
+
static setAlias(alias, colorCode) {
|
|
348
|
+
c.alias.set(alias, colorCode)
|
|
349
|
+
|
|
350
|
+
return this
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Get access to the colours template function for instance usage
|
|
355
|
+
*
|
|
356
|
+
* @returns {import('@gesslar/colours')} The colours template function from \@gesslar/colours
|
|
357
|
+
*/
|
|
358
|
+
get colours() {
|
|
359
|
+
return c
|
|
107
360
|
}
|
|
108
361
|
}
|
|
109
362
|
|
|
110
|
-
|
|
111
|
-
* Global logging utility with proxy-based dual interface.
|
|
112
|
-
* Can be used as both a class and a function for maximum flexibility.
|
|
113
|
-
*
|
|
114
|
-
* @class Glog
|
|
115
|
-
* @example
|
|
116
|
-
* // Use as function
|
|
117
|
-
* Glog('Hello world')
|
|
118
|
-
* Glog(2, 'Debug message')
|
|
119
|
-
*
|
|
120
|
-
* // Use class methods
|
|
121
|
-
* Glog.setLogLevel(3).setLogPrefix('[App]')
|
|
122
|
-
*/
|
|
123
|
-
// Wrap the class in a proxy
|
|
363
|
+
// Wrap in proxy for dual usage
|
|
124
364
|
export default new Proxy(Glog, {
|
|
125
365
|
apply(target, thisArg, argumentsList) {
|
|
126
|
-
// When called as function: call execute method internally
|
|
127
366
|
return target.execute(...argumentsList)
|
|
128
367
|
},
|
|
129
368
|
construct(target, argumentsList) {
|
|
130
369
|
return new target(...argumentsList)
|
|
131
370
|
},
|
|
132
371
|
get(target, prop) {
|
|
133
|
-
// Hide execute method from public API
|
|
134
372
|
if(prop === "execute") {
|
|
135
373
|
return undefined
|
|
136
374
|
}
|