@logtape/adaptor-bunyan 2.1.0-dev.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/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ MIT License
2
+
3
+ Copyright 2024–2025 Hong Minhee
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ 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, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,163 @@
1
+ <!-- deno-fmt-ignore-file -->
2
+
3
+ @logtape/adaptor-bunyan
4
+ =======================
5
+
6
+ [![JSR][JSR badge]][JSR]
7
+ [![npm][npm badge]][npm]
8
+
9
+ *@logtape/adaptor-bunyan* is a [LogTape] adapter that forwards log records to
10
+ [Bunyan] loggers, enabling seamless integration between LogTape-enabled
11
+ libraries and applications using Bunyan for logging infrastructure.
12
+
13
+ [JSR badge]: https://jsr.io/badges/@logtape/adaptor-bunyan
14
+ [JSR]: https://jsr.io/@logtape/adaptor-bunyan
15
+ [npm badge]: https://img.shields.io/npm/v/@logtape/adaptor-bunyan?logo=npm
16
+ [npm]: https://www.npmjs.com/package/@logtape/adaptor-bunyan
17
+ [LogTape]: https://logtape.org/
18
+ [Bunyan]: https://github.com/trentm/node-bunyan
19
+
20
+
21
+ Installation
22
+ ------------
23
+
24
+ ~~~~ sh
25
+ deno add jsr:@logtape/adaptor-bunyan # for Deno
26
+ npm add @logtape/adaptor-bunyan # for npm
27
+ pnpm add @logtape/adaptor-bunyan # for pnpm
28
+ yarn add @logtape/adaptor-bunyan # for Yarn
29
+ bun add @logtape/adaptor-bunyan # for Bun
30
+ ~~~~
31
+
32
+
33
+ Usage
34
+ -----
35
+
36
+ Bunyan does not provide a global default logger; create one with
37
+ `bunyan.createLogger()` and pass it to the adapter.
38
+
39
+ ### Using the install() function
40
+
41
+ The simplest way to integrate LogTape with Bunyan is to use the `install()`
42
+ function:
43
+
44
+ ~~~~ typescript
45
+ import bunyan from "bunyan";
46
+ import { install } from "@logtape/adaptor-bunyan";
47
+
48
+ const bunyanLogger = bunyan.createLogger({ name: "my-app" });
49
+
50
+ install(bunyanLogger);
51
+
52
+ // That's it! All LogTape logs will now be routed to your Bunyan logger
53
+ import { getLogger } from "@logtape/logtape";
54
+ const logger = getLogger("my-app");
55
+ logger.info("This will be logged through Bunyan");
56
+ ~~~~
57
+
58
+ You can also pass configuration options:
59
+
60
+ ~~~~ typescript
61
+ import { install } from "@logtape/adaptor-bunyan";
62
+
63
+ install(bunyanLogger, {
64
+ category: {
65
+ position: "start",
66
+ decorator: "[]",
67
+ separator: "."
68
+ }
69
+ });
70
+ ~~~~
71
+
72
+ ### Manual configuration
73
+
74
+ For full control over the Bunyan integration, configure LogTape manually:
75
+
76
+ ~~~~ typescript
77
+ import { configure } from "@logtape/logtape";
78
+ import { getBunyanSink } from "@logtape/adaptor-bunyan";
79
+ import bunyan from "bunyan";
80
+
81
+ const bunyanLogger = bunyan.createLogger({
82
+ name: "my-app",
83
+ level: "info"
84
+ });
85
+
86
+ await configure({
87
+ sinks: {
88
+ bunyan: getBunyanSink(bunyanLogger, {
89
+ category: {
90
+ position: "start",
91
+ decorator: "[]",
92
+ separator: "."
93
+ }
94
+ })
95
+ },
96
+ loggers: [
97
+ { category: "my-library", sinks: ["bunyan"] }
98
+ ]
99
+ });
100
+ ~~~~
101
+
102
+
103
+ Category formatting
104
+ -------------------
105
+
106
+ The adapter supports flexible category formatting options:
107
+
108
+ ~~~~ typescript
109
+ import { getBunyanSink } from "@logtape/adaptor-bunyan";
110
+
111
+ // Hide categories completely (default)
112
+ const sink1 = getBunyanSink(logger, { category: false });
113
+
114
+ // Use default formatting ("·" separator and ":" decorator)
115
+ const sink2 = getBunyanSink(logger, { category: true });
116
+
117
+ // Custom formatting
118
+ const sink3 = getBunyanSink(logger, {
119
+ category: {
120
+ position: "end", // "start" or "end"
121
+ decorator: "[]", // "[]", "()", "<>", "{}", ":", "-", "|", "/", ""
122
+ separator: "::" // custom separator for multi-part categories
123
+ }
124
+ });
125
+ ~~~~
126
+
127
+
128
+ Customizing interpolated value formatting
129
+ -----------------------------------------
130
+
131
+ By default the adapter renders interpolated values in the message template
132
+ with `node:util.inspect()` (`breakLength: Infinity`). Provide a
133
+ `valueFormatter` to override that — for example, to use `JSON.stringify`
134
+ or a redaction-aware serializer:
135
+
136
+ ~~~~ typescript
137
+ import { getBunyanSink } from "@logtape/adaptor-bunyan";
138
+
139
+ const sink = getBunyanSink(logger, {
140
+ valueFormatter: (value) => JSON.stringify(value),
141
+ });
142
+ ~~~~
143
+
144
+
145
+ Properties and Bunyan reserved fields
146
+ -------------------------------------
147
+
148
+ LogTape `record.properties` are passed verbatim to Bunyan as the merge-object
149
+ of the call. Bunyan automatically applies any `serializers` configured on
150
+ the logger to matching top-level fields.
151
+
152
+ Bunyan reserves a small set of field names (`name`, `hostname`, `pid`,
153
+ `level`, `time`, `msg`, `src`, `v`). If your LogTape properties happen to
154
+ contain any of these names, Bunyan's normal collision behaviour applies —
155
+ configure your structured property names to avoid conflicts.
156
+
157
+
158
+ Docs
159
+ ----
160
+
161
+ See the [API reference] on JSR for further details.
162
+
163
+ [API reference]: https://jsr.io/@logtape/adaptor-bunyan/doc
@@ -0,0 +1,30 @@
1
+ //#region rolldown:runtime
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __copyProps = (to, from, except, desc) => {
9
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
10
+ key = keys[i];
11
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
12
+ get: ((k) => from[k]).bind(null, key),
13
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
14
+ });
15
+ }
16
+ return to;
17
+ };
18
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ value: mod,
20
+ enumerable: true
21
+ }) : target, mod));
22
+
23
+ //#endregion
24
+
25
+ Object.defineProperty(exports, '__toESM', {
26
+ enumerable: true,
27
+ get: function () {
28
+ return __toESM;
29
+ }
30
+ });
package/dist/mod.cjs ADDED
@@ -0,0 +1,181 @@
1
+ const require_rolldown_runtime = require('./_virtual/rolldown_runtime.cjs');
2
+ const node_util = require_rolldown_runtime.__toESM(require("node:util"));
3
+ const __logtape_logtape = require_rolldown_runtime.__toESM(require("@logtape/logtape"));
4
+
5
+ //#region src/mod.ts
6
+ function defaultValueFormatter(value) {
7
+ return (0, node_util.inspect)(value, { breakLength: Infinity });
8
+ }
9
+ function renderMessage(parts, valueFormatter) {
10
+ let rendered = "";
11
+ for (let i = 0; i < parts.length; i++) if (i % 2 === 0) rendered += parts[i];
12
+ else rendered += valueFormatter(parts[i]);
13
+ return rendered;
14
+ }
15
+ function decorateCategoryStart(category, decorator) {
16
+ switch (decorator) {
17
+ case "[]": return `[${category}] `;
18
+ case "()": return `(${category}) `;
19
+ case "<>": return `<${category}> `;
20
+ case "{}": return `{${category}} `;
21
+ case ":": return `${category}: `;
22
+ case "-": return `${category} - `;
23
+ case "|": return `${category} | `;
24
+ case "/": return `${category} / `;
25
+ case "": return `${category} `;
26
+ }
27
+ }
28
+ function decorateCategoryEnd(category, decorator) {
29
+ switch (decorator) {
30
+ case "[]": return ` [${category}]`;
31
+ case "()": return ` (${category})`;
32
+ case "<>": return ` <${category}>`;
33
+ case "{}": return ` {${category}}`;
34
+ case ":": return `: ${category}`;
35
+ case "-": return ` - ${category}`;
36
+ case "|": return ` | ${category}`;
37
+ case "/": return ` / ${category}`;
38
+ case "": return ` ${category}`;
39
+ }
40
+ }
41
+ /**
42
+ * Creates a LogTape sink that forwards log records to a Bunyan logger.
43
+ *
44
+ * Bunyan does not provide a global default logger; you must create one
45
+ * with `bunyan.createLogger({ name: "..." })` and pass it in.
46
+ *
47
+ * LogTape's `record.properties` are passed verbatim to Bunyan as the
48
+ * merge-object, so any `serializers` configured on the Bunyan logger
49
+ * apply automatically. Bunyan's reserved fields (`name`, `hostname`,
50
+ * `pid`, `level`, `time`, `msg`, `src`, `v`) should not be used as
51
+ * property keys.
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * import { configure } from "@logtape/logtape";
56
+ * import { getBunyanSink } from "@logtape/adaptor-bunyan";
57
+ * import bunyan from "bunyan";
58
+ *
59
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
60
+ *
61
+ * await configure({
62
+ * sinks: {
63
+ * bunyan: getBunyanSink(bunyanLogger, {
64
+ * category: {
65
+ * position: "start",
66
+ * decorator: "[]",
67
+ * separator: "."
68
+ * }
69
+ * })
70
+ * },
71
+ * loggers: [
72
+ * { category: "my-library", sinks: ["bunyan"] }
73
+ * ]
74
+ * });
75
+ * ```
76
+ *
77
+ * @param logger The Bunyan logger instance to forward logs to.
78
+ * @param options Configuration options for the sink adapter.
79
+ * @returns A LogTape sink function that can be used in LogTape configuration.
80
+ * @since 2.1.0
81
+ */
82
+ function getBunyanSink(logger, options = {}) {
83
+ const categoryOptions = !options.category ? void 0 : typeof options.category === "object" ? options.category : {};
84
+ const category = categoryOptions == null ? void 0 : {
85
+ separator: categoryOptions.separator ?? "·",
86
+ position: categoryOptions.position ?? "start",
87
+ decorator: categoryOptions.decorator ?? ":"
88
+ };
89
+ const valueFormatter = options.valueFormatter ?? defaultValueFormatter;
90
+ return (record) => {
91
+ let message = "";
92
+ if (category != null && record.category.length > 0) {
93
+ const joined = record.category.join(category.separator);
94
+ if (category.position === "start") message += decorateCategoryStart(joined, category.decorator);
95
+ message += renderMessage(record.message, valueFormatter);
96
+ if (category.position === "end") message += decorateCategoryEnd(joined, category.decorator);
97
+ } else message = renderMessage(record.message, valueFormatter);
98
+ const properties = record.properties;
99
+ switch (record.level) {
100
+ case "trace":
101
+ logger.trace(properties, message);
102
+ return;
103
+ case "debug":
104
+ logger.debug(properties, message);
105
+ return;
106
+ case "info":
107
+ logger.info(properties, message);
108
+ return;
109
+ case "warning":
110
+ logger.warn(properties, message);
111
+ return;
112
+ case "error":
113
+ logger.error(properties, message);
114
+ return;
115
+ case "fatal":
116
+ logger.fatal(properties, message);
117
+ return;
118
+ }
119
+ };
120
+ }
121
+ /**
122
+ * Automatically configures LogTape to route all logs to a Bunyan logger.
123
+ *
124
+ * This is a convenience function that wires up `getBunyanSink()` as
125
+ * LogTape's catch-all sink and routes the meta logger
126
+ * (`["logtape", "meta"]`) to the same sink with `lowestLevel: "warning"`,
127
+ * matching the conventions of the other adapter packages.
128
+ *
129
+ * Bunyan does not provide a global default logger, so the logger argument
130
+ * is required. Create one with `bunyan.createLogger({ name: "..." })`
131
+ * and pass it in.
132
+ *
133
+ * @example Basic auto-configuration
134
+ * ```typescript
135
+ * import bunyan from "bunyan";
136
+ * import { install } from "@logtape/adaptor-bunyan";
137
+ *
138
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
139
+ * install(bunyanLogger);
140
+ *
141
+ * import { getLogger } from "@logtape/logtape";
142
+ * const logger = getLogger("my-app");
143
+ * logger.info("This will be logged through Bunyan");
144
+ * ```
145
+ *
146
+ * @example Auto-configuration with custom options
147
+ * ```typescript
148
+ * import bunyan from "bunyan";
149
+ * import { install } from "@logtape/adaptor-bunyan";
150
+ *
151
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
152
+ * install(bunyanLogger, {
153
+ * category: {
154
+ * position: "start",
155
+ * decorator: "[]",
156
+ * separator: "."
157
+ * }
158
+ * });
159
+ * ```
160
+ *
161
+ * @param logger The Bunyan logger instance to forward logs to.
162
+ * @param options Configuration options for the sink adapter.
163
+ * @since 2.1.0
164
+ */
165
+ function install(logger, options = {}) {
166
+ (0, __logtape_logtape.configureSync)({
167
+ sinks: { bunyan: getBunyanSink(logger, options) },
168
+ loggers: [{
169
+ category: ["logtape", "meta"],
170
+ sinks: ["bunyan"],
171
+ lowestLevel: "warning"
172
+ }, {
173
+ category: [],
174
+ sinks: ["bunyan"]
175
+ }]
176
+ });
177
+ }
178
+
179
+ //#endregion
180
+ exports.getBunyanSink = getBunyanSink;
181
+ exports.install = install;
package/dist/mod.d.cts ADDED
@@ -0,0 +1,169 @@
1
+ import { Sink } from "@logtape/logtape";
2
+
3
+ //#region src/mod.d.ts
4
+
5
+ /**
6
+ * A structural representation of a [Bunyan] logger sufficient for the
7
+ * adapter's needs. Avoids importing Bunyan's own type definitions so the
8
+ * package builds cleanly under both Deno and Node.js.
9
+ *
10
+ * [Bunyan]: https://github.com/trentm/node-bunyan
11
+ *
12
+ * @since 2.1.0
13
+ */
14
+ interface BunyanLogger {
15
+ trace(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
16
+ debug(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
17
+ info(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
18
+ warn(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
19
+ error(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
20
+ fatal(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
21
+ }
22
+ /**
23
+ * Options for configuring the Bunyan sink adapter.
24
+ * @since 2.1.0
25
+ */
26
+ interface BunyanSinkOptions {
27
+ /**
28
+ * Configuration for how LogTape categories are handled in Bunyan logs.
29
+ * - `false` or `undefined`: Categories are not included in the log message
30
+ * - `true`: Categories are included with default formatting
31
+ * - `CategoryOptions`: Custom category formatting configuration
32
+ */
33
+ readonly category?: boolean | CategoryOptions;
34
+ /**
35
+ * A function that converts an interpolated value in the message template
36
+ * to a string. By default, values are formatted with
37
+ * `node:util#inspect()` using `breakLength: Infinity` so each value
38
+ * appears on a single line in the rendered `msg` field.
39
+ *
40
+ * Supply a custom formatter to use, for example, `JSON.stringify`,
41
+ * a redaction-aware serializer, or any other strategy.
42
+ * @default `(value) => inspect(value, { breakLength: Infinity })`
43
+ */
44
+ readonly valueFormatter?: (value: unknown) => string;
45
+ }
46
+ /**
47
+ * Configuration options for formatting LogTape categories in Bunyan log
48
+ * messages.
49
+ * @since 2.1.0
50
+ */
51
+ interface CategoryOptions {
52
+ /**
53
+ * The separator used to join category parts when multiple categories exist.
54
+ * @default "·"
55
+ */
56
+ readonly separator?: string;
57
+ /**
58
+ * Where to position the category in the log message.
59
+ * - `"start"`: Category appears at the beginning of the message
60
+ * - `"end"`: Category appears at the end of the message
61
+ * @default "start"
62
+ */
63
+ readonly position?: "start" | "end";
64
+ /**
65
+ * The decorator used to format the category in the log message.
66
+ * - `"[]"`: [category] format
67
+ * - `"()"`: (category) format
68
+ * - `"<>"`: <category> format
69
+ * - `"{}"`: {category} format
70
+ * - `":"`: category: format
71
+ * - `"-"`: category - format
72
+ * - `"|"`: category | format
73
+ * - `"/"`: category / format
74
+ * - `""`: category format (no decoration)
75
+ * @default ":"
76
+ */
77
+ readonly decorator?: "[]" | "()" | "<>" | "{}" | ":" | "-" | "|" | "/" | "";
78
+ }
79
+ /**
80
+ * Creates a LogTape sink that forwards log records to a Bunyan logger.
81
+ *
82
+ * Bunyan does not provide a global default logger; you must create one
83
+ * with `bunyan.createLogger({ name: "..." })` and pass it in.
84
+ *
85
+ * LogTape's `record.properties` are passed verbatim to Bunyan as the
86
+ * merge-object, so any `serializers` configured on the Bunyan logger
87
+ * apply automatically. Bunyan's reserved fields (`name`, `hostname`,
88
+ * `pid`, `level`, `time`, `msg`, `src`, `v`) should not be used as
89
+ * property keys.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { configure } from "@logtape/logtape";
94
+ * import { getBunyanSink } from "@logtape/adaptor-bunyan";
95
+ * import bunyan from "bunyan";
96
+ *
97
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
98
+ *
99
+ * await configure({
100
+ * sinks: {
101
+ * bunyan: getBunyanSink(bunyanLogger, {
102
+ * category: {
103
+ * position: "start",
104
+ * decorator: "[]",
105
+ * separator: "."
106
+ * }
107
+ * })
108
+ * },
109
+ * loggers: [
110
+ * { category: "my-library", sinks: ["bunyan"] }
111
+ * ]
112
+ * });
113
+ * ```
114
+ *
115
+ * @param logger The Bunyan logger instance to forward logs to.
116
+ * @param options Configuration options for the sink adapter.
117
+ * @returns A LogTape sink function that can be used in LogTape configuration.
118
+ * @since 2.1.0
119
+ */
120
+ declare function getBunyanSink(logger: BunyanLogger, options?: BunyanSinkOptions): Sink;
121
+ /**
122
+ * Automatically configures LogTape to route all logs to a Bunyan logger.
123
+ *
124
+ * This is a convenience function that wires up `getBunyanSink()` as
125
+ * LogTape's catch-all sink and routes the meta logger
126
+ * (`["logtape", "meta"]`) to the same sink with `lowestLevel: "warning"`,
127
+ * matching the conventions of the other adapter packages.
128
+ *
129
+ * Bunyan does not provide a global default logger, so the logger argument
130
+ * is required. Create one with `bunyan.createLogger({ name: "..." })`
131
+ * and pass it in.
132
+ *
133
+ * @example Basic auto-configuration
134
+ * ```typescript
135
+ * import bunyan from "bunyan";
136
+ * import { install } from "@logtape/adaptor-bunyan";
137
+ *
138
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
139
+ * install(bunyanLogger);
140
+ *
141
+ * import { getLogger } from "@logtape/logtape";
142
+ * const logger = getLogger("my-app");
143
+ * logger.info("This will be logged through Bunyan");
144
+ * ```
145
+ *
146
+ * @example Auto-configuration with custom options
147
+ * ```typescript
148
+ * import bunyan from "bunyan";
149
+ * import { install } from "@logtape/adaptor-bunyan";
150
+ *
151
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
152
+ * install(bunyanLogger, {
153
+ * category: {
154
+ * position: "start",
155
+ * decorator: "[]",
156
+ * separator: "."
157
+ * }
158
+ * });
159
+ * ```
160
+ *
161
+ * @param logger The Bunyan logger instance to forward logs to.
162
+ * @param options Configuration options for the sink adapter.
163
+ * @since 2.1.0
164
+ */
165
+ declare function install(logger: BunyanLogger, options?: BunyanSinkOptions): void;
166
+ //# sourceMappingURL=mod.d.ts.map
167
+ //#endregion
168
+ export { BunyanLogger, BunyanSinkOptions, CategoryOptions, getBunyanSink, install };
169
+ //# sourceMappingURL=mod.d.cts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.cts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;AAYA;;;;;;;AA2BiB,UA3BA,YAAA,CA2BA;EAAM,KAAA,CAAA,WAAA,EAzBN,MAyBM,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAUN,KAAA,CAAA,WAAA,EA9BA,MA8BiB,CAAA,MAOF,EAAA,OAAA,CAAA,EAAA,MAAe,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAoB9B,IAAA,CAAA,WAAA,EApDA,MAoDe,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EA+IhB,IAAA,CAAA,WAAa,EA9LZ,MA8LY,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAAA,KAAA,CAAA,WAAA,EAzLZ,MAyLY,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAAA,KACnB,CAAA,WAAA,EArLO,MAqLP,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;;AAEH;AA+FP;;AACU,UA7QO,iBAAA,CA6QP;EAAY;AACW;;;;;gCAvQD;;;;;;;;;;;;;;;;;;UAoBf,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+ID,aAAA,SACN,wBACC,oBACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+Fa,OAAA,SACN,wBACC"}
package/dist/mod.d.ts ADDED
@@ -0,0 +1,169 @@
1
+ import { Sink } from "@logtape/logtape";
2
+
3
+ //#region src/mod.d.ts
4
+
5
+ /**
6
+ * A structural representation of a [Bunyan] logger sufficient for the
7
+ * adapter's needs. Avoids importing Bunyan's own type definitions so the
8
+ * package builds cleanly under both Deno and Node.js.
9
+ *
10
+ * [Bunyan]: https://github.com/trentm/node-bunyan
11
+ *
12
+ * @since 2.1.0
13
+ */
14
+ interface BunyanLogger {
15
+ trace(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
16
+ debug(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
17
+ info(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
18
+ warn(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
19
+ error(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
20
+ fatal(mergeObject: Record<string, unknown>, format: string, ...args: unknown[]): void;
21
+ }
22
+ /**
23
+ * Options for configuring the Bunyan sink adapter.
24
+ * @since 2.1.0
25
+ */
26
+ interface BunyanSinkOptions {
27
+ /**
28
+ * Configuration for how LogTape categories are handled in Bunyan logs.
29
+ * - `false` or `undefined`: Categories are not included in the log message
30
+ * - `true`: Categories are included with default formatting
31
+ * - `CategoryOptions`: Custom category formatting configuration
32
+ */
33
+ readonly category?: boolean | CategoryOptions;
34
+ /**
35
+ * A function that converts an interpolated value in the message template
36
+ * to a string. By default, values are formatted with
37
+ * `node:util#inspect()` using `breakLength: Infinity` so each value
38
+ * appears on a single line in the rendered `msg` field.
39
+ *
40
+ * Supply a custom formatter to use, for example, `JSON.stringify`,
41
+ * a redaction-aware serializer, or any other strategy.
42
+ * @default `(value) => inspect(value, { breakLength: Infinity })`
43
+ */
44
+ readonly valueFormatter?: (value: unknown) => string;
45
+ }
46
+ /**
47
+ * Configuration options for formatting LogTape categories in Bunyan log
48
+ * messages.
49
+ * @since 2.1.0
50
+ */
51
+ interface CategoryOptions {
52
+ /**
53
+ * The separator used to join category parts when multiple categories exist.
54
+ * @default "·"
55
+ */
56
+ readonly separator?: string;
57
+ /**
58
+ * Where to position the category in the log message.
59
+ * - `"start"`: Category appears at the beginning of the message
60
+ * - `"end"`: Category appears at the end of the message
61
+ * @default "start"
62
+ */
63
+ readonly position?: "start" | "end";
64
+ /**
65
+ * The decorator used to format the category in the log message.
66
+ * - `"[]"`: [category] format
67
+ * - `"()"`: (category) format
68
+ * - `"<>"`: <category> format
69
+ * - `"{}"`: {category} format
70
+ * - `":"`: category: format
71
+ * - `"-"`: category - format
72
+ * - `"|"`: category | format
73
+ * - `"/"`: category / format
74
+ * - `""`: category format (no decoration)
75
+ * @default ":"
76
+ */
77
+ readonly decorator?: "[]" | "()" | "<>" | "{}" | ":" | "-" | "|" | "/" | "";
78
+ }
79
+ /**
80
+ * Creates a LogTape sink that forwards log records to a Bunyan logger.
81
+ *
82
+ * Bunyan does not provide a global default logger; you must create one
83
+ * with `bunyan.createLogger({ name: "..." })` and pass it in.
84
+ *
85
+ * LogTape's `record.properties` are passed verbatim to Bunyan as the
86
+ * merge-object, so any `serializers` configured on the Bunyan logger
87
+ * apply automatically. Bunyan's reserved fields (`name`, `hostname`,
88
+ * `pid`, `level`, `time`, `msg`, `src`, `v`) should not be used as
89
+ * property keys.
90
+ *
91
+ * @example
92
+ * ```typescript
93
+ * import { configure } from "@logtape/logtape";
94
+ * import { getBunyanSink } from "@logtape/adaptor-bunyan";
95
+ * import bunyan from "bunyan";
96
+ *
97
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
98
+ *
99
+ * await configure({
100
+ * sinks: {
101
+ * bunyan: getBunyanSink(bunyanLogger, {
102
+ * category: {
103
+ * position: "start",
104
+ * decorator: "[]",
105
+ * separator: "."
106
+ * }
107
+ * })
108
+ * },
109
+ * loggers: [
110
+ * { category: "my-library", sinks: ["bunyan"] }
111
+ * ]
112
+ * });
113
+ * ```
114
+ *
115
+ * @param logger The Bunyan logger instance to forward logs to.
116
+ * @param options Configuration options for the sink adapter.
117
+ * @returns A LogTape sink function that can be used in LogTape configuration.
118
+ * @since 2.1.0
119
+ */
120
+ declare function getBunyanSink(logger: BunyanLogger, options?: BunyanSinkOptions): Sink;
121
+ /**
122
+ * Automatically configures LogTape to route all logs to a Bunyan logger.
123
+ *
124
+ * This is a convenience function that wires up `getBunyanSink()` as
125
+ * LogTape's catch-all sink and routes the meta logger
126
+ * (`["logtape", "meta"]`) to the same sink with `lowestLevel: "warning"`,
127
+ * matching the conventions of the other adapter packages.
128
+ *
129
+ * Bunyan does not provide a global default logger, so the logger argument
130
+ * is required. Create one with `bunyan.createLogger({ name: "..." })`
131
+ * and pass it in.
132
+ *
133
+ * @example Basic auto-configuration
134
+ * ```typescript
135
+ * import bunyan from "bunyan";
136
+ * import { install } from "@logtape/adaptor-bunyan";
137
+ *
138
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
139
+ * install(bunyanLogger);
140
+ *
141
+ * import { getLogger } from "@logtape/logtape";
142
+ * const logger = getLogger("my-app");
143
+ * logger.info("This will be logged through Bunyan");
144
+ * ```
145
+ *
146
+ * @example Auto-configuration with custom options
147
+ * ```typescript
148
+ * import bunyan from "bunyan";
149
+ * import { install } from "@logtape/adaptor-bunyan";
150
+ *
151
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
152
+ * install(bunyanLogger, {
153
+ * category: {
154
+ * position: "start",
155
+ * decorator: "[]",
156
+ * separator: "."
157
+ * }
158
+ * });
159
+ * ```
160
+ *
161
+ * @param logger The Bunyan logger instance to forward logs to.
162
+ * @param options Configuration options for the sink adapter.
163
+ * @since 2.1.0
164
+ */
165
+ declare function install(logger: BunyanLogger, options?: BunyanSinkOptions): void;
166
+ //# sourceMappingURL=mod.d.ts.map
167
+ //#endregion
168
+ export { BunyanLogger, BunyanSinkOptions, CategoryOptions, getBunyanSink, install };
169
+ //# sourceMappingURL=mod.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.d.ts","names":[],"sources":["../src/mod.ts"],"sourcesContent":[],"mappings":";;;;;;AAYA;;;;;;;AA2BiB,UA3BA,YAAA,CA2BA;EAAM,KAAA,CAAA,WAAA,EAzBN,MAyBM,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAUN,KAAA,CAAA,WAAA,EA9BA,MA8BiB,CAAA,MAOF,EAAA,OAAA,CAAA,EAAA,MAAe,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAoB9B,IAAA,CAAA,WAAA,EApDA,MAoDe,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EA+IhB,IAAA,CAAA,WAAa,EA9LZ,MA8LY,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAAA,KAAA,CAAA,WAAA,EAzLZ,MAyLY,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;EAAA,KACnB,CAAA,WAAA,EArLO,MAqLP,CAAA,MAAA,EAAA,OAAA,CAAA,EAAA,MAAA,EAAA,MAAA,EAAA,GAAA,IAAA,EAAA,OAAA,EAAA,CAAA,EAAA,IAAA;;;AAEH;AA+FP;;AACU,UA7QO,iBAAA,CA6QP;EAAY;AACW;;;;;gCAvQD;;;;;;;;;;;;;;;;;;UAoBf,eAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+ID,aAAA,SACN,wBACC,oBACR;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;iBA+Fa,OAAA,SACN,wBACC"}
package/dist/mod.js ADDED
@@ -0,0 +1,180 @@
1
+ import { inspect } from "node:util";
2
+ import { configureSync } from "@logtape/logtape";
3
+
4
+ //#region src/mod.ts
5
+ function defaultValueFormatter(value) {
6
+ return inspect(value, { breakLength: Infinity });
7
+ }
8
+ function renderMessage(parts, valueFormatter) {
9
+ let rendered = "";
10
+ for (let i = 0; i < parts.length; i++) if (i % 2 === 0) rendered += parts[i];
11
+ else rendered += valueFormatter(parts[i]);
12
+ return rendered;
13
+ }
14
+ function decorateCategoryStart(category, decorator) {
15
+ switch (decorator) {
16
+ case "[]": return `[${category}] `;
17
+ case "()": return `(${category}) `;
18
+ case "<>": return `<${category}> `;
19
+ case "{}": return `{${category}} `;
20
+ case ":": return `${category}: `;
21
+ case "-": return `${category} - `;
22
+ case "|": return `${category} | `;
23
+ case "/": return `${category} / `;
24
+ case "": return `${category} `;
25
+ }
26
+ }
27
+ function decorateCategoryEnd(category, decorator) {
28
+ switch (decorator) {
29
+ case "[]": return ` [${category}]`;
30
+ case "()": return ` (${category})`;
31
+ case "<>": return ` <${category}>`;
32
+ case "{}": return ` {${category}}`;
33
+ case ":": return `: ${category}`;
34
+ case "-": return ` - ${category}`;
35
+ case "|": return ` | ${category}`;
36
+ case "/": return ` / ${category}`;
37
+ case "": return ` ${category}`;
38
+ }
39
+ }
40
+ /**
41
+ * Creates a LogTape sink that forwards log records to a Bunyan logger.
42
+ *
43
+ * Bunyan does not provide a global default logger; you must create one
44
+ * with `bunyan.createLogger({ name: "..." })` and pass it in.
45
+ *
46
+ * LogTape's `record.properties` are passed verbatim to Bunyan as the
47
+ * merge-object, so any `serializers` configured on the Bunyan logger
48
+ * apply automatically. Bunyan's reserved fields (`name`, `hostname`,
49
+ * `pid`, `level`, `time`, `msg`, `src`, `v`) should not be used as
50
+ * property keys.
51
+ *
52
+ * @example
53
+ * ```typescript
54
+ * import { configure } from "@logtape/logtape";
55
+ * import { getBunyanSink } from "@logtape/adaptor-bunyan";
56
+ * import bunyan from "bunyan";
57
+ *
58
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
59
+ *
60
+ * await configure({
61
+ * sinks: {
62
+ * bunyan: getBunyanSink(bunyanLogger, {
63
+ * category: {
64
+ * position: "start",
65
+ * decorator: "[]",
66
+ * separator: "."
67
+ * }
68
+ * })
69
+ * },
70
+ * loggers: [
71
+ * { category: "my-library", sinks: ["bunyan"] }
72
+ * ]
73
+ * });
74
+ * ```
75
+ *
76
+ * @param logger The Bunyan logger instance to forward logs to.
77
+ * @param options Configuration options for the sink adapter.
78
+ * @returns A LogTape sink function that can be used in LogTape configuration.
79
+ * @since 2.1.0
80
+ */
81
+ function getBunyanSink(logger, options = {}) {
82
+ const categoryOptions = !options.category ? void 0 : typeof options.category === "object" ? options.category : {};
83
+ const category = categoryOptions == null ? void 0 : {
84
+ separator: categoryOptions.separator ?? "·",
85
+ position: categoryOptions.position ?? "start",
86
+ decorator: categoryOptions.decorator ?? ":"
87
+ };
88
+ const valueFormatter = options.valueFormatter ?? defaultValueFormatter;
89
+ return (record) => {
90
+ let message = "";
91
+ if (category != null && record.category.length > 0) {
92
+ const joined = record.category.join(category.separator);
93
+ if (category.position === "start") message += decorateCategoryStart(joined, category.decorator);
94
+ message += renderMessage(record.message, valueFormatter);
95
+ if (category.position === "end") message += decorateCategoryEnd(joined, category.decorator);
96
+ } else message = renderMessage(record.message, valueFormatter);
97
+ const properties = record.properties;
98
+ switch (record.level) {
99
+ case "trace":
100
+ logger.trace(properties, message);
101
+ return;
102
+ case "debug":
103
+ logger.debug(properties, message);
104
+ return;
105
+ case "info":
106
+ logger.info(properties, message);
107
+ return;
108
+ case "warning":
109
+ logger.warn(properties, message);
110
+ return;
111
+ case "error":
112
+ logger.error(properties, message);
113
+ return;
114
+ case "fatal":
115
+ logger.fatal(properties, message);
116
+ return;
117
+ }
118
+ };
119
+ }
120
+ /**
121
+ * Automatically configures LogTape to route all logs to a Bunyan logger.
122
+ *
123
+ * This is a convenience function that wires up `getBunyanSink()` as
124
+ * LogTape's catch-all sink and routes the meta logger
125
+ * (`["logtape", "meta"]`) to the same sink with `lowestLevel: "warning"`,
126
+ * matching the conventions of the other adapter packages.
127
+ *
128
+ * Bunyan does not provide a global default logger, so the logger argument
129
+ * is required. Create one with `bunyan.createLogger({ name: "..." })`
130
+ * and pass it in.
131
+ *
132
+ * @example Basic auto-configuration
133
+ * ```typescript
134
+ * import bunyan from "bunyan";
135
+ * import { install } from "@logtape/adaptor-bunyan";
136
+ *
137
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
138
+ * install(bunyanLogger);
139
+ *
140
+ * import { getLogger } from "@logtape/logtape";
141
+ * const logger = getLogger("my-app");
142
+ * logger.info("This will be logged through Bunyan");
143
+ * ```
144
+ *
145
+ * @example Auto-configuration with custom options
146
+ * ```typescript
147
+ * import bunyan from "bunyan";
148
+ * import { install } from "@logtape/adaptor-bunyan";
149
+ *
150
+ * const bunyanLogger = bunyan.createLogger({ name: "my-app" });
151
+ * install(bunyanLogger, {
152
+ * category: {
153
+ * position: "start",
154
+ * decorator: "[]",
155
+ * separator: "."
156
+ * }
157
+ * });
158
+ * ```
159
+ *
160
+ * @param logger The Bunyan logger instance to forward logs to.
161
+ * @param options Configuration options for the sink adapter.
162
+ * @since 2.1.0
163
+ */
164
+ function install(logger, options = {}) {
165
+ configureSync({
166
+ sinks: { bunyan: getBunyanSink(logger, options) },
167
+ loggers: [{
168
+ category: ["logtape", "meta"],
169
+ sinks: ["bunyan"],
170
+ lowestLevel: "warning"
171
+ }, {
172
+ category: [],
173
+ sinks: ["bunyan"]
174
+ }]
175
+ });
176
+ }
177
+
178
+ //#endregion
179
+ export { getBunyanSink, install };
180
+ //# sourceMappingURL=mod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mod.js","names":["value: unknown","parts: readonly (string | unknown)[]","valueFormatter: (value: unknown) => string","category: string","decorator: Required<CategoryOptions>[\"decorator\"]","logger: BunyanLogger","options: BunyanSinkOptions","category: Required<CategoryOptions> | undefined","record: LogRecord"],"sources":["../src/mod.ts"],"sourcesContent":["import { inspect } from \"node:util\";\nimport { configureSync, type LogRecord, type Sink } from \"@logtape/logtape\";\n\n/**\n * A structural representation of a [Bunyan] logger sufficient for the\n * adapter's needs. Avoids importing Bunyan's own type definitions so the\n * package builds cleanly under both Deno and Node.js.\n *\n * [Bunyan]: https://github.com/trentm/node-bunyan\n *\n * @since 2.1.0\n */\nexport interface BunyanLogger {\n trace(\n mergeObject: Record<string, unknown>,\n format: string,\n ...args: unknown[]\n ): void;\n debug(\n mergeObject: Record<string, unknown>,\n format: string,\n ...args: unknown[]\n ): void;\n info(\n mergeObject: Record<string, unknown>,\n format: string,\n ...args: unknown[]\n ): void;\n warn(\n mergeObject: Record<string, unknown>,\n format: string,\n ...args: unknown[]\n ): void;\n error(\n mergeObject: Record<string, unknown>,\n format: string,\n ...args: unknown[]\n ): void;\n fatal(\n mergeObject: Record<string, unknown>,\n format: string,\n ...args: unknown[]\n ): void;\n}\n\n/**\n * Options for configuring the Bunyan sink adapter.\n * @since 2.1.0\n */\nexport interface BunyanSinkOptions {\n /**\n * Configuration for how LogTape categories are handled in Bunyan logs.\n * - `false` or `undefined`: Categories are not included in the log message\n * - `true`: Categories are included with default formatting\n * - `CategoryOptions`: Custom category formatting configuration\n */\n readonly category?: boolean | CategoryOptions;\n\n /**\n * A function that converts an interpolated value in the message template\n * to a string. By default, values are formatted with\n * `node:util#inspect()` using `breakLength: Infinity` so each value\n * appears on a single line in the rendered `msg` field.\n *\n * Supply a custom formatter to use, for example, `JSON.stringify`,\n * a redaction-aware serializer, or any other strategy.\n * @default `(value) => inspect(value, { breakLength: Infinity })`\n */\n readonly valueFormatter?: (value: unknown) => string;\n}\n\n/**\n * Configuration options for formatting LogTape categories in Bunyan log\n * messages.\n * @since 2.1.0\n */\nexport interface CategoryOptions {\n /**\n * The separator used to join category parts when multiple categories exist.\n * @default \"·\"\n */\n readonly separator?: string;\n\n /**\n * Where to position the category in the log message.\n * - `\"start\"`: Category appears at the beginning of the message\n * - `\"end\"`: Category appears at the end of the message\n * @default \"start\"\n */\n readonly position?: \"start\" | \"end\";\n\n /**\n * The decorator used to format the category in the log message.\n * - `\"[]\"`: [category] format\n * - `\"()\"`: (category) format\n * - `\"<>\"`: <category> format\n * - `\"{}\"`: {category} format\n * - `\":\"`: category: format\n * - `\"-\"`: category - format\n * - `\"|\"`: category | format\n * - `\"/\"`: category / format\n * - `\"\"`: category format (no decoration)\n * @default \":\"\n */\n readonly decorator?: \"[]\" | \"()\" | \"<>\" | \"{}\" | \":\" | \"-\" | \"|\" | \"/\" | \"\";\n}\n\nfunction defaultValueFormatter(value: unknown): string {\n return inspect(value, { breakLength: Infinity });\n}\n\nfunction renderMessage(\n parts: readonly (string | unknown)[],\n valueFormatter: (value: unknown) => string,\n): string {\n let rendered = \"\";\n for (let i = 0; i < parts.length; i++) {\n if (i % 2 === 0) {\n rendered += parts[i] as string;\n } else {\n rendered += valueFormatter(parts[i]);\n }\n }\n return rendered;\n}\n\nfunction decorateCategoryStart(\n category: string,\n decorator: Required<CategoryOptions>[\"decorator\"],\n): string {\n switch (decorator) {\n case \"[]\":\n return `[${category}] `;\n case \"()\":\n return `(${category}) `;\n case \"<>\":\n return `<${category}> `;\n case \"{}\":\n return `{${category}} `;\n case \":\":\n return `${category}: `;\n case \"-\":\n return `${category} - `;\n case \"|\":\n return `${category} | `;\n case \"/\":\n return `${category} / `;\n case \"\":\n return `${category} `;\n }\n}\n\nfunction decorateCategoryEnd(\n category: string,\n decorator: Required<CategoryOptions>[\"decorator\"],\n): string {\n switch (decorator) {\n case \"[]\":\n return ` [${category}]`;\n case \"()\":\n return ` (${category})`;\n case \"<>\":\n return ` <${category}>`;\n case \"{}\":\n return ` {${category}}`;\n case \":\":\n return `: ${category}`;\n case \"-\":\n return ` - ${category}`;\n case \"|\":\n return ` | ${category}`;\n case \"/\":\n return ` / ${category}`;\n case \"\":\n return ` ${category}`;\n }\n}\n\n/**\n * Creates a LogTape sink that forwards log records to a Bunyan logger.\n *\n * Bunyan does not provide a global default logger; you must create one\n * with `bunyan.createLogger({ name: \"...\" })` and pass it in.\n *\n * LogTape's `record.properties` are passed verbatim to Bunyan as the\n * merge-object, so any `serializers` configured on the Bunyan logger\n * apply automatically. Bunyan's reserved fields (`name`, `hostname`,\n * `pid`, `level`, `time`, `msg`, `src`, `v`) should not be used as\n * property keys.\n *\n * @example\n * ```typescript\n * import { configure } from \"@logtape/logtape\";\n * import { getBunyanSink } from \"@logtape/adaptor-bunyan\";\n * import bunyan from \"bunyan\";\n *\n * const bunyanLogger = bunyan.createLogger({ name: \"my-app\" });\n *\n * await configure({\n * sinks: {\n * bunyan: getBunyanSink(bunyanLogger, {\n * category: {\n * position: \"start\",\n * decorator: \"[]\",\n * separator: \".\"\n * }\n * })\n * },\n * loggers: [\n * { category: \"my-library\", sinks: [\"bunyan\"] }\n * ]\n * });\n * ```\n *\n * @param logger The Bunyan logger instance to forward logs to.\n * @param options Configuration options for the sink adapter.\n * @returns A LogTape sink function that can be used in LogTape configuration.\n * @since 2.1.0\n */\nexport function getBunyanSink(\n logger: BunyanLogger,\n options: BunyanSinkOptions = {},\n): Sink {\n const categoryOptions = !options.category\n ? undefined\n : typeof options.category === \"object\"\n ? options.category\n : {};\n const category: Required<CategoryOptions> | undefined =\n categoryOptions == null ? undefined : {\n separator: categoryOptions.separator ?? \"·\",\n position: categoryOptions.position ?? \"start\",\n decorator: categoryOptions.decorator ?? \":\",\n };\n const valueFormatter = options.valueFormatter ?? defaultValueFormatter;\n return (record: LogRecord) => {\n let message = \"\";\n if (category != null && record.category.length > 0) {\n const joined = record.category.join(category.separator);\n if (category.position === \"start\") {\n message += decorateCategoryStart(joined, category.decorator);\n }\n message += renderMessage(record.message, valueFormatter);\n if (category.position === \"end\") {\n message += decorateCategoryEnd(joined, category.decorator);\n }\n } else {\n message = renderMessage(record.message, valueFormatter);\n }\n const properties = record.properties as Record<string, unknown>;\n switch (record.level) {\n case \"trace\":\n logger.trace(properties, message);\n return;\n case \"debug\":\n logger.debug(properties, message);\n return;\n case \"info\":\n logger.info(properties, message);\n return;\n case \"warning\":\n logger.warn(properties, message);\n return;\n case \"error\":\n logger.error(properties, message);\n return;\n case \"fatal\":\n logger.fatal(properties, message);\n return;\n }\n };\n}\n\n/**\n * Automatically configures LogTape to route all logs to a Bunyan logger.\n *\n * This is a convenience function that wires up `getBunyanSink()` as\n * LogTape's catch-all sink and routes the meta logger\n * (`[\"logtape\", \"meta\"]`) to the same sink with `lowestLevel: \"warning\"`,\n * matching the conventions of the other adapter packages.\n *\n * Bunyan does not provide a global default logger, so the logger argument\n * is required. Create one with `bunyan.createLogger({ name: \"...\" })`\n * and pass it in.\n *\n * @example Basic auto-configuration\n * ```typescript\n * import bunyan from \"bunyan\";\n * import { install } from \"@logtape/adaptor-bunyan\";\n *\n * const bunyanLogger = bunyan.createLogger({ name: \"my-app\" });\n * install(bunyanLogger);\n *\n * import { getLogger } from \"@logtape/logtape\";\n * const logger = getLogger(\"my-app\");\n * logger.info(\"This will be logged through Bunyan\");\n * ```\n *\n * @example Auto-configuration with custom options\n * ```typescript\n * import bunyan from \"bunyan\";\n * import { install } from \"@logtape/adaptor-bunyan\";\n *\n * const bunyanLogger = bunyan.createLogger({ name: \"my-app\" });\n * install(bunyanLogger, {\n * category: {\n * position: \"start\",\n * decorator: \"[]\",\n * separator: \".\"\n * }\n * });\n * ```\n *\n * @param logger The Bunyan logger instance to forward logs to.\n * @param options Configuration options for the sink adapter.\n * @since 2.1.0\n */\nexport function install(\n logger: BunyanLogger,\n options: BunyanSinkOptions = {},\n): void {\n configureSync({\n sinks: {\n bunyan: getBunyanSink(logger, options),\n },\n loggers: [\n {\n category: [\"logtape\", \"meta\"],\n sinks: [\"bunyan\"],\n lowestLevel: \"warning\",\n },\n { category: [], sinks: [\"bunyan\"] },\n ],\n });\n}\n"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,72 @@
1
+ {
2
+ "name": "@logtape/adaptor-bunyan",
3
+ "version": "2.1.0-dev.0",
4
+ "description": "Bunyan adapter for LogTape logging library",
5
+ "keywords": [
6
+ "logging",
7
+ "log",
8
+ "logger",
9
+ "bunyan",
10
+ "adapter",
11
+ "logtape",
12
+ "sink"
13
+ ],
14
+ "license": "MIT",
15
+ "author": {
16
+ "name": "Hong Minhee",
17
+ "email": "hong@minhee.org",
18
+ "url": "https://hongminhee.org/"
19
+ },
20
+ "homepage": "https://logtape.org/",
21
+ "repository": {
22
+ "type": "git",
23
+ "url": "git+https://github.com/dahlia/logtape.git",
24
+ "directory": "packages/adaptor-bunyan/"
25
+ },
26
+ "bugs": {
27
+ "url": "https://github.com/dahlia/logtape/issues"
28
+ },
29
+ "funding": [
30
+ "https://github.com/sponsors/dahlia"
31
+ ],
32
+ "type": "module",
33
+ "module": "./dist/mod.js",
34
+ "main": "./dist/mod.cjs",
35
+ "types": "./dist/mod.d.ts",
36
+ "exports": {
37
+ ".": {
38
+ "types": {
39
+ "import": "./dist/mod.d.ts",
40
+ "require": "./dist/mod.d.cts"
41
+ },
42
+ "import": "./dist/mod.js",
43
+ "require": "./dist/mod.cjs"
44
+ },
45
+ "./package.json": "./package.json"
46
+ },
47
+ "sideEffects": false,
48
+ "files": [
49
+ "dist/"
50
+ ],
51
+ "peerDependencies": {
52
+ "bunyan": "^1.8.0",
53
+ "@logtape/logtape": "^2.1.0"
54
+ },
55
+ "devDependencies": {
56
+ "@alinea/suite": "^0.6.3",
57
+ "@std/assert": "npm:@jsr/std__assert@^1.0.13",
58
+ "@std/async": "npm:@jsr/std__async@^1.0.13",
59
+ "@types/bunyan": "^1.8.11",
60
+ "bunyan": "^1.8.15",
61
+ "tsdown": "^0.12.7",
62
+ "typescript": "^5.8.3"
63
+ },
64
+ "scripts": {
65
+ "build": "tsdown",
66
+ "prepublish": "tsdown",
67
+ "test": "tsdown && node --experimental-transform-types --test",
68
+ "test:bun": "tsdown && bun test",
69
+ "test:deno": "deno test --allow-env --allow-sys",
70
+ "test-all": "tsdown && node --experimental-transform-types --test && bun test && deno test --allow-env --allow-sys"
71
+ }
72
+ }