Skip to content

Commit 44aa6e3

Browse files
kvzclaude
andcommitted
feat: replace --verbose/--quiet with --log-level (-l)
Use syslog-style severity levels inspired by @transloadit/sev-logger: - err (3): Error conditions - warn (4): Warning conditions - notice (5): Normal but significant (default) - info (6): Informational messages - debug (7): Debug-level messages Example: `npx transloadit assemblies list -l debug` 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ce030e9 commit 44aa6e3

File tree

4 files changed

+83
-33
lines changed

4 files changed

+83
-33
lines changed

README.md

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -167,17 +167,30 @@ echo '{"workspace":"my-workspace","template":"my-template","input":"image.jpg"}'
167167
All commands support these common options:
168168

169169
- `--json, -j` - Output results as JSON (useful for scripting)
170-
- `--verbose, -v` - Enable debug output (shows DEBUG messages in addition to INFO/WARNING/ERROR)
171-
- `--quiet, -q` - Suppress non-essential output (only shows ERROR messages, hides INFO and WARNING)
170+
- `--log-level, -l` - Set log verbosity level (default: notice)
172171
- `--help, -h` - Show help for a command
173172

174-
Output levels:
173+
#### Log Levels
175174

176-
| Flag | ERROR | WARNING | INFO | DEBUG |
177-
| ----------- | ----- | ------- | ---- | ----- |
178-
| `--quiet` || | | |
179-
| _(default)_ |||| |
180-
| `--verbose` |||||
175+
The CLI uses [syslog severity levels](https://en.wikipedia.org/wiki/Syslog#Severity_level). Lower = more severe, higher = more verbose:
176+
177+
| Level | Value | Description |
178+
| -------- | ----- | ------------------------------------- |
179+
| `err` | 3 | Error conditions |
180+
| `warn` | 4 | Warning conditions |
181+
| `notice` | 5 | Normal but significant **(default)** |
182+
| `info` | 6 | Informational messages |
183+
| `debug` | 7 | Debug-level messages |
184+
185+
Examples:
186+
187+
```bash
188+
# Show only errors and warnings
189+
npx transloadit assemblies list -l warn
190+
191+
# Show debug output
192+
npx transloadit assemblies list -l debug
193+
```
181194

182195
## SDK Usage
183196

src/cli/OutputCtl.ts

Lines changed: 43 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,54 @@
1+
/**
2+
* Log levels following syslog severity (https://en.wikipedia.org/wiki/Syslog#Severity_level)
3+
* Lower numbers = more severe, higher numbers = more verbose
4+
*/
5+
export const LOG_LEVEL = {
6+
ERR: 3, // Error conditions
7+
WARN: 4, // Warning conditions
8+
NOTICE: 5, // Normal but significant (default)
9+
INFO: 6, // Informational
10+
DEBUG: 7, // Debug-level messages
11+
} as const
12+
13+
export type LogLevelName = keyof typeof LOG_LEVEL
14+
export type LogLevelValue = (typeof LOG_LEVEL)[LogLevelName]
15+
16+
export const LOG_LEVEL_DEFAULT: LogLevelValue = LOG_LEVEL.NOTICE
17+
18+
/** Valid log level names for CLI parsing */
19+
export const LOG_LEVEL_NAMES = Object.keys(LOG_LEVEL).map((k) => k.toLowerCase()) as Lowercase<
20+
LogLevelName
21+
>[]
22+
23+
/** Parse a log level string to its numeric value */
24+
export function parseLogLevel(level: string): LogLevelValue {
25+
const upper = level.toUpperCase() as LogLevelName
26+
if (upper in LOG_LEVEL) {
27+
return LOG_LEVEL[upper]
28+
}
29+
throw new Error(`Invalid log level: ${level}. Valid levels: ${LOG_LEVEL_NAMES.join(', ')}`)
30+
}
31+
132
export interface OutputCtlOptions {
2-
logLevel?: number
33+
logLevel?: LogLevelValue
334
jsonMode?: boolean
435
}
536

637
/** Interface for output controllers (used to allow test mocks) */
738
export interface IOutputCtl {
839
error(msg: unknown): void
940
warn(msg: unknown): void
41+
notice(msg: unknown): void
1042
info(msg: unknown): void
1143
debug(msg: unknown): void
1244
print(simple: unknown, json: unknown): void
1345
}
1446

1547
export default class OutputCtl implements IOutputCtl {
1648
private json: boolean
17-
private logLevel: number
49+
private logLevel: LogLevelValue
1850

19-
constructor({ logLevel = 0, jsonMode = false }: OutputCtlOptions = {}) {
51+
constructor({ logLevel = LOG_LEVEL_DEFAULT, jsonMode = false }: OutputCtlOptions = {}) {
2052
this.json = jsonMode
2153
this.logLevel = logLevel
2254

@@ -33,19 +65,23 @@ export default class OutputCtl implements IOutputCtl {
3365
}
3466

3567
error(msg: unknown): void {
36-
console.error('ERROR ', msg)
68+
if (this.logLevel >= LOG_LEVEL.ERR) console.error('err ', msg)
3769
}
3870

3971
warn(msg: unknown): void {
40-
if (this.logLevel > 0) console.error('WARNING', msg)
72+
if (this.logLevel >= LOG_LEVEL.WARN) console.error('warn ', msg)
73+
}
74+
75+
notice(msg: unknown): void {
76+
if (this.logLevel >= LOG_LEVEL.NOTICE) console.error('notice ', msg)
4177
}
4278

4379
info(msg: unknown): void {
44-
if (this.logLevel > 0) console.error('INFO ', msg)
80+
if (this.logLevel >= LOG_LEVEL.INFO) console.error('info ', msg)
4581
}
4682

4783
debug(msg: unknown): void {
48-
if (this.logLevel > 1) console.error('DEBUG ', msg)
84+
if (this.logLevel >= LOG_LEVEL.DEBUG) console.error('debug ', msg)
4985
}
5086

5187
print(simple: unknown, json: unknown): void {

src/cli/commands/BaseCommand.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,16 @@ import process from 'node:process'
22
import { Command, Option } from 'clipanion'
33
import 'dotenv/config'
44
import { Transloadit as TransloaditClient } from '../../Transloadit.ts'
5-
import OutputCtl, { type IOutputCtl } from '../OutputCtl.ts'
5+
import OutputCtl, {
6+
type IOutputCtl,
7+
LOG_LEVEL_DEFAULT,
8+
LOG_LEVEL_NAMES,
9+
parseLogLevel,
10+
} from '../OutputCtl.ts'
611

712
export abstract class BaseCommand extends Command {
8-
verbose = Option.Boolean('-v,--verbose', false, {
9-
description: 'Enable debug output',
10-
})
11-
12-
quiet = Option.Boolean('-q,--quiet', false, {
13-
description: 'Disable warnings',
13+
logLevelOption = Option.String('-l,--log-level', {
14+
description: `Log level: ${LOG_LEVEL_NAMES.join(', ')} (default: notice)`,
1415
})
1516

1617
json = Option.Boolean('-j,--json', false, {
@@ -20,15 +21,10 @@ export abstract class BaseCommand extends Command {
2021
protected output!: IOutputCtl
2122
protected client!: TransloaditClient
2223

23-
protected get logLevel(): number {
24-
if (this.verbose) return 2
25-
if (this.quiet) return 0
26-
return 1
27-
}
28-
2924
protected setupOutput(): void {
25+
const logLevel = this.logLevelOption ? parseLogLevel(this.logLevelOption) : LOG_LEVEL_DEFAULT
3026
this.output = new OutputCtl({
31-
logLevel: this.logLevel,
27+
logLevel,
3228
jsonMode: this.json,
3329
})
3430
}

test/e2e/cli/OutputCtl.ts

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import type { OutputCtlOptions } from '../../../src/cli/OutputCtl.ts'
1+
import type { LogLevelValue, OutputCtlOptions } from '../../../src/cli/OutputCtl.ts'
2+
import { LOG_LEVEL_DEFAULT } from '../../../src/cli/OutputCtl.ts'
23

34
interface OutputEntry {
4-
type: 'error' | 'warn' | 'info' | 'debug' | 'print'
5+
type: 'error' | 'warn' | 'notice' | 'info' | 'debug' | 'print'
56
msg: unknown
67
json?: unknown
78
}
@@ -14,9 +15,9 @@ export default class OutputCtl {
1415
private output: OutputEntry[]
1516
// These properties are required by the src/cli/OutputCtl interface but not used in tests
1617
private json: boolean
17-
private logLevel: number
18+
private logLevel: LogLevelValue
1819

19-
constructor({ logLevel = 0, jsonMode = false }: OutputCtlOptions = {}) {
20+
constructor({ logLevel = LOG_LEVEL_DEFAULT, jsonMode = false }: OutputCtlOptions = {}) {
2021
this.output = []
2122
this.json = jsonMode
2223
this.logLevel = logLevel
@@ -30,6 +31,10 @@ export default class OutputCtl {
3031
this.output.push({ type: 'warn', msg })
3132
}
3233

34+
notice(msg: unknown): void {
35+
this.output.push({ type: 'notice', msg })
36+
}
37+
3338
info(msg: unknown): void {
3439
this.output.push({ type: 'info', msg })
3540
}

0 commit comments

Comments
 (0)