UNPKG

@rivetkit/core

Version:

1 lines 14.3 kB
{"version":3,"sources":["/home/nathan/rivetkit/packages/core/dist/chunk-4KRNEW7D.cjs","../src/common/log-levels.ts","../src/common/logfmt.ts","../src/common/log.ts"],"names":[],"mappings":"AAAA;AACE;AACF,wDAA6B;AAC7B;AACA;ACIO,IAAM,UAAA,EAA0C;AAAA,EACtD,KAAA,EAAO,CAAA;AAAA,EACP,KAAA,EAAO,CAAA;AAAA,EACP,IAAA,EAAM,CAAA;AAAA,EACN,IAAA,EAAM,CAAA;AAAA,EACN,KAAA,EAAO,CAAA;AAAA,EACP,QAAA,EAAU;AACX,CAAA;AAEO,IAAM,aAAA,EAAyC;AAAA,EACrD,CAAA,EAAG,OAAA;AAAA,EACH,CAAA,EAAG,OAAA;AAAA,EACH,CAAA,EAAG,MAAA;AAAA,EACH,CAAA,EAAG,MAAA;AAAA,EACH,CAAA,EAAG,OAAA;AAAA,EACH,CAAA,EAAG;AACJ,CAAA;ADHA;AACA;AEjBA,IAAM,iBAAA,EAA2C;AAAA,EAChD,CAAC,SAAA,CAAU,QAAQ,CAAA,EAAG,UAAA;AAAA;AAAA,EACtB,CAAC,SAAA,CAAU,KAAK,CAAA,EAAG,UAAA;AAAA;AAAA,EACnB,CAAC,SAAA,CAAU,IAAI,CAAA,EAAG,UAAA;AAAA;AAAA,EAClB,CAAC,SAAA,CAAU,IAAI,CAAA,EAAG,UAAA;AAAA;AAAA,EAClB,CAAC,SAAA,CAAU,KAAK,CAAA,EAAG,UAAA;AAAA;AAAA,EACnB,CAAC,SAAA,CAAU,KAAK,CAAA,EAAG;AAAA;AACpB,CAAA;AAEA,IAAM,YAAA,EAAc,SAAA;AAmBb,SAAS,SAAA,CAAA,GAAa,IAAA,EAAkB;AAC9C,EAAA,IAAI,KAAA,EAAO,EAAA;AAEX,EAAA,IAAA,CAAA,IAAS,EAAA,EAAI,CAAA,EAAG,EAAA,EAAI,IAAA,CAAK,MAAA,EAAQ,CAAA,EAAA,EAAK;AACrC,IAAA,MAAM,CAAC,GAAA,EAAK,QAAQ,EAAA,EAAI,IAAA,CAAK,CAAC,CAAA;AAE9B,IAAA,IAAI,OAAA,EAAS,KAAA;AACb,IAAA,IAAI,WAAA;AACJ,IAAA,GAAA,CAAI,SAAA,GAAY,IAAA,EAAM;AACrB,MAAA,OAAA,EAAS,IAAA;AACT,MAAA,YAAA,EAAc,EAAA;AAAA,IACf,EAAA,KAAO;AACN,MAAA,YAAA,EAAc,QAAA,CAAS,QAAA,CAAS,CAAA;AAAA,IACjC;AAGA,IAAA,GAAA,CAAI,WAAA,CAAY,OAAA,EAAS,IAAA,GAAO,IAAA,IAAQ,MAAA,GAAS,IAAA,IAAQ,OAAA;AACxD,MAAA,YAAA,EAAc,CAAA,EAAA;AAET,IAAA;AAEA,IAAA;AAGQ,IAAA;AACV,IAAA;AACA,IAAA;AACA,IAAA;AAEA,IAAA;AAIS,MAAA;AACA,MAAA;AACL,QAAA;AACA,QAAA;AACF,QAAA;AACK,UAAA;AACT,QAAA;AACU,MAAA;AACF,QAAA;AACE,MAAA;AACF,QAAA;AACT,MAAA;AAGQ,MAAA;AACF,IAAA;AAEQ,MAAA;AACf,IAAA;AAEe,IAAA;AACN,MAAA;AACT,IAAA;AACD,EAAA;AAEO,EAAA;AACR;AAEgB;AACG,EAAA;AACJ,EAAA;AACK,EAAA;AACL,EAAA;AACE,EAAA;AACA,EAAA;AACV,EAAA;AAEY,EAAA;AACnB;AAEgB;AAED,EAAA;AAMN,IAAA;AACR,EAAA;AACiB,EAAA;AAED,IAAA;AAChB,EAAA;AACI,EAAA;AACS,IAAA;AACL,EAAA;AACA,IAAA;AACR,EAAA;AACD;AASiD;AACnC,EAAA;AACb,EAAA;AACkB,EAAA;AACnB;AF7BqB;AACA;AGvFD;AACnB,EAAA;AACA,EAAA;AAE0B,EAAA;AACb,IAAA;AACC,IAAA;AACd,EAAA;AAEuB,EAAA;AACI,IAAA;AACpB,MAAA;AACL,MAAA;AACA,MAAA;AACY,MAAA;AACF,MAAA;AACC,MAAA;AACZ,IAAA;AAES,IAAA;AACH,MAAA;AACN,IAAA;AACD,EAAA;AAEuC,EAAA;AACtB,IAAA;AACjB,EAAA;AAEoC,EAAA;AACvB,IAAA;AACb,EAAA;AAE0B,EAAA;AAChB,IAAA;AACV,EAAA;AAE0B,EAAA;AAChB,IAAA;AACV,EAAA;AAEyB,EAAA;AACf,IAAA;AACV,EAAA;AAEyB,EAAA;AACf,IAAA;AACV,EAAA;AAE0B,EAAA;AAChB,IAAA;AACV,EAAA;AAES,EAAA;AACC,IAAA;AACV,EAAA;AACD;AAEyC;AAEf;AACnB,EAAA;AACL,IAAA;AACD,EAAA;AAEM,EAAA;AACW,EAAA;AACA,IAAA;AACjB,EAAA;AACmB,EAAA;AACpB;AAEmB;AACQ,EAAA;AACV,EAAA;AACA,IAAA;AACD,IAAA;AAEF,MAAA;AAEC,QAAA;AAEA,QAAA;AACZ,MAAA;AACM,IAAA;AACS,MAAA;AAChB,IAAA;AACD,EAAA;AAEc,EAAA;AACI,EAAA;AAEX,EAAA;AACQ,IAAA;AACJ,IAAA;AACQ,IAAA;AACH,IAAA;AACZ,IAAA;AACJ,EAAA;AACD;AAE4B;AACb,EAAA;AACf;AAWgB;AAEhB;AHyDqB;AACA;AACA;AACA;AACA;AACA","file":"/home/nathan/rivetkit/packages/core/dist/chunk-4KRNEW7D.cjs","sourcesContent":[null,"export type LogLevel =\n\t| \"TRACE\"\n\t| \"DEBUG\"\n\t| \"INFO\"\n\t| \"WARN\"\n\t| \"ERROR\"\n\t| \"CRITICAL\";\n\nexport const LogLevels: Record<LogLevel, LevelIndex> = {\n\tTRACE: 0,\n\tDEBUG: 1,\n\tINFO: 2,\n\tWARN: 3,\n\tERROR: 4,\n\tCRITICAL: 5,\n} as const;\n\nexport const LevelNameMap: Record<number, LogLevel> = {\n\t0: \"TRACE\",\n\t1: \"DEBUG\",\n\t2: \"INFO\",\n\t3: \"WARN\",\n\t4: \"ERROR\",\n\t5: \"CRITICAL\",\n};\n\nexport type LevelIndex = number;\n","import { type LogLevel, LogLevels } from \"./log-levels\";\n\nexport type LogEntry = [string, LogValue];\nexport type LogValue = string | number | boolean | null | undefined;\n\nconst LOG_LEVEL_COLORS: Record<number, string> = {\n\t[LogLevels.CRITICAL]: \"\\x1b[31m\", // Red\n\t[LogLevels.ERROR]: \"\\x1b[31m\", // Red\n\t[LogLevels.WARN]: \"\\x1b[33m\", // Yellow\n\t[LogLevels.INFO]: \"\\x1b[32m\", // Green\n\t[LogLevels.DEBUG]: \"\\x1b[36m\", // Cyan\n\t[LogLevels.TRACE]: \"\\x1b[36m\", // Cyan\n};\n\nconst RESET_COLOR = \"\\x1b[0m\";\n\n/**\n * Serializes logfmt line using orderer parameters.\n *\n * We use varargs because it's ordered & it has less overhead than an object.\n *\n * ## Styling Methodology\n *\n * The three things you need to know for every log line is the level, the\n * message, and who called it. These properties are highlighted in different colros\n * and sorted in th eorder that you usually read them.\n *\n * Once you've found a log line you care about, then you want to find the\n * property you need to see. The property names are bolded and the default color\n * while the rest of the data is dim. This lets you scan to find the property\n * name quickly then look closer to read the data associated with the\n * property.\n */\nexport function stringify(...data: LogEntry[]) {\n\tlet line = \"\";\n\n\tfor (let i = 0; i < data.length; i++) {\n\t\tconst [key, valueRaw] = data[i];\n\n\t\tlet isNull = false;\n\t\tlet valueString: string;\n\t\tif (valueRaw == null) {\n\t\t\tisNull = true;\n\t\t\tvalueString = \"\";\n\t\t} else {\n\t\t\tvalueString = valueRaw.toString();\n\t\t}\n\n\t\t// Clip value unless specifically the error message\n\t\tif (valueString.length > 512 && key !== \"msg\" && key !== \"error\")\n\t\t\tvalueString = `${valueString.slice(0, 512)}...`;\n\n\t\tconst needsQuoting =\n\t\t\tvalueString.indexOf(\" \") > -1 || valueString.indexOf(\"=\") > -1;\n\t\tconst needsEscaping =\n\t\t\tvalueString.indexOf('\"') > -1 || valueString.indexOf(\"\\\\\") > -1;\n\n\t\tvalueString = valueString.replace(/\\n/g, \"\\\\n\");\n\t\tif (needsEscaping) valueString = valueString.replace(/[\"\\\\]/g, \"\\\\$&\");\n\t\tif (needsQuoting || needsEscaping) valueString = `\"${valueString}\"`;\n\t\tif (valueString === \"\" && !isNull) valueString = '\"\"';\n\n\t\tif (LOGGER_CONFIG.enableColor) {\n\t\t\t// With color\n\n\t\t\t// Special message colors\n\t\t\tlet color = \"\\x1b[2m\";\n\t\t\tif (key === \"level\") {\n\t\t\t\tconst level = LogLevels[valueString as LogLevel];\n\t\t\t\tconst levelColor = LOG_LEVEL_COLORS[level];\n\t\t\t\tif (levelColor) {\n\t\t\t\t\tcolor = levelColor;\n\t\t\t\t}\n\t\t\t} else if (key === \"msg\") {\n\t\t\t\tcolor = \"\\x1b[32m\";\n\t\t\t} else if (key === \"trace\") {\n\t\t\t\tcolor = \"\\x1b[34m\";\n\t\t\t}\n\n\t\t\t// Format line\n\t\t\tline += `\\x1b[0m\\x1b[1m${key}\\x1b[0m\\x1b[2m=\\x1b[0m${color}${valueString}${RESET_COLOR}`;\n\t\t} else {\n\t\t\t// No color\n\t\t\tline += `${key}=${valueString}`;\n\t\t}\n\n\t\tif (i !== data.length - 1) {\n\t\t\tline += \" \";\n\t\t}\n\t}\n\n\treturn line;\n}\n\nexport function formatTimestamp(date: Date): string {\n\tconst year = date.getUTCFullYear();\n\tconst month = String(date.getUTCMonth() + 1).padStart(2, \"0\");\n\tconst day = String(date.getUTCDate()).padStart(2, \"0\");\n\tconst hours = String(date.getUTCHours()).padStart(2, \"0\");\n\tconst minutes = String(date.getUTCMinutes()).padStart(2, \"0\");\n\tconst seconds = String(date.getUTCSeconds()).padStart(2, \"0\");\n\tconst milliseconds = String(date.getUTCMilliseconds()).padStart(3, \"0\");\n\n\treturn `${year}-${month}-${day}T${hours}:${minutes}:${seconds}.${milliseconds}Z`;\n}\n\nexport function castToLogValue(v: unknown): LogValue {\n\tif (\n\t\ttypeof v === \"string\" ||\n\t\ttypeof v === \"number\" ||\n\t\ttypeof v === \"boolean\" ||\n\t\tv === null ||\n\t\tv === undefined\n\t) {\n\t\treturn v;\n\t}\n\tif (v instanceof Error) {\n\t\t//args.push(...errorToLogEntries(k, v));\n\t\treturn String(v);\n\t}\n\ttry {\n\t\treturn JSON.stringify(v);\n\t} catch {\n\t\treturn \"[cannot stringify]\";\n\t}\n}\n\n// MARK: Config\ninterface GlobalLoggerConfig {\n\tenableColor: boolean;\n\tenableSpreadObject: boolean;\n\tenableErrorStack: boolean;\n}\n\nexport const LOGGER_CONFIG: GlobalLoggerConfig = {\n\tenableColor: false,\n\tenableSpreadObject: false,\n\tenableErrorStack: false,\n};\n\n// MARK: Utils\n/**\n * Converts an object in to an easier to read KV of entries.\n */\nexport function spreadObjectToLogEntries(\n\tbase: string,\n\tdata: unknown,\n): LogEntry[] {\n\tif (\n\t\tLOGGER_CONFIG.enableSpreadObject &&\n\t\ttypeof data === \"object\" &&\n\t\t!Array.isArray(data) &&\n\t\tdata !== null &&\n\t\tObject.keys(data).length !== 0 &&\n\t\tObject.keys(data).length < 16\n\t) {\n\t\tconst logData: LogEntry[] = [];\n\t\tfor (const key in data) {\n\t\t\t// logData.push([`${base}.${key}`, JSON.stringify((data as any)[key])]);\n\n\t\t\tlogData.push(\n\t\t\t\t...spreadObjectToLogEntries(\n\t\t\t\t\t`${base}.${key}`,\n\t\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: FIXME\n\t\t\t\t\t(data as any)[key],\n\t\t\t\t),\n\t\t\t);\n\t\t}\n\t\treturn logData;\n\t}\n\n\treturn [[base, JSON.stringify(data)]];\n}\n\nexport function errorToLogEntries(base: string, error: unknown): LogEntry[] {\n\tif (error instanceof Error) {\n\t\treturn [\n\t\t\t//[`${base}.name`, error.name],\n\t\t\t[`${base}.message`, error.message],\n\t\t\t...(LOGGER_CONFIG.enableErrorStack && error.stack\n\t\t\t\t? [[`${base}.stack`, formatStackTrace(error.stack)] as LogEntry]\n\t\t\t\t: []),\n\t\t\t...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : []),\n\t\t];\n\t}\n\treturn [[base, `${error}`]];\n}\n\n// export function errorToLogEntries(base: string, error: unknown): LogEntry[] {\n// \tif (error instanceof RuntimeError) {\n// \t\treturn [\n// \t\t\t[`${base}.code`, error.code],\n// \t\t\t[`${base}.description`, error.errorConfig?.description],\n// \t\t\t[`${base}.module`, error.moduleName],\n// \t\t\t...(error.trace ? [[`${base}.trace`, stringifyTrace(error.trace)] as LogEntry] : []),\n// \t\t\t...(LOGGER_CONFIG.enableErrorStack && error.stack\n// \t\t\t\t? [[`${base}.stack`, formatStackTrace(error.stack)] as LogEntry]\n// \t\t\t\t: []),\n// \t\t\t...(error.meta ? [[`${base}.meta`, JSON.stringify(error.meta)] as LogEntry] : []),\n// \t\t\t...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : []),\n// \t\t];\n// \t} else if (error instanceof Error) {\n// \t\treturn [\n// \t\t\t[`${base}.name`, error.name],\n// \t\t\t[`${base}.message`, error.message],\n// \t\t\t...(LOGGER_CONFIG.enableErrorStack && error.stack\n// \t\t\t\t? [[`${base}.stack`, formatStackTrace(error.stack)] as LogEntry]\n// \t\t\t\t: []),\n// \t\t\t...(error.cause ? errorToLogEntries(`${base}.cause`, error.cause) : []),\n// \t\t];\n// \t} else {\n// \t\treturn [\n// \t\t\t[base, `${error}`],\n// \t\t];\n// \t}\n// }\n\n/**\n * Formats a JS stack trace in to a legible one-liner.\n */\nfunction formatStackTrace(stackTrace: string): string {\n\tconst regex = /at (.+?)$/gm;\n\tconst matches = [...stackTrace.matchAll(regex)];\n\t// Reverse array since the stack goes from top level -> bottom level\n\tmatches.reverse();\n\treturn matches.map((match) => match[1].trim()).join(\" > \");\n}\n","import { getEnvUniversal } from \"@/utils\";\nimport {\n\ttype LevelIndex,\n\tLevelNameMap,\n\ttype LogLevel,\n\tLogLevels,\n} from \"./log-levels\";\nimport {\n\tcastToLogValue,\n\tformatTimestamp,\n\ttype LogEntry,\n\tstringify,\n} from \"./logfmt\";\n\ninterface LogRecord {\n\targs: unknown[];\n\tdatetime: Date;\n\tlevel: number;\n\tlevelName: string;\n\tloggerName: string;\n\tmsg: string;\n}\n\nexport class Logger {\n\tname: string;\n\tlevel: LogLevel;\n\n\tconstructor(name: string, level: LogLevel) {\n\t\tthis.name = name;\n\t\tthis.level = level;\n\t}\n\n\tlog(level: LevelIndex, message: string, ...args: unknown[]): void {\n\t\tconst record: LogRecord = {\n\t\t\tmsg: message,\n\t\t\targs,\n\t\t\tlevel,\n\t\t\tloggerName: this.name,\n\t\t\tdatetime: new Date(),\n\t\t\tlevelName: LevelNameMap[level],\n\t\t};\n\n\t\tif (this.#shouldLog(level)) {\n\t\t\tthis.#logRecord(record);\n\t\t}\n\t}\n\n\t#shouldLog(level: LevelIndex): boolean {\n\t\treturn level >= LogLevels[this.level];\n\t}\n\n\t#logRecord(record: LogRecord): void {\n\t\tconsole.log(formatter(record));\n\t}\n\n\ttrace(message: string, ...args: unknown[]): void {\n\t\tthis.log(LogLevels.TRACE, message, ...args);\n\t}\n\n\tdebug(message: string, ...args: unknown[]): void {\n\t\tthis.log(LogLevels.DEBUG, message, ...args);\n\t}\n\n\tinfo(message: string, ...args: unknown[]): void {\n\t\tthis.log(LogLevels.INFO, message, ...args);\n\t}\n\n\twarn(message: string, ...args: unknown[]): void {\n\t\tthis.log(LogLevels.WARN, message, ...args);\n\t}\n\n\terror(message: string, ...args: unknown[]): void {\n\t\tthis.log(LogLevels.ERROR, message, ...args);\n\t}\n\n\tcritical(message: string, ...args: unknown[]): void {\n\t\tthis.log(LogLevels.CRITICAL, message, ...args);\n\t}\n}\n\nconst loggers: Record<string, Logger> = {};\n\nexport function getLogger(name = \"default\"): Logger {\n\tconst defaultLogLevelEnv: LogLevel | undefined = getEnvUniversal(\n\t\t\"_LOG_LEVEL\",\n\t) as LogLevel | undefined;\n\n\tconst defaultLogLevel: LogLevel = defaultLogLevelEnv ?? \"INFO\";\n\tif (!loggers[name]) {\n\t\tloggers[name] = new Logger(name, defaultLogLevel);\n\t}\n\treturn loggers[name];\n}\n\nfunction formatter(log: LogRecord): string {\n\tconst args: LogEntry[] = [];\n\tfor (let i = 0; i < log.args.length; i++) {\n\t\tconst logArg = log.args[i];\n\t\tif (logArg && typeof logArg === \"object\") {\n\t\t\t// Spread object\n\t\t\tfor (const k in logArg) {\n\t\t\t\t// biome-ignore lint/suspicious/noExplicitAny: Unknown type\n\t\t\t\tconst v = (logArg as any)[k];\n\n\t\t\t\tpushArg(k, v, args);\n\t\t\t}\n\t\t} else {\n\t\t\tpushArg(`arg${i}`, logArg, args);\n\t\t}\n\t}\n\n\tconst logTs = getEnvUniversal(\"_LOG_TIMESTAMP\") === \"1\";\n\tconst logTarget = getEnvUniversal(\"_LOG_TARGET\") === \"1\";\n\n\treturn stringify(\n\t\t...(logTs ? [[\"ts\", formatTimestamp(new Date())] as LogEntry] : []),\n\t\t[\"level\", LevelNameMap[log.level]],\n\t\t...(logTarget ? [[\"target\", log.loggerName] as LogEntry] : []),\n\t\t[\"msg\", log.msg],\n\t\t...args,\n\t);\n}\n\nfunction pushArg(k: string, v: unknown, args: LogEntry[]) {\n\targs.push([k, castToLogValue(v)]);\n}\n\n// function getEnv(name: string): string | undefined {\n// \tif (typeof window !== \"undefined\" && window.localStorage) {\n// \t\treturn window.localStorage.getItem(name) || undefined;\n// \t}\n// \treturn undefined;\n// \t// TODO(ACTR-9): Add back env config once node compat layer works\n// \t//return crossGetEnv(name);\n// }\n\nexport function setupLogging() {\n\t// Do nothing for now\n}\n"]}