@meadown/logger 1.0.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 +21 -0
- package/README.md +58 -0
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/utils/getFileName.d.ts +6 -0
- package/dist/utils/getFileName.d.ts.map +1 -0
- package/dist/utils/getFileName.js +17 -0
- package/dist/utils/getFileName.js.map +1 -0
- package/dist/utils/getTimeStamp.d.ts +3 -0
- package/dist/utils/getTimeStamp.d.ts.map +1 -0
- package/dist/utils/getTimeStamp.js +11 -0
- package/dist/utils/getTimeStamp.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +9 -0
- package/dist/utils/index.js.map +1 -0
- package/package.json +70 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Dewan Mobashirul
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# @meadown/logger
|
|
2
|
+
|
|
3
|
+
I kept writing `console.log` everywhere, then squinting at my terminal trying to
|
|
4
|
+
remember _which file_ a message came from — and worse, forgetting to pull those logs
|
|
5
|
+
out before shipping. So I made this.
|
|
6
|
+
|
|
7
|
+
It's basically `console.log` with the rough edges sanded off: every message gets a
|
|
8
|
+
label, a timestamp, and the file and line it came from. And it stays quiet in
|
|
9
|
+
production, so you can leave your logs where they are and not worry about them.
|
|
10
|
+
|
|
11
|
+
No dependencies. No config. Import it and you're done.
|
|
12
|
+
|
|
13
|
+
## Install
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm install @meadown/logger
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Using it
|
|
20
|
+
|
|
21
|
+
```ts
|
|
22
|
+
import customLog from "@meadown/logger"
|
|
23
|
+
|
|
24
|
+
customLog("Hello world")
|
|
25
|
+
customLog("Auth", "user logged in") // first word can be a label, if you want one
|
|
26
|
+
|
|
27
|
+
customLog.warn("This is deprecated")
|
|
28
|
+
customLog.error("Something went wrong")
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You'll see something like:
|
|
32
|
+
|
|
33
|
+
```text
|
|
34
|
+
[INFO] 2026-05-30T10:00:00.000Z (server.ts:42) Auth user logged in
|
|
35
|
+
[WARN] 2026-05-30T10:00:00.000Z (server.ts:51) This is deprecated
|
|
36
|
+
[ERROR] 2026-05-30T10:00:00.000Z (server.ts:60) Something went wrong
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
That `(server.ts:42)` bit is the part I missed most with plain `console.log` —
|
|
40
|
+
no more hunting for where a message came from.
|
|
41
|
+
|
|
42
|
+
## What about production?
|
|
43
|
+
|
|
44
|
+
Here's the nice part: you don't have to do anything. Logs show up while you're
|
|
45
|
+
developing and go silent in production. The only thing that flips the switch is your
|
|
46
|
+
`NODE_ENV`:
|
|
47
|
+
|
|
48
|
+
| `NODE_ENV` | Logs? |
|
|
49
|
+
| ---------------------------------------- | ------ |
|
|
50
|
+
| not set, `development`, or anything else | shown |
|
|
51
|
+
| `production` | silent |
|
|
52
|
+
|
|
53
|
+
So leave your logs in the code. Once you ship with `NODE_ENV=production`, they just
|
|
54
|
+
quietly step aside.
|
|
55
|
+
|
|
56
|
+
## License
|
|
57
|
+
|
|
58
|
+
MIT © Dewan Mobashirul
|
package/dist/config.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Logging is enabled in every environment except production, read directly
|
|
3
|
+
* from `process.env.NODE_ENV`. No configuration — set `NODE_ENV=production`
|
|
4
|
+
* in your runtime to silence logs.
|
|
5
|
+
*/
|
|
6
|
+
export declare function isLogAllowed(): boolean;
|
|
7
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAOA;;;;GAIG;AACH,wBAAgB,YAAY,IAAI,OAAO,CAItC"}
|
package/dist/config.js
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* config.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 dewan-meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Logging is enabled in every environment except production, read directly
|
|
9
|
+
* from `process.env.NODE_ENV`. No configuration — set `NODE_ENV=production`
|
|
10
|
+
* in your runtime to silence logs.
|
|
11
|
+
*/
|
|
12
|
+
export function isLogAllowed() {
|
|
13
|
+
// Guard `process` so the logger doesn't throw in non-Node runtimes (browser,
|
|
14
|
+
// edge) where it may be undefined; default to logging when it's absent.
|
|
15
|
+
return typeof process === "undefined" || process.env.NODE_ENV !== "production";
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;;GAIG;AACH,MAAM,UAAU,YAAY;IAC1B,6EAA6E;IAC7E,wEAAwE;IACxE,OAAO,OAAO,OAAO,KAAK,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,YAAY,CAAA;AAChF,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** The logger: a callable for info logs, plus `.error` and `.warn` variants. */
|
|
2
|
+
export interface LogFN {
|
|
3
|
+
(...args: unknown[]): void;
|
|
4
|
+
error(...args: unknown[]): void;
|
|
5
|
+
warn(...args: unknown[]): void;
|
|
6
|
+
}
|
|
7
|
+
/**
|
|
8
|
+
* Logs to the console, but only outside production. Each line is prefixed with
|
|
9
|
+
* an `[INFO]` tag, an ISO timestamp, and the file and line it was called from;
|
|
10
|
+
* all arguments are then printed as-is. `.error` and `.warn` behave the same
|
|
11
|
+
* with their own tags and console channels.
|
|
12
|
+
* @example
|
|
13
|
+
* customLog("Auth", "user logged in")
|
|
14
|
+
* // [INFO] 2026-05-30T10:00:00.000Z (server.ts:42) Auth user logged in
|
|
15
|
+
*/
|
|
16
|
+
declare const customLog: LogFN;
|
|
17
|
+
export default customLog;
|
|
18
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAUA,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;CAC/B;AAmBD;;;;;;;;GAQG;AACH,QAAA,MAAM,SAAS,EAAE,KAGf,CAAA;AAEF,eAAe,SAAS,CAAA"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* index.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 dewan-meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
import { getFileName, getTimeStamp } from "./utils/index.js";
|
|
8
|
+
import { isLogAllowed } from "./config.js";
|
|
9
|
+
/**
|
|
10
|
+
* Builds a log function bound to a console channel and tag. The returned closure
|
|
11
|
+
* is what the caller invokes directly, so {@link getFileName} still resolves the
|
|
12
|
+
* caller's own frame (no extra stack frame is inserted). `console[channel]` is
|
|
13
|
+
* looked up at call time, so reassigning `console.log` (e.g. in tests) is
|
|
14
|
+
* respected. Logs only outside production — see {@link isLogAllowed}.
|
|
15
|
+
*/
|
|
16
|
+
function createLog(channel, tag) {
|
|
17
|
+
return (...args) => {
|
|
18
|
+
if (isLogAllowed())
|
|
19
|
+
console[channel](tag, getTimeStamp(), `(${getFileName()})`, ...args);
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Logs to the console, but only outside production. Each line is prefixed with
|
|
24
|
+
* an `[INFO]` tag, an ISO timestamp, and the file and line it was called from;
|
|
25
|
+
* all arguments are then printed as-is. `.error` and `.warn` behave the same
|
|
26
|
+
* with their own tags and console channels.
|
|
27
|
+
* @example
|
|
28
|
+
* customLog("Auth", "user logged in")
|
|
29
|
+
* // [INFO] 2026-05-30T10:00:00.000Z (server.ts:42) Auth user logged in
|
|
30
|
+
*/
|
|
31
|
+
const customLog = Object.assign(createLog("log", "[INFO]"), {
|
|
32
|
+
error: createLog("error", "[ERROR]"),
|
|
33
|
+
warn: createLog("warn", "[WARN]"),
|
|
34
|
+
});
|
|
35
|
+
export default customLog;
|
|
36
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAS1C;;;;;;GAMG;AACH,SAAS,SAAS,CAChB,OAAiC,EACjC,GAAW;IAEX,OAAO,CAAC,GAAG,IAAe,EAAQ,EAAE;QAClC,IAAI,YAAY,EAAE;YAChB,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,YAAY,EAAE,EAAE,IAAI,WAAW,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,CAAA;IACxE,CAAC,CAAA;AACH,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,SAAS,GAAU,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE;IACjE,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC;IACpC,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC;CAClC,CAAC,CAAA;AAEF,eAAe,SAAS,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getFileName.d.ts","sourceRoot":"","sources":["../../src/utils/getFileName.ts"],"names":[],"mappings":"AAOA;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW,IAAI,MAAM,CAK5C"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* getFileName.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 dewan-meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Returns the caller's source location as `file.ext:line` by reading the call
|
|
9
|
+
* stack, or `"unknown"` if it can't be determined (e.g. minified or eval code).
|
|
10
|
+
*/
|
|
11
|
+
export default function getFileName() {
|
|
12
|
+
const stack = new Error().stack ?? "";
|
|
13
|
+
const line = stack.split("\n")[3] ?? "";
|
|
14
|
+
const match = line.match(/([^/\\]+\.[cm]?[jt]sx?):(\d+)/);
|
|
15
|
+
return match ? match[0] : "unknown";
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=getFileName.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getFileName.js","sourceRoot":"","sources":["../../src/utils/getFileName.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH;;;GAGG;AACH,MAAM,CAAC,OAAO,UAAU,WAAW;IACjC,MAAM,KAAK,GAAG,IAAI,KAAK,EAAE,CAAC,KAAK,IAAI,EAAE,CAAA;IACrC,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IACvC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,CAAA;IACzD,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAA;AACrC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTimeStamp.d.ts","sourceRoot":"","sources":["../../src/utils/getTimeStamp.ts"],"names":[],"mappings":"AAOA,uFAAuF;AACvF,MAAM,CAAC,OAAO,UAAU,YAAY,IAAI,MAAM,CAE7C"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* getTimeStamp.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 dewan-meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
/** Returns the current time as an ISO-8601 string, e.g. `2026-05-30T10:00:00.000Z`. */
|
|
8
|
+
export default function getTimeStamp() {
|
|
9
|
+
return new Date().toISOString();
|
|
10
|
+
}
|
|
11
|
+
//# sourceMappingURL=getTimeStamp.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getTimeStamp.js","sourceRoot":"","sources":["../../src/utils/getTimeStamp.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,uFAAuF;AACvF,MAAM,CAAC,OAAO,UAAU,YAAY;IAClC,OAAO,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAA;AACjC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAA"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* index.ts
|
|
3
|
+
* Created by Dewan Mobashirul
|
|
4
|
+
* Copyright (c) 2026 dewan-meadown
|
|
5
|
+
* All rights reserved
|
|
6
|
+
*/
|
|
7
|
+
export { default as getFileName } from "./getFileName.js";
|
|
8
|
+
export { default as getTimeStamp } from "./getTimeStamp.js";
|
|
9
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/utils/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAA;AACzD,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAA"}
|
package/package.json
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@meadown/logger",
|
|
3
|
+
"version": "1.0.1",
|
|
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
|
+
"keywords": [
|
|
6
|
+
"logger",
|
|
7
|
+
"logging",
|
|
8
|
+
"log",
|
|
9
|
+
"console",
|
|
10
|
+
"typescript",
|
|
11
|
+
"nodejs",
|
|
12
|
+
"zero-dependency",
|
|
13
|
+
"debug"
|
|
14
|
+
],
|
|
15
|
+
"homepage": "https://github.com/meadown/meadown-logger#readme",
|
|
16
|
+
"bugs": {
|
|
17
|
+
"url": "https://github.com/meadown/meadown-logger/issues"
|
|
18
|
+
},
|
|
19
|
+
"repository": {
|
|
20
|
+
"type": "git",
|
|
21
|
+
"url": "git+https://github.com/meadown/meadown-logger.git"
|
|
22
|
+
},
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"author": "Dewan Mobashirul",
|
|
25
|
+
"type": "module",
|
|
26
|
+
"main": "dist/index.js",
|
|
27
|
+
"types": "dist/index.d.ts",
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"files": [
|
|
36
|
+
"dist"
|
|
37
|
+
],
|
|
38
|
+
"engines": {
|
|
39
|
+
"node": ">=18"
|
|
40
|
+
},
|
|
41
|
+
"publishConfig": {
|
|
42
|
+
"access": "public"
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"build": "tsc",
|
|
46
|
+
"test": "tsc && node --test \"test/**/*.test.mjs\"",
|
|
47
|
+
"lint": "eslint src",
|
|
48
|
+
"lint:fix": "eslint src --fix",
|
|
49
|
+
"prepublishOnly": "pnpm run lint && pnpm test && pnpm run build",
|
|
50
|
+
"prepare": "husky",
|
|
51
|
+
"release": "semantic-release"
|
|
52
|
+
},
|
|
53
|
+
"devDependencies": {
|
|
54
|
+
"@commitlint/cli": "^20.5.3",
|
|
55
|
+
"@commitlint/config-conventional": "^20.5.3",
|
|
56
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
57
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
58
|
+
"@semantic-release/git": "^10.0.1",
|
|
59
|
+
"@semantic-release/github": "^12.0.8",
|
|
60
|
+
"@semantic-release/npm": "^13.1.5",
|
|
61
|
+
"@semantic-release/release-notes-generator": "^14.1.1",
|
|
62
|
+
"@types/node": "^25.9.1",
|
|
63
|
+
"conventional-changelog-conventionalcommits": "^9.3.1",
|
|
64
|
+
"eslint": "^10.4.0",
|
|
65
|
+
"husky": "^9.1.7",
|
|
66
|
+
"semantic-release": "^25.0.3",
|
|
67
|
+
"typescript": "^6.0.3",
|
|
68
|
+
"typescript-eslint": "^8.60.0"
|
|
69
|
+
}
|
|
70
|
+
}
|