Skip to content
89 changes: 85 additions & 4 deletions src/addons/consoleCatcher.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,73 @@
const consoleOutput: ConsoleLogEvent[] = [];
let isInitialized = false;

/**

Check warning on line 16 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Missing JSDoc @param "obj" declaration
* Safely stringifies objects handling circular references
*/
const safeStringify = (obj: unknown): string => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd suggest using safe-stringify since it is almost the same, but covered by tests

const seen = new WeakSet();

return JSON.stringify(obj, (key, value) => {

Check warning on line 22 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Block must not be padded by blank lines

if (typeof value === 'object' && value !== null) {

Check warning on line 24 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Block must not be padded by blank lines

if (seen.has(value)) {
return '[Circular]';
}
seen.add(value);
}

return value;
});
};

/**

Check warning on line 36 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Missing JSDoc @param "args" declaration
* Formats console arguments handling %c directives
*/
const formatConsoleArgs = (
args: unknown[]
): { message: string; styles: string[] } => {
if (args.length === 0) return { message: '', styles: [] };

Check warning on line 42 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Object properties must go on a new line

Check warning on line 42 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Expected { after 'if' condition

const firstArg = args[0];
if (typeof firstArg !== 'string' || !firstArg.includes('%c')) {

Check warning on line 45 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Block must not be padded by blank lines

Check warning on line 45 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Expected blank line before this statement

return {
message: args
.map((arg) => (typeof arg === 'string' ? arg : safeStringify(arg)))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if arg is number, boolean?

.join(' '),
styles: [],
};
}

// Handle %c formatting
const message = args[0] as string;
const styles: string[] = [];

// Extract styles from arguments
let styleIndex = 0;

for (let i = 1; i < args.length; i++) {
const arg = args[i];

if (typeof arg === 'string' && message.indexOf('%c', styleIndex) !== -1) {
styles.push(arg);
styleIndex = message.indexOf('%c', styleIndex) + 2;
}
}

// Add remaining arguments that aren't styles
const remainingArgs = args
.slice(styles.length + 1)
.map((arg) => (typeof arg === 'string' ? arg : safeStringify(arg)))
.join(' ');

return {
message: message + (remainingArgs ? ' ' + remainingArgs : ''),
styles,
};
};

const addToConsoleOutput = (logEvent: ConsoleLogEvent): void => {
if (consoleOutput.length >= MAX_LOGS) {
consoleOutput.shift();
Expand All @@ -22,8 +89,10 @@

const createConsoleEventFromError = (
event: ErrorEvent | PromiseRejectionEvent
): ConsoleLogEvent => {

Check warning on line 92 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Block must not be padded by blank lines

if (event instanceof ErrorEvent) {

Check warning on line 94 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Block must not be padded by blank lines

return {
method: 'error',
timestamp: new Date(),
Expand Down Expand Up @@ -53,7 +122,13 @@
}

isInitialized = true;
const consoleMethods: string[] = ['log', 'warn', 'error', 'info', 'debug'];
const consoleMethods: string[] = [
'log',
'warn',
'error',
'info',
'debug',
];

consoleMethods.forEach((method) => {
if (typeof window.console[method] !== 'function') {
Expand All @@ -63,15 +138,19 @@
const oldFunction = window.console[method].bind(window.console);

window.console[method] = function (...args: unknown[]): void {
const stack = new Error().stack?.split('\n').slice(2).join('\n') || '';
const stack =
new Error().stack?.split('\n').slice(2)
.join('\n') || '';

Check failure on line 143 in src/addons/consoleCatcher.ts

View workflow job for this annotation

GitHub Actions / lint

Expected indentation of 14 spaces but found 12
const { message, styles } = formatConsoleArgs(args);

const logEvent: ConsoleLogEvent = {
method,
timestamp: new Date(),
type: method,
message: args.map((arg) => typeof arg === 'string' ? arg : JSON.stringify(arg)).join(' '),
message,
stack,
fileLine: stack.split('\n')[0]?.trim(),
styles,
};

addToConsoleOutput(logEvent);
Expand All @@ -87,10 +166,12 @@
},

getConsoleLogStack(): ConsoleLogEvent[] {

return [ ...consoleOutput ];
},
};
};

const consoleCatcher = createConsoleCatcher();
export const { initConsoleCatcher, getConsoleLogStack, addErrorEvent } = consoleCatcher;
export const { initConsoleCatcher, getConsoleLogStack, addErrorEvent } =
consoleCatcher;
Loading