@qianxude/shared 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/LICENSE +21 -0
- package/README.md +91 -0
- package/dist/global.d.ts +10 -0
- package/dist/global.d.ts.map +1 -0
- package/dist/global.js +2 -0
- package/dist/global.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/interfaces/index.d.ts +3 -0
- package/dist/interfaces/index.d.ts.map +1 -0
- package/dist/interfaces/index.js +2 -0
- package/dist/interfaces/index.js.map +1 -0
- package/dist/interfaces/log.d.ts +74 -0
- package/dist/interfaces/log.d.ts.map +1 -0
- package/dist/interfaces/log.js +2 -0
- package/dist/interfaces/log.js.map +1 -0
- package/dist/interfaces/mod.d.ts +2 -0
- package/dist/interfaces/mod.d.ts.map +1 -0
- package/dist/interfaces/mod.js +2 -0
- package/dist/interfaces/mod.js.map +1 -0
- package/dist/interfaces/session.d.ts +10 -0
- package/dist/interfaces/session.d.ts.map +1 -0
- package/dist/interfaces/session.js +2 -0
- package/dist/interfaces/session.js.map +1 -0
- package/dist/logger.d.ts +90 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/logger.js +242 -0
- package/dist/logger.js.map +1 -0
- package/dist/logger.test.d.ts +2 -0
- package/dist/logger.test.d.ts.map +1 -0
- package/dist/logger.test.js +516 -0
- package/dist/logger.test.js.map +1 -0
- package/package.json +41 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) [2022] [QianXun Information Technologies (TianJin), Ltd.]
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
qian shared types and classes for other libraries
|
|
2
|
+
===========================
|
|
3
|
+
|
|
4
|
+
## Install
|
|
5
|
+
|
|
6
|
+
```bash
|
|
7
|
+
pn add @qianxude/shared
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
## Global Types
|
|
11
|
+
|
|
12
|
+
The `Logger` interface is available as a global type. To use it in your project without imports:
|
|
13
|
+
|
|
14
|
+
### Setup
|
|
15
|
+
|
|
16
|
+
Add the following to your `tsconfig.json`:
|
|
17
|
+
|
|
18
|
+
```json
|
|
19
|
+
{
|
|
20
|
+
"include": [
|
|
21
|
+
"src/**/*.ts",
|
|
22
|
+
"node_modules/@qianxude/shared/dist/global.d.ts"
|
|
23
|
+
]
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Usage
|
|
28
|
+
|
|
29
|
+
Once configured, you can use `Logger` directly without importing:
|
|
30
|
+
|
|
31
|
+
```typescript
|
|
32
|
+
class MyService {
|
|
33
|
+
private logger!: Logger; // No import needed
|
|
34
|
+
}
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
The `Logger` type is still available via regular import if preferred:
|
|
38
|
+
|
|
39
|
+
```typescript
|
|
40
|
+
import type { Logger } from '@qianxude/shared';
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## Production Logger
|
|
44
|
+
|
|
45
|
+
For production-ready logger implementations, see `@qianxude/logger` which provides:
|
|
46
|
+
|
|
47
|
+
- **Pretty console logger** for development
|
|
48
|
+
- **Duo-target logger** (console + file with rotation)
|
|
49
|
+
- **PinoLogger** class implementing the `Logger` interface
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
pn add @qianxude/logger
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```typescript
|
|
56
|
+
import { createDuoTargetPino, PinoLogger } from '@qianxude/logger';
|
|
57
|
+
|
|
58
|
+
const pinoLogger = createDuoTargetPino({
|
|
59
|
+
level: 'info',
|
|
60
|
+
file: './logs/app.log',
|
|
61
|
+
frequency: 'daily',
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const logger = new PinoLogger(pinoLogger, { service: 'my-app' });
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
**Downstream Project Configuration**
|
|
68
|
+
|
|
69
|
+
Downstream projects need to include the global types in their tsconfig.json:
|
|
70
|
+
|
|
71
|
+
{
|
|
72
|
+
"include": [
|
|
73
|
+
"src/**/*.ts",
|
|
74
|
+
"../shared/dist/global.d.ts"
|
|
75
|
+
]
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
Or via typeRoots if preferred:
|
|
79
|
+
|
|
80
|
+
{
|
|
81
|
+
"compilerOptions": {
|
|
82
|
+
"typeRoots": ["./node_modules/@types", "../shared/dist"]
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
## Publish
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
pn publish pkgs/shared --dry-run --filter @qianxude/shared
|
|
90
|
+
pn publish pkgs/shared --filter @qianxude/shared
|
|
91
|
+
```
|
package/dist/global.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { Logger as LoggerType } from './interfaces/log.js';
|
|
2
|
+
declare global {
|
|
3
|
+
type Class<T = unknown> = abstract new (...args: any[]) => T;
|
|
4
|
+
type Constructor<T = unknown> = new (...args: any[]) => T;
|
|
5
|
+
type AbstractConstructor<T = unknown> = abstract new (...args: any[]) => T;
|
|
6
|
+
interface Logger extends LoggerType {
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=global.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global.d.ts","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAEhE,OAAO,CAAC,MAAM,CAAC;IAEb,KAAK,KAAK,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAE7D,KAAK,WAAW,CAAC,CAAC,GAAG,OAAO,IAAI,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAE1D,KAAK,mBAAmB,CAAC,CAAC,GAAG,OAAO,IAAI,QAAQ,MAAM,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;IAE3E,UAAU,MAAO,SAAQ,UAAU;KAAG;CACvC;AAED,OAAO,EAAE,CAAC"}
|
package/dist/global.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"global.js","sourceRoot":"","sources":["../src/global.ts"],"names":[],"mappings":""}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,uBAAuB,CAAC;AACtC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC;AAE9B,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/interfaces/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,CAAC,MAAM,UAAU,CAAC"}
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Numeric mapping of log-level names:
|
|
3
|
+
* - trace 10 – ultra-verbose tracing, used to follow code execution paths
|
|
4
|
+
* - debug 20 – debugging information for troubleshooting
|
|
5
|
+
* - info 30 – general information, records key runtime flows (default level)
|
|
6
|
+
* - warn 40 – warning for unexpected but non-fatal situations
|
|
7
|
+
* - error 50 – error that impairs functionality
|
|
8
|
+
* - fatal 60 – critical error, process is crashing or unrecoverable
|
|
9
|
+
*/
|
|
10
|
+
export type LogLevel = 'fatal' | 'error' | 'warn' | 'info' | 'debug' | 'trace';
|
|
11
|
+
export type Context = Record<string, any>;
|
|
12
|
+
export type WithLevel = {
|
|
13
|
+
level: LogLevel;
|
|
14
|
+
};
|
|
15
|
+
export type Entry = {
|
|
16
|
+
message: string;
|
|
17
|
+
[optionName: string]: any;
|
|
18
|
+
};
|
|
19
|
+
export type LevelEntry = WithLevel & Entry;
|
|
20
|
+
export interface GenericLog {
|
|
21
|
+
(level: LogLevel, message: string, ctx?: Context): void;
|
|
22
|
+
(entry: LevelEntry): void;
|
|
23
|
+
}
|
|
24
|
+
export interface LeveledLog {
|
|
25
|
+
(message: string, ctx?: Context): void;
|
|
26
|
+
(entry: Entry): void;
|
|
27
|
+
}
|
|
28
|
+
export interface Logging {
|
|
29
|
+
log: GenericLog;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* leveled log methods
|
|
33
|
+
*/
|
|
34
|
+
export interface LeveledLogging {
|
|
35
|
+
fatal: LeveledLog;
|
|
36
|
+
error: LeveledLog;
|
|
37
|
+
warn: LeveledLog;
|
|
38
|
+
info: LeveledLog;
|
|
39
|
+
debug: LeveledLog;
|
|
40
|
+
trace: LeveledLog;
|
|
41
|
+
}
|
|
42
|
+
export interface LogLevelAware {
|
|
43
|
+
/**
|
|
44
|
+
* get the logger level.
|
|
45
|
+
*/
|
|
46
|
+
get level(): LogLevel;
|
|
47
|
+
/**
|
|
48
|
+
* set the logger level.
|
|
49
|
+
*/
|
|
50
|
+
setLevel(level: LogLevel): void;
|
|
51
|
+
}
|
|
52
|
+
export interface Logger extends Logging, LeveledLogging {
|
|
53
|
+
/**
|
|
54
|
+
* get the logger context. client code can add or delete props directly
|
|
55
|
+
*/
|
|
56
|
+
get ctx(): Context;
|
|
57
|
+
/**
|
|
58
|
+
* attach info to the logger context (merge)
|
|
59
|
+
*/
|
|
60
|
+
attach(key: string, value: any): void;
|
|
61
|
+
attach(ctx: Context): void;
|
|
62
|
+
attach(...ctx: Context[]): void;
|
|
63
|
+
/**
|
|
64
|
+
* detach info from the logger context
|
|
65
|
+
*/
|
|
66
|
+
detach(ctx: Context): void;
|
|
67
|
+
/**
|
|
68
|
+
* create a new child logger who can extends context and append more as its own.
|
|
69
|
+
*/
|
|
70
|
+
spawn(ctx?: Context): this;
|
|
71
|
+
}
|
|
72
|
+
export interface LogSupport extends Logging, LogLevelAware {
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/interfaces/log.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,CAAC;AAC/E,MAAM,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAC1C,MAAM,MAAM,SAAS,GAAG;IAAE,KAAK,EAAE,QAAQ,CAAA;CAAE,CAAC;AAC5C,MAAM,MAAM,KAAK,GAAG;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,CAAC,UAAU,EAAE,MAAM,GAAG,GAAG,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,KAAK,CAAC;AAE3C,MAAM,WAAW,UAAU;IACzB,CAAC,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACxD,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,CAAC;CAC3B;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;IACvC,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;CACtB;AAED,MAAM,WAAW,OAAO;IACtB,GAAG,EAAE,UAAU,CAAC;CACjB;AAED;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;IAClB,IAAI,EAAE,UAAU,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;IACjB,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;CACnB;AACD,MAAM,WAAW,aAAa;IAC5B;;OAEG;IACH,IAAI,KAAK,IAAI,QAAQ,CAAC;IAEtB;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAAC;CACjC;AAED,MAAM,WAAW,MAAO,SAAQ,OAAO,EAAE,cAAc;IACrD;;OAEG;IACH,IAAI,GAAG,IAAI,OAAO,CAAC;IAEnB;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,IAAI,CAAC;IACtC,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAC3B,MAAM,CAAC,GAAG,GAAG,EAAE,OAAO,EAAE,GAAG,IAAI,CAAC;IAEhC;;OAEG;IACH,MAAM,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAAC;IAE3B;;OAEG;IACH,KAAK,CAAC,GAAG,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;CAC5B;AAED,MAAM,WAAW,UAAW,SAAQ,OAAO,EAAE,aAAa;CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/interfaces/log.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.d.ts","sourceRoot":"","sources":["../../src/interfaces/mod.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mod.js","sourceRoot":"","sources":["../../src/interfaces/mod.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export type AnyObject = Record<string, any>;
|
|
2
|
+
export interface StateAware {
|
|
3
|
+
readonly state: AnyObject;
|
|
4
|
+
}
|
|
5
|
+
export interface Session extends StateAware {
|
|
6
|
+
set(k: string, v: any): void;
|
|
7
|
+
get(k: string): any | undefined;
|
|
8
|
+
toString(): string;
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=session.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../src/interfaces/session.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAE5C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,SAAS,CAAC;CAC3B;AAED,MAAM,WAAW,OAAQ,SAAQ,UAAU;IACzC,GAAG,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,GAAG,IAAI,CAAC;IAC7B,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,GAAG,GAAG,SAAS,CAAC;IAChC,QAAQ,IAAI,MAAM,CAAC;CACpB"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/interfaces/session.ts"],"names":[],"mappings":""}
|
package/dist/logger.d.ts
ADDED
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { Logger, LogSupport, Context, LogLevel, LevelEntry, Entry } from './interfaces/log.js';
|
|
2
|
+
/**
|
|
3
|
+
* Abstract base class for loggers with delegation support.
|
|
4
|
+
* Manages context locally and delegates log operations to an underlying logger.
|
|
5
|
+
*/
|
|
6
|
+
export declare abstract class BaseLogger implements Logger, LogSupport {
|
|
7
|
+
protected _level: LogLevel;
|
|
8
|
+
protected _ctx: Context;
|
|
9
|
+
protected abstract _delegate: LogSupport;
|
|
10
|
+
get level(): LogLevel;
|
|
11
|
+
setLevel(level: LogLevel): void;
|
|
12
|
+
get ctx(): Context;
|
|
13
|
+
attach(key: string, value: any): void;
|
|
14
|
+
attach(ctx: Context): void;
|
|
15
|
+
attach(...ctx: Context[]): void;
|
|
16
|
+
detach(ctx: Context): void;
|
|
17
|
+
/**
|
|
18
|
+
* Goal: Enable runtime replacement of the delegate at the top-level (e.g., app startup) and
|
|
19
|
+
* have all spawned children automatically use the new delegate. This is critical for the pattern where:
|
|
20
|
+
* 1. App starts with default ConsoleLogger
|
|
21
|
+
* 2. At initialization, app calls logger.setDelegate(pinoLogger)
|
|
22
|
+
* 3. All spawned children throughout the app should now use pinoLogger
|
|
23
|
+
* @param ctx
|
|
24
|
+
* @returns
|
|
25
|
+
*/
|
|
26
|
+
spawn(ctx?: Context): this;
|
|
27
|
+
log(level: LogLevel, message: string, ctx?: Context): void;
|
|
28
|
+
log(entry: LevelEntry): void;
|
|
29
|
+
fatal(message: string, ctx?: Context): void;
|
|
30
|
+
fatal(entry: Entry): void;
|
|
31
|
+
error(message: string, ctx?: Context): void;
|
|
32
|
+
error(entry: Entry): void;
|
|
33
|
+
warn(message: string, ctx?: Context): void;
|
|
34
|
+
warn(entry: Entry): void;
|
|
35
|
+
info(message: string, ctx?: Context): void;
|
|
36
|
+
info(entry: Entry): void;
|
|
37
|
+
debug(message: string, ctx?: Context): void;
|
|
38
|
+
debug(entry: Entry): void;
|
|
39
|
+
trace(message: string, ctx?: Context): void;
|
|
40
|
+
trace(entry: Entry): void;
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Console-based logger implementation.
|
|
44
|
+
* Outputs formatted log messages to the console.
|
|
45
|
+
*/
|
|
46
|
+
export declare class ConsoleLogger extends BaseLogger {
|
|
47
|
+
protected _delegate: LogSupport;
|
|
48
|
+
constructor();
|
|
49
|
+
protected _formatMessage(level: LogLevel, message: string, ctx: Context): string;
|
|
50
|
+
log(level: LogLevel, message: string, ctx?: Context): void;
|
|
51
|
+
log(entry: LevelEntry): void;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Configurable logger that delegates to a swappable underlying logger.
|
|
55
|
+
* Allows runtime replacement of the logging implementation.
|
|
56
|
+
*/
|
|
57
|
+
export declare class ConfigurableLogger extends BaseLogger {
|
|
58
|
+
protected _delegate: LogSupport;
|
|
59
|
+
constructor(delegate?: LogSupport);
|
|
60
|
+
/**
|
|
61
|
+
* Replace the underlying logger delegate.
|
|
62
|
+
* Useful for swapping to a different logging implementation (e.g., pino).
|
|
63
|
+
*/
|
|
64
|
+
setDelegate(logger: LogSupport): void;
|
|
65
|
+
/**
|
|
66
|
+
* Get the current delegate logger.
|
|
67
|
+
*/
|
|
68
|
+
getDelegate(): LogSupport;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* Factory function to create a configurable logger.
|
|
72
|
+
* @param initialDelegate - Optional initial delegate logger (defaults to ConsoleLogger)
|
|
73
|
+
*/
|
|
74
|
+
export declare function createConfigurableLogger(initialDelegate?: LogSupport): ConfigurableLogger;
|
|
75
|
+
/**
|
|
76
|
+
* Function to configure a logger with a new delegate.
|
|
77
|
+
* @param logger - The logger instance to configure (must be a ConfigurableLogger)
|
|
78
|
+
* @param delegate - The new logger delegate to set
|
|
79
|
+
*/
|
|
80
|
+
export declare function configureLogger(logger: Logger, delegate: LogSupport): void;
|
|
81
|
+
/**
|
|
82
|
+
* Shared logger instance for use across all dependent packages.
|
|
83
|
+
* By default, logs to console. Can be configured to use a different logger.
|
|
84
|
+
* @example
|
|
85
|
+
* // At app startup, swap to pino:
|
|
86
|
+
* import { logger } from '@qianxude/shared';
|
|
87
|
+
* logger.setDelegate(pinoLogger);
|
|
88
|
+
*/
|
|
89
|
+
export declare const logger: ConfigurableLogger;
|
|
90
|
+
//# sourceMappingURL=logger.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
package/dist/logger.js
ADDED
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Log level numeric values for filtering.
|
|
3
|
+
* Higher values = more severe = less verbose.
|
|
4
|
+
*/
|
|
5
|
+
const LOG_LEVEL_VALUES = {
|
|
6
|
+
trace: 10,
|
|
7
|
+
debug: 20,
|
|
8
|
+
info: 30,
|
|
9
|
+
warn: 40,
|
|
10
|
+
error: 50,
|
|
11
|
+
fatal: 60,
|
|
12
|
+
};
|
|
13
|
+
/**
|
|
14
|
+
* Checks if a message at the given level should be logged
|
|
15
|
+
* based on the logger's configured level.
|
|
16
|
+
* Rule: messageLevel >= loggerLevel (higher numeric = more severe)
|
|
17
|
+
*/
|
|
18
|
+
function shouldLog(messageLevel, loggerLevel) {
|
|
19
|
+
return LOG_LEVEL_VALUES[messageLevel] >= LOG_LEVEL_VALUES[loggerLevel];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Abstract base class for loggers with delegation support.
|
|
23
|
+
* Manages context locally and delegates log operations to an underlying logger.
|
|
24
|
+
*/
|
|
25
|
+
export class BaseLogger {
|
|
26
|
+
_level = 'info';
|
|
27
|
+
_ctx = {};
|
|
28
|
+
get level() {
|
|
29
|
+
return this._level;
|
|
30
|
+
}
|
|
31
|
+
setLevel(level) {
|
|
32
|
+
this._level = level;
|
|
33
|
+
}
|
|
34
|
+
get ctx() {
|
|
35
|
+
return this._ctx;
|
|
36
|
+
}
|
|
37
|
+
attach(first, ...args) {
|
|
38
|
+
if (typeof first === 'string') {
|
|
39
|
+
this._ctx[first] = args[0];
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
Object.assign(this._ctx, first);
|
|
43
|
+
for (const ctx of args) {
|
|
44
|
+
Object.assign(this._ctx, ctx);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
detach(ctx) {
|
|
49
|
+
for (const key of Object.keys(ctx))
|
|
50
|
+
delete this._ctx[key];
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Goal: Enable runtime replacement of the delegate at the top-level (e.g., app startup) and
|
|
54
|
+
* have all spawned children automatically use the new delegate. This is critical for the pattern where:
|
|
55
|
+
* 1. App starts with default ConsoleLogger
|
|
56
|
+
* 2. At initialization, app calls logger.setDelegate(pinoLogger)
|
|
57
|
+
* 3. All spawned children throughout the app should now use pinoLogger
|
|
58
|
+
* @param ctx
|
|
59
|
+
* @returns
|
|
60
|
+
*/
|
|
61
|
+
spawn(ctx) {
|
|
62
|
+
const child = Object.create(this.constructor.prototype);
|
|
63
|
+
child._ctx = { ...this._ctx, ...ctx };
|
|
64
|
+
/**
|
|
65
|
+
* MUST be this here in order to ensure that child use parent to log messages.
|
|
66
|
+
*/
|
|
67
|
+
child._delegate = this;
|
|
68
|
+
return child;
|
|
69
|
+
}
|
|
70
|
+
log(first, message, ctx) {
|
|
71
|
+
if (typeof first === 'string') {
|
|
72
|
+
const mergedCtx = ctx ? { ...this._ctx, ...ctx } : this._ctx;
|
|
73
|
+
this._delegate.log(first, message, mergedCtx);
|
|
74
|
+
}
|
|
75
|
+
else {
|
|
76
|
+
const entry = first;
|
|
77
|
+
const { level, message, ...rest } = entry;
|
|
78
|
+
const mergedCtx = { ...this._ctx, ...rest };
|
|
79
|
+
this._delegate.log({ level, message, ...mergedCtx });
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
fatal(first, ctx) {
|
|
83
|
+
if (typeof first === 'string') {
|
|
84
|
+
this.log('fatal', first, ctx);
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
this.log({ level: 'fatal', ...first, ...ctx });
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
error(first, ctx) {
|
|
91
|
+
if (typeof first === 'string') {
|
|
92
|
+
this.log('error', first, ctx);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
this.log({ level: 'error', ...first, ...ctx });
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
warn(first, ctx) {
|
|
99
|
+
if (typeof first === 'string') {
|
|
100
|
+
this.log('warn', first, ctx);
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
this.log({ level: 'warn', ...first, ...ctx });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
info(first, ctx) {
|
|
107
|
+
if (typeof first === 'string') {
|
|
108
|
+
this.log('info', first, ctx);
|
|
109
|
+
}
|
|
110
|
+
else {
|
|
111
|
+
this.log({ level: 'info', ...first, ...ctx });
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
debug(first, ctx) {
|
|
115
|
+
if (typeof first === 'string') {
|
|
116
|
+
this.log('debug', first, ctx);
|
|
117
|
+
}
|
|
118
|
+
else {
|
|
119
|
+
this.log({ level: 'debug', ...first, ...ctx });
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
trace(first, ctx) {
|
|
123
|
+
if (typeof first === 'string') {
|
|
124
|
+
this.log('trace', first, ctx);
|
|
125
|
+
}
|
|
126
|
+
else {
|
|
127
|
+
this.log({ level: 'trace', ...first, ...ctx });
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Console-based logger implementation.
|
|
133
|
+
* Outputs formatted log messages to the console.
|
|
134
|
+
*/
|
|
135
|
+
export class ConsoleLogger extends BaseLogger {
|
|
136
|
+
_delegate;
|
|
137
|
+
constructor() {
|
|
138
|
+
super();
|
|
139
|
+
this._delegate = this;
|
|
140
|
+
}
|
|
141
|
+
_formatMessage(level, message, ctx) {
|
|
142
|
+
const timestamp = new Date().toISOString();
|
|
143
|
+
const ctxStr = Object.keys(ctx).length > 0 ? ` ${JSON.stringify(ctx)}` : '';
|
|
144
|
+
return `[${timestamp}] ${level.toUpperCase()}: ${message}${ctxStr}`;
|
|
145
|
+
}
|
|
146
|
+
log(first, message, ctx) {
|
|
147
|
+
let level;
|
|
148
|
+
let msg;
|
|
149
|
+
let mergedCtx;
|
|
150
|
+
if (typeof first === 'string') {
|
|
151
|
+
level = first;
|
|
152
|
+
msg = message;
|
|
153
|
+
mergedCtx = ctx ? { ...this._ctx, ...ctx } : this._ctx;
|
|
154
|
+
}
|
|
155
|
+
else {
|
|
156
|
+
const entry = first;
|
|
157
|
+
level = entry.level;
|
|
158
|
+
msg = entry.message;
|
|
159
|
+
mergedCtx = { ...entry };
|
|
160
|
+
delete mergedCtx.message;
|
|
161
|
+
delete mergedCtx.level;
|
|
162
|
+
mergedCtx = { ...this._ctx, ...mergedCtx };
|
|
163
|
+
}
|
|
164
|
+
// Skip if message level is below logger's configured level
|
|
165
|
+
if (!shouldLog(level, this._level)) {
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
const formatted = this._formatMessage(level, msg, mergedCtx);
|
|
169
|
+
switch (level) {
|
|
170
|
+
case 'fatal':
|
|
171
|
+
case 'error':
|
|
172
|
+
console.error(formatted);
|
|
173
|
+
break;
|
|
174
|
+
case 'warn':
|
|
175
|
+
console.warn(formatted);
|
|
176
|
+
break;
|
|
177
|
+
case 'info':
|
|
178
|
+
console.info(formatted);
|
|
179
|
+
break;
|
|
180
|
+
case 'debug':
|
|
181
|
+
case 'trace':
|
|
182
|
+
console.debug(formatted);
|
|
183
|
+
break;
|
|
184
|
+
default:
|
|
185
|
+
console.log(formatted);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
/**
|
|
190
|
+
* Configurable logger that delegates to a swappable underlying logger.
|
|
191
|
+
* Allows runtime replacement of the logging implementation.
|
|
192
|
+
*/
|
|
193
|
+
export class ConfigurableLogger extends BaseLogger {
|
|
194
|
+
_delegate;
|
|
195
|
+
constructor(delegate) {
|
|
196
|
+
super();
|
|
197
|
+
this._delegate = delegate ?? new ConsoleLogger();
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Replace the underlying logger delegate.
|
|
201
|
+
* Useful for swapping to a different logging implementation (e.g., pino).
|
|
202
|
+
*/
|
|
203
|
+
setDelegate(logger) {
|
|
204
|
+
this._delegate = logger;
|
|
205
|
+
}
|
|
206
|
+
/**
|
|
207
|
+
* Get the current delegate logger.
|
|
208
|
+
*/
|
|
209
|
+
getDelegate() {
|
|
210
|
+
return this._delegate;
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Factory function to create a configurable logger.
|
|
215
|
+
* @param initialDelegate - Optional initial delegate logger (defaults to ConsoleLogger)
|
|
216
|
+
*/
|
|
217
|
+
export function createConfigurableLogger(initialDelegate) {
|
|
218
|
+
return new ConfigurableLogger(initialDelegate);
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* Function to configure a logger with a new delegate.
|
|
222
|
+
* @param logger - The logger instance to configure (must be a ConfigurableLogger)
|
|
223
|
+
* @param delegate - The new logger delegate to set
|
|
224
|
+
*/
|
|
225
|
+
export function configureLogger(logger, delegate) {
|
|
226
|
+
if (logger instanceof ConfigurableLogger) {
|
|
227
|
+
logger.setDelegate(delegate);
|
|
228
|
+
}
|
|
229
|
+
else {
|
|
230
|
+
throw new Error('Logger must be a ConfigurableLogger instance');
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Shared logger instance for use across all dependent packages.
|
|
235
|
+
* By default, logs to console. Can be configured to use a different logger.
|
|
236
|
+
* @example
|
|
237
|
+
* // At app startup, swap to pino:
|
|
238
|
+
* import { logger } from '@qianxude/shared';
|
|
239
|
+
* logger.setDelegate(pinoLogger);
|
|
240
|
+
*/
|
|
241
|
+
export const logger = createConfigurableLogger();
|
|
242
|
+
//# sourceMappingURL=logger.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../src/logger.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.test.d.ts","sourceRoot":"","sources":["../src/logger.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,516 @@
|
|
|
1
|
+
import { describe, test, expect, spyOn, beforeEach, afterEach } from 'bun:test';
|
|
2
|
+
import { BaseLogger, ConsoleLogger, ConfigurableLogger, createConfigurableLogger, configureLogger, logger, } from './logger.js';
|
|
3
|
+
/**
|
|
4
|
+
* Mock logger for testing delegation behavior.
|
|
5
|
+
* Implements Logger interface directly to avoid BaseLogger spawn behavior.
|
|
6
|
+
*/
|
|
7
|
+
class MockLogger {
|
|
8
|
+
calls = [];
|
|
9
|
+
_ctx = {};
|
|
10
|
+
_level = 'info';
|
|
11
|
+
get level() {
|
|
12
|
+
return this._level;
|
|
13
|
+
}
|
|
14
|
+
setLevel(level) {
|
|
15
|
+
this._level = level;
|
|
16
|
+
}
|
|
17
|
+
get ctx() {
|
|
18
|
+
return this._ctx;
|
|
19
|
+
}
|
|
20
|
+
attach(first, second) {
|
|
21
|
+
if (typeof first === 'string') {
|
|
22
|
+
this._ctx[first] = second;
|
|
23
|
+
}
|
|
24
|
+
else {
|
|
25
|
+
Object.assign(this._ctx, first);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
detach(ctx) {
|
|
29
|
+
for (const key of Object.keys(ctx))
|
|
30
|
+
delete this._ctx[key];
|
|
31
|
+
}
|
|
32
|
+
spawn(ctx) {
|
|
33
|
+
const child = Object.create(this.constructor.prototype);
|
|
34
|
+
child._ctx = { ...this._ctx, ...ctx };
|
|
35
|
+
return child;
|
|
36
|
+
}
|
|
37
|
+
log(first, message, ctx) {
|
|
38
|
+
if (typeof first === 'string') {
|
|
39
|
+
this.calls.push({ level: first, message: message, ctx: ctx ?? {} });
|
|
40
|
+
}
|
|
41
|
+
else {
|
|
42
|
+
const { level, message: msg, ...rest } = first;
|
|
43
|
+
this.calls.push({ level, message: msg, ctx: rest });
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
fatal(first, ctx) {
|
|
47
|
+
if (typeof first === 'string') {
|
|
48
|
+
this.log('fatal', first, ctx);
|
|
49
|
+
}
|
|
50
|
+
else {
|
|
51
|
+
this.log({ level: 'fatal', ...first });
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
error(first, ctx) {
|
|
55
|
+
if (typeof first === 'string') {
|
|
56
|
+
this.log('error', first, ctx);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
this.log({ level: 'error', ...first });
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
warn(first, ctx) {
|
|
63
|
+
if (typeof first === 'string') {
|
|
64
|
+
this.log('warn', first, ctx);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
this.log({ level: 'warn', ...first });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
info(first, ctx) {
|
|
71
|
+
if (typeof first === 'string') {
|
|
72
|
+
this.log('info', first, ctx);
|
|
73
|
+
}
|
|
74
|
+
else {
|
|
75
|
+
this.log({ level: 'info', ...first });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
debug(first, ctx) {
|
|
79
|
+
if (typeof first === 'string') {
|
|
80
|
+
this.log('debug', first, ctx);
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
this.log({ level: 'debug', ...first });
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
trace(first, ctx) {
|
|
87
|
+
if (typeof first === 'string') {
|
|
88
|
+
this.log('trace', first, ctx);
|
|
89
|
+
}
|
|
90
|
+
else {
|
|
91
|
+
this.log({ level: 'trace', ...first });
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* TestLogger extends BaseLogger and captures log calls for testing.
|
|
97
|
+
* Uses itself as delegate (like ConsoleLogger) to test BaseLogger behavior.
|
|
98
|
+
*/
|
|
99
|
+
class TestLogger extends BaseLogger {
|
|
100
|
+
_delegate;
|
|
101
|
+
calls = [];
|
|
102
|
+
constructor() {
|
|
103
|
+
super();
|
|
104
|
+
this._delegate = this;
|
|
105
|
+
}
|
|
106
|
+
log(first, message, ctx) {
|
|
107
|
+
// Must do our own context merging since we override BaseLogger.log
|
|
108
|
+
if (typeof first === 'string') {
|
|
109
|
+
const mergedCtx = ctx ? { ...this._ctx, ...ctx } : { ...this._ctx };
|
|
110
|
+
this.calls.push({ level: first, message: message, ctx: mergedCtx });
|
|
111
|
+
}
|
|
112
|
+
else {
|
|
113
|
+
const { level, message: msg, ...rest } = first;
|
|
114
|
+
const mergedCtx = { ...this._ctx, ...rest };
|
|
115
|
+
this.calls.push({ level, message: msg, ctx: mergedCtx });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
describe('BaseLogger', () => {
|
|
120
|
+
let testLogger;
|
|
121
|
+
beforeEach(() => {
|
|
122
|
+
testLogger = new TestLogger();
|
|
123
|
+
});
|
|
124
|
+
describe('ctx getter', () => {
|
|
125
|
+
test('returns the current context', () => {
|
|
126
|
+
expect(testLogger.ctx).toEqual({});
|
|
127
|
+
testLogger.attach('key', 'value');
|
|
128
|
+
expect(testLogger.ctx).toEqual({ key: 'value' });
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
describe('attach', () => {
|
|
132
|
+
test('adds single key-value pair', () => {
|
|
133
|
+
testLogger.attach('key', 'value');
|
|
134
|
+
expect(testLogger.ctx).toEqual({ key: 'value' });
|
|
135
|
+
});
|
|
136
|
+
test('merges context object', () => {
|
|
137
|
+
testLogger.attach({ key1: 'value1', key2: 'value2' });
|
|
138
|
+
expect(testLogger.ctx).toEqual({ key1: 'value1', key2: 'value2' });
|
|
139
|
+
});
|
|
140
|
+
test('merges multiple context objects', () => {
|
|
141
|
+
testLogger.attach({ key1: 'value1' }, { key2: 'value2' }, { key3: 'value3' });
|
|
142
|
+
expect(testLogger.ctx).toEqual({ key1: 'value1', key2: 'value2', key3: 'value3' });
|
|
143
|
+
});
|
|
144
|
+
test('later values override earlier ones', () => {
|
|
145
|
+
testLogger.attach({ key: 'first' }, { key: 'second' }, { key: 'third' });
|
|
146
|
+
expect(testLogger.ctx).toEqual({ key: 'third' });
|
|
147
|
+
});
|
|
148
|
+
});
|
|
149
|
+
describe('detach', () => {
|
|
150
|
+
test('removes specified keys from context', () => {
|
|
151
|
+
testLogger.attach({ key1: 'value1', key2: 'value2', key3: 'value3' });
|
|
152
|
+
testLogger.detach({ key1: '', key3: '' });
|
|
153
|
+
expect(testLogger.ctx).toEqual({ key2: 'value2' });
|
|
154
|
+
});
|
|
155
|
+
test('ignores keys that do not exist', () => {
|
|
156
|
+
testLogger.attach({ key1: 'value1' });
|
|
157
|
+
testLogger.detach({ nonexistent: '' });
|
|
158
|
+
expect(testLogger.ctx).toEqual({ key1: 'value1' });
|
|
159
|
+
});
|
|
160
|
+
});
|
|
161
|
+
describe('spawn', () => {
|
|
162
|
+
test('creates child logger inheriting parent context', () => {
|
|
163
|
+
testLogger.attach({ parentKey: 'parentValue' });
|
|
164
|
+
const child = testLogger.spawn();
|
|
165
|
+
expect(child.ctx).toEqual({ parentKey: 'parentValue' });
|
|
166
|
+
});
|
|
167
|
+
test('child can add additional context', () => {
|
|
168
|
+
testLogger.attach({ parentKey: 'parentValue' });
|
|
169
|
+
const child = testLogger.spawn({ childKey: 'childValue' });
|
|
170
|
+
expect(child.ctx).toEqual({ parentKey: 'parentValue', childKey: 'childValue' });
|
|
171
|
+
});
|
|
172
|
+
test('child context is independent from parent', () => {
|
|
173
|
+
testLogger.attach({ key: 'parentValue' });
|
|
174
|
+
const child = testLogger.spawn();
|
|
175
|
+
child.attach('key', 'childValue');
|
|
176
|
+
expect(testLogger.ctx).toEqual({ key: 'parentValue' });
|
|
177
|
+
expect(child.ctx).toEqual({ key: 'childValue' });
|
|
178
|
+
});
|
|
179
|
+
});
|
|
180
|
+
describe('log overloads', () => {
|
|
181
|
+
test('log(level, message, ctx?) - string level with optional context', () => {
|
|
182
|
+
testLogger.log('info', 'test message', { extra: 'data' });
|
|
183
|
+
expect(testLogger.calls).toHaveLength(1);
|
|
184
|
+
expect(testLogger.calls[0]).toEqual({
|
|
185
|
+
level: 'info',
|
|
186
|
+
message: 'test message',
|
|
187
|
+
ctx: { extra: 'data' },
|
|
188
|
+
});
|
|
189
|
+
});
|
|
190
|
+
test('log(level, message) - without context', () => {
|
|
191
|
+
testLogger.log('info', 'test message');
|
|
192
|
+
expect(testLogger.calls).toHaveLength(1);
|
|
193
|
+
expect(testLogger.calls[0]).toEqual({
|
|
194
|
+
level: 'info',
|
|
195
|
+
message: 'test message',
|
|
196
|
+
ctx: {},
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
test('log(entry) - entry object with level property', () => {
|
|
200
|
+
testLogger.log({ level: 'info', message: 'test message', extra: 'data' });
|
|
201
|
+
expect(testLogger.calls).toHaveLength(1);
|
|
202
|
+
expect(testLogger.calls[0]).toEqual({
|
|
203
|
+
level: 'info',
|
|
204
|
+
message: 'test message',
|
|
205
|
+
ctx: { extra: 'data' },
|
|
206
|
+
});
|
|
207
|
+
});
|
|
208
|
+
test('merges instance context with call-time context', () => {
|
|
209
|
+
testLogger.attach({ instanceKey: 'instanceValue' });
|
|
210
|
+
testLogger.log('info', 'test message', { callKey: 'callValue' });
|
|
211
|
+
expect(testLogger.calls[0].ctx).toEqual({
|
|
212
|
+
instanceKey: 'instanceValue',
|
|
213
|
+
callKey: 'callValue',
|
|
214
|
+
});
|
|
215
|
+
});
|
|
216
|
+
test('call-time context overrides instance context', () => {
|
|
217
|
+
testLogger.attach({ key: 'instanceValue' });
|
|
218
|
+
testLogger.log('info', 'test message', { key: 'callValue' });
|
|
219
|
+
expect(testLogger.calls[0].ctx).toEqual({ key: 'callValue' });
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
describe('level-specific methods', () => {
|
|
223
|
+
const levels = ['fatal', 'error', 'warn', 'info', 'debug', 'trace'];
|
|
224
|
+
for (const level of levels) {
|
|
225
|
+
describe(level, () => {
|
|
226
|
+
test(`${level}(message, ctx?) - string message with optional context`, () => {
|
|
227
|
+
testLogger[level]('test message', { extra: 'data' });
|
|
228
|
+
expect(testLogger.calls).toHaveLength(1);
|
|
229
|
+
expect(testLogger.calls[0].level).toBe(level);
|
|
230
|
+
expect(testLogger.calls[0].message).toBe('test message');
|
|
231
|
+
expect(testLogger.calls[0].ctx).toEqual({ extra: 'data' });
|
|
232
|
+
});
|
|
233
|
+
test(`${level}(entry) - entry object`, () => {
|
|
234
|
+
testLogger[level]({ message: 'test message', extra: 'data' });
|
|
235
|
+
expect(testLogger.calls).toHaveLength(1);
|
|
236
|
+
expect(testLogger.calls[0].level).toBe(level);
|
|
237
|
+
expect(testLogger.calls[0].message).toBe('test message');
|
|
238
|
+
expect(testLogger.calls[0].ctx).toEqual({ extra: 'data' });
|
|
239
|
+
});
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
});
|
|
244
|
+
describe('ConsoleLogger', () => {
|
|
245
|
+
let consoleLogger;
|
|
246
|
+
let consoleErrorSpy;
|
|
247
|
+
let consoleWarnSpy;
|
|
248
|
+
let consoleInfoSpy;
|
|
249
|
+
let consoleDebugSpy;
|
|
250
|
+
let consoleLogSpy;
|
|
251
|
+
beforeEach(() => {
|
|
252
|
+
consoleLogger = new ConsoleLogger();
|
|
253
|
+
consoleErrorSpy = spyOn(console, 'error');
|
|
254
|
+
consoleWarnSpy = spyOn(console, 'warn');
|
|
255
|
+
consoleInfoSpy = spyOn(console, 'info');
|
|
256
|
+
consoleDebugSpy = spyOn(console, 'debug');
|
|
257
|
+
consoleLogSpy = spyOn(console, 'log');
|
|
258
|
+
});
|
|
259
|
+
afterEach(() => {
|
|
260
|
+
consoleErrorSpy.mockRestore();
|
|
261
|
+
consoleWarnSpy.mockRestore();
|
|
262
|
+
consoleInfoSpy.mockRestore();
|
|
263
|
+
consoleDebugSpy.mockRestore();
|
|
264
|
+
consoleLogSpy.mockRestore();
|
|
265
|
+
});
|
|
266
|
+
describe('_formatMessage', () => {
|
|
267
|
+
test('includes timestamp, level (uppercase), and message', () => {
|
|
268
|
+
// Access protected method via type assertion
|
|
269
|
+
const formatted = consoleLogger._formatMessage('info', 'test message', {});
|
|
270
|
+
expect(formatted).toMatch(/\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z\]/);
|
|
271
|
+
expect(formatted).toContain('INFO');
|
|
272
|
+
expect(formatted).toContain('test message');
|
|
273
|
+
});
|
|
274
|
+
test('includes context as JSON when non-empty', () => {
|
|
275
|
+
const formatted = consoleLogger._formatMessage('info', 'test message', { key: 'value' });
|
|
276
|
+
expect(formatted).toContain('{"key":"value"}');
|
|
277
|
+
});
|
|
278
|
+
test('omits context when empty', () => {
|
|
279
|
+
const formatted = consoleLogger._formatMessage('info', 'test message', {});
|
|
280
|
+
expect(formatted).not.toContain('{');
|
|
281
|
+
expect(formatted).not.toContain('}');
|
|
282
|
+
});
|
|
283
|
+
});
|
|
284
|
+
describe('log output routing', () => {
|
|
285
|
+
test('fatal routes to console.error', () => {
|
|
286
|
+
consoleLogger.log('fatal', 'fatal message');
|
|
287
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
288
|
+
});
|
|
289
|
+
test('error routes to console.error', () => {
|
|
290
|
+
consoleLogger.log('error', 'error message');
|
|
291
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
292
|
+
});
|
|
293
|
+
test('warn routes to console.warn', () => {
|
|
294
|
+
consoleLogger.log('warn', 'warn message');
|
|
295
|
+
expect(consoleWarnSpy).toHaveBeenCalled();
|
|
296
|
+
});
|
|
297
|
+
test('info routes to console.info', () => {
|
|
298
|
+
consoleLogger.log('info', 'info message');
|
|
299
|
+
expect(consoleInfoSpy).toHaveBeenCalled();
|
|
300
|
+
});
|
|
301
|
+
test('debug routes to console.debug', () => {
|
|
302
|
+
consoleLogger.setLevel('debug');
|
|
303
|
+
consoleLogger.log('debug', 'debug message');
|
|
304
|
+
expect(consoleDebugSpy).toHaveBeenCalled();
|
|
305
|
+
});
|
|
306
|
+
test('trace routes to console.debug', () => {
|
|
307
|
+
consoleLogger.setLevel('trace');
|
|
308
|
+
consoleLogger.log('trace', 'trace message');
|
|
309
|
+
expect(consoleDebugSpy).toHaveBeenCalled();
|
|
310
|
+
});
|
|
311
|
+
});
|
|
312
|
+
describe('log with entry object', () => {
|
|
313
|
+
test('handles entry object format', () => {
|
|
314
|
+
consoleLogger.log({ level: 'info', message: 'entry message', extra: 'data' });
|
|
315
|
+
expect(consoleInfoSpy).toHaveBeenCalled();
|
|
316
|
+
const call = consoleInfoSpy.mock.calls[0][0];
|
|
317
|
+
expect(call).toContain('entry message');
|
|
318
|
+
expect(call).toContain('"extra":"data"');
|
|
319
|
+
});
|
|
320
|
+
});
|
|
321
|
+
describe('context merging', () => {
|
|
322
|
+
test('merges instance context with call context', () => {
|
|
323
|
+
consoleLogger.attach({ instanceKey: 'instanceValue' });
|
|
324
|
+
consoleLogger.log('info', 'test message', { callKey: 'callValue' });
|
|
325
|
+
expect(consoleInfoSpy).toHaveBeenCalled();
|
|
326
|
+
const call = consoleInfoSpy.mock.calls[0][0];
|
|
327
|
+
expect(call).toContain('"instanceKey":"instanceValue"');
|
|
328
|
+
expect(call).toContain('"callKey":"callValue"');
|
|
329
|
+
});
|
|
330
|
+
});
|
|
331
|
+
describe('level filtering', () => {
|
|
332
|
+
test('default level is info', () => {
|
|
333
|
+
expect(consoleLogger.level).toBe('info');
|
|
334
|
+
});
|
|
335
|
+
test('messages below logger level are not output', () => {
|
|
336
|
+
consoleLogger.setLevel('warn');
|
|
337
|
+
consoleLogger.log('debug', 'debug message');
|
|
338
|
+
consoleLogger.log('trace', 'trace message');
|
|
339
|
+
expect(consoleDebugSpy).not.toHaveBeenCalled();
|
|
340
|
+
expect(consoleLogSpy).not.toHaveBeenCalled();
|
|
341
|
+
});
|
|
342
|
+
test('messages at logger level are output', () => {
|
|
343
|
+
consoleLogger.setLevel('warn');
|
|
344
|
+
consoleLogger.log('warn', 'warn message');
|
|
345
|
+
expect(consoleWarnSpy).toHaveBeenCalled();
|
|
346
|
+
});
|
|
347
|
+
test('messages above logger level are output', () => {
|
|
348
|
+
consoleLogger.setLevel('warn');
|
|
349
|
+
consoleLogger.log('error', 'error message');
|
|
350
|
+
consoleLogger.log('fatal', 'fatal message');
|
|
351
|
+
expect(consoleErrorSpy).toHaveBeenCalledTimes(2);
|
|
352
|
+
});
|
|
353
|
+
test('info level allows info, warn, error, fatal', () => {
|
|
354
|
+
consoleLogger.setLevel('info');
|
|
355
|
+
consoleLogger.log('trace', 'trace message');
|
|
356
|
+
consoleLogger.log('debug', 'debug message');
|
|
357
|
+
consoleLogger.log('info', 'info message');
|
|
358
|
+
consoleLogger.log('warn', 'warn message');
|
|
359
|
+
consoleLogger.log('error', 'error message');
|
|
360
|
+
consoleLogger.log('fatal', 'fatal message');
|
|
361
|
+
expect(consoleDebugSpy).not.toHaveBeenCalled(); // trace and debug filtered
|
|
362
|
+
expect(consoleInfoSpy).toHaveBeenCalledTimes(1);
|
|
363
|
+
expect(consoleWarnSpy).toHaveBeenCalledTimes(1);
|
|
364
|
+
expect(consoleErrorSpy).toHaveBeenCalledTimes(2); // error and fatal
|
|
365
|
+
});
|
|
366
|
+
test('trace level allows all messages', () => {
|
|
367
|
+
consoleLogger.setLevel('trace');
|
|
368
|
+
consoleLogger.log('trace', 'trace message');
|
|
369
|
+
consoleLogger.log('debug', 'debug message');
|
|
370
|
+
consoleLogger.log('info', 'info message');
|
|
371
|
+
consoleLogger.log('warn', 'warn message');
|
|
372
|
+
consoleLogger.log('error', 'error message');
|
|
373
|
+
consoleLogger.log('fatal', 'fatal message');
|
|
374
|
+
expect(consoleDebugSpy).toHaveBeenCalledTimes(2); // trace and debug
|
|
375
|
+
expect(consoleInfoSpy).toHaveBeenCalledTimes(1);
|
|
376
|
+
expect(consoleWarnSpy).toHaveBeenCalledTimes(1);
|
|
377
|
+
expect(consoleErrorSpy).toHaveBeenCalledTimes(2); // error and fatal
|
|
378
|
+
});
|
|
379
|
+
test('fatal level only allows fatal messages', () => {
|
|
380
|
+
consoleLogger.setLevel('fatal');
|
|
381
|
+
consoleLogger.log('trace', 'trace message');
|
|
382
|
+
consoleLogger.log('debug', 'debug message');
|
|
383
|
+
consoleLogger.log('info', 'info message');
|
|
384
|
+
consoleLogger.log('warn', 'warn message');
|
|
385
|
+
consoleLogger.log('error', 'error message');
|
|
386
|
+
consoleLogger.log('fatal', 'fatal message');
|
|
387
|
+
expect(consoleErrorSpy).toHaveBeenCalledTimes(1); // only fatal
|
|
388
|
+
});
|
|
389
|
+
test('level filtering works with entry object format', () => {
|
|
390
|
+
consoleLogger.setLevel('warn');
|
|
391
|
+
consoleLogger.log({ level: 'info', message: 'info message' });
|
|
392
|
+
expect(consoleInfoSpy).not.toHaveBeenCalled();
|
|
393
|
+
consoleLogger.log({ level: 'error', message: 'error message' });
|
|
394
|
+
expect(consoleErrorSpy).toHaveBeenCalled();
|
|
395
|
+
});
|
|
396
|
+
test('setLevel changes filtering behavior', () => {
|
|
397
|
+
consoleLogger.setLevel('error');
|
|
398
|
+
consoleLogger.log('warn', 'warn message');
|
|
399
|
+
expect(consoleWarnSpy).not.toHaveBeenCalled();
|
|
400
|
+
consoleLogger.setLevel('debug');
|
|
401
|
+
consoleLogger.log('debug', 'debug message');
|
|
402
|
+
expect(consoleDebugSpy).toHaveBeenCalled();
|
|
403
|
+
});
|
|
404
|
+
});
|
|
405
|
+
});
|
|
406
|
+
describe('ConfigurableLogger', () => {
|
|
407
|
+
let configurableLogger;
|
|
408
|
+
let mockDelegate;
|
|
409
|
+
beforeEach(() => {
|
|
410
|
+
mockDelegate = new MockLogger();
|
|
411
|
+
configurableLogger = new ConfigurableLogger(mockDelegate);
|
|
412
|
+
});
|
|
413
|
+
describe('constructor', () => {
|
|
414
|
+
test('uses provided delegate', () => {
|
|
415
|
+
expect(configurableLogger.getDelegate()).toBe(mockDelegate);
|
|
416
|
+
});
|
|
417
|
+
test('defaults to ConsoleLogger when no delegate provided', () => {
|
|
418
|
+
const defaultLogger = new ConfigurableLogger();
|
|
419
|
+
expect(defaultLogger.getDelegate()).toBeInstanceOf(ConsoleLogger);
|
|
420
|
+
});
|
|
421
|
+
});
|
|
422
|
+
describe('setDelegate / getDelegate', () => {
|
|
423
|
+
test('can swap delegate at runtime', () => {
|
|
424
|
+
const newMockDelegate = new MockLogger();
|
|
425
|
+
configurableLogger.setDelegate(newMockDelegate);
|
|
426
|
+
expect(configurableLogger.getDelegate()).toBe(newMockDelegate);
|
|
427
|
+
});
|
|
428
|
+
test('children spawned before swap use new delegate', () => {
|
|
429
|
+
const child = configurableLogger.spawn();
|
|
430
|
+
const newMockDelegate = new MockLogger();
|
|
431
|
+
configurableLogger.setDelegate(newMockDelegate);
|
|
432
|
+
child.log('info', 'child message');
|
|
433
|
+
expect(newMockDelegate.calls).toHaveLength(1);
|
|
434
|
+
expect(newMockDelegate.calls[0]).toEqual({
|
|
435
|
+
level: 'info',
|
|
436
|
+
message: 'child message',
|
|
437
|
+
ctx: {},
|
|
438
|
+
});
|
|
439
|
+
});
|
|
440
|
+
test('children maintain delegate reference through parent', () => {
|
|
441
|
+
const child = configurableLogger.spawn();
|
|
442
|
+
const newMockDelegate = new MockLogger();
|
|
443
|
+
// Before swap, child uses original delegate
|
|
444
|
+
child.log('info', 'before swap');
|
|
445
|
+
expect(mockDelegate.calls).toHaveLength(1);
|
|
446
|
+
// After swap, child should use new delegate
|
|
447
|
+
configurableLogger.setDelegate(newMockDelegate);
|
|
448
|
+
child.log('info', 'after swap');
|
|
449
|
+
expect(newMockDelegate.calls).toHaveLength(1);
|
|
450
|
+
expect(newMockDelegate.calls[0].message).toBe('after swap');
|
|
451
|
+
});
|
|
452
|
+
test('spawned child inherits parent context', () => {
|
|
453
|
+
configurableLogger.attach({ parentKey: 'parentValue' });
|
|
454
|
+
const child = configurableLogger.spawn({ childKey: 'childValue' });
|
|
455
|
+
child.log('info', 'test message');
|
|
456
|
+
expect(mockDelegate.calls[0].ctx).toEqual({
|
|
457
|
+
parentKey: 'parentValue',
|
|
458
|
+
childKey: 'childValue',
|
|
459
|
+
});
|
|
460
|
+
});
|
|
461
|
+
});
|
|
462
|
+
describe('logging through delegate', () => {
|
|
463
|
+
test('delegates log calls to underlying logger', () => {
|
|
464
|
+
configurableLogger.log('info', 'test message', { key: 'value' });
|
|
465
|
+
expect(mockDelegate.calls).toHaveLength(1);
|
|
466
|
+
expect(mockDelegate.calls[0]).toEqual({
|
|
467
|
+
level: 'info',
|
|
468
|
+
message: 'test message',
|
|
469
|
+
ctx: { key: 'value' },
|
|
470
|
+
});
|
|
471
|
+
});
|
|
472
|
+
test('level-specific methods delegate correctly', () => {
|
|
473
|
+
configurableLogger.error('error message');
|
|
474
|
+
expect(mockDelegate.calls[0].level).toBe('error');
|
|
475
|
+
});
|
|
476
|
+
});
|
|
477
|
+
});
|
|
478
|
+
describe('Factory Functions', () => {
|
|
479
|
+
describe('createConfigurableLogger', () => {
|
|
480
|
+
test('returns ConfigurableLogger instance', () => {
|
|
481
|
+
const logger = createConfigurableLogger();
|
|
482
|
+
expect(logger).toBeInstanceOf(ConfigurableLogger);
|
|
483
|
+
});
|
|
484
|
+
test('uses default ConsoleLogger when no delegate provided', () => {
|
|
485
|
+
const logger = createConfigurableLogger();
|
|
486
|
+
expect(logger.getDelegate()).toBeInstanceOf(ConsoleLogger);
|
|
487
|
+
});
|
|
488
|
+
test('uses provided delegate', () => {
|
|
489
|
+
const mockDelegate = new MockLogger();
|
|
490
|
+
const logger = createConfigurableLogger(mockDelegate);
|
|
491
|
+
expect(logger.getDelegate()).toBe(mockDelegate);
|
|
492
|
+
});
|
|
493
|
+
});
|
|
494
|
+
describe('configureLogger', () => {
|
|
495
|
+
test('sets delegate on ConfigurableLogger', () => {
|
|
496
|
+
const configurableLogger = new ConfigurableLogger();
|
|
497
|
+
const mockDelegate = new MockLogger();
|
|
498
|
+
configureLogger(configurableLogger, mockDelegate);
|
|
499
|
+
expect(configurableLogger.getDelegate()).toBe(mockDelegate);
|
|
500
|
+
});
|
|
501
|
+
test('throws error for non-ConfigurableLogger instances', () => {
|
|
502
|
+
const consoleLogger = new ConsoleLogger();
|
|
503
|
+
const mockDelegate = new MockLogger();
|
|
504
|
+
expect(() => configureLogger(consoleLogger, mockDelegate)).toThrow('Logger must be a ConfigurableLogger instance');
|
|
505
|
+
});
|
|
506
|
+
});
|
|
507
|
+
describe('logger singleton', () => {
|
|
508
|
+
test('is a ConfigurableLogger instance', () => {
|
|
509
|
+
expect(logger).toBeInstanceOf(ConfigurableLogger);
|
|
510
|
+
});
|
|
511
|
+
test('has default ConsoleLogger delegate', () => {
|
|
512
|
+
expect(logger.getDelegate()).toBeInstanceOf(ConsoleLogger);
|
|
513
|
+
});
|
|
514
|
+
});
|
|
515
|
+
});
|
|
516
|
+
//# sourceMappingURL=logger.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"logger.test.js","sourceRoot":"","sources":["../src/logger.test.ts"],"names":[],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@qianxude/shared",
|
|
3
|
+
"version": "0.1.2",
|
|
4
|
+
"description": "qian shared types and classes",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./dist/index.js",
|
|
7
|
+
"types": "./dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
},
|
|
13
|
+
"./global": {
|
|
14
|
+
"types": "./dist/global.d.ts"
|
|
15
|
+
}
|
|
16
|
+
},
|
|
17
|
+
"typesVersions": {
|
|
18
|
+
"*": {
|
|
19
|
+
"global": [
|
|
20
|
+
"./dist/global.d.ts"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"publishConfig": {
|
|
25
|
+
"access": "public"
|
|
26
|
+
},
|
|
27
|
+
"engines": {
|
|
28
|
+
"node": ">=18",
|
|
29
|
+
"bun": ">=1.0.0"
|
|
30
|
+
},
|
|
31
|
+
"files": [
|
|
32
|
+
"dist",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"scripts": {
|
|
37
|
+
"build": "bun x tsc -p tsconfig.json",
|
|
38
|
+
"test": "bun test",
|
|
39
|
+
"typecheck": "bun x tsc -p tsconfig.json --noEmit"
|
|
40
|
+
}
|
|
41
|
+
}
|