termpainter 1.3.0 → 2.0.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.
Files changed (89) hide show
  1. package/README.md +112 -40
  2. package/dist/cjs/box.cjs +16 -3
  3. package/dist/cjs/box.d.cts +5 -1
  4. package/dist/cjs/box.d.ts +5 -1
  5. package/dist/cjs/box.d.ts.map +1 -1
  6. package/dist/cjs/box.js.map +1 -1
  7. package/dist/cjs/columns.cjs +30 -0
  8. package/dist/cjs/columns.d.cts +6 -0
  9. package/dist/cjs/columns.d.ts +6 -0
  10. package/dist/cjs/columns.d.ts.map +1 -0
  11. package/dist/cjs/columns.js.map +1 -0
  12. package/dist/cjs/env.cjs +3 -0
  13. package/dist/cjs/env.d.ts.map +1 -1
  14. package/dist/cjs/env.js.map +1 -1
  15. package/dist/cjs/icons.cjs +4 -0
  16. package/dist/cjs/icons.d.cts +1 -0
  17. package/dist/cjs/icons.d.ts +1 -0
  18. package/dist/cjs/icons.d.ts.map +1 -1
  19. package/dist/cjs/icons.js.map +1 -1
  20. package/dist/cjs/index.cjs +10 -1
  21. package/dist/cjs/index.d.cts +8 -0
  22. package/dist/cjs/index.d.ts +8 -0
  23. package/dist/cjs/index.d.ts.map +1 -1
  24. package/dist/cjs/index.js.map +1 -1
  25. package/dist/cjs/spinner.cjs +14 -4
  26. package/dist/cjs/spinner.d.cts +1 -0
  27. package/dist/cjs/spinner.d.ts +1 -0
  28. package/dist/cjs/spinner.d.ts.map +1 -1
  29. package/dist/cjs/spinner.js.map +1 -1
  30. package/dist/cjs/style.cjs +28 -7
  31. package/dist/cjs/style.d.cts +6 -0
  32. package/dist/cjs/style.d.ts +6 -0
  33. package/dist/cjs/style.d.ts.map +1 -1
  34. package/dist/cjs/style.js.map +1 -1
  35. package/dist/cjs/testmode.cjs +12 -0
  36. package/dist/cjs/testmode.d.cts +3 -0
  37. package/dist/cjs/testmode.d.ts +3 -0
  38. package/dist/cjs/testmode.d.ts.map +1 -0
  39. package/dist/cjs/testmode.js.map +1 -0
  40. package/dist/cjs/theme.cjs +45 -0
  41. package/dist/cjs/theme.d.cts +27 -0
  42. package/dist/cjs/theme.d.ts +27 -0
  43. package/dist/cjs/theme.d.ts.map +1 -0
  44. package/dist/cjs/theme.js.map +1 -0
  45. package/dist/cjs/truncate.cjs +27 -0
  46. package/dist/cjs/truncate.d.cts +2 -0
  47. package/dist/cjs/truncate.d.ts +2 -0
  48. package/dist/cjs/truncate.d.ts.map +1 -0
  49. package/dist/cjs/truncate.js.map +1 -0
  50. package/dist/esm/box.js +16 -3
  51. package/dist/esm/box.js.map +1 -1
  52. package/dist/esm/columns.js +27 -0
  53. package/dist/esm/columns.js.map +1 -0
  54. package/dist/esm/env.js +3 -0
  55. package/dist/esm/env.js.map +1 -1
  56. package/dist/esm/icons.js +3 -0
  57. package/dist/esm/icons.js.map +1 -1
  58. package/dist/esm/index.js +4 -0
  59. package/dist/esm/index.js.map +1 -1
  60. package/dist/esm/spinner.js +14 -4
  61. package/dist/esm/spinner.js.map +1 -1
  62. package/dist/esm/style.js +28 -7
  63. package/dist/esm/style.js.map +1 -1
  64. package/dist/esm/testmode.js +8 -0
  65. package/dist/esm/testmode.js.map +1 -0
  66. package/dist/esm/theme.js +40 -0
  67. package/dist/esm/theme.js.map +1 -0
  68. package/dist/esm/truncate.js +24 -0
  69. package/dist/esm/truncate.js.map +1 -0
  70. package/dist/types/box.d.ts +5 -1
  71. package/dist/types/box.d.ts.map +1 -1
  72. package/dist/types/columns.d.ts +6 -0
  73. package/dist/types/columns.d.ts.map +1 -0
  74. package/dist/types/env.d.ts.map +1 -1
  75. package/dist/types/icons.d.ts +1 -0
  76. package/dist/types/icons.d.ts.map +1 -1
  77. package/dist/types/index.d.ts +8 -0
  78. package/dist/types/index.d.ts.map +1 -1
  79. package/dist/types/spinner.d.ts +1 -0
  80. package/dist/types/spinner.d.ts.map +1 -1
  81. package/dist/types/style.d.ts +6 -0
  82. package/dist/types/style.d.ts.map +1 -1
  83. package/dist/types/testmode.d.ts +3 -0
  84. package/dist/types/testmode.d.ts.map +1 -0
  85. package/dist/types/theme.d.ts +27 -0
  86. package/dist/types/theme.d.ts.map +1 -0
  87. package/dist/types/truncate.d.ts +2 -0
  88. package/dist/types/truncate.d.ts.map +1 -0
  89. package/package.json +1 -1
package/README.md CHANGED
@@ -11,7 +11,8 @@ npm install termpainter
11
11
 
12
12
  ## usage
