| 85 | } |
| 86 | |
| 87 | async function extractZip(zipPath, outDir) { |
| 88 | // Try to use platform tools; no extra npm modules required |
| 89 | if (process.platform === 'win32') { |
| 90 | const cmd = `powershell -NoProfile -Command "Expand-Archive -Path '${zipPath}' -DestinationPath '${outDir.replace(/\\/g, '/')}' -Force"`; |
| 91 | await run(cmd); |
| 92 | return; |
| 93 | } |
| 94 | // Linux/mac: try unzip, else 7z, else busybox unzip |
| 95 | try { |
| 96 | await run('command -v unzip'); |
| 97 | await run(`unzip -o '${zipPath}' -d '${outDir}'`); |
| 98 | return; |
| 99 | } catch {} |
| 100 | try { |
| 101 | await run('command -v 7z'); |
| 102 | await run(`7z x -y '${zipPath}' -o'${outDir}'`); |
| 103 | return; |
| 104 | } catch {} |
| 105 | try { |
| 106 | await run('busybox unzip -h'); |
| 107 | await run(`busybox unzip -o '${zipPath}' -d '${outDir}'`); |
| 108 | return; |
| 109 | } catch {} |
| 110 | throw new Error("No system unzip tool found (unzip/7z/busybox). Git mode is recommended on this panel."); |
| 111 | } |
| 112 | |
| 113 | function copyRecursive(src, dest, ignore = [], relative = '', outList = []) { |
| 114 | if (!fs.existsSync(dest)) fs.mkdirSync(dest, { recursive: true }); |