@nmakarov/cli-toolkit 0.16.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/logger.cjs CHANGED
@@ -70,6 +70,7 @@ var ALL_LEVELS = [
70
70
  "response",
71
71
  "progress"
72
72
  ];
73
+ var DEFAULT_LEVELS = ALL_LEVELS.filter((l) => l !== "silly");
73
74
  var MAX_LEVEL_LENGTH = Math.max(...ALL_LEVELS.map((level) => level.toUpperCase().length));
74
75
  var LEVEL_COLORS = {
75
76
  error: import_chalk.default.red.bold,
@@ -155,7 +156,7 @@ var Logger = class _Logger {
155
156
  silent: false,
156
157
  showLevel: false,
157
158
  timestamp: false,
158
- levels: ALL_LEVELS,
159
+ levels: DEFAULT_LEVELS,
159
160
  progressTimes: false,
160
161
  progressThrottle: void 0
161
162
  };
@@ -315,15 +316,17 @@ var Logger = class _Logger {
315
316
  }
316
317
  normalizeLevels(levels) {
317
318
  if (!levels || !levels.length) {
318
- return ALL_LEVELS;
319
+ return DEFAULT_LEVELS;
319
320
  }
320
- const includes = levels.filter((level) => !level.startsWith("-"));
321
- const excludes = levels.filter((level) => level.startsWith("-")).map((level) => level.slice(1));
322
- const unknown = [...includes, ...excludes].filter((level) => !ALL_LEVELS.includes(level));
321
+ const tokens = levels.map((t) => String(t).trim()).filter(Boolean);
322
+ const explicitIncludes = tokens.filter((t) => !t.startsWith("+") && !t.startsWith("-")).map((t) => t);
323
+ const addIncludes = tokens.filter((t) => t.startsWith("+")).map((t) => t.slice(1));
324
+ const excludes = tokens.filter((t) => t.startsWith("-")).map((t) => t.slice(1));
325
+ const unknown = [...explicitIncludes, ...addIncludes, ...excludes].filter((level) => !ALL_LEVELS.includes(level));
323
326
  if (unknown.length) {
324
327
  console.warn(`[Logger] Unknown level(s): ${unknown.join(", ")}`);
325
328
  }
326
- const base = includes.length ? includes : ALL_LEVELS;
329
+ const base = explicitIncludes.length ? explicitIncludes : Array.from(/* @__PURE__ */ new Set([...DEFAULT_LEVELS, ...addIncludes]));
327
330
  return base.filter((level) => !excludes.includes(level));
328
331
  }
329
332
  isValidMode(mode) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/logger/index.ts","../src/logger/transports.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport util from \"util\";\n\nimport {\n Logger,\n LoggerOptions,\n LoggerProgressOptions,\n LogPayload,\n LevelName,\n LoggerTransport,\n LoggerMode\n} from \"./types.js\";\nimport { ConsoleTransport, ParentProcessTransport } from \"./transports.js\";\nimport type { Context } from \"../init/types.js\";\n\nconst ALL_LEVELS: LevelName[] = [\n \"silly\",\n \"debug\",\n \"logic\",\n \"info\",\n \"notice\",\n \"warn\",\n \"error\",\n \"results\",\n \"request\",\n \"response\",\n \"progress\"\n];\n\n// Calculate maximum level name length for alignment\nconst MAX_LEVEL_LENGTH = Math.max(...ALL_LEVELS.map(level => level.toUpperCase().length));\n\nconst LEVEL_COLORS: Record<LevelName, chalk.Chalk> = {\n error: chalk.red.bold,\n warn: chalk.rgb(255, 165, 0),\n notice: chalk.cyan,\n info: chalk.white.bold,\n logic: chalk.gray,\n debug: chalk.gray,\n silly: chalk.gray,\n request: chalk.green,\n response: chalk.yellow,\n progress: chalk.green,\n results: chalk.magenta\n};\n\ninterface NormalizedOptions {\n mode: LoggerMode;\n route: \"console\" | \"ipc\";\n prefix?: string;\n silent: boolean;\n showLevel: boolean;\n timestamp: boolean;\n levels: LevelName[];\n progressTimes: boolean;\n progressThrottle?: number;\n}\n\nexport class Logger implements Logger {\n private context: any; // Partial context during initialization\n private options: NormalizedOptions;\n private transport: LoggerTransport;\n private readonly startTimes: Record<string, number> = {};\n private readonly lastProgressTimes: Record<string, number> = {};\n\n constructor(context: any, options: LoggerOptions = {}) {\n this.context = context;\n // Set defaults first\n this.options = this.getDefaultOptions();\n // Apply configuration\n if (options) {\n this.configure(options);\n }\n // Initialize transport\n this.updateTransport();\n }\n\n /**\n * Configure logger options. Accepts both LoggerOptions shape and flat param names (levels string, progressWithTimes, progressThrottleMs).\n */\n configure(options: Partial<LoggerOptions> & { progressWithTimes?: boolean; progressThrottleMs?: number; levels?: string | string[] }): void {\n if (options.mode !== undefined) {\n this.options.mode = this.isValidMode(options.mode) ? options.mode : \"text\";\n }\n if (options.route !== undefined) {\n this.options.route = options.route;\n this.updateTransport();\n }\n if (options.prefix !== undefined) this.options.prefix = options.prefix;\n if (options.silent !== undefined) this.options.silent = options.silent;\n if (options.showLevel !== undefined) this.options.showLevel = options.showLevel;\n if (options.timestamp !== undefined) this.options.timestamp = options.timestamp;\n if (options.levels !== undefined) {\n const levels = typeof options.levels === \"string\" ? options.levels.split(\",\") : options.levels;\n this.options.levels = this.normalizeLevels(levels);\n }\n if (options.progress !== undefined) {\n if (options.progress.withTimes !== undefined) this.options.progressTimes = options.progress.withTimes;\n if (options.progress.throttleMs !== undefined) this.options.progressThrottle = options.progress.throttleMs;\n }\n const flat = options as { progressWithTimes?: boolean; progressThrottleMs?: number };\n if (flat.progressWithTimes !== undefined) this.options.progressTimes = flat.progressWithTimes;\n if (flat.progressThrottleMs !== undefined) this.options.progressThrottle = flat.progressThrottleMs;\n }\n\n /**\n * Initialize logger from context and CLI parameters. Whatever is in options goes (after discovered params).\n */\n static init(context: any, options?: LoggerOptions): Logger {\n const paramDefs = {\n mode: \"string default text\",\n route: \"string default console\",\n prefix: \"string\",\n silent: \"boolean default false\",\n showLevel: \"boolean default true\",\n timestamp: \"boolean default false\",\n levels: \"string\",\n progressWithTimes: \"boolean default false\",\n progressThrottleMs: \"number\",\n };\n const discovered = context.params.getAllForModule(paramDefs);\n const config = { ...discovered, ...options } as LoggerOptions & { progressWithTimes?: boolean; progressThrottleMs?: number };\n const logger = new Logger(context, config);\n context.logger = logger;\n return logger;\n }\n\n private getDefaultOptions(): NormalizedOptions {\n return {\n mode: \"text\",\n route: this.shouldUseIpcRoute() ? \"ipc\" : \"console\",\n prefix: undefined,\n silent: false,\n showLevel: false,\n timestamp: false,\n levels: ALL_LEVELS,\n progressTimes: false,\n progressThrottle: undefined,\n };\n }\n\n private updateTransport(): void {\n this.transport = this.options.route === \"ipc\"\n ? new ParentProcessTransport()\n : new ConsoleTransport();\n }\n\n setMode(mode: LoggerMode): void {\n if (!this.isValidMode(mode)) {\n throw new Error(`Unsupported logger mode: ${mode}`);\n }\n this.options.mode = mode;\n }\n\n /** Returns a styled string (bright white) for highlighting; keeps chalk inside logger. */\n highlight(text: string): string {\n return chalk.whiteBright(text);\n }\n\n debug(message?: any, ...chunks: any[]): void {\n this.out({ level: \"debug\", message, chunks });\n }\n\n info(message?: any, ...chunks: any[]): void {\n this.out({ level: \"info\", message, chunks });\n }\n\n notice(message?: any, ...chunks: any[]): void {\n this.out({ level: \"notice\", message, chunks });\n }\n\n warn(message?: any, ...chunks: any[]): void {\n this.out({ level: \"warn\", message, chunks });\n }\n\n error(message?: any, ...chunks: any[]): void {\n this.out({ level: \"error\", message, chunks });\n }\n\n logic(message?: any, ...chunks: any[]): void {\n this.out({ level: \"logic\", message, chunks });\n }\n\n silly(message?: any, ...chunks: any[]): void {\n this.out({ level: \"silly\", message, chunks });\n }\n\n results(results: unknown): void {\n this.out({ level: \"results\", message: \"results\", results });\n }\n\n request(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"request\", message });\n }\n\n response(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"response\", message });\n }\n\n progress(message: string, opts: LoggerProgressOptions): void {\n const { prefix, count, total } = opts;\n const paddedTotal = String(total).length;\n const paddedCount = String(count).padStart(paddedTotal, \" \");\n const payload: LogPayload = {\n level: \"progress\",\n message,\n count: paddedCount,\n total,\n prefix\n };\n\n if (!this.startTimes[prefix ?? \"\"]) {\n this.startTimes[prefix ?? \"\"] = Date.now();\n }\n if (this.options.progressTimes) {\n const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? \"\"]) / 1000;\n let remaining = -1;\n if (count > 1) {\n const rate = elapsedSeconds / (count - 1);\n remaining = (total - count) * rate;\n }\n payload.elapsed = this.round(elapsedSeconds, 2);\n payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;\n }\n\n if (count >= total) {\n delete this.startTimes[prefix ?? \"\"];\n delete this.lastProgressTimes[prefix ?? \"\"];\n }\n\n if (this.shouldOutputProgress(prefix ?? \"\", count, total)) {\n this.out(payload);\n if (this.options.progressThrottle && prefix) {\n this.lastProgressTimes[prefix] = Date.now();\n }\n }\n }\n\n private shouldOutputProgress(prefix: string, count: number, total: number): boolean {\n if (!this.options.progressThrottle) {\n return true;\n }\n if (count === 1 || count === total || !prefix) {\n return true;\n }\n const lastTime = this.lastProgressTimes[prefix];\n if (!lastTime) {\n return true;\n }\n return Date.now() - lastTime >= this.options.progressThrottle;\n }\n\n private out(struct: LogPayload): void {\n if (this.options.silent) {\n return;\n }\n if (!this.options.levels.includes(struct.level)) {\n return;\n }\n\n if (this.options.prefix && !struct.prefix) {\n struct.prefix = this.options.prefix;\n }\n\n const output = this.options.mode === \"json\"\n ? struct\n : this.formatLog(struct);\n\n this.transport.write(output);\n }\n\n private formatLog(struct: LogPayload): string {\n const parts: string[] = [];\n const now = new Date();\n\n if (this.options.timestamp) {\n parts.push(now.toISOString());\n }\n\n if (this.options.showLevel) {\n parts.push(struct.level.toUpperCase().padEnd(MAX_LEVEL_LENGTH));\n }\n\n if (struct.level === \"progress\") {\n if (struct.prefix) {\n parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));\n }\n if (struct.count !== undefined && struct.total !== undefined) {\n parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));\n }\n } else if (struct.prefix) {\n parts.push(chalk.cyan(`[${struct.prefix}]`));\n }\n\n if (struct.message) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter.bold(struct.message));\n }\n\n if (struct.level === \"progress\") {\n if (struct.elapsed !== undefined && struct.remaining !== undefined) {\n const formatter = LEVEL_COLORS[struct.level];\n parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));\n }\n }\n\n if (struct.chunks && struct.chunks.length) {\n parts.push(this.inspectChunks(struct.chunks));\n }\n\n if (struct.results) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter(JSON.stringify(struct.results, null, 4)));\n }\n\n return parts.join(\" \");\n }\n\n private inspectChunks(chunks: any[]): string {\n return chunks\n .map(chunk => util.inspect(chunk, { colors: true, depth: null }))\n .join(\" \");\n }\n\n private shouldUseIpcRoute(): boolean {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n return false;\n }\n // Only use IPC if process.send exists AND we're connected to a parent\n // In Vitest workers, process.send exists but process.connected is undefined/false\n // process.connected is only true in actual child processes created with fork()\n return typeof process.send === \"function\" && process.connected === true;\n }\n\n private normalizeLevels(levels?: string[]): LevelName[] {\n if (!levels || !levels.length) {\n return ALL_LEVELS;\n }\n\n const includes = levels.filter(level => !level.startsWith(\"-\")) as LevelName[];\n const excludes = levels\n .filter(level => level.startsWith(\"-\"))\n .map(level => level.slice(1)) as LevelName[];\n\n const unknown = [...includes, ...excludes].filter(level => !ALL_LEVELS.includes(level));\n if (unknown.length) {\n console.warn(`[Logger] Unknown level(s): ${unknown.join(\", \")}`);\n }\n\n const base = includes.length ? includes : ALL_LEVELS;\n return base.filter(level => !excludes.includes(level));\n }\n\n private isValidMode(mode?: string | null): mode is LoggerMode | undefined {\n return mode === undefined || mode === null || mode === \"text\" || mode === \"json\";\n }\n\n private round(value: number, places: number): number {\n const factor = Math.pow(10, places);\n return Math.round(value * factor) / factor;\n }\n}\n\n","import { LoggerTransport } from \"./types.js\";\n\nexport class ConsoleTransport implements LoggerTransport {\n write(payload: any): void {\n console.info(payload);\n }\n}\n\nexport class ParentProcessTransport implements LoggerTransport {\n write(payload: any): void {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n console.info(payload);\n return;\n }\n // Only use process.send if we're actually connected to a parent process\n // In Vitest workers, process.send exists but shouldn't be used\n if (typeof process.send === \"function\" && process.connected === true) {\n process.send(payload);\n } else {\n console.info(payload);\n }\n }\n}\n\n\n"],"mappings":"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","names":["chalk","util"]}
