Public
Edited
Nov 3, 2023
Paused
Importers
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
async function gh(
link // chosen link in github repo
, {
endpoint = "repos", // endpoint string
ghToken = credentials[0].ghToken, // GitHub Personal Access Token, see https://docs.github.com/en/rest
debug = false // if true, return API url
} = {}) {

// main url endpoint for API, see https://docs.github.com/en/rest/repos/contents#custom-media-types-for-repository-contents
const URL_PREFIX = 'https://api.github.com'

// create header for accepting responses, see https://docs.github.com/en/rest/overview/media-types?apiVersion=2022-11-28
const headers = {
Accept: `application/vnd.github.raw`
}
if (ghToken !== null) {
headers["Authorization"] = `token ${ghToken}`
}

// parse data link: url → path
if (link == undefined) { return "Include GitHub Link (Docs: https://observablehq.com/@periscopic/github-api-in-observable)"}

// parsing the github link
let urlLink = ""
if (link !== "") {
const rawLink = String(link)
let inputLink = rawLink

// get url components to ping api
let unpack = inputLink.split("/").slice(3)
let owner = unpack.slice(0, 1)
let repo = unpack.slice(1, 2)
let flowType = unpack.slice(2, 3) // the kind of link, tree or blob
let branch = unpack.slice(3, 4)
let path = unpack.slice(4)

// get the default branch via the api
let fetchMeta = `${URL_PREFIX}/repos/${[owner, repo].join("/")}`
let resMeta = await fetch(fetchMeta, {
headers: headers
}).then((response) => response.json())
let defaultBranch = resMeta.default_branch

// define branch parameter
let branchRef = branch.slice(0, 1).length === 0 | branch.slice(0, 1)[0] === defaultBranch ? "" : "?ref=" + branch.slice(0, 1)[0]

// define the owner/repo/path
let linkArray = [owner, repo, "contents", path, branchRef]
let linkCollapsed = linkArray.flat()

// finish creating url link
urlLink = linkCollapsed.slice(0, -1).join("/") + linkCollapsed.slice(-1)
if (!urlLink.startsWith("/") & urlLink !== "") { urlLink = '/' + urlLink }
}

// parse the endpoint
const rawEndpoint = String(endpoint)
let urlEndpoint = rawEndpoint
if (!urlEndpoint.startsWith("/")) { urlEndpoint = '/' + urlEndpoint }

// make full link to ping api
let fetchQuery = `${URL_PREFIX}${urlEndpoint}${urlLink}`
if (debug) { return fetchQuery }

// get response, use username/password if provided
const response = await fetch(fetchQuery, {
headers: headers
})

// return response
return response

}
Insert cell
Insert cell
// pack up Observable Secrets, or return empty
credentials = {
try {
let ghToken = Secret("GH_API_PAT")
return [{ghToken}]
} catch (error) {
return [{ghToken: null}]
}
}
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more