@feizk/logger 1.5.0 → 1.6.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/README.md +27 -0
- package/dist/index.d.mts +14 -1
- package/dist/index.d.ts +14 -1
- package/dist/index.js +47 -1
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +47 -1
- package/dist/index.mjs.map +1 -1
- package/package.json +5 -1
- package/CHANGELOG.md +0 -45
- package/src/index.ts +0 -8
- package/src/logger.ts +0 -102
- package/src/types.ts +0 -19
- package/src/utils.ts +0 -42
- package/tests/logger.test.ts +0 -182
- package/tsup.config.ts +0 -10
package/README.md
CHANGED
|
@@ -31,6 +31,11 @@ const logger = new Logger({
|
|
|
31
31
|
formatTimestamp: undefined, // Custom timestamp formatter function, Default: ISO format
|
|
32
32
|
formatLog: undefined, // Custom log formatter function, Default: undefined
|
|
33
33
|
level: 'debug', // 'debug' | 'info' | 'warn' | 'error', Default: 'debug'
|
|
34
|
+
discord: {
|
|
35
|
+
enable: false, // Enable Discord transport
|
|
36
|
+
webhookURL: '', // Discord webhook URL
|
|
37
|
+
formatEmbed: undefined, // Custom embed formatter function
|
|
38
|
+
},
|
|
34
39
|
});
|
|
35
40
|
```
|
|
36
41
|
|
|
@@ -57,6 +62,28 @@ infoLogger.info('Logged'); // and higher
|
|
|
57
62
|
|
|
58
63
|
// Change level dynamically
|
|
59
64
|
logger.setLevel('error');
|
|
65
|
+
|
|
66
|
+
// Enable Discord transport
|
|
67
|
+
const discordLogger = new Logger({
|
|
68
|
+
discord: {
|
|
69
|
+
enable: true,
|
|
70
|
+
webhookURL: 'https://discord.com/api/webhooks/123456789/abcdef',
|
|
71
|
+
},
|
|
72
|
+
});
|
|
73
|
+
discordLogger.error('This will be sent to Discord');
|
|
74
|
+
|
|
75
|
+
// Custom embed formatting
|
|
76
|
+
const customDiscordLogger = new Logger({
|
|
77
|
+
discord: {
|
|
78
|
+
enable: true,
|
|
79
|
+
webhookURL: 'https://discord.com/api/webhooks/123456789/abcdef',
|
|
80
|
+
formatEmbed: (level, timestamp, message) => ({
|
|
81
|
+
title: `${level} - Custom`,
|
|
82
|
+
description: `**Timestamp:** ${timestamp}\n**Message:** ${message}`,
|
|
83
|
+
color: 0xff0000, // Red
|
|
84
|
+
}),
|
|
85
|
+
},
|
|
86
|
+
});
|
|
60
87
|
```
|
|
61
88
|
|
|
62
89
|
## API
|
package/dist/index.d.mts
CHANGED
|
@@ -5,11 +5,17 @@ interface TimestampTypes {
|
|
|
5
5
|
Locale: 'locale';
|
|
6
6
|
Custom: 'custom';
|
|
7
7
|
}
|
|
8
|
+
interface DiscordOptions {
|
|
9
|
+
enable: boolean;
|
|
10
|
+
webhookURL: string;
|
|
11
|
+
formatEmbed?: (level: LogLevel, timestamp: string, message: string) => Record<string, unknown>;
|
|
12
|
+
}
|
|
8
13
|
interface LoggerOptions {
|
|
9
14
|
enableColors?: boolean;
|
|
10
15
|
formatTimestamp?: (types: TimestampTypes, date?: Date) => [TimestampType, string];
|
|
11
16
|
formatLog?: (level: string, timestamp: string, args: unknown[]) => string;
|
|
12
17
|
level?: LogLevel;
|
|
18
|
+
discord?: DiscordOptions;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
/**
|
|
@@ -24,6 +30,13 @@ declare class Logger {
|
|
|
24
30
|
* @param level - The log level to set.
|
|
25
31
|
*/
|
|
26
32
|
setLevel(level: LogLevel): void;
|
|
33
|
+
/**
|
|
34
|
+
* Sends a log message to Discord via webhook if configured.
|
|
35
|
+
* @param level - The log level.
|
|
36
|
+
* @param timestamp - The formatted timestamp.
|
|
37
|
+
* @param args - The log arguments.
|
|
38
|
+
*/
|
|
39
|
+
private sendToDiscord;
|
|
27
40
|
/**
|
|
28
41
|
* Checks if a log level should be output based on the current log level.
|
|
29
42
|
* @param level - The log level to check.
|
|
@@ -54,4 +67,4 @@ declare class Logger {
|
|
|
54
67
|
|
|
55
68
|
declare const TIMESTAMP_TYPES: TimestampTypes;
|
|
56
69
|
|
|
57
|
-
export { type LogLevel, Logger, type LoggerOptions, TIMESTAMP_TYPES, type TimestampType, type TimestampTypes };
|
|
70
|
+
export { type DiscordOptions, type LogLevel, Logger, type LoggerOptions, TIMESTAMP_TYPES, type TimestampType, type TimestampTypes };
|
package/dist/index.d.ts
CHANGED
|
@@ -5,11 +5,17 @@ interface TimestampTypes {
|
|
|
5
5
|
Locale: 'locale';
|
|
6
6
|
Custom: 'custom';
|
|
7
7
|
}
|
|
8
|
+
interface DiscordOptions {
|
|
9
|
+
enable: boolean;
|
|
10
|
+
webhookURL: string;
|
|
11
|
+
formatEmbed?: (level: LogLevel, timestamp: string, message: string) => Record<string, unknown>;
|
|
12
|
+
}
|
|
8
13
|
interface LoggerOptions {
|
|
9
14
|
enableColors?: boolean;
|
|
10
15
|
formatTimestamp?: (types: TimestampTypes, date?: Date) => [TimestampType, string];
|
|
11
16
|
formatLog?: (level: string, timestamp: string, args: unknown[]) => string;
|
|
12
17
|
level?: LogLevel;
|
|
18
|
+
discord?: DiscordOptions;
|
|
13
19
|
}
|
|
14
20
|
|
|
15
21
|
/**
|
|
@@ -24,6 +30,13 @@ declare class Logger {
|
|
|
24
30
|
* @param level - The log level to set.
|
|
25
31
|
*/
|
|
26
32
|
setLevel(level: LogLevel): void;
|
|
33
|
+
/**
|
|
34
|
+
* Sends a log message to Discord via webhook if configured.
|
|
35
|
+
* @param level - The log level.
|
|
36
|
+
* @param timestamp - The formatted timestamp.
|
|
37
|
+
* @param args - The log arguments.
|
|
38
|
+
*/
|
|
39
|
+
private sendToDiscord;
|
|
27
40
|
/**
|
|
28
41
|
* Checks if a log level should be output based on the current log level.
|
|
29
42
|
* @param level - The log level to check.
|
|
@@ -54,4 +67,4 @@ declare class Logger {
|
|
|
54
67
|
|
|
55
68
|
declare const TIMESTAMP_TYPES: TimestampTypes;
|
|
56
69
|
|
|
57
|
-
export { type LogLevel, Logger, type LoggerOptions, TIMESTAMP_TYPES, type TimestampType, type TimestampTypes };
|
|
70
|
+
export { type DiscordOptions, type LogLevel, Logger, type LoggerOptions, TIMESTAMP_TYPES, type TimestampType, type TimestampTypes };
|
package/dist/index.js
CHANGED
|
@@ -56,6 +56,18 @@ function getColor(level, enableColors) {
|
|
|
56
56
|
};
|
|
57
57
|
return colors[level] || level;
|
|
58
58
|
}
|
|
59
|
+
function getDiscordColor(level) {
|
|
60
|
+
const colors = {
|
|
61
|
+
debug: 9807270,
|
|
62
|
+
info: 3447003,
|
|
63
|
+
warn: 15965202,
|
|
64
|
+
error: 15158332
|
|
65
|
+
};
|
|
66
|
+
return colors[level];
|
|
67
|
+
}
|
|
68
|
+
function generateId() {
|
|
69
|
+
return Math.random().toString(36).substr(2, 8).toUpperCase();
|
|
70
|
+
}
|
|
59
71
|
function formatLog(level, timestamp, args, options) {
|
|
60
72
|
const { formatLog: formatLog2, enableColors = true } = options;
|
|
61
73
|
const coloredLevel = getColor(level, enableColors);
|
|
@@ -78,7 +90,8 @@ var Logger = class {
|
|
|
78
90
|
this.options = {
|
|
79
91
|
enableColors: options.enableColors ?? true,
|
|
80
92
|
formatTimestamp: options.formatTimestamp ?? defaultFormatTimestamp,
|
|
81
|
-
formatLog: options.formatLog
|
|
93
|
+
formatLog: options.formatLog,
|
|
94
|
+
discord: options.discord
|
|
82
95
|
};
|
|
83
96
|
this.level = options.level ?? "debug";
|
|
84
97
|
}
|
|
@@ -89,6 +102,35 @@ var Logger = class {
|
|
|
89
102
|
setLevel(level) {
|
|
90
103
|
this.level = level;
|
|
91
104
|
}
|
|
105
|
+
/**
|
|
106
|
+
* Sends a log message to Discord via webhook if configured.
|
|
107
|
+
* @param level - The log level.
|
|
108
|
+
* @param timestamp - The formatted timestamp.
|
|
109
|
+
* @param args - The log arguments.
|
|
110
|
+
*/
|
|
111
|
+
async sendToDiscord(level, timestamp, args) {
|
|
112
|
+
const discord = this.options.discord;
|
|
113
|
+
if (!discord?.enable) return;
|
|
114
|
+
try {
|
|
115
|
+
new URL(discord.webhookURL);
|
|
116
|
+
} catch {
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const message = args.map((arg) => typeof arg === "string" ? arg : JSON.stringify(arg)).join(" ");
|
|
120
|
+
const title = `${level.toUpperCase()}-${generateId()}`;
|
|
121
|
+
const embed = discord.formatEmbed ? discord.formatEmbed(level, timestamp, message) : {
|
|
122
|
+
title,
|
|
123
|
+
description: message,
|
|
124
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
125
|
+
color: getDiscordColor(level)
|
|
126
|
+
};
|
|
127
|
+
await fetch(discord.webhookURL, {
|
|
128
|
+
method: "POST",
|
|
129
|
+
headers: { "Content-Type": "application/json" },
|
|
130
|
+
body: JSON.stringify({ embeds: [embed] })
|
|
131
|
+
}).catch(() => {
|
|
132
|
+
});
|
|
133
|
+
}
|
|
92
134
|
/**
|
|
93
135
|
* Checks if a log level should be output based on the current log level.
|
|
94
136
|
* @param level - The log level to check.
|
|
@@ -108,6 +150,7 @@ var Logger = class {
|
|
|
108
150
|
TIMESTAMP_TYPES
|
|
109
151
|
);
|
|
110
152
|
console.log(...formatLog("[INFO]", timestamp, args, this.options));
|
|
153
|
+
this.sendToDiscord("info", timestamp, args);
|
|
111
154
|
}
|
|
112
155
|
/**
|
|
113
156
|
* Logs a warning message.
|
|
@@ -120,6 +163,7 @@ var Logger = class {
|
|
|
120
163
|
TIMESTAMP_TYPES
|
|
121
164
|
);
|
|
122
165
|
console.log(...formatLog("[WARN]", timestamp, args, this.options));
|
|
166
|
+
this.sendToDiscord("warn", timestamp, args);
|
|
123
167
|
}
|
|
124
168
|
/**
|
|
125
169
|
* Logs an error message.
|
|
@@ -132,6 +176,7 @@ var Logger = class {
|
|
|
132
176
|
TIMESTAMP_TYPES
|
|
133
177
|
);
|
|
134
178
|
console.log(...formatLog("[ERROR]", timestamp, args, this.options));
|
|
179
|
+
this.sendToDiscord("error", timestamp, args);
|
|
135
180
|
}
|
|
136
181
|
/**
|
|
137
182
|
* Logs a debug message.
|
|
@@ -144,6 +189,7 @@ var Logger = class {
|
|
|
144
189
|
TIMESTAMP_TYPES
|
|
145
190
|
);
|
|
146
191
|
console.log(...formatLog("[DEBUG]", timestamp, args, this.options));
|
|
192
|
+
this.sendToDiscord("debug", timestamp, args);
|
|
147
193
|
}
|
|
148
194
|
};
|
|
149
195
|
// Annotate the CommonJS export names for ESM import in node:
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/logger.ts"],"sourcesContent":["export { Logger } from './logger';\nexport { TIMESTAMP_TYPES } from './utils';\nexport type {\n LoggerOptions,\n LogLevel,\n TimestampTypes,\n TimestampType,\n} from './types';\n","import chalk from 'chalk';\nimport type { LoggerOptions, TimestampTypes } from './types';\n\nexport const TIMESTAMP_TYPES: TimestampTypes = {\n ISO: 'iso',\n Locale: 'locale',\n Custom: 'custom',\n};\n\nexport function formatTimestamp(\n formatTimestampFn: NonNullable<LoggerOptions['formatTimestamp']>,\n types: TimestampTypes,\n date: Date = new Date(),\n): string {\n const [, timestamp] = formatTimestampFn(types, date);\n return timestamp;\n}\n\nexport function getColor(level: string, enableColors: boolean): string {\n if (!enableColors) return level;\n const colors: Record<string, string> = {\n '[INFO]': chalk.blue(level),\n '[WARN]': chalk.yellow(level),\n '[ERROR]': chalk.red(level),\n '[DEBUG]': chalk.gray(level),\n };\n return colors[level] || level;\n}\n\nexport function formatLog(\n level: string,\n timestamp: string,\n args: unknown[],\n options: LoggerOptions,\n): [string, ...unknown[]] {\n const { formatLog, enableColors = true } = options;\n const coloredLevel = getColor(level, enableColors);\n if (formatLog) {\n return [formatLog(coloredLevel, timestamp, args)];\n }\n return [`${coloredLevel} ${timestamp}`, ...args];\n}\n","import type { LoggerOptions, LogLevel, TimestampTypes } from './types';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/utils.ts","../src/logger.ts"],"sourcesContent":["export { Logger } from './logger';\nexport { TIMESTAMP_TYPES } from './utils';\nexport type {\n LoggerOptions,\n LogLevel,\n TimestampTypes,\n TimestampType,\n DiscordOptions,\n} from './types';\n","import chalk from 'chalk';\nimport type { LoggerOptions, TimestampTypes, LogLevel } from './types';\n\nexport const TIMESTAMP_TYPES: TimestampTypes = {\n ISO: 'iso',\n Locale: 'locale',\n Custom: 'custom',\n};\n\nexport function formatTimestamp(\n formatTimestampFn: NonNullable<LoggerOptions['formatTimestamp']>,\n types: TimestampTypes,\n date: Date = new Date(),\n): string {\n const [, timestamp] = formatTimestampFn(types, date);\n return timestamp;\n}\n\nexport function getColor(level: string, enableColors: boolean): string {\n if (!enableColors) return level;\n const colors: Record<string, string> = {\n '[INFO]': chalk.blue(level),\n '[WARN]': chalk.yellow(level),\n '[ERROR]': chalk.red(level),\n '[DEBUG]': chalk.gray(level),\n };\n return colors[level] || level;\n}\n\nexport function getDiscordColor(level: LogLevel): number {\n const colors: Record<LogLevel, number> = {\n debug: 0x95a5a6,\n info: 0x3498db,\n warn: 0xf39c12,\n error: 0xe74c3c,\n };\n return colors[level];\n}\n\nexport function generateId(): string {\n return Math.random().toString(36).substr(2, 8).toUpperCase();\n}\n\nexport function formatLog(\n level: string,\n timestamp: string,\n args: unknown[],\n options: LoggerOptions,\n): [string, ...unknown[]] {\n const { formatLog, enableColors = true } = options;\n const coloredLevel = getColor(level, enableColors);\n if (formatLog) {\n return [formatLog(coloredLevel, timestamp, args)];\n }\n return [`${coloredLevel} ${timestamp}`, ...args];\n}\n","import type { LoggerOptions, LogLevel, TimestampTypes } from './types';\nimport {\n formatTimestamp,\n formatLog,\n TIMESTAMP_TYPES,\n getDiscordColor,\n generateId,\n} from './utils';\n\nimport type { TimestampType } from './types';\n\nconst defaultFormatTimestamp = (\n types: TimestampTypes,\n date: Date = new Date(),\n): [TimestampType, string] => [types.ISO, date.toISOString()];\n\nconst LOG_LEVEL_PRIORITIES: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\n/**\n * A simple logger with colored outputs and timestamps.\n */\nexport class Logger {\n private options: LoggerOptions;\n private level: LogLevel;\n\n constructor(options: LoggerOptions = {}) {\n this.options = {\n enableColors: options.enableColors ?? true,\n formatTimestamp: options.formatTimestamp ?? defaultFormatTimestamp,\n formatLog: options.formatLog,\n discord: options.discord,\n };\n this.level = options.level ?? 'debug';\n }\n\n /**\n * Sets the minimum log level for filtering messages.\n * @param level - The log level to set.\n */\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n /**\n * Sends a log message to Discord via webhook if configured.\n * @param level - The log level.\n * @param timestamp - The formatted timestamp.\n * @param args - The log arguments.\n */\n private async sendToDiscord(\n level: LogLevel,\n timestamp: string,\n args: unknown[],\n ): Promise<void> {\n const discord = this.options.discord;\n if (!discord?.enable) return;\n\n try {\n new URL(discord.webhookURL);\n } catch {\n return;\n }\n\n const message = args\n .map((arg) => (typeof arg === 'string' ? arg : JSON.stringify(arg)))\n .join(' ');\n\n const title = `${level.toUpperCase()}-${generateId()}`;\n\n const embed = discord.formatEmbed\n ? discord.formatEmbed(level, timestamp, message)\n : {\n title,\n description: message,\n timestamp: new Date().toISOString(),\n color: getDiscordColor(level),\n };\n\n await fetch(discord.webhookURL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ embeds: [embed] }),\n }).catch(() => {});\n }\n\n /**\n * Checks if a log level should be output based on the current log level.\n * @param level - The log level to check.\n * @returns True if the message should be logged.\n */\n private shouldLog(level: LogLevel): boolean {\n return LOG_LEVEL_PRIORITIES[level] >= LOG_LEVEL_PRIORITIES[this.level];\n }\n\n /**\n * Logs an info message.\n * @param args - The arguments to log.\n */\n info(...args: unknown[]): void {\n if (!this.shouldLog('info')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[INFO]', timestamp, args, this.options));\n this.sendToDiscord('info', timestamp, args);\n }\n\n /**\n * Logs a warning message.\n * @param args - The arguments to log.\n */\n warn(...args: unknown[]): void {\n if (!this.shouldLog('warn')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[WARN]', timestamp, args, this.options));\n this.sendToDiscord('warn', timestamp, args);\n }\n\n /**\n * Logs an error message.\n * @param args - The arguments to log.\n */\n error(...args: unknown[]): void {\n if (!this.shouldLog('error')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[ERROR]', timestamp, args, this.options));\n this.sendToDiscord('error', timestamp, args);\n }\n\n /**\n * Logs a debug message.\n * @param args - The arguments to log.\n */\n debug(...args: unknown[]): void {\n if (!this.shouldLog('debug')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[DEBUG]', timestamp, args, this.options));\n this.sendToDiscord('debug', timestamp, args);\n }\n}\n"],"mappings":"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","names":["chalk","formatLog"]}
|
package/dist/index.mjs
CHANGED
|
@@ -19,6 +19,18 @@ function getColor(level, enableColors) {
|
|
|
19
19
|
};
|
|
20
20
|
return colors[level] || level;
|
|
21
21
|
}
|
|
22
|
+
function getDiscordColor(level) {
|
|
23
|
+
const colors = {
|
|
24
|
+
debug: 9807270,
|
|
25
|
+
info: 3447003,
|
|
26
|
+
warn: 15965202,
|
|
27
|
+
error: 15158332
|
|
28
|
+
};
|
|
29
|
+
return colors[level];
|
|
30
|
+
}
|
|
31
|
+
function generateId() {
|
|
32
|
+
return Math.random().toString(36).substr(2, 8).toUpperCase();
|
|
33
|
+
}
|
|
22
34
|
function formatLog(level, timestamp, args, options) {
|
|
23
35
|
const { formatLog: formatLog2, enableColors = true } = options;
|
|
24
36
|
const coloredLevel = getColor(level, enableColors);
|
|
@@ -41,7 +53,8 @@ var Logger = class {
|
|
|
41
53
|
this.options = {
|
|
42
54
|
enableColors: options.enableColors ?? true,
|
|
43
55
|
formatTimestamp: options.formatTimestamp ?? defaultFormatTimestamp,
|
|
44
|
-
formatLog: options.formatLog
|
|
56
|
+
formatLog: options.formatLog,
|
|
57
|
+
discord: options.discord
|
|
45
58
|
};
|
|
46
59
|
this.level = options.level ?? "debug";
|
|
47
60
|
}
|
|
@@ -52,6 +65,35 @@ var Logger = class {
|
|
|
52
65
|
setLevel(level) {
|
|
53
66
|
this.level = level;
|
|
54
67
|
}
|
|
68
|
+
/**
|
|
69
|
+
* Sends a log message to Discord via webhook if configured.
|
|
70
|
+
* @param level - The log level.
|
|
71
|
+
* @param timestamp - The formatted timestamp.
|
|
72
|
+
* @param args - The log arguments.
|
|
73
|
+
*/
|
|
74
|
+
async sendToDiscord(level, timestamp, args) {
|
|
75
|
+
const discord = this.options.discord;
|
|
76
|
+
if (!discord?.enable) return;
|
|
77
|
+
try {
|
|
78
|
+
new URL(discord.webhookURL);
|
|
79
|
+
} catch {
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
const message = args.map((arg) => typeof arg === "string" ? arg : JSON.stringify(arg)).join(" ");
|
|
83
|
+
const title = `${level.toUpperCase()}-${generateId()}`;
|
|
84
|
+
const embed = discord.formatEmbed ? discord.formatEmbed(level, timestamp, message) : {
|
|
85
|
+
title,
|
|
86
|
+
description: message,
|
|
87
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
88
|
+
color: getDiscordColor(level)
|
|
89
|
+
};
|
|
90
|
+
await fetch(discord.webhookURL, {
|
|
91
|
+
method: "POST",
|
|
92
|
+
headers: { "Content-Type": "application/json" },
|
|
93
|
+
body: JSON.stringify({ embeds: [embed] })
|
|
94
|
+
}).catch(() => {
|
|
95
|
+
});
|
|
96
|
+
}
|
|
55
97
|
/**
|
|
56
98
|
* Checks if a log level should be output based on the current log level.
|
|
57
99
|
* @param level - The log level to check.
|
|
@@ -71,6 +113,7 @@ var Logger = class {
|
|
|
71
113
|
TIMESTAMP_TYPES
|
|
72
114
|
);
|
|
73
115
|
console.log(...formatLog("[INFO]", timestamp, args, this.options));
|
|
116
|
+
this.sendToDiscord("info", timestamp, args);
|
|
74
117
|
}
|
|
75
118
|
/**
|
|
76
119
|
* Logs a warning message.
|
|
@@ -83,6 +126,7 @@ var Logger = class {
|
|
|
83
126
|
TIMESTAMP_TYPES
|
|
84
127
|
);
|
|
85
128
|
console.log(...formatLog("[WARN]", timestamp, args, this.options));
|
|
129
|
+
this.sendToDiscord("warn", timestamp, args);
|
|
86
130
|
}
|
|
87
131
|
/**
|
|
88
132
|
* Logs an error message.
|
|
@@ -95,6 +139,7 @@ var Logger = class {
|
|
|
95
139
|
TIMESTAMP_TYPES
|
|
96
140
|
);
|
|
97
141
|
console.log(...formatLog("[ERROR]", timestamp, args, this.options));
|
|
142
|
+
this.sendToDiscord("error", timestamp, args);
|
|
98
143
|
}
|
|
99
144
|
/**
|
|
100
145
|
* Logs a debug message.
|
|
@@ -107,6 +152,7 @@ var Logger = class {
|
|
|
107
152
|
TIMESTAMP_TYPES
|
|
108
153
|
);
|
|
109
154
|
console.log(...formatLog("[DEBUG]", timestamp, args, this.options));
|
|
155
|
+
this.sendToDiscord("debug", timestamp, args);
|
|
110
156
|
}
|
|
111
157
|
};
|
|
112
158
|
export {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/utils.ts","../src/logger.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { LoggerOptions, TimestampTypes } from './types';\n\nexport const TIMESTAMP_TYPES: TimestampTypes = {\n ISO: 'iso',\n Locale: 'locale',\n Custom: 'custom',\n};\n\nexport function formatTimestamp(\n formatTimestampFn: NonNullable<LoggerOptions['formatTimestamp']>,\n types: TimestampTypes,\n date: Date = new Date(),\n): string {\n const [, timestamp] = formatTimestampFn(types, date);\n return timestamp;\n}\n\nexport function getColor(level: string, enableColors: boolean): string {\n if (!enableColors) return level;\n const colors: Record<string, string> = {\n '[INFO]': chalk.blue(level),\n '[WARN]': chalk.yellow(level),\n '[ERROR]': chalk.red(level),\n '[DEBUG]': chalk.gray(level),\n };\n return colors[level] || level;\n}\n\nexport function formatLog(\n level: string,\n timestamp: string,\n args: unknown[],\n options: LoggerOptions,\n): [string, ...unknown[]] {\n const { formatLog, enableColors = true } = options;\n const coloredLevel = getColor(level, enableColors);\n if (formatLog) {\n return [formatLog(coloredLevel, timestamp, args)];\n }\n return [`${coloredLevel} ${timestamp}`, ...args];\n}\n","import type { LoggerOptions, LogLevel, TimestampTypes } from './types';\nimport {
|
|
1
|
+
{"version":3,"sources":["../src/utils.ts","../src/logger.ts"],"sourcesContent":["import chalk from 'chalk';\nimport type { LoggerOptions, TimestampTypes, LogLevel } from './types';\n\nexport const TIMESTAMP_TYPES: TimestampTypes = {\n ISO: 'iso',\n Locale: 'locale',\n Custom: 'custom',\n};\n\nexport function formatTimestamp(\n formatTimestampFn: NonNullable<LoggerOptions['formatTimestamp']>,\n types: TimestampTypes,\n date: Date = new Date(),\n): string {\n const [, timestamp] = formatTimestampFn(types, date);\n return timestamp;\n}\n\nexport function getColor(level: string, enableColors: boolean): string {\n if (!enableColors) return level;\n const colors: Record<string, string> = {\n '[INFO]': chalk.blue(level),\n '[WARN]': chalk.yellow(level),\n '[ERROR]': chalk.red(level),\n '[DEBUG]': chalk.gray(level),\n };\n return colors[level] || level;\n}\n\nexport function getDiscordColor(level: LogLevel): number {\n const colors: Record<LogLevel, number> = {\n debug: 0x95a5a6,\n info: 0x3498db,\n warn: 0xf39c12,\n error: 0xe74c3c,\n };\n return colors[level];\n}\n\nexport function generateId(): string {\n return Math.random().toString(36).substr(2, 8).toUpperCase();\n}\n\nexport function formatLog(\n level: string,\n timestamp: string,\n args: unknown[],\n options: LoggerOptions,\n): [string, ...unknown[]] {\n const { formatLog, enableColors = true } = options;\n const coloredLevel = getColor(level, enableColors);\n if (formatLog) {\n return [formatLog(coloredLevel, timestamp, args)];\n }\n return [`${coloredLevel} ${timestamp}`, ...args];\n}\n","import type { LoggerOptions, LogLevel, TimestampTypes } from './types';\nimport {\n formatTimestamp,\n formatLog,\n TIMESTAMP_TYPES,\n getDiscordColor,\n generateId,\n} from './utils';\n\nimport type { TimestampType } from './types';\n\nconst defaultFormatTimestamp = (\n types: TimestampTypes,\n date: Date = new Date(),\n): [TimestampType, string] => [types.ISO, date.toISOString()];\n\nconst LOG_LEVEL_PRIORITIES: Record<LogLevel, number> = {\n debug: 0,\n info: 1,\n warn: 2,\n error: 3,\n};\n\n/**\n * A simple logger with colored outputs and timestamps.\n */\nexport class Logger {\n private options: LoggerOptions;\n private level: LogLevel;\n\n constructor(options: LoggerOptions = {}) {\n this.options = {\n enableColors: options.enableColors ?? true,\n formatTimestamp: options.formatTimestamp ?? defaultFormatTimestamp,\n formatLog: options.formatLog,\n discord: options.discord,\n };\n this.level = options.level ?? 'debug';\n }\n\n /**\n * Sets the minimum log level for filtering messages.\n * @param level - The log level to set.\n */\n setLevel(level: LogLevel): void {\n this.level = level;\n }\n\n /**\n * Sends a log message to Discord via webhook if configured.\n * @param level - The log level.\n * @param timestamp - The formatted timestamp.\n * @param args - The log arguments.\n */\n private async sendToDiscord(\n level: LogLevel,\n timestamp: string,\n args: unknown[],\n ): Promise<void> {\n const discord = this.options.discord;\n if (!discord?.enable) return;\n\n try {\n new URL(discord.webhookURL);\n } catch {\n return;\n }\n\n const message = args\n .map((arg) => (typeof arg === 'string' ? arg : JSON.stringify(arg)))\n .join(' ');\n\n const title = `${level.toUpperCase()}-${generateId()}`;\n\n const embed = discord.formatEmbed\n ? discord.formatEmbed(level, timestamp, message)\n : {\n title,\n description: message,\n timestamp: new Date().toISOString(),\n color: getDiscordColor(level),\n };\n\n await fetch(discord.webhookURL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ embeds: [embed] }),\n }).catch(() => {});\n }\n\n /**\n * Checks if a log level should be output based on the current log level.\n * @param level - The log level to check.\n * @returns True if the message should be logged.\n */\n private shouldLog(level: LogLevel): boolean {\n return LOG_LEVEL_PRIORITIES[level] >= LOG_LEVEL_PRIORITIES[this.level];\n }\n\n /**\n * Logs an info message.\n * @param args - The arguments to log.\n */\n info(...args: unknown[]): void {\n if (!this.shouldLog('info')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[INFO]', timestamp, args, this.options));\n this.sendToDiscord('info', timestamp, args);\n }\n\n /**\n * Logs a warning message.\n * @param args - The arguments to log.\n */\n warn(...args: unknown[]): void {\n if (!this.shouldLog('warn')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[WARN]', timestamp, args, this.options));\n this.sendToDiscord('warn', timestamp, args);\n }\n\n /**\n * Logs an error message.\n * @param args - The arguments to log.\n */\n error(...args: unknown[]): void {\n if (!this.shouldLog('error')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[ERROR]', timestamp, args, this.options));\n this.sendToDiscord('error', timestamp, args);\n }\n\n /**\n * Logs a debug message.\n * @param args - The arguments to log.\n */\n debug(...args: unknown[]): void {\n if (!this.shouldLog('debug')) return;\n const timestamp = formatTimestamp(\n this.options.formatTimestamp!,\n TIMESTAMP_TYPES,\n );\n console.log(...formatLog('[DEBUG]', timestamp, args, this.options));\n this.sendToDiscord('debug', timestamp, args);\n }\n}\n"],"mappings":"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","names":["formatLog"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@feizk/logger",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "A simple logger package with colored outputs and timestamps",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -14,6 +14,10 @@
|
|
|
14
14
|
"@types/node": "^20.0.0",
|
|
15
15
|
"vitest": "^1.6.1"
|
|
16
16
|
},
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
17
21
|
"keywords": [
|
|
18
22
|
"logger",
|
|
19
23
|
"console",
|
package/CHANGELOG.md
DELETED
|
@@ -1,45 +0,0 @@
|
|
|
1
|
-
# @feizk/logger
|
|
2
|
-
|
|
3
|
-
## 1.5.0
|
|
4
|
-
|
|
5
|
-
### Minor Changes
|
|
6
|
-
|
|
7
|
-
- f3f8525: - Renamed `timestampFormat` to `formatTimestamp` and changed it to always be a function returning `[TimestampType, string]`
|
|
8
|
-
- Renamed `logFormat` to `formatLog`
|
|
9
|
-
- Renamed `logLevel` to `level`
|
|
10
|
-
- Renamed `setLogLevel` method to `setLevel`
|
|
11
|
-
- Added `TimestampTypes` interface and `TimestampType` union type for type safety
|
|
12
|
-
- Exported `TIMESTAMP_TYPES` constant and new types from the package index
|
|
13
|
-
- Updated `LoggerOptions` interface with new option names and types
|
|
14
|
-
- Modified `formatTimestamp` utility function to accept and call the user-provided function
|
|
15
|
-
- Updated all test cases to use the new option formats
|
|
16
|
-
- Updated README.md documentation, examples, and API reference
|
|
17
|
-
|
|
18
|
-
## 1.4.0
|
|
19
|
-
|
|
20
|
-
### Minor Changes
|
|
21
|
-
|
|
22
|
-
- 2b7b1eb: - Added `LogLevel` type ('debug' | 'info' | 'warn' | 'error') and `logLevel` option to `LoggerOptions` in `types.ts`
|
|
23
|
-
- Updated `logger.ts` to implement log level filtering with a `LOG_LEVEL_PRIORITIES` constant, `shouldLog` private method, and checks before each log call
|
|
24
|
-
- Added `setLogLevel` method to `logger.ts` for dynamic runtime level changes
|
|
25
|
-
- Exported `LogLevel` type from `index.ts` for external use
|
|
26
|
-
- Added comprehensive test cases in `logger.test.ts` for filtering behavior at different levels, dynamic level changes, and default behavior
|
|
27
|
-
- Updated `README.md` with `logLevel` option documentation, usage examples, and API details for the new method
|
|
28
|
-
|
|
29
|
-
## 1.3.0
|
|
30
|
-
|
|
31
|
-
### Minor Changes
|
|
32
|
-
|
|
33
|
-
- 6e3d7e5: - Created `src/types.ts` with `LoggerOptions` interface for `enableColors`, `timestampFormat`, and `logFormat` options\n- Created `src/utils.ts` with utility functions: `formatTimestamp`, `getColor`, and `formatLog`\n- Moved `Logger` class to `src/logger.ts` and made it configurable via constructor options with defaults\n- Updated `src/index.ts` to export `Logger` class and `LoggerOptions` type instead of containing the class\n- Removed the `success` method from `Logger` class (per user feedback)\n- Removed `[SUCCESS]` color mapping from `utils.ts`\n- Added tests in `tests/logger.test.ts` for disabling colors, locale timestamp, custom timestamp function, and custom log format\n- Removed success-related test from `tests/logger.test.ts`\n- Updated `README.md` with usage examples for new options and removed success method documentation\n- Ensured backward compatibility: existing `new Logger()` usage remains unchanged\n- All tests pass (10 tests) and build succeeds
|
|
34
|
-
|
|
35
|
-
## 1.2.0
|
|
36
|
-
|
|
37
|
-
### Minor Changes
|
|
38
|
-
|
|
39
|
-
- 4b70f01: Accept multiple arguments and Any type of arguments on all Logger methods
|
|
40
|
-
|
|
41
|
-
## 1.1.0
|
|
42
|
-
|
|
43
|
-
### Minor Changes
|
|
44
|
-
|
|
45
|
-
- ebc4e0b: Add success logging method to Logger class
|
package/src/index.ts
DELETED
package/src/logger.ts
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import type { LoggerOptions, LogLevel, TimestampTypes } from './types';
|
|
2
|
-
import { formatTimestamp, formatLog, TIMESTAMP_TYPES } from './utils';
|
|
3
|
-
|
|
4
|
-
import type { TimestampType } from './types';
|
|
5
|
-
|
|
6
|
-
const defaultFormatTimestamp = (
|
|
7
|
-
types: TimestampTypes,
|
|
8
|
-
date: Date = new Date(),
|
|
9
|
-
): [TimestampType, string] => [types.ISO, date.toISOString()];
|
|
10
|
-
|
|
11
|
-
const LOG_LEVEL_PRIORITIES: Record<LogLevel, number> = {
|
|
12
|
-
debug: 0,
|
|
13
|
-
info: 1,
|
|
14
|
-
warn: 2,
|
|
15
|
-
error: 3,
|
|
16
|
-
};
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* A simple logger with colored outputs and timestamps.
|
|
20
|
-
*/
|
|
21
|
-
export class Logger {
|
|
22
|
-
private options: LoggerOptions;
|
|
23
|
-
private level: LogLevel;
|
|
24
|
-
|
|
25
|
-
constructor(options: LoggerOptions = {}) {
|
|
26
|
-
this.options = {
|
|
27
|
-
enableColors: options.enableColors ?? true,
|
|
28
|
-
formatTimestamp: options.formatTimestamp ?? defaultFormatTimestamp,
|
|
29
|
-
formatLog: options.formatLog,
|
|
30
|
-
};
|
|
31
|
-
this.level = options.level ?? 'debug';
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/**
|
|
35
|
-
* Sets the minimum log level for filtering messages.
|
|
36
|
-
* @param level - The log level to set.
|
|
37
|
-
*/
|
|
38
|
-
setLevel(level: LogLevel): void {
|
|
39
|
-
this.level = level;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Checks if a log level should be output based on the current log level.
|
|
44
|
-
* @param level - The log level to check.
|
|
45
|
-
* @returns True if the message should be logged.
|
|
46
|
-
*/
|
|
47
|
-
private shouldLog(level: LogLevel): boolean {
|
|
48
|
-
return LOG_LEVEL_PRIORITIES[level] >= LOG_LEVEL_PRIORITIES[this.level];
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Logs an info message.
|
|
53
|
-
* @param args - The arguments to log.
|
|
54
|
-
*/
|
|
55
|
-
info(...args: unknown[]): void {
|
|
56
|
-
if (!this.shouldLog('info')) return;
|
|
57
|
-
const timestamp = formatTimestamp(
|
|
58
|
-
this.options.formatTimestamp!,
|
|
59
|
-
TIMESTAMP_TYPES,
|
|
60
|
-
);
|
|
61
|
-
console.log(...formatLog('[INFO]', timestamp, args, this.options));
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Logs a warning message.
|
|
66
|
-
* @param args - The arguments to log.
|
|
67
|
-
*/
|
|
68
|
-
warn(...args: unknown[]): void {
|
|
69
|
-
if (!this.shouldLog('warn')) return;
|
|
70
|
-
const timestamp = formatTimestamp(
|
|
71
|
-
this.options.formatTimestamp!,
|
|
72
|
-
TIMESTAMP_TYPES,
|
|
73
|
-
);
|
|
74
|
-
console.log(...formatLog('[WARN]', timestamp, args, this.options));
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/**
|
|
78
|
-
* Logs an error message.
|
|
79
|
-
* @param args - The arguments to log.
|
|
80
|
-
*/
|
|
81
|
-
error(...args: unknown[]): void {
|
|
82
|
-
if (!this.shouldLog('error')) return;
|
|
83
|
-
const timestamp = formatTimestamp(
|
|
84
|
-
this.options.formatTimestamp!,
|
|
85
|
-
TIMESTAMP_TYPES,
|
|
86
|
-
);
|
|
87
|
-
console.log(...formatLog('[ERROR]', timestamp, args, this.options));
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Logs a debug message.
|
|
92
|
-
* @param args - The arguments to log.
|
|
93
|
-
*/
|
|
94
|
-
debug(...args: unknown[]): void {
|
|
95
|
-
if (!this.shouldLog('debug')) return;
|
|
96
|
-
const timestamp = formatTimestamp(
|
|
97
|
-
this.options.formatTimestamp!,
|
|
98
|
-
TIMESTAMP_TYPES,
|
|
99
|
-
);
|
|
100
|
-
console.log(...formatLog('[DEBUG]', timestamp, args, this.options));
|
|
101
|
-
}
|
|
102
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
export type LogLevel = 'debug' | 'info' | 'warn' | 'error';
|
|
2
|
-
|
|
3
|
-
export type TimestampType = 'iso' | 'locale' | 'custom';
|
|
4
|
-
|
|
5
|
-
export interface TimestampTypes {
|
|
6
|
-
ISO: 'iso';
|
|
7
|
-
Locale: 'locale';
|
|
8
|
-
Custom: 'custom';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface LoggerOptions {
|
|
12
|
-
enableColors?: boolean;
|
|
13
|
-
formatTimestamp?: (
|
|
14
|
-
types: TimestampTypes,
|
|
15
|
-
date?: Date,
|
|
16
|
-
) => [TimestampType, string];
|
|
17
|
-
formatLog?: (level: string, timestamp: string, args: unknown[]) => string;
|
|
18
|
-
level?: LogLevel;
|
|
19
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,42 +0,0 @@
|
|
|
1
|
-
import chalk from 'chalk';
|
|
2
|
-
import type { LoggerOptions, TimestampTypes } from './types';
|
|
3
|
-
|
|
4
|
-
export const TIMESTAMP_TYPES: TimestampTypes = {
|
|
5
|
-
ISO: 'iso',
|
|
6
|
-
Locale: 'locale',
|
|
7
|
-
Custom: 'custom',
|
|
8
|
-
};
|
|
9
|
-
|
|
10
|
-
export function formatTimestamp(
|
|
11
|
-
formatTimestampFn: NonNullable<LoggerOptions['formatTimestamp']>,
|
|
12
|
-
types: TimestampTypes,
|
|
13
|
-
date: Date = new Date(),
|
|
14
|
-
): string {
|
|
15
|
-
const [, timestamp] = formatTimestampFn(types, date);
|
|
16
|
-
return timestamp;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
export function getColor(level: string, enableColors: boolean): string {
|
|
20
|
-
if (!enableColors) return level;
|
|
21
|
-
const colors: Record<string, string> = {
|
|
22
|
-
'[INFO]': chalk.blue(level),
|
|
23
|
-
'[WARN]': chalk.yellow(level),
|
|
24
|
-
'[ERROR]': chalk.red(level),
|
|
25
|
-
'[DEBUG]': chalk.gray(level),
|
|
26
|
-
};
|
|
27
|
-
return colors[level] || level;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function formatLog(
|
|
31
|
-
level: string,
|
|
32
|
-
timestamp: string,
|
|
33
|
-
args: unknown[],
|
|
34
|
-
options: LoggerOptions,
|
|
35
|
-
): [string, ...unknown[]] {
|
|
36
|
-
const { formatLog, enableColors = true } = options;
|
|
37
|
-
const coloredLevel = getColor(level, enableColors);
|
|
38
|
-
if (formatLog) {
|
|
39
|
-
return [formatLog(coloredLevel, timestamp, args)];
|
|
40
|
-
}
|
|
41
|
-
return [`${coloredLevel} ${timestamp}`, ...args];
|
|
42
|
-
}
|
package/tests/logger.test.ts
DELETED
|
@@ -1,182 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
describe,
|
|
3
|
-
it,
|
|
4
|
-
expect,
|
|
5
|
-
vi,
|
|
6
|
-
beforeEach,
|
|
7
|
-
afterEach,
|
|
8
|
-
type MockInstance,
|
|
9
|
-
} from 'vitest';
|
|
10
|
-
import { Logger, TIMESTAMP_TYPES } from '../src/index';
|
|
11
|
-
|
|
12
|
-
describe('Logger', () => {
|
|
13
|
-
let logger: Logger;
|
|
14
|
-
let consoleSpy: MockInstance<
|
|
15
|
-
[message?: unknown, ...optionalParams: unknown[]],
|
|
16
|
-
void
|
|
17
|
-
>;
|
|
18
|
-
|
|
19
|
-
beforeEach(() => {
|
|
20
|
-
logger = new Logger();
|
|
21
|
-
consoleSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
afterEach(() => {
|
|
25
|
-
consoleSpy.mockRestore();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
it('should have info method', () => {
|
|
29
|
-
logger.info('test message');
|
|
30
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
31
|
-
expect.stringContaining('[INFO]'),
|
|
32
|
-
'test message',
|
|
33
|
-
);
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
it('should have warn method', () => {
|
|
37
|
-
logger.warn('test message');
|
|
38
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
39
|
-
expect.stringContaining('[WARN]'),
|
|
40
|
-
'test message',
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should have error method', () => {
|
|
45
|
-
logger.error('test message');
|
|
46
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
47
|
-
expect.stringContaining('[ERROR]'),
|
|
48
|
-
'test message',
|
|
49
|
-
);
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
it('should have debug method', () => {
|
|
53
|
-
logger.debug('test message');
|
|
54
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
55
|
-
expect.stringContaining('[DEBUG]'),
|
|
56
|
-
'test message',
|
|
57
|
-
);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
it('should include timestamp in logs', () => {
|
|
61
|
-
logger.info('test');
|
|
62
|
-
const callArgs = consoleSpy.mock.calls[0][0];
|
|
63
|
-
expect(callArgs).toMatch(/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z/);
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
it('should handle multiple arguments', () => {
|
|
67
|
-
logger.info('hello', 'world', 42, { key: 'value' });
|
|
68
|
-
const calls = consoleSpy.mock.calls[0];
|
|
69
|
-
expect(calls[0]).toMatch(/\[INFO\]/);
|
|
70
|
-
expect(calls[1]).toBe('hello');
|
|
71
|
-
expect(calls[2]).toBe('world');
|
|
72
|
-
expect(calls[3]).toBe(42);
|
|
73
|
-
expect(calls[4]).toEqual({ key: 'value' });
|
|
74
|
-
});
|
|
75
|
-
|
|
76
|
-
it('should disable colors when enableColors is false', () => {
|
|
77
|
-
const noColorLogger = new Logger({ enableColors: false });
|
|
78
|
-
noColorLogger.info('test message');
|
|
79
|
-
const callArgs = consoleSpy.mock.calls[0][0];
|
|
80
|
-
expect(callArgs).toContain('[INFO]'); // Should not have ANSI codes
|
|
81
|
-
expect(callArgs).not.toContain('\u001b['); // ANSI escape code
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
it('should use locale timestamp format', () => {
|
|
85
|
-
const localeLogger = new Logger({
|
|
86
|
-
formatTimestamp: (types) => [types.Locale, new Date().toLocaleString()],
|
|
87
|
-
});
|
|
88
|
-
localeLogger.info('test');
|
|
89
|
-
const callArgs = consoleSpy.mock.calls[0][0];
|
|
90
|
-
expect(callArgs).toMatch(/\d{1,2}\/\d{1,2}\/\d{4}/); // Basic locale date check
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
it('should use custom timestamp function', () => {
|
|
94
|
-
const customLogger = new Logger({
|
|
95
|
-
formatTimestamp: () => [TIMESTAMP_TYPES.Custom, 'custom-time'],
|
|
96
|
-
});
|
|
97
|
-
customLogger.info('test');
|
|
98
|
-
const callArgs = consoleSpy.mock.calls[0][0];
|
|
99
|
-
expect(callArgs).toContain('custom-time');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('should use custom log format', () => {
|
|
103
|
-
const customLogger = new Logger({
|
|
104
|
-
formatLog: (level, timestamp, args) =>
|
|
105
|
-
`${timestamp} ${level}: ${args.join(' ')}`,
|
|
106
|
-
});
|
|
107
|
-
customLogger.warn('hello', 'world');
|
|
108
|
-
const callArgs = consoleSpy.mock.calls[0][0];
|
|
109
|
-
expect(callArgs).toMatch(
|
|
110
|
-
/\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z \[WARN\]: hello world/,
|
|
111
|
-
);
|
|
112
|
-
});
|
|
113
|
-
|
|
114
|
-
it('should default to debug log level', () => {
|
|
115
|
-
const defaultLogger = new Logger();
|
|
116
|
-
defaultLogger.debug('debug message');
|
|
117
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
118
|
-
expect.stringContaining('[DEBUG]'),
|
|
119
|
-
'debug message',
|
|
120
|
-
);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it('should filter logs below the set level', () => {
|
|
124
|
-
const infoLogger = new Logger({ level: 'info' });
|
|
125
|
-
infoLogger.debug('debug message');
|
|
126
|
-
expect(consoleSpy).not.toHaveBeenCalled();
|
|
127
|
-
|
|
128
|
-
infoLogger.info('info message');
|
|
129
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
130
|
-
expect.stringContaining('[INFO]'),
|
|
131
|
-
'info message',
|
|
132
|
-
);
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
it('should allow all levels when set to debug', () => {
|
|
136
|
-
const debugLogger = new Logger({ level: 'debug' });
|
|
137
|
-
debugLogger.debug('debug');
|
|
138
|
-
debugLogger.info('info');
|
|
139
|
-
debugLogger.warn('warn');
|
|
140
|
-
debugLogger.error('error');
|
|
141
|
-
expect(consoleSpy).toHaveBeenCalledTimes(4);
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
it('should filter debug and info when set to warn', () => {
|
|
145
|
-
const warnLogger = new Logger({ level: 'warn' });
|
|
146
|
-
warnLogger.debug('debug');
|
|
147
|
-
warnLogger.info('info');
|
|
148
|
-
expect(consoleSpy).not.toHaveBeenCalled();
|
|
149
|
-
|
|
150
|
-
warnLogger.warn('warn');
|
|
151
|
-
warnLogger.error('error');
|
|
152
|
-
expect(consoleSpy).toHaveBeenCalledTimes(2);
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
it('should only log errors when set to error', () => {
|
|
156
|
-
const errorLogger = new Logger({ level: 'error' });
|
|
157
|
-
errorLogger.debug('debug');
|
|
158
|
-
errorLogger.info('info');
|
|
159
|
-
errorLogger.warn('warn');
|
|
160
|
-
expect(consoleSpy).not.toHaveBeenCalled();
|
|
161
|
-
|
|
162
|
-
errorLogger.error('error');
|
|
163
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
164
|
-
expect.stringContaining('[ERROR]'),
|
|
165
|
-
'error',
|
|
166
|
-
);
|
|
167
|
-
});
|
|
168
|
-
|
|
169
|
-
it('should allow changing log level dynamically', () => {
|
|
170
|
-
const logger = new Logger();
|
|
171
|
-
logger.setLevel('error');
|
|
172
|
-
logger.debug('debug');
|
|
173
|
-
expect(consoleSpy).not.toHaveBeenCalled();
|
|
174
|
-
|
|
175
|
-
logger.setLevel('debug');
|
|
176
|
-
logger.debug('debug');
|
|
177
|
-
expect(consoleSpy).toHaveBeenCalledWith(
|
|
178
|
-
expect.stringContaining('[DEBUG]'),
|
|
179
|
-
'debug',
|
|
180
|
-
);
|
|
181
|
-
});
|
|
182
|
-
});
|