@optique/logtape 0.8.0-dev.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,20 @@
1
+ MIT License
2
+
3
+ Copyright 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,285 @@
1
+ @optique/logtape
2
+ ================
3
+
4
+ LogTape logging integration for Optique CLI parser.
5
+
6
+ This package provides parsers and utilities for integrating [LogTape] logging
7
+ library with [Optique] CLI applications. It offers various ways to configure
8
+ logging through command-line arguments.
9
+
10
+ [LogTape]: https://github.com/dahlia/logtape
11
+ [Optique]: https://github.com/dahlia/optique
12
+
13
+
14
+ Installation
15
+ ------------
16
+
17
+ ~~~~ bash
18
+ # Deno
19
+ deno add jsr:@optique/logtape jsr:@logtape/logtape
20
+
21
+ # npm
22
+ npm install @optique/logtape @logtape/logtape
23
+ ~~~~
24
+
25
+
26
+ Quick start
27
+ -----------
28
+
29
+ ~~~~ typescript
30
+ import { loggingOptions, createLoggingConfig } from "@optique/logtape";
31
+ import { object, parse } from "@optique/core";
32
+ import { configure } from "@logtape/logtape";
33
+
34
+ const parser = object({
35
+ logging: loggingOptions({ level: "verbosity" }),
36
+ });
37
+
38
+ const result = parse(parser, process.argv.slice(2));
39
+ if (result.success) {
40
+ const config = await createLoggingConfig(result.value.logging);
41
+ await configure(config);
42
+ }
43
+ ~~~~
44
+
45
+
46
+ API
47
+ ---
48
+
49
+ ### `logLevel()`
50
+
51
+ A value parser for LogTape log levels. Parses strings like `"debug"`, `"info"`,
52
+ `"warning"`, etc. into LogTape's `LogLevel` type.
53
+
54
+ ~~~~ typescript
55
+ import { logLevel } from "@optique/logtape";
56
+ import { option, withDefault, object, parse } from "@optique/core";
57
+
58
+ const parser = object({
59
+ level: withDefault(option("--log-level", "-l", logLevel()), "info"),
60
+ });
61
+
62
+ const result = parse(parser, ["--log-level=debug"]);
63
+ // result.value.level === "debug"
64
+ ~~~~
65
+
66
+ Features:
67
+ - Case-insensitive parsing (`"DEBUG"`, `"Debug"`, `"debug"` all work)
68
+ - Valid levels: `"trace"`, `"debug"`, `"info"`, `"warning"`, `"error"`,
69
+ `"fatal"`
70
+ - Provides suggestions for shell completion
71
+
72
+
73
+ ### `verbosity()`
74
+
75
+ A parser for accumulating `-v` flags to determine log level.
76
+
77
+ ~~~~ typescript
78
+ import { verbosity } from "@optique/logtape";
79
+ import { object, parse } from "@optique/core";
80
+
81
+ const parser = object({
82
+ logLevel: verbosity(),
83
+ });
84
+
85
+ // No flags -> "warning"
86
+ parse(parser, []);
87
+
88
+ // -v -> "info"
89
+ parse(parser, ["-v"]);
90
+
91
+ // -vv -> "debug"
92
+ parse(parser, ["-v", "-v"]);
93
+
94
+ // -vvv -> "trace"
95
+ parse(parser, ["-v", "-v", "-v"]);
96
+ ~~~~
97
+
98
+ Options:
99
+ - `short`: Short option name (default: `"-v"`)
100
+ - `long`: Long option name (default: `"--verbose"`)
101
+ - `baseLevel`: Starting log level (default: `"warning"`)
102
+
103
+
104
+ ### `debug()`
105
+
106
+ A simple boolean flag parser for enabling debug logging.
107
+
108
+ ~~~~ typescript
109
+ import { debug } from "@optique/logtape";
110
+ import { object, parse } from "@optique/core";
111
+
112
+ const parser = object({
113
+ logLevel: debug(),
114
+ });
115
+
116
+ // No flag -> "info"
117
+ parse(parser, []);
118
+
119
+ // --debug or -d -> "debug"
120
+ parse(parser, ["--debug"]);
121
+ ~~~~
122
+
123
+ Options:
124
+ - `short`: Short option name (default: `"-d"`)
125
+ - `long`: Long option name (default: `"--debug"`)
126
+ - `debugLevel`: Level when flag is present (default: `"debug"`)
127
+ - `normalLevel`: Level when flag is absent (default: `"info"`)
128
+
129
+
130
+ ### `logOutput()`
131
+
132
+ A parser for log output destination. Accepts `-` for console output or a file
133
+ path for file output.
134
+
135
+ ~~~~ typescript
136
+ import { logOutput, createSink } from "@optique/logtape";
137
+ import { object, parse } from "@optique/core";
138
+
139
+ const parser = object({
140
+ output: logOutput(),
141
+ });
142
+
143
+ // --log-output=- -> console output
144
+ const result1 = parse(parser, ["--log-output=-"]);
145
+ // result1.value.output === { type: "console" }
146
+
147
+ // --log-output=/var/log/app.log -> file output
148
+ const result2 = parse(parser, ["--log-output=/var/log/app.log"]);
149
+ // result2.value.output === { type: "file", path: "/var/log/app.log" }
150
+
151
+ // Create a LogTape sink from the output
152
+ const sink = await createSink(result1.value.output);
153
+ ~~~~
154
+
155
+
156
+ ### `loggingOptions()`
157
+
158
+ A preset that combines log level and log output options into a single group.
159
+ Uses a discriminated union configuration to enforce mutually exclusive options.
160
+
161
+ ~~~~ typescript
162
+ import { loggingOptions, createLoggingConfig } from "@optique/logtape";
163
+ import { object, parse } from "@optique/core";
164
+ import { configure } from "@logtape/logtape";
165
+
166
+ // Using explicit --log-level option
167
+ const parser1 = object({
168
+ logging: loggingOptions({ level: "option" }),
169
+ });
170
+ // Usage: --log-level=debug --log-output=/var/log/app.log
171
+
172
+ // Using -v verbosity flags
173
+ const parser2 = object({
174
+ logging: loggingOptions({ level: "verbosity" }),
175
+ });
176
+ // Usage: -vv --log-output=-
177
+
178
+ // Using --debug flag
179
+ const parser3 = object({
180
+ logging: loggingOptions({ level: "debug" }),
181
+ });
182
+ // Usage: --debug
183
+ ~~~~
184
+
185
+ Configuration options vary by level type:
186
+
187
+ **`level: "option"`**:
188
+ - `long`: Long option name (default: `"--log-level"`)
189
+ - `short`: Short option name (default: `"-l"`)
190
+ - `default`: Default log level (default: `"info"`)
191
+
192
+ **`level: "verbosity"`**:
193
+ - `short`: Short option name (default: `"-v"`)
194
+ - `long`: Long option name (default: `"--verbose"`)
195
+ - `baseLevel`: Base log level (default: `"warning"`)
196
+
197
+ **`level: "debug"`**:
198
+ - `short`: Short option name (default: `"-d"`)
199
+ - `long`: Long option name (default: `"--debug"`)
200
+ - `debugLevel`: Level when flag is present (default: `"debug"`)
201
+ - `normalLevel`: Level when flag is absent (default: `"info"`)
202
+
203
+ Common options:
204
+ - `output.enabled`: Whether to enable log output option (default: `true`)
205
+ - `output.long`: Long option name for output (default: `"--log-output"`)
206
+ - `groupLabel`: Label for option group in help text (default:
207
+ `"Logging options"`)
208
+
209
+
210
+ ### `createLoggingConfig()`
211
+
212
+ Converts parsed logging options into a LogTape configuration object.
213
+
214
+ ~~~~ typescript
215
+ import { loggingOptions, createLoggingConfig } from "@optique/logtape";
216
+ import { object, parse } from "@optique/core";
217
+ import { configure } from "@logtape/logtape";
218
+
219
+ const parser = object({
220
+ logging: loggingOptions({ level: "verbosity" }),
221
+ });
222
+
223
+ const result = parse(parser, ["-vv"]);
224
+ if (result.success) {
225
+ const config = await createLoggingConfig(result.value.logging, {
226
+ // Optional: configure console sink
227
+ stream: "stderr",
228
+ // Or use dynamic stream selection:
229
+ // streamResolver: (level) =>
230
+ // level === "error" || level === "fatal" ? "stderr" : "stdout"
231
+ });
232
+ await configure(config);
233
+ }
234
+ ~~~~
235
+
236
+
237
+ ### `createConsoleSink()`
238
+
239
+ Creates a console sink with configurable stream selection.
240
+
241
+ ~~~~ typescript
242
+ import { createConsoleSink } from "@optique/logtape";
243
+
244
+ // Write to stderr (default)
245
+ const sink1 = createConsoleSink();
246
+
247
+ // Write to stdout
248
+ const sink2 = createConsoleSink({ stream: "stdout" });
249
+
250
+ // Dynamic stream selection based on log level
251
+ const sink3 = createConsoleSink({
252
+ streamResolver: (level) =>
253
+ level === "error" || level === "fatal" ? "stderr" : "stdout",
254
+ });
255
+ ~~~~
256
+
257
+
258
+ ### `createSink()`
259
+
260
+ Creates a LogTape sink from a `LogOutput` value.
261
+
262
+ ~~~~ typescript
263
+ import { createSink, type LogOutput } from "@optique/logtape";
264
+
265
+ // Console sink
266
+ const consoleSink = await createSink({ type: "console" });
267
+
268
+ // File sink (requires @logtape/file package)
269
+ const fileSink = await createSink({ type: "file", path: "/var/log/app.log" });
270
+ ~~~~
271
+
272
+ > [!NOTE]
273
+ > File output requires the `@logtape/file` package to be installed:
274
+ >
275
+ > ~~~~ bash
276
+ > deno add jsr:@logtape/file
277
+ > # or
278
+ > npm install @logtape/file
279
+ > ~~~~
280
+
281
+
282
+ License
283
+ -------
284
+
285
+ Distributed under the MIT License. See the *LICENSE* file for details.