UNPKG

weavebot-core

Version:

Generic content processing framework for web scraping and AI extraction

1 lines 12.6 kB
{"version":3,"sources":["../src/utils/index.ts"],"sourcesContent":["import { Logger as LoggerInterface, LogContext } from '../types';\n\nexport enum LogLevel {\n DEBUG = 0,\n INFO = 1,\n WARN = 2,\n ERROR = 3,\n}\n\nexport interface LogEntry {\n timestamp: string;\n level: LogLevel;\n message: string;\n context?: LogContext;\n error?: Error;\n}\n\nexport class Logger implements LoggerInterface {\n private logLevel: LogLevel;\n\n constructor(level: string = 'info') {\n this.logLevel = this.parseLogLevel(level);\n \n // Configure console output for different environments\n if (process.env.NODE_ENV === 'production') {\n // In production, use structured JSON logging\n this.setupProductionLogging();\n }\n }\n\n private parseLogLevel(level: string): LogLevel {\n switch (level.toLowerCase()) {\n case 'debug': return LogLevel.DEBUG;\n case 'info': return LogLevel.INFO;\n case 'warn': return LogLevel.WARN;\n case 'error': return LogLevel.ERROR;\n default: return LogLevel.INFO;\n }\n }\n\n private setupProductionLogging() {\n // Override console methods for structured logging in production\n const originalLog = console.log;\n const originalWarn = console.warn;\n const originalError = console.error;\n\n console.log = (...args) => {\n if (typeof args[0] === 'object' && args[0].level !== undefined) {\n originalLog(JSON.stringify(args[0]));\n } else {\n originalLog(...args);\n }\n };\n\n console.warn = (...args) => {\n if (typeof args[0] === 'object' && args[0].level !== undefined) {\n originalWarn(JSON.stringify(args[0]));\n } else {\n originalWarn(...args);\n }\n };\n\n console.error = (...args) => {\n if (typeof args[0] === 'object' && args[0].level !== undefined) {\n originalError(JSON.stringify(args[0]));\n } else {\n originalError(...args);\n }\n };\n }\n\n private shouldLog(level: LogLevel): boolean {\n return level >= this.logLevel;\n }\n\n private createLogEntry(level: LogLevel, message: string, context?: LogContext, error?: Error): LogEntry {\n return {\n timestamp: new Date().toISOString(),\n level,\n message,\n context: context ? this.sanitizeContext(context) : undefined,\n error: error ? {\n name: error.name,\n message: error.message,\n stack: error.stack\n } as any : undefined\n };\n }\n\n private sanitizeContext(context: LogContext): LogContext {\n const sanitized = { ...context };\n \n // Remove sensitive information\n const sensitiveKeys = ['password', 'token', 'key', 'secret', 'apikey'];\n \n Object.keys(sanitized).forEach(key => {\n if (sensitiveKeys.some(sensitive => key.toLowerCase().includes(sensitive))) {\n sanitized[key] = '[REDACTED]';\n }\n });\n\n return sanitized;\n }\n\n private formatLogEntry(entry: LogEntry): string {\n const levelNames = {\n [LogLevel.DEBUG]: 'DEBUG',\n [LogLevel.INFO]: 'INFO',\n [LogLevel.WARN]: 'WARN',\n [LogLevel.ERROR]: 'ERROR'\n };\n\n let formatted = `[${entry.timestamp}] ${levelNames[entry.level]}: ${entry.message}`;\n \n if (entry.context && Object.keys(entry.context).length > 0) {\n formatted += ` | Context: ${JSON.stringify(entry.context)}`;\n }\n \n if (entry.error) {\n formatted += ` | Error: ${entry.error.message}`;\n if (entry.error.stack && this.logLevel === LogLevel.DEBUG) {\n formatted += `\\nStack: ${entry.error.stack}`;\n }\n }\n\n return formatted;\n }\n\n private output(entry: LogEntry) {\n if (process.env.NODE_ENV === 'production') {\n // Structured logging for production\n const structuredLog = {\n timestamp: entry.timestamp,\n level: entry.level,\n message: entry.message,\n ...entry.context,\n error: entry.error\n };\n\n switch (entry.level) {\n case LogLevel.ERROR:\n console.error(structuredLog);\n break;\n case LogLevel.WARN:\n console.warn(structuredLog);\n break;\n default:\n console.log(structuredLog);\n }\n } else {\n // Human-readable logging for development\n const formatted = this.formatLogEntry(entry);\n \n switch (entry.level) {\n case LogLevel.ERROR:\n console.error(`\\x1b[31m${formatted}\\x1b[0m`); // Red\n break;\n case LogLevel.WARN:\n console.warn(`\\x1b[33m${formatted}\\x1b[0m`); // Yellow\n break;\n case LogLevel.INFO:\n console.log(`\\x1b[36m${formatted}\\x1b[0m`); // Cyan\n break;\n case LogLevel.DEBUG:\n console.log(`\\x1b[90m${formatted}\\x1b[0m`); // Gray\n break;\n }\n }\n }\n\n debug(message: string, context?: LogContext) {\n if (this.shouldLog(LogLevel.DEBUG)) {\n const entry = this.createLogEntry(LogLevel.DEBUG, message, context);\n this.output(entry);\n }\n }\n\n info(message: string, context?: LogContext) {\n if (this.shouldLog(LogLevel.INFO)) {\n const entry = this.createLogEntry(LogLevel.INFO, message, context);\n this.output(entry);\n }\n }\n\n warn(message: string, context?: LogContext) {\n if (this.shouldLog(LogLevel.WARN)) {\n const entry = this.createLogEntry(LogLevel.WARN, message, context);\n this.output(entry);\n }\n }\n\n error(message: string, contextOrError?: LogContext | Error, error?: Error) {\n if (this.shouldLog(LogLevel.ERROR)) {\n let context: LogContext | undefined;\n let actualError: Error | undefined;\n\n if (contextOrError instanceof Error) {\n actualError = contextOrError;\n } else {\n context = contextOrError;\n actualError = error;\n }\n\n const entry = this.createLogEntry(LogLevel.ERROR, message, context, actualError);\n this.output(entry);\n }\n }\n\n // Performance logging utility\n time(label: string, context?: LogContext): () => void {\n const startTime = Date.now();\n \n this.debug(`Timer started: ${label}`, context);\n \n return () => {\n const duration = Date.now() - startTime;\n this.info(`Timer ended: ${label}`, { ...context, duration });\n };\n }\n}\n\n// Create default logger instance\nexport const createLogger = (level?: string): Logger => {\n return new Logger(level || process.env.LOG_LEVEL || 'info');\n};\n\n// Default logger instance\nexport const defaultLogger = createLogger();\n\n// Utility functions\nexport const isValidUrl = (string: string): boolean => {\n try {\n new URL(string);\n return true;\n } catch (_) {\n return false;\n }\n};\n\nexport const sanitizeInput = (input: string): string => {\n // Basic sanitization to prevent injection attacks\n return input\n .replace(/[<>]/g, '') // Remove potential HTML tags\n .replace(/javascript:/gi, '') // Remove javascript: protocols\n .trim();\n};\n\nexport const sleep = (ms: number): Promise<void> => {\n return new Promise(resolve => setTimeout(resolve, ms));\n};\n\nexport const retry = async <T>(\n fn: () => Promise<T>,\n retries: number = 3,\n delay: number = 1000\n): Promise<T> => {\n try {\n return await fn();\n } catch (error) {\n if (retries > 0) {\n await sleep(delay);\n return retry(fn, retries - 1, delay * 2); // Exponential backoff\n }\n throw error;\n }\n};\n\nexport const formatDuration = (ms: number): string => {\n if (ms < 1000) return `${ms}ms`;\n if (ms < 60000) return `${(ms / 1000).toFixed(1)}s`;\n return `${(ms / 60000).toFixed(1)}m`;\n};\n\nexport const truncateText = (text: string, maxLength: number = 100): string => {\n if (text.length <= maxLength) return text;\n return text.substring(0, maxLength - 3) + '...';\n};"],"mappings":"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","names":["LogLevel"]}