@quenty/cli-output-helpers 1.12.0 → 1.13.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.
@@ -1 +1 @@
1
- {"version":3,"file":"spinner-reporter.test.js","sourceRoot":"","sources":["../../src/reporting/spinner-reporter.test.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spinner-reporter.test.js","sourceRoot":"","sources":["../../src/reporting/spinner-reporter.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@quenty/cli-output-helpers",
3
- "version": "1.12.0",
3
+ "version": "1.13.0",
4
4
  "description": "Helpers to generate Nevermore package and game templates",
5
5
  "type": "module",
6
6
  "keywords": [
@@ -59,5 +59,5 @@
59
59
  "engines": {
60
60
  "node": ">=16"
61
61
  },
62
- "gitHead": "5cba15660c2856169fd0362e1eeeca4c260029c2"
62
+ "gitHead": "9bca59da624eab5ee3f6ee7e0c0edb38e6466722"
63
63
  }
@@ -8,7 +8,6 @@
8
8
  import { formatDurationMs } from '../../cli-utils.js';
9
9
  import {
10
10
  type PackageResult,
11
- type PackageStatus,
12
11
  type ProgressSummary,
13
12
  type JobPhase,
14
13
  } from '../reporter.js';
@@ -106,8 +105,14 @@ function _extractJsonMessage(text: string): string | undefined {
106
105
 
107
106
  // ── Table rendering ─────────────────────────────────────────────────────────
108
107
 
109
- const RUNNING_PHASE_LABELS: Record<string, string> = {
108
+ // Typed Record<JobPhase, string> so adding a new JobPhase fails the build
109
+ // until a label is supplied here.
110
+ const RUNNING_PHASE_LABELS: Record<JobPhase, string> = {
111
+ waiting: '⏸ Waiting...',
110
112
  building: '🔨 Building...',
113
+ downloading: '⬇ Downloading...',
114
+ merging: '🔀 Merging...',
115
+ combining: '🔗 Combining...',
111
116
  uploading: '📤 Uploading...',
112
117
  scheduling: '⏳ Scheduling...',
113
118
  launching: '🚀 Launching...',
@@ -116,10 +121,10 @@ const RUNNING_PHASE_LABELS: Record<string, string> = {
116
121
  };
117
122
 
118
123
  export function formatRunningStatus(
119
- phase: PackageStatus,
124
+ phase: JobPhase,
120
125
  progress?: ProgressSummary
121
126
  ): string {
122
- const label = RUNNING_PHASE_LABELS[phase] ?? '🔄 Running...';
127
+ const label = RUNNING_PHASE_LABELS[phase];
123
128
  if (progress) {
124
129
  const progressText = formatProgressInline(progress);
125
130
  return progressText ? `${label} ${progressText}` : label;
@@ -31,6 +31,8 @@ export function formatProgressInline(progress?: ProgressSummary): string {
31
31
  }
32
32
  // Indeterminate: show label or just the count
33
33
  return progress.label ? `(${progress.label})` : `(${progress.completed})`;
34
+ case 'version':
35
+ return `(v${progress.version})`;
34
36
  }
35
37
  }
36
38
 
@@ -52,6 +54,8 @@ export function formatProgressResult(progress?: ProgressSummary): string {
52
54
  return `(${_formatBytes(progress.totalBytes)})`;
53
55
  case 'steps':
54
56
  return `(${progress.completed}/${progress.total})`;
57
+ case 'version':
58
+ return `(v${progress.version})`;
55
59
  }
56
60
  }
57
61
 
@@ -46,7 +46,17 @@ export interface StepProgress {
46
46
  label?: string;
47
47
  }
48
48
 
49
- export type ProgressSummary = TestCountProgress | ByteProgress | StepProgress;
49
+ /** Place version label: "v14" */
50
+ export interface VersionProgress {
51
+ kind: 'version';
52
+ version: number;
53
+ }
54
+
55
+ export type ProgressSummary =
56
+ | TestCountProgress
57
+ | ByteProgress
58
+ | StepProgress
59
+ | VersionProgress;
50
60
 
51
61
  /** Result for a single package in a batch run. */
52
62
  export interface PackageResult {
@@ -34,10 +34,14 @@ export class SimpleReporter extends BaseReporter {
34
34
 
35
35
  if (result.logs && showLogs) {
36
36
  console.log(result.logs);
37
- } else if (showLogs) {
37
+ } else if (showLogs && !result.error) {
38
38
  OutputHelper.info('(no output)');
39
39
  }
40
40
 
41
+ if (result.error) {
42
+ OutputHelper.error(result.error);
43
+ }
44
+
41
45
  const progressText = formatProgressResult(result.progressSummary);
42
46
  if (result.success) {
43
47
  const msg = progressText
@@ -12,10 +12,9 @@ function setup() {
12
12
 
13
13
  // Capture everything written to stdout
14
14
  const writes: string[] = [];
15
- const realWrite = process.stdout.write.bind(process.stdout);
16
15
  vi.spyOn(process.stdout, 'write').mockImplementation(((
17
16
  chunk: any,
18
- ...args: any[]
17
+ ..._args: any[]
19
18
  ) => {
20
19
  writes.push(typeof chunk === 'string' ? chunk : chunk.toString());
21
20
  return true;
@@ -24,7 +23,7 @@ function setup() {
24
23
  // Suppress console.log (used by startAsync header)
25
24
  vi.spyOn(console, 'log').mockImplementation(() => {});
26
25
 
27
- return { state, spinner, writes, realWrite };
26
+ return { state, spinner, writes };
28
27
  }
29
28
 
30
29
  /** Extract cursor-up escape codes (\x1b[NA) from captured writes. */
@@ -39,7 +38,7 @@ function extractCursorUps(writes: string[]): number[] {
39
38
  return results;
40
39
  }
41
40
 
42
- describe('SpinnerReporter stdout resilience', () => {
41
+ describe('SpinnerReporter cursor math', () => {
43
42
  beforeEach(() => {
44
43
  vi.useFakeTimers();
45
44
  });
@@ -49,7 +48,7 @@ describe('SpinnerReporter stdout resilience', () => {
49
48
  vi.restoreAllMocks();
50
49
  });
51
50
 
52
- it('cursor-up matches rendered line count with no external writes', async () => {
51
+ it('cursor-up matches rendered line count', async () => {
53
52
  const { state, spinner, writes } = setup();
54
53
 
55
54
  state.onPackageStart('pkg-a');
@@ -69,65 +68,96 @@ describe('SpinnerReporter stdout resilience', () => {
69
68
  await spinner.stopAsync();
70
69
  });
71
70
 
72
- it('accounts for single external stdout write between renders', async () => {
71
+ it('cursor-up ignores external writes (they are captured, not emitted)', async () => {
73
72
  const { state, spinner, writes } = setup();
74
73
 
75
74
  state.onPackageStart('pkg-a');
76
75
  await spinner.startAsync();
77
76
 
78
- // Simulate an external write between renders
77
+ // External writes during the spinner are buffered, not sent to the terminal.
79
78
  process.stdout.write('external log\n');
79
+ process.stdout.write('more\nstuff\n');
80
80
 
81
81
  writes.length = 0;
82
82
  vi.advanceTimersByTime(80);
83
83
 
84
- // Should be 3 (rendered) + 1 (external) = 4
84
+ // Still just 3 external writes never actually reach stdout, so they
85
+ // can't shift the cursor.
85
86
  const ups = extractCursorUps(writes);
86
87
  expect(ups.length).toBe(1);
87
- expect(ups[0]).toBe(4);
88
+ expect(ups[0]).toBe(3);
88
89
 
89
90
  await spinner.stopAsync();
90
91
  });
92
+ });
91
93
 
92
- it('accounts for multiple external stdout writes', async () => {
94
+ describe('SpinnerReporter output capture', () => {
95
+ beforeEach(() => {
96
+ vi.useFakeTimers();
97
+ });
98
+
99
+ afterEach(() => {
100
+ vi.useRealTimers();
101
+ vi.restoreAllMocks();
102
+ });
103
+
104
+ it('captures writes during the run and flushes them on stop', async () => {
93
105
  const { state, spinner, writes } = setup();
94
106
 
95
107
  state.onPackageStart('pkg-a');
96
108
  await spinner.startAsync();
97
109
 
98
- // 3 external lines
99
- process.stdout.write('line1\n');
100
- process.stdout.write('line2\nline3\n');
101
-
102
- writes.length = 0;
103
- vi.advanceTimersByTime(80);
110
+ // Capture index where post-spinner output begins.
111
+ process.stdout.write('hello\n');
112
+ process.stdout.write('world\n');
104
113
 
105
- // Should be 3 (rendered) + 3 (external) = 6
106
- const ups = extractCursorUps(writes);
107
- expect(ups.length).toBe(1);
108
- expect(ups[0]).toBe(6);
114
+ // Verify nothing was emitted live (only spinner frames so far).
115
+ expect(writes.join('')).not.toContain('hello');
116
+ expect(writes.join('')).not.toContain('world');
109
117
 
110
118
  await spinner.stopAsync();
119
+
120
+ // After stopAsync, the captured output must have been flushed.
121
+ const all = writes.join('');
122
+ expect(all).toContain('hello');
123
+ expect(all).toContain('world');
124
+ // Order is preserved
125
+ expect(all.indexOf('hello')).toBeLessThan(all.indexOf('world'));
111
126
  });
112
127
 
113
- it('resets extra line count after each render', async () => {
128
+ it('captures stderr writes too', async () => {
114
129
  const { state, spinner, writes } = setup();
130
+ // Intercept stderr the same way stdout is mocked.
131
+ vi.spyOn(process.stderr, 'write').mockImplementation(((
132
+ chunk: any,
133
+ ..._args: any[]
134
+ ) => {
135
+ writes.push(typeof chunk === 'string' ? chunk : chunk.toString());
136
+ return true;
137
+ }) as any);
115
138
 
116
139
  state.onPackageStart('pkg-a');
117
140
  await spinner.startAsync();
118
141
 
119
- // External write before render 2
120
- process.stdout.write('noise\n');
121
- vi.advanceTimersByTime(80);
142
+ process.stderr.write('err line\n');
122
143
 
123
- // No external write before render 3
124
- writes.length = 0;
125
- vi.advanceTimersByTime(80);
144
+ expect(writes.join('')).not.toContain('err line');
126
145
 
127
- // Render 3 should only cursor-up by renderedLineCount (3), no extras
128
- const ups = extractCursorUps(writes);
129
- expect(ups.length).toBe(1);
130
- expect(ups[0]).toBe(3);
146
+ await spinner.stopAsync();
147
+
148
+ expect(writes.join('')).toContain('err line');
149
+ });
150
+
151
+ it('invokes the Node-style completion callback on captured writes', async () => {
152
+ const { state, spinner } = setup();
153
+
154
+ state.onPackageStart('pkg-a');
155
+ await spinner.startAsync();
156
+
157
+ const cb = vi.fn();
158
+ process.stdout.write('payload\n', cb);
159
+
160
+ expect(cb).toHaveBeenCalledTimes(1);
131
161
 
132
162
  await spinner.stopAsync();
133
163
  });
@@ -1,6 +1,6 @@
1
1
  import { OutputHelper } from '../outputHelper.js';
2
2
  import { formatDurationMs } from '../cli-utils.js';
3
- import { type PackageResult, BaseReporter } from './reporter.js';
3
+ import { type JobPhase, type PackageResult, BaseReporter } from './reporter.js';
4
4
  import { type IStateTracker } from './state/state-tracker.js';
5
5
  import {
6
6
  formatProgressInline,
@@ -12,6 +12,8 @@ export interface SpinnerReporterOptions {
12
12
  showLogs: boolean;
13
13
  /** Verb used in the header, e.g. "Testing", "Deploying". Default: "Processing" */
14
14
  actionVerb?: string;
15
+ /** Extra context appended to the header line, e.g. "to target 'integration'". */
16
+ actionContext?: string;
15
17
  /** Label for successful results, e.g. "Deployed". Default: "Passed" */
16
18
  successLabel?: string;
17
19
  /** Label for failed results, e.g. "DEPLOY FAILED". Default: "FAILED" */
@@ -20,10 +22,14 @@ export interface SpinnerReporterOptions {
20
22
 
21
23
  const SPINNER_FRAMES = ['◐', '◓', '◑', '◒'];
22
24
 
23
- /** Emoji + label for each active phase in the spinner. */
24
- const PHASE_LABELS: Record<string, string> = {
25
+ // Typed Record<JobPhase, string> so adding a new JobPhase fails the build
26
+ // until a label is supplied here — otherwise the renderer's else branch
27
+ // would silently flash the failure label during the missing phase.
28
+ const PHASE_LABELS: Record<JobPhase, string> = {
25
29
  waiting: '◇ Waiting',
26
30
  building: '⚙ Building',
31
+ downloading: '⬇ Downloading',
32
+ merging: '🔀 Merging',
27
33
  combining: '🔗 Combining',
28
34
  uploading: '▲ Uploading',
29
35
  scheduling: '◇ Scheduling',
@@ -35,6 +41,14 @@ const PHASE_LABELS: Record<string, string> = {
35
41
  /**
36
42
  * TTY spinner rendering for batch job progress.
37
43
  * Reads all state from IStateTracker; re-renders on a timer interval.
44
+ *
45
+ * Stdout/stderr writes between startAsync() and stopAsync() are *captured*,
46
+ * not passed through. The spinner repaints by rewinding the cursor with
47
+ * `\x1b[NA\x1b[0J`, so any write that landed inside the spinner's render
48
+ * region would be erased on the next 80ms tick. Callers should not have to
49
+ * think about that — we buffer writes and flush them in stopAsync(), so
50
+ * `console.log` / `OutputHelper.info` / etc. during a run still surface,
51
+ * just after the spinner has finished.
38
52
  */
39
53
  export class SpinnerReporter extends BaseReporter {
40
54
  private _state: IStateTracker;
@@ -42,7 +56,7 @@ export class SpinnerReporter extends BaseReporter {
42
56
  private _renderedLineCount: number = 0;
43
57
  private _renderInterval?: ReturnType<typeof setInterval>;
44
58
  private _spinnerFrame: number = 0;
45
- private _extraLines = 0;
59
+ private _capturedOutput: string = '';
46
60
  private _originalStdoutWrite: typeof process.stdout.write | undefined;
47
61
  private _originalStderrWrite: typeof process.stderr.write | undefined;
48
62
  private _isRendering = false;
@@ -56,33 +70,47 @@ export class SpinnerReporter extends BaseReporter {
56
70
  override async startAsync(): Promise<void> {
57
71
  const count = this._state.total;
58
72
  const verb = this._options.actionVerb ?? 'Processing';
59
- console.log(
60
- OutputHelper.formatInfo(
61
- `${verb} ${count} ${count === 1 ? 'package' : 'packages'}\n`
62
- )
63
- );
73
+ const noun = count === 1 ? 'package' : 'packages';
74
+ const context = this._options.actionContext;
75
+ const header = context
76
+ ? `${verb} ${count} ${noun} ${context}`
77
+ : `${verb} ${count} ${noun}`;
78
+ console.log(OutputHelper.formatInfo(`${header}\n`));
64
79
  process.stdout.write('\x1b[?25l');
65
80
  this._renderedLineCount = 0;
66
81
 
67
- // Intercept stdout/stderr to track external writes that shift the cursor.
68
- // Both streams visually consume rows in the same terminal, so both must
69
- // count toward the cursor-rewind math.
82
+ // Intercept stdout/stderr. External writes during the spinner are
83
+ // captured into a buffer instead of going to the terminal, otherwise the
84
+ // next 80ms render tick would clobber them via the cursor-rewind. The
85
+ // buffer is flushed in stopAsync() so callers still see their output —
86
+ // just after the spinner finishes. Writes made *by* the spinner itself
87
+ // (_isRendering=true) pass through normally.
70
88
  this._originalStdoutWrite = process.stdout.write.bind(process.stdout);
71
89
  this._originalStderrWrite = process.stderr.write.bind(process.stderr);
72
90
  const self = this;
73
- const countNewlines = (chunk: any): void => {
74
- if (self._isRendering) return;
75
- const str = typeof chunk === 'string' ? chunk : chunk.toString();
76
- self._extraLines += (str.match(/\n/g) || []).length;
77
- };
78
- process.stdout.write = function (chunk: any, ...args: any[]) {
79
- countNewlines(chunk);
80
- return self._originalStdoutWrite!.call(process.stdout, chunk, ...args);
81
- } as any;
82
- process.stderr.write = function (chunk: any, ...args: any[]) {
83
- countNewlines(chunk);
84
- return self._originalStderrWrite!.call(process.stderr, chunk, ...args);
85
- } as any;
91
+ const intercept = (
92
+ originalWrite: typeof process.stdout.write,
93
+ stream: NodeJS.WriteStream
94
+ ) =>
95
+ function (chunk: any, ...args: any[]) {
96
+ if (self._isRendering) {
97
+ return originalWrite.call(stream, chunk, ...args);
98
+ }
99
+ const str = typeof chunk === 'string' ? chunk : chunk.toString();
100
+ self._capturedOutput += str;
101
+ // Invoke the optional Node-style completion callback if present.
102
+ const cb = args.find((a) => typeof a === 'function');
103
+ if (cb) cb();
104
+ return true;
105
+ };
106
+ process.stdout.write = intercept(
107
+ this._originalStdoutWrite,
108
+ process.stdout
109
+ ) as any;
110
+ process.stderr.write = intercept(
111
+ this._originalStderrWrite,
112
+ process.stderr
113
+ ) as any;
86
114
 
87
115
  this._render();
88
116
  this._renderInterval = setInterval(() => {
@@ -111,6 +139,13 @@ export class SpinnerReporter extends BaseReporter {
111
139
  process.stdout.write('\x1b[?25h');
112
140
  console.log('');
113
141
 
142
+ // Flush anything captured during the run. Goes out *after* the final
143
+ // spinner frame so callers see their late prints below the progress.
144
+ if (this._capturedOutput.length > 0) {
145
+ process.stdout.write(this._capturedOutput);
146
+ this._capturedOutput = '';
147
+ }
148
+
114
149
  if (this._options.showLogs) {
115
150
  this._printAllLogs();
116
151
  } else {
@@ -175,24 +210,12 @@ export class SpinnerReporter extends BaseReporter {
175
210
 
176
211
  let line: string;
177
212
 
178
- const phaseLabel = PHASE_LABELS[state.status];
179
-
180
213
  if (state.status === 'pending') {
181
214
  const icon = OutputHelper.formatDim('○');
182
215
  const statusText = OutputHelper.formatDim('Queued');
183
216
  line = ` ${icon} ${OutputHelper.formatDim(
184
217
  state.name.padEnd(30)
185
218
  )} ${statusText}`;
186
- } else if (phaseLabel) {
187
- const icon = OutputHelper.formatInfo(spinner);
188
- const progressText = formatProgressInline(state.progress);
189
- const plain = progressText
190
- ? `${phaseLabel} ${progressText}`
191
- : phaseLabel;
192
- const statusText = OutputHelper.formatInfo(plain.padEnd(22));
193
- line = ` ${icon} ${state.name.padEnd(
194
- 30
195
- )} ${statusText} ${OutputHelper.formatDim(time)}`;
196
219
  } else if (state.status === 'passed') {
197
220
  const icon = OutputHelper.formatSuccess('✓');
198
221
  const progressText = formatProgressResult(
@@ -208,7 +231,7 @@ export class SpinnerReporter extends BaseReporter {
208
231
  line = ` ${icon} ${state.name.padEnd(
209
232
  30
210
233
  )} ${statusText} ${OutputHelper.formatDim(time)}`;
211
- } else {
234
+ } else if (state.status === 'failed') {
212
235
  const icon = OutputHelper.formatError('✗');
213
236
  const failedPhase = state.result?.failedPhase;
214
237
  const plain = failedPhase
@@ -218,6 +241,17 @@ export class SpinnerReporter extends BaseReporter {
218
241
  line = ` ${icon} ${state.name.padEnd(
219
242
  30
220
243
  )} ${statusText} ${OutputHelper.formatDim(time)}`;
244
+ } else {
245
+ const phaseLabel = PHASE_LABELS[state.status];
246
+ const icon = OutputHelper.formatInfo(spinner);
247
+ const progressText = formatProgressInline(state.progress);
248
+ const plain = progressText
249
+ ? `${phaseLabel} ${progressText}`
250
+ : phaseLabel;
251
+ const statusText = OutputHelper.formatInfo(plain.padEnd(22));
252
+ line = ` ${icon} ${state.name.padEnd(
253
+ 30
254
+ )} ${statusText} ${OutputHelper.formatDim(time)}`;
221
255
  }
222
256
 
223
257
  lines.push(line);
@@ -232,10 +266,8 @@ export class SpinnerReporter extends BaseReporter {
232
266
 
233
267
  this._isRendering = true;
234
268
  let frame = '';
235
- const totalLines = this._renderedLineCount + this._extraLines;
236
- this._extraLines = 0;
237
- if (totalLines > 0) {
238
- frame += `\x1b[${totalLines}A\x1b[0J`;
269
+ if (this._renderedLineCount > 0) {
270
+ frame += `\x1b[${this._renderedLineCount}A\x1b[0J`;
239
271
  }
240
272
  frame += lines.join('\n') + '\n';
241
273
  process.stdout.write(frame);