()
| 79 | let timeoutId: ReturnType<typeof setTimeout>; |
| 80 | |
| 81 | const fetchKeyFiles = async () => { |
| 82 | if (!repoFullName) return; |
| 83 | const cache = getKeyFilesCache(); |
| 84 | if (cache[repoFullName]) { |
| 85 | setKeyFiles(cache[repoFullName]); |
| 86 | setLoading(false); |
| 87 | return; |
| 88 | } |
| 89 | |
| 90 | // Use AbortController to handle timeouts and cancellations |
| 91 | controller = new AbortController(); |
| 92 | timeoutId = setTimeout(() => controller.abort(), 30000); // 30 second timeout |
| 93 | |
| 94 | setLoading(true); |
| 95 | setError(null); |
| 96 | try { |
| 97 | // Use our API endpoint to get the repository structure |
| 98 | const structureRes = await fetch(`/api/get-repo-structure?repo=${encodeURIComponent(repoFullName)}`); |
| 99 | const structureData = await structureRes.json(); |
| 100 | // Debug: log the structureData for troubleshooting |
| 101 | if (typeof window !== 'undefined') { |
| 102 | // Only log in browser |
| 103 | console.log('Repo structureData:', structureData); |
| 104 | } |
| 105 | // Get the file tree from the structure data |
| 106 | |
| 107 | let files: any[] = []; |
| 108 | if (structureData.fileTree && Array.isArray(structureData.fileTree)) { |
| 109 | // Extract all files from the hierarchical file tree |
| 110 | |
| 111 | const extractFiles = (nodes: any[], result: any[] = []) => { |
| 112 | for (const node of nodes) { |
| 113 | if (node.type === 'file' || node.type === 'blob') { |
| 114 | result.push({ |
| 115 | path: node.path, |
| 116 | type: 'blob', |
| 117 | size: node.size || 0 |
| 118 | }); |
| 119 | } else if ((node.type === 'directory' || node.type === 'tree') && node.children) { |
| 120 | extractFiles(node.children, result); |
| 121 | } |
| 122 | } |
| 123 | return result; |
| 124 | }; |
| 125 | files = extractFiles(structureData.fileTree); |
| 126 | } else if (structureData.tree && Array.isArray(structureData.tree)) { |
| 127 | files = structureData.tree.filter((item: any) => item.type === 'blob' || item.type === 'file'); |
| 128 | } else if (structureData.files && Array.isArray(structureData.files)) { |
| 129 | files = structureData.files.filter((item: any) => item.type === 'blob' || item.type === 'file'); |
| 130 | } else { |
| 131 | // Try to fallback to any array of files/blobs in the response |
| 132 | const possibleArrays = Object.values(structureData).filter(v => Array.isArray(v)); |
| 133 | for (const arr of possibleArrays) { |
| 134 | const fileCandidates = arr.filter((item: any) => item && (item.type === 'blob' || item.type === 'file') && item.path); |
| 135 | if (fileCandidates.length > 0) { |
| 136 | files = fileCandidates; |
| 137 | break; |
| 138 | } |
no test coverage detected