( currentData: any, pathParts: string[], targetIndex: number, newValue: any )
| 3 | // Helper to recursively update nested data structure |
| 4 | // Returns the updated root data object |
| 5 | export const updateNestedStructure = ( |
| 6 | currentData: any, |
| 7 | pathParts: string[], |
| 8 | targetIndex: number, |
| 9 | newValue: any |
| 10 | ): any => { |
| 11 | if (pathParts.length === 0 || currentData == null) return currentData; |
| 12 | |
| 13 | const [head, ...tail] = pathParts; |
| 14 | |
| 15 | // If head is a number AND currentData is an array, we are traversing an array |
| 16 | if (!isNaN(Number(head)) && Array.isArray(currentData)) { |
| 17 | const index = Number(head); |
| 18 | const item = currentData[index]; |
| 19 | const updatedItem = updateNestedStructure(item, tail, targetIndex, newValue); |
| 20 | const newData = [...currentData]; |
| 21 | newData[index] = updatedItem; |
| 22 | return newData; |
| 23 | } |
| 24 | |
| 25 | // Map branch names to actual keys |
| 26 | let realKey = head; |
| 27 | let isSwitchCase = false; |
| 28 | |
| 29 | if (head === 'then') realKey = 'thenSteps'; |
| 30 | else if (head === 'else') realKey = 'elseSteps'; |
| 31 | else if (head === 'loop') realKey = 'loopSteps'; |
| 32 | else if (head === '__default__') realKey = 'defaultSteps'; |
| 33 | else { |
| 34 | // Check if it's a switch case |
| 35 | if (currentData.cases && Array.isArray(currentData.cases[head])) { |
| 36 | isSwitchCase = true; |
| 37 | } |
| 38 | } |
| 39 | |
| 40 | // If we are at the end of the path (targeting an array) |
| 41 | if (tail.length === 0) { |
| 42 | if (isSwitchCase) { |
| 43 | const newCases = { ...currentData.cases }; |
| 44 | const targetArray = [...(newCases[head] || [])]; |
| 45 | |
| 46 | if (newValue === null) { |
| 47 | // Handle deletion |
| 48 | const newArray = targetArray.filter((_, i) => i !== targetIndex); |
| 49 | newCases[head] = newArray; |
| 50 | } else { |
| 51 | // Handle update |
| 52 | targetArray[targetIndex] = newValue; |
| 53 | newCases[head] = targetArray; |
| 54 | } |
| 55 | return { ...currentData, cases: newCases }; |
| 56 | } else { |
| 57 | const targetArray = [...(currentData[realKey] || [])]; |
| 58 | |
| 59 | if (newValue === null) { |
| 60 | // Handle deletion |
| 61 | const newArray = targetArray.filter((_, i) => i !== targetIndex); |
| 62 | return { ...currentData, [realKey]: newArray }; |
no outgoing calls
no test coverage detected