Loading source
Pulling the file list, source metadata, and syntax-aware rendering for this listing.
Source from repo
Generate images via OpenAI, Google, OpenRouter, DashScope, Jimeng, Seedream, and Replicate APIs with batch support.
Files
Skill
Size
Entrypoint
Format
Open file
Syntax-highlighted preview of this file as included in the skill package.
scripts/codex-imagegen/logger.ts
1import { appendFile, mkdir } from "node:fs/promises";2import path from "node:path";34export interface LogEntry {5ts: string;6level: "info" | "warn" | "error";7event: string;8[k: string]: unknown;9}1011export class JsonLogger {12constructor(private logFile: string | null, public verbose: boolean) {}1314async log(level: LogEntry["level"], event: string, extra: Record<string, unknown> = {}): Promise<void> {15const entry: LogEntry = { ts: new Date().toISOString(), level, event, ...extra };16const line = JSON.stringify(entry);17if (this.verbose) process.stderr.write(`[${level}] ${event} ${jsonExtras(extra)}\n`);18if (this.logFile) {19await mkdir(path.dirname(this.logFile), { recursive: true });20await appendFile(this.logFile, line + "\n", "utf-8");21}22}2324info(event: string, extra?: Record<string, unknown>) {25return this.log("info", event, extra);26}27warn(event: string, extra?: Record<string, unknown>) {28return this.log("warn", event, extra);29}30error(event: string, extra?: Record<string, unknown>) {31return this.log("error", event, extra);32}33}3435function jsonExtras(extra: Record<string, unknown>): string {36const entries = Object.entries(extra);37if (entries.length === 0) return "";38return entries.map(([k, v]) => `${k}=${typeof v === "string" ? v : JSON.stringify(v)}`).join(" ");39}40