| 166 | } |
| 167 | |
| 168 | async function downloadTemplate(template: Template, targetDir: string) { |
| 169 | const s = spinner() |
| 170 | s.start(`Downloading github.com/${template.repo}...`) |
| 171 | try { |
| 172 | const url = `https://github.com/${template.repo}/archive/refs/heads/main.tar.gz` |
| 173 | const tarResponse = await fetch(url) |
| 174 | if (!tarResponse.ok) { |
| 175 | throw new Error(`${url}: ${tarResponse.status} ${tarResponse.statusText}`) |
| 176 | } |
| 177 | |
| 178 | if (!tarResponse.body) { |
| 179 | throw new Error(`${url}: no body`) |
| 180 | } |
| 181 | |
| 182 | const extractor = tar.extract({ |
| 183 | cwd: targetDir, |
| 184 | strip: 1, |
| 185 | }) |
| 186 | |
| 187 | await new Promise<void>((resolve, reject) => { |
| 188 | Readable.fromWeb(tarResponse.body as any) |
| 189 | .pipe(extractor) |
| 190 | .on('end', resolve) |
| 191 | .on('error', reject) |
| 192 | }) |
| 193 | |
| 194 | s.stop(`Downloaded github.com/${template.repo}`) |
| 195 | } catch (err) { |
| 196 | s.stop(`Failed to download github.com/${template.repo}`) |
| 197 | throw err |
| 198 | } |
| 199 | } |
| 200 | |
| 201 | async function renameTemplate(name: string, targetDir: string) { |
| 202 | const packageJson = JSON.parse(readFileSync(resolve(targetDir, 'package.json'), 'utf-8')) |