This release is 2 versions behind 0.8.1 — the latest version of @logtape/logtape. Jump to latest
Built and signed on GitHub ActionsBuilt and signed on GitHub Actions
Built and signed on GitHub Actions
Simple logging library with zero dependencies for Deno/Node.js/Bun/browsers
This package works with Cloudflare Workers, Node.js, Deno, Bun, Browsers




JSR Score
100%
Published
3 months ago (0.7.1)
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328import { assertEquals } from "jsr:/@std/assert@^0.222.1/assert-equals"; import { fatal, info } from "./fixtures.ts"; import { ansiColorFormatter, defaultConsoleFormatter, defaultTextFormatter, type FormattedValues, getAnsiColorFormatter, getTextFormatter, } from "./formatter.ts"; Deno.test("getTextFormatter()", () => { assertEquals( getTextFormatter()(info), "2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "date" })(info), "2023-11-14 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "date-time" })(info), "2023-11-14 22:13:20.000 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "date-time-timezone" })(info), "2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "date-time-tz" })(info), "2023-11-14 22:13:20.000 +00 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "rfc3339" })(info), "2023-11-14T22:13:20.000Z [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "time" })(info), "22:13:20.000 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "time-timezone" })(info), "22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp: "time-tz" })(info), "22:13:20.000 +00 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ timestamp(ts) { const t = new Date(ts); return t.toUTCString(); }, })(info), "Tue, 14 Nov 2023 22:13:20 GMT [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ level: "ABBR" })(info), "2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ level: "FULL" })(info), "2023-11-14 22:13:20.000 +00:00 [INFO] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ level: "L" })(info), "2023-11-14 22:13:20.000 +00:00 [I] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ level: "abbr" })(info), "2023-11-14 22:13:20.000 +00:00 [inf] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ level: "full" })(info), "2023-11-14 22:13:20.000 +00:00 [info] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ level: "l" })(info), "2023-11-14 22:13:20.000 +00:00 [i] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ level(level) { return level.at(-1) ?? ""; }, })(info), "2023-11-14 22:13:20.000 +00:00 [o] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ category: "." })(info), "2023-11-14 22:13:20.000 +00:00 [INF] my-app.junk: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ category(category) { return `<${category.join("/")}>`; }, })(info), "2023-11-14 22:13:20.000 +00:00 [INF] <my-app/junk>: Hello, 123 & 456!\n", ); assertEquals( getTextFormatter({ value(value) { return typeof value; }, })(info), "2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, number & number!\n", ); let recordedValues: FormattedValues | null = null; assertEquals( getTextFormatter({ format(values) { recordedValues = values; const { timestamp, level, category, message } = values; return `${level} <${category}> ${message} ${timestamp}`; }, })(info), "INF <my-app·junk> Hello, 123 & 456! 2023-11-14 22:13:20.000 +00:00\n", ); assertEquals( recordedValues, { timestamp: "2023-11-14 22:13:20.000 +00:00", level: "INF", category: "my-app·junk", message: "Hello, 123 & 456!", record: info, }, ); }); Deno.test("defaultTextFormatter()", () => { assertEquals( defaultTextFormatter(info), "2023-11-14 22:13:20.000 +00:00 [INF] my-app·junk: Hello, 123 & 456!\n", ); assertEquals( defaultTextFormatter(fatal), "2023-11-14 22:13:20.000 +00:00 [FTL] my-app·junk: Hello, 123 & 456!\n", ); }); Deno.test("getAnsiColorFormatter()", () => { assertEquals( getAnsiColorFormatter()(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ timestampStyle: "bold" })(info), "\x1b[1m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ timestampStyle: null })(info), "2023-11-14 22:13:20.000 +00 " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ timestampColor: "cyan" })(info), "\x1b[2m\x1b[36m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ timestampColor: null })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ timestampStyle: null, timestampColor: "cyan" })( info, ), "\x1b[36m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ timestampStyle: null, timestampColor: null })(info), "2023-11-14 22:13:20.000 +00 " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ levelStyle: null })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ levelStyle: "dim" })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[2m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ levelColors: { debug: "blue", info: "cyan", warning: "yellow", error: "red", fatal: "magenta", }, })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[36mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ levelColors: { debug: "blue", info: null, warning: "yellow", error: "red", fatal: "magenta", }, levelStyle: null, })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m INF " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ categoryStyle: "bold" })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[1mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ categoryStyle: null })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "my-app·junk: " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( getAnsiColorFormatter({ categoryColor: "cyan" })(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2m\x1b[36mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); let recordedValues: FormattedValues | null = null; assertEquals( getAnsiColorFormatter({ format(values) { recordedValues = values; const { timestamp, level, category, message } = values; return `${level} <${category}> ${message} ${timestamp}`; }, })(info), "\x1b[1m\x1b[32mINF\x1b[0m " + "<\x1b[2mmy-app·junk\x1b[0m> " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m! " + "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m\n", ); assertEquals( recordedValues, { timestamp: "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m", level: "\x1b[1m\x1b[32mINF\x1b[0m", category: "\x1b[2mmy-app·junk\x1b[0m", message: "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!", record: info, }, ); }); Deno.test("ansiColorFormatter()", () => { assertEquals( ansiColorFormatter(info), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[32mINF\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); assertEquals( ansiColorFormatter(fatal), "\x1b[2m2023-11-14 22:13:20.000 +00\x1b[0m " + "\x1b[1m\x1b[35mFTL\x1b[0m " + "\x1b[2mmy-app·junk:\x1b[0m " + "Hello, \x1b[33m123\x1b[39m & \x1b[33m456\x1b[39m!\n", ); }); Deno.test("defaultConsoleFormatter()", () => { assertEquals( defaultConsoleFormatter(info), [ "%c22:13:20.000 %cINF%c %cmy-app·junk %cHello, %o & %o!", "color: gray;", "background-color: white; color: black;", "background-color: default;", "color: gray;", "color: default;", 123, 456, ], ); });