@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 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
@@ -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"}
@@ -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,6 @@
1
+ /**
2
+ * Returns the caller's source location as `file.ext:line` by reading the call
3
+ * stack, or `"unknown"` if it can't be determined (e.g. minified or eval code).
4
+ */
5
+ export default function getFileName(): string;
6
+ //# sourceMappingURL=getFileName.d.ts.map
@@ -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,3 @@
1
+ /** Returns the current time as an ISO-8601 string, e.g. `2026-05-30T10:00:00.000Z`. */
2
+ export default function getTimeStamp(): string;
3
+ //# sourceMappingURL=getTimeStamp.d.ts.map
@@ -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,3 @@
1
+ export { default as getFileName } from "./getFileName.js";
2
+ export { default as getTimeStamp } from "./getTimeStamp.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -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
+ }