( currentData: any, pathParts: string[], targetIndex: number )
| 83 | |
| 84 | // Get item at specific path and index |
| 85 | export const getNestedItem = ( |
| 86 | currentData: any, |
| 87 | pathParts: string[], |
| 88 | targetIndex: number |
| 89 | ): FlowNodeData | null => { |
| 90 | if (pathParts.length === 0 || currentData == null) return null; |
| 91 | |
| 92 | const [head, ...tail] = pathParts; |
| 93 | |
| 94 | if (!isNaN(Number(head)) && Array.isArray(currentData)) { |
| 95 | const index = Number(head); |
| 96 | return getNestedItem(currentData[index], tail, targetIndex); |
| 97 | } |
| 98 | |
| 99 | let realKey = head; |
| 100 | let isSwitchCase = false; |
| 101 | |
| 102 | if (head === 'then') realKey = 'thenSteps'; |
| 103 | else if (head === 'else') realKey = 'elseSteps'; |
| 104 | else if (head === 'loop') realKey = 'loopSteps'; |
| 105 | else if (head === '__default__') realKey = 'defaultSteps'; |
| 106 | else { |
| 107 | if (currentData.cases && Array.isArray(currentData.cases[head])) { |
| 108 | isSwitchCase = true; |
| 109 | } |
| 110 | } |
| 111 | |
| 112 | if (tail.length === 0) { |
| 113 | if (isSwitchCase) { |
| 114 | return currentData.cases[head]?.[targetIndex] || null; |
| 115 | } else { |
| 116 | return currentData[realKey]?.[targetIndex] || null; |
| 117 | } |
| 118 | } |
| 119 | |
| 120 | if (isSwitchCase) { |
| 121 | return getNestedItem(currentData.cases[head] || [], tail, targetIndex); |
| 122 | } else { |
| 123 | return getNestedItem(currentData[realKey] || [], tail, targetIndex); |
| 124 | } |
| 125 | }; |
| 126 | |
| 127 | // Adjust target path if it was affected by source removal |
| 128 | export const adjustTargetPath = (sourceBranch: string, sourceIndex: number, targetBranch: string): string => { |
no outgoing calls
no test coverage detected