diff --git a/packages/create-next-app/helpers/examples.ts b/packages/create-next-app/helpers/examples.ts index 44af47b2acf..64a7635cf1d 100644 --- a/packages/create-next-app/helpers/examples.ts +++ b/packages/create-next-app/helpers/examples.ts @@ -3,6 +3,9 @@ import got from 'got' import tar from 'tar' import { Stream } from 'stream' import { promisify } from 'util' +import { join } from 'path' +import { tmpdir } from 'os' +import { createWriteStream } from 'fs' const pipeline = promisify(Stream.pipeline) @@ -79,31 +82,44 @@ export function existsInRepo(nameOrUrl: string): Promise { } } -export function downloadAndExtractRepo( +async function downloadTar(url: string) { + const tempFile = join(tmpdir(), `next.js-cra-example.temp-${Date.now()}`) + await pipeline(got.stream(url), createWriteStream(tempFile)) + return tempFile +} + +export async function downloadAndExtractRepo( root: string, { username, name, branch, filePath }: RepoInfo -): Promise { - return pipeline( - got.stream( - `https://codeload.github.com/${username}/${name}/tar.gz/${branch}` - ), - tar.extract( - { cwd: root, strip: filePath ? filePath.split('/').length + 1 : 1 }, - [`${name}-${branch.replace(/\//g, '-')}${filePath ? `/${filePath}` : ''}`] - ) +) { + const tempFile = await downloadTar( + `https://codeload.github.com/${username}/${name}/tar.gz/${branch}` ) + + await tar.x({ + file: tempFile, + cwd: root, + strip: filePath ? filePath.split('/').length + 1 : 1, + filter: (p) => + p.startsWith( + `${name}-${branch.replace(/\//g, '-')}${filePath ? `/${filePath}` : ''}` + ), + }) } -export function downloadAndExtractExample( - root: string, - name: string -): Promise { +export async function downloadAndExtractExample(root: string, name: string) { if (name === '__internal-testing-retry') { throw new Error('This is an internal example for testing the CLI.') } - return pipeline( - got.stream('https://codeload.github.com/vercel/next.js/tar.gz/canary'), - tar.extract({ cwd: root, strip: 3 }, [`next.js-canary/examples/${name}`]) + const tempFile = await downloadTar( + 'https://codeload.github.com/vercel/next.js/tar.gz/canary' ) + + await tar.x({ + file: tempFile, + cwd: root, + strip: 3, + filter: (p) => p.includes(`next.js-canary/examples/${name}`), + }) }