/** The log of a server: events to stdout, warnings and errors in colour to stderr, and requests when they are on. */ export type Log = { event: (text: string) => void warn: (text: string) => void error: (text: string) => void request: (text: string) => void } /** A log that writes nothing, for tests. */ export const QUIET: Log = { event() {}, warn() {}, error() {}, request() {} } /** * The log of a server. With timestamps each line starts with the local time with milliseconds; requests logs each * request to stderr, otherwise request writes nothing. */ export function createLog(options: { timestamps: boolean; requests: boolean }): Log { const line = (text: string) => { if (!options.timestamps) { return text } const now = new Date() const pad = (value: number, size = 2) => String(value).padStart(size, '0') return `${pad(now.getHours())}:${pad(now.getMinutes())}:${pad(now.getSeconds())}.${pad(now.getMilliseconds(), 3)} ${text}` } return { event: (text) => console.log(line(text)), warn: (text) => console.error(`\x1b[33m${line(`warning: ${text}`)}\x1b[0m`), error: (text) => console.error(`\x1b[31m${line(`error: ${text}`)}\x1b[0m`), request: options.requests ? (text) => console.error(line(text)) : () => {}, } } /** Whether --timestamps auto|on|off asks for timestamps: auto only when stdout is a terminal. */ export function timestampsOn(choice: string) { return choice === 'on' || (choice === 'auto' && process.stdout.isTTY === true) } /** Prints the message in red to stderr as an error and ends the process with status 2. */ export function fail(message: string): never { console.error(`\x1b[31merror: ${message}\x1b[0m`) process.exit(2) }