@meadown/logger 1.2.0 → 1.3.0
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/README.md +20 -14
- package/dist/cjs/utils/color.d.ts +23 -0
- package/dist/cjs/utils/color.js +38 -0
- package/dist/cjs/utils/createLog.js +13 -2
- package/dist/cjs/utils/index.d.ts +1 -0
- package/dist/cjs/utils/index.js +4 -1
- package/dist/cjs/utils/link.d.ts +12 -8
- package/dist/cjs/utils/link.js +14 -33
- package/dist/utils/color.d.ts +24 -0
- package/dist/utils/color.d.ts.map +1 -0
- package/dist/utils/color.js +35 -0
- package/dist/utils/color.js.map +1 -0
- package/dist/utils/createLog.d.ts.map +1 -1
- package/dist/utils/createLog.js +13 -2
- package/dist/utils/createLog.js.map +1 -1
- package/dist/utils/index.d.ts +1 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/link.d.ts +12 -8
- package/dist/utils/link.d.ts.map +1 -1
- package/dist/utils/link.js +14 -33
- package/dist/utils/link.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@ remember _which file_ a message came from — and worse, forgetting to pull thos
|
|
|
5
5
|
out before shipping. So I made this.
|
|
6
6
|
|
|
7
7
|
It's basically `console.log` with the rough edges sanded off: every message gets a
|
|
8
|
-
level tag, a timestamp, and
|
|
9
|
-
|
|
10
|
-
not worry about them.
|
|
8
|
+
**color-coded** level tag, a timestamp, and the file and line it came from — as a
|
|
9
|
+
**clickable link** you can open straight from your terminal. And it stays quiet in
|
|
10
|
+
production, so you can leave your logs where they are and not worry about them.
|
|
11
11
|
|
|
12
12
|
No dependencies. No config. Import it and you're done.
|
|
13
13
|
|
|
@@ -39,21 +39,27 @@ Auth user logged in
|
|
|
39
39
|
Each line is tagged by level — `[INFO]`, `[WARN]`, or `[ERROR]` — followed by the
|
|
40
40
|
timestamp and the source location, with your arguments on the next line.
|
|
41
41
|
|
|
42
|
-
##
|
|
42
|
+
## Color-coded levels
|
|
43
43
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
44
|
+
The level tag is colored so you can spot what matters at a glance — `[INFO]` in
|
|
45
|
+
cyan, `[WARN]` in yellow, `[ERROR]` in red. The timestamp and location stay plain so
|
|
46
|
+
the color draws your eye straight to the level.
|
|
47
47
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
48
|
+
Colors appear automatically when you're in a terminal. When output is piped to a
|
|
49
|
+
file or another program, the tag prints as plain `[INFO]` text — no stray color
|
|
50
|
+
codes in your log files. Nothing to configure.
|
|
51
51
|
|
|
52
|
-
|
|
52
|
+
## Click to open the source
|
|
53
53
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
That `(server.ts:42)` at the end of every log isn't just text — when you're in a
|
|
55
|
+
terminal, it's a **clickable link** that opens the file the log came from. No more
|
|
56
|
+
hunting for where a message came from, and the line number is right there in the
|
|
57
|
+
label.
|
|
58
|
+
|
|
59
|
+
There's nothing to configure. Links show up automatically when output goes to a
|
|
60
|
+
terminal, and when it's piped to a file or another program they quietly drop to
|
|
61
|
+
plain `(server.ts:42)` text — so your log files never get cluttered with escape
|
|
62
|
+
codes.
|
|
57
63
|
|
|
58
64
|
## What about production?
|
|
59
65
|
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/** ANSI SGR codes for the colors/styles the logger uses. */
|
|
2
|
+
declare const CODES: {
|
|
3
|
+
readonly red: 31;
|
|
4
|
+
readonly yellow: 33;
|
|
5
|
+
readonly cyan: 36;
|
|
6
|
+
readonly dim: 2;
|
|
7
|
+
};
|
|
8
|
+
/** The named colors/styles {@link colorize} understands. */
|
|
9
|
+
export type Color = keyof typeof CODES;
|
|
10
|
+
/**
|
|
11
|
+
* Wraps `text` in the ANSI escape codes for `color`, resetting afterwards.
|
|
12
|
+
* Pure string work — deciding *whether* to colorize is {@link supportsColor}'s
|
|
13
|
+
* job, kept separate so callers control it per stream.
|
|
14
|
+
*/
|
|
15
|
+
export declare function colorize(text: string, color: Color): string;
|
|
16
|
+
/**
|
|
17
|
+
* Whether to emit ANSI colors for the given stream. Driven solely by the stream
|
|
18
|
+
* being an interactive terminal (`isTTY`) — no env vars, no config. When output
|
|
19
|
+
* is piped or redirected, colors are skipped so escape codes never end up in
|
|
20
|
+
* files or logs.
|
|
21
|
+
*/
|
|
22
|
+
export declare function supportsColor(streamName: "stdout" | "stderr"): boolean;
|
|
23
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/*
|
|
3
|
+
* color.ts
|
|
4
|
+
* Created by Dewan Mobashirul
|
|
5
|
+
* Copyright (c) 2026 dewan-meadown
|
|
6
|
+
* All rights reserved
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.colorize = colorize;
|
|
10
|
+
exports.supportsColor = supportsColor;
|
|
11
|
+
/** ANSI SGR codes for the colors/styles the logger uses. */
|
|
12
|
+
const CODES = {
|
|
13
|
+
red: 31,
|
|
14
|
+
yellow: 33,
|
|
15
|
+
cyan: 36,
|
|
16
|
+
dim: 2,
|
|
17
|
+
};
|
|
18
|
+
const RESET = "\x1b[0m";
|
|
19
|
+
/**
|
|
20
|
+
* Wraps `text` in the ANSI escape codes for `color`, resetting afterwards.
|
|
21
|
+
* Pure string work — deciding *whether* to colorize is {@link supportsColor}'s
|
|
22
|
+
* job, kept separate so callers control it per stream.
|
|
23
|
+
*/
|
|
24
|
+
function colorize(text, color) {
|
|
25
|
+
return `\x1b[${CODES[color]}m${text}${RESET}`;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether to emit ANSI colors for the given stream. Driven solely by the stream
|
|
29
|
+
* being an interactive terminal (`isTTY`) — no env vars, no config. When output
|
|
30
|
+
* is piped or redirected, colors are skipped so escape codes never end up in
|
|
31
|
+
* files or logs.
|
|
32
|
+
*/
|
|
33
|
+
function supportsColor(streamName) {
|
|
34
|
+
if (typeof process === "undefined")
|
|
35
|
+
return false;
|
|
36
|
+
const stream = streamName === "stdout" ? process.stdout : process.stderr;
|
|
37
|
+
return Boolean(stream?.isTTY);
|
|
38
|
+
}
|
|
@@ -13,7 +13,14 @@ exports.default = createLog;
|
|
|
13
13
|
const getCaller_js_1 = __importDefault(require("./getCaller.js"));
|
|
14
14
|
const getTimeStamp_js_1 = __importDefault(require("./getTimeStamp.js"));
|
|
15
15
|
const link_js_1 = require("./link.js");
|
|
16
|
+
const color_js_1 = require("./color.js");
|
|
16
17
|
const config_js_1 = require("../config.js");
|
|
18
|
+
/** The tag color for each channel: info → cyan, warn → yellow, error → red. */
|
|
19
|
+
const TAG_COLOR = {
|
|
20
|
+
log: "cyan",
|
|
21
|
+
warn: "yellow",
|
|
22
|
+
error: "red",
|
|
23
|
+
};
|
|
17
24
|
/**
|
|
18
25
|
* Renders a caller as a `(file:line)` location. When the terminal supports
|
|
19
26
|
* OSC-8 hyperlinks, the location is a clickable link to the exact source line;
|
|
@@ -24,7 +31,7 @@ function formatLocation(caller, streamName) {
|
|
|
24
31
|
if (caller.file !== null &&
|
|
25
32
|
caller.line !== null &&
|
|
26
33
|
(0, link_js_1.supportsHyperlinks)(streamName))
|
|
27
|
-
return (0, link_js_1.hyperlink)(caller.label, (0, link_js_1.fileUrl)(caller.file
|
|
34
|
+
return (0, link_js_1.hyperlink)(caller.label, (0, link_js_1.fileUrl)(caller.file));
|
|
28
35
|
return caller.label;
|
|
29
36
|
}
|
|
30
37
|
/**
|
|
@@ -41,6 +48,10 @@ function createLog(channel, tag) {
|
|
|
41
48
|
return;
|
|
42
49
|
const caller = (0, getCaller_js_1.default)();
|
|
43
50
|
const location = formatLocation(caller, streamName);
|
|
44
|
-
|
|
51
|
+
// Color only the level tag, and only on a real terminal.
|
|
52
|
+
const tagOut = (0, color_js_1.supportsColor)(streamName)
|
|
53
|
+
? (0, color_js_1.colorize)(tag, TAG_COLOR[channel])
|
|
54
|
+
: tag;
|
|
55
|
+
console[channel](tagOut, (0, getTimeStamp_js_1.default)(), `(${location})`, `\n`, ...args, `\n`);
|
|
45
56
|
};
|
|
46
57
|
}
|
|
@@ -2,3 +2,4 @@ export { default as createLog, type LogChannel } from "./createLog.js";
|
|
|
2
2
|
export { default as getCaller, type Caller } from "./getCaller.js";
|
|
3
3
|
export { default as getTimeStamp } from "./getTimeStamp.js";
|
|
4
4
|
export { fileUrl, hyperlink, supportsHyperlinks } from "./link.js";
|
|
5
|
+
export { colorize, supportsColor, type Color } from "./color.js";
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -9,7 +9,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
9
9
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
10
|
};
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.supportsHyperlinks = exports.hyperlink = exports.fileUrl = exports.getTimeStamp = exports.getCaller = exports.createLog = void 0;
|
|
12
|
+
exports.supportsColor = exports.colorize = exports.supportsHyperlinks = exports.hyperlink = exports.fileUrl = exports.getTimeStamp = exports.getCaller = exports.createLog = void 0;
|
|
13
13
|
var createLog_js_1 = require("./createLog.js");
|
|
14
14
|
Object.defineProperty(exports, "createLog", { enumerable: true, get: function () { return __importDefault(createLog_js_1).default; } });
|
|
15
15
|
var getCaller_js_1 = require("./getCaller.js");
|
|
@@ -20,3 +20,6 @@ var link_js_1 = require("./link.js");
|
|
|
20
20
|
Object.defineProperty(exports, "fileUrl", { enumerable: true, get: function () { return link_js_1.fileUrl; } });
|
|
21
21
|
Object.defineProperty(exports, "hyperlink", { enumerable: true, get: function () { return link_js_1.hyperlink; } });
|
|
22
22
|
Object.defineProperty(exports, "supportsHyperlinks", { enumerable: true, get: function () { return link_js_1.supportsHyperlinks; } });
|
|
23
|
+
var color_js_1 = require("./color.js");
|
|
24
|
+
Object.defineProperty(exports, "colorize", { enumerable: true, get: function () { return color_js_1.colorize; } });
|
|
25
|
+
Object.defineProperty(exports, "supportsColor", { enumerable: true, get: function () { return color_js_1.supportsColor; } });
|
package/dist/cjs/utils/link.d.ts
CHANGED
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Builds a `file://` URL
|
|
3
|
-
*
|
|
2
|
+
* Builds a valid `file://` URL for a path so terminals can open it on click.
|
|
3
|
+
* Paths already in `file://` form are used as-is. We intentionally do NOT append
|
|
4
|
+
* `:line` — that isn't a valid URI and breaks file openers (e.g. GNOME/`gio`,
|
|
5
|
+
* which would look for a file literally named `foo.ts:42`). The line number
|
|
6
|
+
* stays visible in the link's display text instead.
|
|
4
7
|
*/
|
|
5
|
-
export declare function fileUrl(file: string
|
|
8
|
+
export declare function fileUrl(file: string): string;
|
|
6
9
|
/**
|
|
7
10
|
* Wraps `text` in an OSC-8 terminal hyperlink pointing at `url`. Terminals that
|
|
8
|
-
* support OSC-8 render `text` as a clickable link; others
|
|
11
|
+
* support OSC-8 render `text` as a clickable link; others ignore the escape and
|
|
12
|
+
* simply show `text`.
|
|
9
13
|
*/
|
|
10
14
|
export declare function hyperlink(text: string, url: string): string;
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
+
* Whether to emit OSC-8 hyperlinks for the given stream. Driven solely by the
|
|
17
|
+
* stream being an interactive terminal (`isTTY`) — no env vars, no config. When
|
|
18
|
+
* output is piped or redirected, links are skipped so escapes never end up in
|
|
19
|
+
* files or logs. Terminals that don't understand OSC-8 just show the plain text.
|
|
16
20
|
*/
|
|
17
21
|
export declare function supportsHyperlinks(streamName: "stdout" | "stderr"): boolean;
|
package/dist/cjs/utils/link.js
CHANGED
|
@@ -11,16 +11,19 @@ exports.hyperlink = hyperlink;
|
|
|
11
11
|
exports.supportsHyperlinks = supportsHyperlinks;
|
|
12
12
|
const node_url_1 = require("node:url");
|
|
13
13
|
/**
|
|
14
|
-
* Builds a `file://` URL
|
|
15
|
-
*
|
|
14
|
+
* Builds a valid `file://` URL for a path so terminals can open it on click.
|
|
15
|
+
* Paths already in `file://` form are used as-is. We intentionally do NOT append
|
|
16
|
+
* `:line` — that isn't a valid URI and breaks file openers (e.g. GNOME/`gio`,
|
|
17
|
+
* which would look for a file literally named `foo.ts:42`). The line number
|
|
18
|
+
* stays visible in the link's display text instead.
|
|
16
19
|
*/
|
|
17
|
-
function fileUrl(file
|
|
18
|
-
|
|
19
|
-
return `${base}:${line}`;
|
|
20
|
+
function fileUrl(file) {
|
|
21
|
+
return file.startsWith("file://") ? file : (0, node_url_1.pathToFileURL)(file).href;
|
|
20
22
|
}
|
|
21
23
|
/**
|
|
22
24
|
* Wraps `text` in an OSC-8 terminal hyperlink pointing at `url`. Terminals that
|
|
23
|
-
* support OSC-8 render `text` as a clickable link; others
|
|
25
|
+
* support OSC-8 render `text` as a clickable link; others ignore the escape and
|
|
26
|
+
* simply show `text`.
|
|
24
27
|
*/
|
|
25
28
|
function hyperlink(text, url) {
|
|
26
29
|
const OSC = "\x1b]8;;";
|
|
@@ -28,36 +31,14 @@ function hyperlink(text, url) {
|
|
|
28
31
|
return `${OSC}${url}${BEL}${text}${OSC}${BEL}`;
|
|
29
32
|
}
|
|
30
33
|
/**
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
34
|
+
* Whether to emit OSC-8 hyperlinks for the given stream. Driven solely by the
|
|
35
|
+
* stream being an interactive terminal (`isTTY`) — no env vars, no config. When
|
|
36
|
+
* output is piped or redirected, links are skipped so escapes never end up in
|
|
37
|
+
* files or logs. Terminals that don't understand OSC-8 just show the plain text.
|
|
35
38
|
*/
|
|
36
39
|
function supportsHyperlinks(streamName) {
|
|
37
40
|
if (typeof process === "undefined")
|
|
38
41
|
return false;
|
|
39
|
-
const env = process.env;
|
|
40
|
-
const force = env.FORCE_HYPERLINK;
|
|
41
|
-
if (force !== undefined && force !== "")
|
|
42
|
-
return force !== "0" && force.toLowerCase() !== "false";
|
|
43
42
|
const stream = streamName === "stdout" ? process.stdout : process.stderr;
|
|
44
|
-
|
|
45
|
-
return false;
|
|
46
|
-
if (env.TERM === "dumb")
|
|
47
|
-
return false;
|
|
48
|
-
if (env.CI !== undefined && env.CI !== "")
|
|
49
|
-
return false;
|
|
50
|
-
const program = env.TERM_PROGRAM;
|
|
51
|
-
if (program === "vscode" ||
|
|
52
|
-
program === "iTerm.app" ||
|
|
53
|
-
program === "Hyper" ||
|
|
54
|
-
program === "WezTerm")
|
|
55
|
-
return true;
|
|
56
|
-
if (env.WT_SESSION)
|
|
57
|
-
return true; // Windows Terminal
|
|
58
|
-
if (env.KITTY_WINDOW_ID)
|
|
59
|
-
return true;
|
|
60
|
-
if (env.VTE_VERSION !== undefined && Number(env.VTE_VERSION) >= 5000)
|
|
61
|
-
return true; // GNOME, etc.
|
|
62
|
-
return false;
|
|
43
|
+
return Boolean(stream?.isTTY);
|
|
63
44
|
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/** ANSI SGR codes for the colors/styles the logger uses. */
|
|
2
|
+
declare const CODES: {
|
|
3
|
+
readonly red: 31;
|
|
4
|
+
readonly yellow: 33;
|
|
5
|
+
readonly cyan: 36;
|
|
6
|
+
readonly dim: 2;
|
|
7
|
+
};
|
|
8
|
+
/** The named colors/styles {@link colorize} understands. */
|
|
9
|
+
export type Color = keyof typeof CODES;
|
|
10
|
+
/**
|
|
11
|
+
* Wraps `text` in the ANSI escape codes for `color`, resetting afterwards.
|
|
12
|
+
* Pure string work — deciding *whether* to colorize is {@link supportsColor}'s
|
|
13
|
+
* job, kept separate so callers control it per stream.
|
|
14
|
+
*/
|
|
15
|
+
export declare function colorize(text: string, color: Color): string;
|
|
16
|
+
/**
|
|
17
|
+
* Whether to emit ANSI colors for the given stream. Driven solely by the stream
|
|
18
|
+
* being an interactive terminal (`isTTY`) — no env vars, no config. When output
|
|
19
|
+
* is piped or redirected, colors are skipped so escape codes never end up in
|
|
20
|
+
* files or logs.
|
|
21
|
+
*/
|
|
22
|
+
export declare function supportsColor(streamName: "stdout" | "stderr"): boolean;
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=color.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/utils/color.ts"],"names":[],"mappings":"AAOA,4DAA4D;AAC5D,QAAA,MAAM,KAAK;;;;;CAKD,CAAA;AAEV,4DAA4D;AAC5D,MAAM,MAAM,KAAK,GAAG,MAAM,OAAO,KAAK,CAAA;AAItC;;;;GAIG;AACH,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,MAAM,CAE3D;AAED;;;;;GAKG;AACH,wBAAgB,aAAa,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAItE"}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* color.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 dewan-meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
/** ANSI SGR codes for the colors/styles the logger uses. */
|
|
8
|
+
const CODES = {
|
|
9
|
+
red: 31,
|
|
10
|
+
yellow: 33,
|
|
11
|
+
cyan: 36,
|
|
12
|
+
dim: 2,
|
|
13
|
+
};
|
|
14
|
+
const RESET = "\x1b[0m";
|
|
15
|
+
/**
|
|
16
|
+
* Wraps `text` in the ANSI escape codes for `color`, resetting afterwards.
|
|
17
|
+
* Pure string work — deciding *whether* to colorize is {@link supportsColor}'s
|
|
18
|
+
* job, kept separate so callers control it per stream.
|
|
19
|
+
*/
|
|
20
|
+
export function colorize(text, color) {
|
|
21
|
+
return `\x1b[${CODES[color]}m${text}${RESET}`;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Whether to emit ANSI colors for the given stream. Driven solely by the stream
|
|
25
|
+
* being an interactive terminal (`isTTY`) — no env vars, no config. When output
|
|
26
|
+
* is piped or redirected, colors are skipped so escape codes never end up in
|
|
27
|
+
* files or logs.
|
|
28
|
+
*/
|
|
29
|
+
export function supportsColor(streamName) {
|
|
30
|
+
if (typeof process === "undefined")
|
|
31
|
+
return false;
|
|
32
|
+
const stream = streamName === "stdout" ? process.stdout : process.stderr;
|
|
33
|
+
return Boolean(stream?.isTTY);
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=color.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"color.js","sourceRoot":"","sources":["../../src/utils/color.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,4DAA4D;AAC5D,MAAM,KAAK,GAAG;IACZ,GAAG,EAAE,EAAE;IACP,MAAM,EAAE,EAAE;IACV,IAAI,EAAE,EAAE;IACR,GAAG,EAAE,CAAC;CACE,CAAA;AAKV,MAAM,KAAK,GAAG,SAAS,CAAA;AAEvB;;;;GAIG;AACH,MAAM,UAAU,QAAQ,CAAC,IAAY,EAAE,KAAY;IACjD,OAAO,QAAQ,KAAK,CAAC,KAAK,CAAC,IAAI,IAAI,GAAG,KAAK,EAAE,CAAA;AAC/C,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,aAAa,CAAC,UAA+B;IAC3D,IAAI,OAAO,OAAO,KAAK,WAAW;QAAE,OAAO,KAAK,CAAA;IAChD,MAAM,MAAM,GAAG,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAA;IACxE,OAAO,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;AAC/B,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createLog.d.ts","sourceRoot":"","sources":["../../src/utils/createLog.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"createLog.d.ts","sourceRoot":"","sources":["../../src/utils/createLog.ts"],"names":[],"mappings":"AAaA,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAA;AA4BjD;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,OAAO,EAAE,UAAU,EACnB,GAAG,EAAE,MAAM,GACV,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAc9B"}
|
package/dist/utils/createLog.js
CHANGED
|
@@ -7,7 +7,14 @@
|
|
|
7
7
|
import getCaller from "./getCaller.js";
|
|
8
8
|
import getTimeStamp from "./getTimeStamp.js";
|
|
9
9
|
import { fileUrl, hyperlink, supportsHyperlinks } from "./link.js";
|
|
10
|
+
import { colorize, supportsColor } from "./color.js";
|
|
10
11
|
import { isLogAllowed } from "../config.js";
|
|
12
|
+
/** The tag color for each channel: info → cyan, warn → yellow, error → red. */
|
|
13
|
+
const TAG_COLOR = {
|
|
14
|
+
log: "cyan",
|
|
15
|
+
warn: "yellow",
|
|
16
|
+
error: "red",
|
|
17
|
+
};
|
|
11
18
|
/**
|
|
12
19
|
* Renders a caller as a `(file:line)` location. When the terminal supports
|
|
13
20
|
* OSC-8 hyperlinks, the location is a clickable link to the exact source line;
|
|
@@ -18,7 +25,7 @@ function formatLocation(caller, streamName) {
|
|
|
18
25
|
if (caller.file !== null &&
|
|
19
26
|
caller.line !== null &&
|
|
20
27
|
supportsHyperlinks(streamName))
|
|
21
|
-
return hyperlink(caller.label, fileUrl(caller.file
|
|
28
|
+
return hyperlink(caller.label, fileUrl(caller.file));
|
|
22
29
|
return caller.label;
|
|
23
30
|
}
|
|
24
31
|
/**
|
|
@@ -35,7 +42,11 @@ export default function createLog(channel, tag) {
|
|
|
35
42
|
return;
|
|
36
43
|
const caller = getCaller();
|
|
37
44
|
const location = formatLocation(caller, streamName);
|
|
38
|
-
|
|
45
|
+
// Color only the level tag, and only on a real terminal.
|
|
46
|
+
const tagOut = supportsColor(streamName)
|
|
47
|
+
? colorize(tag, TAG_COLOR[channel])
|
|
48
|
+
: tag;
|
|
49
|
+
console[channel](tagOut, getTimeStamp(), `(${location})`, `\n`, ...args, `\n`);
|
|
39
50
|
};
|
|
40
51
|
}
|
|
41
52
|
//# sourceMappingURL=createLog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createLog.js","sourceRoot":"","sources":["../../src/utils/createLog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAA0B,MAAM,gBAAgB,CAAA;AACvD,OAAO,YAAY,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAClE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAK3C;;;;;GAKG;AACH,SAAS,cAAc,CACrB,MAAc,EACd,UAA+B;IAE/B,IACE,MAAM,CAAC,IAAI,KAAK,IAAI;QACpB,MAAM,CAAC,IAAI,KAAK,IAAI;QACpB,kBAAkB,CAAC,UAAU,CAAC;QAE9B,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,
|
|
1
|
+
{"version":3,"file":"createLog.js","sourceRoot":"","sources":["../../src/utils/createLog.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,SAA0B,MAAM,gBAAgB,CAAA;AACvD,OAAO,YAAY,MAAM,mBAAmB,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAClE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAc,MAAM,YAAY,CAAA;AAChE,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAK3C,+EAA+E;AAC/E,MAAM,SAAS,GAA8B;IAC3C,GAAG,EAAE,MAAM;IACX,IAAI,EAAE,QAAQ;IACd,KAAK,EAAE,KAAK;CACb,CAAA;AAED;;;;;GAKG;AACH,SAAS,cAAc,CACrB,MAAc,EACd,UAA+B;IAE/B,IACE,MAAM,CAAC,IAAI,KAAK,IAAI;QACpB,MAAM,CAAC,IAAI,KAAK,IAAI;QACpB,kBAAkB,CAAC,UAAU,CAAC;QAE9B,OAAO,SAAS,CAAC,MAAM,CAAC,KAAK,EAAE,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAA;IACtD,OAAO,MAAM,CAAC,KAAK,CAAA;AACrB,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS,CAC/B,OAAmB,EACnB,GAAW;IAEX,MAAM,UAAU,GAAG,OAAO,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAA;IAC1D,OAAO,CAAC,GAAG,IAAe,EAAQ,EAAE;QAClC,IAAI,CAAC,YAAY,EAAE;YAAE,OAAM;QAC3B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;QAC1B,MAAM,QAAQ,GAAG,cAAc,CAAC,MAAM,EAAE,UAAU,CAAC,CAAA;QAEnD,yDAAyD;QACzD,MAAM,MAAM,GAAG,aAAa,CAAC,UAAU,CAAC;YACtC,CAAC,CAAC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;YACnC,CAAC,CAAC,GAAG,CAAA;QAEP,OAAO,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,YAAY,EAAE,EAAE,IAAI,QAAQ,GAAG,EAAE,IAAI,EAAE,GAAG,IAAI,EAAE,IAAI,CAAC,CAAA;IAChF,CAAC,CAAA;AACH,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -2,4 +2,5 @@ export { default as createLog, type LogChannel } from "./createLog.js";
|
|
|
2
2
|
export { default as getCaller, type Caller } from "./getCaller.js";
|
|
3
3
|
export { default as getTimeStamp } from "./getTimeStamp.js";
|
|
4
4
|
export { fileUrl, hyperlink, supportsHyperlinks } from "./link.js";
|
|
5
|
+
export { colorize, supportsColor, type Color } from "./color.js";
|
|
5
6
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,UAAU,EAAE,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,KAAK,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAClE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,KAAK,KAAK,EAAE,MAAM,YAAY,CAAA"}
|
package/dist/utils/index.js
CHANGED
|
@@ -8,4 +8,5 @@ export { default as createLog } from "./createLog.js";
|
|
|
8
8
|
export { default as getCaller } from "./getCaller.js";
|
|
9
9
|
export { default as getTimeStamp } from "./getTimeStamp.js";
|
|
10
10
|
export { fileUrl, hyperlink, supportsHyperlinks } from "./link.js";
|
|
11
|
+
export { colorize, supportsColor } from "./color.js";
|
|
11
12
|
//# sourceMappingURL=index.js.map
|
package/dist/utils/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,IAAI,SAAS,EAAmB,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAe,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,IAAI,SAAS,EAAmB,MAAM,gBAAgB,CAAA;AACtE,OAAO,EAAE,OAAO,IAAI,SAAS,EAAe,MAAM,gBAAgB,CAAA;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAA;AAC3D,OAAO,EAAE,OAAO,EAAE,SAAS,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAClE,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAc,MAAM,YAAY,CAAA"}
|
package/dist/utils/link.d.ts
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Builds a `file://` URL
|
|
3
|
-
*
|
|
2
|
+
* Builds a valid `file://` URL for a path so terminals can open it on click.
|
|
3
|
+
* Paths already in `file://` form are used as-is. We intentionally do NOT append
|
|
4
|
+
* `:line` — that isn't a valid URI and breaks file openers (e.g. GNOME/`gio`,
|
|
5
|
+
* which would look for a file literally named `foo.ts:42`). The line number
|
|
6
|
+
* stays visible in the link's display text instead.
|
|
4
7
|
*/
|
|
5
|
-
export declare function fileUrl(file: string
|
|
8
|
+
export declare function fileUrl(file: string): string;
|
|
6
9
|
/**
|
|
7
10
|
* Wraps `text` in an OSC-8 terminal hyperlink pointing at `url`. Terminals that
|
|
8
|
-
* support OSC-8 render `text` as a clickable link; others
|
|
11
|
+
* support OSC-8 render `text` as a clickable link; others ignore the escape and
|
|
12
|
+
* simply show `text`.
|
|
9
13
|
*/
|
|
10
14
|
export declare function hyperlink(text: string, url: string): string;
|
|
11
15
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
+
* Whether to emit OSC-8 hyperlinks for the given stream. Driven solely by the
|
|
17
|
+
* stream being an interactive terminal (`isTTY`) — no env vars, no config. When
|
|
18
|
+
* output is piped or redirected, links are skipped so escapes never end up in
|
|
19
|
+
* files or logs. Terminals that don't understand OSC-8 just show the plain text.
|
|
16
20
|
*/
|
|
17
21
|
export declare function supportsHyperlinks(streamName: "stdout" | "stderr"): boolean;
|
|
18
22
|
//# sourceMappingURL=link.d.ts.map
|
package/dist/utils/link.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/utils/link.ts"],"names":[],"mappings":"AASA
|
|
1
|
+
{"version":3,"file":"link.d.ts","sourceRoot":"","sources":["../../src/utils/link.ts"],"names":[],"mappings":"AASA;;;;;;GAMG;AACH,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAE5C;AAED;;;;GAIG;AACH,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAI3D;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,QAAQ,GAAG,QAAQ,GAAG,OAAO,CAI3E"}
|
package/dist/utils/link.js
CHANGED
|
@@ -6,16 +6,19 @@
|
|
|
6
6
|
*/
|
|
7
7
|
import { pathToFileURL } from "node:url";
|
|
8
8
|
/**
|
|
9
|
-
* Builds a `file://` URL
|
|
10
|
-
*
|
|
9
|
+
* Builds a valid `file://` URL for a path so terminals can open it on click.
|
|
10
|
+
* Paths already in `file://` form are used as-is. We intentionally do NOT append
|
|
11
|
+
* `:line` — that isn't a valid URI and breaks file openers (e.g. GNOME/`gio`,
|
|
12
|
+
* which would look for a file literally named `foo.ts:42`). The line number
|
|
13
|
+
* stays visible in the link's display text instead.
|
|
11
14
|
*/
|
|
12
|
-
export function fileUrl(file
|
|
13
|
-
|
|
14
|
-
return `${base}:${line}`;
|
|
15
|
+
export function fileUrl(file) {
|
|
16
|
+
return file.startsWith("file://") ? file : pathToFileURL(file).href;
|
|
15
17
|
}
|
|
16
18
|
/**
|
|
17
19
|
* Wraps `text` in an OSC-8 terminal hyperlink pointing at `url`. Terminals that
|
|
18
|
-
* support OSC-8 render `text` as a clickable link; others
|
|
20
|
+
* support OSC-8 render `text` as a clickable link; others ignore the escape and
|
|
21
|
+
* simply show `text`.
|
|
19
22
|
*/
|
|
20
23
|
export function hyperlink(text, url) {
|
|
21
24
|
const OSC = "\x1b]8;;";
|
|
@@ -23,37 +26,15 @@ export function hyperlink(text, url) {
|
|
|
23
26
|
return `${OSC}${url}${BEL}${text}${OSC}${BEL}`;
|
|
24
27
|
}
|
|
25
28
|
/**
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
29
|
+
* Whether to emit OSC-8 hyperlinks for the given stream. Driven solely by the
|
|
30
|
+
* stream being an interactive terminal (`isTTY`) — no env vars, no config. When
|
|
31
|
+
* output is piped or redirected, links are skipped so escapes never end up in
|
|
32
|
+
* files or logs. Terminals that don't understand OSC-8 just show the plain text.
|
|
30
33
|
*/
|
|
31
34
|
export function supportsHyperlinks(streamName) {
|
|
32
35
|
if (typeof process === "undefined")
|
|
33
36
|
return false;
|
|
34
|
-
const env = process.env;
|
|
35
|
-
const force = env.FORCE_HYPERLINK;
|
|
36
|
-
if (force !== undefined && force !== "")
|
|
37
|
-
return force !== "0" && force.toLowerCase() !== "false";
|
|
38
37
|
const stream = streamName === "stdout" ? process.stdout : process.stderr;
|
|
39
|
-
|
|
40
|
-
return false;
|
|
41
|
-
if (env.TERM === "dumb")
|
|
42
|
-
return false;
|
|
43
|
-
if (env.CI !== undefined && env.CI !== "")
|
|
44
|
-
return false;
|
|
45
|
-
const program = env.TERM_PROGRAM;
|
|
46
|
-
if (program === "vscode" ||
|
|
47
|
-
program === "iTerm.app" ||
|
|
48
|
-
program === "Hyper" ||
|
|
49
|
-
program === "WezTerm")
|
|
50
|
-
return true;
|
|
51
|
-
if (env.WT_SESSION)
|
|
52
|
-
return true; // Windows Terminal
|
|
53
|
-
if (env.KITTY_WINDOW_ID)
|
|
54
|
-
return true;
|
|
55
|
-
if (env.VTE_VERSION !== undefined && Number(env.VTE_VERSION) >= 5000)
|
|
56
|
-
return true; // GNOME, etc.
|
|
57
|
-
return false;
|
|
38
|
+
return Boolean(stream?.isTTY);
|
|
58
39
|
}
|
|
59
40
|
//# sourceMappingURL=link.js.map
|
package/dist/utils/link.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/utils/link.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC
|
|
1
|
+
{"version":3,"file":"link.js","sourceRoot":"","sources":["../../src/utils/link.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAA;AAExC;;;;;;GAMG;AACH,MAAM,UAAU,OAAO,CAAC,IAAY;IAClC,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,IAAI,CAAA;AACrE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,GAAW;IACjD,MAAM,GAAG,GAAG,UAAU,CAAA;IACtB,MAAM,GAAG,GAAG,MAAM,CAAA;IAClB,OAAO,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,IAAI,GAAG,GAAG,GAAG,GAAG,EAAE,CAAA;AAChD,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,kBAAkB,CAAC,UAA+B;IAChE,IAAI,OAAO,OAAO,KAAK,WAAW;QAAE,OAAO,KAAK,CAAA;IAChD,MAAM,MAAM,GAAG,UAAU,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAA;IACxE,OAAO,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,CAAA;AAC/B,CAAC"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meadown/logger",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "A tiny, zero-dependency logger for Node.js and TypeScript that tags each line, timestamps it, shows the source file and line, and goes quiet in production.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"logger",
|