@deployanyway/doggo-log 0.1.0 → 0.2.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/CHANGELOG.md +18 -7
- package/LICENSE +21 -21
- package/README.md +161 -141
- package/bin/cli.js +53 -51
- package/package.json +53 -41
- package/src/index.js +101 -80
- package/src/levels.js +8 -8
package/CHANGELOG.md
CHANGED
|
@@ -1,7 +1,18 @@
|
|
|
1
|
-
# Changelog
|
|
2
|
-
|
|
3
|
-
## 0.
|
|
4
|
-
|
|
5
|
-
-
|
|
6
|
-
-
|
|
7
|
-
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.2.0 — 2026-10-08
|
|
4
|
+
|
|
5
|
+
- Scoped logs, optional barks: Use `logger.child("database")` to create an independent logger with a nested prefix. Enable `{ bark: true }` or CLI `--bark` for dog commentary. JSON preserves the original message and adds a separate `commentary` field. Filtering still suppresses output.
|
|
6
|
+
- Add npm and CI badges to the published README.
|
|
7
|
+
|
|
8
|
+
## 0.1.1 — 2026-10-08
|
|
9
|
+
|
|
10
|
+
- Correct npm installation and npx documentation after the initial publication.
|
|
11
|
+
- Add a searchable, humorous package description and relevant npm keywords.
|
|
12
|
+
- No API, CLI behavior, or dependency changes.
|
|
13
|
+
|
|
14
|
+
## 0.1.0 — 2026-10-08
|
|
15
|
+
|
|
16
|
+
- Six logging methods, level filtering, quiet mode, and custom prefixes.
|
|
17
|
+
- Optional emojis, ANSI colors, timestamps, and JSON output.
|
|
18
|
+
- CLI, tests, documentation, and Node 22/24 CI.
|
package/LICENSE
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2026 Deploy Anyway
|
|
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.
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Deploy Anyway
|
|
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
CHANGED
|
@@ -1,141 +1,161 @@
|
|
|
1
|
-
# doggo-log
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
doglog
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
|
72
|
-
|
|
|
73
|
-
| `
|
|
74
|
-
| `
|
|
75
|
-
| `
|
|
76
|
-
| `
|
|
77
|
-
| `
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
|
99
|
-
|
|
|
100
|
-
| `--
|
|
101
|
-
| `--
|
|
102
|
-
| `--
|
|
103
|
-
| `--
|
|
104
|
-
| `--
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
npm
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
##
|
|
130
|
-
|
|
131
|
-
[
|
|
132
|
-
|
|
133
|
-
##
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
- [
|
|
1
|
+
# doggo-log
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@deployanyway/doggo-log)
|
|
4
|
+
[](https://github.com/DeployAnyway/doggo-log/actions/workflows/ci.yml)
|
|
5
|
+
|
|
6
|
+
A tiny Node.js console logger with JSON output, log levels, and dog emojis. Good logs. Very good logs.
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
🐶 INFO Server started
|
|
10
|
+
🐾 SUCCESS Tests passed
|
|
11
|
+
🦴 WARN API is getting slow
|
|
12
|
+
🚨 ERROR Database connection failed
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
Available on npm. Requires Node 22 or later.
|
|
18
|
+
You can also run from source with Node 22 or 24:
|
|
19
|
+
|
|
20
|
+
```sh
|
|
21
|
+
git clone https://github.com/DeployAnyway/doggo-log.git
|
|
22
|
+
cd doggo-log
|
|
23
|
+
git checkout main
|
|
24
|
+
npm ci
|
|
25
|
+
node examples/basic.js
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Install from npm: `npm install @deployanyway/doggo-log`.
|
|
29
|
+
|
|
30
|
+
## Quick start
|
|
31
|
+
|
|
32
|
+
```js
|
|
33
|
+
import { doglog, createDogLogger } from "@deployanyway/doggo-log";
|
|
34
|
+
|
|
35
|
+
doglog.info("Server started");
|
|
36
|
+
doglog.success("Tests passed");
|
|
37
|
+
doglog.warn("API is getting slow");
|
|
38
|
+
doglog.error("Database connection failed");
|
|
39
|
+
|
|
40
|
+
const logger = createDogLogger({
|
|
41
|
+
timestamp: true,
|
|
42
|
+
level: "debug",
|
|
43
|
+
prefix: "app",
|
|
44
|
+
});
|
|
45
|
+
logger.debug("Listening on port %d", 3000);
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## CLI example
|
|
49
|
+
|
|
50
|
+
```sh
|
|
51
|
+
node bin/cli.js success "Tests passed" --no-emoji
|
|
52
|
+
node bin/cli.js info "Server started" --json --timestamp
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Run with npx: `npx @deployanyway/doggo-log info "Server started"`.
|
|
56
|
+
|
|
57
|
+
## API
|
|
58
|
+
|
|
59
|
+
`doglog` is the default logger. `createDogLogger(options = {})` makes an independent
|
|
60
|
+
logger. Both expose `log`, `info`, `success`, `warn`, `error`, and `debug`.
|
|
61
|
+
Methods accept the same message arguments as Node's `util.format`, including
|
|
62
|
+
format placeholders, objects, and Error instances. Zero arguments log the label
|
|
63
|
+
alone. Each method returns its emitted string, or undefined if filtered/quiet.
|
|
64
|
+
|
|
65
|
+
Default output sends warn/error to stderr and other methods to stdout. Logging
|
|
66
|
+
an error does not set an exit code. The library never calls process.exit.
|
|
67
|
+
Errors from a custom output function propagate to the caller.
|
|
68
|
+
|
|
69
|
+
## Options
|
|
70
|
+
|
|
71
|
+
| Option | Default | Behavior |
|
|
72
|
+
| ----------- | -------------- | ------------------------------------------------------ |
|
|
73
|
+
| `emoji` | true | Dog-themed level symbols |
|
|
74
|
+
| `color` | false | ANSI color for text lines; ignored for JSON |
|
|
75
|
+
| `timestamp` | false | UTC ISO timestamp |
|
|
76
|
+
| `json` | false | One JSON object per call; emoji/color omitted |
|
|
77
|
+
| `quiet` | false | Suppress all output |
|
|
78
|
+
| `prefix` | empty string | Text prefix or JSON prefix field |
|
|
79
|
+
| `level` | info | Minimum level |
|
|
80
|
+
| `write` | console output | Function `(line, level)` for each emitted line |
|
|
81
|
+
| `clock` | current Date | Function returning a valid Date when timestamp enabled |
|
|
82
|
+
|
|
83
|
+
Levels: debug (10), log/info/success (20), warn (30), error (40). Thresholds
|
|
84
|
+
include all levels with equal or higher ranks. At info, debug is suppressed.
|
|
85
|
+
At warn, only warn and error appear. JSON always includes `level` and `message`,
|
|
86
|
+
with `prefix` and `timestamp` included when enabled/nonempty. Object arguments
|
|
87
|
+
are formatted into the message string; they are not separate JSON fields.
|
|
88
|
+
|
|
89
|
+
Invalid options throw TypeError; unknown levels throw RangeError. Names are case
|
|
90
|
+
sensitive. Unknown option keys are ignored. Quiet/filtered calls skip message
|
|
91
|
+
formatting, clock calls, and output. No transports, rotation, telemetry, remote
|
|
92
|
+
service, or production dependencies are required.
|
|
93
|
+
|
|
94
|
+
## CLI reference
|
|
95
|
+
|
|
96
|
+
`doggo-log <method> <message> [options]`
|
|
97
|
+
|
|
98
|
+
| Flag | Behavior |
|
|
99
|
+
| ----------------- | --------------------------------- |
|
|
100
|
+
| `--json` | JSON output |
|
|
101
|
+
| `--timestamp` | ISO timestamp |
|
|
102
|
+
| `--no-emoji` | Plain labels |
|
|
103
|
+
| `--color` | ANSI color |
|
|
104
|
+
| `--prefix text` | Prefix |
|
|
105
|
+
| `--level name` | Minimum level (CLI default debug) |
|
|
106
|
+
| `--quiet` | Suppress output |
|
|
107
|
+
| `--help`, `-h` | Usage |
|
|
108
|
+
| `--version`, `-v` | Version |
|
|
109
|
+
|
|
110
|
+
Quote messages containing shell punctuation. Use `--` before positional arguments
|
|
111
|
+
containing dash-prefixed text. CLI messages are strings, without placeholder
|
|
112
|
+
interpolation. Exit 0 means success (including filtered calls and error logging);
|
|
113
|
+
exit 2 means invalid arguments. No stdin support in this MVP.
|
|
114
|
+
|
|
115
|
+
## Development and examples
|
|
116
|
+
|
|
117
|
+
```sh
|
|
118
|
+
npm ci
|
|
119
|
+
node examples/basic.js
|
|
120
|
+
npm test
|
|
121
|
+
npm run lint
|
|
122
|
+
npm run format:check
|
|
123
|
+
npm pack --dry-run
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
ES modules and Node's test runner. CI runs Node 22/24. Development tooling requires
|
|
127
|
+
Node 22.13+ or 24. Styles and behavior are separate for easy contributions.
|
|
128
|
+
|
|
129
|
+
## Contributing
|
|
130
|
+
|
|
131
|
+
See [CONTRIBUTING.md](CONTRIBUTING.md).
|
|
132
|
+
|
|
133
|
+
## License
|
|
134
|
+
|
|
135
|
+
[MIT](LICENSE).
|
|
136
|
+
|
|
137
|
+
## More from DeployAnyway
|
|
138
|
+
|
|
139
|
+
**Tools for developers who probably know better.**
|
|
140
|
+
|
|
141
|
+
- [error-translator](https://github.com/DeployAnyway/error-translator)
|
|
142
|
+
- [excuse-js](https://github.com/DeployAnyway/excuse-js)
|
|
143
|
+
- [doggo-log](https://github.com/DeployAnyway/doggo-log)
|
|
144
|
+
- [ship-it-meter](https://github.com/DeployAnyway/ship-it-meter)
|
|
145
|
+
- [bro-say](https://github.com/DeployAnyway/bro-say)
|
|
146
|
+
|
|
147
|
+
## Scoped logs, optional barks
|
|
148
|
+
|
|
149
|
+
Use `logger.child("database")` to create an independent logger with a nested prefix. Enable `{ bark: true }` or CLI `--bark` for dog commentary. JSON preserves the original message and adds a separate `commentary` field. Filtering still suppresses output.
|
|
150
|
+
|
|
151
|
+
```sh
|
|
152
|
+
npx @deployanyway/doggo-log success "Migration complete" --bark --prefix database
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
API (import the named functions from this package):
|
|
156
|
+
|
|
157
|
+
```js
|
|
158
|
+
createDogLogger({ bark: true, prefix: "api" })
|
|
159
|
+
.child("database")
|
|
160
|
+
.success("Migration complete");
|
|
161
|
+
```
|
package/bin/cli.js
CHANGED
|
@@ -1,51 +1,53 @@
|
|
|
1
|
-
#!/usr/bin/env node
|
|
2
|
-
import { parseArgs } from "node:util";
|
|
3
|
-
import { readFileSync } from "node:fs";
|
|
4
|
-
import { URL } from "node:url";
|
|
5
|
-
import { createDogLogger } from "../src/index.js";
|
|
6
|
-
import { levels } from "../src/levels.js";
|
|
7
|
-
|
|
8
|
-
try {
|
|
9
|
-
const { values, positionals } = parseArgs({
|
|
10
|
-
allowPositionals: true,
|
|
11
|
-
options: {
|
|
12
|
-
help: { type: "boolean", short: "h" },
|
|
13
|
-
version: { type: "boolean", short: "v" },
|
|
14
|
-
json: { type: "boolean" },
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
);
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
}
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { parseArgs } from "node:util";
|
|
3
|
+
import { readFileSync } from "node:fs";
|
|
4
|
+
import { URL } from "node:url";
|
|
5
|
+
import { createDogLogger } from "../src/index.js";
|
|
6
|
+
import { levels } from "../src/levels.js";
|
|
7
|
+
|
|
8
|
+
try {
|
|
9
|
+
const { values, positionals } = parseArgs({
|
|
10
|
+
allowPositionals: true,
|
|
11
|
+
options: {
|
|
12
|
+
help: { type: "boolean", short: "h" },
|
|
13
|
+
version: { type: "boolean", short: "v" },
|
|
14
|
+
json: { type: "boolean" },
|
|
15
|
+
bark: { type: "boolean" },
|
|
16
|
+
timestamp: { type: "boolean" },
|
|
17
|
+
quiet: { type: "boolean" },
|
|
18
|
+
color: { type: "boolean" },
|
|
19
|
+
"no-emoji": { type: "boolean" },
|
|
20
|
+
prefix: { type: "string" },
|
|
21
|
+
level: { type: "string", default: "debug" },
|
|
22
|
+
},
|
|
23
|
+
});
|
|
24
|
+
if (values.help) {
|
|
25
|
+
console.log(
|
|
26
|
+
"Usage: doggo-log <method> <message> [options]\n\nMethods: log, info, success, warn, error, debug\nOptions:\n --bark Add useful dog commentary\n --json Emit JSON\n --timestamp Include an ISO timestamp\n --no-emoji Disable emojis\n --color Enable ANSI colors\n --prefix text Add a prefix\n --level name Minimum level (CLI default: debug)\n --quiet Suppress output\n -h, --help Show help\n -v, --version Show version\n\nExit codes: 0 success; 2 invalid arguments. Logging an error exits 0.",
|
|
27
|
+
);
|
|
28
|
+
} else if (values.version) {
|
|
29
|
+
console.log(
|
|
30
|
+
JSON.parse(
|
|
31
|
+
readFileSync(new URL("../package.json", import.meta.url), "utf8"),
|
|
32
|
+
).version,
|
|
33
|
+
);
|
|
34
|
+
} else {
|
|
35
|
+
const [method, ...message] = positionals;
|
|
36
|
+
if (!Object.hasOwn(levels, method ?? "") || !message.join(" ").trim())
|
|
37
|
+
throw new TypeError("Provide a valid method and nonempty message.");
|
|
38
|
+
const logger = createDogLogger({
|
|
39
|
+
emoji: !values["no-emoji"],
|
|
40
|
+
bark: values.bark ?? false,
|
|
41
|
+
color: values.color ?? false,
|
|
42
|
+
timestamp: values.timestamp ?? false,
|
|
43
|
+
json: values.json ?? false,
|
|
44
|
+
quiet: values.quiet ?? false,
|
|
45
|
+
prefix: values.prefix ?? "",
|
|
46
|
+
level: values.level,
|
|
47
|
+
});
|
|
48
|
+
logger[method](message.join(" "));
|
|
49
|
+
}
|
|
50
|
+
} catch (error) {
|
|
51
|
+
console.error(`doggo-log: ${error.message}\nRun with --help for usage.`);
|
|
52
|
+
process.exitCode = 2;
|
|
53
|
+
}
|
package/package.json
CHANGED
|
@@ -1,41 +1,53 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@deployanyway/doggo-log",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "A tiny
|
|
5
|
-
"type": "module",
|
|
6
|
-
"exports": "./src/index.js",
|
|
7
|
-
"bin": {
|
|
8
|
-
"doggo-log": "./bin/cli.js"
|
|
9
|
-
},
|
|
10
|
-
"files": [
|
|
11
|
-
"src",
|
|
12
|
-
"bin",
|
|
13
|
-
"README.md",
|
|
14
|
-
"LICENSE",
|
|
15
|
-
"CHANGELOG.md"
|
|
16
|
-
],
|
|
17
|
-
"engines": {
|
|
18
|
-
"node": ">=22"
|
|
19
|
-
},
|
|
20
|
-
"scripts": {
|
|
21
|
-
"test": "node --test",
|
|
22
|
-
"lint": "eslint .",
|
|
23
|
-
"format": "prettier --write .",
|
|
24
|
-
"format:check": "prettier --check ."
|
|
25
|
-
},
|
|
26
|
-
"repository": {
|
|
27
|
-
"type": "git",
|
|
28
|
-
"url": "git+https://github.com/DeployAnyway/doggo-log.git"
|
|
29
|
-
},
|
|
30
|
-
"bugs": {
|
|
31
|
-
"url": "https://github.com/DeployAnyway/doggo-log/issues"
|
|
32
|
-
},
|
|
33
|
-
"license": "MIT",
|
|
34
|
-
"publishConfig": {
|
|
35
|
-
"access": "public"
|
|
36
|
-
},
|
|
37
|
-
"devDependencies": {
|
|
38
|
-
"eslint": "^10.12.0",
|
|
39
|
-
"prettier": "^3.6.2"
|
|
40
|
-
}
|
|
41
|
-
|
|
1
|
+
{
|
|
2
|
+
"name": "@deployanyway/doggo-log",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "A tiny Node.js console logger with JSON output, log levels, and dog emojis. Good logs. Very good logs.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"exports": "./src/index.js",
|
|
7
|
+
"bin": {
|
|
8
|
+
"doggo-log": "./bin/cli.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"src",
|
|
12
|
+
"bin",
|
|
13
|
+
"README.md",
|
|
14
|
+
"LICENSE",
|
|
15
|
+
"CHANGELOG.md"
|
|
16
|
+
],
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=22"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"test": "node --test",
|
|
22
|
+
"lint": "eslint .",
|
|
23
|
+
"format": "prettier --write .",
|
|
24
|
+
"format:check": "prettier --check ."
|
|
25
|
+
},
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "git+https://github.com/DeployAnyway/doggo-log.git"
|
|
29
|
+
},
|
|
30
|
+
"bugs": {
|
|
31
|
+
"url": "https://github.com/DeployAnyway/doggo-log/issues"
|
|
32
|
+
},
|
|
33
|
+
"license": "MIT",
|
|
34
|
+
"publishConfig": {
|
|
35
|
+
"access": "public"
|
|
36
|
+
},
|
|
37
|
+
"devDependencies": {
|
|
38
|
+
"eslint": "^10.12.0",
|
|
39
|
+
"prettier": "^3.6.2"
|
|
40
|
+
},
|
|
41
|
+
"keywords": [
|
|
42
|
+
"nodejs",
|
|
43
|
+
"javascript",
|
|
44
|
+
"cli",
|
|
45
|
+
"developer-tools",
|
|
46
|
+
"logger",
|
|
47
|
+
"logging",
|
|
48
|
+
"console",
|
|
49
|
+
"json",
|
|
50
|
+
"log-levels",
|
|
51
|
+
"dog"
|
|
52
|
+
]
|
|
53
|
+
}
|
package/src/index.js
CHANGED
|
@@ -1,80 +1,101 @@
|
|
|
1
|
-
import { format } from "node:util";
|
|
2
|
-
import { levels } from "./levels.js";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
level
|
|
66
|
-
message,
|
|
67
|
-
|
|
68
|
-
.
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
1
|
+
import { format } from "node:util";
|
|
2
|
+
import { levels } from "./levels.js";
|
|
3
|
+
const barks = {
|
|
4
|
+
debug: "Sniffing for clues.",
|
|
5
|
+
log: "Filed under things I sniffed.",
|
|
6
|
+
info: "Good to know. Good dog to tell you.",
|
|
7
|
+
success: "Treat budget approved.",
|
|
8
|
+
warn: "Suspicious squirrel detected.",
|
|
9
|
+
error: "The dog has fetched the incident report.",
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Create a small logger. Methods return the emitted line, or undefined if filtered.
|
|
14
|
+
* @param {{emoji?: boolean, color?: boolean, timestamp?: boolean, json?: boolean, quiet?: boolean, prefix?: string, level?: string, write?: (line: string, level: string) => void, clock?: () => Date}} [options]
|
|
15
|
+
*/
|
|
16
|
+
export function createDogLogger(options = {}) {
|
|
17
|
+
if (!options || typeof options !== "object" || Array.isArray(options))
|
|
18
|
+
throw new TypeError("Options must be an object.");
|
|
19
|
+
const config = {
|
|
20
|
+
emoji: true,
|
|
21
|
+
bark: false,
|
|
22
|
+
color: false,
|
|
23
|
+
timestamp: false,
|
|
24
|
+
json: false,
|
|
25
|
+
quiet: false,
|
|
26
|
+
prefix: "",
|
|
27
|
+
level: "info",
|
|
28
|
+
write: (line, level) =>
|
|
29
|
+
level === "warn" || level === "error"
|
|
30
|
+
? console.error(line)
|
|
31
|
+
: console.log(line),
|
|
32
|
+
clock: () => new Date(),
|
|
33
|
+
...options,
|
|
34
|
+
};
|
|
35
|
+
for (const key of ["emoji", "color", "timestamp", "json", "quiet", "bark"]) {
|
|
36
|
+
if (typeof config[key] !== "boolean")
|
|
37
|
+
throw new TypeError(`${key} must be a boolean.`);
|
|
38
|
+
}
|
|
39
|
+
if (typeof config.prefix !== "string")
|
|
40
|
+
throw new TypeError("prefix must be a string.");
|
|
41
|
+
if (typeof config.level !== "string" || !Object.hasOwn(levels, config.level))
|
|
42
|
+
throw new RangeError(
|
|
43
|
+
`level must be one of: ${Object.keys(levels).join(", ")}.`,
|
|
44
|
+
);
|
|
45
|
+
if (typeof config.write !== "function" || typeof config.clock !== "function")
|
|
46
|
+
throw new TypeError("write and clock must be functions.");
|
|
47
|
+
const logger = Object.fromEntries(
|
|
48
|
+
Object.entries(levels).map(([level, style]) => [
|
|
49
|
+
level,
|
|
50
|
+
(...args) => {
|
|
51
|
+
if (config.quiet || style.rank < levels[config.level].rank)
|
|
52
|
+
return undefined;
|
|
53
|
+
const message = format(...args);
|
|
54
|
+
const commentary = config.bark ? barks[level] : undefined;
|
|
55
|
+
let timestamp;
|
|
56
|
+
if (config.timestamp) {
|
|
57
|
+
const date = config.clock();
|
|
58
|
+
if (!(date instanceof Date) || !Number.isFinite(date.getTime()))
|
|
59
|
+
throw new TypeError("clock must return a valid Date.");
|
|
60
|
+
timestamp = date.toISOString();
|
|
61
|
+
}
|
|
62
|
+
let line;
|
|
63
|
+
if (config.json) {
|
|
64
|
+
line = JSON.stringify({
|
|
65
|
+
level,
|
|
66
|
+
message,
|
|
67
|
+
...(commentary ? { commentary } : {}),
|
|
68
|
+
...(config.prefix ? { prefix: config.prefix } : {}),
|
|
69
|
+
...(timestamp ? { timestamp } : {}),
|
|
70
|
+
});
|
|
71
|
+
} else {
|
|
72
|
+
line = [
|
|
73
|
+
timestamp,
|
|
74
|
+
config.prefix,
|
|
75
|
+
config.emoji ? style.emoji : undefined,
|
|
76
|
+
level.toUpperCase().padEnd(7),
|
|
77
|
+
message,
|
|
78
|
+
commentary,
|
|
79
|
+
]
|
|
80
|
+
.filter((part) => part !== undefined && part !== "")
|
|
81
|
+
.join(" ");
|
|
82
|
+
if (config.color) line = `\u001b[${style.color}m${line}\u001b[0m`;
|
|
83
|
+
}
|
|
84
|
+
config.write(line, level);
|
|
85
|
+
return line;
|
|
86
|
+
},
|
|
87
|
+
]),
|
|
88
|
+
);
|
|
89
|
+
logger.child = (prefix) => {
|
|
90
|
+
if (typeof prefix !== "string" || !prefix.trim())
|
|
91
|
+
throw new TypeError("Child prefix must be a nonempty string.");
|
|
92
|
+
return createDogLogger({
|
|
93
|
+
...config,
|
|
94
|
+
prefix: [config.prefix, prefix.trim()].filter(Boolean).join(":"),
|
|
95
|
+
});
|
|
96
|
+
};
|
|
97
|
+
return logger;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** Default logger: emoji enabled, no timestamp/color, info threshold. */
|
|
101
|
+
export const doglog = createDogLogger();
|
package/src/levels.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
export const levels = {
|
|
2
|
-
debug: { rank: 10, emoji: "🔍", color: 90 },
|
|
3
|
-
log: { rank: 20, emoji: "🐶", color: 37 },
|
|
4
|
-
info: { rank: 20, emoji: "🐶", color: 36 },
|
|
5
|
-
success: { rank: 20, emoji: "🐾", color: 32 },
|
|
6
|
-
warn: { rank: 30, emoji: "🦴", color: 33 },
|
|
7
|
-
error: { rank: 40, emoji: "🚨", color: 31 },
|
|
8
|
-
};
|
|
1
|
+
export const levels = {
|
|
2
|
+
debug: { rank: 10, emoji: "🔍", color: 90 },
|
|
3
|
+
log: { rank: 20, emoji: "🐶", color: 37 },
|
|
4
|
+
info: { rank: 20, emoji: "🐶", color: 36 },
|
|
5
|
+
success: { rank: 20, emoji: "🐾", color: 32 },
|
|
6
|
+
warn: { rank: 30, emoji: "🦴", color: 33 },
|
|
7
|
+
error: { rank: 40, emoji: "🚨", color: 31 },
|
|
8
|
+
};
|