@@ -12,7 +12,6 @@ import {
1212 cancel ,
1313} from '@clack/prompts' ;
1414
15- import commands from './index.mjs' ;
1615import logger from '../../src/logger/index.mjs' ;
1716
1817/**
@@ -53,127 +52,143 @@ function escapeShellArg(arg) {
5352}
5453
5554/**
56- * Main interactive function for the API Docs Tooling command line interface.
57- * Guides the user through a series of prompts, validates inputs, and generates a command to run.
58- * @returns {Promise<void> } Resolves once the command is generated and executed.
55+ * @type {import('../utils.mjs').Command }
5956 */
60- export default async function interactive ( ) {
61- // Step 1: Introduction to the tool
62- intro ( 'Welcome to API Docs Tooling' ) ;
63-
64- // Step 2: Choose the action based on available command definitions
65- const actionOptions = commands . map ( ( { description } , i ) => ( {
66- label : description ,
67- value : i ,
68- } ) ) ;
69-
70- const selectedAction = await select ( {
71- message : 'What would you like to do?' ,
72- options : actionOptions ,
73- } ) ;
74-
75- if ( isCancel ( selectedAction ) ) {
76- cancel ( 'Cancelled.' ) ;
77- process . exit ( 0 ) ;
78- }
79-
80- // Retrieve the options for the selected action
81- const { options, name } = commands [ selectedAction ] ;
82- const answers = { } ; // Store answers from user prompts
83-
84- // Step 3: Collect input for each option
85- for ( const [ key , { prompt } ] of Object . entries ( options ) ) {
86- let response ;
87- const promptMessage = getMessage ( prompt ) ;
88-
89- switch ( prompt . type ) {
90- case 'text' :
91- response = await text ( {
92- message : promptMessage ,
93- initialValue : prompt . initialValue || '' ,
94- validate : prompt . required ? requireValue : undefined ,
95- } ) ;
96- if ( response ) {
97- // Store response; split into an array if variadic
98- answers [ key ] = prompt . variadic
99- ? response . split ( ',' ) . map ( s => s . trim ( ) )
100- : response ;
101- }
102- break ;
103-
104- case 'confirm' :
105- response = await confirm ( {
106- message : promptMessage ,
107- initialValue : prompt . initialValue ,
108- } ) ;
109- answers [ key ] = response ;
110- break ;
111-
112- case 'multiselect' :
113- response = await multiselect ( {
114- message : promptMessage ,
115- options : prompt . options ,
116- required : ! ! prompt . required ,
117- } ) ;
118- answers [ key ] = response ;
119- break ;
120-
121- case 'select' :
122- response = await select ( {
123- message : promptMessage ,
124- options : prompt . options ,
125- } ) ;
126- answers [ key ] = response ;
127- break ;
128- }
57+ export default {
58+ name : 'interactive' ,
59+ description : 'Launch guided CLI wizard' ,
60+ options : { } ,
61+ /**
62+ * Main interactive function for the API Docs Tooling command line interface.
63+ * Guides the user through a series of prompts, validates inputs, and generates a command to run.
64+ * @returns {Promise<void> } Resolves once the command is generated and executed.
65+ */
66+ async action ( ) {
67+ // Import commands dynamically to avoid circular dependency
68+ const { default : commands } = await import ( './index.mjs' ) ;
69+
70+ // Filter out the interactive command itself
71+ const availableCommands = commands . filter (
72+ cmd => cmd . name !== 'interactive'
73+ ) ;
74+
75+ // Step 1: Introduction to the tool
76+ intro ( 'Welcome to API Docs Tooling' ) ;
77+
78+ // Step 2: Choose the action based on available command definitions
79+ const actionOptions = availableCommands . map ( ( cmd , i ) => ( {
80+ label : cmd . description ,
81+ value : i ,
82+ } ) ) ;
83+
84+ const selectedAction = await select ( {
85+ message : 'What would you like to do?' ,
86+ options : actionOptions ,
87+ } ) ;
12988
130- // Handle cancellation
131- if ( isCancel ( response ) ) {
89+ if ( isCancel ( selectedAction ) ) {
13290 cancel ( 'Cancelled.' ) ;
13391 process . exit ( 0 ) ;
13492 }
135- }
13693
137- // Step 4: Build the final command by escaping values
138- const cmdParts = [ 'npx' , 'doc-kit' , name ] ;
139- const executionArgs = [ name ] ;
94+ // Retrieve the options for the selected action
95+ const { options, name } = availableCommands [ selectedAction ] ;
96+ const answers = { } ; // Store answers from user prompts
97+
98+ // Step 3: Collect input for each option
99+ for ( const [ key , { prompt } ] of Object . entries ( options ) ) {
100+ let response ;
101+ const promptMessage = getMessage ( prompt ) ;
102+
103+ switch ( prompt . type ) {
104+ case 'text' :
105+ response = await text ( {
106+ message : promptMessage ,
107+ initialValue : prompt . initialValue || '' ,
108+ validate : prompt . required ? requireValue : undefined ,
109+ } ) ;
110+ if ( response ) {
111+ // Store response; split into an array if variadic
112+ answers [ key ] = prompt . variadic
113+ ? response . split ( ',' ) . map ( s => s . trim ( ) )
114+ : response ;
115+ }
116+ break ;
117+
118+ case 'confirm' :
119+ response = await confirm ( {
120+ message : promptMessage ,
121+ initialValue : prompt . initialValue ,
122+ } ) ;
123+ answers [ key ] = response ;
124+ break ;
125+
126+ case 'multiselect' :
127+ response = await multiselect ( {
128+ message : promptMessage ,
129+ options : prompt . options ,
130+ required : ! ! prompt . required ,
131+ } ) ;
132+ answers [ key ] = response ;
133+ break ;
134+
135+ case 'select' :
136+ response = await select ( {
137+ message : promptMessage ,
138+ options : prompt . options ,
139+ } ) ;
140+ answers [ key ] = response ;
141+ break ;
142+ }
140143
141- for ( const [ key , { flags } ] of Object . entries ( options ) ) {
142- const value = answers [ key ] ;
143- // Skip empty values
144- if ( value == null || ( Array . isArray ( value ) && value . length === 0 ) ) {
145- continue ;
144+ // Handle cancellation
145+ if ( isCancel ( response ) ) {
146+ cancel ( 'Cancelled.' ) ;
147+ process . exit ( 0 ) ;
148+ }
146149 }
147150
148- const flag = flags [ 0 ] . split ( / [ \s , ] + / ) [ 0 ] ; // Use the first flag
151+ // Step 4: Build the final command by escaping values
152+ const cmdParts = [ 'npx' , 'doc-kit' , name ] ;
153+ const executionArgs = [ name ] ;
149154
150- // Handle different value types (boolean, array, string)
151- if ( typeof value === 'boolean' ) {
152- if ( value ) {
153- cmdParts . push ( flag ) ;
154- executionArgs . push ( flag ) ;
155+ for ( const [ key , { flags } ] of Object . entries ( options ) ) {
156+ const value = answers [ key ] ;
157+ // Skip empty values
158+ if ( value == null || ( Array . isArray ( value ) && value . length === 0 ) ) {
159+ continue ;
155160 }
156- } else if ( Array . isArray ( value ) ) {
157- for ( const item of value ) {
158- cmdParts . push ( flag , escapeShellArg ( item ) ) ;
159- executionArgs . push ( flag , item ) ;
161+
162+ const flag = flags [ 0 ] . split ( / [ \s , ] + / ) [ 0 ] ; // Use the first flag
163+
164+ // Handle different value types (boolean, array, string)
165+ if ( typeof value === 'boolean' ) {
166+ if ( value ) {
167+ cmdParts . push ( flag ) ;
168+ executionArgs . push ( flag ) ;
169+ }
170+ } else if ( Array . isArray ( value ) ) {
171+ for ( const item of value ) {
172+ cmdParts . push ( flag , escapeShellArg ( item ) ) ;
173+ executionArgs . push ( flag , item ) ;
174+ }
175+ } else {
176+ cmdParts . push ( flag , escapeShellArg ( value ) ) ;
177+ executionArgs . push ( flag , value ) ;
160178 }
161- } else {
162- cmdParts . push ( flag , escapeShellArg ( value ) ) ;
163- executionArgs . push ( flag , value ) ;
164179 }
165- }
166180
167- const finalCommand = cmdParts . join ( ' ' ) ;
181+ const finalCommand = cmdParts . join ( ' ' ) ;
168182
169- logger . info ( `\nGenerated command:\n${ finalCommand } \n` ) ;
183+ logger . info ( `\nGenerated command:\n${ finalCommand } \n` ) ;
170184
171- // Step 5: Confirm and execute the generated command
172- if ( await confirm ( { message : 'Run now?' , initialValue : true } ) ) {
173- spawnSync ( process . execPath , [ process . argv [ 1 ] , ...executionArgs ] , {
174- stdio : 'inherit' ,
175- } ) ;
176- }
185+ // Step 5: Confirm and execute the generated command
186+ if ( await confirm ( { message : 'Run now?' , initialValue : true } ) ) {
187+ spawnSync ( process . execPath , [ process . argv [ 1 ] , ...executionArgs ] , {
188+ stdio : 'inherit' ,
189+ } ) ;
190+ }
177191
178- outro ( 'Done!' ) ;
179- }
192+ outro ( 'Done!' ) ;
193+ } ,
194+ } ;
0 commit comments