-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathformat.ts
More file actions
109 lines (96 loc) · 3.14 KB
/
format.ts
File metadata and controls
109 lines (96 loc) · 3.14 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
/*
* Copyright (c) 2025, Salesforce, Inc.
* SPDX-License-Identifier: Apache-2
* For full license text, see the license.txt file in the repo root or http://www.apache.org/licenses/LICENSE-2.0
*/
import type {LogEntry} from '@salesforce/b2c-tooling-sdk/operations/logs';
import {createPathNormalizer, discoverAndCreateNormalizer} from '@salesforce/b2c-tooling-sdk/operations/logs';
/**
* Default log prefixes to retrieve/tail.
*/
export const DEFAULT_PREFIXES = ['error', 'customerror'];
/**
* ANSI color codes for log levels.
*/
const LEVEL_COLORS: Record<string, string> = {
ERROR: '\u001B[31m', // Red
FATAL: '\u001B[35m', // Magenta
WARN: '\u001B[33m', // Yellow
INFO: '\u001B[36m', // Cyan
DEBUG: '\u001B[90m', // Gray
TRACE: '\u001B[90m', // Gray
};
const RESET = '\u001B[0m';
const DIM = '\u001B[2m';
const BOLD = '\u001B[1m';
/**
* Formats a log entry for human-readable output.
*
* Output format:
* LEVEL [timestamp] [file]
* message (may be multi-line)
*/
export function formatEntry(entry: LogEntry, useColor: boolean): string {
const headerParts: string[] = [];
// Level first (most important for scanning)
if (entry.level) {
if (useColor) {
const color = LEVEL_COLORS[entry.level] || '';
headerParts.push(`${color}${BOLD}${entry.level}${RESET}`);
} else {
headerParts.push(entry.level);
}
}
// Timestamp
if (entry.timestamp) {
if (useColor) {
headerParts.push(`${DIM}[${entry.timestamp}]${RESET}`);
} else {
headerParts.push(`[${entry.timestamp}]`);
}
}
// File name (dimmed)
if (useColor) {
headerParts.push(`${DIM}[${entry.file}]${RESET}`);
} else {
headerParts.push(`[${entry.file}]`);
}
// Build output: header line followed by message, with trailing blank line
const header = headerParts.join(' ');
return `${header}\n${entry.message}\n`;
}
/**
* Matches a B2C log line start: [YYYY-MM-DD HH:MM:SS.mmm GMT] LEVEL ...
*/
const LOG_LINE_RE = /^(\[\d{4}-\d{2}-\d{2}\s+\d{2}:\d{2}:\d{2}\.\d+\s+\w+\])\s+(ERROR|FATAL|WARN|INFO|DEBUG|TRACE)\b/;
/**
* Applies ANSI highlighting to raw log text, line by line.
* Timestamps are dimmed, log levels are colored to match `formatEntry` output.
* Useful for job logs and other raw log content that hasn't been parsed into LogEntry objects.
*/
export function highlightLogText(text: string): string {
return text
.split('\n')
.map((line) => {
const match = LOG_LINE_RE.exec(line);
if (!match) return line;
const [, timestamp, level] = match;
const color = LEVEL_COLORS[level] || '';
const rest = line.slice(match[0].length);
return `${DIM}${timestamp}${RESET} ${color}${level}${RESET}${rest}`;
})
.join('\n');
}
/**
* Sets up a path normalizer for IDE click-to-open functionality.
* Priority: 1) explicit cartridgePath, 2) auto-discover cartridges, 3) undefined (no normalization)
*/
export function setupPathNormalizer(
cartridgePath: string | undefined,
noNormalize: boolean,
): ((msg: string) => string) | undefined {
if (noNormalize) {
return undefined;
}
return cartridgePath ? createPathNormalizer({cartridgePath}) : discoverAndCreateNormalizer();
}