tim-logger 0.0.34 → 0.0.35
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/server.cjs.js +3 -3
- package/dist/server.cjs.js.map +1 -1
- package/dist/server.d.ts.map +1 -1
- package/dist/server.es.js +45 -53
- package/dist/server.es.js.map +1 -1
- package/package.json +1 -1
package/dist/server.cjs.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("kleur"),C=require("node:fs/promises"),D=require("node:path"),O=require("node:util"),l=require("winston"),k=require("winston-transport"),_=require("./console-intercept-CL_BfKQo.cjs");function
|
|
2
|
-
`,"utf8")})().catch(n=>{const s=n instanceof Error?n.message:
|
|
3
|
-
${a}`:u})),
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("kleur"),C=require("node:fs/promises"),D=require("node:path"),O=require("node:util"),l=require("winston"),k=require("winston-transport"),_=require("./console-intercept-CL_BfKQo.cjs");function v(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const o in t)if(o!=="default"){const r=Object.getOwnPropertyDescriptor(t,o);Object.defineProperty(e,o,r.get?r:{enumerable:!0,get:()=>t[o]})}}return e.default=t,Object.freeze(e)}const f=v(C),F=v(D),h=v(O);function q(t){if(!t)return{};const e={};for(const[o,r]of Object.entries(t))r!==void 0&&(e[o]=r);return e}const T=Symbol.for("message"),x=t=>{if(!t||typeof t!="object")return;const e=t.logPath;return typeof e=="string"&&e.length?e:void 0};class R extends k{defaultLogPath;ensuredDirs=new Set;lineFormat;constructor({defaultLogPath:e,format:o}){super(),this.defaultLogPath=e,this.lineFormat=o}log(e,o){setImmediate(()=>this.emit("logged",e));const r=x(e.logEvent?.data)??this.defaultLogPath;if(!r){o();return}(async()=>{const n=F.dirname(r);this.ensuredDirs.has(n)||(this.ensuredDirs.add(n),await f.mkdir(n,{recursive:!0}).catch(()=>{}));const s=this.lineFormat.transform({...e},this.lineFormat.options??{}),m=s[T]??s.message??"";await f.appendFile(r,`${m}
|
|
2
|
+
`,"utf8")})().catch(n=>{const s=n instanceof Error?n.message:h.format("%o",n);console.warn("[tim-logger] Failed to write log file",{logPath:r,error:s})}).finally(o)}}const I=l.format.combine(l.format.timestamp({format:()=>new Date().toISOString()}),l.format.printf(t=>{const e=t.logEvent??{},o=t.timestamp??new Date().toISOString(),r=String(e.source??"LOG"),a=String(e.message??t.message??""),n=e.data??{},s=n&&typeof n=="object"&&Object.keys(n).length?` | ${JSON.stringify(n)}`:"";return`[${o}] ${r.padStart(12)}: ${a}${s}`})),z=["console"],A=(t,e,o,r)=>typeof t=="string"?{message:t,level:e,source:o,data:r}:{...t,level:t.level??e,source:t.source??o,data:t.data??r},G=t=>{if(!t)return"";try{return JSON.stringify(t)}catch{return"[unserializable data]"}},N=l.format.combine(l.format.timestamp(),l.format.errors({stack:!0}),l.format.colorize({all:!0}),l.format.printf(t=>{const{timestamp:e,level:o="info",message:r="",stack:a,logEvent:n}=t,s=n??{},m=s.source??"LOG",p=s.verb??o?.toUpperCase?.()??"LOG",y=[s.machineId,s.sessionId].filter(Boolean),$=y.length?d.gray(` [${y.join(" ")}]`):"",i=s.data?d.gray(` ${G(s.data)}`):"",c=typeof s.duration=="number"?d.yellow(` ${s.duration}ms`):"",u=`${e} ${d.bold(`[${m}]`)} ${d.cyan(p)} ${r}${c}${$}${i}`;return a?`${u}
|
|
3
|
+
${a}`:u})),S=(t={})=>{const e=t.transports?.length?t.transports:z;let o=!1;const r=[];e.includes("console")&&r.push(new l.transports.Console({format:N}));const a=t.logPath??t.fsPath??"log.txt";e.includes("fs")&&r.push(new R({defaultLogPath:a,format:I}));const n=l.createLogger({level:"info",transports:r.length?r:[new l.transports.Console]}),s=async(i,c)=>{const u=A(i,"info",t.source,c),P=u.level??"info",w={...u,level:P,timestamp:u.timestamp??Date.now()};if(n.log({level:P,message:w.message,logEvent:w}),e.includes("custom"))if(t.addLog){const L={...w};L.data=q(L.data),await Promise.resolve(t.addLog(L))}else o||(o=!0,console.warn("[tim-logger] Custom transport requested without addLog handler."))},m=async(i,c)=>s({message:i,level:"info",data:c,source:t.source}),p=async(i,c)=>s({message:i,level:"warn",data:c,source:t.source});return{log:s,info:m,warn:p,error:async(i,c)=>s({message:i,level:"error",data:c,source:t.source}),clearLogs:async(i=()=>!0)=>{if(e.includes("fs"))try{await f.mkdir(F.dirname(a),{recursive:!0}).catch(()=>{}),await f.writeFile(a,"",{flag:"a"}),await f.truncate(a,0),await m("🧹 Logs cleared",{logPath:a})}catch(c){const u=c instanceof Error?c.message:h.format("%o",c);await p("Failed to clear logs",{logPath:a,error:u})}e.includes("custom")&&t.clearLogs&&await t.clearLogs(i)}}};let g=S();const U=(t={})=>(g=S(t),g),H=(t,e)=>g.log(t,e),J=(t,e)=>g.info(t,e),B=(t,e)=>g.warn(t,e),b=(t,e)=>g.error(t,e),V=()=>g.clearLogs?.()??Promise.resolve();let E=!1;function j(t,e){const o=e instanceof Error?e.stack||e.message:h.format("%o",e);b(`❌ ${t}: ${o}`)}function K({onCrash:t}={}){if(E)return;E=!0;const e=o=>r=>{if(j(o,r),typeof t=="function")try{t(r)}catch(a){const n=a instanceof Error?a.stack||a.message:h.format("%o",a);b(`❌ Crash handler failed: ${n}`)}};process.on("uncaughtException",e("Uncaught Exception")),process.on("unhandledRejection",e("Unhandled Rejection"))}exports.interceptConsoleLogs=_.interceptConsoleLogs;exports.clearLogs=V;exports.createServerLogger=S;exports.error=b;exports.info=J;exports.init=U;exports.log=H;exports.logCrash=j;exports.registerCrashHandlers=K;exports.warn=B;
|
|
4
4
|
//# sourceMappingURL=server.cjs.js.map
|
package/dist/server.cjs.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.cjs.js","sources":["../src/object.ts","../src/server.ts"],"sourcesContent":["export function cleanObject<T extends Record<string, unknown>>(\n obj?: T\n): Partial<T> {\n if (!obj) return {};\n\n const out: Partial<T> = {};\n for (const [key, value] of Object.entries(obj) as [keyof T, T[keyof T]][]) {\n if (value !== undefined) out[key] = value;\n }\n return out;\n}\n","import kleur from 'kleur';\nimport type { TransformableInfo } from 'logform';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as util from 'node:util';\nimport {\n createLogger as createWinstonLogger,\n transports,\n format as winstonFormat,\n} from 'winston';\nimport TransportStream from 'winston-transport';\nimport { cleanObject } from './object';\nimport type { Logger, ServerLoggerConfig, ServerTransport } from './types';\n\ntype FileInfo = TransformableInfo & {\n logEvent?: Partial<LogEvent>;\n};\n\nconst MESSAGE = Symbol.for('message');\n\nconst getLogPathFromData = (data?: Json) => {\n if (!data || typeof data !== 'object') return undefined;\n const maybeLogPath = (data as Record<string, unknown>).logPath;\n return typeof maybeLogPath === 'string' && maybeLogPath.length\n ? maybeLogPath\n : undefined;\n};\n\nclass DynamicFileTransport extends TransportStream {\n private defaultLogPath: string;\n private ensuredDirs = new Set<string>();\n private lineFormat: ReturnType<typeof winstonFormat.combine>;\n\n constructor({\n defaultLogPath,\n format,\n }: {\n defaultLogPath: string;\n format: ReturnType<typeof winstonFormat.combine>;\n }) {\n // IMPORTANT: don't pass `format` into super if you're going to transform manually\n super();\n this.defaultLogPath = defaultLogPath;\n this.lineFormat = format;\n }\n\n override log(info: FileInfo, callback: () => void) {\n setImmediate(() => this.emit('logged', info));\n\n const logPath =\n getLogPathFromData(info.logEvent?.data) ?? this.defaultLogPath;\n\n if (!logPath) {\n callback();\n return;\n }\n\n const write = async () => {\n console.log({\n path: typeof path,\n logPath: typeof path.dirname,\n fs: typeof fs,\n mkdir: typeof fs.mkdir,\n lineFormat: typeof this.lineFormat,\n transform: typeof this.lineFormat.transform,\n });\n\n const dir = path.dirname(logPath);\n if (!this.ensuredDirs.has(dir)) {\n this.ensuredDirs.add(dir);\n await fs.mkdir(dir, { recursive: true }).catch(() => {});\n }\n\n // clone because logform formats mutate `info`\n const formatted = this.lineFormat.transform(\n { ...info },\n this.lineFormat.options ?? {}\n ) as FileInfo;\n\n const message =\n (formatted as any)[MESSAGE] ?? formatted.message ?? '';\n\n await fs.appendFile(logPath, `${message}\\n`, 'utf8');\n };\n\n void write()\n .catch((err) => {\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n console.warn('[tim-logger] Failed to write log file', {\n logPath,\n error: msg,\n });\n })\n .finally(callback);\n }\n}\n\nconst fileLineFormat = winstonFormat.combine(\n winstonFormat.timestamp({ format: () => new Date().toISOString() }),\n winstonFormat.printf((info: FileInfo) => {\n const entry = info.logEvent ?? {};\n\n // Use the formatter timestamp (or fallback), instead of generating a new one.\n const timestamp =\n (info.timestamp as string) ?? new Date().toISOString();\n\n const name = String(entry.source ?? 'LOG');\n const text = String(entry.message ?? info.message ?? '');\n\n const data = (entry.data ?? {}) as Record<string, unknown>;\n const dataString =\n data && typeof data === 'object' && Object.keys(data).length\n ? ` | ${JSON.stringify(data)}`\n : '';\n\n return `[${timestamp}] ${name.padStart(12)}: ${text}${dataString}`;\n })\n);\n\nconst DEFAULT_SERVER_TRANSPORTS: ServerTransport[] = ['console'];\n\ntype ConsoleInfo = TransformableInfo & {\n timestamp?: string;\n stack?: string;\n logEvent?: Partial<LogEvent>;\n};\n\nconst normalizeEvent = (\n eventOrMessage: LogEvent | string,\n level?: LogLevel,\n source?: string,\n data?: Json\n): LogEvent => {\n if (typeof eventOrMessage === 'string') {\n return { message: eventOrMessage, level, source, data } as LogEvent;\n }\n\n return {\n ...eventOrMessage,\n level: eventOrMessage.level ?? level,\n source: eventOrMessage.source ?? source,\n data: eventOrMessage.data ?? data,\n };\n};\n\nconst stringifyData = (data?: Json) => {\n if (!data) return '';\n try {\n return JSON.stringify(data);\n } catch {\n return '[unserializable data]';\n }\n};\n\nconst consoleFormat = winstonFormat.combine(\n winstonFormat.timestamp(),\n winstonFormat.errors({ stack: true }),\n winstonFormat.colorize({ all: true }),\n winstonFormat.printf((info: ConsoleInfo) => {\n const {\n timestamp,\n level = 'info',\n message = '',\n stack,\n logEvent,\n } = info;\n\n const entry: Partial<LogEvent> = logEvent ?? {};\n const source = entry.source ?? 'LOG';\n const verb = entry.verb ?? level?.toUpperCase?.() ?? 'LOG';\n\n const contextParts = [entry.machineId, entry.sessionId].filter(Boolean);\n const ctx = contextParts.length\n ? kleur.gray(` [${contextParts.join(' ')}]`)\n : '';\n\n const data = entry.data\n ? kleur.gray(` ${stringifyData(entry.data)}`)\n : '';\n\n const duration =\n typeof entry.duration === 'number'\n ? kleur.yellow(` ${entry.duration}ms`)\n : '';\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${message}${duration}${ctx}${data}`;\n\n return stack ? `${base}\\n${stack}` : base;\n })\n);\n\nexport const createServerLogger = (config: ServerLoggerConfig = {}): Logger => {\n const transportsArr = config.transports?.length\n ? config.transports\n : DEFAULT_SERVER_TRANSPORTS;\n let warnedMissingCustom = false;\n\n const winstonTransports: TransportStream[] = [];\n\n if (transportsArr.includes('console')) {\n winstonTransports.push(\n new transports.Console({\n format: consoleFormat,\n })\n );\n }\n\n const defaultLogPath = config.logPath ?? config.fsPath ?? 'log.txt';\n\n if (transportsArr.includes('fs')) {\n winstonTransports.push(\n new DynamicFileTransport({\n defaultLogPath,\n format: fileLineFormat,\n })\n );\n }\n\n const baseLogger = createWinstonLogger({\n level: 'info',\n transports: winstonTransports.length\n ? winstonTransports\n : [new transports.Console()],\n });\n\n const log = async (eventOrMessage: LogEvent | string, data?: Json) => {\n const event = normalizeEvent(\n eventOrMessage,\n 'info',\n config.source,\n data\n );\n const resolvedLevel = event.level ?? 'info';\n\n const payload = {\n ...event,\n level: resolvedLevel,\n timestamp: event.timestamp ?? Date.now(),\n };\n\n baseLogger.log({\n level: resolvedLevel,\n message: payload.message,\n logEvent: payload,\n });\n\n if (transportsArr.includes('custom')) {\n if (config.addLog) {\n const clean = { ...payload };\n clean.data = cleanObject(clean.data);\n await Promise.resolve(config.addLog(clean));\n } else if (!warnedMissingCustom) {\n warnedMissingCustom = true;\n console.warn(\n '[tim-logger] Custom transport requested without addLog handler.'\n );\n }\n }\n };\n\n const info = async (message: string, data?: Json) =>\n log({\n message,\n level: 'info',\n data,\n source: config.source,\n } as LogEvent);\n\n const warn = async (message: string, data?: Json) =>\n log({\n message,\n level: 'warn',\n data,\n source: config.source,\n } as LogEvent);\n\n const error = async (message: string, data?: Json) =>\n log({\n message,\n level: 'error',\n data,\n source: config.source,\n } as LogEvent);\n\n /**\n * Clears the fs transport logs by truncating the file.\n * No-op if 'fs' transport is not enabled.\n */\n const clearLogs = async (predicate = () => true) => {\n if (transportsArr.includes('fs')) {\n try {\n // Ensure file exists, then truncate.\n await fs\n .mkdir(path.dirname(defaultLogPath), {\n recursive: true,\n })\n .catch(() => {});\n await fs.writeFile(defaultLogPath, '', { flag: 'a' }); // touch\n await fs.truncate(defaultLogPath, 0);\n await info('🧹 Logs cleared', { logPath: defaultLogPath });\n } catch (err) {\n // Don’t throw; log the failure instead.\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n await warn('Failed to clear logs', {\n logPath: defaultLogPath,\n error: msg,\n });\n }\n }\n\n if (transportsArr.includes('custom') && config.clearLogs) {\n await config.clearLogs(predicate);\n }\n };\n\n return { log, info, warn, error, clearLogs };\n};\n\nlet defaultLogger = createServerLogger();\n\nexport const init = (config: ServerLoggerConfig = {}) => {\n defaultLogger = createServerLogger(config);\n return defaultLogger;\n};\n\nexport const log = (eventOrMessage: LogEvent | string, data?: Json) =>\n defaultLogger.log(eventOrMessage, data);\nexport const info = (message: string, data?: Json) =>\n defaultLogger.info(message, data);\nexport const warn = (message: string, data?: Json) =>\n defaultLogger.warn(message, data);\nexport const error = (message: string, data?: Json) =>\n defaultLogger.error(message, data);\nexport const clearLogs = () => defaultLogger.clearLogs?.() ?? Promise.resolve();\nexport { interceptConsoleLogs } from './console-intercept';\n\n// newly added\nlet crashHandlersRegistered = false;\n\nexport function logCrash(type: string, err: unknown) {\n const message =\n err instanceof Error\n ? err.stack || err.message\n : util.format('%o', err);\n void error(`❌ ${type}: ${message}`);\n}\n\nexport function registerCrashHandlers({\n onCrash,\n}: { onCrash?: (err: unknown) => void } = {}) {\n if (crashHandlersRegistered) return;\n crashHandlersRegistered = true;\n\n const handleCrash = (type: string) => (err: unknown) => {\n logCrash(type, err);\n if (typeof onCrash === 'function') {\n try {\n onCrash(err);\n } catch (handlerErr) {\n // FIX: was `log.error(...)` (wrong symbol). Use our logger.\n const msg =\n handlerErr instanceof Error\n ? handlerErr.stack || handlerErr.message\n : util.format('%o', handlerErr);\n void error(`❌ Crash handler failed: ${msg}`);\n }\n }\n };\n\n process.on('uncaughtException', handleCrash('Uncaught Exception'));\n process.on('unhandledRejection', handleCrash('Unhandled Rejection'));\n}\n"],"names":["cleanObject","obj","out","key","value","MESSAGE","getLogPathFromData","data","maybeLogPath","DynamicFileTransport","TransportStream","defaultLogPath","format","info","callback","logPath","path","fs","dir","formatted","message","err","msg","util","fileLineFormat","winstonFormat","entry","timestamp","name","text","dataString","DEFAULT_SERVER_TRANSPORTS","normalizeEvent","eventOrMessage","level","source","stringifyData","consoleFormat","stack","logEvent","verb","contextParts","ctx","kleur","duration","base","createServerLogger","config","transportsArr","warnedMissingCustom","winstonTransports","transports","baseLogger","createWinstonLogger","log","event","resolvedLevel","payload","clean","warn","predicate","clearLogs","defaultLogger","init","error","crashHandlersRegistered","logCrash","type","registerCrashHandlers","onCrash","handleCrash","handlerErr"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.cjs.js","sources":["../src/object.ts","../src/server.ts"],"sourcesContent":["export function cleanObject<T extends Record<string, unknown>>(\n obj?: T\n): Partial<T> {\n if (!obj) return {};\n\n const out: Partial<T> = {};\n for (const [key, value] of Object.entries(obj) as [keyof T, T[keyof T]][]) {\n if (value !== undefined) out[key] = value;\n }\n return out;\n}\n","import kleur from 'kleur';\nimport type { TransformableInfo } from 'logform';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as util from 'node:util';\nimport {\n createLogger as createWinstonLogger,\n transports,\n format as winstonFormat,\n} from 'winston';\nimport TransportStream from 'winston-transport';\nimport { cleanObject } from './object';\nimport type { Logger, ServerLoggerConfig, ServerTransport } from './types';\n\ntype FileInfo = TransformableInfo & {\n logEvent?: Partial<LogEvent>;\n};\n\nconst MESSAGE = Symbol.for('message');\n\nconst getLogPathFromData = (data?: Json) => {\n if (!data || typeof data !== 'object') return undefined;\n const maybeLogPath = (data as Record<string, unknown>).logPath;\n return typeof maybeLogPath === 'string' && maybeLogPath.length\n ? maybeLogPath\n : undefined;\n};\n\nclass DynamicFileTransport extends TransportStream {\n private defaultLogPath: string;\n private ensuredDirs = new Set<string>();\n private lineFormat: ReturnType<typeof winstonFormat.combine>;\n\n constructor({\n defaultLogPath,\n format,\n }: {\n defaultLogPath: string;\n format: ReturnType<typeof winstonFormat.combine>;\n }) {\n // IMPORTANT: don't pass `format` into super if you're going to transform manually\n super();\n this.defaultLogPath = defaultLogPath;\n this.lineFormat = format;\n }\n\n override log(info: FileInfo, callback: () => void) {\n setImmediate(() => this.emit('logged', info));\n\n const logPath =\n getLogPathFromData(info.logEvent?.data) ?? this.defaultLogPath;\n\n if (!logPath) {\n callback();\n return;\n }\n\n const write = async () => {\n const dir = path.dirname(logPath);\n if (!this.ensuredDirs.has(dir)) {\n this.ensuredDirs.add(dir);\n await fs.mkdir(dir, { recursive: true }).catch(() => {});\n }\n\n // clone because logform formats mutate `info`\n const formatted = this.lineFormat.transform(\n { ...info },\n this.lineFormat.options ?? {}\n ) as FileInfo;\n\n const message =\n (formatted as any)[MESSAGE] ?? formatted.message ?? '';\n\n await fs.appendFile(logPath, `${message}\\n`, 'utf8');\n };\n\n void write()\n .catch((err) => {\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n console.warn('[tim-logger] Failed to write log file', {\n logPath,\n error: msg,\n });\n })\n .finally(callback);\n }\n}\n\nconst fileLineFormat = winstonFormat.combine(\n winstonFormat.timestamp({ format: () => new Date().toISOString() }),\n winstonFormat.printf((info: FileInfo) => {\n const entry = info.logEvent ?? {};\n\n // Use the formatter timestamp (or fallback), instead of generating a new one.\n const timestamp =\n (info.timestamp as string) ?? new Date().toISOString();\n\n const name = String(entry.source ?? 'LOG');\n const text = String(entry.message ?? info.message ?? '');\n\n const data = (entry.data ?? {}) as Record<string, unknown>;\n const dataString =\n data && typeof data === 'object' && Object.keys(data).length\n ? ` | ${JSON.stringify(data)}`\n : '';\n\n return `[${timestamp}] ${name.padStart(12)}: ${text}${dataString}`;\n })\n);\n\nconst DEFAULT_SERVER_TRANSPORTS: ServerTransport[] = ['console'];\n\ntype ConsoleInfo = TransformableInfo & {\n timestamp?: string;\n stack?: string;\n logEvent?: Partial<LogEvent>;\n};\n\nconst normalizeEvent = (\n eventOrMessage: LogEvent | string,\n level?: LogLevel,\n source?: string,\n data?: Json\n): LogEvent => {\n if (typeof eventOrMessage === 'string') {\n return { message: eventOrMessage, level, source, data } as LogEvent;\n }\n\n return {\n ...eventOrMessage,\n level: eventOrMessage.level ?? level,\n source: eventOrMessage.source ?? source,\n data: eventOrMessage.data ?? data,\n };\n};\n\nconst stringifyData = (data?: Json) => {\n if (!data) return '';\n try {\n return JSON.stringify(data);\n } catch {\n return '[unserializable data]';\n }\n};\n\nconst consoleFormat = winstonFormat.combine(\n winstonFormat.timestamp(),\n winstonFormat.errors({ stack: true }),\n winstonFormat.colorize({ all: true }),\n winstonFormat.printf((info: ConsoleInfo) => {\n const {\n timestamp,\n level = 'info',\n message = '',\n stack,\n logEvent,\n } = info;\n\n const entry: Partial<LogEvent> = logEvent ?? {};\n const source = entry.source ?? 'LOG';\n const verb = entry.verb ?? level?.toUpperCase?.() ?? 'LOG';\n\n const contextParts = [entry.machineId, entry.sessionId].filter(Boolean);\n const ctx = contextParts.length\n ? kleur.gray(` [${contextParts.join(' ')}]`)\n : '';\n\n const data = entry.data\n ? kleur.gray(` ${stringifyData(entry.data)}`)\n : '';\n\n const duration =\n typeof entry.duration === 'number'\n ? kleur.yellow(` ${entry.duration}ms`)\n : '';\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${message}${duration}${ctx}${data}`;\n\n return stack ? `${base}\\n${stack}` : base;\n })\n);\n\nexport const createServerLogger = (config: ServerLoggerConfig = {}): Logger => {\n const transportsArr = config.transports?.length\n ? config.transports\n : DEFAULT_SERVER_TRANSPORTS;\n let warnedMissingCustom = false;\n\n const winstonTransports: TransportStream[] = [];\n\n if (transportsArr.includes('console')) {\n winstonTransports.push(\n new transports.Console({\n format: consoleFormat,\n })\n );\n }\n\n const defaultLogPath = config.logPath ?? config.fsPath ?? 'log.txt';\n\n if (transportsArr.includes('fs')) {\n winstonTransports.push(\n new DynamicFileTransport({\n defaultLogPath,\n format: fileLineFormat,\n })\n );\n }\n\n const baseLogger = createWinstonLogger({\n level: 'info',\n transports: winstonTransports.length\n ? winstonTransports\n : [new transports.Console()],\n });\n\n const log = async (eventOrMessage: LogEvent | string, data?: Json) => {\n const event = normalizeEvent(\n eventOrMessage,\n 'info',\n config.source,\n data\n );\n const resolvedLevel = event.level ?? 'info';\n\n const payload = {\n ...event,\n level: resolvedLevel,\n timestamp: event.timestamp ?? Date.now(),\n };\n\n baseLogger.log({\n level: resolvedLevel,\n message: payload.message,\n logEvent: payload,\n });\n\n if (transportsArr.includes('custom')) {\n if (config.addLog) {\n const clean = { ...payload };\n clean.data = cleanObject(clean.data);\n await Promise.resolve(config.addLog(clean));\n } else if (!warnedMissingCustom) {\n warnedMissingCustom = true;\n console.warn(\n '[tim-logger] Custom transport requested without addLog handler.'\n );\n }\n }\n };\n\n const info = async (message: string, data?: Json) =>\n log({\n message,\n level: 'info',\n data,\n source: config.source,\n } as LogEvent);\n\n const warn = async (message: string, data?: Json) =>\n log({\n message,\n level: 'warn',\n data,\n source: config.source,\n } as LogEvent);\n\n const error = async (message: string, data?: Json) =>\n log({\n message,\n level: 'error',\n data,\n source: config.source,\n } as LogEvent);\n\n /**\n * Clears the fs transport logs by truncating the file.\n * No-op if 'fs' transport is not enabled.\n */\n const clearLogs = async (predicate = () => true) => {\n if (transportsArr.includes('fs')) {\n try {\n // Ensure file exists, then truncate.\n await fs\n .mkdir(path.dirname(defaultLogPath), {\n recursive: true,\n })\n .catch(() => {});\n await fs.writeFile(defaultLogPath, '', { flag: 'a' }); // touch\n await fs.truncate(defaultLogPath, 0);\n await info('🧹 Logs cleared', { logPath: defaultLogPath });\n } catch (err) {\n // Don’t throw; log the failure instead.\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n await warn('Failed to clear logs', {\n logPath: defaultLogPath,\n error: msg,\n });\n }\n }\n\n if (transportsArr.includes('custom') && config.clearLogs) {\n await config.clearLogs(predicate);\n }\n };\n\n return { log, info, warn, error, clearLogs };\n};\n\nlet defaultLogger = createServerLogger();\n\nexport const init = (config: ServerLoggerConfig = {}) => {\n defaultLogger = createServerLogger(config);\n return defaultLogger;\n};\n\nexport const log = (eventOrMessage: LogEvent | string, data?: Json) =>\n defaultLogger.log(eventOrMessage, data);\nexport const info = (message: string, data?: Json) =>\n defaultLogger.info(message, data);\nexport const warn = (message: string, data?: Json) =>\n defaultLogger.warn(message, data);\nexport const error = (message: string, data?: Json) =>\n defaultLogger.error(message, data);\nexport const clearLogs = () => defaultLogger.clearLogs?.() ?? Promise.resolve();\nexport { interceptConsoleLogs } from './console-intercept';\n\n// newly added\nlet crashHandlersRegistered = false;\n\nexport function logCrash(type: string, err: unknown) {\n const message =\n err instanceof Error\n ? err.stack || err.message\n : util.format('%o', err);\n void error(`❌ ${type}: ${message}`);\n}\n\nexport function registerCrashHandlers({\n onCrash,\n}: { onCrash?: (err: unknown) => void } = {}) {\n if (crashHandlersRegistered) return;\n crashHandlersRegistered = true;\n\n const handleCrash = (type: string) => (err: unknown) => {\n logCrash(type, err);\n if (typeof onCrash === 'function') {\n try {\n onCrash(err);\n } catch (handlerErr) {\n // FIX: was `log.error(...)` (wrong symbol). Use our logger.\n const msg =\n handlerErr instanceof Error\n ? handlerErr.stack || handlerErr.message\n : util.format('%o', handlerErr);\n void error(`❌ Crash handler failed: ${msg}`);\n }\n }\n };\n\n process.on('uncaughtException', handleCrash('Uncaught Exception'));\n process.on('unhandledRejection', handleCrash('Unhandled Rejection'));\n}\n"],"names":["cleanObject","obj","out","key","value","MESSAGE","getLogPathFromData","data","maybeLogPath","DynamicFileTransport","TransportStream","defaultLogPath","format","info","callback","logPath","dir","path","fs","formatted","message","err","msg","util","fileLineFormat","winstonFormat","entry","timestamp","name","text","dataString","DEFAULT_SERVER_TRANSPORTS","normalizeEvent","eventOrMessage","level","source","stringifyData","consoleFormat","stack","logEvent","verb","contextParts","ctx","kleur","duration","base","createServerLogger","config","transportsArr","warnedMissingCustom","winstonTransports","transports","baseLogger","createWinstonLogger","log","event","resolvedLevel","payload","clean","warn","predicate","clearLogs","defaultLogger","init","error","crashHandlersRegistered","logCrash","type","registerCrashHandlers","onCrash","handleCrash","handlerErr"],"mappings":"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"}
|
package/dist/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAmB,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAmB,MAAM,SAAS,CAAC;AA6K3E,eAAO,MAAM,kBAAkB,GAAI,SAAQ,kBAAuB,KAAG,MA8HpE,CAAC;AAIF,eAAO,MAAM,IAAI,GAAI,SAAQ,kBAAuB,WAGnD,CAAC;AAEF,eAAO,MAAM,GAAG,GAAI,gBAAgB,QAAQ,GAAG,MAAM,EAAE,OAAO,IAAI,kBACvB,CAAC;AAC5C,eAAO,MAAM,IAAI,GAAI,SAAS,MAAM,EAAE,OAAO,IAAI,kBACZ,CAAC;AACtC,eAAO,MAAM,IAAI,GAAI,SAAS,MAAM,EAAE,OAAO,IAAI,kBACZ,CAAC;AACtC,eAAO,MAAM,KAAK,GAAI,SAAS,MAAM,EAAE,OAAO,IAAI,kBACZ,CAAC;AACvC,eAAO,MAAM,SAAS,qBAAyD,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAK3D,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,QAMlD;AAED,wBAAgB,qBAAqB,CAAC,EAClC,OAAO,GACV,GAAE;IAAE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,IAAI,CAAA;CAAO,QAsB3C"}
|
package/dist/server.es.js
CHANGED
|
@@ -1,23 +1,23 @@
|
|
|
1
1
|
import d from "kleur";
|
|
2
|
-
import * as
|
|
3
|
-
import * as
|
|
4
|
-
import * as
|
|
5
|
-
import { format as m, transports as
|
|
6
|
-
import
|
|
2
|
+
import * as f from "node:fs/promises";
|
|
3
|
+
import * as P from "node:path";
|
|
4
|
+
import * as p from "node:util";
|
|
5
|
+
import { format as m, transports as S, createLogger as D } from "winston";
|
|
6
|
+
import x from "winston-transport";
|
|
7
7
|
import { i as X } from "./console-intercept-ByhsZ0kO.js";
|
|
8
|
-
function
|
|
8
|
+
function C(t) {
|
|
9
9
|
if (!t) return {};
|
|
10
10
|
const e = {};
|
|
11
11
|
for (const [r, o] of Object.entries(t))
|
|
12
12
|
o !== void 0 && (e[r] = o);
|
|
13
13
|
return e;
|
|
14
14
|
}
|
|
15
|
-
const
|
|
15
|
+
const k = Symbol.for("message"), j = (t) => {
|
|
16
16
|
if (!t || typeof t != "object") return;
|
|
17
17
|
const e = t.logPath;
|
|
18
18
|
return typeof e == "string" && e.length ? e : void 0;
|
|
19
19
|
};
|
|
20
|
-
class R extends
|
|
20
|
+
class R extends x {
|
|
21
21
|
defaultLogPath;
|
|
22
22
|
ensuredDirs = /* @__PURE__ */ new Set();
|
|
23
23
|
lineFormat;
|
|
@@ -35,25 +35,17 @@ class R extends D {
|
|
|
35
35
|
return;
|
|
36
36
|
}
|
|
37
37
|
(async () => {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
logPath: typeof h.dirname,
|
|
41
|
-
fs: typeof g,
|
|
42
|
-
mkdir: typeof g.mkdir,
|
|
43
|
-
lineFormat: typeof this.lineFormat,
|
|
44
|
-
transform: typeof this.lineFormat.transform
|
|
45
|
-
});
|
|
46
|
-
const a = h.dirname(o);
|
|
47
|
-
this.ensuredDirs.has(a) || (this.ensuredDirs.add(a), await g.mkdir(a, { recursive: !0 }).catch(() => {
|
|
38
|
+
const a = P.dirname(o);
|
|
39
|
+
this.ensuredDirs.has(a) || (this.ensuredDirs.add(a), await f.mkdir(a, { recursive: !0 }).catch(() => {
|
|
48
40
|
}));
|
|
49
41
|
const s = this.lineFormat.transform(
|
|
50
42
|
{ ...e },
|
|
51
43
|
this.lineFormat.options ?? {}
|
|
52
|
-
),
|
|
53
|
-
await
|
|
44
|
+
), g = s[k] ?? s.message ?? "";
|
|
45
|
+
await f.appendFile(o, `${g}
|
|
54
46
|
`, "utf8");
|
|
55
47
|
})().catch((a) => {
|
|
56
|
-
const s = a instanceof Error ? a.message :
|
|
48
|
+
const s = a instanceof Error ? a.message : p.format("%o", a);
|
|
57
49
|
console.warn("[tim-logger] Failed to write log file", {
|
|
58
50
|
logPath: o,
|
|
59
51
|
error: s
|
|
@@ -90,18 +82,18 @@ const O = m.combine(
|
|
|
90
82
|
message: o = "",
|
|
91
83
|
stack: n,
|
|
92
84
|
logEvent: a
|
|
93
|
-
} = t, s = a ?? {},
|
|
94
|
-
|
|
95
|
-
)} ${o}${i}${
|
|
85
|
+
} = t, s = a ?? {}, g = s.source ?? "LOG", h = s.verb ?? r?.toUpperCase?.() ?? "LOG", w = [s.machineId, s.sessionId].filter(Boolean), v = w.length ? d.gray(` [${w.join(" ")}]`) : "", c = s.data ? d.gray(` ${A(s.data)}`) : "", i = typeof s.duration == "number" ? d.yellow(` ${s.duration}ms`) : "", l = `${e} ${d.bold(`[${g}]`)} ${d.cyan(
|
|
86
|
+
h
|
|
87
|
+
)} ${o}${i}${v}${c}`;
|
|
96
88
|
return n ? `${l}
|
|
97
89
|
${n}` : l;
|
|
98
90
|
})
|
|
99
|
-
),
|
|
91
|
+
), b = (t = {}) => {
|
|
100
92
|
const e = t.transports?.length ? t.transports : T;
|
|
101
93
|
let r = !1;
|
|
102
94
|
const o = [];
|
|
103
95
|
e.includes("console") && o.push(
|
|
104
|
-
new
|
|
96
|
+
new S.Console({
|
|
105
97
|
format: G
|
|
106
98
|
})
|
|
107
99
|
);
|
|
@@ -112,43 +104,43 @@ ${n}` : l;
|
|
|
112
104
|
format: O
|
|
113
105
|
})
|
|
114
106
|
);
|
|
115
|
-
const a =
|
|
107
|
+
const a = D({
|
|
116
108
|
level: "info",
|
|
117
|
-
transports: o.length ? o : [new
|
|
109
|
+
transports: o.length ? o : [new S.Console()]
|
|
118
110
|
}), s = async (c, i) => {
|
|
119
111
|
const l = I(
|
|
120
112
|
c,
|
|
121
113
|
"info",
|
|
122
114
|
t.source,
|
|
123
115
|
i
|
|
124
|
-
),
|
|
116
|
+
), $ = l.level ?? "info", y = {
|
|
125
117
|
...l,
|
|
126
|
-
level:
|
|
118
|
+
level: $,
|
|
127
119
|
timestamp: l.timestamp ?? Date.now()
|
|
128
120
|
};
|
|
129
121
|
if (a.log({
|
|
130
|
-
level:
|
|
131
|
-
message:
|
|
132
|
-
logEvent:
|
|
122
|
+
level: $,
|
|
123
|
+
message: y.message,
|
|
124
|
+
logEvent: y
|
|
133
125
|
}), e.includes("custom"))
|
|
134
126
|
if (t.addLog) {
|
|
135
|
-
const
|
|
136
|
-
|
|
127
|
+
const L = { ...y };
|
|
128
|
+
L.data = C(L.data), await Promise.resolve(t.addLog(L));
|
|
137
129
|
} else r || (r = !0, console.warn(
|
|
138
130
|
"[tim-logger] Custom transport requested without addLog handler."
|
|
139
131
|
));
|
|
140
|
-
},
|
|
132
|
+
}, g = async (c, i) => s({
|
|
141
133
|
message: c,
|
|
142
134
|
level: "info",
|
|
143
135
|
data: i,
|
|
144
136
|
source: t.source
|
|
145
|
-
}),
|
|
137
|
+
}), h = async (c, i) => s({
|
|
146
138
|
message: c,
|
|
147
139
|
level: "warn",
|
|
148
140
|
data: i,
|
|
149
141
|
source: t.source
|
|
150
142
|
});
|
|
151
|
-
return { log: s, info:
|
|
143
|
+
return { log: s, info: g, warn: h, error: async (c, i) => s({
|
|
152
144
|
message: c,
|
|
153
145
|
level: "error",
|
|
154
146
|
data: i,
|
|
@@ -156,13 +148,13 @@ ${n}` : l;
|
|
|
156
148
|
}), clearLogs: async (c = () => !0) => {
|
|
157
149
|
if (e.includes("fs"))
|
|
158
150
|
try {
|
|
159
|
-
await
|
|
151
|
+
await f.mkdir(P.dirname(n), {
|
|
160
152
|
recursive: !0
|
|
161
153
|
}).catch(() => {
|
|
162
|
-
}), await
|
|
154
|
+
}), await f.writeFile(n, "", { flag: "a" }), await f.truncate(n, 0), await g("🧹 Logs cleared", { logPath: n });
|
|
163
155
|
} catch (i) {
|
|
164
|
-
const l = i instanceof Error ? i.message :
|
|
165
|
-
await
|
|
156
|
+
const l = i instanceof Error ? i.message : p.format("%o", i);
|
|
157
|
+
await h("Failed to clear logs", {
|
|
166
158
|
logPath: n,
|
|
167
159
|
error: l
|
|
168
160
|
});
|
|
@@ -170,33 +162,33 @@ ${n}` : l;
|
|
|
170
162
|
e.includes("custom") && t.clearLogs && await t.clearLogs(c);
|
|
171
163
|
} };
|
|
172
164
|
};
|
|
173
|
-
let u =
|
|
174
|
-
const J = (t = {}) => (u =
|
|
175
|
-
let
|
|
165
|
+
let u = b();
|
|
166
|
+
const J = (t = {}) => (u = b(t), u), _ = (t, e) => u.log(t, e), q = (t, e) => u.info(t, e), B = (t, e) => u.warn(t, e), F = (t, e) => u.error(t, e), V = () => u.clearLogs?.() ?? Promise.resolve();
|
|
167
|
+
let E = !1;
|
|
176
168
|
function U(t, e) {
|
|
177
|
-
const r = e instanceof Error ? e.stack || e.message :
|
|
178
|
-
|
|
169
|
+
const r = e instanceof Error ? e.stack || e.message : p.format("%o", e);
|
|
170
|
+
F(`❌ ${t}: ${r}`);
|
|
179
171
|
}
|
|
180
172
|
function K({
|
|
181
173
|
onCrash: t
|
|
182
174
|
} = {}) {
|
|
183
|
-
if (
|
|
184
|
-
|
|
175
|
+
if (E) return;
|
|
176
|
+
E = !0;
|
|
185
177
|
const e = (r) => (o) => {
|
|
186
178
|
if (U(r, o), typeof t == "function")
|
|
187
179
|
try {
|
|
188
180
|
t(o);
|
|
189
181
|
} catch (n) {
|
|
190
|
-
const a = n instanceof Error ? n.stack || n.message :
|
|
191
|
-
|
|
182
|
+
const a = n instanceof Error ? n.stack || n.message : p.format("%o", n);
|
|
183
|
+
F(`❌ Crash handler failed: ${a}`);
|
|
192
184
|
}
|
|
193
185
|
};
|
|
194
186
|
process.on("uncaughtException", e("Uncaught Exception")), process.on("unhandledRejection", e("Unhandled Rejection"));
|
|
195
187
|
}
|
|
196
188
|
export {
|
|
197
189
|
V as clearLogs,
|
|
198
|
-
|
|
199
|
-
|
|
190
|
+
b as createServerLogger,
|
|
191
|
+
F as error,
|
|
200
192
|
q as info,
|
|
201
193
|
J as init,
|
|
202
194
|
X as interceptConsoleLogs,
|
package/dist/server.es.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.es.js","sources":["../src/object.ts","../src/server.ts"],"sourcesContent":["export function cleanObject<T extends Record<string, unknown>>(\n obj?: T\n): Partial<T> {\n if (!obj) return {};\n\n const out: Partial<T> = {};\n for (const [key, value] of Object.entries(obj) as [keyof T, T[keyof T]][]) {\n if (value !== undefined) out[key] = value;\n }\n return out;\n}\n","import kleur from 'kleur';\nimport type { TransformableInfo } from 'logform';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as util from 'node:util';\nimport {\n createLogger as createWinstonLogger,\n transports,\n format as winstonFormat,\n} from 'winston';\nimport TransportStream from 'winston-transport';\nimport { cleanObject } from './object';\nimport type { Logger, ServerLoggerConfig, ServerTransport } from './types';\n\ntype FileInfo = TransformableInfo & {\n logEvent?: Partial<LogEvent>;\n};\n\nconst MESSAGE = Symbol.for('message');\n\nconst getLogPathFromData = (data?: Json) => {\n if (!data || typeof data !== 'object') return undefined;\n const maybeLogPath = (data as Record<string, unknown>).logPath;\n return typeof maybeLogPath === 'string' && maybeLogPath.length\n ? maybeLogPath\n : undefined;\n};\n\nclass DynamicFileTransport extends TransportStream {\n private defaultLogPath: string;\n private ensuredDirs = new Set<string>();\n private lineFormat: ReturnType<typeof winstonFormat.combine>;\n\n constructor({\n defaultLogPath,\n format,\n }: {\n defaultLogPath: string;\n format: ReturnType<typeof winstonFormat.combine>;\n }) {\n // IMPORTANT: don't pass `format` into super if you're going to transform manually\n super();\n this.defaultLogPath = defaultLogPath;\n this.lineFormat = format;\n }\n\n override log(info: FileInfo, callback: () => void) {\n setImmediate(() => this.emit('logged', info));\n\n const logPath =\n getLogPathFromData(info.logEvent?.data) ?? this.defaultLogPath;\n\n if (!logPath) {\n callback();\n return;\n }\n\n const write = async () => {\n console.log({\n path: typeof path,\n logPath: typeof path.dirname,\n fs: typeof fs,\n mkdir: typeof fs.mkdir,\n lineFormat: typeof this.lineFormat,\n transform: typeof this.lineFormat.transform,\n });\n\n const dir = path.dirname(logPath);\n if (!this.ensuredDirs.has(dir)) {\n this.ensuredDirs.add(dir);\n await fs.mkdir(dir, { recursive: true }).catch(() => {});\n }\n\n // clone because logform formats mutate `info`\n const formatted = this.lineFormat.transform(\n { ...info },\n this.lineFormat.options ?? {}\n ) as FileInfo;\n\n const message =\n (formatted as any)[MESSAGE] ?? formatted.message ?? '';\n\n await fs.appendFile(logPath, `${message}\\n`, 'utf8');\n };\n\n void write()\n .catch((err) => {\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n console.warn('[tim-logger] Failed to write log file', {\n logPath,\n error: msg,\n });\n })\n .finally(callback);\n }\n}\n\nconst fileLineFormat = winstonFormat.combine(\n winstonFormat.timestamp({ format: () => new Date().toISOString() }),\n winstonFormat.printf((info: FileInfo) => {\n const entry = info.logEvent ?? {};\n\n // Use the formatter timestamp (or fallback), instead of generating a new one.\n const timestamp =\n (info.timestamp as string) ?? new Date().toISOString();\n\n const name = String(entry.source ?? 'LOG');\n const text = String(entry.message ?? info.message ?? '');\n\n const data = (entry.data ?? {}) as Record<string, unknown>;\n const dataString =\n data && typeof data === 'object' && Object.keys(data).length\n ? ` | ${JSON.stringify(data)}`\n : '';\n\n return `[${timestamp}] ${name.padStart(12)}: ${text}${dataString}`;\n })\n);\n\nconst DEFAULT_SERVER_TRANSPORTS: ServerTransport[] = ['console'];\n\ntype ConsoleInfo = TransformableInfo & {\n timestamp?: string;\n stack?: string;\n logEvent?: Partial<LogEvent>;\n};\n\nconst normalizeEvent = (\n eventOrMessage: LogEvent | string,\n level?: LogLevel,\n source?: string,\n data?: Json\n): LogEvent => {\n if (typeof eventOrMessage === 'string') {\n return { message: eventOrMessage, level, source, data } as LogEvent;\n }\n\n return {\n ...eventOrMessage,\n level: eventOrMessage.level ?? level,\n source: eventOrMessage.source ?? source,\n data: eventOrMessage.data ?? data,\n };\n};\n\nconst stringifyData = (data?: Json) => {\n if (!data) return '';\n try {\n return JSON.stringify(data);\n } catch {\n return '[unserializable data]';\n }\n};\n\nconst consoleFormat = winstonFormat.combine(\n winstonFormat.timestamp(),\n winstonFormat.errors({ stack: true }),\n winstonFormat.colorize({ all: true }),\n winstonFormat.printf((info: ConsoleInfo) => {\n const {\n timestamp,\n level = 'info',\n message = '',\n stack,\n logEvent,\n } = info;\n\n const entry: Partial<LogEvent> = logEvent ?? {};\n const source = entry.source ?? 'LOG';\n const verb = entry.verb ?? level?.toUpperCase?.() ?? 'LOG';\n\n const contextParts = [entry.machineId, entry.sessionId].filter(Boolean);\n const ctx = contextParts.length\n ? kleur.gray(` [${contextParts.join(' ')}]`)\n : '';\n\n const data = entry.data\n ? kleur.gray(` ${stringifyData(entry.data)}`)\n : '';\n\n const duration =\n typeof entry.duration === 'number'\n ? kleur.yellow(` ${entry.duration}ms`)\n : '';\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${message}${duration}${ctx}${data}`;\n\n return stack ? `${base}\\n${stack}` : base;\n })\n);\n\nexport const createServerLogger = (config: ServerLoggerConfig = {}): Logger => {\n const transportsArr = config.transports?.length\n ? config.transports\n : DEFAULT_SERVER_TRANSPORTS;\n let warnedMissingCustom = false;\n\n const winstonTransports: TransportStream[] = [];\n\n if (transportsArr.includes('console')) {\n winstonTransports.push(\n new transports.Console({\n format: consoleFormat,\n })\n );\n }\n\n const defaultLogPath = config.logPath ?? config.fsPath ?? 'log.txt';\n\n if (transportsArr.includes('fs')) {\n winstonTransports.push(\n new DynamicFileTransport({\n defaultLogPath,\n format: fileLineFormat,\n })\n );\n }\n\n const baseLogger = createWinstonLogger({\n level: 'info',\n transports: winstonTransports.length\n ? winstonTransports\n : [new transports.Console()],\n });\n\n const log = async (eventOrMessage: LogEvent | string, data?: Json) => {\n const event = normalizeEvent(\n eventOrMessage,\n 'info',\n config.source,\n data\n );\n const resolvedLevel = event.level ?? 'info';\n\n const payload = {\n ...event,\n level: resolvedLevel,\n timestamp: event.timestamp ?? Date.now(),\n };\n\n baseLogger.log({\n level: resolvedLevel,\n message: payload.message,\n logEvent: payload,\n });\n\n if (transportsArr.includes('custom')) {\n if (config.addLog) {\n const clean = { ...payload };\n clean.data = cleanObject(clean.data);\n await Promise.resolve(config.addLog(clean));\n } else if (!warnedMissingCustom) {\n warnedMissingCustom = true;\n console.warn(\n '[tim-logger] Custom transport requested without addLog handler.'\n );\n }\n }\n };\n\n const info = async (message: string, data?: Json) =>\n log({\n message,\n level: 'info',\n data,\n source: config.source,\n } as LogEvent);\n\n const warn = async (message: string, data?: Json) =>\n log({\n message,\n level: 'warn',\n data,\n source: config.source,\n } as LogEvent);\n\n const error = async (message: string, data?: Json) =>\n log({\n message,\n level: 'error',\n data,\n source: config.source,\n } as LogEvent);\n\n /**\n * Clears the fs transport logs by truncating the file.\n * No-op if 'fs' transport is not enabled.\n */\n const clearLogs = async (predicate = () => true) => {\n if (transportsArr.includes('fs')) {\n try {\n // Ensure file exists, then truncate.\n await fs\n .mkdir(path.dirname(defaultLogPath), {\n recursive: true,\n })\n .catch(() => {});\n await fs.writeFile(defaultLogPath, '', { flag: 'a' }); // touch\n await fs.truncate(defaultLogPath, 0);\n await info('🧹 Logs cleared', { logPath: defaultLogPath });\n } catch (err) {\n // Don’t throw; log the failure instead.\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n await warn('Failed to clear logs', {\n logPath: defaultLogPath,\n error: msg,\n });\n }\n }\n\n if (transportsArr.includes('custom') && config.clearLogs) {\n await config.clearLogs(predicate);\n }\n };\n\n return { log, info, warn, error, clearLogs };\n};\n\nlet defaultLogger = createServerLogger();\n\nexport const init = (config: ServerLoggerConfig = {}) => {\n defaultLogger = createServerLogger(config);\n return defaultLogger;\n};\n\nexport const log = (eventOrMessage: LogEvent | string, data?: Json) =>\n defaultLogger.log(eventOrMessage, data);\nexport const info = (message: string, data?: Json) =>\n defaultLogger.info(message, data);\nexport const warn = (message: string, data?: Json) =>\n defaultLogger.warn(message, data);\nexport const error = (message: string, data?: Json) =>\n defaultLogger.error(message, data);\nexport const clearLogs = () => defaultLogger.clearLogs?.() ?? Promise.resolve();\nexport { interceptConsoleLogs } from './console-intercept';\n\n// newly added\nlet crashHandlersRegistered = false;\n\nexport function logCrash(type: string, err: unknown) {\n const message =\n err instanceof Error\n ? err.stack || err.message\n : util.format('%o', err);\n void error(`❌ ${type}: ${message}`);\n}\n\nexport function registerCrashHandlers({\n onCrash,\n}: { onCrash?: (err: unknown) => void } = {}) {\n if (crashHandlersRegistered) return;\n crashHandlersRegistered = true;\n\n const handleCrash = (type: string) => (err: unknown) => {\n logCrash(type, err);\n if (typeof onCrash === 'function') {\n try {\n onCrash(err);\n } catch (handlerErr) {\n // FIX: was `log.error(...)` (wrong symbol). Use our logger.\n const msg =\n handlerErr instanceof Error\n ? handlerErr.stack || handlerErr.message\n : util.format('%o', handlerErr);\n void error(`❌ Crash handler failed: ${msg}`);\n }\n }\n };\n\n process.on('uncaughtException', handleCrash('Uncaught Exception'));\n process.on('unhandledRejection', handleCrash('Unhandled Rejection'));\n}\n"],"names":["cleanObject","obj","out","key","value","MESSAGE","getLogPathFromData","data","maybeLogPath","DynamicFileTransport","TransportStream","defaultLogPath","format","info","callback","logPath","path","fs","dir","formatted","message","err","msg","util","fileLineFormat","winstonFormat","entry","timestamp","name","text","dataString","DEFAULT_SERVER_TRANSPORTS","normalizeEvent","eventOrMessage","level","source","stringifyData","consoleFormat","stack","logEvent","verb","contextParts","ctx","kleur","duration","base","createServerLogger","config","transportsArr","warnedMissingCustom","winstonTransports","transports","baseLogger","createWinstonLogger","log","event","resolvedLevel","payload","clean","warn","predicate","clearLogs","defaultLogger","init","error","crashHandlersRegistered","logCrash","type","registerCrashHandlers","onCrash","handleCrash","handlerErr"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"server.es.js","sources":["../src/object.ts","../src/server.ts"],"sourcesContent":["export function cleanObject<T extends Record<string, unknown>>(\n obj?: T\n): Partial<T> {\n if (!obj) return {};\n\n const out: Partial<T> = {};\n for (const [key, value] of Object.entries(obj) as [keyof T, T[keyof T]][]) {\n if (value !== undefined) out[key] = value;\n }\n return out;\n}\n","import kleur from 'kleur';\nimport type { TransformableInfo } from 'logform';\nimport * as fs from 'node:fs/promises';\nimport * as path from 'node:path';\nimport * as util from 'node:util';\nimport {\n createLogger as createWinstonLogger,\n transports,\n format as winstonFormat,\n} from 'winston';\nimport TransportStream from 'winston-transport';\nimport { cleanObject } from './object';\nimport type { Logger, ServerLoggerConfig, ServerTransport } from './types';\n\ntype FileInfo = TransformableInfo & {\n logEvent?: Partial<LogEvent>;\n};\n\nconst MESSAGE = Symbol.for('message');\n\nconst getLogPathFromData = (data?: Json) => {\n if (!data || typeof data !== 'object') return undefined;\n const maybeLogPath = (data as Record<string, unknown>).logPath;\n return typeof maybeLogPath === 'string' && maybeLogPath.length\n ? maybeLogPath\n : undefined;\n};\n\nclass DynamicFileTransport extends TransportStream {\n private defaultLogPath: string;\n private ensuredDirs = new Set<string>();\n private lineFormat: ReturnType<typeof winstonFormat.combine>;\n\n constructor({\n defaultLogPath,\n format,\n }: {\n defaultLogPath: string;\n format: ReturnType<typeof winstonFormat.combine>;\n }) {\n // IMPORTANT: don't pass `format` into super if you're going to transform manually\n super();\n this.defaultLogPath = defaultLogPath;\n this.lineFormat = format;\n }\n\n override log(info: FileInfo, callback: () => void) {\n setImmediate(() => this.emit('logged', info));\n\n const logPath =\n getLogPathFromData(info.logEvent?.data) ?? this.defaultLogPath;\n\n if (!logPath) {\n callback();\n return;\n }\n\n const write = async () => {\n const dir = path.dirname(logPath);\n if (!this.ensuredDirs.has(dir)) {\n this.ensuredDirs.add(dir);\n await fs.mkdir(dir, { recursive: true }).catch(() => {});\n }\n\n // clone because logform formats mutate `info`\n const formatted = this.lineFormat.transform(\n { ...info },\n this.lineFormat.options ?? {}\n ) as FileInfo;\n\n const message =\n (formatted as any)[MESSAGE] ?? formatted.message ?? '';\n\n await fs.appendFile(logPath, `${message}\\n`, 'utf8');\n };\n\n void write()\n .catch((err) => {\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n console.warn('[tim-logger] Failed to write log file', {\n logPath,\n error: msg,\n });\n })\n .finally(callback);\n }\n}\n\nconst fileLineFormat = winstonFormat.combine(\n winstonFormat.timestamp({ format: () => new Date().toISOString() }),\n winstonFormat.printf((info: FileInfo) => {\n const entry = info.logEvent ?? {};\n\n // Use the formatter timestamp (or fallback), instead of generating a new one.\n const timestamp =\n (info.timestamp as string) ?? new Date().toISOString();\n\n const name = String(entry.source ?? 'LOG');\n const text = String(entry.message ?? info.message ?? '');\n\n const data = (entry.data ?? {}) as Record<string, unknown>;\n const dataString =\n data && typeof data === 'object' && Object.keys(data).length\n ? ` | ${JSON.stringify(data)}`\n : '';\n\n return `[${timestamp}] ${name.padStart(12)}: ${text}${dataString}`;\n })\n);\n\nconst DEFAULT_SERVER_TRANSPORTS: ServerTransport[] = ['console'];\n\ntype ConsoleInfo = TransformableInfo & {\n timestamp?: string;\n stack?: string;\n logEvent?: Partial<LogEvent>;\n};\n\nconst normalizeEvent = (\n eventOrMessage: LogEvent | string,\n level?: LogLevel,\n source?: string,\n data?: Json\n): LogEvent => {\n if (typeof eventOrMessage === 'string') {\n return { message: eventOrMessage, level, source, data } as LogEvent;\n }\n\n return {\n ...eventOrMessage,\n level: eventOrMessage.level ?? level,\n source: eventOrMessage.source ?? source,\n data: eventOrMessage.data ?? data,\n };\n};\n\nconst stringifyData = (data?: Json) => {\n if (!data) return '';\n try {\n return JSON.stringify(data);\n } catch {\n return '[unserializable data]';\n }\n};\n\nconst consoleFormat = winstonFormat.combine(\n winstonFormat.timestamp(),\n winstonFormat.errors({ stack: true }),\n winstonFormat.colorize({ all: true }),\n winstonFormat.printf((info: ConsoleInfo) => {\n const {\n timestamp,\n level = 'info',\n message = '',\n stack,\n logEvent,\n } = info;\n\n const entry: Partial<LogEvent> = logEvent ?? {};\n const source = entry.source ?? 'LOG';\n const verb = entry.verb ?? level?.toUpperCase?.() ?? 'LOG';\n\n const contextParts = [entry.machineId, entry.sessionId].filter(Boolean);\n const ctx = contextParts.length\n ? kleur.gray(` [${contextParts.join(' ')}]`)\n : '';\n\n const data = entry.data\n ? kleur.gray(` ${stringifyData(entry.data)}`)\n : '';\n\n const duration =\n typeof entry.duration === 'number'\n ? kleur.yellow(` ${entry.duration}ms`)\n : '';\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${message}${duration}${ctx}${data}`;\n\n return stack ? `${base}\\n${stack}` : base;\n })\n);\n\nexport const createServerLogger = (config: ServerLoggerConfig = {}): Logger => {\n const transportsArr = config.transports?.length\n ? config.transports\n : DEFAULT_SERVER_TRANSPORTS;\n let warnedMissingCustom = false;\n\n const winstonTransports: TransportStream[] = [];\n\n if (transportsArr.includes('console')) {\n winstonTransports.push(\n new transports.Console({\n format: consoleFormat,\n })\n );\n }\n\n const defaultLogPath = config.logPath ?? config.fsPath ?? 'log.txt';\n\n if (transportsArr.includes('fs')) {\n winstonTransports.push(\n new DynamicFileTransport({\n defaultLogPath,\n format: fileLineFormat,\n })\n );\n }\n\n const baseLogger = createWinstonLogger({\n level: 'info',\n transports: winstonTransports.length\n ? winstonTransports\n : [new transports.Console()],\n });\n\n const log = async (eventOrMessage: LogEvent | string, data?: Json) => {\n const event = normalizeEvent(\n eventOrMessage,\n 'info',\n config.source,\n data\n );\n const resolvedLevel = event.level ?? 'info';\n\n const payload = {\n ...event,\n level: resolvedLevel,\n timestamp: event.timestamp ?? Date.now(),\n };\n\n baseLogger.log({\n level: resolvedLevel,\n message: payload.message,\n logEvent: payload,\n });\n\n if (transportsArr.includes('custom')) {\n if (config.addLog) {\n const clean = { ...payload };\n clean.data = cleanObject(clean.data);\n await Promise.resolve(config.addLog(clean));\n } else if (!warnedMissingCustom) {\n warnedMissingCustom = true;\n console.warn(\n '[tim-logger] Custom transport requested without addLog handler.'\n );\n }\n }\n };\n\n const info = async (message: string, data?: Json) =>\n log({\n message,\n level: 'info',\n data,\n source: config.source,\n } as LogEvent);\n\n const warn = async (message: string, data?: Json) =>\n log({\n message,\n level: 'warn',\n data,\n source: config.source,\n } as LogEvent);\n\n const error = async (message: string, data?: Json) =>\n log({\n message,\n level: 'error',\n data,\n source: config.source,\n } as LogEvent);\n\n /**\n * Clears the fs transport logs by truncating the file.\n * No-op if 'fs' transport is not enabled.\n */\n const clearLogs = async (predicate = () => true) => {\n if (transportsArr.includes('fs')) {\n try {\n // Ensure file exists, then truncate.\n await fs\n .mkdir(path.dirname(defaultLogPath), {\n recursive: true,\n })\n .catch(() => {});\n await fs.writeFile(defaultLogPath, '', { flag: 'a' }); // touch\n await fs.truncate(defaultLogPath, 0);\n await info('🧹 Logs cleared', { logPath: defaultLogPath });\n } catch (err) {\n // Don’t throw; log the failure instead.\n const msg =\n err instanceof Error ? err.message : util.format('%o', err);\n await warn('Failed to clear logs', {\n logPath: defaultLogPath,\n error: msg,\n });\n }\n }\n\n if (transportsArr.includes('custom') && config.clearLogs) {\n await config.clearLogs(predicate);\n }\n };\n\n return { log, info, warn, error, clearLogs };\n};\n\nlet defaultLogger = createServerLogger();\n\nexport const init = (config: ServerLoggerConfig = {}) => {\n defaultLogger = createServerLogger(config);\n return defaultLogger;\n};\n\nexport const log = (eventOrMessage: LogEvent | string, data?: Json) =>\n defaultLogger.log(eventOrMessage, data);\nexport const info = (message: string, data?: Json) =>\n defaultLogger.info(message, data);\nexport const warn = (message: string, data?: Json) =>\n defaultLogger.warn(message, data);\nexport const error = (message: string, data?: Json) =>\n defaultLogger.error(message, data);\nexport const clearLogs = () => defaultLogger.clearLogs?.() ?? Promise.resolve();\nexport { interceptConsoleLogs } from './console-intercept';\n\n// newly added\nlet crashHandlersRegistered = false;\n\nexport function logCrash(type: string, err: unknown) {\n const message =\n err instanceof Error\n ? err.stack || err.message\n : util.format('%o', err);\n void error(`❌ ${type}: ${message}`);\n}\n\nexport function registerCrashHandlers({\n onCrash,\n}: { onCrash?: (err: unknown) => void } = {}) {\n if (crashHandlersRegistered) return;\n crashHandlersRegistered = true;\n\n const handleCrash = (type: string) => (err: unknown) => {\n logCrash(type, err);\n if (typeof onCrash === 'function') {\n try {\n onCrash(err);\n } catch (handlerErr) {\n // FIX: was `log.error(...)` (wrong symbol). Use our logger.\n const msg =\n handlerErr instanceof Error\n ? handlerErr.stack || handlerErr.message\n : util.format('%o', handlerErr);\n void error(`❌ Crash handler failed: ${msg}`);\n }\n }\n };\n\n process.on('uncaughtException', handleCrash('Uncaught Exception'));\n process.on('unhandledRejection', handleCrash('Unhandled Rejection'));\n}\n"],"names":["cleanObject","obj","out","key","value","MESSAGE","getLogPathFromData","data","maybeLogPath","DynamicFileTransport","TransportStream","defaultLogPath","format","info","callback","logPath","dir","path","fs","formatted","message","err","msg","util","fileLineFormat","winstonFormat","entry","timestamp","name","text","dataString","DEFAULT_SERVER_TRANSPORTS","normalizeEvent","eventOrMessage","level","source","stringifyData","consoleFormat","stack","logEvent","verb","contextParts","ctx","kleur","duration","base","createServerLogger","config","transportsArr","warnedMissingCustom","winstonTransports","transports","baseLogger","createWinstonLogger","log","event","resolvedLevel","payload","clean","warn","predicate","clearLogs","defaultLogger","init","error","crashHandlersRegistered","logCrash","type","registerCrashHandlers","onCrash","handleCrash","handlerErr"],"mappings":"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"}
|