@meadown/logger 1.4.0 → 1.5.1
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/LICENSE +1 -1
- package/README.md +41 -11
- package/SECURITY.md +50 -0
- package/dist/cjs/index.d.ts +5 -8
- package/dist/cjs/index.js +15 -4
- package/dist/cjs/utils/color.d.ts +2 -1
- package/dist/cjs/utils/color.js +2 -1
- package/dist/cjs/utils/createLog.d.ts +4 -0
- package/dist/cjs/utils/createLog.js +62 -9
- package/dist/cjs/utils/getTimeStamp.d.ts +3 -3
- package/dist/cjs/utils/getTimeStamp.js +5 -6
- package/dist/cjs/utils/index.d.ts +1 -1
- package/dist/cjs/utils/index.js +3 -1
- package/dist/index.d.ts +5 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -5
- package/dist/index.js.map +1 -1
- package/dist/utils/color.d.ts +2 -1
- package/dist/utils/color.d.ts.map +1 -1
- package/dist/utils/color.js +2 -1
- package/dist/utils/color.js.map +1 -1
- package/dist/utils/createLog.d.ts +4 -0
- package/dist/utils/createLog.d.ts.map +1 -1
- package/dist/utils/createLog.js +60 -9
- package/dist/utils/createLog.js.map +1 -1
- package/dist/utils/getTimeStamp.d.ts +3 -3
- package/dist/utils/getTimeStamp.d.ts.map +1 -1
- package/dist/utils/getTimeStamp.js +5 -6
- package/dist/utils/getTimeStamp.js.map +1 -1
- package/dist/utils/index.d.ts +1 -1
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +1 -1
- package/dist/utils/index.js.map +1 -1
- package/package.json +4 -2
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -14,7 +14,11 @@ No dependencies. No config. Import it and you're done.
|
|
|
14
14
|
## Install
|
|
15
15
|
|
|
16
16
|
```bash
|
|
17
|
+
pnpm add @meadown/logger
|
|
18
|
+
# or
|
|
17
19
|
npm install @meadown/logger
|
|
20
|
+
# or
|
|
21
|
+
yarn add @meadown/logger
|
|
18
22
|
```
|
|
19
23
|
|
|
20
24
|
## Using it
|
|
@@ -32,14 +36,15 @@ customLog.error("Something went wrong")
|
|
|
32
36
|
You'll see something like:
|
|
33
37
|
|
|
34
38
|
```text
|
|
35
|
-
[INFO]
|
|
36
|
-
|
|
39
|
+
[INFO]
|
|
40
|
+
├── Auth user logged in
|
|
41
|
+
└── 05-30 04:00:00 PM - (server.ts:42)
|
|
37
42
|
```
|
|
38
43
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
scan
|
|
44
|
+
Each entry is a little tree: the level tag — `[INFO]`, `[WARN]`, or `[ERROR]` — on
|
|
45
|
+
top, your message hanging off a `├──` branch, and a short local timestamp
|
|
46
|
+
(month-day, 12-hour time) plus the source location on the `└──` branch below.
|
|
47
|
+
Entries are spaced apart by a blank line so they're easy to scan in a busy terminal.
|
|
43
48
|
|
|
44
49
|
### One thing if you re-export it
|
|
45
50
|
|
|
@@ -59,12 +64,13 @@ export const customLog = (...args) => log(...args)
|
|
|
59
64
|
## Color-coded levels
|
|
60
65
|
|
|
61
66
|
The level tag is colored so you can spot what matters at a glance — `[INFO]` in
|
|
62
|
-
cyan, `[WARN]` in yellow, `[ERROR]` in red. The
|
|
63
|
-
|
|
67
|
+
cyan, `[WARN]` in yellow, `[ERROR]` in red. The timestamp and source location are
|
|
68
|
+
tinted teal, and the tree branches sit in a quiet gray, so the colored level tag is
|
|
69
|
+
what your eye lands on first.
|
|
64
70
|
|
|
65
71
|
Colors appear automatically when you're in a terminal. When output is piped to a
|
|
66
|
-
file or another program,
|
|
67
|
-
|
|
72
|
+
file or another program, everything prints as plain text — no stray color codes in
|
|
73
|
+
your log files. Nothing to configure.
|
|
68
74
|
|
|
69
75
|
## Click to open the source
|
|
70
76
|
|
|
@@ -78,6 +84,22 @@ terminal, and when it's piped to a file or another program they quietly drop to
|
|
|
78
84
|
plain `(server.ts:42)` text — so your log files never get cluttered with escape
|
|
79
85
|
codes.
|
|
80
86
|
|
|
87
|
+
## Trimming long messages
|
|
88
|
+
|
|
89
|
+
By default you see everything you log, however long. But if a big object or a
|
|
90
|
+
chatty multi-line message is drowning out your terminal, you can cap how many
|
|
91
|
+
lines each message shows:
|
|
92
|
+
|
|
93
|
+
```ts
|
|
94
|
+
import customLog from "@meadown/logger"
|
|
95
|
+
|
|
96
|
+
customLog.maxLines = 5 // show the first 5 lines, then "... N more lines"
|
|
97
|
+
customLog.maxLines = 0 // back to the default — show everything
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
It only trims the _message_, never the tag, timestamp, or location, and the setting
|
|
101
|
+
applies to `customLog`, `.error`, and `.warn` alike.
|
|
102
|
+
|
|
81
103
|
## What about production?
|
|
82
104
|
|
|
83
105
|
Here's the nice part: you don't have to do anything. Logs show up while you're
|
|
@@ -92,6 +114,14 @@ developing and go silent in production. The only thing that flips the switch is
|
|
|
92
114
|
So leave your logs in the code. Once you ship with `NODE_ENV=production`, they just
|
|
93
115
|
quietly step aside.
|
|
94
116
|
|
|
117
|
+
## Security
|
|
118
|
+
|
|
119
|
+
It's a tiny, zero-dependency package with no file, network, or dynamic-code access.
|
|
120
|
+
See [SECURITY.md](https://github.com/meadown/meadown-logger/blob/main/SECURITY.md)
|
|
121
|
+
for the security model and how to report a vulnerability. One thing to know: like
|
|
122
|
+
`console.log`, log arguments are written to the terminal as-is and are not
|
|
123
|
+
sanitized — don't log untrusted data to a terminal you trust.
|
|
124
|
+
|
|
95
125
|
## License
|
|
96
126
|
|
|
97
|
-
MIT ©
|
|
127
|
+
MIT © meadown
|
package/SECURITY.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
# Security Policy
|
|
2
|
+
|
|
3
|
+
## Reporting a vulnerability
|
|
4
|
+
|
|
5
|
+
Please report security issues **privately** by email to
|
|
6
|
+
[inbox.meadown@gmail.com](mailto:inbox.meadown@gmail.com).
|
|
7
|
+
|
|
8
|
+
Include a description, the affected version, and steps to reproduce. We aim to
|
|
9
|
+
acknowledge reports within a few days and to coordinate a fix and disclosure.
|
|
10
|
+
|
|
11
|
+
> Once this repository is public, reports can also be filed via GitHub Security
|
|
12
|
+
> Advisories ("Report a vulnerability" under the Security tab).
|
|
13
|
+
|
|
14
|
+
## Supported versions
|
|
15
|
+
|
|
16
|
+
Only the latest published `@meadown/logger` release receives security fixes.
|
|
17
|
+
|
|
18
|
+
## Security model
|
|
19
|
+
|
|
20
|
+
`@meadown/logger` is intentionally minimal, which keeps its attack surface small:
|
|
21
|
+
|
|
22
|
+
- **Zero runtime dependencies.** Installing the package pulls in no transitive
|
|
23
|
+
packages, so there is no third-party supply-chain surface to inherit.
|
|
24
|
+
- **No I/O or dynamic execution.** It does not read or write files, open network
|
|
25
|
+
connections, spawn processes, or use `eval`/`Function`. It only writes to the
|
|
26
|
+
console and reads `process.env.NODE_ENV` (to stay quiet in production).
|
|
27
|
+
- **Nothing is persisted.** Log output is never written to disk, so the logger
|
|
28
|
+
cannot leak logged data to a temp file or similar.
|
|
29
|
+
|
|
30
|
+
## Trust boundary: log arguments are output, not input
|
|
31
|
+
|
|
32
|
+
Like `console.log` itself, this logger passes the arguments you give it through
|
|
33
|
+
to the terminal as output. **It does not sanitize them.**
|
|
34
|
+
|
|
35
|
+
If you log **untrusted data** (user input, third-party API responses, etc.) that
|
|
36
|
+
contains terminal control or escape sequences (ANSI `\x1b[…`, OSC-8 hyperlinks,
|
|
37
|
+
carriage returns), those sequences reach the terminal and can manipulate it —
|
|
38
|
+
e.g. overwrite previously printed text or spoof a clickable link. This is an
|
|
39
|
+
inherent property of writing untrusted text to a terminal, not specific to this
|
|
40
|
+
package.
|
|
41
|
+
|
|
42
|
+
Guidance:
|
|
43
|
+
|
|
44
|
+
- Treat log output as you would any other untrusted text rendered in a terminal.
|
|
45
|
+
- Do not log raw untrusted input to a terminal or log stream you treat as
|
|
46
|
+
trusted; sanitize or encode it first if that is a concern in your environment.
|
|
47
|
+
|
|
48
|
+
The clickable source link the logger emits is built from the runtime call
|
|
49
|
+
stack's file path (encoded via `node:url`'s `pathToFileURL`), not from your
|
|
50
|
+
arguments, so the logger's own escape sequences are not attacker-influenced.
|
package/dist/cjs/index.d.ts
CHANGED
|
@@ -3,15 +3,12 @@ export interface LogFN {
|
|
|
3
3
|
(...args: unknown[]): void;
|
|
4
4
|
error(...args: unknown[]): void;
|
|
5
5
|
warn(...args: unknown[]): void;
|
|
6
|
+
/**
|
|
7
|
+
* How many lines of a multi-line message to show before collapsing the rest
|
|
8
|
+
* into a `… N more lines` summary. `0` (the default) shows everything.
|
|
9
|
+
*/
|
|
10
|
+
maxLines: number;
|
|
6
11
|
}
|
|
7
|
-
/**
|
|
8
|
-
* Logs to the console, but only outside production. Each line is prefixed with
|
|
9
|
-
* a level tag, a local AM/PM timestamp with timezone, and a clickable link to
|
|
10
|
-
* the file it was called from; all arguments are then printed as-is.
|
|
11
|
-
* @example
|
|
12
|
-
* customLog("Auth", "user logged in")
|
|
13
|
-
* // [INFO] 2026-05-30 04:00:00 PM GMT+6 (server.ts:42) Auth user logged in
|
|
14
|
-
*/
|
|
15
12
|
declare const customLog: LogFN;
|
|
16
13
|
export { customLog };
|
|
17
14
|
export default customLog;
|
package/dist/cjs/index.js
CHANGED
|
@@ -10,15 +10,26 @@ exports.customLog = void 0;
|
|
|
10
10
|
const index_js_1 = require("./utils/index.js");
|
|
11
11
|
/**
|
|
12
12
|
* Logs to the console, but only outside production. Each line is prefixed with
|
|
13
|
-
* a level tag, a local
|
|
14
|
-
*
|
|
13
|
+
* a level tag, a short local timestamp, and a clickable link to the file it was
|
|
14
|
+
* called from; all arguments are then printed as-is.
|
|
15
15
|
* @example
|
|
16
16
|
* customLog("Auth", "user logged in")
|
|
17
|
-
* // [INFO]
|
|
17
|
+
* // [INFO] 05-30 04:00:00 PM (server.ts:42) Auth user logged in
|
|
18
|
+
* @example
|
|
19
|
+
* customLog.maxLines = 5 // long messages collapse to 5 lines; 0 = show all
|
|
18
20
|
*/
|
|
19
|
-
const
|
|
21
|
+
const logger = Object.assign((0, index_js_1.createLog)("log", "[INFO]"), {
|
|
20
22
|
error: (0, index_js_1.createLog)("error", "[ERROR]"),
|
|
21
23
|
warn: (0, index_js_1.createLog)("warn", "[WARN]"),
|
|
22
24
|
});
|
|
25
|
+
// `maxLines` is a live getter/setter backed by the shared collapse setting, so
|
|
26
|
+
// setting it once affects info, error, and warn alike.
|
|
27
|
+
Object.defineProperty(logger, "maxLines", {
|
|
28
|
+
get: index_js_1.getVisibleLines,
|
|
29
|
+
set: index_js_1.setVisibleLines,
|
|
30
|
+
enumerable: true,
|
|
31
|
+
configurable: true,
|
|
32
|
+
});
|
|
33
|
+
const customLog = logger;
|
|
23
34
|
exports.customLog = customLog;
|
|
24
35
|
exports.default = customLog;
|
|
@@ -4,7 +4,8 @@ declare const CODES: {
|
|
|
4
4
|
readonly yellow: 33;
|
|
5
5
|
readonly cyan: 36;
|
|
6
6
|
readonly gray: 90;
|
|
7
|
-
readonly
|
|
7
|
+
readonly teal: "38;5;30";
|
|
8
|
+
readonly dimTeal: "38;5;23";
|
|
8
9
|
};
|
|
9
10
|
/** The named colors/styles {@link colorize} understands. */
|
|
10
11
|
export type Color = keyof typeof CODES;
|
package/dist/cjs/utils/color.js
CHANGED
|
@@ -1,5 +1,9 @@
|
|
|
1
1
|
/** The console channels the logger writes to. */
|
|
2
2
|
export type LogChannel = "log" | "error" | "warn";
|
|
3
|
+
/** How many lines a long message shows before collapsing (0 = all). */
|
|
4
|
+
export declare function getVisibleLines(): number;
|
|
5
|
+
/** Set how many lines a long message shows before collapsing (0 = all). */
|
|
6
|
+
export declare function setVisibleLines(value: number): void;
|
|
3
7
|
/**
|
|
4
8
|
* Builds a log function bound to a console channel and tag. The returned closure
|
|
5
9
|
* is what the caller invokes directly, so {@link getCaller} still resolves the
|
|
@@ -9,7 +9,10 @@ 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.getVisibleLines = getVisibleLines;
|
|
13
|
+
exports.setVisibleLines = setVisibleLines;
|
|
12
14
|
exports.default = createLog;
|
|
15
|
+
const node_util_1 = require("node:util");
|
|
13
16
|
const getCaller_js_1 = __importDefault(require("./getCaller.js"));
|
|
14
17
|
const getTimeStamp_js_1 = __importDefault(require("./getTimeStamp.js"));
|
|
15
18
|
const link_js_1 = require("./link.js");
|
|
@@ -21,6 +24,46 @@ const TAG_COLOR = {
|
|
|
21
24
|
warn: "yellow",
|
|
22
25
|
error: "red",
|
|
23
26
|
};
|
|
27
|
+
/** Visible width of the `└── ` branch; message lines left-align under it. */
|
|
28
|
+
const MESSAGE_INDENT = " ";
|
|
29
|
+
/** Max message lines to show before collapsing the rest; 0 (default) shows all. */
|
|
30
|
+
let visibleLines = 0;
|
|
31
|
+
/** How many lines a long message shows before collapsing (0 = all). */
|
|
32
|
+
function getVisibleLines() {
|
|
33
|
+
return visibleLines;
|
|
34
|
+
}
|
|
35
|
+
/** Set how many lines a long message shows before collapsing (0 = all). */
|
|
36
|
+
function setVisibleLines(value) {
|
|
37
|
+
visibleLines = Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Collapses a long multi-line message to {@link visibleLines} lines, replacing
|
|
41
|
+
* the rest with a dimmed `… N more lines` summary. When `visibleLines` is 0
|
|
42
|
+
* (the default) nothing is collapsed — the full message is shown.
|
|
43
|
+
*/
|
|
44
|
+
function collapse(text, useColor) {
|
|
45
|
+
if (visibleLines < 1)
|
|
46
|
+
return text;
|
|
47
|
+
const lines = text.split("\n");
|
|
48
|
+
if (lines.length <= visibleLines)
|
|
49
|
+
return text;
|
|
50
|
+
const hidden = lines.length - visibleLines;
|
|
51
|
+
const summary = `${MESSAGE_INDENT}... ${hidden} more line${hidden === 1 ? "" : "s"}`;
|
|
52
|
+
const visible = lines.slice(0, visibleLines);
|
|
53
|
+
visible.push(useColor ? (0, color_js_1.colorize)(summary, "gray") : summary);
|
|
54
|
+
return visible.join("\n");
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Renders the args into a single message string exactly as console would —
|
|
58
|
+
* objects/errors via util.inspect, `%s`/`%d` format specifiers, and colors when
|
|
59
|
+
* on a terminal — then hang-indents every continuation line so multi-line
|
|
60
|
+
* output (multi-line strings, pretty-printed objects, error stacks) all stays
|
|
61
|
+
* left-aligned under the `└── ` branch, and collapses very long output.
|
|
62
|
+
*/
|
|
63
|
+
function renderMessage(args, useColor) {
|
|
64
|
+
const text = (0, node_util_1.formatWithOptions)({ colors: useColor }, ...args);
|
|
65
|
+
return collapse(text.replace(/\n/g, `\n${MESSAGE_INDENT}`), useColor);
|
|
66
|
+
}
|
|
24
67
|
/**
|
|
25
68
|
* Renders a caller as a `(file:line)` location. When the terminal supports
|
|
26
69
|
* OSC-8 hyperlinks, the location is a clickable link to the source file while
|
|
@@ -49,15 +92,25 @@ function createLog(channel, tag) {
|
|
|
49
92
|
return;
|
|
50
93
|
const caller = (0, getCaller_js_1.default)();
|
|
51
94
|
const location = formatLocation(caller, streamName);
|
|
52
|
-
//
|
|
53
|
-
//
|
|
95
|
+
// Colors (terminal only): tag by level, timestamp teal, location dim teal,
|
|
96
|
+
// branch and separator gray.
|
|
54
97
|
const useColor = (0, color_js_1.supportsColor)(streamName);
|
|
55
|
-
const
|
|
56
|
-
const
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
98
|
+
const tagOut = useColor ? (0, color_js_1.colorize)(tag, TAG_COLOR[channel]) : tag;
|
|
99
|
+
const timeStamp = useColor
|
|
100
|
+
? (0, color_js_1.colorize)((0, getTimeStamp_js_1.default)(), "teal")
|
|
101
|
+
: (0, getTimeStamp_js_1.default)();
|
|
102
|
+
const locOut = useColor
|
|
103
|
+
? (0, color_js_1.colorize)(`(${location})`, "dimTeal")
|
|
104
|
+
: `(${location})`;
|
|
105
|
+
const connector = useColor ? (0, color_js_1.colorize)("├──", "gray") : "└──";
|
|
106
|
+
const connectorBottom = useColor ? (0, color_js_1.colorize)("└──", "gray") : "└──";
|
|
107
|
+
const separator = useColor ? (0, color_js_1.colorize)("-", "gray") : "-";
|
|
108
|
+
// Layout: the tag, the message hanging off a `├──` branch, then the
|
|
109
|
+
// timestamp and location on a `└──` branch below.
|
|
110
|
+
const message = renderMessage(args, useColor);
|
|
111
|
+
const meta = `\n${connectorBottom} ${timeStamp} ${separator} ${locOut}`;
|
|
112
|
+
// Leading `\n` puts a blank line above each entry — in the same call and on
|
|
113
|
+
// the right stream (a separate `console.log` would always hit stdout).
|
|
114
|
+
console[channel](`\n${tagOut}`, `\n${connector}`, message, meta);
|
|
62
115
|
};
|
|
63
116
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns
|
|
3
|
-
*
|
|
4
|
-
* stay consistent.
|
|
2
|
+
* Returns a short local timestamp: month-day plus 12-hour time, e.g.
|
|
3
|
+
* `05-30 04:00:00 PM`. The year and timezone are dropped to keep log lines
|
|
4
|
+
* compact; date and time are both local so they stay consistent.
|
|
5
5
|
*/
|
|
6
6
|
export default function getTimeStamp(date?: Date): string;
|
|
@@ -7,23 +7,22 @@
|
|
|
7
7
|
*/
|
|
8
8
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
9
|
exports.default = getTimeStamp;
|
|
10
|
-
// Time-only formatter (date is built separately
|
|
10
|
+
// Time-only 12-hour formatter (date is built separately, timezone is dropped).
|
|
11
11
|
const TIME_FORMATTER = new Intl.DateTimeFormat("en-US", {
|
|
12
12
|
hour: "2-digit",
|
|
13
13
|
minute: "2-digit",
|
|
14
14
|
second: "2-digit",
|
|
15
15
|
hour12: true,
|
|
16
|
-
timeZoneName: "short",
|
|
17
16
|
});
|
|
18
17
|
function pad(value) {
|
|
19
18
|
return String(value).padStart(2, "0");
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
|
-
* Returns
|
|
23
|
-
*
|
|
24
|
-
* stay consistent.
|
|
21
|
+
* Returns a short local timestamp: month-day plus 12-hour time, e.g.
|
|
22
|
+
* `05-30 04:00:00 PM`. The year and timezone are dropped to keep log lines
|
|
23
|
+
* compact; date and time are both local so they stay consistent.
|
|
25
24
|
*/
|
|
26
25
|
function getTimeStamp(date = new Date()) {
|
|
27
|
-
const datePart = `${
|
|
26
|
+
const datePart = `${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
28
27
|
return `${datePart} ${TIME_FORMATTER.format(date)}`;
|
|
29
28
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as createLog, type LogChannel } from "./createLog.js";
|
|
1
|
+
export { default as createLog, getVisibleLines, setVisibleLines, 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";
|
package/dist/cjs/utils/index.js
CHANGED
|
@@ -9,9 +9,11 @@ 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.supportsColor = exports.colorize = 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.setVisibleLines = exports.getVisibleLines = 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
|
+
Object.defineProperty(exports, "getVisibleLines", { enumerable: true, get: function () { return createLog_js_1.getVisibleLines; } });
|
|
16
|
+
Object.defineProperty(exports, "setVisibleLines", { enumerable: true, get: function () { return createLog_js_1.setVisibleLines; } });
|
|
15
17
|
var getCaller_js_1 = require("./getCaller.js");
|
|
16
18
|
Object.defineProperty(exports, "getCaller", { enumerable: true, get: function () { return __importDefault(getCaller_js_1).default; } });
|
|
17
19
|
var getTimeStamp_js_1 = require("./getTimeStamp.js");
|
package/dist/index.d.ts
CHANGED
|
@@ -3,15 +3,12 @@ export interface LogFN {
|
|
|
3
3
|
(...args: unknown[]): void;
|
|
4
4
|
error(...args: unknown[]): void;
|
|
5
5
|
warn(...args: unknown[]): void;
|
|
6
|
+
/**
|
|
7
|
+
* How many lines of a multi-line message to show before collapsing the rest
|
|
8
|
+
* into a `… N more lines` summary. `0` (the default) shows everything.
|
|
9
|
+
*/
|
|
10
|
+
maxLines: number;
|
|
6
11
|
}
|
|
7
|
-
/**
|
|
8
|
-
* Logs to the console, but only outside production. Each line is prefixed with
|
|
9
|
-
* a level tag, a local AM/PM timestamp with timezone, and a clickable link to
|
|
10
|
-
* the file it was called from; all arguments are then printed as-is.
|
|
11
|
-
* @example
|
|
12
|
-
* customLog("Auth", "user logged in")
|
|
13
|
-
* // [INFO] 2026-05-30 04:00:00 PM GMT+6 (server.ts:42) Auth user logged in
|
|
14
|
-
*/
|
|
15
12
|
declare const customLog: LogFN;
|
|
16
13
|
export { customLog };
|
|
17
14
|
export default customLog;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,gFAAgF;AAChF,MAAM,WAAW,KAAK;IACpB,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AASA,gFAAgF;AAChF,MAAM,WAAW,KAAK;IACpB,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC1B,KAAK,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC/B,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,EAAE,GAAG,IAAI,CAAA;IAC9B;;;OAGG;IACH,QAAQ,EAAE,MAAM,CAAA;CACjB;AA0BD,QAAA,MAAM,SAAS,EAAa,KAAK,CAAA;AAEjC,OAAO,EAAE,SAAS,EAAE,CAAA;AACpB,eAAe,SAAS,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -4,19 +4,30 @@
|
|
|
4
4
|
* Copyright (c) 2026 dewan-meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
|
-
import { createLog } from "./utils/index.js";
|
|
7
|
+
import { createLog, getVisibleLines, setVisibleLines } from "./utils/index.js";
|
|
8
8
|
/**
|
|
9
9
|
* Logs to the console, but only outside production. Each line is prefixed with
|
|
10
|
-
* a level tag, a local
|
|
11
|
-
*
|
|
10
|
+
* a level tag, a short local timestamp, and a clickable link to the file it was
|
|
11
|
+
* called from; all arguments are then printed as-is.
|
|
12
12
|
* @example
|
|
13
13
|
* customLog("Auth", "user logged in")
|
|
14
|
-
* // [INFO]
|
|
14
|
+
* // [INFO] 05-30 04:00:00 PM (server.ts:42) Auth user logged in
|
|
15
|
+
* @example
|
|
16
|
+
* customLog.maxLines = 5 // long messages collapse to 5 lines; 0 = show all
|
|
15
17
|
*/
|
|
16
|
-
const
|
|
18
|
+
const logger = Object.assign(createLog("log", "[INFO]"), {
|
|
17
19
|
error: createLog("error", "[ERROR]"),
|
|
18
20
|
warn: createLog("warn", "[WARN]"),
|
|
19
21
|
});
|
|
22
|
+
// `maxLines` is a live getter/setter backed by the shared collapse setting, so
|
|
23
|
+
// setting it once affects info, error, and warn alike.
|
|
24
|
+
Object.defineProperty(logger, "maxLines", {
|
|
25
|
+
get: getVisibleLines,
|
|
26
|
+
set: setVisibleLines,
|
|
27
|
+
enumerable: true,
|
|
28
|
+
configurable: true,
|
|
29
|
+
});
|
|
30
|
+
const customLog = logger;
|
|
20
31
|
export { customLog };
|
|
21
32
|
export default customLog;
|
|
22
33
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAA;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAA;AAc9E;;;;;;;;;GASG;AACH,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE;IACvD,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC;IACpC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC;CAClC,CAAC,CAAA;AAEF,+EAA+E;AAC/E,uDAAuD;AACvD,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,UAAU,EAAE;IACxC,GAAG,EAAE,eAAe;IACpB,GAAG,EAAE,eAAe;IACpB,UAAU,EAAE,IAAI;IAChB,YAAY,EAAE,IAAI;CACnB,CAAC,CAAA;AAEF,MAAM,SAAS,GAAG,MAAe,CAAA;AAEjC,OAAO,EAAE,SAAS,EAAE,CAAA;AACpB,eAAe,SAAS,CAAA"}
|
package/dist/utils/color.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ declare const CODES: {
|
|
|
4
4
|
readonly yellow: 33;
|
|
5
5
|
readonly cyan: 36;
|
|
6
6
|
readonly gray: 90;
|
|
7
|
-
readonly
|
|
7
|
+
readonly teal: "38;5;30";
|
|
8
|
+
readonly dimTeal: "38;5;23";
|
|
8
9
|
};
|
|
9
10
|
/** The named colors/styles {@link colorize} understands. */
|
|
10
11
|
export type Color = keyof typeof CODES;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/utils/color.ts"],"names":[],"mappings":"AAOA,4DAA4D;AAC5D,QAAA,MAAM,KAAK
|
|
1
|
+
{"version":3,"file":"color.d.ts","sourceRoot":"","sources":["../../src/utils/color.ts"],"names":[],"mappings":"AAOA,4DAA4D;AAC5D,QAAA,MAAM,KAAK;;;;;;;CAOD,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"}
|
package/dist/utils/color.js
CHANGED
package/dist/utils/color.js.map
CHANGED
|
@@ -1 +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,IAAI,EAAE,EAAE,EAAE,uCAAuC;IACjD,
|
|
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,IAAI,EAAE,EAAE,EAAE,uCAAuC;IACjD,IAAI,EAAE,SAAS,EAAE,2BAA2B;IAC5C,OAAO,EAAE,SAAS,EAAE,kCAAkC;CAC9C,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,5 +1,9 @@
|
|
|
1
1
|
/** The console channels the logger writes to. */
|
|
2
2
|
export type LogChannel = "log" | "error" | "warn";
|
|
3
|
+
/** How many lines a long message shows before collapsing (0 = all). */
|
|
4
|
+
export declare function getVisibleLines(): number;
|
|
5
|
+
/** Set how many lines a long message shows before collapsing (0 = all). */
|
|
6
|
+
export declare function setVisibleLines(value: number): void;
|
|
3
7
|
/**
|
|
4
8
|
* Builds a log function bound to a console channel and tag. The returned closure
|
|
5
9
|
* is what the caller invokes directly, so {@link getCaller} still resolves the
|
|
@@ -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":"AAeA,iDAAiD;AACjD,MAAM,MAAM,UAAU,GAAG,KAAK,GAAG,OAAO,GAAG,MAAM,CAAA;AAejD,uEAAuE;AACvE,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAED,2EAA2E;AAC3E,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,CAEnD;AAkDD;;;;;;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,CA8B9B"}
|
package/dist/utils/createLog.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Copyright (c) 2026 dewan-meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
|
+
import { formatWithOptions } from "node:util";
|
|
7
8
|
import getCaller from "./getCaller.js";
|
|
8
9
|
import getTimeStamp from "./getTimeStamp.js";
|
|
9
10
|
import { fileUrl, hyperlink, supportsHyperlinks } from "./link.js";
|
|
@@ -15,6 +16,46 @@ const TAG_COLOR = {
|
|
|
15
16
|
warn: "yellow",
|
|
16
17
|
error: "red",
|
|
17
18
|
};
|
|
19
|
+
/** Visible width of the `└── ` branch; message lines left-align under it. */
|
|
20
|
+
const MESSAGE_INDENT = " ";
|
|
21
|
+
/** Max message lines to show before collapsing the rest; 0 (default) shows all. */
|
|
22
|
+
let visibleLines = 0;
|
|
23
|
+
/** How many lines a long message shows before collapsing (0 = all). */
|
|
24
|
+
export function getVisibleLines() {
|
|
25
|
+
return visibleLines;
|
|
26
|
+
}
|
|
27
|
+
/** Set how many lines a long message shows before collapsing (0 = all). */
|
|
28
|
+
export function setVisibleLines(value) {
|
|
29
|
+
visibleLines = Number.isFinite(value) && value > 0 ? Math.floor(value) : 0;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Collapses a long multi-line message to {@link visibleLines} lines, replacing
|
|
33
|
+
* the rest with a dimmed `… N more lines` summary. When `visibleLines` is 0
|
|
34
|
+
* (the default) nothing is collapsed — the full message is shown.
|
|
35
|
+
*/
|
|
36
|
+
function collapse(text, useColor) {
|
|
37
|
+
if (visibleLines < 1)
|
|
38
|
+
return text;
|
|
39
|
+
const lines = text.split("\n");
|
|
40
|
+
if (lines.length <= visibleLines)
|
|
41
|
+
return text;
|
|
42
|
+
const hidden = lines.length - visibleLines;
|
|
43
|
+
const summary = `${MESSAGE_INDENT}... ${hidden} more line${hidden === 1 ? "" : "s"}`;
|
|
44
|
+
const visible = lines.slice(0, visibleLines);
|
|
45
|
+
visible.push(useColor ? colorize(summary, "gray") : summary);
|
|
46
|
+
return visible.join("\n");
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Renders the args into a single message string exactly as console would —
|
|
50
|
+
* objects/errors via util.inspect, `%s`/`%d` format specifiers, and colors when
|
|
51
|
+
* on a terminal — then hang-indents every continuation line so multi-line
|
|
52
|
+
* output (multi-line strings, pretty-printed objects, error stacks) all stays
|
|
53
|
+
* left-aligned under the `└── ` branch, and collapses very long output.
|
|
54
|
+
*/
|
|
55
|
+
function renderMessage(args, useColor) {
|
|
56
|
+
const text = formatWithOptions({ colors: useColor }, ...args);
|
|
57
|
+
return collapse(text.replace(/\n/g, `\n${MESSAGE_INDENT}`), useColor);
|
|
58
|
+
}
|
|
18
59
|
/**
|
|
19
60
|
* Renders a caller as a `(file:line)` location. When the terminal supports
|
|
20
61
|
* OSC-8 hyperlinks, the location is a clickable link to the source file while
|
|
@@ -43,16 +84,26 @@ export default function createLog(channel, tag) {
|
|
|
43
84
|
return;
|
|
44
85
|
const caller = getCaller();
|
|
45
86
|
const location = formatLocation(caller, streamName);
|
|
46
|
-
//
|
|
47
|
-
//
|
|
87
|
+
// Colors (terminal only): tag by level, timestamp teal, location dim teal,
|
|
88
|
+
// branch and separator gray.
|
|
48
89
|
const useColor = supportsColor(streamName);
|
|
49
|
-
const
|
|
50
|
-
const
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
90
|
+
const tagOut = useColor ? colorize(tag, TAG_COLOR[channel]) : tag;
|
|
91
|
+
const timeStamp = useColor
|
|
92
|
+
? colorize(getTimeStamp(), "teal")
|
|
93
|
+
: getTimeStamp();
|
|
94
|
+
const locOut = useColor
|
|
95
|
+
? colorize(`(${location})`, "dimTeal")
|
|
96
|
+
: `(${location})`;
|
|
97
|
+
const connector = useColor ? colorize("├──", "gray") : "└──";
|
|
98
|
+
const connectorBottom = useColor ? colorize("└──", "gray") : "└──";
|
|
99
|
+
const separator = useColor ? colorize("-", "gray") : "-";
|
|
100
|
+
// Layout: the tag, the message hanging off a `├──` branch, then the
|
|
101
|
+
// timestamp and location on a `└──` branch below.
|
|
102
|
+
const message = renderMessage(args, useColor);
|
|
103
|
+
const meta = `\n${connectorBottom} ${timeStamp} ${separator} ${locOut}`;
|
|
104
|
+
// Leading `\n` puts a blank line above each entry — in the same call and on
|
|
105
|
+
// the right stream (a separate `console.log` would always hit stdout).
|
|
106
|
+
console[channel](`\n${tagOut}`, `\n${connector}`, message, meta);
|
|
56
107
|
};
|
|
57
108
|
}
|
|
58
109
|
//# 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,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;;;;;;GAMG;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,
|
|
1
|
+
{"version":3,"file":"createLog.js","sourceRoot":"","sources":["../../src/utils/createLog.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Returns
|
|
3
|
-
*
|
|
4
|
-
* stay consistent.
|
|
2
|
+
* Returns a short local timestamp: month-day plus 12-hour time, e.g.
|
|
3
|
+
* `05-30 04:00:00 PM`. The year and timezone are dropped to keep log lines
|
|
4
|
+
* compact; date and time are both local so they stay consistent.
|
|
5
5
|
*/
|
|
6
6
|
export default function getTimeStamp(date?: Date): string;
|
|
7
7
|
//# sourceMappingURL=getTimeStamp.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTimeStamp.d.ts","sourceRoot":"","sources":["../../src/utils/getTimeStamp.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"getTimeStamp.d.ts","sourceRoot":"","sources":["../../src/utils/getTimeStamp.ts"],"names":[],"mappings":"AAmBA;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,IAAI,OAAa,GAAG,MAAM,CAG9D"}
|
|
@@ -4,24 +4,23 @@
|
|
|
4
4
|
* Copyright (c) 2026 dewan-meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
|
-
// Time-only formatter (date is built separately
|
|
7
|
+
// Time-only 12-hour formatter (date is built separately, timezone is dropped).
|
|
8
8
|
const TIME_FORMATTER = new Intl.DateTimeFormat("en-US", {
|
|
9
9
|
hour: "2-digit",
|
|
10
10
|
minute: "2-digit",
|
|
11
11
|
second: "2-digit",
|
|
12
12
|
hour12: true,
|
|
13
|
-
timeZoneName: "short",
|
|
14
13
|
});
|
|
15
14
|
function pad(value) {
|
|
16
15
|
return String(value).padStart(2, "0");
|
|
17
16
|
}
|
|
18
17
|
/**
|
|
19
|
-
* Returns
|
|
20
|
-
*
|
|
21
|
-
* stay consistent.
|
|
18
|
+
* Returns a short local timestamp: month-day plus 12-hour time, e.g.
|
|
19
|
+
* `05-30 04:00:00 PM`. The year and timezone are dropped to keep log lines
|
|
20
|
+
* compact; date and time are both local so they stay consistent.
|
|
22
21
|
*/
|
|
23
22
|
export default function getTimeStamp(date = new Date()) {
|
|
24
|
-
const datePart = `${
|
|
23
|
+
const datePart = `${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
25
24
|
return `${datePart} ${TIME_FORMATTER.format(date)}`;
|
|
26
25
|
}
|
|
27
26
|
//# sourceMappingURL=getTimeStamp.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"getTimeStamp.js","sourceRoot":"","sources":["../../src/utils/getTimeStamp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+EAA+E;AAC/E,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;IACtD,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,IAAI;
|
|
1
|
+
{"version":3,"file":"getTimeStamp.js","sourceRoot":"","sources":["../../src/utils/getTimeStamp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+EAA+E;AAC/E,MAAM,cAAc,GAAG,IAAI,IAAI,CAAC,cAAc,CAAC,OAAO,EAAE;IACtD,IAAI,EAAE,SAAS;IACf,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,SAAS;IACjB,MAAM,EAAE,IAAI;CACb,CAAC,CAAA;AAEF,SAAS,GAAG,CAAC,KAAa;IACxB,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;AACvC,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY,CAAC,IAAI,GAAG,IAAI,IAAI,EAAE;IACpD,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC,IAAI,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,IAAI,GAAG,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAA;IACrE,OAAO,GAAG,QAAQ,IAAI,cAAc,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAA;AACrD,CAAC"}
|
package/dist/utils/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { default as createLog, type LogChannel } from "./createLog.js";
|
|
1
|
+
export { default as createLog, getVisibleLines, setVisibleLines, 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";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAOA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,OAAO,IAAI,SAAS,EACpB,eAAe,EACf,eAAe,EACf,KAAK,UAAU,GAChB,MAAM,gBAAgB,CAAA;AACvB,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
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
* Copyright (c) 2026 dewan-meadown
|
|
5
5
|
* All rights reserved
|
|
6
6
|
*/
|
|
7
|
-
export { default as createLog } from "./createLog.js";
|
|
7
|
+
export { default as createLog, getVisibleLines, setVisibleLines, } 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";
|
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,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EACL,OAAO,IAAI,SAAS,EACpB,eAAe,EACf,eAAe,GAEhB,MAAM,gBAAgB,CAAA;AACvB,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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meadown/logger",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.5.1",
|
|
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",
|
|
@@ -39,7 +39,8 @@
|
|
|
39
39
|
}
|
|
40
40
|
},
|
|
41
41
|
"files": [
|
|
42
|
-
"dist"
|
|
42
|
+
"dist",
|
|
43
|
+
"SECURITY.md"
|
|
43
44
|
],
|
|
44
45
|
"engines": {
|
|
45
46
|
"node": ">=18"
|
|
@@ -52,6 +53,7 @@
|
|
|
52
53
|
"test": "tsc && node --test \"test/**/*.test.mjs\"",
|
|
53
54
|
"lint": "eslint src",
|
|
54
55
|
"lint:fix": "eslint src --fix",
|
|
56
|
+
"demo": "pnpm build && node examples/demo.mjs",
|
|
55
57
|
"prepublishOnly": "pnpm run lint && pnpm test && pnpm run build",
|
|
56
58
|
"prepare": "husky",
|
|
57
59
|
"release": "semantic-release"
|