@meadown/logger 1.8.11 → 1.9.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 +149 -51
- package/dist/cjs/{config.js → config/index.js} +1 -1
- package/dist/cjs/{constants.d.ts → const/index.d.ts} +0 -5
- package/dist/cjs/{constants.js → const/index.js} +2 -8
- package/dist/cjs/{caller → domain/caller}/getCaller.js +1 -1
- package/dist/cjs/{colors → domain/colors}/color.js +1 -1
- package/dist/cjs/{decorations → domain/decorations}/link.js +1 -1
- package/dist/cjs/{terminal → domain/terminal}/isTTY.js +1 -1
- package/dist/cjs/{time → domain/time}/getTimeStamp.js +1 -1
- package/dist/cjs/domain/write/helpers/buildContext.d.ts +16 -0
- package/dist/cjs/domain/write/helpers/buildContext.js +40 -0
- package/dist/{core/writeLog → cjs/domain/write}/helpers/formatLocation.d.ts +1 -1
- package/dist/cjs/{core/writeLog → domain/write}/helpers/formatLocation.js +2 -2
- package/dist/cjs/{core/writeLog → domain/write}/helpers/index.d.ts +1 -0
- package/dist/cjs/{core/writeLog → domain/write}/helpers/index.js +5 -2
- package/dist/cjs/{core/writeLog → domain/write}/helpers/renderMessage.js +6 -5
- package/dist/cjs/{core/writeLog → domain/write}/helpers/visibleLines.js +3 -3
- package/dist/cjs/{core/writeLog → domain/write}/index.js +1 -1
- package/dist/{core/writeLog → cjs/domain/write}/writeLog.d.ts +2 -2
- package/dist/cjs/domain/write/writeLog.js +24 -0
- package/dist/cjs/features/logger/index.d.ts +1 -0
- package/dist/cjs/features/logger/index.js +21 -0
- package/dist/cjs/features/logger-error/index.d.ts +1 -0
- package/dist/cjs/features/logger-error/index.js +21 -0
- package/dist/cjs/features/logger-group/createGroup.d.ts +11 -0
- package/dist/cjs/features/logger-group/createGroup.js +21 -0
- package/dist/cjs/features/logger-group/index.d.ts +1 -0
- package/dist/cjs/features/logger-group/index.js +14 -0
- package/dist/cjs/features/logger-group/writeGroup.d.ts +8 -0
- package/dist/cjs/features/logger-group/writeGroup.js +20 -0
- package/dist/cjs/features/logger-max-lines/index.d.ts +1 -0
- package/dist/cjs/features/logger-max-lines/index.js +12 -0
- package/dist/cjs/features/logger-tap/createTap.d.ts +5 -0
- package/dist/cjs/features/logger-tap/createTap.js +33 -0
- package/dist/cjs/features/logger-tap/index.d.ts +1 -0
- package/dist/cjs/features/logger-tap/index.js +14 -0
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/buildBlock.js +2 -2
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/format.js +2 -2
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/index.js +1 -1
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/isThenable.js +1 -1
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/response.js +2 -2
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/index.js +1 -1
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/tapAsync.d.ts +1 -1
- package/dist/cjs/{tap → features/logger-tap}/tapAsync/tapAsync.js +6 -3
- package/dist/cjs/features/logger-warn/index.d.ts +1 -0
- package/dist/cjs/features/logger-warn/index.js +21 -0
- package/dist/cjs/index.d.ts +17 -1
- package/dist/cjs/index.js +12 -8
- package/dist/cjs/types/index.d.ts +2 -0
- package/dist/cjs/types/index.js +8 -0
- package/dist/{config.js → config/index.js} +1 -1
- package/dist/{constants.d.ts → const/index.d.ts} +0 -5
- package/dist/{constants.js → const/index.js} +1 -7
- package/dist/{caller → domain/caller}/getCaller.js +1 -1
- package/dist/{colors → domain/colors}/color.js +1 -1
- package/dist/{decorations → domain/decorations}/link.js +1 -1
- package/dist/{terminal → domain/terminal}/isTTY.js +1 -1
- package/dist/{time → domain/time}/getTimeStamp.js +1 -1
- package/dist/domain/write/helpers/buildContext.d.ts +16 -0
- package/dist/domain/write/helpers/buildContext.js +33 -0
- package/dist/{cjs/core/writeLog → domain/write}/helpers/formatLocation.d.ts +1 -1
- package/dist/{core/writeLog → domain/write}/helpers/formatLocation.js +2 -2
- package/dist/{core/writeLog → domain/write}/helpers/index.d.ts +1 -0
- package/dist/{core/writeLog → domain/write}/helpers/index.js +2 -1
- package/dist/{core/writeLog → domain/write}/helpers/renderMessage.js +5 -4
- package/dist/{core/writeLog → domain/write}/helpers/visibleLines.js +2 -2
- package/dist/{core/writeLog → domain/write}/index.js +1 -1
- package/dist/{cjs/core/writeLog → domain/write}/writeLog.d.ts +2 -2
- package/dist/domain/write/writeLog.js +21 -0
- package/dist/features/logger/index.d.ts +1 -0
- package/dist/features/logger/index.js +15 -0
- package/dist/features/logger-error/index.d.ts +1 -0
- package/dist/features/logger-error/index.js +15 -0
- package/dist/features/logger-group/createGroup.d.ts +11 -0
- package/dist/features/logger-group/createGroup.js +15 -0
- package/dist/features/logger-group/index.d.ts +1 -0
- package/dist/features/logger-group/index.js +7 -0
- package/dist/features/logger-group/writeGroup.d.ts +8 -0
- package/dist/features/logger-group/writeGroup.js +17 -0
- package/dist/features/logger-max-lines/index.d.ts +1 -0
- package/dist/features/logger-max-lines/index.js +7 -0
- package/dist/features/logger-tap/createTap.d.ts +5 -0
- package/dist/features/logger-tap/createTap.js +27 -0
- package/dist/features/logger-tap/index.d.ts +1 -0
- package/dist/features/logger-tap/index.js +7 -0
- package/dist/{tap → features/logger-tap}/tapAsync/helpers/buildBlock.js +2 -2
- package/dist/{tap → features/logger-tap}/tapAsync/helpers/format.js +2 -2
- package/dist/{tap → features/logger-tap}/tapAsync/helpers/index.js +1 -1
- package/dist/{tap → features/logger-tap}/tapAsync/helpers/isThenable.js +1 -1
- package/dist/{tap → features/logger-tap}/tapAsync/helpers/response.js +2 -2
- package/dist/{tap → features/logger-tap}/tapAsync/index.js +1 -1
- package/dist/{tap → features/logger-tap}/tapAsync/tapAsync.d.ts +1 -1
- package/dist/{tap → features/logger-tap}/tapAsync/tapAsync.js +6 -3
- package/dist/features/logger-warn/index.d.ts +1 -0
- package/dist/features/logger-warn/index.js +15 -0
- package/dist/index.d.ts +17 -1
- package/dist/index.js +12 -8
- package/dist/types/index.d.ts +2 -0
- package/dist/types/index.js +7 -0
- package/package.json +1 -1
- package/dist/cjs/core/createLog.d.ts +0 -8
- package/dist/cjs/core/createLog.js +0 -29
- package/dist/cjs/core/writeLog/writeLog.js +0 -43
- package/dist/cjs/tap/createTap.d.ts +0 -18
- package/dist/cjs/tap/createTap.js +0 -51
- package/dist/core/createLog.d.ts +0 -8
- package/dist/core/createLog.js +0 -23
- package/dist/core/writeLog/writeLog.js +0 -37
- package/dist/tap/createTap.d.ts +0 -18
- package/dist/tap/createTap.js +0 -45
- /package/dist/cjs/{config.d.ts → config/index.d.ts} +0 -0
- /package/dist/{caller → cjs/domain/caller}/getCaller.d.ts +0 -0
- /package/dist/cjs/{colors → domain/colors}/color.d.ts +0 -0
- /package/dist/cjs/{decorations → domain/decorations}/link.d.ts +0 -0
- /package/dist/cjs/{terminal → domain/terminal}/isTTY.d.ts +0 -0
- /package/dist/cjs/{time → domain/time}/getTimeStamp.d.ts +0 -0
- /package/dist/cjs/{core/writeLog → domain/write}/helpers/renderMessage.d.ts +0 -0
- /package/dist/cjs/{core/writeLog → domain/write}/helpers/visibleLines.d.ts +0 -0
- /package/dist/cjs/{core/writeLog → domain/write}/index.d.ts +0 -0
- /package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/buildBlock.d.ts +0 -0
- /package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/format.d.ts +0 -0
- /package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/index.d.ts +0 -0
- /package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/isThenable.d.ts +0 -0
- /package/dist/cjs/{tap → features/logger-tap}/tapAsync/helpers/response.d.ts +0 -0
- /package/dist/cjs/{tap → features/logger-tap}/tapAsync/index.d.ts +0 -0
- /package/dist/{config.d.ts → config/index.d.ts} +0 -0
- /package/dist/{cjs → domain}/caller/getCaller.d.ts +0 -0
- /package/dist/{colors → domain/colors}/color.d.ts +0 -0
- /package/dist/{decorations → domain/decorations}/link.d.ts +0 -0
- /package/dist/{terminal → domain/terminal}/isTTY.d.ts +0 -0
- /package/dist/{time → domain/time}/getTimeStamp.d.ts +0 -0
- /package/dist/{core/writeLog → domain/write}/helpers/renderMessage.d.ts +0 -0
- /package/dist/{core/writeLog → domain/write}/helpers/visibleLines.d.ts +0 -0
- /package/dist/{core/writeLog → domain/write}/index.d.ts +0 -0
- /package/dist/{tap → features/logger-tap}/tapAsync/helpers/buildBlock.d.ts +0 -0
- /package/dist/{tap → features/logger-tap}/tapAsync/helpers/format.d.ts +0 -0
- /package/dist/{tap → features/logger-tap}/tapAsync/helpers/index.d.ts +0 -0
- /package/dist/{tap → features/logger-tap}/tapAsync/helpers/isThenable.d.ts +0 -0
- /package/dist/{tap → features/logger-tap}/tapAsync/helpers/response.d.ts +0 -0
- /package/dist/{tap → features/logger-tap}/tapAsync/index.d.ts +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* writeLog.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { renderMessage, buildContext, TAG_COLOR } from "./helpers/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Renders and writes one log entry. The `caller` is resolved by the *caller* of
|
|
10
|
+
* this function (the log closure or `tap`) and passed in, so this helper never
|
|
11
|
+
* touches the stack — keeping {@link getCaller}'s frame depth correct no matter
|
|
12
|
+
* which user-facing function delegates here.
|
|
13
|
+
*/
|
|
14
|
+
export function writeLog(opts) {
|
|
15
|
+
const { channel, tag, args, caller } = opts;
|
|
16
|
+
const { useColor, paint, timeStamp, locOut, connector, connectorEnd, separator, } = buildContext(channel, caller);
|
|
17
|
+
const tagOut = paint(tag, TAG_COLOR[channel]);
|
|
18
|
+
const message = renderMessage(args, useColor);
|
|
19
|
+
const meta = `\n${connectorEnd} ${timeStamp} ${separator} ${locOut}`;
|
|
20
|
+
console[channel](`\n${tagOut} \n${connector} ${message}${meta}`);
|
|
21
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function log(...args: unknown[]): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* index.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { isLogAllowed } from "../../config/index.js";
|
|
8
|
+
import getCaller from "../../domain/caller/getCaller.js";
|
|
9
|
+
import { writeLog } from "../../domain/write/writeLog.js";
|
|
10
|
+
export default function log(...args) {
|
|
11
|
+
if (!isLogAllowed())
|
|
12
|
+
return;
|
|
13
|
+
const caller = getCaller();
|
|
14
|
+
writeLog({ channel: "log", tag: "[INFO]", args, caller });
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function logError(...args: unknown[]): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* index.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { isLogAllowed } from "../../config/index.js";
|
|
8
|
+
import getCaller from "../../domain/caller/getCaller.js";
|
|
9
|
+
import { writeLog } from "../../domain/write/writeLog.js";
|
|
10
|
+
export default function logError(...args) {
|
|
11
|
+
if (!isLogAllowed())
|
|
12
|
+
return;
|
|
13
|
+
const caller = getCaller();
|
|
14
|
+
writeLog({ channel: "error", tag: "[ERROR]", args, caller });
|
|
15
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { type LogChannel } from "../../types/index.js";
|
|
2
|
+
export interface GroupOptions {
|
|
3
|
+
name: string;
|
|
4
|
+
type?: LogChannel;
|
|
5
|
+
logs: unknown[];
|
|
6
|
+
}
|
|
7
|
+
/** Type of `logger.group` — use this to annotate variables or parameters that accept it. */
|
|
8
|
+
export interface Group {
|
|
9
|
+
(opts: GroupOptions): void;
|
|
10
|
+
}
|
|
11
|
+
export default function group({ name, type, logs, }: GroupOptions): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* createGroup.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { isLogAllowed } from "../../config/index.js";
|
|
8
|
+
import getCaller from "../../domain/caller/getCaller.js";
|
|
9
|
+
import { writeGroup } from "./writeGroup.js";
|
|
10
|
+
export default function group({ name, type = "log", logs, }) {
|
|
11
|
+
if (!isLogAllowed())
|
|
12
|
+
return;
|
|
13
|
+
const caller = getCaller();
|
|
14
|
+
writeGroup({ name, channel: type, logs, caller });
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, type Group, type GroupOptions } from "./createGroup.js";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* writeGroup.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { renderMessage, buildContext, TAG_COLOR, } from "../../domain/write/helpers/index.js";
|
|
8
|
+
export function writeGroup(opts) {
|
|
9
|
+
const { name, channel, logs, caller } = opts;
|
|
10
|
+
const { useColor, paint, timeStamp, locOut, connector, connectorEnd, separator, } = buildContext(channel, caller);
|
|
11
|
+
const tagOut = paint(`[${name.toUpperCase()}]`, TAG_COLOR[channel]);
|
|
12
|
+
const itemLines = logs
|
|
13
|
+
.map((item) => `\n${connector} ${renderMessage([item], useColor)}`)
|
|
14
|
+
.join("");
|
|
15
|
+
const meta = `\n${connectorEnd} ${timeStamp} ${separator} ${locOut}`;
|
|
16
|
+
console[channel](`\n${tagOut} ${itemLines}${meta}`);
|
|
17
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { getVisibleLines, setVisibleLines } from "../../domain/write/index.js";
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* createTap.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { isLogAllowed } from "../../config/index.js";
|
|
8
|
+
import getCaller from "../../domain/caller/getCaller.js";
|
|
9
|
+
import { writeLog } from "../../domain/write/writeLog.js";
|
|
10
|
+
import { isThenable, tapAsync } from "./tapAsync/index.js";
|
|
11
|
+
export default function tap(value, label) {
|
|
12
|
+
if (!isLogAllowed())
|
|
13
|
+
return value;
|
|
14
|
+
const caller = getCaller();
|
|
15
|
+
if (isThenable(value)) {
|
|
16
|
+
tapAsync(value, label, caller);
|
|
17
|
+
}
|
|
18
|
+
else {
|
|
19
|
+
writeLog({
|
|
20
|
+
channel: "log",
|
|
21
|
+
tag: "[TAP]",
|
|
22
|
+
args: label === undefined ? [value] : [label, value],
|
|
23
|
+
caller,
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default, type Tap } from "./createTap.js";
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* buildBlock.ts
|
|
3
3
|
* Created by Dewan Mobashirul
|
|
4
|
-
* Copyright (c) 2026
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
7
|
import { formatWithOptions } from "node:util";
|
|
8
8
|
import { formatDuration } from "./format.js";
|
|
9
|
-
import { colorize } from "
|
|
9
|
+
import { colorize } from "../../../../domain/colors/color.js";
|
|
10
10
|
import { formatStatus } from "./response.js";
|
|
11
11
|
/**
|
|
12
12
|
* Renders the nested tree block:
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* format.ts
|
|
3
3
|
* Created by Dewan Mobashirul
|
|
4
|
-
* Copyright (c) 2026
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
|
-
import { colorize } from "
|
|
7
|
+
import { colorize } from "../../../../domain/colors/color.js";
|
|
8
8
|
/** `65ms` (green) · `1.2s` (yellow) · `5.8s` (red). */
|
|
9
9
|
export function formatDuration(ms, useColor) {
|
|
10
10
|
const text = ms >= 1000 ? `${(ms / 1000).toFixed(2)}s` : `${ms}ms`;
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* response.ts
|
|
3
3
|
* Created by Dewan Mobashirul
|
|
4
|
-
* Copyright (c) 2026
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
7
|
import { formatBytes } from "./format.js";
|
|
8
|
-
import { colorize } from "
|
|
8
|
+
import { colorize } from "../../../../domain/colors/color.js";
|
|
9
9
|
/** Whether the resolved value is a fetch `Response` we can read. */
|
|
10
10
|
export function isResponse(value) {
|
|
11
11
|
const v = value;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Caller } from "
|
|
1
|
+
import { type Caller } from "../../../domain/caller/getCaller.js";
|
|
2
2
|
/**
|
|
3
3
|
* The async tap. Fire-and-forget: returns `promise` immediately (unchanged),
|
|
4
4
|
* and logs a rich block once it resolves. For a `Response`, reads the body from
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* tapAsync.ts
|
|
3
3
|
* Created by Dewan Mobashirul
|
|
4
|
-
* Copyright (c) 2026
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
7
|
import { performance } from "node:perf_hooks";
|
|
8
8
|
import { formatDuration, formatBytes, isResponse, readBody, buildBlock, } from "./helpers/index.js";
|
|
9
|
-
import { isTTY } from "
|
|
10
|
-
import { writeLog } from "
|
|
9
|
+
import { isTTY } from "../../../domain/terminal/isTTY.js";
|
|
10
|
+
import { writeLog } from "../../../domain/write/index.js";
|
|
11
|
+
import { isLogAllowed } from "../../../config/index.js";
|
|
11
12
|
/**
|
|
12
13
|
* The async tap. Fire-and-forget: returns `promise` immediately (unchanged),
|
|
13
14
|
* and logs a rich block once it resolves. For a `Response`, reads the body from
|
|
@@ -16,6 +17,8 @@ import { writeLog } from "../../core/writeLog/index.js";
|
|
|
16
17
|
* the logged location points at the user's file.
|
|
17
18
|
*/
|
|
18
19
|
export function tapAsync(promise, label, caller) {
|
|
20
|
+
if (!isLogAllowed())
|
|
21
|
+
return;
|
|
19
22
|
const useColor = isTTY("stdout");
|
|
20
23
|
const start = performance.now();
|
|
21
24
|
void promise.then((resolved) => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export default function logWarn(...args: unknown[]): void;
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* index.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { isLogAllowed } from "../../config/index.js";
|
|
8
|
+
import getCaller from "../../domain/caller/getCaller.js";
|
|
9
|
+
import { writeLog } from "../../domain/write/writeLog.js";
|
|
10
|
+
export default function logWarn(...args) {
|
|
11
|
+
if (!isLogAllowed())
|
|
12
|
+
return;
|
|
13
|
+
const caller = getCaller();
|
|
14
|
+
writeLog({ channel: "warn", tag: "[WARN]", args, caller });
|
|
15
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type Tap } from "./features/logger-tap/index.js";
|
|
2
|
+
import { type Group } from "./features/logger-group/index.js";
|
|
1
3
|
/** Type of the logger — use this to annotate variables or parameters that accept it. */
|
|
2
4
|
export interface Logger {
|
|
3
5
|
/** Log at info level — `stdout`, cyan `[INFO]` tag. */
|
|
@@ -26,7 +28,21 @@ export interface Logger {
|
|
|
26
28
|
* @param value Any value or promise — always returned as-is.
|
|
27
29
|
* @param label Optional label shown next to the value in the log line.
|
|
28
30
|
*/
|
|
29
|
-
tap
|
|
31
|
+
tap: Tap;
|
|
32
|
+
/**
|
|
33
|
+
* Log multiple related items as one block under a shared name and single
|
|
34
|
+
* timestamp. Each item in `logs` renders on its own `├──` branch — any value
|
|
35
|
+
* is accepted (string, object, function, Promise, …).
|
|
36
|
+
*
|
|
37
|
+
* `type` sets the channel and tag color: `"info"` (default), `"warn"`, `"error"`.
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* ```ts
|
|
41
|
+
* logger.group({ name: "Server setup", logs: [`port: ${port}`, `env: ${env}`] })
|
|
42
|
+
* logger.group({ name: "Validation failed", type: "error", logs: ["email invalid"] })
|
|
43
|
+
* ```
|
|
44
|
+
*/
|
|
45
|
+
group: Group;
|
|
30
46
|
/**
|
|
31
47
|
* How many lines to show before the rest collapses into a
|
|
32
48
|
* `… N more lines` summary. `0` (default) shows everything.
|
package/dist/index.js
CHANGED
|
@@ -1,12 +1,15 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* index.ts
|
|
3
3
|
* Created by Dewan Mobashirul
|
|
4
|
-
* Copyright (c) 2026
|
|
4
|
+
* Copyright (c) 2026 meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
8
|
-
import
|
|
9
|
-
import
|
|
7
|
+
import { getVisibleLines, setVisibleLines, } from "./features/logger-max-lines/index.js";
|
|
8
|
+
import logInfo from "./features/logger/index.js";
|
|
9
|
+
import logWarn from "./features/logger-warn/index.js";
|
|
10
|
+
import logError from "./features/logger-error/index.js";
|
|
11
|
+
import tap from "./features/logger-tap/index.js";
|
|
12
|
+
import group from "./features/logger-group/index.js";
|
|
10
13
|
/**
|
|
11
14
|
* A logger built for development — colored tags, a local timestamp, and a
|
|
12
15
|
* clickable `(file:line)` link on every line so you always know where a
|
|
@@ -27,10 +30,11 @@ import { getVisibleLines, setVisibleLines } from "./core/writeLog/index.js";
|
|
|
27
30
|
* const res = await logger.tap(fetch(url), "GET /users")
|
|
28
31
|
* ```
|
|
29
32
|
*/
|
|
30
|
-
const logger = Object.assign(
|
|
31
|
-
error:
|
|
32
|
-
warn:
|
|
33
|
-
tap
|
|
33
|
+
const logger = Object.assign(logInfo, {
|
|
34
|
+
error: logError,
|
|
35
|
+
warn: logWarn,
|
|
36
|
+
tap,
|
|
37
|
+
group,
|
|
34
38
|
});
|
|
35
39
|
// `maxLines` is a live getter/setter backed by the shared collapse setting, so
|
|
36
40
|
// setting it once affects info, error, and warn alike.
|
package/package.json
CHANGED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type LogChannel } from "../constants.js";
|
|
2
|
-
/**
|
|
3
|
-
* Builds a log function bound to a console channel and tag. The returned closure
|
|
4
|
-
* is what the caller invokes directly, so {@link getCaller} resolves the caller's
|
|
5
|
-
* own frame; the resolved caller is then handed to {@link writeLog}, which never
|
|
6
|
-
* touches the stack. Logs only outside production — see {@link isLogAllowed}.
|
|
7
|
-
*/
|
|
8
|
-
export default function createLog(channel: LogChannel, tag: string): (...args: unknown[]) => void;
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* createLog.ts
|
|
4
|
-
* Created by Dewan Mobashirul
|
|
5
|
-
* Copyright (c) 2026 dewan-meadown
|
|
6
|
-
* All rights reserved
|
|
7
|
-
*/
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.default = createLog;
|
|
13
|
-
const getCaller_js_1 = __importDefault(require("../caller/getCaller.js"));
|
|
14
|
-
const index_js_1 = require("./writeLog/index.js");
|
|
15
|
-
const config_js_1 = require("../config.js");
|
|
16
|
-
/**
|
|
17
|
-
* Builds a log function bound to a console channel and tag. The returned closure
|
|
18
|
-
* is what the caller invokes directly, so {@link getCaller} resolves the caller's
|
|
19
|
-
* own frame; the resolved caller is then handed to {@link writeLog}, which never
|
|
20
|
-
* touches the stack. Logs only outside production — see {@link isLogAllowed}.
|
|
21
|
-
*/
|
|
22
|
-
function createLog(channel, tag) {
|
|
23
|
-
return (...args) => {
|
|
24
|
-
if (!(0, config_js_1.isLogAllowed)())
|
|
25
|
-
return;
|
|
26
|
-
const caller = (0, getCaller_js_1.default)();
|
|
27
|
-
(0, index_js_1.writeLog)({ channel, tag, args, caller });
|
|
28
|
-
};
|
|
29
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* writeLog.ts
|
|
4
|
-
* Created by Dewan Mobashirul
|
|
5
|
-
* Copyright (c) 2026 dewan-meadown
|
|
6
|
-
* All rights reserved
|
|
7
|
-
*/
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.writeLog = writeLog;
|
|
13
|
-
const constants_js_1 = require("../../constants.js");
|
|
14
|
-
const isTTY_js_1 = require("../../terminal/isTTY.js");
|
|
15
|
-
const getTimeStamp_js_1 = __importDefault(require("../../time/getTimeStamp.js"));
|
|
16
|
-
const color_js_1 = require("../../colors/color.js");
|
|
17
|
-
const index_js_1 = require("./helpers/index.js");
|
|
18
|
-
/**
|
|
19
|
-
* Renders and writes one log entry. The `caller` is resolved by the *caller* of
|
|
20
|
-
* this function (the log closure or `tap`) and passed in, so this helper never
|
|
21
|
-
* touches the stack — keeping {@link getCaller}'s frame depth correct no matter
|
|
22
|
-
* which user-facing function delegates here.
|
|
23
|
-
*/
|
|
24
|
-
function writeLog(opts) {
|
|
25
|
-
const { channel, tag, args, caller } = opts;
|
|
26
|
-
const streamName = channel === "log" ? "stdout" : "stderr";
|
|
27
|
-
// One terminal check drives both color and clickable links — `isTTY` is the
|
|
28
|
-
// single source of truth (DRY). Off when output is piped/redirected.
|
|
29
|
-
const useColor = (0, isTTY_js_1.isTTY)(streamName);
|
|
30
|
-
const paint = (s, c) => (useColor ? (0, color_js_1.colorize)(s, c) : s);
|
|
31
|
-
const location = (0, index_js_1.formatLocation)(caller, useColor);
|
|
32
|
-
const tagOut = paint(tag, constants_js_1.TAG_COLOR[channel]);
|
|
33
|
-
const timeStamp = paint((0, getTimeStamp_js_1.default)(), "teal");
|
|
34
|
-
const locOut = paint(`(${location})`, "dimTeal");
|
|
35
|
-
const connector = paint(constants_js_1.BRANCH, "gray");
|
|
36
|
-
const connectorBottom = paint(constants_js_1.BRANCH_END, "gray");
|
|
37
|
-
const separator = paint(constants_js_1.SEPARATOR, "gray");
|
|
38
|
-
// Layout: the tag, the message hanging off a `├──` branch, then the timestamp
|
|
39
|
-
// and location on a `└──` branch below. Leading `\n` spaces entries apart.
|
|
40
|
-
const message = (0, index_js_1.renderMessage)(args, useColor);
|
|
41
|
-
const meta = `\n${connectorBottom} ${timeStamp} ${separator} ${locOut}`;
|
|
42
|
-
console[channel](`\n${tagOut}`, `\n${connector}`, message, meta);
|
|
43
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
/** Logs a value and returns it unchanged. Promises route to the timed path. */
|
|
2
|
-
export interface Tap {
|
|
3
|
-
<T>(value: T, label?: string): T;
|
|
4
|
-
}
|
|
5
|
-
/**
|
|
6
|
-
* Builds `tap` — logs a value and returns it **unchanged**, so it drops into any
|
|
7
|
-
* expression (`const u = logger.tap(getUser(), "user")`). The consumer always
|
|
8
|
-
* gets back exactly what they passed; the only effect is a clean log.
|
|
9
|
-
*
|
|
10
|
-
* - A plain value is logged synchronously and returned.
|
|
11
|
-
* - A **promise** is returned as-is (same object, never awaited or wrapped), and
|
|
12
|
-
* its elapsed time — plus the HTTP status if it resolves to a `Response` — is
|
|
13
|
-
* logged in the background (fire-and-forget, non-blocking).
|
|
14
|
-
*
|
|
15
|
-
* The returned closure is what the caller invokes directly, so {@link getCaller}
|
|
16
|
-
* resolves the caller's own frame. Silent in production; the value still flows.
|
|
17
|
-
*/
|
|
18
|
-
export default function createTap(): Tap;
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*
|
|
3
|
-
* createTap.ts
|
|
4
|
-
* Created by Dewan Mobashirul
|
|
5
|
-
* Copyright (c) 2026 dewan-meadown
|
|
6
|
-
* All rights reserved
|
|
7
|
-
*/
|
|
8
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
9
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
10
|
-
};
|
|
11
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
-
exports.default = createTap;
|
|
13
|
-
const config_js_1 = require("../config.js");
|
|
14
|
-
const getCaller_js_1 = __importDefault(require("../caller/getCaller.js"));
|
|
15
|
-
const index_js_1 = require("../core/writeLog/index.js");
|
|
16
|
-
const index_js_2 = require("./tapAsync/index.js");
|
|
17
|
-
/**
|
|
18
|
-
* Builds `tap` — logs a value and returns it **unchanged**, so it drops into any
|
|
19
|
-
* expression (`const u = logger.tap(getUser(), "user")`). The consumer always
|
|
20
|
-
* gets back exactly what they passed; the only effect is a clean log.
|
|
21
|
-
*
|
|
22
|
-
* - A plain value is logged synchronously and returned.
|
|
23
|
-
* - A **promise** is returned as-is (same object, never awaited or wrapped), and
|
|
24
|
-
* its elapsed time — plus the HTTP status if it resolves to a `Response` — is
|
|
25
|
-
* logged in the background (fire-and-forget, non-blocking).
|
|
26
|
-
*
|
|
27
|
-
* The returned closure is what the caller invokes directly, so {@link getCaller}
|
|
28
|
-
* resolves the caller's own frame. Silent in production; the value still flows.
|
|
29
|
-
*/
|
|
30
|
-
function createTap() {
|
|
31
|
-
const tap = (value, label) => {
|
|
32
|
-
if (!(0, config_js_1.isLogAllowed)())
|
|
33
|
-
return value;
|
|
34
|
-
const caller = (0, getCaller_js_1.default)();
|
|
35
|
-
if ((0, index_js_2.isThenable)(value)) {
|
|
36
|
-
// value is a promise → hand off to the async tap (caller passed in so the
|
|
37
|
-
// location stays on the user's file, not on this helper).
|
|
38
|
-
(0, index_js_2.tapAsync)(value, label, caller);
|
|
39
|
-
}
|
|
40
|
-
else {
|
|
41
|
-
(0, index_js_1.writeLog)({
|
|
42
|
-
channel: "log",
|
|
43
|
-
tag: "[TAP]",
|
|
44
|
-
args: label === undefined ? [value] : [label, value],
|
|
45
|
-
caller,
|
|
46
|
-
});
|
|
47
|
-
}
|
|
48
|
-
return value;
|
|
49
|
-
};
|
|
50
|
-
return tap;
|
|
51
|
-
}
|
package/dist/core/createLog.d.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import { type LogChannel } from "../constants.js";
|
|
2
|
-
/**
|
|
3
|
-
* Builds a log function bound to a console channel and tag. The returned closure
|
|
4
|
-
* is what the caller invokes directly, so {@link getCaller} resolves the caller's
|
|
5
|
-
* own frame; the resolved caller is then handed to {@link writeLog}, which never
|
|
6
|
-
* touches the stack. Logs only outside production — see {@link isLogAllowed}.
|
|
7
|
-
*/
|
|
8
|
-
export default function createLog(channel: LogChannel, tag: string): (...args: unknown[]) => void;
|
package/dist/core/createLog.js
DELETED
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* createLog.ts
|
|
3
|
-
* Created by Dewan Mobashirul
|
|
4
|
-
* Copyright (c) 2026 dewan-meadown
|
|
5
|
-
* All rights reserved
|
|
6
|
-
*/
|
|
7
|
-
import getCaller from "../caller/getCaller.js";
|
|
8
|
-
import { writeLog } from "./writeLog/index.js";
|
|
9
|
-
import { isLogAllowed } from "../config.js";
|
|
10
|
-
/**
|
|
11
|
-
* Builds a log function bound to a console channel and tag. The returned closure
|
|
12
|
-
* is what the caller invokes directly, so {@link getCaller} resolves the caller's
|
|
13
|
-
* own frame; the resolved caller is then handed to {@link writeLog}, which never
|
|
14
|
-
* touches the stack. Logs only outside production — see {@link isLogAllowed}.
|
|
15
|
-
*/
|
|
16
|
-
export default function createLog(channel, tag) {
|
|
17
|
-
return (...args) => {
|
|
18
|
-
if (!isLogAllowed())
|
|
19
|
-
return;
|
|
20
|
-
const caller = getCaller();
|
|
21
|
-
writeLog({ channel, tag, args, caller });
|
|
22
|
-
};
|
|
23
|
-
}
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* writeLog.ts
|
|
3
|
-
* Created by Dewan Mobashirul
|
|
4
|
-
* Copyright (c) 2026 dewan-meadown
|
|
5
|
-
* All rights reserved
|
|
6
|
-
*/
|
|
7
|
-
import { TAG_COLOR, BRANCH, BRANCH_END, SEPARATOR, } from "../../constants.js";
|
|
8
|
-
import { isTTY } from "../../terminal/isTTY.js";
|
|
9
|
-
import getTimeStamp from "../../time/getTimeStamp.js";
|
|
10
|
-
import { colorize } from "../../colors/color.js";
|
|
11
|
-
import { renderMessage, formatLocation } from "./helpers/index.js";
|
|
12
|
-
/**
|
|
13
|
-
* Renders and writes one log entry. The `caller` is resolved by the *caller* of
|
|
14
|
-
* this function (the log closure or `tap`) and passed in, so this helper never
|
|
15
|
-
* touches the stack — keeping {@link getCaller}'s frame depth correct no matter
|
|
16
|
-
* which user-facing function delegates here.
|
|
17
|
-
*/
|
|
18
|
-
export function writeLog(opts) {
|
|
19
|
-
const { channel, tag, args, caller } = opts;
|
|
20
|
-
const streamName = channel === "log" ? "stdout" : "stderr";
|
|
21
|
-
// One terminal check drives both color and clickable links — `isTTY` is the
|
|
22
|
-
// single source of truth (DRY). Off when output is piped/redirected.
|
|
23
|
-
const useColor = isTTY(streamName);
|
|
24
|
-
const paint = (s, c) => (useColor ? colorize(s, c) : s);
|
|
25
|
-
const location = formatLocation(caller, useColor);
|
|
26
|
-
const tagOut = paint(tag, TAG_COLOR[channel]);
|
|
27
|
-
const timeStamp = paint(getTimeStamp(), "teal");
|
|
28
|
-
const locOut = paint(`(${location})`, "dimTeal");
|
|
29
|
-
const connector = paint(BRANCH, "gray");
|
|
30
|
-
const connectorBottom = paint(BRANCH_END, "gray");
|
|
31
|
-
const separator = paint(SEPARATOR, "gray");
|
|
32
|
-
// Layout: the tag, the message hanging off a `├──` branch, then the timestamp
|
|
33
|
-
// and location on a `└──` branch below. Leading `\n` spaces entries apart.
|
|
34
|
-
const message = renderMessage(args, useColor);
|
|
35
|
-
const meta = `\n${connectorBottom} ${timeStamp} ${separator} ${locOut}`;
|
|
36
|
-
console[channel](`\n${tagOut}`, `\n${connector}`, message, meta);
|
|
37
|
-
}
|