13
13
  ```ts
14
- import { style, badge, box, paint, spin, strip, setIcons, setSilent, isInteractive } from 'termpainter'
14
+ import { style, badge, box, paint, spin, strip, columns, truncate,
15
+ setIcons, setSilent, setTheme, resetTheme, setTestMode, isInteractive } from 'termpainter'
15
16
  ```
16
17
 
17
18
  ### styles
@@ -51,6 +52,20 @@ DEBUG=1 node app.js # shows debug output
51
52
  node app.js # debug lines are invisible
52
53
  ```
53
54
 
55
+ ### list
56
+
57
+ bulleted list. each item can be a plain string or a pre-styled string.
58
+ ```ts
59
+ style.list(['Build started', 'Running tests', 'Deploying'])
60
+ // • Build started
61
+ // • Running tests
62
+ // • Deploying
63
+
64
+ style.list([style.success('Lint passed'), style.warn('Coverage at 74%')])
65
+
66
+ style.list(items, { bullet: '-', color: 'gray', indent: 2 })
67
+ ```
68
+
54
69
  ### badges
55
70
 
56
71
  inline labels. good for status, versions, environments.
@@ -64,11 +79,18 @@ badge('offline', 'red')
64
79
 
65
80
  ### boxes
66
81
 
67
- draws a clean unicode border around anything. multiline works fine. fully composable — pass styled strings directly.
82
+ draws a clean unicode border around anything. multiline works fine. fully composable — pass styled strings directly. supports an optional title in the top border.
68
83
  ```ts
69
84
  box('Deploy complete\n3 services restarted\nAll checks passed', 'green')
70
85
  box('Critical error\nProcess exited with code 1', 'red')
71
86
  box(style.success('done')) // styled content inside a box
87
+
88
+ // with title
89
+ box('Deploy complete\n3 services restarted', { color: 'green', title: 'Deploy' })
90
+ // ╭ Deploy ──────────────────╮
91
+ // │ Deploy complete │
92
+ // │ 3 services restarted │
93
+ // ╰──────────────────────────╯
72
94
  ```
73
95
 
74
96
  ### divider
@@ -121,27 +143,43 @@ style.group('Deploy', [
121
143
  // ▶ Deploy
122
144
  // ℹ Building
123
145
  // ✔ Done
146
+ ```
124
147
 
125
- style.group('Checks', [
126
- style.success('Lint passed'),
127
- style.warn('Coverage at 74%'),
128
- style.error('Tests failed'),
129
- ])
148
+ ### columns
149
+
150
+ renders two strings side by side, ANSI-aware. falls back to two lines in non-interactive environments.
151
+ ```ts
152
+ columns('Left content', 'Right content')
153
+ columns(style.success('Build passed'), style.info('Tests: 22/22'))
154
+ columns(badge('production', 'green'), badge('v2.0.0', 'cyan'))
155
+
156
+ columns(left, right, { width: 100, gap: 6 })
157
+ ```
158
+
159
+ ### truncate
160
+
161
+ truncates a string to a maximum visible length and appends `…`. uses `strip()` internally so ANSI codes don't count toward the length.
162
+ ```ts
163
+ truncate('very long string that overflows', 20)
164
+ // => 'very long string tha…'
165
+
166
+ truncate(style.success('Build complete'), 10)
167
+ // => truncated styled string with ANSI codes preserved
130
168
  ```
131
169
 
132
170
  ### spinner
133
171
 
134
- animated terminal spinner. returns a handle with `succeed` and `fail` to stop it. no external dependencies. automatically degrades to a single printed line when not running in a TTY (CI, piped output).
172
+ animated terminal spinner. returns a handle with `succeed`, `fail`, and `update`. no external dependencies. automatically degrades to static line-by-line output when not in a TTY.
135
173
  ```ts
136
174
  const s = spin('Deploying...')
137
175
 
138
- // later, when done:
176
+ s.update('Still working...') // update message while spinning
177
+ s.update('Almost done...')
178
+
139
179
  s.succeed('Deploy complete') // stops spinner, shows style.success
140
180
  s.fail('Deploy failed') // stops spinner, shows style.error
141
181
 
142
- // optional: reuse the original message
143
- s.succeed()
144
- s.fail()
182
+ s.succeed() // reuse current message
145
183
  ```
146
184
 
147
185
  ### strip
@@ -154,12 +192,47 @@ const raw = strip(style.success('Build complete'))
154
192
  fs.appendFileSync('app.log', strip(style.info('Server started')) + '\n')
155
193
  ```
156
194
 
195
+ ### themes
196
+
197
+ globally override colors and icons for all `style.*` methods. all keys are optional — unspecified entries fall back to defaults. call `resetTheme()` to restore factory defaults.
198
+ ```ts
199
+ import { setTheme, resetTheme } from 'termpainter'
200
+
201
+ setTheme({
202
+ success: { color: 'cyan', icon: '✓' },
203
+ error: { color: 'magenta', icon: '✕' },
204
+ warn: { color: 'yellow' },
205
+ info: { color: 'blue', icon: '→' },
206
+ debug: { color: 'gray', dim: true },
207
+ muted: { color: 'gray', dim: true },
208
+ highlight: { color: 'green' },
209
+ })
210
+
211
+ style.success('done') // ✓ done (cyan, custom icon)
212
+ style.error('oops') // ✕ oops (magenta)
213
+
214
+ resetTheme() // back to defaults
215
+ ```
216
+
217
+ ### test mode
218
+
219
+ makes output deterministic for snapshot testing. `style.timestamp()` omits the time prefix, `spin()` renders statically without animation, `isInteractive()` returns `false`.
220
+ ```ts
221
+ import { setTestMode } from 'termpainter'
222
+
223
+ setTestMode(true)
224
+
225
+ style.timestamp('Server started') // => 'Server started' (no [HH:MM:SS])
226
+ const s = spin('Loading...') // prints once, no animation
227
+ s.succeed('Done') // prints style.success line
228
+
229
+ setTestMode(false) // restore normal behavior
230
+ ```
231
+
157
232
  ### silent mode
158
233
 
159
234
  suppress all output globally. every function returns an empty string and produces no side effects. useful for tests, CI, and benchmarks.
160
235
  ```ts
