@@ -98,14 +98,17 @@ const limitOptions = <TOption>(params: LimitOptionsParams<TOption>): string[] =>
98
98
} ) ;
99
99
} ;
100
100
101
- export interface TextOptions {
101
+ export interface CommonOptions {
102
+ input ?: Readable ;
103
+ output ?: Writable ;
104
+ }
105
+
106
+ export interface TextOptions extends CommonOptions {
102
107
message : string ;
103
108
placeholder ?: string ;
104
109
defaultValue ?: string ;
105
110
initialValue ?: string ;
106
111
validate ?: ( value : string ) => string | Error | undefined ;
107
- input ?: Readable ;
108
- output ?: Writable ;
109
112
}
110
113
export const text = ( opts : TextOptions ) => {
111
114
return new TextPrompt ( {
@@ -140,7 +143,7 @@ export const text = (opts: TextOptions) => {
140
143
} ) . prompt ( ) as Promise < string | symbol > ;
141
144
} ;
142
145
143
- export interface PasswordOptions {
146
+ export interface PasswordOptions extends CommonOptions {
144
147
message : string ;
145
148
mask ?: string ;
146
149
validate ?: ( value : string ) => string | Error | undefined ;
@@ -149,6 +152,8 @@ export const password = (opts: PasswordOptions) => {
149
152
return new PasswordPrompt ( {
150
153
validate : opts . validate ,
151
154
mask : opts . mask ?? S_PASSWORD_MASK ,
155
+ input : opts . input ,
156
+ output : opts . output ,
152
157
render ( ) {
153
158
const title = `${ color . gray ( S_BAR ) } \n${ symbol ( this . state ) } ${ opts . message } \n` ;
154
159
const value = this . valueWithCursor ;
@@ -172,7 +177,7 @@ export const password = (opts: PasswordOptions) => {
172
177
} ) . prompt ( ) as Promise < string | symbol > ;
173
178
} ;
174
179
175
- export interface ConfirmOptions {
180
+ export interface ConfirmOptions extends CommonOptions {
176
181
message : string ;
177
182
active ?: string ;
178
183
inactive ?: string ;
@@ -184,6 +189,8 @@ export const confirm = (opts: ConfirmOptions) => {
184
189
return new ConfirmPrompt ( {
185
190
active,
186
191
inactive,
192
+ input : opts . input ,
193
+ output : opts . output ,
187
194
initialValue : opts . initialValue ?? true ,
188
195
render ( ) {
189
196
const title = `${ color . gray ( S_BAR ) } \n${ symbol ( this . state ) } ${ opts . message } \n` ;
@@ -252,7 +259,7 @@ export type Option<Value> = Value extends Primitive
252
259
hint ?: string ;
253
260
} ;
254
261
255
- export interface SelectOptions < Value > {
262
+ export interface SelectOptions < Value > extends CommonOptions {
256
263
message : string ;
257
264
options : Option < Value > [ ] ;
258
265
initialValue ?: Value ;
@@ -278,6 +285,8 @@ export const select = <Value>(opts: SelectOptions<Value>) => {
278
285
279
286
return new SelectPrompt ( {
280
287
options : opts . options ,
288
+ input : opts . input ,
289
+ output : opts . output ,
281
290
initialValue : opts . initialValue ,
282
291
render ( ) {
283
292
const title = `${ color . gray ( S_BAR ) } \n${ symbol ( this . state ) } ${ opts . message } \n` ;
@@ -327,6 +336,8 @@ export const selectKey = <Value extends string>(opts: SelectOptions<Value>) => {
327
336
328
337
return new SelectKeyPrompt ( {
329
338
options : opts . options ,
339
+ input : opts . input ,
340
+ output : opts . output ,
330
341
initialValue : opts . initialValue ,
331
342
render ( ) {
332
343
const title = `${ color . gray ( S_BAR ) } \n${ symbol ( this . state ) } ${ opts . message } \n` ;
@@ -351,7 +362,7 @@ export const selectKey = <Value extends string>(opts: SelectOptions<Value>) => {
351
362
} ) . prompt ( ) as Promise < Value | symbol > ;
352
363
} ;
353
364
354
- export interface MultiSelectOptions < Value > {
365
+ export interface MultiSelectOptions < Value > extends CommonOptions {
355
366
message : string ;
356
367
options : Option < Value > [ ] ;
357
368
initialValues ?: Value [ ] ;
@@ -389,6 +400,8 @@ export const multiselect = <Value>(opts: MultiSelectOptions<Value>) => {
389
400
390
401
return new MultiSelectPrompt ( {
391
402
options : opts . options ,
403
+ input : opts . input ,
404
+ output : opts . output ,
392
405
initialValues : opts . initialValues ,
393
406
required : opts . required ?? true ,
394
407
cursorAt : opts . cursorAt ,
@@ -461,7 +474,7 @@ export const multiselect = <Value>(opts: MultiSelectOptions<Value>) => {
461
474
} ) . prompt ( ) as Promise < Value [ ] | symbol > ;
462
475
} ;
463
476
464
- export interface GroupMultiSelectOptions < Value > {
477
+ export interface GroupMultiSelectOptions < Value > extends CommonOptions {
465
478
message : string ;
466
479
options : Record < string , Option < Value > [ ] > ;
467
480
initialValues ?: Value [ ] ;
@@ -522,6 +535,8 @@ export const groupMultiselect = <Value>(opts: GroupMultiSelectOptions<Value>) =>
522
535
523
536
return new GroupMultiSelectPrompt ( {
524
537
options : opts . options ,
538
+ input : opts . input ,
539
+ output : opts . output ,
525
540
initialValues : opts . initialValues ,
526
541
required : opts . required ?? true ,
527
542
cursorAt : opts . cursorAt ,
@@ -614,9 +629,10 @@ export const groupMultiselect = <Value>(opts: GroupMultiSelectOptions<Value>) =>
614
629
} ) . prompt ( ) as Promise < Value [ ] | symbol > ;
615
630
} ;
616
631
617
- export const note = ( message = '' , title = '' ) => {
632
+ export const note = ( message = '' , title = '' , opts ?: CommonOptions ) => {
618
633
const lines = `\n${ message } \n` . split ( '\n' ) ;
619
634
const titleLen = strip ( title ) . length ;
635
+ const output : Writable = opts ?. output ?? process . stdout ;
620
636
const len =
621
637
Math . max (
622
638
lines . reduce ( ( sum , ln ) => {
@@ -633,59 +649,71 @@ export const note = (message = '', title = '') => {
633
649
) } `
634
650
)
635
651
. join ( '\n' ) ;
636
- process . stdout . write (
652
+ output . write (
637
653
`${ color . gray ( S_BAR ) } \n${ color . green ( S_STEP_SUBMIT ) } ${ color . reset ( title ) } ${ color . gray (
638
654
S_BAR_H . repeat ( Math . max ( len - titleLen - 1 , 1 ) ) + S_CORNER_TOP_RIGHT
639
655
) } \n${ msg } \n${ color . gray ( S_CONNECT_LEFT + S_BAR_H . repeat ( len + 2 ) + S_CORNER_BOTTOM_RIGHT ) } \n`
640
656
) ;
641
657
} ;
642
658
643
- export const cancel = ( message = '' ) => {
644
- process . stdout . write ( `${ color . gray ( S_BAR_END ) } ${ color . red ( message ) } \n\n` ) ;
659
+ export const cancel = ( message = '' , opts ?: CommonOptions ) => {
660
+ const output : Writable = opts ?. output ?? process . stdout ;
661
+ output . write ( `${ color . gray ( S_BAR_END ) } ${ color . red ( message ) } \n\n` ) ;
645
662
} ;
646
663
647
- export const intro = ( title = '' ) => {
648
- process . stdout . write ( `${ color . gray ( S_BAR_START ) } ${ title } \n` ) ;
664
+ export const intro = ( title = '' , opts ?: CommonOptions ) => {
665
+ const output : Writable = opts ?. output ?? process . stdout ;
666
+ output . write ( `${ color . gray ( S_BAR_START ) } ${ title } \n` ) ;
649
667
} ;
650
668
651
- export const outro = ( message = '' ) => {
652
- process . stdout . write ( `${ color . gray ( S_BAR ) } \n${ color . gray ( S_BAR_END ) } ${ message } \n\n` ) ;
669
+ export const outro = ( message = '' , opts ?: CommonOptions ) => {
670
+ const output : Writable = opts ?. output ?? process . stdout ;
671
+ output . write ( `${ color . gray ( S_BAR ) } \n${ color . gray ( S_BAR_END ) } ${ message } \n\n` ) ;
653
672
} ;
654
673
655
- export type LogMessageOptions = {
674
+ export interface LogMessageOptions extends CommonOptions {
656
675
symbol ?: string ;
657
- } ;
676
+ }
658
677
export const log = {
659
- message : ( message = '' , { symbol = color . gray ( S_BAR ) } : LogMessageOptions = { } ) => {
678
+ message : (
679
+ message = '' ,
680
+ { symbol = color . gray ( S_BAR ) , output = process . stdout } : LogMessageOptions = { }
681
+ ) => {
660
682
const parts = [ `${ color . gray ( S_BAR ) } ` ] ;
661
683
if ( message ) {
662
684
const [ firstLine , ...lines ] = message . split ( '\n' ) ;
663
685
parts . push ( `${ symbol } ${ firstLine } ` , ...lines . map ( ( ln ) => `${ color . gray ( S_BAR ) } ${ ln } ` ) ) ;
664
686
}
665
- process . stdout . write ( `${ parts . join ( '\n' ) } \n` ) ;
687
+ output . write ( `${ parts . join ( '\n' ) } \n` ) ;
666
688
} ,
667
- info : ( message : string ) => {
668
- log . message ( message , { symbol : color . blue ( S_INFO ) } ) ;
689
+ info : ( message : string , opts ?: LogMessageOptions ) => {
690
+ log . message ( message , { ... opts , symbol : color . blue ( S_INFO ) } ) ;
669
691
} ,
670
- success : ( message : string ) => {
671
- log . message ( message , { symbol : color . green ( S_SUCCESS ) } ) ;
692
+ success : ( message : string , opts ?: LogMessageOptions ) => {
693
+ log . message ( message , { ... opts , symbol : color . green ( S_SUCCESS ) } ) ;
672
694
} ,
673
- step : ( message : string ) => {
674
- log . message ( message , { symbol : color . green ( S_STEP_SUBMIT ) } ) ;
695
+ step : ( message : string , opts ?: LogMessageOptions ) => {
696
+ log . message ( message , { ... opts , symbol : color . green ( S_STEP_SUBMIT ) } ) ;
675
697
} ,
676
- warn : ( message : string ) => {
677
- log . message ( message , { symbol : color . yellow ( S_WARN ) } ) ;
698
+ warn : ( message : string , opts ?: LogMessageOptions ) => {
699
+ log . message ( message , { ... opts , symbol : color . yellow ( S_WARN ) } ) ;
678
700
} ,
679
701
/** alias for `log.warn()`. */
680
- warning : ( message : string ) => {
681
- log . warn ( message ) ;
702
+ warning : ( message : string , opts ?: LogMessageOptions ) => {
703
+ log . warn ( message , opts ) ;
682
704
} ,
683
- error : ( message : string ) => {
684
- log . message ( message , { symbol : color . red ( S_ERROR ) } ) ;
705
+ error : ( message : string , opts ?: LogMessageOptions ) => {
706
+ log . message ( message , { ... opts , symbol : color . red ( S_ERROR ) } ) ;
685
707
} ,
686
708
} ;
687
709
688
710
const prefix = `${ color . gray ( S_BAR ) } ` ;
711
+
712
+ // TODO (43081j): this currently doesn't support custom `output` writables
713
+ // because we rely on `columns` existing (i.e. `process.stdout.columns).
714
+ //
715
+ // If we want to support `output` being passed in, we will need to use
716
+ // a condition like `if (output insance Writable)` to check if it has columns
689
717
export const stream = {
690
718
message : async (
691
719
iterable : Iterable < string > | AsyncIterable < string > ,
@@ -730,9 +758,8 @@ export const stream = {
730
758
} ,
731
759
} ;
732
760
733
- export interface SpinnerOptions {
761
+ export interface SpinnerOptions extends CommonOptions {
734
762
indicator ?: 'dots' | 'timer' ;
735
- output ?: Writable ;
736
763
}
737
764
738
765
export interface SpinnerResult {
@@ -937,11 +964,11 @@ export type Task = {
937
964
/**
938
965
* Define a group of tasks to be executed
939
966
*/
940
- export const tasks = async ( tasks : Task [ ] ) => {
967
+ export const tasks = async ( tasks : Task [ ] , opts ?: CommonOptions ) => {
941
968
for ( const task of tasks ) {
942
969
if ( task . enabled === false ) continue ;
943
970
944
- const s = spinner ( ) ;
971
+ const s = spinner ( opts ) ;
945
972
s . start ( task . title ) ;
946
973
const result = await task . task ( s . message ) ;
947
974
s . stop ( result || task . title ) ;
0 commit comments