@@ -119,7 +119,6 @@ export class ResourceController<T extends StringIndexedObject> {
119119 // Parse data from the user supplied config
120120 const parsedConfig = new ConfigParser ( desired , state , this . parsedSettings . statefulParameters )
121121 const {
122- allParameters,
123122 allNonStatefulParameters,
124123 allStatefulParameters,
125124 } = parsedConfig ;
@@ -130,7 +129,6 @@ export class ResourceController<T extends StringIndexedObject> {
130129 // Short circuit here. If the resource is non-existent, there's no point checking stateful parameters
131130 if ( currentArray === null
132131 || currentArray === undefined
133- || this . settings . allowMultiple // Stateful parameters are not supported currently if allowMultiple is true
134132 || currentArray . length === 0
135133 || currentArray . filter ( Boolean ) . length === 0
136134 ) {
@@ -144,13 +142,13 @@ export class ResourceController<T extends StringIndexedObject> {
144142 } ) ;
145143 }
146144
147- // Refresh stateful parameters. These parameters have state external to the resource. allowMultiple
148- // does not work together with stateful parameters
149- const statefulCurrentParameters = await this . refreshStatefulParameters ( allStatefulParameters , allParameters ) ;
145+ // Refresh stateful parameters. These parameters have state external to the resource. Each variation of the
146+ // current parameters (each array element) is passed into the stateful parameter refresh.
147+ const statefulCurrentParameters = await this . refreshStatefulParameters ( allStatefulParameters , currentArray ) ;
150148
151149 return Plan . calculate ( {
152150 desired,
153- currentArray : [ { ...currentArray [ 0 ] , ...statefulCurrentParameters } ] as Partial < T > [ ] ,
151+ currentArray : currentArray . map ( ( c , idx ) => ( { ...c , ...statefulCurrentParameters [ idx ] } ) ) ,
154152 state,
155153 core,
156154 settings : this . parsedSettings ,
@@ -249,26 +247,21 @@ export class ResourceController<T extends StringIndexedObject> {
249247
250248 if ( currentParametersArray === null
251249 || currentParametersArray === undefined
252- || this . settings . allowMultiple // Stateful parameters are not supported currently if allowMultiple is true
253250 || currentParametersArray . filter ( Boolean ) . length === 0
254251 ) {
255- for ( const result of currentParametersArray ?? [ ] ) {
256- await this . applyTransformParameters ( result , true ) ;
257- this . removeDefaultValues ( result , parameters )
258- }
259-
260- return currentParametersArray
261- ?. map ( ( r ) => ( { core, parameters : r } ) )
262- ?? null ;
252+ return [ ] ;
263253 }
264254
265- const statefulCurrentParameters = await this . refreshStatefulParameters ( allStatefulParameters , parametersToRefresh ) ;
266- const resultParameters = { ...currentParametersArray [ 0 ] , ...statefulCurrentParameters } ;
255+ const statefulCurrentParameters = await this . refreshStatefulParameters ( allStatefulParameters , currentParametersArray ) ;
256+ const resultParametersArray = currentParametersArray
257+ ?. map ( ( r , idx ) => ( { ...r , ...statefulCurrentParameters [ idx ] } ) )
267258
268- await this . applyTransformParameters ( resultParameters , true ) ;
269- this . removeDefaultValues ( resultParameters , parameters )
259+ for ( const result of resultParametersArray ) {
260+ await this . applyTransformParameters ( result , true ) ;
261+ this . removeDefaultValues ( result , parameters ) ;
262+ }
270263
271- return [ { core, parameters : resultParameters } ] ;
264+ return resultParametersArray ?. map ( ( r ) => ( { core, parameters : r } ) )
272265 }
273266
274267 private async applyCreate ( plan : Plan < T > ) : Promise < void > {
@@ -410,21 +403,23 @@ ${JSON.stringify(refresh, null, 2)}
410403
411404 // Refresh stateful parameters
412405 // This refreshes parameters that are stateful (they can be added, deleted separately from the resource)
413- private async refreshStatefulParameters ( statefulParametersConfig : Partial < T > , allParameters : Partial < T > ) : Promise < Partial < T > > {
414- const result : Partial < T > = { }
406+ private async refreshStatefulParameters ( statefulParametersConfig : Partial < T > , allParameters : Array < Partial < T > > ) : Promise < Array < Partial < T > > > {
407+ const result : Array < Partial < T > > = Array . from ( { length : allParameters . length } , ( ) => ( { } ) )
415408 const sortedEntries = Object . entries ( statefulParametersConfig )
416409 . sort (
417410 ( [ key1 ] , [ key2 ] ) => this . parsedSettings . statefulParameterOrder . get ( key1 ) ! - this . parsedSettings . statefulParameterOrder . get ( key2 ) !
418411 )
419412
420- await Promise . all ( sortedEntries . map ( async ( [ key , desiredValue ] ) => {
421- const statefulParameter = this . parsedSettings . statefulParameters . get ( key ) ;
422- if ( ! statefulParameter ) {
423- throw new Error ( `Stateful parameter ${ key } was not found` ) ;
424- }
413+ for ( const [ idx , refreshedParams ] of allParameters . entries ( ) ) {
414+ await Promise . all ( sortedEntries . map ( async ( [ key , desiredValue ] ) => {
415+ const statefulParameter = this . parsedSettings . statefulParameters . get ( key ) ;
416+ if ( ! statefulParameter ) {
417+ throw new Error ( `Stateful parameter ${ key } was not found` ) ;
418+ }
425419
426- ( result as Record < string , unknown > ) [ key ] = await statefulParameter . refresh ( desiredValue ?? null , allParameters )
427- } ) )
420+ ( result [ idx ] [ key ] as T [ keyof T ] | null ) = await statefulParameter . refresh ( desiredValue ?? null , refreshedParams )
421+ } ) )
422+ }
428423
429424 return result ;
430425 }
@@ -461,39 +456,5 @@ ${JSON.stringify(refresh, null, 2)}
461456 ? Object . keys ( ( this . settings . schema as any ) ?. properties )
462457 : Object . keys ( this . parsedSettings . parameterSettings ) ;
463458 }
464-
465- /**
466- * When multiples of the same resource are allowed, this matching function will match a given config with one of the
467- * existing configs on the system. For example if there are multiple versions of Android Studios installed, we can use
468- * the application name and location to match it to our desired configs name and location.
469- *
470- * @param params
471- * @private
472- */
473- private matchParameters (
474- desired : Partial < T > | null ,
475- currentArray : Partial < T > [ ] | null
476- ) : Partial < T > | null {
477- if ( ! this . parsedSettings . allowMultiple ) {
478- return currentArray ?. [ 0 ] ?? null ;
479- }
480-
481- if ( ! currentArray ) {
482- return null ;
483- }
484-
485- const { matcher : parameterMatcher , id } = this . parsedSettings ;
486- const matcher = ( desired : Partial < T > , currentArray : Partial < T > [ ] ) : Partial < T > | undefined => {
487- const matched = currentArray . filter ( ( c ) => parameterMatcher ( desired , c ) )
488- if ( matched . length > 0 ) {
489- console . log ( `Resource: ${ id } did not uniquely match resources when allow multiple is set to true` )
490- }
491-
492- return matched [ 0 ] ;
493- }
494-
495- return matcher ( desired ! , currentArray ) ?? null ;
496- }
497-
498459}
499460
0 commit comments