@x-oasis/log 0.1.1 → 0.1.2
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 +4 -0
- package/package.json +5 -1
- package/.turbo/turbo-build.log +0 -26
- package/CHANGELOG.md +0 -17
- package/src/index.ts +0 -39
- package/src/logger.ts +0 -247
- package/src/types.ts +0 -109
- package/src/utils.ts +0 -63
- package/test/test.spec.ts +0 -333
- package/tsconfig.build.json +0 -11
- package/tsconfig.json +0 -7
- package/vitest.config.ts +0 -21
package/README.md
CHANGED
|
@@ -335,6 +335,10 @@ This library is designed to work in all modern browsers. It uses standard browse
|
|
|
335
335
|
|
|
336
336
|
Full TypeScript support with comprehensive type definitions included.
|
|
337
337
|
|
|
338
|
+
## Reading More
|
|
339
|
+
- [loglayer](https://github.com/loglayer/loglayer)
|
|
340
|
+
- [loglevel](https://github.com/pimterry/loglevel)
|
|
341
|
+
|
|
338
342
|
## License
|
|
339
343
|
|
|
340
344
|
ISC
|
package/package.json
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@x-oasis/log",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "A friendly logging library for browser environments",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"typings": "dist/index.d.ts",
|
|
7
7
|
"module": "dist/log.esm.js",
|
|
8
|
+
"files": [
|
|
9
|
+
"dist",
|
|
10
|
+
"index.ts"
|
|
11
|
+
],
|
|
8
12
|
"publishConfig": {
|
|
9
13
|
"access": "public"
|
|
10
14
|
},
|
package/.turbo/turbo-build.log
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
> @x-oasis/log@0.1.1 build /home/runner/work/x-oasis/x-oasis/packages/error/log
|
|
3
|
-
> tsdx build --tsconfig tsconfig.build.json
|
|
4
|
-
|
|
5
|
-
@rollup/plugin-replace: 'preventAssignment' currently defaults to false. It is recommended to set this option to `true`, as the next major version will default this option to `true`.
|
|
6
|
-
@rollup/plugin-replace: 'preventAssignment' currently defaults to false. It is recommended to set this option to `true`, as the next major version will default this option to `true`.
|
|
7
|
-
⠙ Creating entry file
|
|
8
|
-
[2K[1A[2K[G⠙ Building modules
|
|
9
|
-
[2K[1A[2K[G✓ Creating entry file 4.5 secs
|
|
10
|
-
⠹ Building modules
|
|
11
|
-
[2K[1A[2K[G⠸ Building modules
|
|
12
|
-
[2K[1A[2K[G⠼ Building modules
|
|
13
|
-
[2K[1A[2K[G⠴ Building modules
|
|
14
|
-
[2K[1A[2K[G⠦ Building modules
|
|
15
|
-
[2K[1A[2K[G⠧ Building modules
|
|
16
|
-
[2K[1A[2K[G⠇ Building modules
|
|
17
|
-
[2K[1A[2K[G⠏ Building modules
|
|
18
|
-
[2K[1A[2K[G⠋ Building modules
|
|
19
|
-
[2K[1A[2K[G⠙ Building modules
|
|
20
|
-
[2K[1A[2K[G⠹ Building modules
|
|
21
|
-
[2K[1A[2K[G⠸ Building modules
|
|
22
|
-
[2K[1A[2K[G⠼ Building modules
|
|
23
|
-
[tsdx]: Your rootDir is currently set to "./". Please change your rootDir to "./src".
|
|
24
|
-
TSDX has deprecated setting tsconfig.compilerOptions.rootDir to "./" as it caused buggy output for declarationMaps and more.
|
|
25
|
-
You may also need to change your include to remove "test", which also caused declarations to be unnecessarily created for test files.
|
|
26
|
-
[2K[1A[2K[G✓ Building modules 14.7 secs
|
package/CHANGELOG.md
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
# @x-oasis/log
|
|
2
|
-
|
|
3
|
-
## 0.1.1
|
|
4
|
-
|
|
5
|
-
### Patch Changes
|
|
6
|
-
|
|
7
|
-
- f1aae14: bump version
|
|
8
|
-
|
|
9
|
-
## 0.1.0
|
|
10
|
-
|
|
11
|
-
### Initial Release
|
|
12
|
-
|
|
13
|
-
- Initial release of the log library
|
|
14
|
-
- Support for multiple log levels (trace, debug, info, warn, error)
|
|
15
|
-
- Browser-friendly API with chainable methods
|
|
16
|
-
- Context and metadata support
|
|
17
|
-
- Configurable log levels and output handlers
|
package/src/index.ts
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { Logger } from './logger';
|
|
2
|
-
import { LogLevel } from './types';
|
|
3
|
-
|
|
4
|
-
export { Logger, LogLevel };
|
|
5
|
-
export type {
|
|
6
|
-
LogEntry,
|
|
7
|
-
LoggerOptions,
|
|
8
|
-
LoggerChain,
|
|
9
|
-
OutputHandler,
|
|
10
|
-
} from './types';
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* Default logger instance
|
|
14
|
-
*/
|
|
15
|
-
export const defaultLogger = new Logger();
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Convenience methods using the default logger
|
|
19
|
-
*/
|
|
20
|
-
export const log = {
|
|
21
|
-
trace: (message: string, context?: Record<string, unknown>) =>
|
|
22
|
-
defaultLogger.trace(message, context),
|
|
23
|
-
debug: (message: string, context?: Record<string, unknown>) =>
|
|
24
|
-
defaultLogger.debug(message, context),
|
|
25
|
-
info: (message: string, context?: Record<string, unknown>) =>
|
|
26
|
-
defaultLogger.info(message, context),
|
|
27
|
-
warn: (message: string, context?: Record<string, unknown>) =>
|
|
28
|
-
defaultLogger.warn(message, context),
|
|
29
|
-
error: (message: string, context?: Record<string, unknown>) =>
|
|
30
|
-
defaultLogger.error(message, context),
|
|
31
|
-
setLevel: (level: LogLevel | keyof typeof LogLevel) =>
|
|
32
|
-
defaultLogger.setLevel(level),
|
|
33
|
-
withContext: (context: Record<string, unknown>) =>
|
|
34
|
-
defaultLogger.withContext(context),
|
|
35
|
-
withPrefix: (prefix: string) => defaultLogger.withPrefix(prefix),
|
|
36
|
-
chain: () => defaultLogger.chain(),
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
export default Logger;
|
package/src/logger.ts
DELETED
|
@@ -1,247 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
LogLevel,
|
|
3
|
-
LogEntry,
|
|
4
|
-
LoggerOptions,
|
|
5
|
-
LoggerChain,
|
|
6
|
-
OutputHandler,
|
|
7
|
-
} from './types';
|
|
8
|
-
import { parseLogLevel, createConsoleHandler } from './utils';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Main Logger class
|
|
12
|
-
*/
|
|
13
|
-
export class Logger {
|
|
14
|
-
private level: LogLevel;
|
|
15
|
-
private handler: OutputHandler;
|
|
16
|
-
private enableTimestamp: boolean;
|
|
17
|
-
private defaultContext?: Record<string, unknown>;
|
|
18
|
-
private defaultPrefix?: string;
|
|
19
|
-
|
|
20
|
-
constructor(options: LoggerOptions = {}) {
|
|
21
|
-
this.level = options.level ? parseLogLevel(options.level) : LogLevel.INFO;
|
|
22
|
-
this.handler = options.handler || createConsoleHandler();
|
|
23
|
-
this.enableTimestamp =
|
|
24
|
-
options.enableTimestamp !== undefined ? options.enableTimestamp : true;
|
|
25
|
-
this.defaultContext = options.defaultContext;
|
|
26
|
-
this.defaultPrefix = options.defaultPrefix;
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* Set the minimum log level
|
|
31
|
-
*/
|
|
32
|
-
setLevel(level: LogLevel | keyof typeof LogLevel): void {
|
|
33
|
-
this.level = parseLogLevel(level);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Get the current log level
|
|
38
|
-
*/
|
|
39
|
-
getLevel(): LogLevel {
|
|
40
|
-
return this.level;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Set a custom output handler
|
|
45
|
-
*/
|
|
46
|
-
setHandler(handler: OutputHandler): void {
|
|
47
|
-
this.handler = handler;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Set default context that will be included in all logs
|
|
52
|
-
*/
|
|
53
|
-
setDefaultContext(context: Record<string, unknown>): void {
|
|
54
|
-
this.defaultContext = context;
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Set default prefix for all log messages
|
|
59
|
-
*/
|
|
60
|
-
setDefaultPrefix(prefix: string): void {
|
|
61
|
-
this.defaultPrefix = prefix;
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
/**
|
|
65
|
-
* Create a chainable logger instance
|
|
66
|
-
*/
|
|
67
|
-
chain(): LoggerChain {
|
|
68
|
-
return new LoggerChainBuilder(this);
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
/**
|
|
72
|
-
* Log at trace level
|
|
73
|
-
*/
|
|
74
|
-
trace(message: string, context?: Record<string, unknown>): void {
|
|
75
|
-
this.log(LogLevel.TRACE, message, context);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
/**
|
|
79
|
-
* Log at debug level
|
|
80
|
-
*/
|
|
81
|
-
debug(message: string, context?: Record<string, unknown>): void {
|
|
82
|
-
this.log(LogLevel.DEBUG, message, context);
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Log at info level
|
|
87
|
-
*/
|
|
88
|
-
info(message: string, context?: Record<string, unknown>): void {
|
|
89
|
-
this.log(LogLevel.INFO, message, context);
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
/**
|
|
93
|
-
* Log at warn level
|
|
94
|
-
*/
|
|
95
|
-
warn(message: string, context?: Record<string, unknown>): void {
|
|
96
|
-
this.log(LogLevel.WARN, message, context);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
* Log at error level
|
|
101
|
-
*/
|
|
102
|
-
error(message: string, context?: Record<string, unknown>): void {
|
|
103
|
-
this.log(LogLevel.ERROR, message, context);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
/**
|
|
107
|
-
* Internal log method
|
|
108
|
-
*/
|
|
109
|
-
private log(
|
|
110
|
-
level: LogLevel,
|
|
111
|
-
message: string,
|
|
112
|
-
context?: Record<string, unknown>
|
|
113
|
-
): void {
|
|
114
|
-
if (level < this.level) {
|
|
115
|
-
return;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
const entry: LogEntry = {
|
|
119
|
-
level,
|
|
120
|
-
message,
|
|
121
|
-
timestamp: this.enableTimestamp ? Date.now() : 0,
|
|
122
|
-
prefix: this.defaultPrefix,
|
|
123
|
-
};
|
|
124
|
-
|
|
125
|
-
// Merge default context with provided context
|
|
126
|
-
if (this.defaultContext || context) {
|
|
127
|
-
entry.context = {
|
|
128
|
-
...this.defaultContext,
|
|
129
|
-
...context,
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
this.handler(entry);
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
/**
|
|
137
|
-
* Create a chainable logger with initial context
|
|
138
|
-
*/
|
|
139
|
-
withContext(context: Record<string, unknown>): LoggerChain {
|
|
140
|
-
return new LoggerChainBuilder(this).withContext(context);
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Create a chainable logger with initial prefix
|
|
145
|
-
*/
|
|
146
|
-
withPrefix(prefix: string): LoggerChain {
|
|
147
|
-
return new LoggerChainBuilder(this).withPrefix(prefix);
|
|
148
|
-
}
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Chainable logger builder
|
|
153
|
-
*/
|
|
154
|
-
class LoggerChainBuilder implements LoggerChain {
|
|
155
|
-
private logger: Logger;
|
|
156
|
-
private context?: Record<string, unknown>;
|
|
157
|
-
private metadata?: Record<string, unknown>;
|
|
158
|
-
private errorObj?: Error;
|
|
159
|
-
private prefix?: string;
|
|
160
|
-
|
|
161
|
-
constructor(logger: Logger) {
|
|
162
|
-
this.logger = logger;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
withContext(context: Record<string, unknown>): LoggerChain {
|
|
166
|
-
this.context = {
|
|
167
|
-
...this.context,
|
|
168
|
-
...context,
|
|
169
|
-
};
|
|
170
|
-
return this;
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
withMetadata(metadata: Record<string, unknown>): LoggerChain {
|
|
174
|
-
this.metadata = {
|
|
175
|
-
...this.metadata,
|
|
176
|
-
...metadata,
|
|
177
|
-
};
|
|
178
|
-
return this;
|
|
179
|
-
}
|
|
180
|
-
|
|
181
|
-
withError(error: Error): LoggerChain {
|
|
182
|
-
this.errorObj = error;
|
|
183
|
-
return this;
|
|
184
|
-
}
|
|
185
|
-
|
|
186
|
-
withPrefix(prefix: string): LoggerChain {
|
|
187
|
-
this.prefix = prefix;
|
|
188
|
-
return this;
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
private createEntry(level: LogLevel, message: string): LogEntry {
|
|
192
|
-
const entry: LogEntry = {
|
|
193
|
-
level,
|
|
194
|
-
message,
|
|
195
|
-
timestamp: this.logger['enableTimestamp'] ? Date.now() : 0,
|
|
196
|
-
prefix: this.prefix || this.logger['defaultPrefix'],
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
// Merge contexts
|
|
200
|
-
const defaultContext = this.logger['defaultContext'];
|
|
201
|
-
if (defaultContext || this.context) {
|
|
202
|
-
entry.context = {
|
|
203
|
-
...defaultContext,
|
|
204
|
-
...this.context,
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
if (this.metadata) {
|
|
209
|
-
entry.metadata = this.metadata;
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
if (this.errorObj) {
|
|
213
|
-
entry.error = this.errorObj;
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
return entry;
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
private log(level: LogLevel, message: string): void {
|
|
220
|
-
if (level < this.logger.getLevel()) {
|
|
221
|
-
return;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
const entry = this.createEntry(level, message);
|
|
225
|
-
this.logger['handler'](entry);
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
trace(message: string): void {
|
|
229
|
-
this.log(LogLevel.TRACE, message);
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
debug(message: string): void {
|
|
233
|
-
this.log(LogLevel.DEBUG, message);
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
info(message: string): void {
|
|
237
|
-
this.log(LogLevel.INFO, message);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
warn(message: string): void {
|
|
241
|
-
this.log(LogLevel.WARN, message);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
error(message: string): void {
|
|
245
|
-
this.log(LogLevel.ERROR, message);
|
|
246
|
-
}
|
|
247
|
-
}
|
package/src/types.ts
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Log levels in order of severity
|
|
3
|
-
*/
|
|
4
|
-
export enum LogLevel {
|
|
5
|
-
TRACE = 0,
|
|
6
|
-
DEBUG = 1,
|
|
7
|
-
INFO = 2,
|
|
8
|
-
WARN = 3,
|
|
9
|
-
ERROR = 4,
|
|
10
|
-
SILENT = 5,
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Log entry data structure
|
|
15
|
-
*/
|
|
16
|
-
export interface LogEntry {
|
|
17
|
-
level: LogLevel;
|
|
18
|
-
message: string;
|
|
19
|
-
timestamp: number;
|
|
20
|
-
context?: Record<string, unknown>;
|
|
21
|
-
metadata?: Record<string, unknown>;
|
|
22
|
-
error?: Error;
|
|
23
|
-
prefix?: string;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Output handler function type
|
|
28
|
-
*/
|
|
29
|
-
export type OutputHandler = (entry: LogEntry) => void;
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Logger configuration options
|
|
33
|
-
*/
|
|
34
|
-
export interface LoggerOptions {
|
|
35
|
-
/**
|
|
36
|
-
* Minimum log level to output (default: LogLevel.INFO)
|
|
37
|
-
*/
|
|
38
|
-
level?: LogLevel | keyof typeof LogLevel;
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Custom output handler (default: console)
|
|
42
|
-
*/
|
|
43
|
-
handler?: OutputHandler;
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Enable timestamps in log entries (default: true)
|
|
47
|
-
*/
|
|
48
|
-
enableTimestamp?: boolean;
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Default context that will be included in all logs
|
|
52
|
-
*/
|
|
53
|
-
defaultContext?: Record<string, unknown>;
|
|
54
|
-
|
|
55
|
-
/**
|
|
56
|
-
* Default prefix for all log messages
|
|
57
|
-
*/
|
|
58
|
-
defaultPrefix?: string;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
/**
|
|
62
|
-
* Chainable logger interface
|
|
63
|
-
*/
|
|
64
|
-
export interface LoggerChain {
|
|
65
|
-
/**
|
|
66
|
-
* Add context data that will be included in this log entry
|
|
67
|
-
*/
|
|
68
|
-
withContext(context: Record<string, unknown>): LoggerChain;
|
|
69
|
-
|
|
70
|
-
/**
|
|
71
|
-
* Add metadata that will be included in this log entry
|
|
72
|
-
*/
|
|
73
|
-
withMetadata(metadata: Record<string, unknown>): LoggerChain;
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Add an error object to this log entry
|
|
77
|
-
*/
|
|
78
|
-
withError(error: Error): LoggerChain;
|
|
79
|
-
|
|
80
|
-
/**
|
|
81
|
-
* Add a prefix to this log message
|
|
82
|
-
*/
|
|
83
|
-
withPrefix(prefix: string): LoggerChain;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Log at trace level
|
|
87
|
-
*/
|
|
88
|
-
trace(message: string): void;
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* Log at debug level
|
|
92
|
-
*/
|
|
93
|
-
debug(message: string): void;
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Log at info level
|
|
97
|
-
*/
|
|
98
|
-
info(message: string): void;
|
|
99
|
-
|
|
100
|
-
/**
|
|
101
|
-
* Log at warn level
|
|
102
|
-
*/
|
|
103
|
-
warn(message: string): void;
|
|
104
|
-
|
|
105
|
-
/**
|
|
106
|
-
* Log at error level
|
|
107
|
-
*/
|
|
108
|
-
error(message: string): void;
|
|
109
|
-
}
|
package/src/utils.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { LogLevel, LogEntry } from './types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Convert log level string to LogLevel enum
|
|
5
|
-
*/
|
|
6
|
-
export function parseLogLevel(
|
|
7
|
-
level: LogLevel | keyof typeof LogLevel
|
|
8
|
-
): LogLevel {
|
|
9
|
-
if (typeof level === 'number') {
|
|
10
|
-
return level;
|
|
11
|
-
}
|
|
12
|
-
return LogLevel[level] ?? LogLevel.INFO;
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* Get log level name
|
|
17
|
-
*/
|
|
18
|
-
export function getLogLevelName(level: LogLevel): string {
|
|
19
|
-
return LogLevel[level] ?? 'UNKNOWN';
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Default console output handler
|
|
24
|
-
*/
|
|
25
|
-
export function createConsoleHandler(): (entry: LogEntry) => void {
|
|
26
|
-
const consoleMethods: Record<number, typeof console.log> = {
|
|
27
|
-
[LogLevel.TRACE]: console.trace || console.debug,
|
|
28
|
-
[LogLevel.DEBUG]: console.debug,
|
|
29
|
-
[LogLevel.INFO]: console.info,
|
|
30
|
-
[LogLevel.WARN]: console.warn,
|
|
31
|
-
[LogLevel.ERROR]: console.error,
|
|
32
|
-
};
|
|
33
|
-
|
|
34
|
-
return (entry) => {
|
|
35
|
-
const method = consoleMethods[entry.level] || console.log;
|
|
36
|
-
const parts: unknown[] = [];
|
|
37
|
-
|
|
38
|
-
// Add prefix if present
|
|
39
|
-
if (entry.prefix) {
|
|
40
|
-
parts.push(entry.prefix);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// Add message
|
|
44
|
-
parts.push(entry.message);
|
|
45
|
-
|
|
46
|
-
// Add context if present
|
|
47
|
-
if (entry.context && Object.keys(entry.context).length > 0) {
|
|
48
|
-
parts.push('\nContext:', entry.context);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
// Add metadata if present
|
|
52
|
-
if (entry.metadata && Object.keys(entry.metadata).length > 0) {
|
|
53
|
-
parts.push('\nMetadata:', entry.metadata);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
// Add error if present
|
|
57
|
-
if (entry.error) {
|
|
58
|
-
parts.push('\nError:', entry.error);
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
method(...parts);
|
|
62
|
-
};
|
|
63
|
-
}
|
package/test/test.spec.ts
DELETED
|
@@ -1,333 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, vi, beforeEach } from 'vitest';
|
|
2
|
-
import { Logger, LogLevel } from '../src';
|
|
3
|
-
// import { log } from '../src';
|
|
4
|
-
|
|
5
|
-
describe('Logger', () => {
|
|
6
|
-
let mockHandler: ReturnType<typeof vi.fn>;
|
|
7
|
-
let logger: Logger;
|
|
8
|
-
|
|
9
|
-
beforeEach(() => {
|
|
10
|
-
mockHandler = vi.fn();
|
|
11
|
-
logger = new Logger({
|
|
12
|
-
handler: mockHandler,
|
|
13
|
-
enableTimestamp: false,
|
|
14
|
-
});
|
|
15
|
-
});
|
|
16
|
-
|
|
17
|
-
describe('Basic logging', () => {
|
|
18
|
-
it('should log at trace level', () => {
|
|
19
|
-
logger.setLevel(LogLevel.TRACE);
|
|
20
|
-
logger.trace('test message');
|
|
21
|
-
|
|
22
|
-
expect(mockHandler).toHaveBeenCalledTimes(1);
|
|
23
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
24
|
-
expect.objectContaining({
|
|
25
|
-
level: LogLevel.TRACE,
|
|
26
|
-
message: 'test message',
|
|
27
|
-
})
|
|
28
|
-
);
|
|
29
|
-
});
|
|
30
|
-
|
|
31
|
-
it('should log at debug level', () => {
|
|
32
|
-
logger.setLevel(LogLevel.DEBUG);
|
|
33
|
-
logger.debug('test message');
|
|
34
|
-
|
|
35
|
-
expect(mockHandler).toHaveBeenCalledTimes(1);
|
|
36
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
37
|
-
expect.objectContaining({
|
|
38
|
-
level: LogLevel.DEBUG,
|
|
39
|
-
message: 'test message',
|
|
40
|
-
})
|
|
41
|
-
);
|
|
42
|
-
});
|
|
43
|
-
|
|
44
|
-
it('should log at info level', () => {
|
|
45
|
-
logger.info('test message');
|
|
46
|
-
|
|
47
|
-
expect(mockHandler).toHaveBeenCalledTimes(1);
|
|
48
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
49
|
-
expect.objectContaining({
|
|
50
|
-
level: LogLevel.INFO,
|
|
51
|
-
message: 'test message',
|
|
52
|
-
})
|
|
53
|
-
);
|
|
54
|
-
});
|
|
55
|
-
|
|
56
|
-
it('should log at warn level', () => {
|
|
57
|
-
logger.warn('test message');
|
|
58
|
-
|
|
59
|
-
expect(mockHandler).toHaveBeenCalledTimes(1);
|
|
60
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
61
|
-
expect.objectContaining({
|
|
62
|
-
level: LogLevel.WARN,
|
|
63
|
-
message: 'test message',
|
|
64
|
-
})
|
|
65
|
-
);
|
|
66
|
-
});
|
|
67
|
-
|
|
68
|
-
it('should log at error level', () => {
|
|
69
|
-
logger.error('test message');
|
|
70
|
-
|
|
71
|
-
expect(mockHandler).toHaveBeenCalledTimes(1);
|
|
72
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
73
|
-
expect.objectContaining({
|
|
74
|
-
level: LogLevel.ERROR,
|
|
75
|
-
message: 'test message',
|
|
76
|
-
})
|
|
77
|
-
);
|
|
78
|
-
});
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
describe('Log level filtering', () => {
|
|
82
|
-
it('should not log messages below the set level', () => {
|
|
83
|
-
logger.setLevel(LogLevel.WARN);
|
|
84
|
-
logger.trace('trace message');
|
|
85
|
-
logger.debug('debug message');
|
|
86
|
-
logger.info('info message');
|
|
87
|
-
|
|
88
|
-
expect(mockHandler).not.toHaveBeenCalled();
|
|
89
|
-
|
|
90
|
-
logger.warn('warn message');
|
|
91
|
-
logger.error('error message');
|
|
92
|
-
|
|
93
|
-
expect(mockHandler).toHaveBeenCalledTimes(2);
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
it('should log all messages when level is TRACE', () => {
|
|
97
|
-
logger.setLevel(LogLevel.TRACE);
|
|
98
|
-
logger.trace('trace');
|
|
99
|
-
logger.debug('debug');
|
|
100
|
-
logger.info('info');
|
|
101
|
-
logger.warn('warn');
|
|
102
|
-
logger.error('error');
|
|
103
|
-
|
|
104
|
-
expect(mockHandler).toHaveBeenCalledTimes(5);
|
|
105
|
-
});
|
|
106
|
-
});
|
|
107
|
-
|
|
108
|
-
describe('Context support', () => {
|
|
109
|
-
it('should include context in log entries', () => {
|
|
110
|
-
logger.info('test message', { userId: '123', action: 'login' });
|
|
111
|
-
|
|
112
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
113
|
-
expect.objectContaining({
|
|
114
|
-
context: {
|
|
115
|
-
userId: '123',
|
|
116
|
-
action: 'login',
|
|
117
|
-
},
|
|
118
|
-
})
|
|
119
|
-
);
|
|
120
|
-
});
|
|
121
|
-
|
|
122
|
-
it('should merge default context with provided context', () => {
|
|
123
|
-
logger.setDefaultContext({ app: 'my-app', version: '1.0.0' });
|
|
124
|
-
logger.info('test message', { userId: '123' });
|
|
125
|
-
|
|
126
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
127
|
-
expect.objectContaining({
|
|
128
|
-
context: {
|
|
129
|
-
app: 'my-app',
|
|
130
|
-
version: '1.0.0',
|
|
131
|
-
userId: '123',
|
|
132
|
-
},
|
|
133
|
-
})
|
|
134
|
-
);
|
|
135
|
-
});
|
|
136
|
-
});
|
|
137
|
-
|
|
138
|
-
describe('Chainable API', () => {
|
|
139
|
-
it('should support chaining with context', () => {
|
|
140
|
-
logger
|
|
141
|
-
.chain()
|
|
142
|
-
.withContext({ userId: '123' })
|
|
143
|
-
.withContext({ action: 'login' })
|
|
144
|
-
.info('User logged in');
|
|
145
|
-
|
|
146
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
147
|
-
expect.objectContaining({
|
|
148
|
-
context: {
|
|
149
|
-
userId: '123',
|
|
150
|
-
action: 'login',
|
|
151
|
-
},
|
|
152
|
-
message: 'User logged in',
|
|
153
|
-
})
|
|
154
|
-
);
|
|
155
|
-
});
|
|
156
|
-
|
|
157
|
-
it('should support chaining with metadata', () => {
|
|
158
|
-
logger
|
|
159
|
-
.chain()
|
|
160
|
-
.withMetadata({ duration: 150, status: 'success' })
|
|
161
|
-
.info('Request completed');
|
|
162
|
-
|
|
163
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
164
|
-
expect.objectContaining({
|
|
165
|
-
metadata: {
|
|
166
|
-
duration: 150,
|
|
167
|
-
status: 'success',
|
|
168
|
-
},
|
|
169
|
-
message: 'Request completed',
|
|
170
|
-
})
|
|
171
|
-
);
|
|
172
|
-
});
|
|
173
|
-
|
|
174
|
-
it('should support chaining with error', () => {
|
|
175
|
-
const error = new Error('Something went wrong');
|
|
176
|
-
logger.chain().withError(error).error('Operation failed');
|
|
177
|
-
|
|
178
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
179
|
-
expect.objectContaining({
|
|
180
|
-
error,
|
|
181
|
-
message: 'Operation failed',
|
|
182
|
-
})
|
|
183
|
-
);
|
|
184
|
-
});
|
|
185
|
-
|
|
186
|
-
it('should support chaining with prefix', () => {
|
|
187
|
-
logger.chain().withPrefix('[API]').info('Request received');
|
|
188
|
-
|
|
189
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
190
|
-
expect.objectContaining({
|
|
191
|
-
prefix: '[API]',
|
|
192
|
-
message: 'Request received',
|
|
193
|
-
})
|
|
194
|
-
);
|
|
195
|
-
});
|
|
196
|
-
|
|
197
|
-
it('should support complex chaining', () => {
|
|
198
|
-
const error = new Error('Validation failed');
|
|
199
|
-
logger
|
|
200
|
-
.chain()
|
|
201
|
-
.withContext({ userId: '123' })
|
|
202
|
-
.withMetadata({ field: 'email', value: 'invalid' })
|
|
203
|
-
.withError(error)
|
|
204
|
-
.withPrefix('[VALIDATION]')
|
|
205
|
-
.warn('Validation error');
|
|
206
|
-
|
|
207
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
208
|
-
expect.objectContaining({
|
|
209
|
-
context: { userId: '123' },
|
|
210
|
-
metadata: { field: 'email', value: 'invalid' },
|
|
211
|
-
error,
|
|
212
|
-
prefix: '[VALIDATION]',
|
|
213
|
-
message: 'Validation error',
|
|
214
|
-
})
|
|
215
|
-
);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
describe('withContext and withPrefix methods', () => {
|
|
220
|
-
it('should create chainable logger with context', () => {
|
|
221
|
-
logger.withContext({ userId: '123' }).info('User action');
|
|
222
|
-
|
|
223
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
224
|
-
expect.objectContaining({
|
|
225
|
-
context: { userId: '123' },
|
|
226
|
-
})
|
|
227
|
-
);
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
it('should create chainable logger with prefix', () => {
|
|
231
|
-
logger.withPrefix('[APP]').info('Application started');
|
|
232
|
-
|
|
233
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
234
|
-
expect.objectContaining({
|
|
235
|
-
prefix: '[APP]',
|
|
236
|
-
})
|
|
237
|
-
);
|
|
238
|
-
});
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
describe('Default prefix', () => {
|
|
242
|
-
it('should include default prefix in all logs', () => {
|
|
243
|
-
logger.setDefaultPrefix('[MY-APP]');
|
|
244
|
-
logger.info('Test message');
|
|
245
|
-
|
|
246
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
247
|
-
expect.objectContaining({
|
|
248
|
-
prefix: '[MY-APP]',
|
|
249
|
-
})
|
|
250
|
-
);
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
it('should allow overriding default prefix with chain prefix', () => {
|
|
254
|
-
logger.setDefaultPrefix('[DEFAULT]');
|
|
255
|
-
logger.chain().withPrefix('[OVERRIDE]').info('Test message');
|
|
256
|
-
|
|
257
|
-
expect(mockHandler).toHaveBeenCalledWith(
|
|
258
|
-
expect.objectContaining({
|
|
259
|
-
prefix: '[OVERRIDE]',
|
|
260
|
-
})
|
|
261
|
-
);
|
|
262
|
-
});
|
|
263
|
-
});
|
|
264
|
-
|
|
265
|
-
describe('Timestamp', () => {
|
|
266
|
-
it('should include timestamp when enabled', () => {
|
|
267
|
-
const loggerWithTimestamp = new Logger({
|
|
268
|
-
handler: mockHandler,
|
|
269
|
-
enableTimestamp: true,
|
|
270
|
-
});
|
|
271
|
-
loggerWithTimestamp.info('test');
|
|
272
|
-
|
|
273
|
-
const call = mockHandler.mock.calls[0][0];
|
|
274
|
-
expect(call.timestamp).toBeGreaterThan(0);
|
|
275
|
-
});
|
|
276
|
-
|
|
277
|
-
it('should not include timestamp when disabled', () => {
|
|
278
|
-
logger.info('test');
|
|
279
|
-
|
|
280
|
-
const call = mockHandler.mock.calls[0][0];
|
|
281
|
-
expect(call.timestamp).toBe(0);
|
|
282
|
-
});
|
|
283
|
-
});
|
|
284
|
-
|
|
285
|
-
describe('Log level string parsing', () => {
|
|
286
|
-
it('should accept log level as string', () => {
|
|
287
|
-
logger.setLevel('DEBUG');
|
|
288
|
-
logger.setLevel('WARN');
|
|
289
|
-
logger.setLevel('ERROR');
|
|
290
|
-
|
|
291
|
-
expect(logger.getLevel()).toBe(LogLevel.ERROR);
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
it('should default to INFO for invalid string', () => {
|
|
295
|
-
logger.setLevel('INVALID' as any);
|
|
296
|
-
expect(logger.getLevel()).toBe(LogLevel.INFO);
|
|
297
|
-
});
|
|
298
|
-
});
|
|
299
|
-
});
|
|
300
|
-
|
|
301
|
-
// describe('Default logger (log)', () => {
|
|
302
|
-
// it('should provide convenience methods', () => {
|
|
303
|
-
// const originalConsole = console.info;
|
|
304
|
-
// const mockConsole = vi.fn();
|
|
305
|
-
// console.info = mockConsole;
|
|
306
|
-
|
|
307
|
-
// try {
|
|
308
|
-
// log.info('test message');
|
|
309
|
-
// expect(mockConsole).toHaveBeenCalled();
|
|
310
|
-
// } finally {
|
|
311
|
-
// console.info = originalConsole;
|
|
312
|
-
// }
|
|
313
|
-
// });
|
|
314
|
-
|
|
315
|
-
// it('should support setLevel', () => {
|
|
316
|
-
// expect(() => log.setLevel(LogLevel.DEBUG)).not.toThrow();
|
|
317
|
-
// });
|
|
318
|
-
|
|
319
|
-
// it('should support withContext', () => {
|
|
320
|
-
// const chain = log.withContext({ test: 'value' });
|
|
321
|
-
// expect(chain).toBeDefined();
|
|
322
|
-
// });
|
|
323
|
-
|
|
324
|
-
// it('should support withPrefix', () => {
|
|
325
|
-
// const chain = log.withPrefix('[TEST]');
|
|
326
|
-
// expect(chain).toBeDefined();
|
|
327
|
-
// });
|
|
328
|
-
|
|
329
|
-
// it('should support chain', () => {
|
|
330
|
-
// const chain = log.chain();
|
|
331
|
-
// expect(chain).toBeDefined();
|
|
332
|
-
// });
|
|
333
|
-
// });
|
package/tsconfig.build.json
DELETED
package/tsconfig.json
DELETED
package/vitest.config.ts
DELETED
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'vitest/config';
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
test: {
|
|
5
|
-
globals: true,
|
|
6
|
-
include: ['test/**/*.(spec|test).ts'],
|
|
7
|
-
exclude: ['node_modules/**'],
|
|
8
|
-
threads: false,
|
|
9
|
-
|
|
10
|
-
coverage: {
|
|
11
|
-
provider: 'istanbul',
|
|
12
|
-
},
|
|
13
|
-
},
|
|
14
|
-
|
|
15
|
-
resolve: {
|
|
16
|
-
alias: {},
|
|
17
|
-
},
|
|
18
|
-
define: {
|
|
19
|
-
__DEV__: false,
|
|
20
|
-
},
|
|
21
|
-
});
|