1
+ {"version":3,"sources":["../src/logger/index.ts","../src/logger/transports.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport util from \"util\";\n\nimport {\n Logger as LoggerInterface,\n LoggerOptions,\n LoggerProgressOptions,\n LogPayload,\n LevelName,\n LoggerTransport,\n LoggerMode\n} from \"./types.js\";\nimport { ConsoleTransport, ParentProcessTransport } from \"./transports.js\";\nimport type { Context } from \"../init/types.js\";\n\nconst ALL_LEVELS: LevelName[] = [\n \"silly\",\n \"debug\",\n \"logic\",\n \"info\",\n \"notice\",\n \"warn\",\n \"error\",\n \"results\",\n \"request\",\n \"response\",\n \"progress\"\n];\nconst DEFAULT_LEVELS: LevelName[] = ALL_LEVELS.filter((l) => l !== \"silly\");\n\n// Calculate maximum level name length for alignment\nconst MAX_LEVEL_LENGTH = Math.max(...ALL_LEVELS.map(level => level.toUpperCase().length));\n\nconst LEVEL_COLORS: Record<LevelName, chalk.Chalk> = {\n error: chalk.red.bold,\n warn: chalk.rgb(255, 165, 0),\n notice: chalk.cyan,\n info: chalk.white.bold,\n logic: chalk.gray,\n debug: chalk.gray,\n silly: chalk.gray,\n request: chalk.green,\n response: chalk.yellow,\n progress: chalk.green,\n results: chalk.magenta\n};\n\ninterface NormalizedOptions {\n mode: LoggerMode;\n route: \"console\" | \"ipc\";\n prefix?: string;\n silent: boolean;\n showLevel: boolean;\n timestamp: boolean;\n levels: LevelName[];\n progressTimes: boolean;\n progressThrottle?: number;\n}\n\nexport class Logger implements LoggerInterface {\n private context: any; // Partial context during initialization\n private options: NormalizedOptions;\n private transport!: LoggerTransport;\n private readonly startTimes: Record<string, number> = {};\n private readonly lastProgressTimes: Record<string, number> = {};\n\n constructor(context: any, options: LoggerOptions = {}) {\n this.context = context;\n // Set defaults first\n this.options = this.getDefaultOptions();\n // Apply configuration\n if (options) {\n this.configure(options);\n }\n // Initialize transport\n this.updateTransport();\n }\n\n /**\n * Configure logger options. Accepts both LoggerOptions shape and flat param names (levels string, progressWithTimes, progressThrottleMs).\n */\n configure(options: Partial<LoggerOptions> & { progressWithTimes?: boolean; progressThrottleMs?: number; levels?: string | string[] }): void {\n if (options.mode !== undefined) {\n this.options.mode = this.isValidMode(options.mode) ? options.mode : \"text\";\n }\n if (options.route !== undefined) {\n this.options.route = options.route;\n this.updateTransport();\n }\n if (options.prefix !== undefined) this.options.prefix = options.prefix;\n if (options.silent !== undefined) this.options.silent = options.silent;\n if (options.showLevel !== undefined) this.options.showLevel = options.showLevel;\n if (options.timestamp !== undefined) this.options.timestamp = options.timestamp;\n if (options.levels !== undefined) {\n const levels = typeof options.levels === \"string\" ? options.levels.split(\",\") : options.levels;\n this.options.levels = this.normalizeLevels(levels);\n }\n if (options.progress !== undefined) {\n if (options.progress.withTimes !== undefined) this.options.progressTimes = options.progress.withTimes;\n if (options.progress.throttleMs !== undefined) this.options.progressThrottle = options.progress.throttleMs;\n }\n const flat = options as { progressWithTimes?: boolean; progressThrottleMs?: number };\n if (flat.progressWithTimes !== undefined) this.options.progressTimes = flat.progressWithTimes;\n if (flat.progressThrottleMs !== undefined) this.options.progressThrottle = flat.progressThrottleMs;\n }\n\n /**\n * Initialize logger from context and CLI parameters. Whatever is in options goes (after discovered params).\n */\n static init(context: any, options?: LoggerOptions): Logger {\n const paramDefs = {\n mode: \"string default text\",\n route: \"string default console\",\n prefix: \"string\",\n silent: \"boolean default false\",\n showLevel: \"boolean default true\",\n timestamp: \"boolean default false\",\n levels: \"string\",\n progressWithTimes: \"boolean default false\",\n progressThrottleMs: \"number\",\n };\n const discovered = context.params.getAllForModule(paramDefs);\n const config = { ...discovered, ...options } as LoggerOptions & { progressWithTimes?: boolean; progressThrottleMs?: number };\n const logger = new Logger(context, config);\n context.logger = logger;\n return logger;\n }\n\n private getDefaultOptions(): NormalizedOptions {\n return {\n mode: \"text\",\n route: this.shouldUseIpcRoute() ? \"ipc\" : \"console\",\n prefix: undefined,\n silent: false,\n showLevel: false,\n timestamp: false,\n levels: DEFAULT_LEVELS,\n progressTimes: false,\n progressThrottle: undefined,\n };\n }\n\n private updateTransport(): void {\n this.transport = this.options.route === \"ipc\"\n ? new ParentProcessTransport()\n : new ConsoleTransport();\n }\n\n setMode(mode: LoggerMode): void {\n if (!this.isValidMode(mode)) {\n throw new Error(`Unsupported logger mode: ${mode}`);\n }\n this.options.mode = mode;\n }\n\n /** Returns a styled string (bright white) for highlighting; keeps chalk inside logger. */\n highlight(text: string): string {\n return chalk.whiteBright(text);\n }\n\n debug(message?: any, ...chunks: any[]): void {\n this.out({ level: \"debug\", message, chunks });\n }\n\n info(message?: any, ...chunks: any[]): void {\n this.out({ level: \"info\", message, chunks });\n }\n\n notice(message?: any, ...chunks: any[]): void {\n this.out({ level: \"notice\", message, chunks });\n }\n\n warn(message?: any, ...chunks: any[]): void {\n this.out({ level: \"warn\", message, chunks });\n }\n\n error(message?: any, ...chunks: any[]): void {\n this.out({ level: \"error\", message, chunks });\n }\n\n logic(message?: any, ...chunks: any[]): void {\n this.out({ level: \"logic\", message, chunks });\n }\n\n silly(message?: any, ...chunks: any[]): void {\n this.out({ level: \"silly\", message, chunks });\n }\n\n results(results: unknown): void {\n this.out({ level: \"results\", message: \"results\", results });\n }\n\n request(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"request\", message });\n }\n\n response(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"response\", message });\n }\n\n progress(message: string, opts: LoggerProgressOptions): void {\n const { prefix, count, total } = opts;\n const paddedTotal = String(total).length;\n const paddedCount = String(count).padStart(paddedTotal, \" \");\n const payload: LogPayload = {\n level: \"progress\",\n message,\n count: paddedCount,\n total,\n prefix\n };\n\n if (!this.startTimes[prefix ?? \"\"]) {\n this.startTimes[prefix ?? \"\"] = Date.now();\n }\n if (this.options.progressTimes) {\n const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? \"\"]) / 1000;\n let remaining = -1;\n if (count > 1) {\n const rate = elapsedSeconds / (count - 1);\n remaining = (total - count) * rate;\n }\n payload.elapsed = this.round(elapsedSeconds, 2);\n payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;\n }\n\n if (count >= total) {\n delete this.startTimes[prefix ?? \"\"];\n delete this.lastProgressTimes[prefix ?? \"\"];\n }\n\n if (this.shouldOutputProgress(prefix ?? \"\", count, total)) {\n this.out(payload);\n if (this.options.progressThrottle && prefix) {\n this.lastProgressTimes[prefix] = Date.now();\n }\n }\n }\n\n private shouldOutputProgress(prefix: string, count: number, total: number): boolean {\n if (!this.options.progressThrottle) {\n return true;\n }\n if (count === 1 || count === total || !prefix) {\n return true;\n }\n const lastTime = this.lastProgressTimes[prefix];\n if (!lastTime) {\n return true;\n }\n return Date.now() - lastTime >= this.options.progressThrottle;\n }\n\n private out(struct: LogPayload): void {\n if (this.options.silent) {\n return;\n }\n if (!this.options.levels.includes(struct.level)) {\n return;\n }\n\n if (this.options.prefix && !struct.prefix) {\n struct.prefix = this.options.prefix;\n }\n\n const output = this.options.mode === \"json\"\n ? struct\n : this.formatLog(struct);\n\n this.transport.write(output);\n }\n\n private formatLog(struct: LogPayload): string {\n const parts: string[] = [];\n const now = new Date();\n\n if (this.options.timestamp) {\n parts.push(now.toISOString());\n }\n\n if (this.options.showLevel) {\n parts.push(struct.level.toUpperCase().padEnd(MAX_LEVEL_LENGTH));\n }\n\n if (struct.level === \"progress\") {\n if (struct.prefix) {\n parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));\n }\n if (struct.count !== undefined && struct.total !== undefined) {\n parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));\n }\n } else if (struct.prefix) {\n parts.push(chalk.cyan(`[${struct.prefix}]`));\n }\n\n if (struct.message) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter.bold(struct.message));\n }\n\n if (struct.level === \"progress\") {\n if (struct.elapsed !== undefined && struct.remaining !== undefined) {\n const formatter = LEVEL_COLORS[struct.level];\n parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));\n }\n }\n\n if (struct.chunks && struct.chunks.length) {\n parts.push(this.inspectChunks(struct.chunks));\n }\n\n if (struct.results) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter(JSON.stringify(struct.results, null, 4)));\n }\n\n return parts.join(\" \");\n }\n\n private inspectChunks(chunks: any[]): string {\n return chunks\n .map(chunk => util.inspect(chunk, { colors: true, depth: null }))\n .join(\" \");\n }\n\n private shouldUseIpcRoute(): boolean {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n return false;\n }\n // Only use IPC if process.send exists AND we're connected to a parent\n // In Vitest workers, process.send exists but process.connected is undefined/false\n // process.connected is only true in actual child processes created with fork()\n return typeof process.send === \"function\" && process.connected === true;\n }\n\n private normalizeLevels(levels?: string[]): LevelName[] {\n if (!levels || !levels.length) {\n return DEFAULT_LEVELS;\n }\n\n const tokens = levels.map((t) => String(t).trim()).filter(Boolean);\n const explicitIncludes = tokens\n .filter((t) => !t.startsWith(\"+\") && !t.startsWith(\"-\"))\n .map((t) => t as LevelName);\n const addIncludes = tokens\n .filter((t) => t.startsWith(\"+\"))\n .map((t) => t.slice(1) as LevelName);\n const excludes = tokens\n .filter((t) => t.startsWith(\"-\"))\n .map((t) => t.slice(1) as LevelName);\n\n const unknown = [...explicitIncludes, ...addIncludes, ...excludes].filter(level => !ALL_LEVELS.includes(level));\n if (unknown.length) {\n console.warn(`[Logger] Unknown level(s): ${unknown.join(\", \")}`);\n }\n\n const base = explicitIncludes.length\n ? explicitIncludes\n : Array.from(new Set<LevelName>([...DEFAULT_LEVELS, ...addIncludes]));\n return base.filter(level => !excludes.includes(level));\n }\n\n private isValidMode(mode?: string | null): mode is LoggerMode | undefined {\n return mode === undefined || mode === null || mode === \"text\" || mode === \"json\";\n }\n\n private round(value: number, places: number): number {\n const factor = Math.pow(10, places);\n return Math.round(value * factor) / factor;\n }\n}\n\n","import { LoggerTransport } from \"./types.js\";\n\nexport class ConsoleTransport implements LoggerTransport {\n write(payload: any): void {\n console.info(payload);\n }\n}\n\nexport class ParentProcessTransport implements LoggerTransport {\n write(payload: any): void {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n console.info(payload);\n return;\n }\n // Only use process.send if we're actually connected to a parent process\n // In Vitest workers, process.send exists but shouldn't be used\n if (typeof process.send === \"function\" && process.connected === true) {\n process.send(payload);\n } else {\n console.info(payload);\n }\n }\n}\n\n\n"],"mappings":"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","names":["chalk","util"]}
package/dist/logger.js CHANGED
@@ -36,6 +36,7 @@ var ALL_LEVELS = [
36
36
  "response",
37
37
  "progress"
38
38
  ];
