@@ -4,21 +4,39 @@ import figlet from "figlet";
44import inquirer from "inquirer" ;
55import shell from "shelljs" ;
66import yargs from "yargs/yargs" ;
7+ import {
8+ Options ,
9+ CommandLineOptions ,
10+ UserResponse ,
11+ APIType ,
12+ BackendType ,
13+ DatabaseType ,
14+ AuthType ,
15+ } from "./optionTypes" ;
716
817type CommandLineArgs = Array < string > ;
918
10- type Options = {
11- [ x : string ] : unknown ;
12- backend ?: string ;
13- api ?: string ;
14- database ?: string ;
15- auth ?: boolean ;
16- output ?: string ;
17- _ ?: ( string | number ) [ ] ;
18- $0 ?: string ;
19+ type Choice < T > = {
20+ name : string ;
21+ value : T ;
1922} ;
2023
21- const OPTIONS = {
24+ type OptionConfig < T > = {
25+ id : string ;
26+ description : string ;
27+ message : string ;
28+ choices : ReadonlyArray < Choice < T > > ;
29+ } ;
30+
31+ type OptionConfigs = {
32+ backend : OptionConfig < BackendType > ;
33+ api : OptionConfig < APIType > ;
34+ database : OptionConfig < DatabaseType > ;
35+ auth : OptionConfig < void > ;
36+ outputDir : OptionConfig < void > ;
37+ } ;
38+
39+ const OPTIONS : OptionConfigs = {
2240 backend : {
2341 id : "b" ,
2442 description : "Backend language" ,
@@ -50,16 +68,18 @@ const OPTIONS = {
5068 id : "au" ,
5169 description : "Include built-in auth features" ,
5270 message : "Would you like built-in auth features?" ,
71+ choices : [ ] ,
5372 } ,
54- output : {
73+ outputDir : {
5574 id : "o" ,
5675 description : "Output directory" ,
5776 message :
5877 "Which directory would you like the starter code folder to be in (default is current directory)?" ,
78+ choices : [ ] ,
5979 } ,
6080} ;
6181
62- const parseArguments = ( args : CommandLineArgs ) => {
82+ const parseArguments = ( args : CommandLineArgs ) : CommandLineOptions => {
6383 const { argv } = yargs ( args . slice ( 2 ) ) . options ( {
6484 backend : {
6585 alias : OPTIONS . backend . id ,
@@ -84,17 +104,24 @@ const parseArguments = (args: CommandLineArgs) => {
84104 type : "boolean" ,
85105 description : OPTIONS . auth . description ,
86106 } ,
87- output : {
88- alias : OPTIONS . output . id ,
107+ outputDir : {
108+ alias : OPTIONS . outputDir . id ,
89109 type : "string" ,
90- description : OPTIONS . output . description ,
110+ description : OPTIONS . outputDir . description ,
91111 } ,
92112 } ) ;
93113
94- return argv ;
114+ return {
115+ backend : argv . backend as BackendType ,
116+ api : argv . api as APIType ,
117+ database : argv . database as DatabaseType ,
118+ auth : argv . auth ,
119+ } ;
95120} ;
96121
97- const promptOptions = async ( options : Options ) => {
122+ const promptOptions = async (
123+ options : CommandLineOptions ,
124+ ) : Promise < UserResponse > => {
98125 const prompts = [ ] ;
99126 if ( ! options . backend ) {
100127 prompts . push ( {
@@ -132,33 +159,37 @@ const promptOptions = async (options: Options) => {
132159 } ) ;
133160 }
134161
135- if ( ! options . output ) {
162+ if ( ! options . outputDir ) {
136163 prompts . push ( {
137164 type : "output" ,
138- name : "output " ,
139- message : OPTIONS . output . message ,
165+ name : "outputDir " ,
166+ message : OPTIONS . outputDir . message ,
140167 default : "." ,
141168 } ) ;
142169 }
143170
144171 const answers = await inquirer . prompt ( prompts ) ;
145172
146173 return {
147- backend : options . backend || answers . backend ,
148- api : options . api || answers . api ,
149- database : options . database || answers . database ,
150- auth : options . auth || answers . auth ,
151- output : options . output || answers . output ,
174+ appOptions : {
175+ backend : options . backend || answers . backend ,
176+ api : options . api || answers . api ,
177+ database : options . database || answers . database ,
178+ auth : ( options . auth || answers . auth ? "auth" : null ) as AuthType ,
179+ } ,
180+ outputDir : options . outputDir || answers . outputDir ,
152181 } ;
153182} ;
154183
155184const confirmPrompt = async ( options : Options ) => {
156185 const backendName = OPTIONS . backend . choices . find (
157186 ( choice ) => choice . value === options . backend ,
158187 ) ?. name ;
188+
159189 const apiName = OPTIONS . api . choices . find (
160190 ( choice ) => choice . value === options . api ,
161191 ) ?. name ;
192+
162193 const databaseName = OPTIONS . database . choices . find (
163194 ( choice ) => choice . value === options . database ,
164195 ) ?. name ;
@@ -179,7 +210,7 @@ const confirmPrompt = async (options: Options) => {
179210 return confirm ;
180211} ;
181212
182- const cli = async ( args : CommandLineArgs ) = > {
213+ async function cli ( args : CommandLineArgs ) : Promise < Options | null > {
183214 console . log (
184215 boxen (
185216 chalk . bold (
@@ -193,26 +224,37 @@ const cli = async (args: CommandLineArgs) => {
193224 } ,
194225 ) ,
195226 ) ;
196- let options : Options = parseArguments ( args ) ;
197- options = await promptOptions ( options ) ;
198- const confirm = await confirmPrompt ( options ) ;
227+
228+ const commandLineOptions : CommandLineOptions = parseArguments ( args ) ;
229+
230+ const { appOptions, outputDir } = await promptOptions ( commandLineOptions ) ;
231+
232+ const confirm = await confirmPrompt ( appOptions ) ;
233+
199234 if ( ! confirm ) {
200235 console . log ( chalk . red . bold ( "Blueprint app creation has been cancelled." ) ) ;
201- return ;
236+ return null ;
202237 }
238+
203239 console . log ( chalk . green . bold ( "Confirmed. Creating blueprint app..." ) ) ;
204- const path = options . output ;
240+
241+ const path = outputDir ;
205242 const changeDirectory = shell . cd ( path ) ;
243+
206244 if ( changeDirectory . code !== 0 ) {
207245 console . log ( "No directory exists. Exiting..." ) ;
208- return ;
246+ return null ;
209247 }
248+
210249 const clone = shell . exec (
211250 "git clone https://github.com/uwblueprint/starter-code-v2.git" ,
212251 ) ;
252+
213253 if ( clone . code !== 0 ) {
214254 console . log ( "Git clone failed. Exiting..." ) ;
215255 }
216- } ;
256+
257+ return appOptions ;
258+ }
217259
218260export default cli ;
0 commit comments