( jsxText: string, nodePath: any, reservedKeysByParent: Map<string, Set<string>>, )
| 1128 | } |
| 1129 | |
| 1130 | function deduplicateKey( |
| 1131 | jsxText: string, |
| 1132 | nodePath: any, |
| 1133 | reservedKeysByParent: Map<string, Set<string>>, |
| 1134 | ): string { |
| 1135 | const attrs = nodePath.node.openingElement?.attributes ?? []; |
| 1136 | const keyAttr = attrs.find( |
| 1137 | (a: any) => a.type === "JSXAttribute" && a.name?.name === "key" |
| 1138 | ); |
| 1139 | if (!keyAttr?.value) return jsxText; |
| 1140 | const originalKey = getLiteralAttributeValue(keyAttr.value); |
| 1141 | if (!originalKey) return jsxText; |
| 1142 | |
| 1143 | const parentIdentity = getDuplicateParentIdentity(nodePath); |
| 1144 | let usedKeys = reservedKeysByParent.get(parentIdentity); |
| 1145 | if (!usedKeys) { |
| 1146 | usedKeys = collectSiblingLiteralKeys(nodePath); |
| 1147 | reservedKeysByParent.set(parentIdentity, usedKeys); |
| 1148 | } |
| 1149 | |
| 1150 | const newKey = pickUniqueDuplicateKey(originalKey, usedKeys); |
| 1151 | return jsxText.replace( |
| 1152 | new RegExp(`key=(["'])${escapeRegex(originalKey)}\\1`), |
| 1153 | (_match, quote: string) => `key=${quote}${newKey}${quote}`, |
| 1154 | ); |
| 1155 | } |
| 1156 | |
| 1157 | function getTextLikeNodeValue(node: any): string { |
| 1158 | if (!node) return ""; |
no test coverage detected