@feizk/logger 1.6.0 → 1.7.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +21 -60
- package/dist/index.d.mts +18 -2
- package/dist/index.d.ts +18 -2
- package/dist/index.js +43 -4
- package/dist/index.mjs +43 -4
- package/package.json +1 -1
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -21,70 +21,27 @@ logger.error('This is an error');
|
|
|
21
21
|
logger.debug('This is a debug message');
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
## Options
|
|
25
25
|
|
|
26
|
-
|
|
26
|
+
| Option | Type | Default | Description |
|
|
27
|
+
| --------------- | -------------------------------- | ----------- | ------------------------------------- |
|
|
28
|
+
| `enableColors` | `boolean` | `true` | Enable colored output |
|
|
29
|
+
| `formatTimestamp`| `function \| undefined` | `ISO format`| Custom timestamp formatter function |
|
|
30
|
+
| `formatLog` | `function \| undefined` | `undefined` | Custom log formatter function |
|
|
31
|
+
| `level` | `'debug' \| 'info' \| 'warn' \| 'error'` | `'debug'` | Minimum log level |
|
|
32
|
+
| `discord` | `object \| undefined` | `undefined` | Discord transport options |
|
|
27
33
|
|
|
28
|
-
|
|
29
|
-
const logger = new Logger({
|
|
30
|
-
enableColors: true, // Default: true
|
|
31
|
-
formatTimestamp: undefined, // Custom timestamp formatter function, Default: ISO format
|
|
32
|
-
formatLog: undefined, // Custom log formatter function, Default: undefined
|
|
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
|
-
},
|
|
39
|
-
});
|
|
40
|
-
```
|
|
34
|
+
### Discord Options
|
|
41
35
|
|
|
42
|
-
|
|
36
|
+
The `discord` option configures Discord webhook integration. It has the following properties:
|
|
43
37
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
});
|
|
52
|
-
|
|
53
|
-
// Custom timestamp
|
|
54
|
-
const customLogger = new Logger({
|
|
55
|
-
formatTimestamp: () => [TIMESTAMP_TYPES.Custom, 'custom-time'],
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
// Filter logs below info level
|
|
59
|
-
const infoLogger = new Logger({ level: 'info' });
|
|
60
|
-
infoLogger.debug('Not logged');
|
|
61
|
-
infoLogger.info('Logged'); // and higher
|
|
62
|
-
|
|
63
|
-
// Change level dynamically
|
|
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
|
-
});
|
|
87
|
-
```
|
|
38
|
+
- `enable`: `boolean`, default `false` - Enable Discord transport
|
|
39
|
+
- `webhookURL`: `string`, default `''` - Discord webhook URL
|
|
40
|
+
- `formatEmbed`: `function \| undefined`, default `undefined` - Custom embed formatter function
|
|
41
|
+
- `batchSize`: `number`, default `10` - Number of embeds per batch request
|
|
42
|
+
- `batchDelay`: `number`, default `2000` - Delay in ms between batch sends
|
|
43
|
+
- `maxRetries`: `number`, default `3` - Maximum retry attempts for failed sends
|
|
44
|
+
- `retryDelayBase`: `number`, default `1000` - Base delay in ms for exponential backoff
|
|
88
45
|
|
|
89
46
|
## API
|
|
90
47
|
|
|
@@ -97,3 +54,7 @@ const customDiscordLogger = new Logger({
|
|
|
97
54
|
- `setLevel(level: LogLevel)`: Sets the minimum log level for filtering messages.
|
|
98
55
|
|
|
99
56
|
All messages include a timestamp and are colored accordingly (unless disabled via options).
|
|
57
|
+
|
|
58
|
+
## License
|
|
59
|
+
|
|
60
|
+
MIT
|
package/dist/index.d.mts
CHANGED
|
@@ -8,14 +8,18 @@ interface TimestampTypes {
|
|
|
8
8
|
interface DiscordOptions {
|
|
9
9
|
enable: boolean;
|
|
10
10
|
webhookURL: string;
|
|
11
|
+
batchSize?: number;
|
|
12
|
+
batchDelay?: number;
|
|
13
|
+
maxRetries?: number;
|
|
14
|
+
retryDelayBase?: number;
|
|
11
15
|
formatEmbed?: (level: LogLevel, timestamp: string, message: string) => Record<string, unknown>;
|
|
12
16
|
}
|
|
13
17
|
interface LoggerOptions {
|
|
18
|
+
level?: LogLevel;
|
|
14
19
|
enableColors?: boolean;
|
|
20
|
+
discord?: DiscordOptions;
|
|
15
21
|
formatTimestamp?: (types: TimestampTypes, date?: Date) => [TimestampType, string];
|
|
16
22
|
formatLog?: (level: string, timestamp: string, args: unknown[]) => string;
|
|
17
|
-
level?: LogLevel;
|
|
18
|
-
discord?: DiscordOptions;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/**
|
|
@@ -24,6 +28,9 @@ interface LoggerOptions {
|
|
|
24
28
|
declare class Logger {
|
|
25
29
|
private options;
|
|
26
30
|
private level;
|
|
31
|
+
private discordQueue;
|
|
32
|
+
private isProcessing;
|
|
33
|
+
private processTimeout?;
|
|
27
34
|
constructor(options?: LoggerOptions);
|
|
28
35
|
/**
|
|
29
36
|
* Sets the minimum log level for filtering messages.
|
|
@@ -37,6 +44,15 @@ declare class Logger {
|
|
|
37
44
|
* @param args - The log arguments.
|
|
38
45
|
*/
|
|
39
46
|
private sendToDiscord;
|
|
47
|
+
/**
|
|
48
|
+
* Processes the Discord queue by sending batches of embeds.
|
|
49
|
+
*/
|
|
50
|
+
private processQueue;
|
|
51
|
+
/**
|
|
52
|
+
* Sends a batch of embeds to Discord.
|
|
53
|
+
* @param embeds - The embeds to send.
|
|
54
|
+
*/
|
|
55
|
+
private sendBatch;
|
|
40
56
|
/**
|
|
41
57
|
* Checks if a log level should be output based on the current log level.
|
|
42
58
|
* @param level - The log level to check.
|
package/dist/index.d.ts
CHANGED
|
@@ -8,14 +8,18 @@ interface TimestampTypes {
|
|
|
8
8
|
interface DiscordOptions {
|
|
9
9
|
enable: boolean;
|
|
10
10
|
webhookURL: string;
|
|
11
|
+
batchSize?: number;
|
|
12
|
+
batchDelay?: number;
|
|
13
|
+
maxRetries?: number;
|
|
14
|
+
retryDelayBase?: number;
|
|
11
15
|
formatEmbed?: (level: LogLevel, timestamp: string, message: string) => Record<string, unknown>;
|
|
12
16
|
}
|
|
13
17
|
interface LoggerOptions {
|
|
18
|
+
level?: LogLevel;
|
|
14
19
|
enableColors?: boolean;
|
|
20
|
+
discord?: DiscordOptions;
|
|
15
21
|
formatTimestamp?: (types: TimestampTypes, date?: Date) => [TimestampType, string];
|
|
16
22
|
formatLog?: (level: string, timestamp: string, args: unknown[]) => string;
|
|
17
|
-
level?: LogLevel;
|
|
18
|
-
discord?: DiscordOptions;
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
/**
|
|
@@ -24,6 +28,9 @@ interface LoggerOptions {
|
|
|
24
28
|
declare class Logger {
|
|
25
29
|
private options;
|
|
26
30
|
private level;
|
|
31
|
+
private discordQueue;
|
|
32
|
+
private isProcessing;
|
|
33
|
+
private processTimeout?;
|
|
27
34
|
constructor(options?: LoggerOptions);
|
|
28
35
|
/**
|
|
29
36
|
* Sets the minimum log level for filtering messages.
|
|
@@ -37,6 +44,15 @@ declare class Logger {
|
|
|
37
44
|
* @param args - The log arguments.
|
|
38
45
|
*/
|
|
39
46
|
private sendToDiscord;
|
|
47
|
+
/**
|
|
48
|
+
* Processes the Discord queue by sending batches of embeds.
|
|
49
|
+
*/
|
|
50
|
+
private processQueue;
|
|
51
|
+
/**
|
|
52
|
+
* Sends a batch of embeds to Discord.
|
|
53
|
+
* @param embeds - The embeds to send.
|
|
54
|
+
*/
|
|
55
|
+
private sendBatch;
|
|
40
56
|
/**
|
|
41
57
|
* Checks if a log level should be output based on the current log level.
|
|
42
58
|
* @param level - The log level to check.
|
package/dist/index.js
CHANGED
|
@@ -87,6 +87,8 @@ var LOG_LEVEL_PRIORITIES = {
|
|
|
87
87
|
};
|
|
88
88
|
var Logger = class {
|
|
89
89
|
constructor(options = {}) {
|
|
90
|
+
this.discordQueue = [];
|
|
91
|
+
this.isProcessing = false;
|
|
90
92
|
this.options = {
|
|
91
93
|
enableColors: options.enableColors ?? true,
|
|
92
94
|
formatTimestamp: options.formatTimestamp ?? defaultFormatTimestamp,
|
|
@@ -108,7 +110,7 @@ var Logger = class {
|
|
|
108
110
|
* @param timestamp - The formatted timestamp.
|
|
109
111
|
* @param args - The log arguments.
|
|
110
112
|
*/
|
|
111
|
-
|
|
113
|
+
sendToDiscord(level, timestamp, args) {
|
|
112
114
|
const discord = this.options.discord;
|
|
113
115
|
if (!discord?.enable) return;
|
|
114
116
|
try {
|
|
@@ -124,11 +126,49 @@ var Logger = class {
|
|
|
124
126
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
125
127
|
color: getDiscordColor(level)
|
|
126
128
|
};
|
|
129
|
+
this.discordQueue.push({ embed, retryCount: 0 });
|
|
130
|
+
if (!this.isProcessing) {
|
|
131
|
+
this.isProcessing = true;
|
|
132
|
+
setTimeout(() => this.processQueue(), 0);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
/**
|
|
136
|
+
* Processes the Discord queue by sending batches of embeds.
|
|
137
|
+
*/
|
|
138
|
+
processQueue() {
|
|
139
|
+
if (this.discordQueue.length === 0) {
|
|
140
|
+
this.isProcessing = false;
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
this.isProcessing = true;
|
|
144
|
+
const discord = this.options.discord;
|
|
145
|
+
const batchSize = discord.batchSize ?? 10;
|
|
146
|
+
const batch = this.discordQueue.splice(0, batchSize);
|
|
147
|
+
this.sendBatch(batch.map((item) => item.embed)).then(() => {
|
|
148
|
+
const delay = discord.batchDelay ?? 2e3;
|
|
149
|
+
this.processTimeout = setTimeout(() => this.processQueue(), delay);
|
|
150
|
+
}).catch(() => {
|
|
151
|
+
const maxRetries = discord.maxRetries ?? 3;
|
|
152
|
+
const retryItems = batch.filter((item) => item.retryCount < maxRetries).map((item) => ({
|
|
153
|
+
...item,
|
|
154
|
+
retryCount: item.retryCount + 1
|
|
155
|
+
}));
|
|
156
|
+
this.discordQueue.unshift(...retryItems);
|
|
157
|
+
const retryDelayBase = discord.retryDelayBase ?? 1e3;
|
|
158
|
+
const delay = retryDelayBase * Math.pow(2, batch[0]?.retryCount ?? 0);
|
|
159
|
+
this.processTimeout = setTimeout(() => this.processQueue(), delay);
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Sends a batch of embeds to Discord.
|
|
164
|
+
* @param embeds - The embeds to send.
|
|
165
|
+
*/
|
|
166
|
+
async sendBatch(embeds) {
|
|
167
|
+
const discord = this.options.discord;
|
|
127
168
|
await fetch(discord.webhookURL, {
|
|
128
169
|
method: "POST",
|
|
129
170
|
headers: { "Content-Type": "application/json" },
|
|
130
|
-
body: JSON.stringify({ embeds
|
|
131
|
-
}).catch(() => {
|
|
171
|
+
body: JSON.stringify({ embeds })
|
|
132
172
|
});
|
|
133
173
|
}
|
|
134
174
|
/**
|
|
@@ -197,4 +237,3 @@ var Logger = class {
|
|
|
197
237
|
Logger,
|
|
198
238
|
TIMESTAMP_TYPES
|
|
199
239
|
});
|
|
200
|
-
//# sourceMappingURL=index.js.map
|
package/dist/index.mjs
CHANGED
|
@@ -50,6 +50,8 @@ var LOG_LEVEL_PRIORITIES = {
|
|
|
50
50
|
};
|
|
51
51
|
var Logger = class {
|
|
52
52
|
constructor(options = {}) {
|
|
53
|
+
this.discordQueue = [];
|
|
54
|
+
this.isProcessing = false;
|
|
53
55
|
this.options = {
|
|
54
56
|
enableColors: options.enableColors ?? true,
|
|
55
57
|
formatTimestamp: options.formatTimestamp ?? defaultFormatTimestamp,
|
|
@@ -71,7 +73,7 @@ var Logger = class {
|
|
|
71
73
|
* @param timestamp - The formatted timestamp.
|
|
72
74
|
* @param args - The log arguments.
|
|
73
75
|
*/
|
|
74
|
-
|
|
76
|
+
sendToDiscord(level, timestamp, args) {
|
|
75
77
|
const discord = this.options.discord;
|
|
76
78
|
if (!discord?.enable) return;
|
|
77
79
|
try {
|
|
@@ -87,11 +89,49 @@ var Logger = class {
|
|
|
87
89
|
timestamp: (/* @__PURE__ */ new Date()).toISOString(),
|
|
88
90
|
color: getDiscordColor(level)
|
|
89
91
|
};
|
|
92
|
+
this.discordQueue.push({ embed, retryCount: 0 });
|
|
93
|
+
if (!this.isProcessing) {
|
|
94
|
+
this.isProcessing = true;
|
|
95
|
+
setTimeout(() => this.processQueue(), 0);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Processes the Discord queue by sending batches of embeds.
|
|
100
|
+
*/
|
|
101
|
+
processQueue() {
|
|
102
|
+
if (this.discordQueue.length === 0) {
|
|
103
|
+
this.isProcessing = false;
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
this.isProcessing = true;
|
|
107
|
+
const discord = this.options.discord;
|
|
108
|
+
const batchSize = discord.batchSize ?? 10;
|
|
109
|
+
const batch = this.discordQueue.splice(0, batchSize);
|
|
110
|
+
this.sendBatch(batch.map((item) => item.embed)).then(() => {
|
|
111
|
+
const delay = discord.batchDelay ?? 2e3;
|
|
112
|
+
this.processTimeout = setTimeout(() => this.processQueue(), delay);
|
|
113
|
+
}).catch(() => {
|
|
114
|
+
const maxRetries = discord.maxRetries ?? 3;
|
|
115
|
+
const retryItems = batch.filter((item) => item.retryCount < maxRetries).map((item) => ({
|
|
116
|
+
...item,
|
|
117
|
+
retryCount: item.retryCount + 1
|
|
118
|
+
}));
|
|
119
|
+
this.discordQueue.unshift(...retryItems);
|
|
120
|
+
const retryDelayBase = discord.retryDelayBase ?? 1e3;
|
|
121
|
+
const delay = retryDelayBase * Math.pow(2, batch[0]?.retryCount ?? 0);
|
|
122
|
+
this.processTimeout = setTimeout(() => this.processQueue(), delay);
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Sends a batch of embeds to Discord.
|
|
127
|
+
* @param embeds - The embeds to send.
|
|
128
|
+
*/
|
|
129
|
+
async sendBatch(embeds) {
|
|
130
|
+
const discord = this.options.discord;
|
|
90
131
|
await fetch(discord.webhookURL, {
|
|
91
132
|
method: "POST",
|
|
92
133
|
headers: { "Content-Type": "application/json" },
|
|
93
|
-
body: JSON.stringify({ embeds
|
|
94
|
-
}).catch(() => {
|
|
134
|
+
body: JSON.stringify({ embeds })
|
|
95
135
|
});
|
|
96
136
|
}
|
|
97
137
|
/**
|
|
@@ -159,4 +199,3 @@ export {
|
|
|
159
199
|
Logger,
|
|
160
200
|
TIMESTAMP_TYPES
|
|
161
201
|
};
|
|
162
|
-
//# sourceMappingURL=index.mjs.map
|
package/package.json
CHANGED
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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"]}
|