Skip to content

Commit 327dd7a

Browse files
authored
refactor: simplify ProcessOutput constructor (#1095)
relates #1053 * refactor: simplify `ProcessOutput` constructor * refactor: make private lazy dto factory * chore: update dts tests
1 parent 5ba714d commit 327dd7a

File tree

2 files changed

+94
-77
lines changed

2 files changed

+94
-77
lines changed

src/core.ts

+88-70
Original file line numberDiff line numberDiff line change
@@ -203,9 +203,7 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
203203
},
204204
}
205205
)
206-
/**
207-
* State machine stages
208-
*/
206+
209207
type ProcessStage = 'initial' | 'halted' | 'running' | 'fulfilled' | 'rejected'
210208

211209
type Resolve = (out: ProcessOutput) => void
@@ -312,35 +310,23 @@ export class ProcessPromise extends Promise<ProcessOutput> {
312310
$.log({ kind: 'stderr', data, verbose: !self.isQuiet(), id })
313311
},
314312
end: (data, c) => {
315-
const { error, status, signal, duration, ctx } = data
316-
const { stdout, stderr, stdall } = ctx.store
317-
const dto: ProcessOutputLazyDto = {
318-
code: () => status,
319-
signal: () => signal,
320-
duration: () => duration,
321-
stdout: once(() => bufArrJoin(stdout)),
322-
stderr: once(() => bufArrJoin(stderr)),
323-
stdall: once(() => bufArrJoin(stdall)),
324-
message: once(() => ProcessOutput.getExitMessage(
325-
status,
326-
signal,
327-
dto.stderr(),
328-
self._from
329-
)),
330-
...error && {
331-
code: () => null,
332-
signal: () => null,
333-
message: () => ProcessOutput.getErrorMessage(error, self._from)
334-
}
335-
}
313+
const { error, status, signal, duration, ctx: {store} } = data
314+
const { stdout, stderr } = store
315+
const output = self._output = new ProcessOutput({
316+
code: status,
317+
signal,
318+
error,
319+
duration,
320+
store,
321+
from: self._from,
322+
})
323+
324+
$.log({ kind: 'end', signal, exitCode: status, duration, error, verbose: self.isVerbose(), id })
336325

337326
// Ensures EOL
338327
if (stdout.length && getLast(getLast(stdout)) !== BR_CC) c.on.stdout!(EOL, c)
339328
if (stderr.length && getLast(getLast(stderr)) !== BR_CC) c.on.stderr!(EOL, c)
340329

341-
$.log({ kind: 'end', signal, exitCode: status, duration, error, verbose: self.isVerbose(), id })
342-
const output = self._output = new ProcessOutput(dto)
343-
344330
if (error || status !== 0 && !self.isNothrow()) {
345331
self._stage = 'rejected'
346332
self._reject(output)
@@ -669,76 +655,72 @@ export class ProcessPromise extends Promise<ProcessOutput> {
669655
}
670656
}
671657

672-
type GettersRecord<T extends Record<any, any>> = { [K in keyof T]: () => T[K] }
673-
674-
type ProcessOutputLazyDto = GettersRecord<{
658+
type ProcessDto = {
675659
code: number | null
676660
signal: NodeJS.Signals | null
661+
duration: number
662+
error: any
663+
from: string
664+
store: TSpawnStore
665+
}
666+
667+
type ProcessOutputDto = ProcessDto & {
677668
stdout: string
678669
stderr: string
679670
stdall: string
680671
message: string
681-
duration: number
682-
}>
672+
}
683673

684674
export class ProcessOutput extends Error {
685-
private readonly _code: number | null = null
686-
private readonly _signal: NodeJS.Signals | null
687-
private readonly _stdout: string
688-
private readonly _stderr: string
689-
private readonly _combined: string
690-
private readonly _duration: number
691-
692-
constructor(dto: ProcessOutputLazyDto)
675+
private readonly _dto: ProcessOutputDto
676+
constructor(dto: ProcessDto)
693677
constructor(
694678
code: number | null,
695679
signal: NodeJS.Signals | null,
696680
stdout: string,
697681
stderr: string,
698-
combined: string,
682+
stdall: string,
699683
message: string,
700684
duration?: number
701685
)
702686
constructor(
703-
code: number | null | ProcessOutputLazyDto,
687+
code: number | null | ProcessDto,
704688
signal: NodeJS.Signals | null = null,
705689
stdout: string = '',
706690
stderr: string = '',
707-
combined: string = '',
691+
stdall: string = '',
708692
message: string = '',
709693
duration: number = 0
710694
) {
711695
super(message)
712-
this._signal = signal
713-
this._stdout = stdout
714-
this._stderr = stderr
715-
this._combined = combined
716-
this._duration = duration
717-
if (code !== null && typeof code === 'object') {
718-
Object.defineProperties(this, {
719-
_code: { get: code.code },
720-
_signal: { get: code.signal },
721-
_duration: { get: code.duration },
722-
_stdout: { get: code.stdout },
723-
_stderr: { get: code.stderr },
724-
_combined: { get: code.stdall },
725-
message: { get: code.message },
726-
})
727-
} else {
728-
this._code = code
729-
}
696+
Reflect.deleteProperty(this, 'message')
697+
this._dto =
698+
code !== null && typeof code === 'object'
699+
? ProcessOutput.createLazyDto(code)
700+
: {
701+
code,
702+
signal,
703+
duration,
704+
stdout,
705+
stderr,
706+
stdall,
707+
error: null,
708+
from: '',
709+
message,
710+
store: { stdout: [], stderr: [], stdall: [] },
711+
}
730712
}
731713

732714
toString(): string {
733-
return this._combined
715+
return this._dto.stdall
734716
}
735717

736718
json<T = any>(): T {
737-
return JSON.parse(this._combined)
719+
return JSON.parse(this._dto.stdall)
738720
}
739721

740722
buffer(): Buffer {
741-
return Buffer.from(this._combined)
723+
return Buffer.from(this._dto.stdall)
742724
}
743725

744726
blob(type = 'text/plain'): Blob {
@@ -760,27 +742,63 @@ export class ProcessOutput extends Error {
760742
}
761743

762744
valueOf(): string {
763-
return this._combined.trim()
745+
return this._dto.stdall.trim()
764746
}
765747

766748
get stdout(): string {
767-
return this._stdout
749+
return this._dto.stdout
768750
}
769751

770752
get stderr(): string {
771-
return this._stderr
753+
return this._dto.stderr
772754
}
773755

774756
get exitCode(): number | null {
775-
return this._code
757+
return this._dto.code
776758
}
777759

778760
get signal(): NodeJS.Signals | null {
779-
return this._signal
761+
return this._dto.signal
780762
}
781763

782764
get duration(): number {
783-
return this._duration
765+
return this._dto.duration
766+
}
767+
768+
get message(): string {
769+
return this._dto.message
770+
}
771+
772+
private static createLazyDto({
773+
code,
774+
signal,
775+
duration,
776+
store: { stdout, stderr, stdall },
777+
from,
778+
error,
779+
}: ProcessDto): ProcessOutputDto {
780+
const dto = Object.defineProperties(
781+
{
782+
code,
783+
signal,
784+
duration,
785+
},
786+
{
787+
stdout: { get: once(() => bufArrJoin(stdout)) },
788+
stderr: { get: once(() => bufArrJoin(stderr)) },
789+
stdall: { get: once(() => bufArrJoin(stdall)) },
790+
message: {
791+
get: once(() =>
792+
ProcessOutput.getExitMessage(code, signal, dto.stderr, from)
793+
),
794+
},
795+
...(error && {
796+
message: { get: () => ProcessOutput.getErrorMessage(error, from) },
797+
}),
798+
}
799+
) as ProcessOutputDto
800+
801+
return dto
784802
}
785803

786804
static getExitMessage = formatExitMessage

test-d/core.test-d.ts

+6-7
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,12 @@ expectType<number | null>(o.exitCode)
4646
expectType<NodeJS.Signals | null>(o.signal)
4747
// prettier-ignore
4848
expectType<ProcessOutput>(new ProcessOutput({
49-
code() { return null },
50-
signal() { return null },
51-
stdall() { return '' },
52-
stderr() { return '' },
53-
stdout() { return '' },
54-
duration() { return 0 },
55-
message() { return '' },
49+
code: null,
50+
signal: null,
51+
duration: 0,
52+
store: { stdout: [], stderr: [], stdall: [] },
53+
error: null,
54+
from: ''
5655
}))
5756

5857
expectType<ProcessOutput>(new ProcessOutput(null, null, '', '', '', '', 1))

0 commit comments

Comments
 (0)