diff --git a/src/lib/octokit.ts b/src/lib/octokit.ts index 76bd54c..cd9f7bf 100644 --- a/src/lib/octokit.ts +++ b/src/lib/octokit.ts @@ -139,65 +139,82 @@ export async function getRepoSnapshot( ) { const client = createOctokit(accessToken); + const getNestedString = ( + obj: unknown, + path: string[], + ): string | undefined => { + let cur: unknown = obj; + for (const p of path) { + if ( + typeof cur === "object" && + cur !== null && + p in (cur as Record) + ) { + cur = (cur as Record)[p]; + } else { + return undefined; + } + } + return typeof cur === "string" ? cur : undefined; + }; + try { const { data: repoInfo } = await client.rest.repos.get({ owner, repo, }); - - // Resolve the branch to a tree SHA (default_branch is a name, not a SHA) - let treeSha: string | undefined = undefined; + let repoTree: Awaited>["data"]; try { - const { data: branch } = await client.rest.repos.getBranch({ + ({ data: repoTree } = await client.rest.git.getTree({ owner, repo, - branch: repoInfo.default_branch, - }); - - const getNestedString = ( - obj: unknown, - path: string[], - ): string | undefined => { - let cur: unknown = obj; - for (const p of path) { - if ( - typeof cur === "object" && - cur !== null && - p in (cur as Record) - ) { - cur = (cur as Record)[p]; - } else { - return undefined; + tree_sha: repoInfo.default_branch, + })); + } catch (initialTreeError: unknown) { + let resolvedTreeSha: string | undefined; + + try { + const { data: branch } = await client.rest.repos.getBranch({ + owner, + repo, + branch: repoInfo.default_branch, + }); + + resolvedTreeSha = getNestedString(branch, [ + "commit", + "commit", + "tree", + "sha", + ]); + + if (!resolvedTreeSha) { + const commitSha = getNestedString(branch, ["commit", "sha"]); + if (commitSha) { + const { data: commit } = await client.rest.git.getCommit({ + owner, + repo, + commit_sha: commitSha, + }); + resolvedTreeSha = + typeof commit.tree?.sha === "string" + ? commit.tree.sha + : undefined; } } - return typeof cur === "string" ? cur : undefined; - }; - - treeSha = getNestedString(branch, ["commit", "commit", "tree", "sha"]); - - if (!treeSha) { - const commitSha = getNestedString(branch, ["commit", "sha"]); - - if (commitSha) { - const { data: commit } = await client.rest.git.getCommit({ - owner, - repo, - commit_sha: commitSha, - }); + } catch { + // Ignore fallback resolution errors and rethrow the original tree lookup error below. + } - treeSha = commit.tree.sha; - } + if (!resolvedTreeSha) { + throw initialTreeError; } - } catch { - // If resolving the branch fails, fall back to the previous behavior - treeSha = undefined; - } - const { data: repoTree } = await client.rest.git.getTree({ - owner, - repo, - tree_sha: treeSha ?? repoInfo.default_branch, - }); + ({ data: repoTree } = await client.rest.git.getTree({ + owner, + repo, + tree_sha: resolvedTreeSha, + })); + } type RepoTreeItem = (typeof repoTree.tree)[number]; const repoContents = repoTree.tree.filter(