@@ -10,6 +10,7 @@ import { createInputBox } from '../../../shared/ui/inputPrompter'
1010import { createCommonButtons } from '../../../shared/ui/buttons'
1111import { createQuickPick } from '../../../shared/ui/pickerPrompter'
1212import { createFolderPrompt } from '../../../shared/ui/common/location'
13+ import { createExitPrompter } from '../../../shared/ui/common/exitPrompter'
1314import { MetadataManager } from './metadataManager'
1415import { ToolkitError } from '../../../shared/errors'
1516
@@ -19,158 +20,138 @@ export interface CreateServerlessLandWizardForm {
1920 pattern : string
2021 runtime : string
2122 iac : string
22- assetName : string
2323}
2424
25- /**
26- * Wizard for creating Serverless Land applications
27- * Guides users through the project creation process
28- */
29- export class CreateServerlessLandWizard extends Wizard < CreateServerlessLandWizardForm > {
30- private metadataManager : MetadataManager
31-
32- public constructor ( context : { defaultRegion ?: string ; credentials ?: AWS . Credentials } ) {
33- super ( )
34- this . metadataManager = MetadataManager . getInstance ( )
35-
36- // Bind the steps
37- this . form . pattern . bindPrompter ( ( ) => this . promptPattern ( ) )
38- this . form . runtime . bindPrompter ( ( state ) => this . promptRuntime ( state . pattern ) )
39- this . form . iac . bindPrompter ( ( state ) => this . promptIac ( state . pattern ) )
40- this . form . location . bindPrompter ( ( ) => this . promptLocation ( ) )
41- this . form . name . bindPrompter ( ( ) => this . promptName ( ) )
42- }
25+ async function loadMetadata ( ) : Promise < MetadataManager > {
26+ const metadataManager = MetadataManager . getInstance ( )
27+ const projectRoot = path . resolve ( __dirname , '../../../../../' )
28+ const metadataPath = path . join ( projectRoot , 'src' , 'awsService' , 'appBuilder' , 'serverlessLand' , 'metadata.json' )
29+ await metadataManager . loadMetadata ( metadataPath )
30+ return metadataManager
31+ }
4332
44- private async loadMetadata ( ) : Promise < void > {
45- const projectRoot = path . resolve ( __dirname , '../../../../../' )
46- const metadataPath = path . join (
47- projectRoot ,
48- 'src' ,
49- 'awsService' ,
50- 'appBuilder' ,
51- 'serverlessLand' ,
52- 'metadata.json'
53- )
54- await this . metadataManager . loadMetadata ( metadataPath )
33+ function promptPattern ( metadataManager : MetadataManager ) {
34+ const patterns = metadataManager . getPatterns ( )
35+ if ( patterns . length === 0 ) {
36+ throw new Error ( 'No patterns found in metadata' )
5537 }
5638
57- private async promptPattern ( ) {
58- const patterns = this . metadataManager . getPatterns ( )
59- if ( patterns . length === 0 ) {
60- throw new Error ( 'No patterns found in metadata' )
39+ return createQuickPick < string > (
40+ patterns . map ( ( p ) => ( {
41+ label : p . label ,
42+ detail : p . description ,
43+ data : p . label ,
44+ buttons : [
45+ {
46+ iconPath : new vscode . ThemeIcon ( 'github' ) ,
47+ tooltip : 'Open in GitHub' ,
48+ } ,
49+ {
50+ iconPath : new vscode . ThemeIcon ( 'open-preview' ) ,
51+ tooltip : 'Open in Serverless Land' ,
52+ } ,
53+ ] ,
54+ } ) ) ,
55+ {
56+ title : 'Select a Pattern for your application' ,
57+ placeholder : 'Choose a pattern for your project' ,
58+ buttons : createCommonButtons ( ) ,
59+ matchOnDescription : true ,
60+ matchOnDetail : true ,
6161 }
62+ )
63+ }
6264
63- return createQuickPick < string > (
64- patterns . map ( ( p ) => ( {
65- label : p . label ,
66- detail : p . description ,
67- data : p . label ,
68- buttons : [
69- {
70- iconPath : new vscode . ThemeIcon ( 'github' ) ,
71- tooltip : 'Open in GitHub' ,
72- } ,
73- {
74- iconPath : new vscode . ThemeIcon ( 'open-preview' ) ,
75- tooltip : 'Open in Serverless Land' ,
76- } ,
77- ] ,
78- } ) ) ,
79- {
80- title : 'Select a Pattern for your application' ,
81- placeholder : 'Choose a pattern for your project' ,
82- buttons : createCommonButtons ( ) ,
83- matchOnDescription : true ,
84- matchOnDetail : true ,
85- }
86- )
65+ function promptRuntime ( metadataManager : MetadataManager , pattern : string | undefined ) {
66+ if ( ! pattern || typeof pattern !== 'string' ) {
67+ throw new Error ( 'Pattern not selected' )
8768 }
8869
89- private async promptRuntime ( pattern : string | undefined ) {
90- if ( ! pattern || typeof pattern !== 'string' ) {
91- throw new Error ( 'Pattern not selected' )
92- }
93-
94- const runtimes = this . metadataManager . getRuntimes ( pattern )
95- if ( runtimes . length === 0 ) {
96- throw new Error ( 'No runtimes found for the selected pattern' )
97- }
98-
99- return createQuickPick < string > (
100- runtimes . map ( ( r ) => ( {
101- label : r . label ,
102- data : r . label ,
103- } ) ) ,
104- {
105- title : 'Select Runtime' ,
106- placeholder : 'Choose a runtime for your project' ,
107- buttons : [ vscode . QuickInputButtons . Back ] ,
108- }
109- )
70+ const runtimes = metadataManager . getRuntimes ( pattern )
71+ if ( runtimes . length === 0 ) {
72+ throw new Error ( 'No runtimes found for the selected pattern' )
11073 }
11174
112- private async promptIac ( pattern : string | undefined ) {
113- if ( ! pattern || typeof pattern !== 'string' ) {
114- throw new Error ( 'Pattern not selected' )
115- }
116-
117- const iacOptions = this . metadataManager . getIacOptions ( pattern )
118- if ( iacOptions . length === 0 ) {
119- throw new Error ( 'No IAC options found for the selected pattern' )
75+ return createQuickPick < string > (
76+ runtimes . map ( ( r ) => ( {
77+ label : r . label ,
78+ data : r . label ,
79+ } ) ) ,
80+ {
81+ title : 'Select Runtime' ,
82+ placeholder : 'Choose a runtime for your project' ,
83+ buttons : [ vscode . QuickInputButtons . Back ] ,
12084 }
85+ )
86+ }
12187
122- return createQuickPick < string > (
123- iacOptions . map ( ( i ) => ( {
124- label : i . label ,
125- data : i . label ,
126- } ) ) ,
127- {
128- title : 'Select IaC' ,
129- placeholder : 'Choose an IaC option for your project' ,
130- buttons : [ vscode . QuickInputButtons . Back ] ,
131- }
132- )
88+ function promptIac ( metadataManager : MetadataManager , pattern : string | undefined ) {
89+ if ( ! pattern || typeof pattern !== 'string' ) {
90+ throw new Error ( 'Pattern not selected' )
13391 }
13492
135- private async promptLocation ( ) {
136- return createFolderPrompt ( vscode . workspace . workspaceFolders ?? [ ] , {
137- title : 'Select Project Location' ,
138- buttons : [ vscode . QuickInputButtons . Back ] ,
139- browseFolderDetail : 'Select a folder for your project' ,
140- } )
93+ const iacOptions = metadataManager . getIacOptions ( pattern )
94+ if ( iacOptions . length === 0 ) {
95+ throw new Error ( 'No IAC options found for the selected pattern' )
14196 }
14297
143- private async promptName ( ) {
144- return createInputBox ( {
145- title : 'Enter Project Name' ,
146- placeholder : 'Enter a name for your new application' ,
98+ return createQuickPick < string > (
99+ iacOptions . map ( ( i ) => ( {
100+ label : i . label ,
101+ data : i . label ,
102+ } ) ) ,
103+ {
104+ title : 'Select IaC' ,
105+ placeholder : 'Choose an IaC option for your project' ,
147106 buttons : [ vscode . QuickInputButtons . Back ] ,
148- validateInput : ( value : string ) : string | undefined => {
149- if ( ! value ) {
150- return 'Application name cannot be empty'
151- }
152- if ( value . includes ( path . sep ) ) {
153- return `The path separator (${ path . sep } ) is not allowed in application names`
154- }
155- return undefined
156- } ,
157- } )
158- }
107+ }
108+ )
109+ }
159110
160- public override async run ( ) : Promise < CreateServerlessLandWizardForm | undefined > {
161- try {
162- await this . loadMetadata ( )
163- const form = await super . run ( )
164- if ( ! form ) {
165- return undefined
166- }
111+ function promptLocation ( ) {
112+ return createFolderPrompt ( vscode . workspace . workspaceFolders ?? [ ] , {
113+ title : 'Select Project Location' ,
114+ buttons : [ vscode . QuickInputButtons . Back ] ,
115+ browseFolderDetail : 'Select a folder for your project' ,
116+ } )
117+ }
167118
168- return {
169- ...form ,
170- assetName : this . metadataManager . getAssetName ( form . pattern , form . runtime , form . iac ) ,
119+ function promptName ( ) {
120+ return createInputBox ( {
121+ title : 'Enter Project Name' ,
122+ placeholder : 'Enter a name for your new application' ,
123+ buttons : [ vscode . QuickInputButtons . Back ] ,
124+ validateInput : ( value : string ) : string | undefined => {
125+ if ( ! value ) {
126+ return 'Application name cannot be empty'
171127 }
172- } catch ( err ) {
173- throw new ToolkitError ( `Failed to run wizard: ${ err instanceof Error ? err . message : String ( err ) } ` )
174- }
128+ if ( value . includes ( path . sep ) ) {
129+ return `The path separator (${ path . sep } ) is not allowed in application names`
130+ }
131+ return undefined
132+ } ,
133+ } )
134+ }
135+
136+ /**
137+ * Wizard for creating Serverless Land applications
138+ * Guides users through the project creation process
139+ */
140+ export class CreateServerlessLandWizard extends Wizard < CreateServerlessLandWizardForm > {
141+ private metadataManager : MetadataManager
142+
143+ public constructor ( context : { defaultRegion ?: string ; credentials ?: AWS . Credentials } ) {
144+ super ( {
145+ exitPrompterProvider : createExitPrompter ,
146+ } )
147+ loadMetadata ( ) . catch ( ( err : any ) => {
148+ throw new ToolkitError ( `Failed to load metadata: ${ err } ` )
149+ } )
150+ this . metadataManager = MetadataManager . getInstance ( )
151+ this . form . pattern . bindPrompter ( ( ) => promptPattern ( this . metadataManager ) )
152+ this . form . runtime . bindPrompter ( ( state ) => promptRuntime ( this . metadataManager , state . pattern ) )
153+ this . form . iac . bindPrompter ( ( state ) => promptIac ( this . metadataManager , state . pattern ) )
154+ this . form . location . bindPrompter ( ( ) => promptLocation ( ) )
155+ this . form . name . bindPrompter ( ( ) => promptName ( ) )
175156 }
176157}
0 commit comments