Skip to content
Snippets Groups Projects
repo.ts 1.75 KiB
Newer Older
  • Learn to ignore specific revisions
  • import { createWriteStream, promises } from "fs";
    import got from "got";
    import { tmpdir } from "os";
    import { join } from "path";
    import { Stream } from "stream";
    import tar from "tar";
    import { promisify } from "util";
    import { makeDir } from "./make-dir";
    
    export type RepoInfo = {
      username: string;
      name: string;
      branch: string;
      filePath: string;
    };
    
    const pipeline = promisify(Stream.pipeline);
    
    async function downloadTar(url: string) {
      const tempFile = join(tmpdir(), `next.js-cna-example.temp-${Date.now()}`);
      await pipeline(got.stream(url), createWriteStream(tempFile));
      return tempFile;
    }
    
    export async function downloadAndExtractRepo(
      root: string,
      { username, name, branch, filePath }: RepoInfo,
    ) {
      await makeDir(root);
    
      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}/` : "/"
            }`,
          ),
      });
    
      await promises.unlink(tempFile);
    }
    
    export async function getRepoRootFolders(
      owner: string,
      repo: string,
    ): Promise<string[]> {
      const url = `https://api.github.com/repos/${owner}/${repo}/contents`;
    
      const response = await got(url, {
        responseType: "json",
      });
    
      const data = response.body as any[];
      const folders = data.filter((item) => item.type === "dir");
      return folders.map((item) => item.name);
    }
    
    
    export async function getRepoRawContent(repoFilePath: string) {
      const url = `https://raw.githubusercontent.com/${repoFilePath}`;
      const response = await got(url, {
        responseType: "text",
      });
      return response.body;
    }