39
+ var DEFAULT_LEVELS = ALL_LEVELS.filter((l) => l !== "silly");
39
40
  var MAX_LEVEL_LENGTH = Math.max(...ALL_LEVELS.map((level) => level.toUpperCase().length));
40
41
  var LEVEL_COLORS = {
41
42
  error: chalk.red.bold,
@@ -121,7 +122,7 @@ var Logger = class _Logger {
121
122
  silent: false,
122
123
  showLevel: false,
123
124
  timestamp: false,
124
- levels: ALL_LEVELS,
125
+ levels: DEFAULT_LEVELS,
125
126
  progressTimes: false,
126
127
  progressThrottle: void 0
127
128
  };
@@ -281,15 +282,17 @@ var Logger = class _Logger {
281
282
  }
282
283
  normalizeLevels(levels) {
283
284
  if (!levels || !levels.length) {
284
- return ALL_LEVELS;
285
+ return DEFAULT_LEVELS;
285
286
  }
286
- const includes = levels.filter((level) => !level.startsWith("-"));
287
- const excludes = levels.filter((level) => level.startsWith("-")).map((level) => level.slice(1));
288
- const unknown = [...includes, ...excludes].filter((level) => !ALL_LEVELS.includes(level));
287
+ const tokens = levels.map((t) => String(t).trim()).filter(Boolean);
288
+ const explicitIncludes = tokens.filter((t) => !t.startsWith("+") && !t.startsWith("-")).map((t) => t);
289
+ const addIncludes = tokens.filter((t) => t.startsWith("+")).map((t) => t.slice(1));
290
+ const excludes = tokens.filter((t) => t.startsWith("-")).map((t) => t.slice(1));
291
+ const unknown = [...explicitIncludes, ...addIncludes, ...excludes].filter((level) => !ALL_LEVELS.includes(level));
289
292
  if (unknown.length) {
290
293
  console.warn(`[Logger] Unknown level(s): ${unknown.join(", ")}`);
291
294
  }
292
- const base = includes.length ? includes : ALL_LEVELS;
295
+ const base = explicitIncludes.length ? explicitIncludes : Array.from(/* @__PURE__ */ new Set([...DEFAULT_LEVELS, ...addIncludes]));
293
296
  return base.filter((level) => !excludes.includes(level));
294
297
  }
295
298
  isValidMode(mode) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/logger/index.ts","../src/logger/transports.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport util from \"util\";\n\nimport {\n Logger,\n LoggerOptions,\n LoggerProgressOptions,\n LogPayload,\n LevelName,\n LoggerTransport,\n LoggerMode\n} from \"./types.js\";\nimport { ConsoleTransport, ParentProcessTransport } from \"./transports.js\";\nimport type { Context } from \"../init/types.js\";\n\nconst ALL_LEVELS: LevelName[] = [\n \"silly\",\n \"debug\",\n \"logic\",\n \"info\",\n \"notice\",\n \"warn\",\n \"error\",\n \"results\",\n \"request\",\n \"response\",\n \"progress\"\n];\n\n// Calculate maximum level name length for alignment\nconst MAX_LEVEL_LENGTH = Math.max(...ALL_LEVELS.map(level => level.toUpperCase().length));\n\nconst LEVEL_COLORS: Record<LevelName, chalk.Chalk> = {\n error: chalk.red.bold,\n warn: chalk.rgb(255, 165, 0),\n notice: chalk.cyan,\n info: chalk.white.bold,\n logic: chalk.gray,\n debug: chalk.gray,\n silly: chalk.gray,\n request: chalk.green,\n response: chalk.yellow,\n progress: chalk.green,\n results: chalk.magenta\n};\n\ninterface NormalizedOptions {\n mode: LoggerMode;\n route: \"console\" | \"ipc\";\n prefix?: string;\n silent: boolean;\n showLevel: boolean;\n timestamp: boolean;\n levels: LevelName[];\n progressTimes: boolean;\n progressThrottle?: number;\n}\n\nexport class Logger implements Logger {\n private context: any; // Partial context during initialization\n private options: NormalizedOptions;\n private transport: LoggerTransport;\n private readonly startTimes: Record<string, number> = {};\n private readonly lastProgressTimes: Record<string, number> = {};\n\n constructor(context: any, options: LoggerOptions = {}) {\n this.context = context;\n // Set defaults first\n this.options = this.getDefaultOptions();\n // Apply configuration\n if (options) {\n this.configure(options);\n }\n // Initialize transport\n this.updateTransport();\n }\n\n /**\n * Configure logger options. Accepts both LoggerOptions shape and flat param names (levels string, progressWithTimes, progressThrottleMs).\n */\n configure(options: Partial<LoggerOptions> & { progressWithTimes?: boolean; progressThrottleMs?: number; levels?: string | string[] }): void {\n if (options.mode !== undefined) {\n this.options.mode = this.isValidMode(options.mode) ? options.mode : \"text\";\n }\n if (options.route !== undefined) {\n this.options.route = options.route;\n this.updateTransport();\n }\n if (options.prefix !== undefined) this.options.prefix = options.prefix;\n if (options.silent !== undefined) this.options.silent = options.silent;\n if (options.showLevel !== undefined) this.options.showLevel = options.showLevel;\n if (options.timestamp !== undefined) this.options.timestamp = options.timestamp;\n if (options.levels !== undefined) {\n const levels = typeof options.levels === \"string\" ? options.levels.split(\",\") : options.levels;\n this.options.levels = this.normalizeLevels(levels);\n }\n if (options.progress !== undefined) {\n if (options.progress.withTimes !== undefined) this.options.progressTimes = options.progress.withTimes;\n if (options.progress.throttleMs !== undefined) this.options.progressThrottle = options.progress.throttleMs;\n }\n const flat = options as { progressWithTimes?: boolean; progressThrottleMs?: number };\n if (flat.progressWithTimes !== undefined) this.options.progressTimes = flat.progressWithTimes;\n if (flat.progressThrottleMs !== undefined) this.options.progressThrottle = flat.progressThrottleMs;\n }\n\n /**\n * Initialize logger from context and CLI parameters. Whatever is in options goes (after discovered params).\n */\n static init(context: any, options?: LoggerOptions): Logger {\n const paramDefs = {\n mode: \"string default text\",\n route: \"string default console\",\n prefix: \"string\",\n silent: \"boolean default false\",\n showLevel: \"boolean default true\",\n timestamp: \"boolean default false\",\n levels: \"string\",\n progressWithTimes: \"boolean default false\",\n progressThrottleMs: \"number\",\n };\n const discovered = context.params.getAllForModule(paramDefs);\n const config = { ...discovered, ...options } as LoggerOptions & { progressWithTimes?: boolean; progressThrottleMs?: number };\n const logger = new Logger(context, config);\n context.logger = logger;\n return logger;\n }\n\n private getDefaultOptions(): NormalizedOptions {\n return {\n mode: \"text\",\n route: this.shouldUseIpcRoute() ? \"ipc\" : \"console\",\n prefix: undefined,\n silent: false,\n showLevel: false,\n timestamp: false,\n levels: ALL_LEVELS,\n progressTimes: false,\n progressThrottle: undefined,\n };\n }\n\n private updateTransport(): void {\n this.transport = this.options.route === \"ipc\"\n ? new ParentProcessTransport()\n : new ConsoleTransport();\n }\n\n setMode(mode: LoggerMode): void {\n if (!this.isValidMode(mode)) {\n throw new Error(`Unsupported logger mode: ${mode}`);\n }\n this.options.mode = mode;\n }\n\n /** Returns a styled string (bright white) for highlighting; keeps chalk inside logger. */\n highlight(text: string): string {\n return chalk.whiteBright(text);\n }\n\n debug(message?: any, ...chunks: any[]): void {\n this.out({ level: \"debug\", message, chunks });\n }\n\n info(message?: any, ...chunks: any[]): void {\n this.out({ level: \"info\", message, chunks });\n }\n\n notice(message?: any, ...chunks: any[]): void {\n this.out({ level: \"notice\", message, chunks });\n }\n\n warn(message?: any, ...chunks: any[]): void {\n this.out({ level: \"warn\", message, chunks });\n }\n\n error(message?: any, ...chunks: any[]): void {\n this.out({ level: \"error\", message, chunks });\n }\n\n logic(message?: any, ...chunks: any[]): void {\n this.out({ level: \"logic\", message, chunks });\n }\n\n silly(message?: any, ...chunks: any[]): void {\n this.out({ level: \"silly\", message, chunks });\n }\n\n results(results: unknown): void {\n this.out({ level: \"results\", message: \"results\", results });\n }\n\n request(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"request\", message });\n }\n\n response(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"response\", message });\n }\n\n progress(message: string, opts: LoggerProgressOptions): void {\n const { prefix, count, total } = opts;\n const paddedTotal = String(total).length;\n const paddedCount = String(count).padStart(paddedTotal, \" \");\n const payload: LogPayload = {\n level: \"progress\",\n message,\n count: paddedCount,\n total,\n prefix\n };\n\n if (!this.startTimes[prefix ?? \"\"]) {\n this.startTimes[prefix ?? \"\"] = Date.now();\n }\n if (this.options.progressTimes) {\n const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? \"\"]) / 1000;\n let remaining = -1;\n if (count > 1) {\n const rate = elapsedSeconds / (count - 1);\n remaining = (total - count) * rate;\n }\n payload.elapsed = this.round(elapsedSeconds, 2);\n payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;\n }\n\n if (count >= total) {\n delete this.startTimes[prefix ?? \"\"];\n delete this.lastProgressTimes[prefix ?? \"\"];\n }\n\n if (this.shouldOutputProgress(prefix ?? \"\", count, total)) {\n this.out(payload);\n if (this.options.progressThrottle && prefix) {\n this.lastProgressTimes[prefix] = Date.now();\n }\n }\n }\n\n private shouldOutputProgress(prefix: string, count: number, total: number): boolean {\n if (!this.options.progressThrottle) {\n return true;\n }\n if (count === 1 || count === total || !prefix) {\n return true;\n }\n const lastTime = this.lastProgressTimes[prefix];\n if (!lastTime) {\n return true;\n }\n return Date.now() - lastTime >= this.options.progressThrottle;\n }\n\n private out(struct: LogPayload): void {\n if (this.options.silent) {\n return;\n }\n if (!this.options.levels.includes(struct.level)) {\n return;\n }\n\n if (this.options.prefix && !struct.prefix) {\n struct.prefix = this.options.prefix;\n }\n\n const output = this.options.mode === \"json\"\n ? struct\n : this.formatLog(struct);\n\n this.transport.write(output);\n }\n\n private formatLog(struct: LogPayload): string {\n const parts: string[] = [];\n const now = new Date();\n\n if (this.options.timestamp) {\n parts.push(now.toISOString());\n }\n\n if (this.options.showLevel) {\n parts.push(struct.level.toUpperCase().padEnd(MAX_LEVEL_LENGTH));\n }\n\n if (struct.level === \"progress\") {\n if (struct.prefix) {\n parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));\n }\n if (struct.count !== undefined && struct.total !== undefined) {\n parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));\n }\n } else if (struct.prefix) {\n parts.push(chalk.cyan(`[${struct.prefix}]`));\n }\n\n if (struct.message) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter.bold(struct.message));\n }\n\n if (struct.level === \"progress\") {\n if (struct.elapsed !== undefined && struct.remaining !== undefined) {\n const formatter = LEVEL_COLORS[struct.level];\n parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));\n }\n }\n\n if (struct.chunks && struct.chunks.length) {\n parts.push(this.inspectChunks(struct.chunks));\n }\n\n if (struct.results) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter(JSON.stringify(struct.results, null, 4)));\n }\n\n return parts.join(\" \");\n }\n\n private inspectChunks(chunks: any[]): string {\n return chunks\n .map(chunk => util.inspect(chunk, { colors: true, depth: null }))\n .join(\" \");\n }\n\n private shouldUseIpcRoute(): boolean {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n return false;\n }\n // Only use IPC if process.send exists AND we're connected to a parent\n // In Vitest workers, process.send exists but process.connected is undefined/false\n // process.connected is only true in actual child processes created with fork()\n return typeof process.send === \"function\" && process.connected === true;\n }\n\n private normalizeLevels(levels?: string[]): LevelName[] {\n if (!levels || !levels.length) {\n return ALL_LEVELS;\n }\n\n const includes = levels.filter(level => !level.startsWith(\"-\")) as LevelName[];\n const excludes = levels\n .filter(level => level.startsWith(\"-\"))\n .map(level => level.slice(1)) as LevelName[];\n\n const unknown = [...includes, ...excludes].filter(level => !ALL_LEVELS.includes(level));\n if (unknown.length) {\n console.warn(`[Logger] Unknown level(s): ${unknown.join(\", \")}`);\n }\n\n const base = includes.length ? includes : ALL_LEVELS;\n return base.filter(level => !excludes.includes(level));\n }\n\n private isValidMode(mode?: string | null): mode is LoggerMode | undefined {\n return mode === undefined || mode === null || mode === \"text\" || mode === \"json\";\n }\n\n private round(value: number, places: number): number {\n const factor = Math.pow(10, places);\n return Math.round(value * factor) / factor;\n }\n}\n\n","import { LoggerTransport } from \"./types.js\";\n\nexport class ConsoleTransport implements LoggerTransport {\n write(payload: any): void {\n console.info(payload);\n }\n}\n\nexport class ParentProcessTransport implements LoggerTransport {\n write(payload: any): void {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n console.info(payload);\n return;\n }\n // Only use process.send if we're actually connected to a parent process\n // In Vitest workers, process.send exists but shouldn't be used\n if (typeof process.send === \"function\" && process.connected === true) {\n process.send(payload);\n } else {\n console.info(payload);\n }\n }\n}\n\n\n"],"mappings":";AAAA,OAAO,WAAW;AAClB,OAAO,UAAU;;;ACCV,IAAM,mBAAN,MAAkD;AAAA,EACrD,MAAM,SAAoB;AACtB,YAAQ,KAAK,OAAO;AAAA,EACxB;AACJ;AAEO,IAAM,yBAAN,MAAwD;AAAA,EAC3D,MAAM,SAAoB;AAEtB,QAAI,QAAQ,IAAI,UAAU,QAAQ,IAAI,aAAa,QAAQ;AACvD,cAAQ,KAAK,OAAO;AACpB;AAAA,IACJ;AAGA,QAAI,OAAO,QAAQ,SAAS,cAAc,QAAQ,cAAc,MAAM;AAClE,cAAQ,KAAK,OAAO;AAAA,IACxB,OAAO;AACH,cAAQ,KAAK,OAAO;AAAA,IACxB;AAAA,EACJ;AACJ;;;ADRA,IAAM,aAA0B;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACJ;AAGA,IAAM,mBAAmB,KAAK,IAAI,GAAG,WAAW,IAAI,WAAS,MAAM,YAAY,EAAE,MAAM,CAAC;AAExF,IAAM,eAA+C;AAAA,EACjD,OAAO,MAAM,IAAI;AAAA,EACjB,MAAM,MAAM,IAAI,KAAK,KAAK,CAAC;AAAA,EAC3B,QAAQ,MAAM;AAAA,EACd,MAAM,MAAM,MAAM;AAAA,EAClB,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AAAA,EACb,OAAO,MAAM;AAAA,EACb,SAAS,MAAM;AAAA,EACf,UAAU,MAAM;AAAA,EAChB,UAAU,MAAM;AAAA,EAChB,SAAS,MAAM;AACnB;AAcO,IAAM,SAAN,MAAM,QAAyB;AAAA,EAC1B;AAAA;AAAA,EACA;AAAA,EACA;AAAA,EACS,aAAqC,CAAC;AAAA,EACtC,oBAA4C,CAAC;AAAA,EAE9D,YAAY,SAAc,UAAyB,CAAC,GAAG;AACnD,SAAK,UAAU;AAEf,SAAK,UAAU,KAAK,kBAAkB;AAEtC,QAAI,SAAS;AACT,WAAK,UAAU,OAAO;AAAA,IAC1B;AAEA,SAAK,gBAAgB;AAAA,EACzB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,SAAkI;AACxI,QAAI,QAAQ,SAAS,QAAW;AAC5B,WAAK,QAAQ,OAAO,KAAK,YAAY,QAAQ,IAAI,IAAI,QAAQ,OAAO;AAAA,IACxE;AACA,QAAI,QAAQ,UAAU,QAAW;AAC7B,WAAK,QAAQ,QAAQ,QAAQ;AAC7B,WAAK,gBAAgB;AAAA,IACzB;AACA,QAAI,QAAQ,WAAW,OAAW,MAAK,QAAQ,SAAS,QAAQ;AAChE,QAAI,QAAQ,WAAW,OAAW,MAAK,QAAQ,SAAS,QAAQ;AAChE,QAAI,QAAQ,cAAc,OAAW,MAAK,QAAQ,YAAY,QAAQ;AACtE,QAAI,QAAQ,cAAc,OAAW,MAAK,QAAQ,YAAY,QAAQ;AACtE,QAAI,QAAQ,WAAW,QAAW;AAC9B,YAAM,SAAS,OAAO,QAAQ,WAAW,WAAW,QAAQ,OAAO,MAAM,GAAG,IAAI,QAAQ;AACxF,WAAK,QAAQ,SAAS,KAAK,gBAAgB,MAAM;AAAA,IACrD;AACA,QAAI,QAAQ,aAAa,QAAW;AAChC,UAAI,QAAQ,SAAS,cAAc,OAAW,MAAK,QAAQ,gBAAgB,QAAQ,SAAS;AAC5F,UAAI,QAAQ,SAAS,eAAe,OAAW,MAAK,QAAQ,mBAAmB,QAAQ,SAAS;AAAA,IACpG;AACA,UAAM,OAAO;AACb,QAAI,KAAK,sBAAsB,OAAW,MAAK,QAAQ,gBAAgB,KAAK;AAC5E,QAAI,KAAK,uBAAuB,OAAW,MAAK,QAAQ,mBAAmB,KAAK;AAAA,EACpF;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,KAAK,SAAc,SAAiC;AACvD,UAAM,YAAY;AAAA,MACd,MAAM;AAAA,MACN,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,mBAAmB;AAAA,MACnB,oBAAoB;AAAA,IACxB;AACA,UAAM,aAAa,QAAQ,OAAO,gBAAgB,SAAS;AAC3D,UAAM,SAAS,EAAE,GAAG,YAAY,GAAG,QAAQ;AAC3C,UAAM,SAAS,IAAI,QAAO,SAAS,MAAM;AACzC,YAAQ,SAAS;AACjB,WAAO;AAAA,EACX;AAAA,EAEQ,oBAAuC;AAC3C,WAAO;AAAA,MACH,MAAM;AAAA,MACN,OAAO,KAAK,kBAAkB,IAAI,QAAQ;AAAA,MAC1C,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,eAAe;AAAA,MACf,kBAAkB;AAAA,IACtB;AAAA,EACJ;AAAA,EAEQ,kBAAwB;AAC5B,SAAK,YAAY,KAAK,QAAQ,UAAU,QAClC,IAAI,uBAAuB,IAC3B,IAAI,iBAAiB;AAAA,EAC/B;AAAA,EAEA,QAAQ,MAAwB;AAC5B,QAAI,CAAC,KAAK,YAAY,IAAI,GAAG;AACzB,YAAM,IAAI,MAAM,4BAA4B,IAAI,EAAE;AAAA,IACtD;AACA,SAAK,QAAQ,OAAO;AAAA,EACxB;AAAA;AAAA,EAGA,UAAU,MAAsB;AAC5B,WAAO,MAAM,YAAY,IAAI;AAAA,EACjC;AAAA,EAEA,MAAM,YAAkB,QAAqB;AACzC,SAAK,IAAI,EAAE,OAAO,SAAS,SAAS,OAAO,CAAC;AAAA,EAChD;AAAA,EAEA,KAAK,YAAkB,QAAqB;AACxC,SAAK,IAAI,EAAE,OAAO,QAAQ,SAAS,OAAO,CAAC;AAAA,EAC/C;AAAA,EAEA,OAAO,YAAkB,QAAqB;AAC1C,SAAK,IAAI,EAAE,OAAO,UAAU,SAAS,OAAO,CAAC;AAAA,EACjD;AAAA,EAEA,KAAK,YAAkB,QAAqB;AACxC,SAAK,IAAI,EAAE,OAAO,QAAQ,SAAS,OAAO,CAAC;AAAA,EAC/C;AAAA,EAEA,MAAM,YAAkB,QAAqB;AACzC,SAAK,IAAI,EAAE,OAAO,SAAS,SAAS,OAAO,CAAC;AAAA,EAChD;AAAA,EAEA,MAAM,YAAkB,QAAqB;AACzC,SAAK,IAAI,EAAE,OAAO,SAAS,SAAS,OAAO,CAAC;AAAA,EAChD;AAAA,EAEA,MAAM,YAAkB,QAAqB;AACzC,SAAK,IAAI,EAAE,OAAO,SAAS,SAAS,OAAO,CAAC;AAAA,EAChD;AAAA,EAEA,QAAQ,SAAwB;AAC5B,SAAK,IAAI,EAAE,OAAO,WAAW,SAAS,WAAW,QAAQ,CAAC;AAAA,EAC9D;AAAA,EAEA,QAAQ,cAAsB,QAAqB;AAC/C,UAAM,UAAU,KAAK,cAAc,CAAC,WAAW,GAAG,MAAM,CAAC;AACzD,SAAK,IAAI,EAAE,OAAO,WAAW,QAAQ,CAAC;AAAA,EAC1C;AAAA,EAEA,SAAS,cAAsB,QAAqB;AAChD,UAAM,UAAU,KAAK,cAAc,CAAC,WAAW,GAAG,MAAM,CAAC;AACzD,SAAK,IAAI,EAAE,OAAO,YAAY,QAAQ,CAAC;AAAA,EAC3C;AAAA,EAEA,SAAS,SAAiB,MAAmC;AACzD,UAAM,EAAE,QAAQ,OAAO,MAAM,IAAI;AACjC,UAAM,cAAc,OAAO,KAAK,EAAE;AAClC,UAAM,cAAc,OAAO,KAAK,EAAE,SAAS,aAAa,GAAG;AAC3D,UAAM,UAAsB;AAAA,MACxB,OAAO;AAAA,MACP;AAAA,MACA,OAAO;AAAA,MACP;AAAA,MACA;AAAA,IACJ;AAEA,QAAI,CAAC,KAAK,WAAW,UAAU,EAAE,GAAG;AAChC,WAAK,WAAW,UAAU,EAAE,IAAI,KAAK,IAAI;AAAA,IAC7C;AACA,QAAI,KAAK,QAAQ,eAAe;AAC5B,YAAM,kBAAkB,KAAK,IAAI,IAAI,KAAK,WAAW,UAAU,EAAE,KAAK;AACtE,UAAI,YAAY;AAChB,UAAI,QAAQ,GAAG;AACX,cAAM,OAAO,kBAAkB,QAAQ;AACvC,qBAAa,QAAQ,SAAS;AAAA,MAClC;AACA,cAAQ,UAAU,KAAK,MAAM,gBAAgB,CAAC;AAC9C,cAAQ,YAAY,aAAa,IAAI,KAAK,MAAM,WAAW,CAAC,IAAI;AAAA,IACpE;AAEA,QAAI,SAAS,OAAO;AAChB,aAAO,KAAK,WAAW,UAAU,EAAE;AACnC,aAAO,KAAK,kBAAkB,UAAU,EAAE;AAAA,IAC9C;AAEA,QAAI,KAAK,qBAAqB,UAAU,IAAI,OAAO,KAAK,GAAG;AACvD,WAAK,IAAI,OAAO;AAChB,UAAI,KAAK,QAAQ,oBAAoB,QAAQ;AACzC,aAAK,kBAAkB,MAAM,IAAI,KAAK,IAAI;AAAA,MAC9C;AAAA,IACJ;AAAA,EACJ;AAAA,EAEQ,qBAAqB,QAAgB,OAAe,OAAwB;AAChF,QAAI,CAAC,KAAK,QAAQ,kBAAkB;AAChC,aAAO;AAAA,IACX;AACA,QAAI,UAAU,KAAK,UAAU,SAAS,CAAC,QAAQ;AAC3C,aAAO;AAAA,IACX;AACA,UAAM,WAAW,KAAK,kBAAkB,MAAM;AAC9C,QAAI,CAAC,UAAU;AACX,aAAO;AAAA,IACX;AACA,WAAO,KAAK,IAAI,IAAI,YAAY,KAAK,QAAQ;AAAA,EACjD;AAAA,EAEQ,IAAI,QAA0B;AAClC,QAAI,KAAK,QAAQ,QAAQ;AACrB;AAAA,IACJ;AACA,QAAI,CAAC,KAAK,QAAQ,OAAO,SAAS,OAAO,KAAK,GAAG;AAC7C;AAAA,IACJ;AAEA,QAAI,KAAK,QAAQ,UAAU,CAAC,OAAO,QAAQ;AACvC,aAAO,SAAS,KAAK,QAAQ;AAAA,IACjC;AAEA,UAAM,SAAS,KAAK,QAAQ,SAAS,SAC/B,SACA,KAAK,UAAU,MAAM;AAE3B,SAAK,UAAU,MAAM,MAAM;AAAA,EAC/B;AAAA,EAEQ,UAAU,QAA4B;AAC1C,UAAM,QAAkB,CAAC;AACzB,UAAM,MAAM,oBAAI,KAAK;AAErB,QAAI,KAAK,QAAQ,WAAW;AACxB,YAAM,KAAK,IAAI,YAAY,CAAC;AAAA,IAChC;AAEA,QAAI,KAAK,QAAQ,WAAW;AACxB,YAAM,KAAK,OAAO,MAAM,YAAY,EAAE,OAAO,gBAAgB,CAAC;AAAA,IAClE;AAEA,QAAI,OAAO,UAAU,YAAY;AAC7B,UAAI,OAAO,QAAQ;AACf,cAAM,KAAK,aAAa,OAAO,KAAK,EAAE,KAAK,OAAO,MAAM,CAAC;AAAA,MAC7D;AACA,UAAI,OAAO,UAAU,UAAa,OAAO,UAAU,QAAW;AAC1D,cAAM,KAAK,aAAa,OAAO,KAAK,EAAE,GAAG,OAAO,KAAK,IAAI,OAAO,KAAK,EAAE,CAAC;AAAA,MAC5E;AAAA,IACJ,WAAW,OAAO,QAAQ;AACtB,YAAM,KAAK,MAAM,KAAK,IAAI,OAAO,MAAM,GAAG,CAAC;AAAA,IAC/C;AAEA,QAAI,OAAO,SAAS;AAChB,YAAM,YAAY,aAAa,OAAO,KAAK,KAAK,MAAM;AACtD,YAAM,KAAK,UAAU,KAAK,OAAO,OAAO,CAAC;AAAA,IAC7C;AAEA,QAAI,OAAO,UAAU,YAAY;AAC7B,UAAI,OAAO,YAAY,UAAa,OAAO,cAAc,QAAW;AAChE,cAAM,YAAY,aAAa,OAAO,KAAK;AAC3C,cAAM,KAAK,UAAU,GAAG,OAAO,OAAO,IAAI,OAAO,SAAS,EAAE,CAAC;AAAA,MACjE;AAAA,IACJ;AAEA,QAAI,OAAO,UAAU,OAAO,OAAO,QAAQ;AACvC,YAAM,KAAK,KAAK,cAAc,OAAO,MAAM,CAAC;AAAA,IAChD;AAEA,QAAI,OAAO,SAAS;AAChB,YAAM,YAAY,aAAa,OAAO,KAAK,KAAK,MAAM;AACtD,YAAM,KAAK,UAAU,KAAK,UAAU,OAAO,SAAS,MAAM,CAAC,CAAC,CAAC;AAAA,IACjE;AAEA,WAAO,MAAM,KAAK,GAAG;AAAA,EACzB;AAAA,EAEQ,cAAc,QAAuB;AACzC,WAAO,OACF,IAAI,WAAS,KAAK,QAAQ,OAAO,EAAE,QAAQ,MAAM,OAAO,KAAK,CAAC,CAAC,EAC/D,KAAK,GAAG;AAAA,EACjB;AAAA,EAEQ,oBAA6B;AAEjC,QAAI,QAAQ,IAAI,UAAU,QAAQ,IAAI,aAAa,QAAQ;AACvD,aAAO;AAAA,IACX;AAIA,WAAO,OAAO,QAAQ,SAAS,cAAc,QAAQ,cAAc;AAAA,EACvE;AAAA,EAEQ,gBAAgB,QAAgC;AACpD,QAAI,CAAC,UAAU,CAAC,OAAO,QAAQ;AAC3B,aAAO;AAAA,IACX;AAEA,UAAM,WAAW,OAAO,OAAO,WAAS,CAAC,MAAM,WAAW,GAAG,CAAC;AAC9D,UAAM,WAAW,OACZ,OAAO,WAAS,MAAM,WAAW,GAAG,CAAC,EACrC,IAAI,WAAS,MAAM,MAAM,CAAC,CAAC;AAEhC,UAAM,UAAU,CAAC,GAAG,UAAU,GAAG,QAAQ,EAAE,OAAO,WAAS,CAAC,WAAW,SAAS,KAAK,CAAC;AACtF,QAAI,QAAQ,QAAQ;AAChB,cAAQ,KAAK,8BAA8B,QAAQ,KAAK,IAAI,CAAC,EAAE;AAAA,IACnE;AAEA,UAAM,OAAO,SAAS,SAAS,WAAW;AAC1C,WAAO,KAAK,OAAO,WAAS,CAAC,SAAS,SAAS,KAAK,CAAC;AAAA,EACzD;AAAA,EAEQ,YAAY,MAAsD;AACtE,WAAO,SAAS,UAAa,SAAS,QAAQ,SAAS,UAAU,SAAS;AAAA,EAC9E;AAAA,EAEQ,MAAM,OAAe,QAAwB;AACjD,UAAM,SAAS,KAAK,IAAI,IAAI,MAAM;AAClC,WAAO,KAAK,MAAM,QAAQ,MAAM,IAAI;AAAA,EACxC;AACJ;","names":[]}
