UNPKG

alinea

Version:
89 lines (87 loc) 3.07 kB
import { pLimit } from "../../chunks/chunk-C53YJRET.js"; import "../../chunks/chunk-NZLE2WMY.js"; // src/core/source/GithubSource.ts import * as paths from "alinea/core/util/Paths"; import { HttpError } from "../HttpError.js"; import { assert } from "../util/Assert.js"; import { ReadonlyTree } from "./Tree.js"; var GithubSource = class { #current = ReadonlyTree.EMPTY; #options; #limit = pLimit(8); constructor(options) { this.#options = options; } get contentLocation() { const { contentDir, rootDir } = this.#options; return paths.join(rootDir, contentDir); } async getTree() { const current = this.#current; const newTree = await this.getTreeIfDifferent(current.sha); if (newTree) return this.#current = newTree; return current; } async shaAt(ref) { const { owner, repo, authToken } = this.#options; const parentDir = this.contentLocation.split("/").slice(0, -1).join("/"); const parentInfo = await fetch( `https://api.github.com/repos/${owner}/${repo}/contents/${parentDir}?ref=${ref}`, { headers: { Authorization: `Bearer ${authToken}` } } ); assert(parentInfo.ok, `Failed to get parent: ${parentInfo.statusText}`); const parents = await parentInfo.json(); assert(Array.isArray(parents)); const parent = parents.find((entry) => entry.path === this.contentLocation); if (!parent) return ReadonlyTree.EMPTY.sha; assert(typeof parent.sha === "string"); return parent.sha; } async getTreeIfDifferent(sha) { const { branch, owner, repo, authToken } = this.#options; const remoteSha = await this.shaAt(branch); if (remoteSha === sha) return void 0; const treeInfo = await fetch( `https://api.github.com/repos/${owner}/${repo}/git/trees/${remoteSha}?recursive=true`, { headers: { Authorization: `Bearer ${authToken}` } } ); assert(treeInfo.ok, `Failed to get tree: ${treeInfo.statusText}`); const treeData = await treeInfo.json(); assert(treeData.truncated === false); const tree = ReadonlyTree.fromFlat(treeData); return tree; } async *getBlobs(shas) { const { owner, repo, authToken } = this.#options; const responses = shas.map((sha) => { const promise = this.#limit( () => fetch( `https://api.github.com/repos/${owner}/${repo}/git/blobs/${sha}`, { headers: { Authorization: `Bearer ${authToken}` } } ) ); return [sha, promise]; }); for (const [sha, promise] of responses) { const response = await promise; if (!response.ok) throw new HttpError( response.status, `Failed to get blob: ${response.statusText}` ); const blobData = await response.json(); assert(blobData.encoding === "base64"); assert(typeof blobData.content === "string"); assert(blobData.size > 0); yield [sha, Uint8Array.from(atob(blobData.content), (c) => c.charCodeAt(0))]; } } async applyChanges(batch) { throw new Error("Not implemented"); } }; export { GithubSource };