trufflehog-js
Version:
TypeScript wrapper for TruffleHog secret scanner
136 lines (112 loc) • 3.33 kB
text/typescript
/**
* Copyright (c) 2025 maloma7. All rights reserved.
* SPDX-License-Identifier: MIT
*/
import type { Logger, LogLevel } from "./types.ts";
const LOG_LEVELS: Record<LogLevel, number> = {
debug: 0,
info: 1,
warn: 2,
error: 3,
};
const LOG_COLORS = {
debug: "\x1b[90m", // Gray
info: "\x1b[36m", // Cyan
warn: "\x1b[33m", // Yellow
error: "\x1b[31m", // Red
reset: "\x1b[0m",
} as const;
export class TruffleHogLogger implements Logger {
private readonly level: LogLevel;
private readonly quiet: boolean;
private readonly timestamp: boolean;
constructor(
options: {
level?: LogLevel;
quiet?: boolean;
timestamp?: boolean;
} = {},
) {
this.level = options.level ?? this.getDefaultLogLevel();
this.quiet = options.quiet ?? false;
this.timestamp = options.timestamp ?? false;
}
private getDefaultLogLevel(): LogLevel {
const envLevel = Bun.env.TRUFFLEHOG_LOG_LEVEL?.toLowerCase() as LogLevel;
if (envLevel && envLevel in LOG_LEVELS) {
return envLevel;
}
// Default to 'warn' for pre-commit hooks to minimize noise
return "warn";
}
private shouldLog(level: LogLevel): boolean {
if (this.quiet && level !== "error") {
return false;
}
return LOG_LEVELS[level] >= LOG_LEVELS[this.level];
}
private formatMessage(level: LogLevel, message: string): string {
const timestamp = this.timestamp ? `[${new Date().toISOString()}] ` : "";
const prefix = level === "info" ? "" : `[${level.toUpperCase()}] `;
const color = LOG_COLORS[level];
const reset = LOG_COLORS.reset;
return `${color}${timestamp}${prefix}${message}${reset}`;
}
debug(message: string, ...args: unknown[]): void {
if (!this.shouldLog("debug")) return;
const formatted = this.formatMessage("debug", message);
if (args.length > 0) {
globalThis.console.debug(formatted, ...args);
} else {
globalThis.console.debug(formatted);
}
}
info(message: string, ...args: unknown[]): void {
if (!this.shouldLog("info")) return;
const formatted = this.formatMessage("info", message);
if (args.length > 0) {
globalThis.console.info(formatted, ...args);
} else {
globalThis.console.info(formatted);
}
}
warn(message: string, ...args: unknown[]): void {
if (!this.shouldLog("warn")) return;
const formatted = this.formatMessage("warn", message);
if (args.length > 0) {
globalThis.console.warn(formatted, ...args);
} else {
globalThis.console.warn(formatted);
}
}
error(message: string, ...args: unknown[]): void {
if (!this.shouldLog("error")) return;
const formatted = this.formatMessage("error", message);
if (args.length > 0) {
globalThis.console.error(formatted, ...args);
} else {
globalThis.console.error(formatted);
}
}
}
export function createLogger(options?: {
level?: LogLevel;
quiet?: boolean;
verbose?: boolean;
timestamp?: boolean;
}): Logger {
let level: LogLevel | undefined = options?.level;
if (options?.verbose && !level) {
level = "debug";
} else if (options?.quiet && !level) {
level = "error";
}
return new TruffleHogLogger({
...(level !== undefined ? { level } : {}),
...(options?.quiet !== undefined ? { quiet: options.quiet } : {}),
...(options?.timestamp !== undefined
? { timestamp: options.timestamp }
: {}),
});
}
export const defaultLogger = new TruffleHogLogger();