1
+ {"version":3,"sources":["../src/logger/index.ts","../src/logger/transports.ts"],"sourcesContent":["import chalk from \"chalk\";\nimport util from \"util\";\n\nimport {\n Logger as LoggerInterface,\n LoggerOptions,\n LoggerProgressOptions,\n LogPayload,\n LevelName,\n LoggerTransport,\n LoggerMode\n} from \"./types.js\";\nimport { ConsoleTransport, ParentProcessTransport } from \"./transports.js\";\nimport type { Context } from \"../init/types.js\";\n\nconst ALL_LEVELS: LevelName[] = [\n \"silly\",\n \"debug\",\n \"logic\",\n \"info\",\n \"notice\",\n \"warn\",\n \"error\",\n \"results\",\n \"request\",\n \"response\",\n \"progress\"\n];\nconst DEFAULT_LEVELS: LevelName[] = ALL_LEVELS.filter((l) => l !== \"silly\");\n\n// Calculate maximum level name length for alignment\nconst MAX_LEVEL_LENGTH = Math.max(...ALL_LEVELS.map(level => level.toUpperCase().length));\n\nconst LEVEL_COLORS: Record<LevelName, chalk.Chalk> = {\n error: chalk.red.bold,\n warn: chalk.rgb(255, 165, 0),\n notice: chalk.cyan,\n info: chalk.white.bold,\n logic: chalk.gray,\n debug: chalk.gray,\n silly: chalk.gray,\n request: chalk.green,\n response: chalk.yellow,\n progress: chalk.green,\n results: chalk.magenta\n};\n\ninterface NormalizedOptions {\n mode: LoggerMode;\n route: \"console\" | \"ipc\";\n prefix?: string;\n silent: boolean;\n showLevel: boolean;\n timestamp: boolean;\n levels: LevelName[];\n progressTimes: boolean;\n progressThrottle?: number;\n}\n\nexport class Logger implements LoggerInterface {\n private context: any; // Partial context during initialization\n private options: NormalizedOptions;\n private transport!: LoggerTransport;\n private readonly startTimes: Record<string, number> = {};\n private readonly lastProgressTimes: Record<string, number> = {};\n\n constructor(context: any, options: LoggerOptions = {}) {\n this.context = context;\n // Set defaults first\n this.options = this.getDefaultOptions();\n // Apply configuration\n if (options) {\n this.configure(options);\n }\n // Initialize transport\n this.updateTransport();\n }\n\n /**\n * Configure logger options. Accepts both LoggerOptions shape and flat param names (levels string, progressWithTimes, progressThrottleMs).\n */\n configure(options: Partial<LoggerOptions> & { progressWithTimes?: boolean; progressThrottleMs?: number; levels?: string | string[] }): void {\n if (options.mode !== undefined) {\n this.options.mode = this.isValidMode(options.mode) ? options.mode : \"text\";\n }\n if (options.route !== undefined) {\n this.options.route = options.route;\n this.updateTransport();\n }\n if (options.prefix !== undefined) this.options.prefix = options.prefix;\n if (options.silent !== undefined) this.options.silent = options.silent;\n if (options.showLevel !== undefined) this.options.showLevel = options.showLevel;\n if (options.timestamp !== undefined) this.options.timestamp = options.timestamp;\n if (options.levels !== undefined) {\n const levels = typeof options.levels === \"string\" ? options.levels.split(\",\") : options.levels;\n this.options.levels = this.normalizeLevels(levels);\n }\n if (options.progress !== undefined) {\n if (options.progress.withTimes !== undefined) this.options.progressTimes = options.progress.withTimes;\n if (options.progress.throttleMs !== undefined) this.options.progressThrottle = options.progress.throttleMs;\n }\n const flat = options as { progressWithTimes?: boolean; progressThrottleMs?: number };\n if (flat.progressWithTimes !== undefined) this.options.progressTimes = flat.progressWithTimes;\n if (flat.progressThrottleMs !== undefined) this.options.progressThrottle = flat.progressThrottleMs;\n }\n\n /**\n * Initialize logger from context and CLI parameters. Whatever is in options goes (after discovered params).\n */\n static init(context: any, options?: LoggerOptions): Logger {\n const paramDefs = {\n mode: \"string default text\",\n route: \"string default console\",\n prefix: \"string\",\n silent: \"boolean default false\",\n showLevel: \"boolean default true\",\n timestamp: \"boolean default false\",\n levels: \"string\",\n progressWithTimes: \"boolean default false\",\n progressThrottleMs: \"number\",\n };\n const discovered = context.params.getAllForModule(paramDefs);\n const config = { ...discovered, ...options } as LoggerOptions & { progressWithTimes?: boolean; progressThrottleMs?: number };\n const logger = new Logger(context, config);\n context.logger = logger;\n return logger;\n }\n\n private getDefaultOptions(): NormalizedOptions {\n return {\n mode: \"text\",\n route: this.shouldUseIpcRoute() ? \"ipc\" : \"console\",\n prefix: undefined,\n silent: false,\n showLevel: false,\n timestamp: false,\n levels: DEFAULT_LEVELS,\n progressTimes: false,\n progressThrottle: undefined,\n };\n }\n\n private updateTransport(): void {\n this.transport = this.options.route === \"ipc\"\n ? new ParentProcessTransport()\n : new ConsoleTransport();\n }\n\n setMode(mode: LoggerMode): void {\n if (!this.isValidMode(mode)) {\n throw new Error(`Unsupported logger mode: ${mode}`);\n }\n this.options.mode = mode;\n }\n\n /** Returns a styled string (bright white) for highlighting; keeps chalk inside logger. */\n highlight(text: string): string {\n return chalk.whiteBright(text);\n }\n\n debug(message?: any, ...chunks: any[]): void {\n this.out({ level: \"debug\", message, chunks });\n }\n\n info(message?: any, ...chunks: any[]): void {\n this.out({ level: \"info\", message, chunks });\n }\n\n notice(message?: any, ...chunks: any[]): void {\n this.out({ level: \"notice\", message, chunks });\n }\n\n warn(message?: any, ...chunks: any[]): void {\n this.out({ level: \"warn\", message, chunks });\n }\n\n error(message?: any, ...chunks: any[]): void {\n this.out({ level: \"error\", message, chunks });\n }\n\n logic(message?: any, ...chunks: any[]): void {\n this.out({ level: \"logic\", message, chunks });\n }\n\n silly(message?: any, ...chunks: any[]): void {\n this.out({ level: \"silly\", message, chunks });\n }\n\n results(results: unknown): void {\n this.out({ level: \"results\", message: \"results\", results });\n }\n\n request(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"request\", message });\n }\n\n response(operation: string, ...chunks: any[]): void {\n const message = this.inspectChunks([operation, ...chunks]);\n this.out({ level: \"response\", message });\n }\n\n progress(message: string, opts: LoggerProgressOptions): void {\n const { prefix, count, total } = opts;\n const paddedTotal = String(total).length;\n const paddedCount = String(count).padStart(paddedTotal, \" \");\n const payload: LogPayload = {\n level: \"progress\",\n message,\n count: paddedCount,\n total,\n prefix\n };\n\n if (!this.startTimes[prefix ?? \"\"]) {\n this.startTimes[prefix ?? \"\"] = Date.now();\n }\n if (this.options.progressTimes) {\n const elapsedSeconds = (Date.now() - this.startTimes[prefix ?? \"\"]) / 1000;\n let remaining = -1;\n if (count > 1) {\n const rate = elapsedSeconds / (count - 1);\n remaining = (total - count) * rate;\n }\n payload.elapsed = this.round(elapsedSeconds, 2);\n payload.remaining = remaining >= 0 ? this.round(remaining, 2) : remaining;\n }\n\n if (count >= total) {\n delete this.startTimes[prefix ?? \"\"];\n delete this.lastProgressTimes[prefix ?? \"\"];\n }\n\n if (this.shouldOutputProgress(prefix ?? \"\", count, total)) {\n this.out(payload);\n if (this.options.progressThrottle && prefix) {\n this.lastProgressTimes[prefix] = Date.now();\n }\n }\n }\n\n private shouldOutputProgress(prefix: string, count: number, total: number): boolean {\n if (!this.options.progressThrottle) {\n return true;\n }\n if (count === 1 || count === total || !prefix) {\n return true;\n }\n const lastTime = this.lastProgressTimes[prefix];\n if (!lastTime) {\n return true;\n }\n return Date.now() - lastTime >= this.options.progressThrottle;\n }\n\n private out(struct: LogPayload): void {\n if (this.options.silent) {\n return;\n }\n if (!this.options.levels.includes(struct.level)) {\n return;\n }\n\n if (this.options.prefix && !struct.prefix) {\n struct.prefix = this.options.prefix;\n }\n\n const output = this.options.mode === \"json\"\n ? struct\n : this.formatLog(struct);\n\n this.transport.write(output);\n }\n\n private formatLog(struct: LogPayload): string {\n const parts: string[] = [];\n const now = new Date();\n\n if (this.options.timestamp) {\n parts.push(now.toISOString());\n }\n\n if (this.options.showLevel) {\n parts.push(struct.level.toUpperCase().padEnd(MAX_LEVEL_LENGTH));\n }\n\n if (struct.level === \"progress\") {\n if (struct.prefix) {\n parts.push(LEVEL_COLORS[struct.level].bold(struct.prefix));\n }\n if (struct.count !== undefined && struct.total !== undefined) {\n parts.push(LEVEL_COLORS[struct.level](`${struct.count}/${struct.total}`));\n }\n } else if (struct.prefix) {\n parts.push(chalk.cyan(`[${struct.prefix}]`));\n }\n\n if (struct.message) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter.bold(struct.message));\n }\n\n if (struct.level === \"progress\") {\n if (struct.elapsed !== undefined && struct.remaining !== undefined) {\n const formatter = LEVEL_COLORS[struct.level];\n parts.push(formatter(`${struct.elapsed}/${struct.remaining}`));\n }\n }\n\n if (struct.chunks && struct.chunks.length) {\n parts.push(this.inspectChunks(struct.chunks));\n }\n\n if (struct.results) {\n const formatter = LEVEL_COLORS[struct.level] ?? chalk.white;\n parts.push(formatter(JSON.stringify(struct.results, null, 4)));\n }\n\n return parts.join(\" \");\n }\n\n private inspectChunks(chunks: any[]): string {\n return chunks\n .map(chunk => util.inspect(chunk, { colors: true, depth: null }))\n .join(\" \");\n }\n\n private shouldUseIpcRoute(): boolean {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n return false;\n }\n // Only use IPC if process.send exists AND we're connected to a parent\n // In Vitest workers, process.send exists but process.connected is undefined/false\n // process.connected is only true in actual child processes created with fork()\n return typeof process.send === \"function\" && process.connected === true;\n }\n\n private normalizeLevels(levels?: string[]): LevelName[] {\n if (!levels || !levels.length) {\n return DEFAULT_LEVELS;\n }\n\n const tokens = levels.map((t) => String(t).trim()).filter(Boolean);\n const explicitIncludes = tokens\n .filter((t) => !t.startsWith(\"+\") && !t.startsWith(\"-\"))\n .map((t) => t as LevelName);\n const addIncludes = tokens\n .filter((t) => t.startsWith(\"+\"))\n .map((t) => t.slice(1) as LevelName);\n const excludes = tokens\n .filter((t) => t.startsWith(\"-\"))\n .map((t) => t.slice(1) as LevelName);\n\n const unknown = [...explicitIncludes, ...addIncludes, ...excludes].filter(level => !ALL_LEVELS.includes(level));\n if (unknown.length) {\n console.warn(`[Logger] Unknown level(s): ${unknown.join(\", \")}`);\n }\n\n const base = explicitIncludes.length\n ? explicitIncludes\n : Array.from(new Set<LevelName>([...DEFAULT_LEVELS, ...addIncludes]));\n return base.filter(level => !excludes.includes(level));\n }\n\n private isValidMode(mode?: string | null): mode is LoggerMode | undefined {\n return mode === undefined || mode === null || mode === \"text\" || mode === \"json\";\n }\n\n private round(value: number, places: number): number {\n const factor = Math.pow(10, places);\n return Math.round(value * factor) / factor;\n }\n}\n\n","import { LoggerTransport } from \"./types.js\";\n\nexport class ConsoleTransport implements LoggerTransport {\n write(payload: any): void {\n console.info(payload);\n }\n}\n\nexport class ParentProcessTransport implements LoggerTransport {\n write(payload: any): void {\n // Don't use IPC in test environments (Vitest workers interfere with process.send)\n if (process.env.VITEST || process.env.NODE_ENV === \"test\") {\n console.info(payload);\n return;\n }\n // Only use process.send if we're actually connected to a parent process\n // In Vitest workers, process.send exists but shouldn't be used\n if (typeof process.send === \"function\" && process.connected === true) {\n process.send(payload);\n } else {\n console.info(payload);\n }\n }\n}\n\n\n"],"mappings":"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","names":[]}