-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsemantic-methods.ts
More file actions
142 lines (136 loc) · 4.95 KB
/
semantic-methods.ts
File metadata and controls
142 lines (136 loc) · 4.95 KB
1
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
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
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/**
* @file Free-function bodies for the symbol-prefixed semantic `Logger` methods
* (`done`, `fail`, `info`, `skip`, `step`, `success`, `warn`). Each strips
* any leading status symbol from the message, re-prefixes it with the theme's
* colored symbol, writes to the appropriate stream (status messages to
* stderr, `step` to stdout), and updates the shared blank-line / call-count
* tracking via the exported logger symbols. Pulling these out of `./node`
* keeps the `Logger` class body under the file-size cap. The class retains
* one-line delegators that resolve `con` / `indent` / `symbols` from its
* private state and forward them here.
*/
import { ArrayPrototypeAt, ArrayPrototypeSlice } from '../primordials/array'
import { ReflectApply } from '../primordials/reflect'
import { applyLinePrefix } from '../strings/format'
import { isBlankString } from '../strings/predicates'
import { stripLoggerSymbols } from './symbols-builder'
import { incLogCallCountSymbol, lastWasBlankSymbol } from './symbols'
import type { ConsoleLike, LoggerTrackable } from './console-methods'
import type { LogSymbols } from './types'
/**
* Apply a `node:console` method with the given indentation prefix on its first
* (string) argument.
*
* Mirrors the former private `#apply`: when the first argument is a string it
* is line-prefixed with `indent`; otherwise the args pass through unchanged.
* Tracks the blank-line state for `targetStream` and bumps the call count.
* Returns the logger for chaining.
*
* @param logger - The calling logger instance.
* @param con - The logger's resolved console instance.
* @param methodName - The `node:console` method to invoke (`log`, `error`,
* ...).
* @param args - The arguments forwarded to the console method.
* @param targetStream - The stream the method writes to.
* @param indent - The resolved indentation prefix for `targetStream`.
*/
export function applyMethod<T extends LoggerTrackable>(
logger: T,
con: ConsoleLike,
methodName: string,
args: unknown[],
targetStream: 'stderr' | 'stdout',
indent: string,
): T {
const text = ArrayPrototypeAt(args, 0)
const hasText = typeof text === 'string'
const logArgs = hasText
? [
applyLinePrefix(text, { prefix: indent }),
...ArrayPrototypeSlice(args, 1),
]
: args
ReflectApply(con[methodName] as (...a: unknown[]) => unknown, con, logArgs)
logger[lastWasBlankSymbol](hasText && isBlankString(logArgs[0]), targetStream)
logger[incLogCallCountSymbol]()
return logger
}
/**
* Logs a main step message with a colored arrow symbol to stdout.
*
* Strips any leading status symbol from `msg`, re-prefixes it with the theme's
* `step` symbol, and writes to stdout (unlike the other semantic methods, which
* go to stderr). The blank line before the step is handled by the caller.
* Returns the logger for chaining.
*
* @param logger - The calling logger instance.
* @param con - The logger's resolved console instance.
* @param indent - The resolved stdout indentation prefix.
* @param symbols - The logger's resolved `LogSymbols` map.
* @param msg - The step message to log.
* @param extras - Additional arguments to log.
*/
export function stepMethod<T extends LoggerTrackable>(
logger: T,
con: ConsoleLike,
indent: string,
symbols: LogSymbols,
msg: string,
extras: unknown[],
): T {
const text = stripLoggerSymbols(msg)
con.log(
applyLinePrefix(`${symbols.step} ${text}`, {
prefix: indent,
}),
...extras,
)
logger[lastWasBlankSymbol](false, 'stdout')
logger[incLogCallCountSymbol]()
return logger
}
/**
* Strip a leading status symbol, re-prefix with the colored symbol for
* `symbolType`, and write to stderr.
*
* Mirrors the former private `#symbolApply`: status messages (info / fail /
* success / warn / skip / done) always go to stderr. Returns the logger for
* chaining.
*
* @param logger - The calling logger instance.
* @param con - The logger's resolved console instance.
* @param indent - The resolved stderr indentation prefix.
* @param symbols - The logger's resolved `LogSymbols` map.
* @param symbolType - The `LogSymbols` key whose symbol prefixes the message.
* @param args - The message and additional arguments to log.
*/
export function symbolApplyMethod<T extends LoggerTrackable>(
logger: T,
con: ConsoleLike,
indent: string,
symbols: LogSymbols,
symbolType: string,
args: unknown[],
): T {
let text = args[0]
let extras: unknown[]
/* c8 ignore start - text-non-string arm fires only when caller passes
an object as the first argument; tests always pass a string. */
if (typeof text === 'string') {
text = stripLoggerSymbols(text)
extras = args.slice(1)
} else {
extras = args
text = ''
}
/* c8 ignore stop */
con.error(
applyLinePrefix(`${symbols[symbolType as keyof LogSymbols]} ${text}`, {
prefix: indent,
}),
...extras,
)
logger[lastWasBlankSymbol](false, 'stderr')
logger[incLogCallCountSymbol]()
return logger
}