import { writeFileSync } from 'fs'; import { join } from 'path'; import { ensureFolderExists } from './file-utils'; import { Image } from './image-utils'; export default class Diagnostics { private store: Array<{ time: Date, message: string, image: Image, additionalMessage: string }>; private enabled: boolean; private prefixes: Array; constructor(enabled: boolean) { this.enabled = enabled; if (this.enabled) { this.prefixes = []; this.store = new Array<{ time: Date, message: string, image: Image, additionalMessage: string }>(); } } pushPrefix(value: string): void { if (!this.enabled) { return; } this.prefixes.push(value); } popPrefix(): boolean { if (!this.enabled) { return false; } return !!this.prefixes.length && !!this.prefixes.pop(); } private preformatMessage(message: string): string { return this.prefixes.join() + message; } log(value: string, data?: Image | unknown): void { if (!this.enabled) { return; } const { image, additionalMessage } = data instanceof Image ? { image: data.clone(), additionalMessage: undefined } : { image: undefined, additionalMessage: JSON.stringify(data, null, 2) }; this.store.push({ time: new Date(), message: this.preformatMessage(value), image, additionalMessage, }); } save(basePath: string, relative: string): void { if (!this.enabled) { return; } if (relative.endsWith('.png')) { relative = relative.slice(0, -4); } const folderName = join(basePath, relative); ensureFolderExists(folderName); this.store .filter((x) => x.image) .forEach((x) => { const fileName = this.getImageFileName(x); writeFileSync(join(folderName, fileName), x.image.getBuffer()); }); const logString = this.store.map((x) => { let result = `[${x.time}] ${x.message} `; if (x.image) { result += `>> ${this.getImageFileName(x)}`; } if (x.additionalMessage) { result += `:\r\n${x.additionalMessage}`; } return result; }).join('\r\n'); writeFileSync(join(folderName, 'log.txt'), logString); } private getImageFileName(x: { message: string; image: Image; }) { let fileName = x.message; // https://docs.microsoft.com/en-us/windows/win32/api/shlobj_core/nf-shlobj_core-pathcleanupspec#remarks fileName = fileName.replace(/[\\/:*?"<>|\s]/g, '_'); if (!fileName.endsWith('.png')) { fileName += '.png'; } return fileName; } }