Last active
March 29, 2023 15:21
-
-
Save abstractalgo/3f1646964f7cbfe48397cd7d67b07cea to your computer and use it in GitHub Desktop.
Revisions
-
abstractalgo revised this gist
Mar 29, 2023 . 1 changed file with 42 additions and 34 deletions.There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -1,72 +1,80 @@ import { DirectoryNode, FileSystemTree } from "@webcontainer/api"; export const getGithubFilesTree = async ({ owner, repo, path, branch = "master", }: { owner: string; repo: string; path: string; branch?: string; }): Promise<FileSystemTree> => { // 1. get file tree from Github const latestCommitRes = await fetch( `https://api.github.com/repos/${owner}/${repo}/commits/${branch}` ); const latestCommit = (await latestCommitRes.json()) as { sha: string }; const ghTreeRes = await fetch( `https://api.github.com/repos/${owner}/${repo}/git/trees/${latestCommit.sha}?recursive=1` ); const fsNodes = ( (await ghTreeRes.json()) as { tree: { path: string; type: "blob" | "tree"; size: number; url: string; }[]; } ).tree; // 2. get file contents from Github for files that match the path const fileContents: Record<string, string> = await (async () => { const filteredTree = fsNodes.filter( (i) => i.path.startsWith(path) && i.type === "blob" ); const contentFetches = filteredTree.map((i) => fetch( `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${i.path}` ) ); const contentRes = await Promise.all(contentFetches); const content = await Promise.all(contentRes.map((res) => res.text())); const fileContents: Record<string, string> = {}; for (let idx = 0; idx < filteredTree.length; idx++) { fileContents[filteredTree[idx].path] = content[idx]; } return fileContents; })(); // 3. construct a full file system tree let fsTree: FileSystemTree = {}; fsNodes.forEach((item) => { const path = item.path; const pathParts = path.split("/"); let currentLevel = fsTree; pathParts.forEach((part) => { const isPartAFilename = fsNodes.find( (i) => i.path === item.path && i.type === "blob" ); if (!currentLevel[part]) { currentLevel[part] = isPartAFilename ? { file: { contents: fileContents[path] ?? "~", }, } : { @@ -77,11 +85,11 @@ cursive=1`); }); }); // 4. return the subtree for the path for (const pathPart of path.split("/")) { fsTree = (fsTree[pathPart] as DirectoryNode).directory; } return fsTree; }; -
abstractalgo created this gist
Mar 29, 2023 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,87 @@ import { DirectoryNode, FileSystemTree } from '@webcontainer/api'; export const getGithubFiles = async ({ owner, repo, path, branch = 'master', }: { owner: string; repo: string; path: string; branch?: string; }): Promise<FileSystemTree> => { const latestCommitRes = await fetch( `https://api.github.com/repos/${owner}/${repo}/commits/${branch}` ); const latestCommit = (await latestCommitRes.json()) as { sha: string }; const treeRes = await fetch(`https://api.github.com/repos/${owner}/${repo}/git/trees/${latestCommit.sha}?re cursive=1`); const fsNodes = ( (await treeRes.json()) as { tree: { path: string; type: 'blob' | 'tree'; size: number; url: string; }[]; } ).tree; const filteredTree = fsNodes.filter( (i) => i.path.startsWith(path) && i.type === 'blob' ); // const contentFetches = filteredTree.map(i=>fetch(`https://api.github.com/repos/${owner}/${repo}/contents/${i.path}`)) const contentFetches = filteredTree.map((i) => fetch( `https://raw.githubusercontent.com/${owner}/${repo}/${branch}/${i.path}` ) ); const contentRes = await Promise.all(contentFetches); const content = await Promise.all(contentRes.map((res) => res.text())); const fileContents: Record<string, string> = {}; for (let idx = 0; idx < filteredTree.length; idx++) { fileContents[filteredTree[idx].path] = content[idx]; } // ----------------------- let tree: FileSystemTree = {}; fsNodes.forEach((item) => { const path = item.path; const pathParts = path.split('/'); let currentLevel = tree; pathParts.forEach((part) => { const isPartAFilename = fsNodes.find( (i) => i.path === item.path && i.type === 'blob' ); if (!currentLevel[part]) { currentLevel[part] = isPartAFilename ? { file: { contents: fileContents[path] ?? '~', }, } : { directory: {}, }; } currentLevel = (currentLevel[part] as DirectoryNode).directory; }); }); for (const pathPart of path.split('/')) { tree = (tree[pathPart] as DirectoryNode).directory; } console.log(tree); return tree; };