@@ -326,15 +326,27 @@ export class Plan<T extends StringIndexedObject> {
326326
327327 // For stateful mode, we're done after filtering by the keys of desired + state. Stateless mode
328328 // requires additional filtering for stateful parameter arrays and objects.
329- if ( isStateful ) {
329+ if ( isStateful && desired ) {
330330 return filteredCurrent ;
331331 }
332332
333+ // We also want to filter parameters when in delete mode. We don't want to delete parameters that
334+ // are not specified in the original config.
335+ if ( isStateful && ! desired ) {
336+ const arrayStatefulParameters = Object . fromEntries (
337+ Object . entries ( filteredCurrent )
338+ . filter ( ( [ k , v ] ) => isArrayParameterWithFiltering ( k , v ) )
339+ . map ( ( [ k , v ] ) => [ k , filterArrayParameterForDeletes ( k , v ) ] )
340+ )
341+
342+ return { ...filteredCurrent , ...arrayStatefulParameters }
343+ }
344+
333345 // TODO: Add object handling here in addition to arrays in the future
334346 const arrayStatefulParameters = Object . fromEntries (
335347 Object . entries ( filteredCurrent )
336348 . filter ( ( [ k , v ] ) => isArrayParameterWithFiltering ( k , v ) )
337- . map ( ( [ k , v ] ) => [ k , filterArrayStatefulParameter ( k , v ) ] )
349+ . map ( ( [ k , v ] ) => [ k , filterArrayParameterForStatelessMode ( k , v ) ] )
338350 )
339351
340352 return { ...filteredCurrent , ...arrayStatefulParameters }
@@ -378,7 +390,7 @@ export class Plan<T extends StringIndexedObject> {
378390
379391 function isArrayParameterWithFiltering ( k : string , v : T [ keyof T ] ) : boolean {
380392 const filterParameter = getFilterParameter ( k ) ;
381-
393+
382394 if ( settings . parameterSettings ?. [ k ] ?. type === 'stateful' ) {
383395 const statefulSetting = settings . parameterSettings [ k ] as ParsedStatefulParameterSetting ;
384396 return statefulSetting . nestedSettings . type === 'array' &&
@@ -392,7 +404,7 @@ export class Plan<T extends StringIndexedObject> {
392404 }
393405
394406 // For stateless mode, we must filter the current array so that the diff algorithm will not detect any deletes
395- function filterArrayStatefulParameter ( k : string , v : unknown [ ] ) : unknown [ ] {
407+ function filterArrayParameterForStatelessMode ( k : string , v : unknown [ ] ) : unknown [ ] {
396408 const desiredArray = desired ! [ k ] as unknown [ ] ;
397409 const matcher = settings . parameterSettings ! [ k ] ! . type === 'stateful'
398410 ? ( ( settings . parameterSettings ! [ k ] as ParsedStatefulParameterSetting )
@@ -427,6 +439,43 @@ export class Plan<T extends StringIndexedObject> {
427439 ? filterParameter ( desiredCopy , currentCopy )
428440 : defaultFilterMethod ( desiredCopy , currentCopy ) ;
429441 }
442+
443+ function filterArrayParameterForDeletes ( k : string , v : unknown [ ] ) : unknown [ ] {
444+ const stateArray = state ! [ k ] as unknown [ ] ;
445+ const matcher = settings . parameterSettings ! [ k ] ! . type === 'stateful'
446+ ? ( ( settings . parameterSettings ! [ k ] as ParsedStatefulParameterSetting )
447+ . nestedSettings as ParsedArrayParameterSetting )
448+ . isElementEqual
449+ : ( settings . parameterSettings ! [ k ] as ParsedArrayParameterSetting )
450+ . isElementEqual
451+
452+ const stateCopy = [ ...stateArray ] ;
453+ const currentCopy = [ ...v ] ;
454+
455+ const defaultFilterMethod = ( ( state : any [ ] , current : any [ ] ) => {
456+ const result = [ ] ;
457+
458+ for ( let counter = state . length - 1 ; counter >= 0 ; counter -- ) {
459+ const idx = currentCopy . findIndex ( ( e2 ) => matcher ( state [ counter ] , e2 ) )
460+
461+ if ( idx === - 1 ) {
462+ continue ;
463+ }
464+
465+ state . splice ( counter , 1 )
466+ const [ element ] = current . splice ( idx , 1 )
467+ result . push ( element )
468+ }
469+
470+ return result ;
471+ } )
472+
473+
474+ const filterParameter = getFilterParameter ( k ) ;
475+ return typeof filterParameter === 'function'
476+ ? filterParameter ( stateCopy , currentCopy )
477+ : defaultFilterMethod ( stateCopy , currentCopy ) ;
478+ }
430479 }
431480
432481 // TODO: This needs to be revisited. I don't think this is valid anymore.
0 commit comments