161
- import { setSilent } from 'termpainter'
162
-
163
236
  setSilent(true)
164
237
 
165
238
  style.success('done') // ''
@@ -169,42 +242,35 @@ box('hello') // ''
169
242
  setSilent(false) // restore normal output
170
243
  ```
171
244
 
172
- ### isInteractive
173
-
174
- returns `true` if stdout is an interactive TTY. useful for conditionally using spinners or dynamic layouts.
175
- ```ts
176
- import { isInteractive } from 'termpainter'
177
-
178
- if (isInteractive()) {
179
- const s = spin('Loading...')
180
- // ...
181
- } else {
182
- console.log(style.muted('Loading...'))
183
- }
184
- ```
185
-
186
245
  ### custom icons
187
246
 
188
247
  override the default icons for any or all style methods. unspecified keys fall back to defaults.
189
248
  ```ts
190
- import { setIcons } from 'termpainter'
191
-
192
249
  setIcons({ success: '✓', error: '✕' })
193
250
 
194
- style.success('done') // ✓ done (custom icon)
195
- style.warn('careful') // ⚠ careful (default icon unchanged)
251
+ style.success('done') // ✓ done
252
+ style.warn('careful') // ⚠ careful (default unchanged)
196
253
  ```
197
254
 
198
255
  available keys: `success`, `error`, `warn`, `info`, `debug`
199
256
 
257
+ ### isInteractive
258
+
259
+ returns `true` if stdout is an interactive TTY. always `false` in test mode.
260
+ ```ts
261
+ if (isInteractive()) {
262
+ const s = spin('Loading...')
263
+ } else {
264
+ console.log(style.muted('Loading...'))
265
+ }
266
+ ```
267
+
200
268
  ---
201
269
 
202
270
  ## color support
203
271
 
204
272
  termpainter automatically strips all ANSI codes when `NO_COLOR` is set, when running in CI, or when output is piped. your logs won't be full of broken escape sequences.
205
273
  ```ts
206
- import { isColorEnabled } from 'termpainter'
207
-
208
274
  isColorEnabled() // true in an interactive terminal, false everywhere else
