@@ -21,10 +21,17 @@ export type ImportResult = { result: ResourceConfig[], errors: string[] }
2121export interface ImportArgs {
2222 typeIds ?: string [ ] ;
2323 path : string ;
24+ updateExisting ?: boolean ;
2425 secureMode ?: boolean ;
2526 verbosityLevel ?: number ;
2627}
2728
29+ enum SaveType {
30+ EXISTING ,
31+ NEW ,
32+ NONE
33+ }
34+
2835export class ImportOrchestrator {
2936 static async run (
3037 args : ImportArgs ,
@@ -39,11 +46,11 @@ export class ImportOrchestrator {
3946 ) ;
4047
4148 await ( ! typeIds || typeIds . length === 0
42- ? ImportOrchestrator . autoImportAll ( reporter , initializationResult )
43- : ImportOrchestrator . runNewImport ( typeIds , reporter , initializationResult ) ) ;
49+ ? ImportOrchestrator . autoImportAll ( reporter , initializationResult , args )
50+ : ImportOrchestrator . runNewImport ( typeIds , reporter , initializationResult , args ) ) ;
4451 }
4552
46- static async autoImportAll ( reporter : Reporter , initializeResult : InitializationResult ) {
53+ static async autoImportAll ( reporter : Reporter , initializeResult : InitializationResult , args : ImportArgs ) {
4754 const { project, pluginManager, typeIdsToDependenciesMap } = initializeResult ;
4855
4956 ctx . subprocessStarted ( SubProcessName . IMPORT_RESOURCE )
@@ -74,18 +81,18 @@ export class ImportOrchestrator {
7481 [ ...project . resourceConfigs , ...importedResources ] . map ( ( r ) => r . type ) ,
7582 ) ;
7683
77- await ImportOrchestrator . updateExistingFiles (
84+ await ImportOrchestrator . saveResults (
7885 reporter ,
79- project ,
8086 { result : importedResources , errors : [ ] } ,
87+ project ,
8188 resourceInfoList ,
82- project . codifyFiles [ 0 ] ,
8389 pluginManager ,
84- ) ;
90+ args
91+ )
8592 }
8693
8794 /** Import new resources. Type ids supplied. This will ask for any required parameters */
88- static async runNewImport ( typeIds : string [ ] , reporter : Reporter , initializeResult : InitializationResult ) : Promise < void > {
95+ static async runNewImport ( typeIds : string [ ] , reporter : Reporter , initializeResult : InitializationResult , args : ImportArgs ) : Promise < void > {
8996 const { project, pluginManager, typeIdsToDependenciesMap } = initializeResult ;
9097
9198 const matchedTypes = this . matchTypeIds ( typeIds , [ ...typeIdsToDependenciesMap . keys ( ) ] )
@@ -104,7 +111,7 @@ export class ImportOrchestrator {
104111 resourceInfoList . push ( ...( await pluginManager . getMultipleResourceInfo (
105112 project . resourceConfigs . map ( ( r ) => r . type )
106113 ) ) ) ;
107- await ImportOrchestrator . saveResults ( reporter , importResult , project , resourceInfoList , pluginManager )
114+ await ImportOrchestrator . saveResults ( reporter , importResult , project , resourceInfoList , pluginManager , args )
108115 }
109116
110117 static async import (
@@ -146,98 +153,20 @@ export class ImportOrchestrator {
146153 }
147154 }
148155
149- private static matchTypeIds ( typeIds : string [ ] , validTypeIds : string [ ] ) : string [ ] {
150- const result : string [ ] = [ ] ;
151- const unsupportedTypeIds : string [ ] = [ ] ;
152-
153- for ( const typeId of typeIds ) {
154- if ( ! typeId . includes ( '*' ) && ! typeId . includes ( '?' ) ) {
155- const matched = validTypeIds . includes ( typeId ) ;
156- if ( ! matched ) {
157- unsupportedTypeIds . push ( typeId ) ;
158- continue ;
159- }
160-
161- result . push ( typeId )
162- continue ;
163- }
164-
165- const matched = validTypeIds . filter ( ( valid ) => wildCardMatch ( valid , typeId ) )
166- if ( matched . length === 0 ) {
167- unsupportedTypeIds . push ( typeId ) ;
168- continue ;
169- }
170-
171- result . push ( ...matched ) ;
172- }
173-
174- if ( unsupportedTypeIds . length > 0 ) {
175- throw new Error ( `The following resources cannot be imported. No plugins found that support the following types:
176- ${ JSON . stringify ( unsupportedTypeIds ) } `) ;
177- }
178-
179- return result ;
180- }
181-
182- private static async validate ( typeIds : string [ ] , project : Project , pluginManager : PluginManager , dependencyMap : DependencyMap ) : Promise < void > {
183- project . validateTypeIds ( dependencyMap ) ;
184-
185- const unsupportedTypeIds = typeIds . filter ( ( type ) => ! dependencyMap . has ( type ) ) ;
186- if ( unsupportedTypeIds . length > 0 ) {
187- throw new Error ( `The following resources cannot be imported. No plugins found that support the following types:
188- ${ JSON . stringify ( unsupportedTypeIds ) } `) ;
189- }
190- }
191-
192- private static async getImportParameters ( reporter : Reporter , project : Project , resourceInfoList : ResourceInfo [ ] ) : Promise < Array < ResourceConfig > > {
193- // Figure out which resources we need to prompt the user for additional info (based on the resource info)
194- const [ noPrompt , askPrompt ] = resourceInfoList . reduce ( ( result , info ) => {
195- info . getRequiredParameters ( ) . length === 0 ? result [ 0 ] . push ( info ) : result [ 1 ] . push ( info ) ;
196- return result ;
197- } , [ < ResourceInfo [ ] > [ ] , < ResourceInfo [ ] > [ ] ] )
198-
199- askPrompt . forEach ( ( info ) => {
200- const matchedResources = project . findAll ( info . type ) ;
201- if ( matchedResources . length > 0 ) {
202- info . attachDefaultValues ( matchedResources [ 0 ] ) ;
203- }
204- } )
205-
206- if ( askPrompt . length > 0 ) {
207- await reporter . displayImportWarning ( askPrompt . map ( ( r ) => r . type ) , noPrompt . map ( ( r ) => r . type ) ) ;
208- }
209-
210- const userSupplied = await reporter . promptUserForValues ( askPrompt , PromptType . IMPORT ) ;
211-
212- return [
213- ...noPrompt . map ( ( info ) => new ResourceConfig ( { type : info . type } ) ) ,
214- ...userSupplied
215- ]
216- }
217-
218- private static async saveResults (
156+ static async saveResults (
219157 reporter : Reporter ,
220158 importResult : ImportResult ,
221159 project : Project ,
222160 resourceInfoList : ResourceInfo [ ] ,
223161 pluginManager : PluginManager ,
162+ args : ImportArgs ,
224163 ) : Promise < void > {
225- const projectExists = ! project . isEmpty ( ) ;
226164 const multipleCodifyFiles = project . codifyFiles . length > 1 ;
227165
228- const promptResult = await reporter . promptOptions (
229- '\nDo you want to save the results?' ,
230- [
231- projectExists ?
232- multipleCodifyFiles ? 'Update existing files' : `Update existing file (${ project . codifyFiles } )`
233- : undefined ,
234- 'In a new file' ,
235- 'No'
236- ] . filter ( Boolean ) as string [ ]
237- )
166+ const saveType = await ImportOrchestrator . getSaveType ( reporter , project , args ) ;
238167
239168 // Update an existing file
240- if ( projectExists && promptResult === 0 ) {
169+ if ( saveType === SaveType . EXISTING ) {
241170 const file = multipleCodifyFiles
242171 ? project . codifyFiles [ await reporter . promptOptions ( '\nIf new resources are added, where to write them?' , project . codifyFiles ) ]
243172 : project . codifyFiles [ 0 ] ;
@@ -246,7 +175,7 @@ ${JSON.stringify(unsupportedTypeIds)}`);
246175 }
247176
248177 // Write to a new file
249- if ( ( ! projectExists && promptResult === 0 ) || ( projectExists && promptResult === 1 ) ) {
178+ if ( saveType === SaveType . NEW ) {
250179 const newFileName = await ImportOrchestrator . generateNewImportFileName ( ) ;
251180 await ImportOrchestrator . saveNewFile ( reporter , newFileName , importResult ) ;
252181 return ;
@@ -259,7 +188,7 @@ ${JSON.stringify(unsupportedTypeIds)}`);
259188 await sleep ( 100 ) ;
260189 }
261190
262- private static async updateExistingFiles (
191+ static async updateExistingFiles (
263192 reporter : Reporter ,
264193 existingProject : Project ,
265194 importResult : ImportResult ,
@@ -330,6 +259,114 @@ ${JSON.stringify(unsupportedTypeIds)}`);
330259 await sleep ( 100 ) ;
331260 }
332261
262+ private static matchTypeIds ( typeIds : string [ ] , validTypeIds : string [ ] ) : string [ ] {
263+ const result : string [ ] = [ ] ;
264+ const unsupportedTypeIds : string [ ] = [ ] ;
265+
266+ for ( const typeId of typeIds ) {
267+ if ( ! typeId . includes ( '*' ) && ! typeId . includes ( '?' ) ) {
268+ const matched = validTypeIds . includes ( typeId ) ;
269+ if ( ! matched ) {
270+ unsupportedTypeIds . push ( typeId ) ;
271+ continue ;
272+ }
273+
274+ result . push ( typeId )
275+ continue ;
276+ }
277+
278+ const matched = validTypeIds . filter ( ( valid ) => wildCardMatch ( valid , typeId ) )
279+ if ( matched . length === 0 ) {
280+ unsupportedTypeIds . push ( typeId ) ;
281+ continue ;
282+ }
283+
284+ result . push ( ...matched ) ;
285+ }
286+
287+ if ( unsupportedTypeIds . length > 0 ) {
288+ throw new Error ( `The following resources cannot be imported. No plugins found that support the following types:
289+ ${ JSON . stringify ( unsupportedTypeIds ) } `) ;
290+ }
291+
292+ return result ;
293+ }
294+
295+ private static async validate ( typeIds : string [ ] , project : Project , pluginManager : PluginManager , dependencyMap : DependencyMap ) : Promise < void > {
296+ project . validateTypeIds ( dependencyMap ) ;
297+
298+ const unsupportedTypeIds = typeIds . filter ( ( type ) => ! dependencyMap . has ( type ) ) ;
299+ if ( unsupportedTypeIds . length > 0 ) {
300+ throw new Error ( `The following resources cannot be imported. No plugins found that support the following types:
301+ ${ JSON . stringify ( unsupportedTypeIds ) } `) ;
302+ }
303+ }
304+
305+ private static async getImportParameters ( reporter : Reporter , project : Project , resourceInfoList : ResourceInfo [ ] ) : Promise < Array < ResourceConfig > > {
306+ // Figure out which resources we need to prompt the user for additional info (based on the resource info)
307+ const [ noPrompt , askPrompt ] = resourceInfoList . reduce ( ( result , info ) => {
308+ info . getRequiredParameters ( ) . length === 0 ? result [ 0 ] . push ( info ) : result [ 1 ] . push ( info ) ;
309+ return result ;
310+ } , [ < ResourceInfo [ ] > [ ] , < ResourceInfo [ ] > [ ] ] )
311+
312+ askPrompt . forEach ( ( info ) => {
313+ const matchedResources = project . findAll ( info . type ) ;
314+ if ( matchedResources . length > 0 ) {
315+ info . attachDefaultValues ( matchedResources [ 0 ] ) ;
316+ }
317+ } )
318+
319+ if ( askPrompt . length > 0 ) {
320+ await reporter . displayImportWarning ( askPrompt . map ( ( r ) => r . type ) , noPrompt . map ( ( r ) => r . type ) ) ;
321+ }
322+
323+ const userSupplied = await reporter . promptUserForValues ( askPrompt , PromptType . IMPORT ) ;
324+
325+ return [
326+ ...noPrompt . map ( ( info ) => new ResourceConfig ( { type : info . type } ) ) ,
327+ ...userSupplied
328+ ]
329+ }
330+
331+ private static async getSaveType (
332+ reporter : Reporter ,
333+ project : Project ,
334+ args : ImportArgs ,
335+ ) : Promise < SaveType > {
336+ const projectExists = project . exists ( ) ;
337+ const multipleCodifyFiles = project . codifyFiles . length > 1 ;
338+
339+ if ( args . updateExisting && projectExists ) {
340+ return SaveType . EXISTING ;
341+ }
342+
343+ const promptResult = await reporter . promptOptions (
344+ '\nDo you want to save the results?' ,
345+ [
346+ projectExists ?
347+ multipleCodifyFiles ? 'Update existing files' : `Update existing file (${ project . codifyFiles } )`
348+ : undefined ,
349+ 'In a new file' ,
350+ 'No'
351+ ] . filter ( Boolean ) as string [ ]
352+ ) ;
353+
354+ if ( projectExists ) {
355+ switch ( promptResult ) {
356+ case 0 : { return SaveType . EXISTING ; }
357+ case 1 : { return SaveType . NEW ; }
358+ case 2 : { return SaveType . NONE ; }
359+ }
360+ } else {
361+ switch ( promptResult ) {
362+ case 0 : { return SaveType . NEW ; }
363+ case 1 : { return SaveType . NONE ; }
364+ }
365+ }
366+
367+ throw new Error ( 'Unexpected response from prompt' ) ;
368+ }
369+
333370 private static async saveNewFile ( reporter : Reporter , filePath : string , importResult : ImportResult ) : Promise < void > {
334371 const newFile = JSON . stringify ( importResult . result . map ( ( r ) => r . raw ) , null , 2 ) ;
335372 const diff = prettyFormatFileDiff ( '' , newFile ) ;
@@ -363,7 +400,7 @@ ${JSON.stringify(unsupportedTypeIds)}`);
363400 let fileName = path . join ( folderPath , 'import.codify.jsonc' )
364401 let counter = 1 ;
365402
366- while ( true ) {
403+ while ( true ) {
367404 if ( ! ( await FileUtils . fileExists ( fileName ) ) ) {
368405 return fileName ;
369406 }
0 commit comments