@qlover/scripts-context 1.0.0 → 1.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/dist/index.js +354 -6
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -2818,9 +2818,116 @@ var LogEvent = class {
|
|
|
2818
2818
|
this.context = context;
|
|
2819
2819
|
this.timestamp = Date.now();
|
|
2820
2820
|
}
|
|
2821
|
+
/**
|
|
2822
|
+
* Timestamp when the log event was created
|
|
2823
|
+
*
|
|
2824
|
+
* Automatically set to the current time in milliseconds since the Unix epoch
|
|
2825
|
+
* when the event is constructed. This ensures accurate timing information
|
|
2826
|
+
* for each log entry.
|
|
2827
|
+
*
|
|
2828
|
+
* @example
|
|
2829
|
+
* ```typescript
|
|
2830
|
+
* const event = new LogEvent('info', ['message'], 'app');
|
|
2831
|
+
* console.log(new Date(event.timestamp).toISOString());
|
|
2832
|
+
* // Output: "2024-03-21T14:30:45.123Z"
|
|
2833
|
+
* ```
|
|
2834
|
+
*/
|
|
2821
2835
|
timestamp;
|
|
2822
2836
|
};
|
|
2823
2837
|
var LogContext = class {
|
|
2838
|
+
/**
|
|
2839
|
+
* Creates a new LogContext instance
|
|
2840
|
+
*
|
|
2841
|
+
* @param value - Optional context value of type Value
|
|
2842
|
+
*
|
|
2843
|
+
* The value parameter is marked as optional to support:
|
|
2844
|
+
* - Empty contexts (no value provided)
|
|
2845
|
+
* - Explicitly undefined values
|
|
2846
|
+
* - Nullable types (Value | null)
|
|
2847
|
+
*
|
|
2848
|
+
* The value is stored as a public property to allow:
|
|
2849
|
+
* - Direct access in formatters and handlers
|
|
2850
|
+
* - Type-safe value extraction
|
|
2851
|
+
* - Optional chaining support
|
|
2852
|
+
*
|
|
2853
|
+
* @example Basic construction
|
|
2854
|
+
* ```typescript
|
|
2855
|
+
* // With value
|
|
2856
|
+
* const context = new LogContext({ userId: 123 });
|
|
2857
|
+
* console.log(context.value?.userId); // 123
|
|
2858
|
+
*
|
|
2859
|
+
* // Empty context
|
|
2860
|
+
* const empty = new LogContext();
|
|
2861
|
+
* console.log(empty.value); // undefined
|
|
2862
|
+
* ```
|
|
2863
|
+
*
|
|
2864
|
+
* @example Type-safe construction
|
|
2865
|
+
* ```typescript
|
|
2866
|
+
* interface UserContext {
|
|
2867
|
+
* id: number;
|
|
2868
|
+
* name: string;
|
|
2869
|
+
* role?: string;
|
|
2870
|
+
* }
|
|
2871
|
+
*
|
|
2872
|
+
* const context = new LogContext<UserContext>({
|
|
2873
|
+
* id: 123,
|
|
2874
|
+
* name: 'John',
|
|
2875
|
+
* role: 'admin' // Optional property
|
|
2876
|
+
* });
|
|
2877
|
+
*
|
|
2878
|
+
* // Type-safe access
|
|
2879
|
+
* const userId = context.value?.id; // number | undefined
|
|
2880
|
+
* const role = context.value?.role; // string | undefined
|
|
2881
|
+
* ```
|
|
2882
|
+
*
|
|
2883
|
+
* @example Nullable context
|
|
2884
|
+
* ```typescript
|
|
2885
|
+
* type NullableContext = {
|
|
2886
|
+
* sessionId: string;
|
|
2887
|
+
* } | null;
|
|
2888
|
+
*
|
|
2889
|
+
* // With value
|
|
2890
|
+
* const active = new LogContext<NullableContext>({
|
|
2891
|
+
* sessionId: 'sess-123'
|
|
2892
|
+
* });
|
|
2893
|
+
*
|
|
2894
|
+
* // With null
|
|
2895
|
+
* const inactive = new LogContext<NullableContext>(null);
|
|
2896
|
+
*
|
|
2897
|
+
* // Type-safe null handling
|
|
2898
|
+
* console.log(active.value?.sessionId); // 'sess-123'
|
|
2899
|
+
* console.log(inactive.value?.sessionId); // undefined
|
|
2900
|
+
* ```
|
|
2901
|
+
*
|
|
2902
|
+
* @example Context in logging
|
|
2903
|
+
* ```typescript
|
|
2904
|
+
* interface RequestContext {
|
|
2905
|
+
* path: string;
|
|
2906
|
+
* method: string;
|
|
2907
|
+
* duration: number;
|
|
2908
|
+
* }
|
|
2909
|
+
*
|
|
2910
|
+
* const context = new LogContext<RequestContext>({
|
|
2911
|
+
* path: '/api/users',
|
|
2912
|
+
* method: 'GET',
|
|
2913
|
+
* duration: 150
|
|
2914
|
+
* });
|
|
2915
|
+
*
|
|
2916
|
+
* // Using context in log messages
|
|
2917
|
+
* logger.info('Request completed', context);
|
|
2918
|
+
*
|
|
2919
|
+
* // Accessing context in formatters
|
|
2920
|
+
* class RequestFormatter implements FormatterInterface<RequestContext> {
|
|
2921
|
+
* format(event: LogEvent<RequestContext>): string[] {
|
|
2922
|
+
* const ctx = event.context?.value;
|
|
2923
|
+
* return [
|
|
2924
|
+
* ctx ? `${ctx.method} ${ctx.path} (${ctx.duration}ms)` : 'Unknown',
|
|
2925
|
+
* ...event.args
|
|
2926
|
+
* ];
|
|
2927
|
+
* }
|
|
2928
|
+
* }
|
|
2929
|
+
* ```
|
|
2930
|
+
*/
|
|
2824
2931
|
constructor(value) {
|
|
2825
2932
|
this.value = value;
|
|
2826
2933
|
}
|
|
@@ -3113,23 +3220,189 @@ var Logger = class {
|
|
|
3113
3220
|
}
|
|
3114
3221
|
};
|
|
3115
3222
|
var ConsoleHandler = class {
|
|
3223
|
+
/**
|
|
3224
|
+
* Creates a new ConsoleHandler instance
|
|
3225
|
+
*
|
|
3226
|
+
* @param formatter - Optional formatter for customizing log message format
|
|
3227
|
+
* If not provided, raw log messages will be output
|
|
3228
|
+
*
|
|
3229
|
+
* @example Without formatter
|
|
3230
|
+
* ```typescript
|
|
3231
|
+
* const handler = new ConsoleHandler();
|
|
3232
|
+
* // Output: Raw message without formatting
|
|
3233
|
+
* ```
|
|
3234
|
+
*
|
|
3235
|
+
* @example With timestamp formatter
|
|
3236
|
+
* ```typescript
|
|
3237
|
+
* const handler = new ConsoleHandler(
|
|
3238
|
+
* new TimestampFormatter({
|
|
3239
|
+
* locale: 'zh-CN',
|
|
3240
|
+
* prefixTemplate: '[{formattedTimestamp}] {level}:'
|
|
3241
|
+
* })
|
|
3242
|
+
* );
|
|
3243
|
+
* // Output: [2024-03-21 14:30:45] INFO: Message
|
|
3244
|
+
* ```
|
|
3245
|
+
*
|
|
3246
|
+
* @example With JSON formatter
|
|
3247
|
+
* ```typescript
|
|
3248
|
+
* const handler = new ConsoleHandler(
|
|
3249
|
+
* new JSONFormatter({
|
|
3250
|
+
* pretty: true,
|
|
3251
|
+
* fields: ['timestamp', 'level', 'message']
|
|
3252
|
+
* })
|
|
3253
|
+
* );
|
|
3254
|
+
* // Output: {
|
|
3255
|
+
* // "timestamp": "2024-03-21T14:30:45.000Z",
|
|
3256
|
+
* // "level": "INFO",
|
|
3257
|
+
* // "message": "Application started"
|
|
3258
|
+
* // }
|
|
3259
|
+
* ```
|
|
3260
|
+
*/
|
|
3116
3261
|
constructor(formatter = null) {
|
|
3117
3262
|
this.formatter = formatter;
|
|
3118
3263
|
}
|
|
3119
3264
|
/**
|
|
3120
|
-
*
|
|
3265
|
+
* Sets or updates the formatter for this handler
|
|
3121
3266
|
*
|
|
3122
|
-
*
|
|
3123
|
-
*
|
|
3267
|
+
* This method allows dynamic updating of the formatter after handler creation.
|
|
3268
|
+
* It's useful when you need to change the formatting style without creating
|
|
3269
|
+
* a new handler instance.
|
|
3270
|
+
*
|
|
3271
|
+
* @override Implementation of HandlerInterface
|
|
3272
|
+
* @param formatter - The formatter instance to use for formatting log messages
|
|
3273
|
+
*
|
|
3274
|
+
* @example Changing formatter at runtime
|
|
3275
|
+
* ```typescript
|
|
3276
|
+
* const handler = new ConsoleHandler();
|
|
3277
|
+
* const logger = new Logger({ handlers: [handler] });
|
|
3278
|
+
*
|
|
3279
|
+
* // Initially no formatting
|
|
3280
|
+
* logger.info('Plain message');
|
|
3281
|
+
* // Output: Plain message
|
|
3282
|
+
*
|
|
3283
|
+
* // Switch to timestamp formatting
|
|
3284
|
+
* handler.setFormatter(new TimestampFormatter());
|
|
3285
|
+
* logger.info('Formatted message');
|
|
3286
|
+
* // Output: [2024-03-21 14:30:45 INFO] Formatted message
|
|
3287
|
+
*
|
|
3288
|
+
* // Switch to JSON formatting
|
|
3289
|
+
* handler.setFormatter(new JSONFormatter());
|
|
3290
|
+
* logger.info('JSON message');
|
|
3291
|
+
* // Output: {"timestamp":"2024-03-21T14:30:45.000Z","level":"INFO","message":"JSON message"}
|
|
3292
|
+
* ```
|
|
3293
|
+
*
|
|
3294
|
+
* @example Conditional formatting
|
|
3295
|
+
* ```typescript
|
|
3296
|
+
* const handler = new ConsoleHandler();
|
|
3297
|
+
* const logger = new Logger({ handlers: [handler] });
|
|
3298
|
+
*
|
|
3299
|
+
* if (process.env.NODE_ENV === 'development') {
|
|
3300
|
+
* // Use pretty formatting in development
|
|
3301
|
+
* handler.setFormatter(new TimestampFormatter({
|
|
3302
|
+
* prefixTemplate: '[{formattedTimestamp}] {level}:'
|
|
3303
|
+
* }));
|
|
3304
|
+
* } else {
|
|
3305
|
+
* // Use JSON formatting in production
|
|
3306
|
+
* handler.setFormatter(new JSONFormatter({
|
|
3307
|
+
* fields: ['timestamp', 'level', 'message', 'metadata']
|
|
3308
|
+
* }));
|
|
3309
|
+
* }
|
|
3310
|
+
* ```
|
|
3124
3311
|
*/
|
|
3125
3312
|
setFormatter(formatter) {
|
|
3126
3313
|
this.formatter = formatter;
|
|
3127
3314
|
}
|
|
3128
3315
|
/**
|
|
3129
|
-
*
|
|
3316
|
+
* Processes and outputs a log event to the console
|
|
3130
3317
|
*
|
|
3131
|
-
*
|
|
3132
|
-
*
|
|
3318
|
+
* This method:
|
|
3319
|
+
* 1. Extracts level and arguments from the event
|
|
3320
|
+
* 2. Applies formatting if a formatter is set
|
|
3321
|
+
* 3. Selects appropriate console method based on level
|
|
3322
|
+
* 4. Outputs the formatted message to the console
|
|
3323
|
+
*
|
|
3324
|
+
* @override Implementation of HandlerInterface
|
|
3325
|
+
* @param event - The log event to process and output
|
|
3326
|
+
*
|
|
3327
|
+
* @example Basic event handling
|
|
3328
|
+
* ```typescript
|
|
3329
|
+
* const handler = new ConsoleHandler();
|
|
3330
|
+
*
|
|
3331
|
+
* // Simple message
|
|
3332
|
+
* handler.append({
|
|
3333
|
+
* level: 'info',
|
|
3334
|
+
* args: ['Application started'],
|
|
3335
|
+
* timestamp: Date.now(),
|
|
3336
|
+
* loggerName: 'app'
|
|
3337
|
+
* });
|
|
3338
|
+
* // Console output: Application started
|
|
3339
|
+
*
|
|
3340
|
+
* // Message with context
|
|
3341
|
+
* handler.append({
|
|
3342
|
+
* level: 'error',
|
|
3343
|
+
* args: [
|
|
3344
|
+
* 'Database connection failed',
|
|
3345
|
+
* { host: 'localhost', port: 5432, error: 'Connection refused' }
|
|
3346
|
+
* ],
|
|
3347
|
+
* timestamp: Date.now(),
|
|
3348
|
+
* loggerName: 'db'
|
|
3349
|
+
* });
|
|
3350
|
+
* // Console output: Database connection failed { host: 'localhost', ... }
|
|
3351
|
+
* ```
|
|
3352
|
+
*
|
|
3353
|
+
* @example Formatted event handling
|
|
3354
|
+
* ```typescript
|
|
3355
|
+
* const handler = new ConsoleHandler(
|
|
3356
|
+
* new TimestampFormatter({
|
|
3357
|
+
* prefixTemplate: '[{formattedTimestamp}] {level}:'
|
|
3358
|
+
* })
|
|
3359
|
+
* );
|
|
3360
|
+
*
|
|
3361
|
+
* handler.append({
|
|
3362
|
+
* level: 'warn',
|
|
3363
|
+
* args: ['High memory usage', { usage: '85%' }],
|
|
3364
|
+
* timestamp: Date.now(),
|
|
3365
|
+
* loggerName: 'system'
|
|
3366
|
+
* });
|
|
3367
|
+
* // Console output: [2024-03-21 14:30:45] WARN: High memory usage { usage: '85%' }
|
|
3368
|
+
* ```
|
|
3369
|
+
*
|
|
3370
|
+
* @example Level-specific console methods
|
|
3371
|
+
* ```typescript
|
|
3372
|
+
* const handler = new ConsoleHandler();
|
|
3373
|
+
*
|
|
3374
|
+
* // Uses console.error()
|
|
3375
|
+
* handler.append({
|
|
3376
|
+
* level: 'error',
|
|
3377
|
+
* args: ['Critical error'],
|
|
3378
|
+
* timestamp: Date.now(),
|
|
3379
|
+
* loggerName: 'app'
|
|
3380
|
+
* });
|
|
3381
|
+
*
|
|
3382
|
+
* // Uses console.warn()
|
|
3383
|
+
* handler.append({
|
|
3384
|
+
* level: 'warn',
|
|
3385
|
+
* args: ['Deprecated feature used'],
|
|
3386
|
+
* timestamp: Date.now(),
|
|
3387
|
+
* loggerName: 'app'
|
|
3388
|
+
* });
|
|
3389
|
+
*
|
|
3390
|
+
* // Uses console.debug()
|
|
3391
|
+
* handler.append({
|
|
3392
|
+
* level: 'debug',
|
|
3393
|
+
* args: ['Processing request'],
|
|
3394
|
+
* timestamp: Date.now(),
|
|
3395
|
+
* loggerName: 'app'
|
|
3396
|
+
* });
|
|
3397
|
+
*
|
|
3398
|
+
* // Unknown level falls back to console.log()
|
|
3399
|
+
* handler.append({
|
|
3400
|
+
* level: 'custom',
|
|
3401
|
+
* args: ['Custom message'],
|
|
3402
|
+
* timestamp: Date.now(),
|
|
3403
|
+
* loggerName: 'app'
|
|
3404
|
+
* });
|
|
3405
|
+
* ```
|
|
3133
3406
|
*/
|
|
3134
3407
|
append(event) {
|
|
3135
3408
|
const { level, args } = event;
|
|
@@ -3145,12 +3418,87 @@ var defaultLocaleOptions = {
|
|
|
3145
3418
|
timeZone: "UTC"
|
|
3146
3419
|
};
|
|
3147
3420
|
var TimestampFormatter = class {
|
|
3421
|
+
/**
|
|
3422
|
+
* Creates a new TimestampFormatter instance
|
|
3423
|
+
*
|
|
3424
|
+
* @param options - Configuration options for the formatter
|
|
3425
|
+
*
|
|
3426
|
+
* @example
|
|
3427
|
+
* ```typescript
|
|
3428
|
+
* const formatter = new TimestampFormatter({
|
|
3429
|
+
* locale: 'zh-CN',
|
|
3430
|
+
* prefixTemplate: '[{formattedTimestamp}] {level}:'
|
|
3431
|
+
* });
|
|
3432
|
+
* ```
|
|
3433
|
+
*/
|
|
3148
3434
|
constructor(options = {}) {
|
|
3149
3435
|
this.options = options;
|
|
3150
3436
|
}
|
|
3437
|
+
/**
|
|
3438
|
+
* Replaces template variables in the prefix string with actual values
|
|
3439
|
+
*
|
|
3440
|
+
* This internal method handles the variable substitution in prefix templates,
|
|
3441
|
+
* replacing placeholders like {timestamp} with their corresponding values.
|
|
3442
|
+
*
|
|
3443
|
+
* @param template - The template string containing variables in curly braces
|
|
3444
|
+
* @param vars - Object containing variable names and their values
|
|
3445
|
+
* @returns The template string with all variables replaced
|
|
3446
|
+
*
|
|
3447
|
+
* @example Internal usage
|
|
3448
|
+
* ```typescript
|
|
3449
|
+
* const vars = {
|
|
3450
|
+
* timestamp: '1679395845000',
|
|
3451
|
+
* level: 'INFO',
|
|
3452
|
+
* formattedTimestamp: '2024-03-21 14:30:45'
|
|
3453
|
+
* };
|
|
3454
|
+
*
|
|
3455
|
+
* // Template: "[{formattedTimestamp}] {level}"
|
|
3456
|
+
* // Result: "[2024-03-21 14:30:45] INFO"
|
|
3457
|
+
* const result = this.replacePrefix(template, vars);
|
|
3458
|
+
* ```
|
|
3459
|
+
*
|
|
3460
|
+
* @protected
|
|
3461
|
+
*/
|
|
3151
3462
|
replacePrefix(template, vars) {
|
|
3152
3463
|
return template.replace(/\{([^{}]+)\}/g, (match, p1) => vars[p1] || match);
|
|
3153
3464
|
}
|
|
3465
|
+
/**
|
|
3466
|
+
* Formats a log event by adding a timestamp prefix
|
|
3467
|
+
*
|
|
3468
|
+
* This method implements the FormatterInterface.format method. It:
|
|
3469
|
+
* 1. Extracts format type from context (if provided)
|
|
3470
|
+
* 2. Formats the timestamp according to locale and options
|
|
3471
|
+
* 3. Builds the prefix using the template
|
|
3472
|
+
* 4. Returns the formatted log entry
|
|
3473
|
+
*
|
|
3474
|
+
* @param event - The log event to format
|
|
3475
|
+
* @param event.timestamp - Event timestamp in milliseconds
|
|
3476
|
+
* @param event.level - Log level (e.g., INFO, ERROR)
|
|
3477
|
+
* @param event.args - Original log message arguments
|
|
3478
|
+
* @param event.context - Optional context with format customization
|
|
3479
|
+
* @param event.loggerName - Name of the logger instance
|
|
3480
|
+
*
|
|
3481
|
+
* @returns Array containing the formatted prefix followed by original arguments
|
|
3482
|
+
*
|
|
3483
|
+
* @example Internal processing
|
|
3484
|
+
* ```typescript
|
|
3485
|
+
* // Input event:
|
|
3486
|
+
* {
|
|
3487
|
+
* timestamp: 1679395845000,
|
|
3488
|
+
* level: 'INFO',
|
|
3489
|
+
* args: ['User logged in', { userId: 123 }],
|
|
3490
|
+
* context: { formatType: 'datetime' },
|
|
3491
|
+
* loggerName: 'UserService'
|
|
3492
|
+
* }
|
|
3493
|
+
*
|
|
3494
|
+
* // Output array:
|
|
3495
|
+
* [
|
|
3496
|
+
* '[2024-03-21 14:30:45 INFO]',
|
|
3497
|
+
* 'User logged in',
|
|
3498
|
+
* { userId: 123 }
|
|
3499
|
+
* ]
|
|
3500
|
+
* ```
|
|
3501
|
+
*/
|
|
3154
3502
|
format({ timestamp, level, args, context, loggerName }) {
|
|
3155
3503
|
const {
|
|
3156
3504
|
locale = "zh-CN",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qlover/scripts-context",
|
|
3
3
|
"description": "A scripts context for frontwork",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.1.2",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"private": false,
|
|
7
7
|
"homepage": "https://github.com/qlover/fe-base/tree/master/packages/scripts-context#readme",
|
|
@@ -45,15 +45,15 @@
|
|
|
45
45
|
"@types/shelljs": "^0.8.15",
|
|
46
46
|
"lodash": "^4.17.21",
|
|
47
47
|
"@qlover/env-loader": "0.3.0",
|
|
48
|
-
"@qlover/logger": "0.
|
|
48
|
+
"@qlover/logger": "0.2.0"
|
|
49
49
|
},
|
|
50
50
|
"dependencies": {
|
|
51
|
-
"@qlover/fe-corekit": "^1.
|
|
51
|
+
"@qlover/fe-corekit": "^2.1.0",
|
|
52
52
|
"chalk": "^5.3.0",
|
|
53
53
|
"cosmiconfig": "^9.0.0"
|
|
54
54
|
},
|
|
55
55
|
"scripts": {
|
|
56
56
|
"build": "tsup",
|
|
57
|
-
"build:docs": "fe-code2md
|
|
57
|
+
"build:docs": "fe-code2md -p src -g docs --formatOutput prettier --removePrefix"
|
|
58
58
|
}
|
|
59
59
|
}
|