@quenty/cli-output-helpers 1.11.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.11.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": "82b1b57a799a4b35231d426e3561be9ab5b36ba2"
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,8 +56,9 @@ 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;
61
+ private _originalStderrWrite: typeof process.stderr.write | undefined;
47
62
  private _isRendering = false;
48
63
 
49
64
  constructor(state: IStateTracker, options: SpinnerReporterOptions) {
@@ -55,24 +70,47 @@ export class SpinnerReporter extends BaseReporter {
55
70
  override async startAsync(): Promise<void> {
56
71
  const count = this._state.total;
57
72
  const verb = this._options.actionVerb ?? 'Processing';
58
- console.log(
59
- OutputHelper.formatInfo(
60
- `${verb} ${count} ${count === 1 ? 'package' : 'packages'}\n`
61
- )
62
- );
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`));
63
79
  process.stdout.write('\x1b[?25l');
64
80
  this._renderedLineCount = 0;
65
81
 
66
- // Intercept stdout to track external writes that shift the cursor
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.
67
88
  this._originalStdoutWrite = process.stdout.write.bind(process.stdout);
89
+ this._originalStderrWrite = process.stderr.write.bind(process.stderr);
68
90
  const self = this;
69
- process.stdout.write = function (chunk: any, ...args: any[]) {
70
- if (!self._isRendering) {
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
+ }
71
99
  const str = typeof chunk === 'string' ? chunk : chunk.toString();
72
- self._extraLines += (str.match(/\n/g) || []).length;
73
- }
74
- return self._originalStdoutWrite!.call(process.stdout, chunk, ...args);
75
- } as any;
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;
76
114
 
77
115
  this._render();
78
116
  this._renderInterval = setInterval(() => {
@@ -88,15 +126,26 @@ export class SpinnerReporter extends BaseReporter {
88
126
  }
89
127
  this._render();
90
128
 
91
- // Restore original stdout.write
129
+ // Restore original stdout.write / stderr.write
92
130
  if (this._originalStdoutWrite) {
93
131
  process.stdout.write = this._originalStdoutWrite;
94
132
  this._originalStdoutWrite = undefined;
95
133
  }
134
+ if (this._originalStderrWrite) {
135
+ process.stderr.write = this._originalStderrWrite;
136
+ this._originalStderrWrite = undefined;
137
+ }
96
138
 
97
139
  process.stdout.write('\x1b[?25h');
98
140
  console.log('');
99
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
+
100
149
  if (this._options.showLogs) {
101
150
  this._printAllLogs();
102
151
  } else {
@@ -161,24 +210,12 @@ export class SpinnerReporter extends BaseReporter {
161
210
 
162
211
  let line: string;
163
212
 
164
- const phaseLabel = PHASE_LABELS[state.status];
165
-
166
213
  if (state.status === 'pending') {
167
214
  const icon = OutputHelper.formatDim('○');
168
215
  const statusText = OutputHelper.formatDim('Queued');
169
216
  line = ` ${icon} ${OutputHelper.formatDim(
170
217
  state.name.padEnd(30)
171
218
  )} ${statusText}`;
172
- } else if (phaseLabel) {
173
- const icon = OutputHelper.formatInfo(spinner);
174
- const progressText = formatProgressInline(state.progress);
175
- const plain = progressText
176
- ? `${phaseLabel} ${progressText}`
177
- : phaseLabel;
178
- const statusText = OutputHelper.formatInfo(plain.padEnd(22));
179
- line = ` ${icon} ${state.name.padEnd(
180
- 30
181
- )} ${statusText} ${OutputHelper.formatDim(time)}`;
182
219
  } else if (state.status === 'passed') {
183
220
  const icon = OutputHelper.formatSuccess('✓');
184
221
  const progressText = formatProgressResult(
@@ -194,7 +231,7 @@ export class SpinnerReporter extends BaseReporter {
194
231
  line = ` ${icon} ${state.name.padEnd(
195
232
  30
196
233
  )} ${statusText} ${OutputHelper.formatDim(time)}`;
197
- } else {
234
+ } else if (state.status === 'failed') {
198
235
  const icon = OutputHelper.formatError('✗');
199
236
  const failedPhase = state.result?.failedPhase;
200
237
  const plain = failedPhase
@@ -204,6 +241,17 @@ export class SpinnerReporter extends BaseReporter {
204
241
  line = ` ${icon} ${state.name.padEnd(
205
242
  30
206
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)}`;
207
255
  }
208
256
 
209
257
  lines.push(line);
@@ -218,10 +266,8 @@ export class SpinnerReporter extends BaseReporter {
218
266
 
219
267
  this._isRendering = true;
220
268
  let frame = '';
221
- const totalLines = this._renderedLineCount + this._extraLines;
222
- this._extraLines = 0;
223
- if (totalLines > 0) {
224
- frame += `\x1b[${totalLines}A\x1b[0J`;
269
+ if (this._renderedLineCount > 0) {
270
+ frame += `\x1b[${this._renderedLineCount}A\x1b[0J`;
225
271
  }
226
272
  frame += lines.join('\n') + '\n';
227
273
  process.stdout.write(frame);