@nu-art/logger 0.401.1

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/debug-flags.js ADDED
@@ -0,0 +1,196 @@
1
+ /*
2
+ * @nu-art/logger - Flexible logging infrastructure with multiple output targets
3
+ * Copyright (C) 2024 Adam van der Kruk aka TacB0sS
4
+ * Licensed under the Apache License, Version 2.0
5
+ */
6
+ import { LogLevel, LogLevelOrdinal } from './types.js';
7
+ /**
8
+ * Represents a debug flag that controls logging for a specific logger tag.
9
+ *
10
+ * Each DebugFlag controls two aspects of logging:
11
+ * 1. **Enabled state**: Whether logging is active for this flag
12
+ * 2. **Minimum log level**: The lowest log level that will be output
13
+ *
14
+ * DebugFlags are automatically registered with the DebugFlags singleton when created.
15
+ * They are typically created automatically by Logger instances using the logger's tag.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * // Created automatically by Logger
20
+ * const logger = new Logger('MyService');
21
+ * // logger._DEBUG_FLAG is a DebugFlag with key 'MyService'
22
+ *
23
+ * // Or manually
24
+ * const flag = DebugFlags.createFlag('CustomTag', LogLevel.Debug);
25
+ * flag.enable();
26
+ * flag.setMinLevel(LogLevel.Warning);
27
+ * ```
28
+ */
29
+ export class DebugFlag {
30
+ /** Default minimum log level for new debug flags */
31
+ static DefaultLogLevel = LogLevel.Info;
32
+ /** Unique identifier for this debug flag (typically matches logger tag) */
33
+ key;
34
+ /** Minimum log level that will be output when this flag is enabled */
35
+ minLogLevel;
36
+ /**
37
+ * Creates a new DebugFlag and automatically registers it with DebugFlags.
38
+ *
39
+ * @param key - Unique identifier for this flag
40
+ * @param minLogLevel - Minimum log level (defaults to DebugFlag.DefaultLogLevel)
41
+ */
42
+ constructor(key, minLogLevel = DebugFlag.DefaultLogLevel) {
43
+ this.key = key;
44
+ this.minLogLevel = minLogLevel;
45
+ DebugFlags.add(this);
46
+ }
47
+ /**
48
+ * Sets the minimum log level for this flag.
49
+ *
50
+ * Only log messages at or above this level will be output when the flag is enabled.
51
+ *
52
+ * @param minLogLevel - Minimum log level (Verbose < Debug < Info < Warning < Error)
53
+ */
54
+ setMinLevel(minLogLevel) {
55
+ this.minLogLevel = minLogLevel;
56
+ }
57
+ /**
58
+ * Renames this debug flag (updates the key).
59
+ *
60
+ * Useful when a logger's tag changes. Updates the registration in DebugFlags.
61
+ *
62
+ * @param newKey - New key/identifier for this flag
63
+ */
64
+ rename(newKey) {
65
+ const oldKey = this.key;
66
+ DebugFlags.rename(oldKey, newKey);
67
+ this.key = newKey;
68
+ // Update ActiveDebugFlags if the flag is enabled
69
+ const activeIndex = DebugFlags.instance.ActiveDebugFlags.indexOf(oldKey);
70
+ if (activeIndex > -1) {
71
+ DebugFlags.instance.ActiveDebugFlags[activeIndex] = newKey;
72
+ }
73
+ }
74
+ /**
75
+ * Gets the unique key/identifier for this flag.
76
+ */
77
+ getKey() {
78
+ return this.key;
79
+ }
80
+ /**
81
+ * Enables or disables this debug flag.
82
+ *
83
+ * When disabled, all logging for this flag is suppressed regardless of log level.
84
+ * When enabled, logging is controlled by the minimum log level.
85
+ *
86
+ * @param enable - If true, enables the flag. If false, disables it. Defaults to true.
87
+ */
88
+ enable(enable = true) {
89
+ if (this.isEnabled() === enable)
90
+ return;
91
+ if (enable)
92
+ this._enable();
93
+ else
94
+ this._disable();
95
+ }
96
+ /**
97
+ * Checks if this debug flag is currently enabled.
98
+ *
99
+ * @returns true if enabled, false otherwise
100
+ */
101
+ isEnabled() {
102
+ return DebugFlags.instance.ActiveDebugFlags.includes(this.key);
103
+ }
104
+ /**
105
+ * Checks if a log message at the given level should be output.
106
+ *
107
+ * Returns true if:
108
+ * - The flag is enabled, AND
109
+ * - The log level is at or above the minimum log level
110
+ *
111
+ * @param level - Log level to check
112
+ * @returns true if the message should be logged, false otherwise
113
+ */
114
+ canLog(level) {
115
+ if (!this.isEnabled())
116
+ return false;
117
+ return LogLevelOrdinal.indexOf(level) >= LogLevelOrdinal.indexOf(this.minLogLevel);
118
+ }
119
+ /**
120
+ * Enables this flag by adding it to the active flags list.
121
+ */
122
+ _enable() {
123
+ DebugFlags.instance.ActiveDebugFlags.push(this.key);
124
+ }
125
+ /**
126
+ * Disables this flag by removing it from the active flags list.
127
+ */
128
+ _disable() {
129
+ const index = DebugFlags.instance.ActiveDebugFlags.indexOf(this.key);
130
+ if (index > -1)
131
+ DebugFlags.instance.ActiveDebugFlags.splice(index, 1);
132
+ }
133
+ }
134
+ /**
135
+ * Singleton manager for all debug flags in the application.
136
+ *
137
+ * Maintains a registry of all DebugFlag instances and tracks which flags are
138
+ * currently active (enabled). Provides factory methods for creating flags.
139
+ *
140
+ * DebugFlags are used throughout the application to control logging granularity
141
+ * - you can enable/disable logging for specific modules or services by toggling
142
+ * their associated debug flags.
143
+ */
144
+ export class DebugFlags {
145
+ /** Singleton instance of DebugFlags */
146
+ static instance = new DebugFlags();
147
+ /** Registry of all debug flags, keyed by their identifier */
148
+ AllDebugFlags = {};
149
+ /** List of keys for currently enabled (active) debug flags */
150
+ ActiveDebugFlags = [];
151
+ /**
152
+ * Private constructor enforces singleton pattern.
153
+ */
154
+ constructor() {
155
+ }
156
+ /**
157
+ * Creates a new DebugFlag and registers it.
158
+ *
159
+ * This is the only way to create DebugFlag instances (constructor is private).
160
+ * The flag is automatically registered in AllDebugFlags.
161
+ *
162
+ * @param key - Unique identifier for the flag
163
+ * @param minLogLevel - Minimum log level (defaults to DebugFlag.DefaultLogLevel)
164
+ * @returns The newly created DebugFlag
165
+ */
166
+ static createFlag(key, minLogLevel = DebugFlag.DefaultLogLevel) {
167
+ // @ts-ignore
168
+ return new DebugFlag(key, minLogLevel);
169
+ }
170
+ /**
171
+ * Registers a debug flag in the AllDebugFlags registry.
172
+ *
173
+ * Called automatically when a DebugFlag is created. Should not be called directly.
174
+ *
175
+ * @param flag - DebugFlag to register
176
+ */
177
+ static add(flag) {
178
+ this.instance.AllDebugFlags[flag.getKey()] = flag;
179
+ }
180
+ /**
181
+ * Renames a debug flag by updating its key in the registry.
182
+ *
183
+ * Moves the flag from the old key to the new key in AllDebugFlags.
184
+ * Also updates the flag's internal key via the flag's rename method.
185
+ *
186
+ * @param previousKey - Current key of the flag
187
+ * @param newKey - New key for the flag
188
+ */
189
+ static rename(previousKey, newKey) {
190
+ const flag = this.instance.AllDebugFlags[previousKey];
191
+ if (!flag)
192
+ return;
193
+ delete this.instance.AllDebugFlags[previousKey];
194
+ this.instance.AllDebugFlags[newKey] = flag;
195
+ }
196
+ }
@@ -0,0 +1,27 @@
1
+ /**
2
+ * CSS style properties for console.log() styling.
3
+ *
4
+ * Used with the `%c` format specifier in console.log() to apply CSS styles.
5
+ */
6
+ export type LogStyle = {
7
+ 'color'?: string;
8
+ 'background-color'?: string;
9
+ 'padding'?: string;
10
+ 'border-radius'?: string;
11
+ };
12
+ /**
13
+ * Generates a CSS style string for console.log() formatting.
14
+ *
15
+ * Combines multiple style objects into a single CSS string compatible with
16
+ * the `%c` format specifier in console.log().
17
+ *
18
+ * **Usage**:
19
+ * ```typescript
20
+ * const style = getLogStyle({color: 'red', 'background-color': 'yellow'});
21
+ * console.log('%cStyled text', style, 'normal text');
22
+ * ```
23
+ *
24
+ * @param styleObj - One or more style objects (merged together)
25
+ * @returns CSS style string
26
+ */
27
+ export declare function getLogStyle(...styleObj: LogStyle[]): string;
@@ -0,0 +1,29 @@
1
+ /*
2
+ * @nu-art/logger - Flexible logging infrastructure with multiple output targets
3
+ * Copyright (C) 2024 Adam van der Kruk aka TacB0sS
4
+ * Licensed under the Apache License, Version 2.0
5
+ */
6
+ /**
7
+ * Generates a CSS style string for console.log() formatting.
8
+ *
9
+ * Combines multiple style objects into a single CSS string compatible with
10
+ * the `%c` format specifier in console.log().
11
+ *
12
+ * **Usage**:
13
+ * ```typescript
14
+ * const style = getLogStyle({color: 'red', 'background-color': 'yellow'});
15
+ * console.log('%cStyled text', style, 'normal text');
16
+ * ```
17
+ *
18
+ * @param styleObj - One or more style objects (merged together)
19
+ * @returns CSS style string
20
+ */
21
+ export function getLogStyle(...styleObj) {
22
+ let style = '';
23
+ styleObj.forEach(obj => {
24
+ const _arr = Object.keys(obj).map((key) => `${key}: ${obj[key]}`);
25
+ style += _arr.join(';');
26
+ style += ';';
27
+ });
28
+ return style;
29
+ }
package/index.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ export * from './Logger.js';
2
+ export * from './BeLogged.js';
3
+ export * from './LogClient.js';
4
+ export * from './types.js';
5
+ export * from './debug-flags.js';
6
+ export * from './LogClient_Terminal.js';
7
+ export * from './LogClient_Browser.js';
8
+ export * from './LogClient_BrowserGroups.js';
9
+ export * from './LogClient_File.js';
10
+ export * from './LogClient_MemBuffer.js';
11
+ export * from './LogClient_Function.js';
12
+ export * from './LogClient_ConsoleProxy.js';
13
+ export * from './LogClient_BaseRotate.js';
14
+ export * from './get-log-style.js';
15
+ export * from './utils.js';
package/index.js ADDED
@@ -0,0 +1,20 @@
1
+ /*
2
+ * @nu-art/logger - Flexible logging infrastructure with multiple output targets
3
+ * Copyright (C) 2024 Adam van der Kruk aka TacB0sS
4
+ * Licensed under the Apache License, Version 2.0
5
+ */
6
+ export * from './Logger.js';
7
+ export * from './BeLogged.js';
8
+ export * from './LogClient.js';
9
+ export * from './types.js';
10
+ export * from './debug-flags.js';
11
+ export * from './LogClient_Terminal.js';
12
+ export * from './LogClient_Browser.js';
13
+ export * from './LogClient_BrowserGroups.js';
14
+ export * from './LogClient_File.js';
15
+ export * from './LogClient_MemBuffer.js';
16
+ export * from './LogClient_Function.js';
17
+ export * from './LogClient_ConsoleProxy.js';
18
+ export * from './LogClient_BaseRotate.js';
19
+ export * from './get-log-style.js';
20
+ export * from './utils.js';
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "@nu-art/logger",
3
+ "version": "0.401.1",
4
+ "description": "Flexible logging infrastructure with multiple output targets, debug flags, and log rotation support",
5
+ "type": "module",
6
+ "keywords": [
7
+ "typescript",
8
+ "logging",
9
+ "logger",
10
+ "log-client",
11
+ "debug-flags",
12
+ "log-rotation",
13
+ "nu-art",
14
+ "thunderstorm"
15
+ ],
16
+ "homepage": "https://github.com/nu-art-js/thunderstorm",
17
+ "bugs": {
18
+ "url": "https://github.com/nu-art-js/thunderstorm/issues?q=is%3Aissue+label%3Alogger"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "git+ssh://git@github.com:nu-art-js/thunderstorm.git",
23
+ "directory": "_thunderstorm/logger"
24
+ },
25
+ "publishConfig": {
26
+ "directory": "dist"
27
+ },
28
+ "license": "Apache-2.0",
29
+ "author": "TacB0sS",
30
+ "scripts": {
31
+ "build": "tsc",
32
+ "typedocs": "typedoc --options typedoc.json",
33
+ "run-tests": "ts-mocha --timeout 50000 -p src/test/tsconfig.json src/test/run-all-tests.ts"
34
+ },
35
+ "dependencies": {},
36
+ "devDependencies": {
37
+ "@nu-art/testalot": "0.401.1"
38
+ },
39
+ "unitConfig": {
40
+ "type": "typescript-lib"
41
+ },
42
+ "exports": {
43
+ ".": {
44
+ "types": "./index.d.ts",
45
+ "import": "./index.js"
46
+ },
47
+ "./testing": {
48
+ "types": "./testing/index.d.ts",
49
+ "import": "./testing/index.js"
50
+ }
51
+ }
52
+ }
package/types.d.ts ADDED
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Log levels ordered from most verbose (lowest priority) to least verbose (highest priority).
3
+ *
4
+ * Used for filtering and controlling log output granularity.
5
+ */
6
+ export declare enum LogLevel {
7
+ Verbose = "Verbose",
8
+ Debug = "Debug",
9
+ Info = "Info",
10
+ Warning = "Warning",
11
+ Error = "Error"
12
+ }
13
+ /**
14
+ * Array of log levels in ordinal order (least to most severe).
15
+ *
16
+ * Used for comparisons and determining if a log level meets a threshold.
17
+ */
18
+ export declare const LogLevelOrdinal: LogLevel[];
19
+ /**
20
+ * Function type that composes the prefix string for log messages.
21
+ *
22
+ * The prefix typically includes timestamp, log level indicator, and tag.
23
+ *
24
+ * @param tag - Logger tag/identifier
25
+ * @param level - Log level
26
+ * @returns Formatted prefix string
27
+ */
28
+ export type LogPrefixComposer = (tag: string, level: LogLevel) => string;
29
+ /**
30
+ * Type for log message parameters - can be any value that can be logged.
31
+ */
32
+ export type LogParam = string | boolean | number | object | any[] | Error | undefined | null | symbol | bigint;
package/types.js ADDED
@@ -0,0 +1,30 @@
1
+ /*
2
+ * @nu-art/logger - Flexible logging infrastructure with multiple output targets
3
+ * Copyright (C) 2024 Adam van der Kruk aka TacB0sS
4
+ * Licensed under the Apache License, Version 2.0
5
+ */
6
+ /**
7
+ * Log levels ordered from most verbose (lowest priority) to least verbose (highest priority).
8
+ *
9
+ * Used for filtering and controlling log output granularity.
10
+ */
11
+ export var LogLevel;
12
+ (function (LogLevel) {
13
+ LogLevel["Verbose"] = "Verbose";
14
+ LogLevel["Debug"] = "Debug";
15
+ LogLevel["Info"] = "Info";
16
+ LogLevel["Warning"] = "Warning";
17
+ LogLevel["Error"] = "Error";
18
+ })(LogLevel || (LogLevel = {}));
19
+ /**
20
+ * Array of log levels in ordinal order (least to most severe).
21
+ *
22
+ * Used for comparisons and determining if a log level meets a threshold.
23
+ */
24
+ export const LogLevelOrdinal = [
25
+ LogLevel.Verbose,
26
+ LogLevel.Debug,
27
+ LogLevel.Info,
28
+ LogLevel.Warning,
29
+ LogLevel.Error,
30
+ ];
package/utils.d.ts ADDED
@@ -0,0 +1,49 @@
1
+ import { LogParam } from './types.js';
2
+ /**
3
+ * Converts an object to a formatted string for logging.
4
+ *
5
+ * @param instance - Object to stringify
6
+ * @returns Formatted string representation
7
+ */
8
+ export declare function _logger_logObject(instance: object): string;
9
+ /**
10
+ * Converts an array of log parameters to an array of strings.
11
+ *
12
+ * Handles different types appropriately:
13
+ * - undefined → 'undefined'
14
+ * - null → 'null'
15
+ * - string → as-is
16
+ * - number → string conversion
17
+ * - Error → stack trace extraction
18
+ * - object → JSON stringification
19
+ *
20
+ * @param params - Array of log parameters
21
+ * @returns Array of string representations
22
+ */
23
+ export declare function _logger_convertLogParamsToStrings(params: LogParam[]): string[];
24
+ /**
25
+ * Formats an Error object into a readable string with stack trace and cause chain.
26
+ *
27
+ * Processes the error stack trace, removes duplicate stack frames, and handles
28
+ * CustomException instances specially. Recursively processes error causes to build
29
+ * a complete error chain.
30
+ *
31
+ * **Note**: Mutates and filters the stack trace to remove framework-specific noise
32
+ * and duplicate frames.
33
+ *
34
+ * @param error - Error object to format
35
+ * @param fullStack - Accumulated stack trace from previous errors in the chain
36
+ * @returns Formatted error string with stack trace
37
+ */
38
+ export declare function _logger_logException(error: Error, fullStack?: string): string;
39
+ /**
40
+ * Indents all newlines in a string with a prefix.
41
+ *
42
+ * Useful for formatting multi-line log messages so that continuation lines
43
+ * are properly aligned with the log prefix.
44
+ *
45
+ * @param linePrefix - Prefix to add before each line
46
+ * @param input - String that may contain newlines
47
+ * @returns String with all newlines prefixed
48
+ */
49
+ export declare function _logger_indentNewLineBy(linePrefix: string, input: string): string;
package/utils.js ADDED
@@ -0,0 +1,106 @@
1
+ /*
2
+ * @nu-art/logger - Flexible logging infrastructure with multiple output targets
3
+ * Copyright (C) 2024 Adam van der Kruk aka TacB0sS
4
+ * Licensed under the Apache License, Version 2.0
5
+ */
6
+ /**
7
+ * Converts an object to a formatted string for logging.
8
+ *
9
+ * @param instance - Object to stringify
10
+ * @returns Formatted string representation
11
+ */
12
+ export function _logger_logObject(instance) {
13
+ return JSON.stringify(instance, null, 2);
14
+ }
15
+ /**
16
+ * Converts an array of log parameters to an array of strings.
17
+ *
18
+ * Handles different types appropriately:
19
+ * - undefined → 'undefined'
20
+ * - null → 'null'
21
+ * - string → as-is
22
+ * - number → string conversion
23
+ * - Error → stack trace extraction
24
+ * - object → JSON stringification
25
+ *
26
+ * @param params - Array of log parameters
27
+ * @returns Array of string representations
28
+ */
29
+ export function _logger_convertLogParamsToStrings(params) {
30
+ return params.map(toLog => {
31
+ if (typeof toLog === 'undefined')
32
+ return 'undefined';
33
+ if (toLog === null)
34
+ return 'null';
35
+ if (typeof toLog === 'string')
36
+ return toLog;
37
+ if (typeof toLog === 'number')
38
+ return `${toLog}`;
39
+ if (typeof toLog === 'function')
40
+ return 'function';
41
+ if (typeof toLog === 'symbol')
42
+ return 'symbol';
43
+ if (typeof toLog === 'bigint')
44
+ return `BigInt(${toLog.toString()})`;
45
+ // @ts-ignore
46
+ if (toLog.stack)
47
+ return _logger_logException(toLog);
48
+ return JSON.stringify(toLog, null, 2);
49
+ });
50
+ }
51
+ /**
52
+ * Formats an Error object into a readable string with stack trace and cause chain.
53
+ *
54
+ * Processes the error stack trace, removes duplicate stack frames, and handles
55
+ * CustomException instances specially. Recursively processes error causes to build
56
+ * a complete error chain.
57
+ *
58
+ * **Note**: Mutates and filters the stack trace to remove framework-specific noise
59
+ * and duplicate frames.
60
+ *
61
+ * @param error - Error object to format
62
+ * @param fullStack - Accumulated stack trace from previous errors in the chain
63
+ * @returns Formatted error string with stack trace
64
+ */
65
+ export function _logger_logException(error, fullStack = '') {
66
+ let toPrint = '';
67
+ let errorMessage;
68
+ let isCustomException = false;
69
+ if (error.stack) {
70
+ const stackAsList = error.stack.split('\n');
71
+ errorMessage = stackAsList[0];
72
+ const errorMessageIndex = stackAsList.indexOf(errorMessage);
73
+ if (errorMessageIndex > -1)
74
+ stackAsList.splice(errorMessageIndex, 1);
75
+ toPrint = stackAsList.reduce((toRet, stacktrace) => {
76
+ if (fullStack.indexOf(stacktrace) !== -1)
77
+ return toRet;
78
+ return toRet + stacktrace + '\n';
79
+ }, toPrint);
80
+ isCustomException = toPrint.indexOf('CustomException') !== -1;
81
+ toPrint = toPrint.replace(/\s+at.*?CustomException.*?\n/, '\n');
82
+ toPrint = toPrint.replace(/\s+at.*?new\s+(.*?) \(.*?\n/, `${fullStack.length === 0 ? '' : '\nCaused by '}$1: ${errorMessage.replace('Error: ', '')}\n`);
83
+ if (!isCustomException && errorMessage)
84
+ toPrint = errorMessage + '\n' + toPrint;
85
+ }
86
+ const cause = error.cause;
87
+ if (cause) {
88
+ let causeStack = _logger_logException(cause, toPrint);
89
+ causeStack = causeStack.replace(`Error: ${cause.message}`, `${cause.message}`);
90
+ toPrint += `${causeStack}`;
91
+ }
92
+ return toPrint;
93
+ }
94
+ /**
95
+ * Indents all newlines in a string with a prefix.
96
+ *
97
+ * Useful for formatting multi-line log messages so that continuation lines
98
+ * are properly aligned with the log prefix.
99
+ *
100
+ * @param linePrefix - Prefix to add before each line
101
+ * @param input - String that may contain newlines
102
+ * @returns String with all newlines prefixed
103
+ */
104
+ export function _logger_indentNewLineBy(linePrefix, input) {
105
+ return linePrefix + input.replace(/\n/g, `\n${linePrefix}`);
106
+ }