[READ-ONLY] Mirror of https://github.com/bombshell-dev/clack. Effortlessly build beautiful command-line apps bomb.sh/docs/clack/basics/getting-started/
cli command-line command-line-app node prompt prompts
5

Configure Feed

Select the types of activity you want to include in your feed.

feat(@clack/prompts): builder onCancel api

Bruno Rocha (Aug 11, 2023, 10:51 AM -0300) 6009a969 20c19d9d

+59 -32
+10
examples/builder.ts
··· 56 56 }) 57 57 ) 58 58 .run(); 59 + 60 + await p 61 + .builder() 62 + .add('cancel', () => p.text({ message: 'Try cancel prompt (Ctrl + C):' })) 63 + .add('afterCancel', () => p.text({ message: 'This will not appear!' })) 64 + .onCancel(({ results }) => { 65 + p.cancel('Builder canceled'); 66 + process.exit(0); 67 + }) 68 + .run(); 59 69 })();
+49 -32
packages/prompts/src/index.ts
··· 714 714 return new RegExp(pattern, 'g'); 715 715 } 716 716 717 - export type PromptGroupAwaitedReturn<T> = { 717 + type Prettify<T> = { 718 + [P in keyof T]: T[P]; 719 + } & {}; 720 + 721 + export type PromptGroupAwaitedReturn<T> = Prettify<{ 718 722 [P in keyof T]: Exclude<Awaited<T[P]>, symbol>; 723 + }>; 724 + 725 + export type PromptWithOptions<TResults, TReturn> = (opts: { 726 + results: PromptGroupAwaitedReturn<TResults>; 727 + }) => TReturn; 728 + 729 + export type PromptGroup<T> = { 730 + [P in keyof T]: PromptWithOptions<Partial<Omit<T, P>>, void | Promise<T[P] | void>>; 719 731 }; 720 732 721 733 export interface PromptGroupOptions<T> { ··· 723 735 * Control how the group can be canceled 724 736 * if one of the prompts is canceled. 725 737 */ 726 - onCancel?: (opts: { results: Prettify<Partial<PromptGroupAwaitedReturn<T>>> }) => void; 738 + onCancel?: PromptWithOptions<Partial<T>, void>; 727 739 } 728 740 729 - type Prettify<T> = { 730 - [P in keyof T]: T[P]; 731 - } & {}; 732 - 733 - export type PromptGroup<T> = { 734 - [P in keyof T]: (opts: { 735 - results: Prettify<Partial<PromptGroupAwaitedReturn<Omit<T, P>>>>; 736 - }) => void | Promise<T[P] | void>; 737 - }; 738 - 739 741 /** 740 742 * Define a group of prompts to be displayed 741 743 * and return a results of objects within the group ··· 743 745 export const group = async <T>( 744 746 prompts: PromptGroup<T>, 745 747 opts?: PromptGroupOptions<T> 746 - ): Promise<Prettify<PromptGroupAwaitedReturn<T>>> => { 748 + ): Promise<PromptGroupAwaitedReturn<T>> => { 747 749 const results = {} as any; 748 750 const promptNames = Object.keys(prompts); 749 751 ··· 768 770 return results; 769 771 }; 770 772 773 + type NextPromptBuilder< 774 + TResults extends Record<string, unknown>, 775 + TKey extends string, 776 + TResult 777 + > = PromptBuilder< 778 + { 779 + [Key in keyof TResults]: Key extends TKey ? TResult : TResults[Key]; 780 + } & { 781 + [Key in TKey]: TResult; 782 + } 783 + >; 784 + 771 785 class PromptBuilder<TResults extends Record<string, unknown> = {}> { 772 - private results = {} as TResults; 786 + private results: TResults = {} as TResults; 787 + private prompts: Record<string, PromptWithOptions<TResults, unknown>> = {}; 788 + private cancelCallback: PromptWithOptions<Partial<TResults>, void> | undefined; 773 789 774 - add<TKey extends string, TResult extends Promise<unknown>>( 790 + public add<TKey extends string, TResult>( 775 791 key: TKey extends keyof TResults ? never : TKey, 776 - prompt: (data: { results: Prettify<PromptGroupAwaitedReturn<TResults>> }) => TResult 777 - ): PromptBuilder< 778 - { 779 - [Key in keyof TResults]: Key extends TKey ? TResult : TResults[Key]; 780 - } & { 781 - [Key in TKey]: TResult; 782 - } 783 - > { 784 - // @ts-ignore 785 - this.results[key] = prompt; 786 - // @ts-ignore 792 + prompt: PromptWithOptions<TResults, TResult> 793 + ): NextPromptBuilder<TResults, TKey, TResult> { 794 + this.prompts[key] = prompt; 795 + return this as NextPromptBuilder<TResults, TKey, TResult>; 796 + } 797 + 798 + public onCancel(cb: PromptWithOptions<Partial<TResults>, void>): PromptBuilder<TResults> { 799 + this.cancelCallback = cb; 787 800 return this; 788 801 } 789 802 790 - async run(): Promise<Prettify<PromptGroupAwaitedReturn<TResults>>> { 791 - for (const [key, prompt] of Object.entries(this.results)) { 792 - // @ts-ignore 793 - this.results[key] = await prompt({ results: this.results }); 803 + public async run(): Promise<PromptGroupAwaitedReturn<TResults>> { 804 + for (const [key, prompt] of Object.entries(this.prompts)) { 805 + const result = await prompt({ results: this.results as any }); 806 + if (isCancel(result)) { 807 + this.cancelCallback?.({ results: this.results as any }); 808 + continue; 809 + } 810 + //@ts-ignore 811 + this.results[key] = result; 794 812 } 795 - // @ts-ignore 796 - return this.results; 813 + return this.results as PromptGroupAwaitedReturn<TResults>; 797 814 } 798 815 } 799 816