209
275
  ```
210
276
 
@@ -224,15 +290,21 @@ isColorEnabled() // true in an interactive terminal, false everywhere else
224
290
  | `style.highlight(msg)` | cyan |
225
291
  | `style.divider(color?)` | 40 char horizontal rule, default gray |
226
292
  | `style.table(data, color?)` | aligned key-value table, keys in cyan |
227
- | `style.timestamp(msg, color?)` | prepends [HH:MM:SS], default gray |
228
- | `badge(text, color?)` | [text] in chosen color, default white |
229
- | `box(text, color?)` | unicode border box, multiline and ANSI-aware |
293
+ | `style.timestamp(msg, color?)` | prepends [HH:MM:SS], default gray; omitted in test mode |
230
294
  | `style.group(label, lines[])` | ▶ label in cyan, lines indented 2 spaces |
231
- | `spin(msg)` | animated spinner, returns `{ succeed(msg?), fail(msg?) }` |
232
- | `strip(str)` | removes all ANSI escape codes from a string |
295
+ | `style.list(items, options?)` | bulleted list, options: bullet, color, indent |
296
+ | `badge(text, color?)` | [text] in chosen color, default white |
297
+ | `box(text, color\|options?)` | unicode border box; options: color, title |
298
+ | `columns(left, right, options?)` | two columns side by side; options: width, gap |
299
+ | `truncate(str, maxLength)` | truncate to maxLength visible chars, append … |
300
+ | `spin(msg)` | animated spinner; returns `{ succeed, fail, update }` |
301
+ | `strip(str)` | removes all ANSI escape codes |
302
+ | `setTheme(theme)` | override colors and icons globally |
303
+ | `resetTheme()` | restore default theme |
233
304
  | `setIcons(icons)` | override icons for error, success, warn, info, debug |
234
305
  | `setSilent(mode)` | suppress all output globally when `true` |
235
- | `isInteractive()` | returns `true` if stdout is a TTY |
306
+ | `setTestMode(mode)` | deterministic output for snapshot testing |
307
+ | `isInteractive()` | returns `true` if stdout is a TTY (false in test mode) |
236
308
  | `paint(text, options?)` | raw ANSI composer |
237
309
  | `isColorEnabled()` | returns true if colors are active |
238
310
 
package/dist/cjs/box.cjs CHANGED
@@ -5,13 +5,26 @@ const paint_js_1 = require('./paint.cjs');
5
5
  const codes_js_1 = require('./codes.cjs');
6
6
  const env_js_1 = require('./env.cjs');
7
7
  const silent_js_1 = require('./silent.cjs');
8
- function box(text, color = 'white') {
8
+ function box(text, options) {
9
9
  if ((0, silent_js_1.isSilent)())
10
10
  return '';
11
+ const color = (typeof options === 'string' ? options : options?.color) ?? 'white';
12
+ const title = typeof options === 'object' ? options.title : undefined;
11
13
  const lines = text.split('\n');
12
14
  const width = Math.max(...lines.map((l) => (0, paint_js_1.strip)(l).length));
15
+ function buildTop(colorCode) {
16
+ const inner = width + 2; // total dashes without title
17
+ if (title) {
18
+ const titleSection = ` ${title} `;
19
+ const dashes = Math.max(0, inner - titleSection.length);
20
+ const raw = `╭${titleSection}${'─'.repeat(dashes)}╮`;
21
+ return colorCode ? `${colorCode}${raw}${codes_js_1.RESET}` : raw;
22
+ }
23
+ const raw = `╭${'─'.repeat(inner)}╮`;
24
+ return colorCode ? `${colorCode}${raw}${codes_js_1.RESET}` : raw;
25
+ }
13
26
  if (!(0, env_js_1.isColorEnabled)()) {
14
- const top = `╭${'─'.repeat(width + 2)}╮`;
27
+ const top = buildTop();
15
28
  const bottom = `╰${'─'.repeat(width + 2)}╯`;
16
29
  const middle = lines.map((line) => {
17
30
  const padding = ' '.repeat(width - (0, paint_js_1.strip)(line).length);
@@ -20,7 +33,7 @@ function box(text, color = 'white') {
20
33
  return [top, ...middle, bottom].join('\n');
21
34
  }
22
35
  const c = paint_js_1.fgMap[color];
23
- const top = `${c}╭${'─'.repeat(width + 2)}╮${codes_js_1.RESET}`;
36
+ const top = buildTop(c);
24
37
  const bottom = `${c}╰${'─'.repeat(width + 2)}╯${codes_js_1.RESET}`;
25
38
  const middle = lines.map((line) => {
26
39
  const padding = ' '.repeat(width - (0, paint_js_1.strip)(line).length);
@@ -1,3 +1,7 @@
1
1
  import { type Color } from './paint.js';
2
- export declare function box(text: string, color?: Color): string;
2
+ export interface BoxOptions {
3
+ color?: Color;
4
+ title?: string;
5
+ }
6
+ export declare function box(text: string, options?: Color | BoxOptions): string;
3
7
  //# sourceMappingURL=box.d.ts.map
package/dist/cjs/box.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  import { type Color } from './paint.js';
2
- export declare function box(text: string, color?: Color): string;
2
+ export interface BoxOptions {
3
+ color?: Color;
4
+ title?: string;
5
+ }
6
+ export declare function box(text: string, options?: Color | BoxOptions): string;
3
7
  //# sourceMappingURL=box.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAgB,MAAM,YAAY,CAAC;AAKtD,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,GAAE,KAAe,GAAG,MAAM,CAwBhE"}
1
+ {"version":3,"file":"box.d.ts","sourceRoot":"","sources":["../../src/box.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,KAAK,EAAgB,MAAM,YAAY,CAAC;AAKtD,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,KAAK,GAAG,UAAU,GAAG,MAAM,CAwCtE"}
@@ -1 +1 @@
1
- {"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/box.ts"],"names":[],"mappings":";;AAKA,kBAwBC;AA7BD,yCAAsD;AACtD,yCAAmC;AACnC,qCAA0C;AAC1C,2CAAuC;AAEvC,SAAgB,GAAG,CAAC,IAAY,EAAE,QAAe,OAAO;IACtD,IAAI,IAAA,oBAAQ,GAAE;QAAE,OAAO,EAAE,CAAC;IAC1B,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAA,gBAAK,EAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAE7D,IAAI,CAAC,IAAA,uBAAc,GAAE,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;QACzC,MAAM,MAAM,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,GAAG,CAAC;QAC5C,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;YAChC,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,IAAA,gBAAK,EAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;YACvD,OAAO,KAAK,IAAI,GAAG,OAAO,IAAI,CAAC;QACjC,CAAC,CAAC,CAAC;QACH,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAC7C,CAAC;IAED,MAAM,CAAC,GAAG,gBAAK,CAAC,KAAK,CAAC,CAAC;IACvB,MAAM,GAAG,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,gBAAK,EAAE,CAAC;IACrD,MAAM,MAAM,GAAG,GAAG,CAAC,IAAI,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC,IAAI,gBAAK,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE;QAChC,MAAM,OAAO,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,GAAG,IAAA,gBAAK,EAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC;QACvD,OAAO,GAAG,CAAC,IAAI,gBAAK,IAAI,IAAI,GAAG,OAAO,IAAI,CAAC,IAAI,gBAAK,EAAE,CAAC;IACzD,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,EAAE,GAAG,MAAM,EAAE,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC7C,CAAC"}
1
+ {"version":3,"file":"box.js","sourceRoot":"","sources":["../../src/box.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.columns = columns;
4
+ const paint_js_1 = require('./paint.cjs');
5
+ const env_js_1 = require('./env.cjs');
6
+ const silent_js_1 = require('./silent.cjs');
7
+ function columns(left, right, options = {}) {
8
+ if ((0, silent_js_1.isSilent)())
9
+ return '';
10
+ if (!(0, env_js_1.isInteractive)()) {
11
+ return `${left}\n${right}`;
12
+ }
13
+ const totalWidth = options.width ?? 80;
14
+ const gap = options.gap ?? 4;
15
+ const colWidth = Math.floor((totalWidth - gap) / 2);
16
+ const gapStr = ' '.repeat(gap);
17
+ const leftLines = left.split('\n');
18
+ const rightLines = right.split('\n');
19
+ const lineCount = Math.max(leftLines.length, rightLines.length);
20
+ const result = [];
21
+ for (let i = 0; i < lineCount; i++) {
22
+ const l = leftLines[i] ?? '';
23
+ const r = rightLines[i] ?? '';
24
+ const visible = (0, paint_js_1.strip)(l).length;
25
+ const padding = visible < colWidth ? ' '.repeat(colWidth - visible) : '';
26
+ result.push(`${l}${padding}${gapStr}${r}`);
27
+ }
28
+ return result.join('\n');
29
+ }
30
+ //# sourceMappingURL=columns.js.map
@@ -0,0 +1,6 @@
1
+ export interface ColumnsOptions {
2
+ width?: number;
3
+ gap?: number;
4
+ }
5
+ export declare function columns(left: string, right: string, options?: ColumnsOptions): string;
6
+ //# sourceMappingURL=columns.d.ts.map
@@ -0,0 +1,6 @@
1
+ export interface ColumnsOptions {
2
+ width?: number;
3
+ gap?: number;
4
+ }
5
+ export declare function columns(left: string, right: string, options?: ColumnsOptions): string;
6
+ //# sourceMappingURL=columns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"columns.d.ts","sourceRoot":"","sources":["../../src/columns.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,MAAM,CA0BzF"}
@@ -0,0 +1 @@
1
+ {"version":3,"file":"columns.js","sourceRoot":"","sources":["../../src/columns.ts"],"names":[],"mappings":";;AASA,0BA0BC;AAnCD,yCAAmC;AACnC,qCAAyC;AACzC,2CAAuC;AAOvC,SAAgB,OAAO,CAAC,IAAY,EAAE,KAAa,EAAE,UAA0B,EAAE;IAC/E,IAAI,IAAA,oBAAQ,GAAE;QAAE,OAAO,EAAE,CAAC;IAE1B,IAAI,CAAC,IAAA,sBAAa,GAAE,EAAE,CAAC;QACrB,OAAO,GAAG,IAAI,KAAK,KAAK,EAAE,CAAC;IAC7B,CAAC;IAED,MAAM,UAAU,GAAG,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;IACvC,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,IAAI,CAAC,CAAC;IAC7B,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,UAAU,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC;IACpD,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAE/B,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACnC,MAAM,UAAU,GAAG,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,EAAE,UAAU,CAAC,MAAM,CAAC,CAAC;IAEhE,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,EAAE,CAAC,EAAE,EAAE,CAAC;QACnC,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,CAAC,GAAG,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC9B,MAAM,OAAO,GAAG,IAAA,gBAAK,EAAC,CAAC,CAAC,CAAC,MAAM,CAAC;QAChC,MAAM,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,QAAQ,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,OAAO,GAAG,MAAM,GAAG,CAAC,EAAE,CAAC,CAAC;IAC7C,CAAC;IAED,OAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC3B,CAAC"}
package/dist/cjs/env.cjs CHANGED
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.isInteractive = isInteractive;
4
4
  exports.isColorEnabled = isColorEnabled;
5
+ const testmode_js_1 = require('./testmode.cjs');
5
6
  /**
6
7
  * Returns true if ANSI color codes should be emitted.
7
8
  * Colors are disabled when any of the following are true:
@@ -10,6 +11,8 @@ exports.isColorEnabled = isColorEnabled;
10
11
  * - process.stdout.isTTY is false/undefined (output is being piped)
11
12
  */
12
13
  function isInteractive() {
14
+ if ((0, testmode_js_1.isTestMode)())
15
+ return false;
13
16
  return process.stdout.isTTY === true;
14
17
  }
15
18
  function isColorEnabled() {
@@ -1 +1 @@
1
- {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/env.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAKxC"}
1
+ {"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/env.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAgB,aAAa,IAAI,OAAO,CAGvC;AAED,wBAAgB,cAAc,IAAI,OAAO,CAKxC"}
@@ -1 +1 @@
1
- {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/env.ts"],"names":[],"mappings":";;AAOA,sCAEC;AAED,wCAKC;AAhBD;;;;;;GAMG;AACH,SAAgB,aAAa;IAC3B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;AACvC,CAAC;AAED,SAAgB,cAAc;IAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"env.js","sourceRoot":"","sources":["../../src/env.ts"],"names":[],"mappings":";;AASA,sCAGC;AAED,wCAKC;AAnBD,+CAA2C;AAE3C;;;;;;GAMG;AACH,SAAgB,aAAa;IAC3B,IAAI,IAAA,wBAAU,GAAE;QAAE,OAAO,KAAK,CAAC;IAC/B,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,IAAI,CAAC;AACvC,CAAC;AAED,SAAgB,cAAc;IAC5B,IAAI,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IACrD,IAAI,OAAO,CAAC,GAAG,CAAC,EAAE,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC;IAC/C,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK;QAAE,OAAO,KAAK,CAAC;IACxC,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -2,6 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.setIcons = setIcons;
4
4
  exports.getIcons = getIcons;
5
+ exports.resetIcons = resetIcons;
5
6
  const defaults = {
6
7
  error: '✖',
7
8
  success: '✔',
@@ -16,4 +17,7 @@ function setIcons(icons) {
16
17
  function getIcons() {
17
18
  return current;
18
19
  }
20
+ function resetIcons() {
21
+ current = { ...defaults };
22
+ }
19
23
  //# sourceMappingURL=icons.js.map
@@ -7,4 +7,5 @@ export interface Icons {
7
7
  }
8
8
  export declare function setIcons(icons: Partial<Icons>): void;
9
9
  export declare function getIcons(): Icons;
10
+ export declare function resetIcons(): void;
10
11
  //# sourceMappingURL=icons.d.ts.map
@@ -7,4 +7,5 @@ export interface Icons {
7
7
  }
8
8
  export declare function setIcons(icons: Partial<Icons>): void;
9
9
  export declare function getIcons(): Icons;
10
+ export declare function resetIcons(): void;
10
11
  //# sourceMappingURL=icons.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/icons.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAYD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAEpD;AAED,wBAAgB,QAAQ,IAAI,KAAK,CAEhC"}
1
+ {"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/icons.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,KAAK;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf;AAYD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,CAEpD;AAED,wBAAgB,QAAQ,IAAI,KAAK,CAEhC;AAED,wBAAgB,UAAU,IAAI,IAAI,CAEjC"}
@@ -1 +1 @@
1
- {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/icons.ts"],"names":[],"mappings":";;AAkBA,4BAEC;AAED,4BAEC;AAhBD,MAAM,QAAQ,GAAU;IACtB,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,IAAI,OAAO,GAAU,EAAE,GAAG,QAAQ,EAAE,CAAC;AAErC,SAAgB,QAAQ,CAAC,KAAqB;IAC5C,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;AACtC,CAAC;AAED,SAAgB,QAAQ;IACtB,OAAO,OAAO,CAAC;AACjB,CAAC"}
1
+ {"version":3,"file":"icons.js","sourceRoot":"","sources":["../../src/icons.ts"],"names":[],"mappings":";;AAkBA,4BAEC;AAED,4BAEC;AAED,gCAEC;AApBD,MAAM,QAAQ,GAAU;IACtB,KAAK,EAAE,GAAG;IACV,OAAO,EAAE,GAAG;IACZ,IAAI,EAAE,GAAG;IACT,IAAI,EAAE,GAAG;IACT,KAAK,EAAE,IAAI;CACZ,CAAC;AAEF,IAAI,OAAO,GAAU,EAAE,GAAG,QAAQ,EAAE,CAAC;AAErC,SAAgB,QAAQ,CAAC,KAAqB;IAC5C,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,GAAG,KAAK,EAAE,CAAC;AACtC,CAAC;AAED,SAAgB,QAAQ;IACtB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,SAAgB,UAAU;IACxB,OAAO,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;AAC5B,CAAC"}
@@ -14,7 +14,7 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.isInteractive = exports.isColorEnabled = exports.setSilent = exports.setIcons = exports.spin = exports.box = exports.badge = exports.style = exports.strip = exports.paint = void 0;
17
+ exports.isInteractive = exports.isColorEnabled = exports.setTestMode = exports.resetTheme = exports.setTheme = exports.setSilent = exports.setIcons = exports.truncate = exports.columns = exports.spin = exports.box = exports.badge = exports.style = exports.strip = exports.paint = void 0;
18
18
  var paint_js_1 = require('./paint.cjs');
19
19
  Object.defineProperty(exports, "paint", { enumerable: true, get: function () { return paint_js_1.paint; } });
20
20
  Object.defineProperty(exports, "strip", { enumerable: true, get: function () { return paint_js_1.strip; } });
@@ -26,10 +26,19 @@ var box_js_1 = require('./box.cjs');
26
26
  Object.defineProperty(exports, "box", { enumerable: true, get: function () { return box_js_1.box; } });
27
27
  var spinner_js_1 = require('./spinner.cjs');
28
28
  Object.defineProperty(exports, "spin", { enumerable: true, get: function () { return spinner_js_1.spin; } });
29
+ var columns_js_1 = require('./columns.cjs');
30
+ Object.defineProperty(exports, "columns", { enumerable: true, get: function () { return columns_js_1.columns; } });
31
+ var truncate_js_1 = require('./truncate.cjs');
32
+ Object.defineProperty(exports, "truncate", { enumerable: true, get: function () { return truncate_js_1.truncate; } });
29
33
  var icons_js_1 = require('./icons.cjs');
30
34
  Object.defineProperty(exports, "setIcons", { enumerable: true, get: function () { return icons_js_1.setIcons; } });
31
35
  var silent_js_1 = require('./silent.cjs');
32
36
  Object.defineProperty(exports, "setSilent", { enumerable: true, get: function () { return silent_js_1.setSilent; } });
37
+ var theme_js_1 = require('./theme.cjs');
38
+ Object.defineProperty(exports, "setTheme", { enumerable: true, get: function () { return theme_js_1.setTheme; } });
39
+ Object.defineProperty(exports, "resetTheme", { enumerable: true, get: function () { return theme_js_1.resetTheme; } });
40
+ var testmode_js_1 = require('./testmode.cjs');
41
+ Object.defineProperty(exports, "setTestMode", { enumerable: true, get: function () { return testmode_js_1.setTestMode; } });
33
42
  var env_js_1 = require('./env.cjs');
34
43
  Object.defineProperty(exports, "isColorEnabled", { enumerable: true, get: function () { return env_js_1.isColorEnabled; } });
35
44
  Object.defineProperty(exports, "isInteractive", { enumerable: true, get: function () { return env_js_1.isInteractive; } });
@@ -1,13 +1,21 @@
1
1
  export { paint, strip } from './paint.js';
2
2
  export type { PaintOptions, Color } from './paint.js';
3
3
  export { style } from './style.js';
4
+ export type { ListOptions } from './style.js';
4
5
  export { badge } from './badge.js';
5
6
  export { box } from './box.js';
7
+ export type { BoxOptions } from './box.js';
6
8
  export { spin } from './spinner.js';
7
9
  export type { SpinnerHandle } from './spinner.js';
10
+ export { columns } from './columns.js';
11
+ export type { ColumnsOptions } from './columns.js';
12
+ export { truncate } from './truncate.js';
8
13
  export { setIcons } from './icons.js';
9
14
  export type { Icons } from './icons.js';
10
15
  export { setSilent } from './silent.js';
16
+ export { setTheme, resetTheme } from './theme.js';
17
+ export type { Theme, ThemeEntry } from './theme.js';
18
+ export { setTestMode } from './testmode.js';
11
19
  export { isColorEnabled, isInteractive } from './env.js';
12
20
  export * from './codes.js';
13
21
  //# sourceMappingURL=index.d.ts.map
@@ -1,13 +1,21 @@
1
1
  export { paint, strip } from './paint.js';
2
2
  export type { PaintOptions, Color } from './paint.js';
3
3
  export { style } from './style.js';
4
+ export type { ListOptions } from './style.js';
4
5
  export { badge } from './badge.js';
5
6
  export { box } from './box.js';
7
+ export type { BoxOptions } from './box.js';
6
8
  export { spin } from './spinner.js';
7
9
  export type { SpinnerHandle } from './spinner.js';
10
+ export { columns } from './columns.js';
11
+ export type { ColumnsOptions } from './columns.js';
12
+ export { truncate } from './truncate.js';
8
13
  export { setIcons } from './icons.js';
9
14
  export type { Icons } from './icons.js';
10
15
  export { setSilent } from './silent.js';
16
+ export { setTheme, resetTheme } from './theme.js';
17
+ export type { Theme, ThemeEntry } from './theme.js';
18
+ export { setTestMode } from './testmode.js';
11
19
  export { isColorEnabled, isInteractive } from './env.js';
12
20
  export * from './codes.js';
13
21
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzD,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAC1C,YAAY,EAAE,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACtD,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACnC,OAAO,EAAE,GAAG,EAAE,MAAM,UAAU,CAAC;AAC/B,YAAY,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACpC,YAAY,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,YAAY,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AACnD,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AACtC,YAAY,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClD,YAAY,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzD,cAAc,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uCAA0C;AAAjC,iGAAA,KAAK,OAAA;AAAE,iGAAA,KAAK,OAAA;AAErB,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AACd,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AACd,mCAA+B;AAAtB,6FAAA,GAAG,OAAA;AACZ,2CAAoC;AAA3B,kGAAA,IAAI,OAAA;AAEb,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AAEjB,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,mCAAyD;AAAhD,wGAAA,cAAc,OAAA;AAAE,uGAAA,aAAa,OAAA;AACtC,6CAA2B"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,uCAA0C;AAAjC,iGAAA,KAAK,OAAA;AAAE,iGAAA,KAAK,OAAA;AAErB,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AAEd,uCAAmC;AAA1B,iGAAA,KAAK,OAAA;AACd,mCAA+B;AAAtB,6FAAA,GAAG,OAAA;AAEZ,2CAAoC;AAA3B,kGAAA,IAAI,OAAA;AAEb,2CAAuC;AAA9B,qGAAA,OAAO,OAAA;AAEhB,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,uCAAsC;AAA7B,oGAAA,QAAQ,OAAA;AAEjB,yCAAwC;AAA/B,sGAAA,SAAS,OAAA;AAClB,uCAAkD;AAAzC,oGAAA,QAAQ,OAAA;AAAE,sGAAA,UAAU,OAAA;AAE7B,6CAA4C;AAAnC,0GAAA,WAAW,OAAA;AACpB,mCAAyD;AAAhD,wGAAA,cAAc,OAAA;AAAE,uGAAA,aAAa,OAAA;AACtC,6CAA2B"}
@@ -3,15 +3,18 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.spin = spin;
4
4
  const style_js_1 = require('./style.cjs');
5
5
  const silent_js_1 = require('./silent.cjs');
6
+ const testmode_js_1 = require('./testmode.cjs');
6
7
  const FRAMES = ['⠋', '⠙', '⠹', '⠸', '⠼', '⠴', '⠦', '⠧', '⠇', '⠏'];
7
8
  function spin(msg) {
8
9
  if ((0, silent_js_1.isSilent)()) {
9
10
  return {
10
11
  succeed(_) { },
11
12
  fail(_) { },
13
+ update(_) { },
12
14
  };
13
15
  }
14
- if (!process.stdout.isTTY) {
16
+ // Non-TTY and test mode: static single-line output, no animation
17
+ if (!process.stdout.isTTY || (0, testmode_js_1.isTestMode)()) {
15
18
  process.stdout.write(style_js_1.style.muted(msg) + '\n');
16
19
  return {
17
20
  succeed(newMsg) {
@@ -20,12 +23,16 @@ function spin(msg) {
20
23
  fail(newMsg) {
21
24
  process.stdout.write(style_js_1.style.error(newMsg ?? msg) + '\n');
22
25
  },
26
+ update(newMsg) {
27
+ process.stdout.write(style_js_1.style.muted(newMsg) + '\n');
28
+ },
23
29
  };
24
30
  }
31
+ let currentMsg = msg;
25
32
  let i = 0;
26
33
  const timer = setInterval(() => {
27
34
  const frame = FRAMES[i % FRAMES.length];
28
- process.stdout.write(`\r\x1b[K${frame} ${msg}`);
35
+ process.stdout.write(`\r\x1b[K${frame} ${currentMsg}`);
29
36
  i++;
30
37
  }, 80);
31
38
  function stop(output) {
@@ -34,10 +41,13 @@ function spin(msg) {
34
41
  }
35
42
  return {
36
43
  succeed(newMsg) {
37
- stop(style_js_1.style.success(newMsg ?? msg));
44
+ stop(style_js_1.style.success(newMsg ?? currentMsg));
38
45
  },
39
46
  fail(newMsg) {
40
- stop(style_js_1.style.error(newMsg ?? msg));
47
+ stop(style_js_1.style.error(newMsg ?? currentMsg));
48
+ },
49
+ update(newMsg) {
50
+ currentMsg = newMsg;
41
51
  },
42
52
  };
43
53
  }
@@ -1,6 +1,7 @@
1
1
  export interface SpinnerHandle {
2
2
  succeed(msg?: string): void;
3
3
  fail(msg?: string): void;
4
+ update(msg: string): void;
4
5
  }
5
6
  export declare function spin(msg: string): SpinnerHandle;
6
7
  //# sourceMappingURL=spinner.d.ts.map
@@ -1,6 +1,7 @@
1
1
  export interface SpinnerHandle {
2
2
  succeed(msg?: string): void;
3
3
  fail(msg?: string): void;
4
+ update(msg: string): void;
4
5
  }
5
6
  export declare function spin(msg: string): SpinnerHandle;
6
7
  //# sourceMappingURL=spinner.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/spinner.ts"],"names":[],"mappings":"AAKA,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAwC/C"}
1
+ {"version":3,"file":"spinner.d.ts","sourceRoot":"","sources":["../../src/spinner.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,aAAa;IAC5B,OAAO,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wBAAgB,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,CAiD/C"}
@@ -1 +1 @@
1
- {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/spinner.ts"],"names":[],"mappings":";;AAUA,oBAwCC;AAlDD,yCAAmC;AACnC,2CAAuC;AAEvC,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAOlE,SAAgB,IAAI,CAAC,GAAW;IAC9B,IAAI,IAAA,oBAAQ,GAAE,EAAE,CAAC;QACf,OAAO;YACL,OAAO,CAAC,CAAU,IAAS,CAAC;YAC5B,IAAI,CAAC,CAAU,IAAS,CAAC;SAC1B,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;QAC1B,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9C,OAAO;YACL,OAAO,CAAC,MAAe;gBACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAK,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC,MAAe;gBAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAK,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAC1D,CAAC;SACF,CAAC;IACJ,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,IAAI,GAAG,EAAE,CAAC,CAAC;QAChD,CAAC,EAAE,CAAC;IACN,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,IAAI,CAAC,MAAc;QAC1B,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,MAAM,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,OAAO,CAAC,MAAe;YACrB,IAAI,CAAC,gBAAK,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC;QACrC,CAAC;QACD,IAAI,CAAC,MAAe;YAClB,IAAI,CAAC,gBAAK,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,CAAC,CAAC;QACnC,CAAC;KACF,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"spinner.js","sourceRoot":"","sources":["../../src/spinner.ts"],"names":[],"mappings":";;AAYA,oBAiDC;AA7DD,yCAAmC;AACnC,2CAAuC;AACvC,+CAA2C;AAE3C,MAAM,MAAM,GAAG,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC;AAQlE,SAAgB,IAAI,CAAC,GAAW;IAC9B,IAAI,IAAA,oBAAQ,GAAE,EAAE,CAAC;QACf,OAAO;YACL,OAAO,CAAC,CAAU,IAAS,CAAC;YAC5B,IAAI,CAAC,CAAU,IAAS,CAAC;YACzB,MAAM,CAAC,CAAS,IAAS,CAAC;SAC3B,CAAC;IACJ,CAAC;IAED,iEAAiE;IACjE,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,IAAI,IAAA,wBAAU,GAAE,EAAE,CAAC;QAC1C,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAK,CAAC,KAAK,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;QAC9C,OAAO;YACL,OAAO,CAAC,MAAe;gBACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAK,CAAC,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAC5D,CAAC;YACD,IAAI,CAAC,MAAe;gBAClB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAK,CAAC,KAAK,CAAC,MAAM,IAAI,GAAG,CAAC,GAAG,IAAI,CAAC,CAAC;YAC1D,CAAC;YACD,MAAM,CAAC,MAAc;gBACnB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,gBAAK,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC;YACnD,CAAC;SACF,CAAC;IACJ,CAAC;IAED,IAAI,UAAU,GAAG,GAAG,CAAC;IACrB,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,MAAM,KAAK,GAAG,WAAW,CAAC,GAAG,EAAE;QAC7B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QACxC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,KAAK,IAAI,UAAU,EAAE,CAAC,CAAC;QACvD,CAAC,EAAE,CAAC;IACN,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,SAAS,IAAI,CAAC,MAAc;QAC1B,aAAa,CAAC,KAAK,CAAC,CAAC;QACrB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,WAAW,MAAM,IAAI,CAAC,CAAC;IAC9C,CAAC;IAED,OAAO;QACL,OAAO,CAAC,MAAe;YACrB,IAAI,CAAC,gBAAK,CAAC,OAAO,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,CAAC,MAAe;YAClB,IAAI,CAAC,gBAAK,CAAC,KAAK,CAAC,MAAM,IAAI,UAAU,CAAC,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,CAAC,MAAc;YACnB,UAAU,GAAG,MAAM,CAAC;QACtB,CAAC;KACF,CAAC;AACJ,CAAC"}