UNPKG

@farmfe/core

Version:

Farm is a extremely fast web build tool written in Rust. Farm can start a project in milliseconds and perform HMR within 10ms, making it much faster than similar tools like webpack and vite.

189 lines 6.33 kB
import { PersistentCacheBrand, colors } from './color.js'; /* eslint-disable @typescript-eslint/no-explicit-any */ import { pad, version } from './share.js'; var LogLevel; (function (LogLevel) { LogLevel["Trace"] = "trace"; LogLevel["Debug"] = "debug"; LogLevel["Info"] = "info"; LogLevel["Warn"] = "warn"; LogLevel["Error"] = "error"; })(LogLevel || (LogLevel = {})); const LOGGER_METHOD = { info: 'log', warn: 'warn', error: 'error' }; const warnOnceMessages = new Set(); const infoOnceMessages = new Set(); const errorOnceMessages = new Set(); export class Logger { constructor(options, levelValues = { trace: 0, debug: 1, info: 2, warn: 3, error: 4 }, prefix) { this.options = options; this.levelValues = levelValues; this.prefix = prefix; if (!this.options) this.options = {}; this.brandPrefix(); } brandPrefix(color) { const { name = 'Farm' } = this.options; const formattedName = colors.bold(name); const formattedPrefix = colors.bold(`[ ${formattedName} ]`); this.prefix = color ? color(formattedPrefix) : formattedPrefix; } logMessage(level, message, color, showBanner = true) { const loggerMethod = level in LOGGER_METHOD ? LOGGER_METHOD[level] : 'log'; if (this.levelValues[level] <= this.levelValues[level]) { const prefix = showBanner ? this.prefix + ' ' : ''; const loggerMessage = color ? color(prefix + message) : prefix + message; console[loggerMethod](loggerMessage); } } setPrefix(options) { if (options.name) { this.options.name = options.name; this.brandPrefix(options.brandColor); } } trace(message) { this.brandPrefix(colors.green); this.logMessage(LogLevel.Trace, message, colors.magenta); } debug(message) { this.brandPrefix(colors.debugColor); this.logMessage(LogLevel.Debug, message, colors.blue); } info(message, iOptions) { const options = iOptions; if (options) { this.setPrefix(options); } if (!options || !options.brandColor) { this.brandPrefix(colors.brandColor); } this.logMessage(LogLevel.Info, message, null); } warn(message) { this.brandPrefix(colors.yellow); this.logMessage(LogLevel.Warn, message, colors.yellow); } error(message, errorOptions) { this.brandPrefix(colors.red); const effectiveOptions = { ...this.options, ...errorOptions }; const causeError = errorOptions?.e || errorOptions?.error; let error; if (typeof message === 'string') { error = new Error(message); error.stack = ''; } else { error = message; } if (causeError) { error.message += `\nCaused by: ${causeError.stack ?? causeError}`; } this.logMessage(LogLevel.Error, error, colors.red); if (effectiveOptions.exit) { process.exit(1); } } infoOnce(message) { if (!infoOnceMessages.has(message)) { infoOnceMessages.add(message); this.info(message); } } warnOnce(message) { if (!warnOnceMessages.has(message)) { warnOnceMessages.add(message); this.warn(message); } } errorOnce(message) { if (!errorOnceMessages.has(message)) { errorOnceMessages.add(message); this.error(message); } } hasErrorLogged(message) { return errorOnceMessages.has(message); } hasWarnLogged(message) { return warnOnceMessages.has(message); } } // use in test // TODO: impl ILogger export class NoopLogger extends Logger { setPrefix(_options) { } trace(_message) { } debug(_message) { } info(_message, _iOptions) { } warn(_message) { } error(_message, _errorOptions) { if (_errorOptions.exit) { let e = _message instanceof Error ? _message : new Error(_message); if (_errorOptions?.e || _errorOptions?.error) { e.cause = _errorOptions.e || _errorOptions.error; } throw e; } } infoOnce(_message) { } warnOnce(_message) { } errorOnce(_message) { } hasErrorLogged(_message) { return false; } hasWarnLogged(_message) { return false; } } export function printServerUrls(urls, logger, previewFlag = false) { if (previewFlag) logger.info(colors.bold(colors.magenta('preview server running at: \n'))); const colorUrl = (url) => colors.cyan(url.replace(/:(\d+)\//, (_, port) => `:${colors.bold(port)}/`)); const logUrl = (url, type) => logger.info(`${colors.bold(colors.magenta('>'))} ${colors.bold(type)}${colors.bold(colorUrl(url))}`); urls.local.map((url) => logUrl(url, 'Local: ')); urls.network.map((url) => logUrl(url, 'Network: ')); } export function bootstrapLogger(options) { return new Logger(options); } export function bootstrap(times, config) { const usePersistentCache = config.config.persistentCache; const persistentCacheFlag = usePersistentCache ? colors.bold(PersistentCacheBrand) : ''; console.log('\n', colors.bold(colors.brandColor(`${'ϟ'} Farm v${version}`))); console.log(`${colors.bold(colors.green(` ✓`))} ${colors.bold('Ready in')} ${colors.bold(colors.green(`${times}ms`))} ${persistentCacheFlag}`, '\n'); } export const logger = new Logger(); export function buildErrorMessage(err, args = [], includeStack = true) { if (err.plugin) args.push(` Plugin: ${colors.magenta(err.plugin)}`); const loc = err.loc ? `:${err.loc.line}:${err.loc.column}` : ''; if (err.id) args.push(` File: ${colors.cyan(err.id)}${loc}`); if (err.frame) args.push(colors.yellow(pad(err.frame))); if (includeStack && err.stack) args.push(pad(cleanStack(err.stack))); return args.join('\n'); } function cleanStack(stack) { return stack .split(/\n/g) .filter((l) => /^\s*at/.test(l)) .join('\n'); } //# sourceMappingURL=logger.js.map