tim-logger 0.0.39 → 0.0.40
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 +92 -86
- 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"),D=require("node:fs/promises"),
|
|
2
|
-
`,"utf8")})().catch(n=>{const s=n instanceof Error?n.message:
|
|
3
|
-
${a}`:f})),b=(t={})=>{const e=t.transports?.length?t.transports:
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const d=require("kleur"),D=require("node:fs/promises"),_=require("node:path"),k=require("node:util"),l=require("winston"),q=require("winston-transport"),A=require("./console-intercept-CL_BfKQo.cjs");function S(t){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(t){for(const r in t)if(r!=="default"){const o=Object.getOwnPropertyDescriptor(t,r);Object.defineProperty(e,r,o.get?o:{enumerable:!0,get:()=>t[r]})}}return e.default=t,Object.freeze(e)}const h=S(D),j=S(_),w=S(k);function v(t){if(t===void 0)return t;if(Array.isArray(t))return t.filter(r=>r!==void 0).map(r=>v(r));if(t&&typeof t=="object"){const e={};for(const[r,o]of Object.entries(t))o!==void 0&&(e[r]=v(o));return e}return t}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 q{defaultLogPath;ensuredDirs=new Set;lineFormat;constructor({defaultLogPath:e,format:r}){super(),this.defaultLogPath=e,this.lineFormat=r}log(e,r){setImmediate(()=>this.emit("logged",e));const o=x(e.logEvent?.data)??this.defaultLogPath;if(!o){r();return}(async()=>{const n=j.dirname(o);this.ensuredDirs.has(n)||(this.ensuredDirs.add(n),await h.mkdir(n,{recursive:!0}).catch(()=>{}));const s=this.lineFormat.transform({...e},this.lineFormat.options??{}),m=s[T]??s.message??"";await h.appendFile(o,`${m}
|
|
2
|
+
`,"utf8")})().catch(n=>{const s=n instanceof Error?n.message:w.format("%o",n);console.warn("[tim-logger] Failed to write log file",{logPath:o,error:s})}).finally(r)}}const I=l.format.combine(l.format.timestamp({format:()=>new Date().toISOString()}),l.format.printf(t=>{const e=t.logEvent??{},r=t.timestamp??new Date().toISOString(),o=String(e.source??"LOG"),a=String(e.message??t.message??""),n=F(e.data),s=n&&typeof n=="object"&&Object.keys(n).length?` | ${JSON.stringify(n)}`:"";return`[${r}] ${o.padStart(12)}: ${a}${s}`})),H=["console"],G=(t,e,r,o)=>typeof t=="string"?{message:t,level:e,source:r,data:o}:{...t,level:t.level??e,source:t.source??r,data:t.data??o},N=t=>{if(!t)return"";try{return JSON.stringify(t)}catch{return"[unserializable data]"}};function F(t){if(!t||typeof t!="object"||Array.isArray(t)||!("logPath"in t))return t;const{logPath:e,...r}=t;return r}const U=l.format.combine(l.format.timestamp({format:"HH:mm:ss"}),l.format.errors({stack:!0}),l.format.printf(t=>{const{timestamp:e,level:r="info",message:o="",stack:a,logEvent:n}=t,s=n??{},m=s.source??"LOG",p=s.verb??r?.toUpperCase?.()??"LOG",L=[s.machineId,s.sessionId].filter(Boolean),$=L.length?d.gray(` [${L.join(" ")}]`):"",i=F(s.data),c=i?d.gray(` ${N(i)}`):"",u=typeof s.duration=="number"?d.yellow(` ${s.duration}ms`):"",y=typeof o=="string"?o.trimStart():String(o),f=`${e} ${d.bold(`[${m}]`)} ${d.cyan(p)} ${y}${u}${$}${c}`;return a?`${f}
|
|
3
|
+
${a}`:f})),b=(t={})=>{const e=t.transports?.length?t.transports:H;let r=!1;const o=[];e.includes("console")&&o.push(new l.transports.Console({format:U}));const a=t.logPath??t.fsPath??"log.txt";e.includes("fs")&&o.push(new R({defaultLogPath:a,format:I}));const n=l.createLogger({level:"info",transports:o.length?o:[new l.transports.Console]}),s=async(i,c)=>{const u=G(i,"info",t.source,c),y=u.level??"info",f={...u,level:y,timestamp:u.timestamp??Date.now()};if(n.log({level:y,message:f.message,logEvent:f}),e.includes("custom"))if(t.addLog){const C=v({...f});await Promise.resolve(t.addLog(C))}else r||(r=!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 h.mkdir(j.dirname(a),{recursive:!0}).catch(()=>{}),await h.writeFile(a,"",{flag:"a"}),await h.truncate(a,0),await m("🧹 Logs cleared",{logPath:a})}catch(c){const u=c instanceof Error?c.message:w.format("%o",c);await p("Failed to clear logs",{logPath:a,error:u})}e.includes("custom")&&t.clearLogs&&await t.clearLogs(i)}}};let g=b();const z=(t={})=>(g=b(t),g),J=(t,e)=>g.log(t,e),B=(t,e)=>g.info(t,e),V=(t,e)=>g.warn(t,e),P=(t,e)=>g.error(t,e),K=()=>g.clearLogs?.()??Promise.resolve();let E=!1;function O(t,e){const r=e instanceof Error?e.stack||e.message:w.format("%o",e);P(`❌ ${t}: ${r}`)}function M({onCrash:t}={}){if(E)return;E=!0;const e=r=>o=>{if(O(r,o),typeof t=="function")try{t(o)}catch(a){const n=a instanceof Error?a.stack||a.message:w.format("%o",a);P(`❌ Crash handler failed: ${n}`)}};process.on("uncaughtException",e("Uncaught Exception")),process.on("unhandledRejection",e("Unhandled Rejection"))}exports.interceptConsoleLogs=A.interceptConsoleLogs;exports.clearLogs=K;exports.createServerLogger=b;exports.error=P;exports.info=B;exports.init=z;exports.log=J;exports.logCrash=O;exports.registerCrashHandlers=M;exports.warn=V;
|
|
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>(input: T): T {\n if (input === undefined) return input;\n\n // Arrays: clean items and drop undefineds\n if (Array.isArray(input)) {\n const arr = (input as unknown[])\n .filter((v) => v !== undefined)\n .map((v) => cleanObject(v));\n return arr as unknown as T;\n }\n\n // Objects: clean keys recursively, drop undefined values\n if (input && typeof input === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = cleanObject(v);\n }\n return out as unknown as T;\n }\n\n // Primitives / functions / etc: return as-is\n\n return input;\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({ format: 'HH:mm:ss' }),\n winstonFormat.errors({ stack: 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 cleanMessage =\n typeof message === 'string' ? message.trimStart() : String(message);\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${cleanMessage}${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 = cleanObject({ ...payload });\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","input","v","out","k","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","cleanMessage","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>(input: T): T {\n if (input === undefined) return input;\n\n // Arrays: clean items and drop undefineds\n if (Array.isArray(input)) {\n const arr = (input as unknown[])\n .filter((v) => v !== undefined)\n .map((v) => cleanObject(v));\n return arr as unknown as T;\n }\n\n // Objects: clean keys recursively, drop undefined values\n if (input && typeof input === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = cleanObject(v);\n }\n return out as unknown as T;\n }\n\n // Primitives / functions / etc: return as-is\n\n return input;\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 dataForOutput = stripLogPath(entry.data);\n const dataString =\n dataForOutput &&\n typeof dataForOutput === 'object' &&\n Object.keys(dataForOutput as Record<string, unknown>).length\n ? ` | ${JSON.stringify(dataForOutput)}`\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\nfunction stripLogPath(data?: Json): Json | undefined {\n if (!data || typeof data !== 'object' || Array.isArray(data)) return data;\n if (!('logPath' in data)) return data;\n const { logPath: _logPath, ...rest } = data as Record<string, unknown>;\n return rest;\n}\n\nconst consoleFormat = winstonFormat.combine(\n winstonFormat.timestamp({ format: 'HH:mm:ss' }),\n winstonFormat.errors({ stack: 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 dataForOutput = stripLogPath(entry.data);\n const data = dataForOutput\n ? kleur.gray(` ${stringifyData(dataForOutput)}`)\n : '';\n\n const duration =\n typeof entry.duration === 'number'\n ? kleur.yellow(` ${entry.duration}ms`)\n : '';\n\n const cleanMessage =\n typeof message === 'string' ? message.trimStart() : String(message);\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${cleanMessage}${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 = cleanObject({ ...payload });\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","input","v","out","k","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","dataForOutput","stripLogPath","dataString","DEFAULT_SERVER_TRANSPORTS","normalizeEvent","eventOrMessage","level","source","stringifyData","_logPath","rest","consoleFormat","stack","logEvent","verb","contextParts","ctx","kleur","duration","cleanMessage","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;AAyL3E,eAAO,MAAM,kBAAkB,GAAI,SAAQ,kBAAuB,KAAG,MA6HpE,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,28 +1,28 @@
|
|
|
1
|
-
import
|
|
1
|
+
import d from "kleur";
|
|
2
2
|
import * as h from "node:fs/promises";
|
|
3
3
|
import * as b from "node:path";
|
|
4
|
-
import * as
|
|
5
|
-
import { format as m, transports as S, createLogger as
|
|
6
|
-
import
|
|
7
|
-
import { i as
|
|
8
|
-
function
|
|
4
|
+
import * as w from "node:util";
|
|
5
|
+
import { format as m, transports as S, createLogger as x } from "winston";
|
|
6
|
+
import C from "winston-transport";
|
|
7
|
+
import { i as Y } from "./console-intercept-ByhsZ0kO.js";
|
|
8
|
+
function v(t) {
|
|
9
9
|
if (t === void 0) return t;
|
|
10
10
|
if (Array.isArray(t))
|
|
11
|
-
return t.filter((o) => o !== void 0).map((o) =>
|
|
11
|
+
return t.filter((o) => o !== void 0).map((o) => v(o));
|
|
12
12
|
if (t && typeof t == "object") {
|
|
13
13
|
const e = {};
|
|
14
14
|
for (const [o, r] of Object.entries(t))
|
|
15
|
-
r !== void 0 && (e[o] =
|
|
15
|
+
r !== void 0 && (e[o] = v(r));
|
|
16
16
|
return e;
|
|
17
17
|
}
|
|
18
18
|
return t;
|
|
19
19
|
}
|
|
20
|
-
const
|
|
20
|
+
const k = Symbol.for("message"), A = (t) => {
|
|
21
21
|
if (!t || typeof t != "object") return;
|
|
22
22
|
const e = t.logPath;
|
|
23
23
|
return typeof e == "string" && e.length ? e : void 0;
|
|
24
24
|
};
|
|
25
|
-
class
|
|
25
|
+
class O extends C {
|
|
26
26
|
defaultLogPath;
|
|
27
27
|
ensuredDirs = /* @__PURE__ */ new Set();
|
|
28
28
|
lineFormat;
|
|
@@ -34,23 +34,23 @@ class R extends x {
|
|
|
34
34
|
}
|
|
35
35
|
log(e, o) {
|
|
36
36
|
setImmediate(() => this.emit("logged", e));
|
|
37
|
-
const r =
|
|
37
|
+
const r = A(e.logEvent?.data) ?? this.defaultLogPath;
|
|
38
38
|
if (!r) {
|
|
39
39
|
o();
|
|
40
40
|
return;
|
|
41
41
|
}
|
|
42
42
|
(async () => {
|
|
43
|
-
const
|
|
44
|
-
this.ensuredDirs.has(
|
|
43
|
+
const n = b.dirname(r);
|
|
44
|
+
this.ensuredDirs.has(n) || (this.ensuredDirs.add(n), await h.mkdir(n, { recursive: !0 }).catch(() => {
|
|
45
45
|
}));
|
|
46
46
|
const s = this.lineFormat.transform(
|
|
47
47
|
{ ...e },
|
|
48
48
|
this.lineFormat.options ?? {}
|
|
49
|
-
),
|
|
50
|
-
await h.appendFile(r, `${
|
|
49
|
+
), u = s[k] ?? s.message ?? "";
|
|
50
|
+
await h.appendFile(r, `${u}
|
|
51
51
|
`, "utf8");
|
|
52
|
-
})().catch((
|
|
53
|
-
const s =
|
|
52
|
+
})().catch((n) => {
|
|
53
|
+
const s = n instanceof Error ? n.message : w.format("%o", n);
|
|
54
54
|
console.warn("[tim-logger] Failed to write log file", {
|
|
55
55
|
logPath: r,
|
|
56
56
|
error: s
|
|
@@ -58,25 +58,31 @@ class R extends x {
|
|
|
58
58
|
}).finally(o);
|
|
59
59
|
}
|
|
60
60
|
}
|
|
61
|
-
const
|
|
61
|
+
const R = m.combine(
|
|
62
62
|
m.timestamp({ format: () => (/* @__PURE__ */ new Date()).toISOString() }),
|
|
63
63
|
m.printf((t) => {
|
|
64
|
-
const e = t.logEvent ?? {}, o = t.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(), r = String(e.source ?? "LOG"),
|
|
65
|
-
return `[${o}] ${r.padStart(12)}: ${
|
|
64
|
+
const e = t.logEvent ?? {}, o = t.timestamp ?? (/* @__PURE__ */ new Date()).toISOString(), r = String(e.source ?? "LOG"), a = String(e.message ?? t.message ?? ""), n = E(e.data), s = n && typeof n == "object" && Object.keys(n).length ? ` | ${JSON.stringify(n)}` : "";
|
|
65
|
+
return `[${o}] ${r.padStart(12)}: ${a}${s}`;
|
|
66
66
|
})
|
|
67
|
-
),
|
|
67
|
+
), T = ["console"], I = (t, e, o, r) => typeof t == "string" ? { message: t, level: e, source: o, data: r } : {
|
|
68
68
|
...t,
|
|
69
69
|
level: t.level ?? e,
|
|
70
70
|
source: t.source ?? o,
|
|
71
71
|
data: t.data ?? r
|
|
72
|
-
},
|
|
72
|
+
}, G = (t) => {
|
|
73
73
|
if (!t) return "";
|
|
74
74
|
try {
|
|
75
75
|
return JSON.stringify(t);
|
|
76
76
|
} catch {
|
|
77
77
|
return "[unserializable data]";
|
|
78
78
|
}
|
|
79
|
-
}
|
|
79
|
+
};
|
|
80
|
+
function E(t) {
|
|
81
|
+
if (!t || typeof t != "object" || Array.isArray(t) || !("logPath" in t)) return t;
|
|
82
|
+
const { logPath: e, ...o } = t;
|
|
83
|
+
return o;
|
|
84
|
+
}
|
|
85
|
+
const H = m.combine(
|
|
80
86
|
m.timestamp({ format: "HH:mm:ss" }),
|
|
81
87
|
m.errors({ stack: !0 }),
|
|
82
88
|
m.printf((t) => {
|
|
@@ -84,121 +90,121 @@ const A = m.combine(
|
|
|
84
90
|
timestamp: e,
|
|
85
91
|
level: o = "info",
|
|
86
92
|
message: r = "",
|
|
87
|
-
stack:
|
|
88
|
-
logEvent:
|
|
89
|
-
} = t, s =
|
|
93
|
+
stack: a,
|
|
94
|
+
logEvent: n
|
|
95
|
+
} = t, s = n ?? {}, u = s.source ?? "LOG", p = s.verb ?? o?.toUpperCase?.() ?? "LOG", L = [s.machineId, s.sessionId].filter(Boolean), $ = L.length ? d.gray(` [${L.join(" ")}]`) : "", c = E(s.data), i = c ? d.gray(` ${G(c)}`) : "", l = typeof s.duration == "number" ? d.yellow(` ${s.duration}ms`) : "", y = typeof r == "string" ? r.trimStart() : String(r), f = `${e} ${d.bold(`[${u}]`)} ${d.cyan(
|
|
90
96
|
p
|
|
91
|
-
)} ${
|
|
92
|
-
return
|
|
93
|
-
${
|
|
97
|
+
)} ${y}${l}${$}${i}`;
|
|
98
|
+
return a ? `${f}
|
|
99
|
+
${a}` : f;
|
|
94
100
|
})
|
|
95
|
-
),
|
|
96
|
-
const e = t.transports?.length ? t.transports :
|
|
101
|
+
), F = (t = {}) => {
|
|
102
|
+
const e = t.transports?.length ? t.transports : T;
|
|
97
103
|
let o = !1;
|
|
98
104
|
const r = [];
|
|
99
105
|
e.includes("console") && r.push(
|
|
100
106
|
new S.Console({
|
|
101
|
-
format:
|
|
107
|
+
format: H
|
|
102
108
|
})
|
|
103
109
|
);
|
|
104
|
-
const
|
|
110
|
+
const a = t.logPath ?? t.fsPath ?? "log.txt";
|
|
105
111
|
e.includes("fs") && r.push(
|
|
106
|
-
new
|
|
107
|
-
defaultLogPath:
|
|
108
|
-
format:
|
|
112
|
+
new O({
|
|
113
|
+
defaultLogPath: a,
|
|
114
|
+
format: R
|
|
109
115
|
})
|
|
110
116
|
);
|
|
111
|
-
const
|
|
117
|
+
const n = x({
|
|
112
118
|
level: "info",
|
|
113
119
|
transports: r.length ? r : [new S.Console()]
|
|
114
|
-
}), s = async (
|
|
115
|
-
const l =
|
|
116
|
-
|
|
120
|
+
}), s = async (c, i) => {
|
|
121
|
+
const l = I(
|
|
122
|
+
c,
|
|
117
123
|
"info",
|
|
118
124
|
t.source,
|
|
119
|
-
|
|
120
|
-
),
|
|
125
|
+
i
|
|
126
|
+
), y = l.level ?? "info", f = {
|
|
121
127
|
...l,
|
|
122
|
-
level:
|
|
128
|
+
level: y,
|
|
123
129
|
timestamp: l.timestamp ?? Date.now()
|
|
124
130
|
};
|
|
125
|
-
if (
|
|
126
|
-
level:
|
|
127
|
-
message:
|
|
128
|
-
logEvent:
|
|
131
|
+
if (n.log({
|
|
132
|
+
level: y,
|
|
133
|
+
message: f.message,
|
|
134
|
+
logEvent: f
|
|
129
135
|
}), e.includes("custom"))
|
|
130
136
|
if (t.addLog) {
|
|
131
|
-
const D =
|
|
137
|
+
const D = v({ ...f });
|
|
132
138
|
await Promise.resolve(t.addLog(D));
|
|
133
139
|
} else o || (o = !0, console.warn(
|
|
134
140
|
"[tim-logger] Custom transport requested without addLog handler."
|
|
135
141
|
));
|
|
136
|
-
},
|
|
137
|
-
message:
|
|
142
|
+
}, u = async (c, i) => s({
|
|
143
|
+
message: c,
|
|
138
144
|
level: "info",
|
|
139
|
-
data:
|
|
145
|
+
data: i,
|
|
140
146
|
source: t.source
|
|
141
|
-
}), p = async (
|
|
142
|
-
message:
|
|
147
|
+
}), p = async (c, i) => s({
|
|
148
|
+
message: c,
|
|
143
149
|
level: "warn",
|
|
144
|
-
data:
|
|
150
|
+
data: i,
|
|
145
151
|
source: t.source
|
|
146
152
|
});
|
|
147
|
-
return { log: s, info:
|
|
148
|
-
message:
|
|
153
|
+
return { log: s, info: u, warn: p, error: async (c, i) => s({
|
|
154
|
+
message: c,
|
|
149
155
|
level: "error",
|
|
150
|
-
data:
|
|
156
|
+
data: i,
|
|
151
157
|
source: t.source
|
|
152
|
-
}), clearLogs: async (
|
|
158
|
+
}), clearLogs: async (c = () => !0) => {
|
|
153
159
|
if (e.includes("fs"))
|
|
154
160
|
try {
|
|
155
|
-
await h.mkdir(b.dirname(
|
|
161
|
+
await h.mkdir(b.dirname(a), {
|
|
156
162
|
recursive: !0
|
|
157
163
|
}).catch(() => {
|
|
158
|
-
}), await h.writeFile(
|
|
159
|
-
} catch (
|
|
160
|
-
const l =
|
|
164
|
+
}), await h.writeFile(a, "", { flag: "a" }), await h.truncate(a, 0), await u("🧹 Logs cleared", { logPath: a });
|
|
165
|
+
} catch (i) {
|
|
166
|
+
const l = i instanceof Error ? i.message : w.format("%o", i);
|
|
161
167
|
await p("Failed to clear logs", {
|
|
162
|
-
logPath:
|
|
168
|
+
logPath: a,
|
|
163
169
|
error: l
|
|
164
170
|
});
|
|
165
171
|
}
|
|
166
|
-
e.includes("custom") && t.clearLogs && await t.clearLogs(
|
|
172
|
+
e.includes("custom") && t.clearLogs && await t.clearLogs(c);
|
|
167
173
|
} };
|
|
168
174
|
};
|
|
169
|
-
let g =
|
|
170
|
-
const J = (t = {}) => (g =
|
|
171
|
-
let
|
|
172
|
-
function
|
|
173
|
-
const o = e instanceof Error ? e.stack || e.message :
|
|
174
|
-
|
|
175
|
+
let g = F();
|
|
176
|
+
const J = (t = {}) => (g = F(t), g), q = (t, e) => g.log(t, e), B = (t, e) => g.info(t, e), V = (t, e) => g.warn(t, e), j = (t, e) => g.error(t, e), K = () => g.clearLogs?.() ?? Promise.resolve();
|
|
177
|
+
let P = !1;
|
|
178
|
+
function U(t, e) {
|
|
179
|
+
const o = e instanceof Error ? e.stack || e.message : w.format("%o", e);
|
|
180
|
+
j(`❌ ${t}: ${o}`);
|
|
175
181
|
}
|
|
176
|
-
function
|
|
182
|
+
function Q({
|
|
177
183
|
onCrash: t
|
|
178
184
|
} = {}) {
|
|
179
|
-
if (
|
|
180
|
-
|
|
185
|
+
if (P) return;
|
|
186
|
+
P = !0;
|
|
181
187
|
const e = (o) => (r) => {
|
|
182
|
-
if (
|
|
188
|
+
if (U(o, r), typeof t == "function")
|
|
183
189
|
try {
|
|
184
190
|
t(r);
|
|
185
|
-
} catch (
|
|
186
|
-
const
|
|
187
|
-
|
|
191
|
+
} catch (a) {
|
|
192
|
+
const n = a instanceof Error ? a.stack || a.message : w.format("%o", a);
|
|
193
|
+
j(`❌ Crash handler failed: ${n}`);
|
|
188
194
|
}
|
|
189
195
|
};
|
|
190
196
|
process.on("uncaughtException", e("Uncaught Exception")), process.on("unhandledRejection", e("Unhandled Rejection"));
|
|
191
197
|
}
|
|
192
198
|
export {
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
199
|
+
K as clearLogs,
|
|
200
|
+
F as createServerLogger,
|
|
201
|
+
j as error,
|
|
202
|
+
B as info,
|
|
197
203
|
J as init,
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
204
|
+
Y as interceptConsoleLogs,
|
|
205
|
+
q as log,
|
|
206
|
+
U as logCrash,
|
|
207
|
+
Q as registerCrashHandlers,
|
|
208
|
+
V as warn
|
|
203
209
|
};
|
|
204
210
|
//# sourceMappingURL=server.es.js.map
|
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>(input: T): T {\n if (input === undefined) return input;\n\n // Arrays: clean items and drop undefineds\n if (Array.isArray(input)) {\n const arr = (input as unknown[])\n .filter((v) => v !== undefined)\n .map((v) => cleanObject(v));\n return arr as unknown as T;\n }\n\n // Objects: clean keys recursively, drop undefined values\n if (input && typeof input === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = cleanObject(v);\n }\n return out as unknown as T;\n }\n\n // Primitives / functions / etc: return as-is\n\n return input;\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({ format: 'HH:mm:ss' }),\n winstonFormat.errors({ stack: 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 cleanMessage =\n typeof message === 'string' ? message.trimStart() : String(message);\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${cleanMessage}${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 = cleanObject({ ...payload });\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","input","v","out","k","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","cleanMessage","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>(input: T): T {\n if (input === undefined) return input;\n\n // Arrays: clean items and drop undefineds\n if (Array.isArray(input)) {\n const arr = (input as unknown[])\n .filter((v) => v !== undefined)\n .map((v) => cleanObject(v));\n return arr as unknown as T;\n }\n\n // Objects: clean keys recursively, drop undefined values\n if (input && typeof input === 'object') {\n const out: Record<string, unknown> = {};\n for (const [k, v] of Object.entries(input as Record<string, unknown>)) {\n if (v === undefined) continue;\n out[k] = cleanObject(v);\n }\n return out as unknown as T;\n }\n\n // Primitives / functions / etc: return as-is\n\n return input;\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 dataForOutput = stripLogPath(entry.data);\n const dataString =\n dataForOutput &&\n typeof dataForOutput === 'object' &&\n Object.keys(dataForOutput as Record<string, unknown>).length\n ? ` | ${JSON.stringify(dataForOutput)}`\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\nfunction stripLogPath(data?: Json): Json | undefined {\n if (!data || typeof data !== 'object' || Array.isArray(data)) return data;\n if (!('logPath' in data)) return data;\n const { logPath: _logPath, ...rest } = data as Record<string, unknown>;\n return rest;\n}\n\nconst consoleFormat = winstonFormat.combine(\n winstonFormat.timestamp({ format: 'HH:mm:ss' }),\n winstonFormat.errors({ stack: 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 dataForOutput = stripLogPath(entry.data);\n const data = dataForOutput\n ? kleur.gray(` ${stringifyData(dataForOutput)}`)\n : '';\n\n const duration =\n typeof entry.duration === 'number'\n ? kleur.yellow(` ${entry.duration}ms`)\n : '';\n\n const cleanMessage =\n typeof message === 'string' ? message.trimStart() : String(message);\n\n const base = `${timestamp} ${kleur.bold(`[${source}]`)} ${kleur.cyan(\n verb\n )} ${cleanMessage}${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 = cleanObject({ ...payload });\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","input","v","out","k","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","dataForOutput","stripLogPath","dataString","DEFAULT_SERVER_TRANSPORTS","normalizeEvent","eventOrMessage","level","source","stringifyData","_logPath","rest","consoleFormat","stack","logEvent","verb","contextParts","ctx","kleur","duration","cleanMessage","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":";;;;;;;AAAO,SAASA,EAAeC,GAAa;AACxC,MAAIA,MAAU,OAAW,QAAOA;AAGhC,MAAI,MAAM,QAAQA,CAAK;AAInB,WAHaA,EACR,OAAO,CAACC,MAAMA,MAAM,MAAS,EAC7B,IAAI,CAACA,MAAMF,EAAYE,CAAC,CAAC;AAKlC,MAAID,KAAS,OAAOA,KAAU,UAAU;AACpC,UAAME,IAA+B,CAAA;AACrC,eAAW,CAACC,GAAGF,CAAC,KAAK,OAAO,QAAQD,CAAgC;AAChE,MAAIC,MAAM,WACVC,EAAIC,CAAC,IAAIJ,EAAYE,CAAC;AAE1B,WAAOC;AAAA,EACX;AAIA,SAAOF;AACX;ACNA,MAAMI,IAAU,OAAO,IAAI,SAAS,GAE9BC,IAAqB,CAACC,MAAgB;AACxC,MAAI,CAACA,KAAQ,OAAOA,KAAS,SAAU;AACvC,QAAMC,IAAgBD,EAAiC;AACvD,SAAO,OAAOC,KAAiB,YAAYA,EAAa,SAClDA,IACA;AACV;AAEA,MAAMC,UAA6BC,EAAgB;AAAA,EACvC;AAAA,EACA,kCAAkB,IAAA;AAAA,EAClB;AAAA,EAER,YAAY;AAAA,IACR,gBAAAC;AAAA,IACA,QAAAC;AAAA,EAAA,GAID;AAEC,UAAA,GACA,KAAK,iBAAiBD,GACtB,KAAK,aAAaC;AAAA,EACtB;AAAA,EAES,IAAIC,GAAgBC,GAAsB;AAC/C,iBAAa,MAAM,KAAK,KAAK,UAAUD,CAAI,CAAC;AAE5C,UAAME,IACFT,EAAmBO,EAAK,UAAU,IAAI,KAAK,KAAK;AAEpD,QAAI,CAACE,GAAS;AACV,MAAAD,EAAA;AACA;AAAA,IACJ;AAqBA,KAnBc,YAAY;AACtB,YAAME,IAAMC,EAAK,QAAQF,CAAO;AAChC,MAAK,KAAK,YAAY,IAAIC,CAAG,MACzB,KAAK,YAAY,IAAIA,CAAG,GACxB,MAAME,EAAG,MAAMF,GAAK,EAAE,WAAW,GAAA,CAAM,EAAE,MAAM,MAAM;AAAA,MAAC,CAAC;AAI3D,YAAMG,IAAY,KAAK,WAAW;AAAA,QAC9B,EAAE,GAAGN,EAAAA;AAAAA,QACL,KAAK,WAAW,WAAW,CAAA;AAAA,MAAC,GAG1BO,IACDD,EAAkBd,CAAO,KAAKc,EAAU,WAAW;AAExD,YAAMD,EAAG,WAAWH,GAAS,GAAGK,CAAO;AAAA,GAAM,MAAM;AAAA,IACvD,GAEK,EACA,MAAM,CAACC,MAAQ;AACZ,YAAMC,IACFD,aAAe,QAAQA,EAAI,UAAUE,EAAK,OAAO,MAAMF,CAAG;AAC9D,cAAQ,KAAK,yCAAyC;AAAA,QAClD,SAAAN;AAAA,QACA,OAAOO;AAAA,MAAA,CACV;AAAA,IACL,CAAC,EACA,QAAQR,CAAQ;AAAA,EACzB;AACJ;AAEA,MAAMU,IAAiBC,EAAc;AAAA,EACjCA,EAAc,UAAU,EAAE,QAAQ,2BAAU,KAAA,GAAO,YAAA,GAAe;AAAA,EAClEA,EAAc,OAAO,CAACZ,MAAmB;AACrC,UAAMa,IAAQb,EAAK,YAAY,CAAA,GAGzBc,IACDd,EAAK,cAAwB,oBAAI,KAAA,GAAO,YAAA,GAEvCe,IAAO,OAAOF,EAAM,UAAU,KAAK,GACnCG,IAAO,OAAOH,EAAM,WAAWb,EAAK,WAAW,EAAE,GAEjDiB,IAAgBC,EAAaL,EAAM,IAAI,GACvCM,IACFF,KACA,OAAOA,KAAkB,YACzB,OAAO,KAAKA,CAAwC,EAAE,SAChD,MAAM,KAAK,UAAUA,CAAa,CAAC,KACnC;AAEV,WAAO,IAAIH,CAAS,KAAKC,EAAK,SAAS,EAAE,CAAC,KAAKC,CAAI,GAAGG,CAAU;AAAA,EACpE,CAAC;AACL,GAEMC,IAA+C,CAAC,SAAS,GAQzDC,IAAiB,CACnBC,GACAC,GACAC,GACA9B,MAEI,OAAO4B,KAAmB,WACnB,EAAE,SAASA,GAAgB,OAAAC,GAAO,QAAAC,GAAQ,MAAA9B,EAAA,IAG9C;AAAA,EACH,GAAG4B;AAAA,EACH,OAAOA,EAAe,SAASC;AAAA,EAC/B,QAAQD,EAAe,UAAUE;AAAA,EACjC,MAAMF,EAAe,QAAQ5B;AAAA,GAI/B+B,IAAgB,CAAC/B,MAAgB;AACnC,MAAI,CAACA,EAAM,QAAO;AAClB,MAAI;AACA,WAAO,KAAK,UAAUA,CAAI;AAAA,EAC9B,QAAQ;AACJ,WAAO;AAAA,EACX;AACJ;AAEA,SAASwB,EAAaxB,GAA+B;AAEjD,MADI,CAACA,KAAQ,OAAOA,KAAS,YAAY,MAAM,QAAQA,CAAI,KACvD,EAAE,aAAaA,GAAO,QAAOA;AACjC,QAAM,EAAE,SAASgC,GAAU,GAAGC,MAASjC;AACvC,SAAOiC;AACX;AAEA,MAAMC,IAAgBhB,EAAc;AAAA,EAChCA,EAAc,UAAU,EAAE,QAAQ,YAAY;AAAA,EAC9CA,EAAc,OAAO,EAAE,OAAO,IAAM;AAAA,EACpCA,EAAc,OAAO,CAACZ,MAAsB;AACxC,UAAM;AAAA,MACF,WAAAc;AAAA,MACA,OAAAS,IAAQ;AAAA,MACR,SAAAhB,IAAU;AAAA,MACV,OAAAsB;AAAA,MACA,UAAAC;AAAA,IAAA,IACA9B,GAEEa,IAA2BiB,KAAY,CAAA,GACvCN,IAASX,EAAM,UAAU,OACzBkB,IAAOlB,EAAM,QAAQU,GAAO,mBAAmB,OAE/CS,IAAe,CAACnB,EAAM,WAAWA,EAAM,SAAS,EAAE,OAAO,OAAO,GAChEoB,IAAMD,EAAa,SACnBE,EAAM,KAAK,KAAKF,EAAa,KAAK,GAAG,CAAC,GAAG,IACzC,IAEAf,IAAgBC,EAAaL,EAAM,IAAI,GACvCnB,IAAOuB,IACPiB,EAAM,KAAK,IAAIT,EAAcR,CAAa,CAAC,EAAE,IAC7C,IAEAkB,IACF,OAAOtB,EAAM,YAAa,WACpBqB,EAAM,OAAO,IAAIrB,EAAM,QAAQ,IAAI,IACnC,IAEJuB,IACF,OAAO7B,KAAY,WAAWA,EAAQ,UAAA,IAAc,OAAOA,CAAO,GAEhE8B,IAAO,GAAGvB,CAAS,IAAIoB,EAAM,KAAK,IAAIV,CAAM,GAAG,CAAC,IAAIU,EAAM;AAAA,MAC5DH;AAAA,IAAA,CACH,IAAIK,CAAY,GAAGD,CAAQ,GAAGF,CAAG,GAAGvC,CAAI;AAEzC,WAAOmC,IAAQ,GAAGQ,CAAI;AAAA,EAAKR,CAAK,KAAKQ;AAAA,EACzC,CAAC;AACL,GAEaC,IAAqB,CAACC,IAA6B,OAAe;AAC3E,QAAMC,IAAgBD,EAAO,YAAY,SACnCA,EAAO,aACPnB;AACN,MAAIqB,IAAsB;AAE1B,QAAMC,IAAuC,CAAA;AAE7C,EAAIF,EAAc,SAAS,SAAS,KAChCE,EAAkB;AAAA,IACd,IAAIC,EAAW,QAAQ;AAAA,MACnB,QAAQf;AAAA,IAAA,CACX;AAAA,EAAA;AAIT,QAAM9B,IAAiByC,EAAO,WAAWA,EAAO,UAAU;AAE1D,EAAIC,EAAc,SAAS,IAAI,KAC3BE,EAAkB;AAAA,IACd,IAAI9C,EAAqB;AAAA,MACrB,gBAAAE;AAAA,MACA,QAAQa;AAAA,IAAA,CACX;AAAA,EAAA;AAIT,QAAMiC,IAAaC,EAAoB;AAAA,IACnC,OAAO;AAAA,IACP,YAAYH,EAAkB,SACxBA,IACA,CAAC,IAAIC,EAAW,SAAS;AAAA,EAAA,CAClC,GAEKG,IAAM,OAAOxB,GAAmC5B,MAAgB;AAClE,UAAMqD,IAAQ1B;AAAA,MACVC;AAAA,MACA;AAAA,MACAiB,EAAO;AAAA,MACP7C;AAAA,IAAA,GAEEsD,IAAgBD,EAAM,SAAS,QAE/BE,IAAU;AAAA,MACZ,GAAGF;AAAA,MACH,OAAOC;AAAA,MACP,WAAWD,EAAM,aAAa,KAAK,IAAA;AAAA,IAAI;AAS3C,QANAH,EAAW,IAAI;AAAA,MACX,OAAOI;AAAA,MACP,SAASC,EAAQ;AAAA,MACjB,UAAUA;AAAA,IAAA,CACb,GAEGT,EAAc,SAAS,QAAQ;AAC/B,UAAID,EAAO,QAAQ;AACf,cAAMW,IAAQ/D,EAAY,EAAE,GAAG8D,GAAS;AACxC,cAAM,QAAQ,QAAQV,EAAO,OAAOW,CAAK,CAAC;AAAA,MAC9C,MAAA,CAAYT,MACRA,IAAsB,IACtB,QAAQ;AAAA,QACJ;AAAA,MAAA;AAAA,EAIhB,GAEMzC,IAAO,OAAOO,GAAiBb,MACjCoD,EAAI;AAAA,IACA,SAAAvC;AAAA,IACA,OAAO;AAAA,IACP,MAAAb;AAAA,IACA,QAAQ6C,EAAO;AAAA,EAAA,CACN,GAEXY,IAAO,OAAO5C,GAAiBb,MACjCoD,EAAI;AAAA,IACA,SAAAvC;AAAA,IACA,OAAO;AAAA,IACP,MAAAb;AAAA,IACA,QAAQ6C,EAAO;AAAA,EAAA,CACN;AA0CjB,SAAO,EAAE,KAAAO,GAAK,MAAA9C,GAAM,MAAAmD,GAAM,OAxCZ,OAAO5C,GAAiBb,MAClCoD,EAAI;AAAA,IACA,SAAAvC;AAAA,IACA,OAAO;AAAA,IACP,MAAAb;AAAA,IACA,QAAQ6C,EAAO;AAAA,EAAA,CACN,GAkCgB,WA5Bf,OAAOa,IAAY,MAAM,OAAS;AAChD,QAAIZ,EAAc,SAAS,IAAI;AAC3B,UAAI;AAEA,cAAMnC,EACD,MAAMD,EAAK,QAAQN,CAAc,GAAG;AAAA,UACjC,WAAW;AAAA,QAAA,CACd,EACA,MAAM,MAAM;AAAA,QAAC,CAAC,GACnB,MAAMO,EAAG,UAAUP,GAAgB,IAAI,EAAE,MAAM,KAAK,GACpD,MAAMO,EAAG,SAASP,GAAgB,CAAC,GACnC,MAAME,EAAK,mBAAmB,EAAE,SAASF,GAAgB;AAAA,MAC7D,SAASU,GAAK;AAEV,cAAMC,IACFD,aAAe,QAAQA,EAAI,UAAUE,EAAK,OAAO,MAAMF,CAAG;AAC9D,cAAM2C,EAAK,wBAAwB;AAAA,UAC/B,SAASrD;AAAA,UACT,OAAOW;AAAA,QAAA,CACV;AAAA,MACL;AAGJ,IAAI+B,EAAc,SAAS,QAAQ,KAAKD,EAAO,aAC3C,MAAMA,EAAO,UAAUa,CAAS;AAAA,EAExC,EAEiCC;AACrC;AAEA,IAAIC,IAAgBhB,EAAA;AAEb,MAAMiB,IAAO,CAAChB,IAA6B,QAC9Ce,IAAgBhB,EAAmBC,CAAM,GAClCe,IAGER,IAAM,CAACxB,GAAmC5B,MACnD4D,EAAc,IAAIhC,GAAgB5B,CAAI,GAC7BM,IAAO,CAACO,GAAiBb,MAClC4D,EAAc,KAAK/C,GAASb,CAAI,GACvByD,IAAO,CAAC5C,GAAiBb,MAClC4D,EAAc,KAAK/C,GAASb,CAAI,GACvB8D,IAAQ,CAACjD,GAAiBb,MACnC4D,EAAc,MAAM/C,GAASb,CAAI,GACxB2D,IAAY,MAAMC,EAAc,YAAA,KAAiB,QAAQ,QAAA;AAItE,IAAIG,IAA0B;AAEvB,SAASC,EAASC,GAAcnD,GAAc;AACjD,QAAMD,IACFC,aAAe,QACTA,EAAI,SAASA,EAAI,UACjBE,EAAK,OAAO,MAAMF,CAAG;AAC/B,EAAKgD,EAAM,KAAKG,CAAI,KAAKpD,CAAO,EAAE;AACtC;AAEO,SAASqD,EAAsB;AAAA,EAClC,SAAAC;AACJ,IAA0C,IAAI;AAC1C,MAAIJ,EAAyB;AAC7B,EAAAA,IAA0B;AAE1B,QAAMK,IAAc,CAACH,MAAiB,CAACnD,MAAiB;AAEpD,QADAkD,EAASC,GAAMnD,CAAG,GACd,OAAOqD,KAAY;AACnB,UAAI;AACA,QAAAA,EAAQrD,CAAG;AAAA,MACf,SAASuD,GAAY;AAEjB,cAAMtD,IACFsD,aAAsB,QAChBA,EAAW,SAASA,EAAW,UAC/BrD,EAAK,OAAO,MAAMqD,CAAU;AACtC,QAAKP,EAAM,2BAA2B/C,CAAG,EAAE;AAAA,MAC/C;AAAA,EAER;AAEA,UAAQ,GAAG,qBAAqBqD,EAAY,oBAAoB,CAAC,GACjE,QAAQ,GAAG,sBAAsBA,EAAY,qBAAqB,CAAC;AACvE;"}
|